예제 #1
0
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
예제 #2
0
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)
예제 #3
0
def test_list_max_length_invalid():
    with pytest.raises(InvalidListLength):
        _validate([1, 2, 3], List(min_length=1, max_length=2))
예제 #4
0
def test_list_min_max_length_valid():
    _validate([1, 2, 3], List(min_length=1, max_length=3))
예제 #5
0
def test_list_invalid_type():
    error = pytest.raises(InvalidTypeError,
                          lambda: _validate(tuple(), List(Bool()))).value

    assert error.object_name == ""
    assert error.object_type == tuple
예제 #6
0
def test_list_modification():
    _validate_modification(["1", "2"], List(ToInt()), [1, 2])
예제 #7
0
def test_list_without_scheme():
    _validate(["string"], List())
예제 #8
0
def test_list_full():
    _validate([True, False], List(Bool()))
예제 #9
0
def test_list_empty():
    _validate([], List(Bool()))
예제 #10
0
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]
예제 #11
0
}, {
    "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)