def test_list_invalid_element_type(): error = pytest.raises( InvalidTypeError, lambda: _validate([False, 10, True], List(Bool()))).value assert error.object_name == "[1]" assert error.object_type == int
class ExportsInfo(Sequence): """Information about volume exports.""" __scheme__ = List(DictScheme({ "sdcId": String(), "sdcIp": String(), "limitIops": Integer(), "limitBwInMbps": Integer() }), optional=True) def __init__(self, data=None): self._data = data or [] def __getitem__(self, index): return self._data[index] def __len__(self): return len(self._data) def __contains__(self, key): if isinstance(key, Sdc): return key["id"] in (e["sdcId"] for e in self._data) else: super(ExportsInfo, self).__contains__(key)
def test_list_max_length_invalid(): with pytest.raises(InvalidListLength): _validate([1, 2, 3], List(min_length=1, max_length=2))
def test_list_min_max_length_valid(): _validate([1, 2, 3], List(min_length=1, max_length=3))
def test_list_invalid_type(): error = pytest.raises(InvalidTypeError, lambda: _validate(tuple(), List(Bool()))).value assert error.object_name == "" assert error.object_type == tuple
def test_list_modification(): _validate_modification(["1", "2"], List(ToInt()), [1, 2])
def test_list_without_scheme(): _validate(["string"], List())
def test_list_full(): _validate([True, False], List(Bool()))
def test_list_empty(): _validate([], List(Bool()))
class BaseResource(Mapping): """Base resource model.""" __scheme__ = { "id": String(), "links": List( DictScheme({ "href": String(), "rel": String() }), optional=True ) } """Data scheme for instance validation.""" __parents__ = None """ References to parent resources by fields. Example: frozenset([ ("parentField", "ResourceClassName") ]) """ __resource__ = None """ Custom resource name that overrides default name based on name of resource class. """ @classmethod def _get_name(cls): """Returns resource name. Attention: for internal use only! """ resource = cls.__resource__ if not resource: resource = camelize(underscore(cls.__name__)) return resource @classmethod def _get_scheme(cls): """Returns resource scheme for proper validation. Attention: for internal use only! """ scheme = {} for base in cls.mro(): if bool( issubclass(base, BaseResource) and getattr(base, "__scheme__", None) ): scheme.update(base.__scheme__) return DictScheme(scheme, ignore_unknown=True) @classmethod def one(cls, instance_id, **kwargs): """Returns instance of resource. :param instance_id: id of resource instance :returns: instance of resource """ return cls(instance_id, **kwargs) @pyscaleio.inject @classmethod def all(cls, client, instance_ids=None, **kwargs): """Returns list of resource instances. :param instance_ids: list of instance ids (optional) :returns: list of resource instances """ if not instance_ids: instances = client.get_instances_of(cls._get_name()) else: if isinstance(instance_ids, string_types): instance_ids = (instance_ids,) instances = client.perform_action_on_type( cls._get_name(), "queryBySelectedIds", {"ids": instance_ids}) return [cls(instance=instance, client=client) for instance in instances ] @pyscaleio.inject def __init__(self, client, instance_id=None, instance=None): self._client = client self._scheme = {} if instance_id and instance: raise exceptions.ScaleIONotBothParameters("instance_id", "instance") if instance_id: instance = self._client.get_instance_of(self._get_name(), instance_id) self._instance = self._validate(instance or {}) def __getitem__(self, key): return self._instance[key] def __iter__(self): return iter(self._instance) def __len__(self): return len(self._instance) @property def links(self): return self["links"] def _validate(self, instance): """Validates the instance if resource according to scheme. Attention: for internal use only! """ try: return validate("instance", instance, self._get_scheme()) except ValidationError as e: raise exceptions.ScaleIOValidationError(e) def update(self): """Updates resource instance.""" instance = self._client.get_instance_of(self._get_name(), self["id"]) instance = self._validate(instance) fields = set(list(instance) + list(self._instance)) for field in fields: try: instance[field] except KeyError: del self._instance[field] else: self._instance[field] = instance[field]
}, { "id": 2, "name": "two", "value": 2.0, "zero": False, "dividers": [1, 2], "dividers_map": { 1: 1.0, 2: 2.0, }, }] SCHEME = List(DictScheme({ "id": Integer(choices=(0, 2)), "name": String(), "value": Float(), "zero": Bool(), "dividers": List(Integer()), "dividers_map": Dict(Integer(), Float()), })) def test_validate(): _validate("items", copy.deepcopy(ITEMS), SCHEME) def test_validate_invalid_type(): items = copy.deepcopy(ITEMS) items[1]["id"] = "string" error = pytest.raises(InvalidTypeError, lambda: _validate("items", items, SCHEME)