Ejemplo n.º 1
0
def test_equal_objects_return_true_with_equal_nested_list_of_object_references(
):
    assert equal_objects(
        {
            'name': 'foo',
            'config': {
                'version':
                '1',
                'ports': [{
                    'name': 'oldPortName',
                    'type': 'port',
                    'id': '123'
                }, {
                    'name': 'oldPortName2',
                    'type': 'port',
                    'id': '234'
                }]
            }
        }, {
            'name': 'foo',
            'config': {
                'version':
                '1',
                'ports': [{
                    'name': 'newPortName',
                    'type': 'port',
                    'id': '123'
                }, {
                    'name': 'newPortName2',
                    'type': 'port',
                    'id': '234',
                    'extraField': 'foo'
                }]
            }
        })
Ejemplo n.º 2
0
def test_equal_objects_return_true_with_equal_nested_object_references():
    assert equal_objects(
        {
            'name': 'foo',
            'config': {
                'version': '1',
                'port': {
                    'name': 'oldPortName',
                    'type': 'port',
                    'id': '123'
                }
            }
        },
        {
            'name': 'foo',
            'config': {
                'version': '1',
                'port': {
                    'name': 'newPortName',
                    'type': 'port',
                    'id': '123'
                }
            }
        }
    )
Ejemplo n.º 3
0
    def _check_if_the_same_object(self, operation_name, params, e):
        """
        Special check used in the scope of 'add_object' operation, which can be requested as a standalone operation or
        in the scope of 'upsert_object' operation. This method executed in case 'add_object' failed and should try to
        find the object that caused "object duplicate" error. In case single object found and it's equal to one we are
        trying to create - the existing object will be returned (attempt to have kind of idempotency for add action).
        In the case when we got more than one object returned as a result of the request to API - it will be hard to
        find exact duplicate so the exception will be raised.
        """
        model_name = self.get_operation_spec(operation_name)[OperationField.MODEL_NAME]
        get_list_operation = self._find_get_list_operation(model_name)
        if get_list_operation:
            data = params[ParamName.DATA]
            if not params.get(ParamName.FILTERS):
                params[ParamName.FILTERS] = {'name': data['name']}

            existing_obj = None
            existing_objs = self.get_objects_by_filter(get_list_operation, params)

            for i, obj in enumerate(existing_objs):
                if i > 0:
                    raise FtdConfigurationError(MULTIPLE_DUPLICATES_FOUND_ERROR)
                existing_obj = obj

            if existing_obj is not None:
                if equal_objects(existing_obj, data):
                    return existing_obj
                else:
                    raise FtdConfigurationError(
                        'Cannot add new object. '
                        'An object with the same name but different parameters already exists.',
                        existing_obj)

        raise e
Ejemplo n.º 4
0
    def add_object(self, url_path, body_params, path_params=None, query_params=None, update_if_exists=False):
        def is_duplicate_name_error(err):
            return err.code == UNPROCESSABLE_ENTITY_STATUS and DUPLICATE_NAME_ERROR_MESSAGE in str(err)

        def update_existing_object(obj):
            new_path_params = {} if path_params is None else path_params
            new_path_params['objId'] = obj['id']
            return self.send_request(url_path=url_path + '/{objId}',
                                     http_method=HTTPMethod.PUT,
                                     body_params=copy_identity_properties(obj, body_params),
                                     path_params=new_path_params,
                                     query_params=query_params)

        try:
            return self.send_request(url_path=url_path, http_method=HTTPMethod.POST, body_params=body_params,
                                     path_params=path_params, query_params=query_params)
        except FtdServerError as e:
            if is_duplicate_name_error(e):
                existing_obj = self.get_object_by_name(url_path, body_params['name'], path_params)
                if equal_objects(existing_obj, body_params):
                    return existing_obj
                elif update_if_exists:
                    return update_existing_object(existing_obj)
                else:
                    raise FtdConfigurationError(
                        'Cannot add new object. An object with the same name but different parameters already exists.')
            else:
                raise e
Ejemplo n.º 5
0
def test_equal_objects_return_false_with_different_nested_object_references():
    assert not equal_objects(
        {
            'name': 'foo',
            'config': {
                'version': '1',
                'port': {
                    'name': 'oldPortName',
                    'type': 'port',
                    'id': '123'
                }
            }
        },
        {
            'name': 'foo',
            'config': {
                'version': '1',
                'port': {
                    'name': 'oldPortName',
                    'type': 'port',
                    'id': '234'
                }
            }
        }
    )
Ejemplo n.º 6
0
def test_equal_objects_return_false_with_different_array_length():
    assert not equal_objects(
        {'foo': [{
            'id': '1',
            'type': 'network',
            'ignored_field': 'foo'
        }]}, {'foo': []})
Ejemplo n.º 7
0
    def upsert_object(self, op_name, params):
        """
        Updates an object if it already exists, or tries to create a new one if there is no
        such object. If multiple objects match filter criteria, or add operation is not supported,
        the exception is raised.

        :param op_name: upsert operation name
        :type op_name: str
        :param params: params that upsert operation should be executed with
        :type params: dict
        :return: upserted object representation
        :rtype: dict
        """
        def extract_and_validate_model():
            model = op_name[len(OperationNamePrefix.UPSERT):]
            if not self._conn.get_model_spec(model):
                raise FtdInvalidOperationNameError(op_name)
            return model

        model_name = extract_and_validate_model()
        model_operations = self.get_operation_specs_by_model_name(model_name)

        if not self._operation_checker.is_upsert_operation_supported(
                model_operations):
            raise FtdInvalidOperationNameError(op_name)

        existing_obj = self._find_object_matching_params(model_name, params)
        if existing_obj:
            equal_to_existing_obj = equal_objects(existing_obj,
                                                  params[ParamName.DATA])
            return existing_obj if equal_to_existing_obj \
                else self._edit_upserted_object(model_operations, existing_obj, params)
        else:
            return self._add_upserted_object(model_operations, params)
Ejemplo n.º 8
0
def test_equal_objects_return_true_with_equal_nested_dicts():
    assert equal_objects({'foo': {
        'bar': 1,
        'buz': 2
    }}, {'foo': {
        'buz': 2,
        'bar': 1
    }})
Ejemplo n.º 9
0
def test_equal_objects_return_true_with_equal_ref_arrays():
    assert equal_objects(
        {'foo': [
            {'id': '1', 'type': 'network', 'ignored_field': 'foo'}
        ]},
        {'foo': [
            {'id': '1', 'type': 'network', 'ignored_field': 'bar'}
        ]}
    )
Ejemplo n.º 10
0
    def edit_object(self, url_path, body_params, path_params=None, query_params=None):
        existing_object = self.send_request(url_path=url_path, http_method=HTTPMethod.GET, path_params=path_params)

        if not existing_object:
            raise FtdConfigurationError('Referenced object does not exist')
        elif equal_objects(existing_object, body_params):
            return existing_object
        else:
            return self.send_request(url_path=url_path, http_method=HTTPMethod.PUT, body_params=body_params,
                                     path_params=path_params, query_params=query_params)
Ejemplo n.º 11
0
def test_equal_objects_return_true_with_different_ref_types():
    assert not equal_objects(
        {'foo': {
            'id': '1',
            'type': 'network',
            'ignored_field': 'foo'
        }}, {'foo': {
            'id': '1',
            'type': 'accessRule',
            'ignored_field': 'bar'
        }})
Ejemplo n.º 12
0
def test_equal_objects_return_true_with_same_object_refs():
    assert equal_objects(
        {'foo': {
            'id': '1',
            'type': 'network',
            'ignored_field': 'foo'
        }}, {'foo': {
            'id': '1',
            'type': 'network',
            'ignored_field': 'bar'
        }})
Ejemplo n.º 13
0
    def edit_object(self, operation_name, params):
        data, dummy, path_params = _get_user_params(params)

        model_name = self.get_operation_spec(operation_name)[OperationField.MODEL_NAME]
        get_operation = self._find_get_operation(model_name)

        if get_operation:
            existing_object = self.send_general_request(get_operation, {ParamName.PATH_PARAMS: path_params})
            if not existing_object:
                raise FtdConfigurationError('Referenced object does not exist')
            elif equal_objects(existing_object, data):
                return existing_object

        return self.send_general_request(operation_name, params)
Ejemplo n.º 14
0
    def _check_equality_with_existing_object(self, operation_name, params, e):
        """
        Looks for an existing object that caused "object duplicate" error and
        checks whether it corresponds to the one specified in `params`.

        In case a single object is found and it is equal to one we are trying
        to create, the existing object is returned.

        When the existing object is not equal to the object being created or
        several objects are returned, an exception is raised.
        """
        model_name = self.get_operation_spec(operation_name)[
            OperationField.MODEL_NAME]
        existing_obj = self._find_object_matching_params(model_name, params)

        if existing_obj is not None:
            if equal_objects(existing_obj, params[ParamName.DATA]):
                return existing_obj
            else:
                raise FtdConfigurationError(DUPLICATE_ERROR, existing_obj)

        raise e
Ejemplo n.º 15
0
def test_equal_objects_return_false_with_different_length():
    assert not equal_objects({'foo': 1}, {'foo': 1, 'bar': 2})
Ejemplo n.º 16
0
def test_equal_objects_return_true_with_ignored_fields():
    assert equal_objects({
        'foo': 1,
        'version': '123',
        'id': '123123'
    }, {'foo': 1})
Ejemplo n.º 17
0
def test_equal_objects_return_true_with_equal_lists():
    assert equal_objects({'foo': ['bar']}, {'foo': ['bar']})
Ejemplo n.º 18
0
def test_equal_objects_return_true_with_equal_objects():
    assert equal_objects({'foo': 1, 'bar': 2}, {'bar': 2, 'foo': 1})
Ejemplo n.º 19
0
def test_equal_objects_return_false_with_different_list_length():
    assert not equal_objects({'foo': []}, {'foo': ['bar']})
Ejemplo n.º 20
0
def test_equal_objects_return_false_with_different_nested_values():
    assert not equal_objects({'foo': {'bar': 1}}, {'foo': {'bar': 2}})
Ejemplo n.º 21
0
def test_equal_objects_return_false_with_different_values():
    assert not equal_objects({'foo': 1}, {'foo': 2})
Ejemplo n.º 22
0
def test_equal_objects_return_false_with_different_fields():
    assert not equal_objects({'foo': 1}, {'bar': 1})
Ejemplo n.º 23
0
def test_equal_objects_return_true_with_equal_str_like_values():
    assert equal_objects({'foo': b'bar'}, {'foo': u'bar'})