def test_module_should_fail_if_validation_error_in_data(self, connection_mock): connection_mock.get_operation_spec.return_value = {'method': HTTPMethod.POST, 'url': '/test'} report = { 'required': ['objects[0].type'], 'invalid_type': [ { 'path': 'objects[3].id', 'expected_type': 'string', 'actually_value': 1 } ] } connection_mock.validate_data.return_value = (False, json.dumps(report, sort_keys=True, indent=4)) with pytest.raises(ValidationError) as e_info: resource = BaseConfigurationResource(connection_mock, False) resource.crud_operation('addTest', {'data': {}}) result = e_info.value.args[0] key = 'Invalid data provided' assert result[key] result[key] = json.loads(result[key]) assert result == {key: { 'invalid_type': [{'actually_value': 1, 'expected_type': 'string', 'path': 'objects[3].id'}], 'required': ['objects[0].type'] }}
def _resource_execute_operation(params, connection): resource = BaseConfigurationResource(connection) op_name = params['operation'] resp = resource.execute_operation(op_name, params) return resp
def main(): fields = dict( operation=dict(type='str', required=True), data=dict(type='dict'), query_params=dict(type='dict'), path_params=dict(type='dict'), register_as=dict(type='str'), filters=dict(type='dict') ) module = AnsibleModule(argument_spec=fields, supports_check_mode=True) params = module.params connection = Connection(module._socket_path) resource = BaseConfigurationResource(connection, module.check_mode) op_name = params['operation'] try: resp = resource.execute_operation(op_name, params) module.exit_json(changed=resource.config_changed, response=resp, ansible_facts=construct_ansible_facts(resp, module.params)) except FtdInvalidOperationNameError as e: module.fail_json(msg='Invalid operation name provided: %s' % e.operation_name) except FtdConfigurationError as e: module.fail_json(msg='Failed to execute %s operation because of the configuration error: %s' % (op_name, e.msg)) except FtdServerError as e: module.fail_json(msg='Server returned an error trying to execute %s operation. Status code: %s. ' 'Server response: %s' % (op_name, e.code, e.response)) except FtdUnexpectedResponse as e: module.fail_json(msg=e.args[0]) except ValidationError as e: module.fail_json(msg=e.args[0]) except CheckModeException: module.exit_json(changed=False)
def test_get_objects_by_filter_with_multiple_responses( self, send_request_mock): send_request_mock.side_effect = [{ 'items': [{ 'name': 'obj1', 'type': 'foo' }, { 'name': 'obj2', 'type': 'bar' }] }, { 'items': [{ 'name': 'obj3', 'type': 'foo' }] }, { 'items': [] }] resource = BaseConfigurationResource(None) assert [{ 'name': 'obj1', 'type': 'foo' }, { 'name': 'obj3', 'type': 'foo' }] == resource.get_objects_by_filter('/objects', {'type': 'foo'})
def setUp(self, fetch_system_info_mock): self._conn = mock.MagicMock() self._resource = BaseConfigurationResource(self._conn) fetch_system_info_mock.return_value = { 'databaseInfo': { 'buildVersion': '6.3.0' } }
def test_get_objects_by_filter_with_multiple_responses(self, send_request_mock, fetch_system_info_mock, connection_mock): send_request_mock.side_effect = [ {'items': [ {'name': 'obj1', 'type': 'foo'}, {'name': 'obj2', 'type': 'bar'} ]}, {'items': [ {'name': 'obj3', 'type': 'foo'} ]}, {'items': []} ] fetch_system_info_mock.return_value = { 'databaseInfo': { 'buildVersion': '6.3.0' } } connection_mock.get_operation_spec.return_value = { 'method': HTTPMethod.GET, 'url': '/object/' } resource = BaseConfigurationResource(connection_mock, False) assert [{'name': 'obj1', 'type': 'foo'}] == list(resource.get_objects_by_filter( 'test', {ParamName.FILTERS: {'type': 'foo'}})) send_request_mock.assert_has_calls( [ mock.call('/object/', 'get', {}, {}, {'limit': 10, 'offset': 0}) ] ) send_request_mock.reset_mock() send_request_mock.side_effect = [ {'items': [ {'name': 'obj1', 'type': 'foo'}, {'name': 'obj2', 'type': 'bar'} ]}, {'items': [ {'name': 'obj3', 'type': 'foo'} ]}, {'items': []} ] resp = list(resource.get_objects_by_filter( 'test', { ParamName.FILTERS: {'type': 'foo'}, ParamName.QUERY_PARAMS: {'limit': 2} })) assert [{'name': 'obj1', 'type': 'foo'}, {'name': 'obj3', 'type': 'foo'}] == resp send_request_mock.assert_has_calls( [ mock.call('/object/', 'get', {}, {}, {'limit': 2, 'offset': 0}), mock.call('/object/', 'get', {}, {}, {'limit': 2, 'offset': 2}) ] )
def test_get_objects_by_filter_with_multiple_filters(self, send_request_mock, fetch_system_info_mock, connection_mock): objects = [ {'name': 'obj1', 'type': 1, 'foo': {'bar': 'buzz'}}, {'name': 'obj2', 'type': 1, 'foo': {'bar': 'buz'}}, {'name': 'obj3', 'type': 2, 'foo': {'bar': 'buzz'}} ] fetch_system_info_mock.return_value = { 'databaseInfo': { 'buildVersion': '6.3.0' } } connection_mock.get_operation_spec.return_value = { 'method': HTTPMethod.GET, 'url': '/object/' } resource = BaseConfigurationResource(connection_mock, False) send_request_mock.side_effect = [{'items': objects}, {'items': []}] # resource.get_objects_by_filter returns generator so to be able compare generated list with expected list # we need evaluate it. assert objects == list(resource.get_objects_by_filter('test', {})) send_request_mock.assert_has_calls( [ mock.call('/object/', 'get', {}, {}, {'limit': 10, 'offset': 0}) ] ) send_request_mock.reset_mock() send_request_mock.side_effect = [{'items': objects}, {'items': []}] # resource.get_objects_by_filter returns generator so to be able compare generated list with expected list # we need evaluate it. assert [objects[0]] == list(resource.get_objects_by_filter('test', {ParamName.FILTERS: {'name': 'obj1'}})) send_request_mock.assert_has_calls( [ mock.call('/object/', 'get', {}, {}, {QueryParams.FILTER: 'name:obj1', 'limit': 10, 'offset': 0}) ] ) send_request_mock.reset_mock() send_request_mock.side_effect = [{'items': objects}, {'items': []}] # resource.get_objects_by_filter returns generator so to be able compare generated list with expected list # we need evaluate it. assert [objects[1]] == list(resource.get_objects_by_filter( 'test', {ParamName.FILTERS: {'name': 'obj2', 'type': 1, 'foo': {'bar': 'buz'}}})) send_request_mock.assert_has_calls( [ mock.call('/object/', 'get', {}, {}, {QueryParams.FILTER: 'name:obj2', 'limit': 10, 'offset': 0}) ] )
def test_stringify_name_filter(self, test_api_version, expected_result, connection_mock): filters = {"name": "object_name"} with patch.object(BaseConfigurationResource, '_fetch_system_info') as fetch_system_info_mock: fetch_system_info_mock.return_value = { 'databaseInfo': { 'buildVersion': test_api_version } } resource = BaseConfigurationResource(connection_mock, False) assert resource._stringify_name_filter(filters) == expected_result, "Unexpected result for version %s" % ( test_api_version)
def _resource_execute_operation(params, connection): with mock.patch.object(BaseConfigurationResource, '_fetch_system_info') as fetch_system_info_mock: fetch_system_info_mock.return_value = { 'databaseInfo': { 'buildVersion': '6.3.0' } } resource = BaseConfigurationResource(connection) op_name = params['operation'] resp = resource.execute_operation(op_name, params) return resp
def main(): fields = dict(device_hostname=dict(type='str', required=True), device_username=dict(type='str', required=False, default='admin'), device_password=dict(type='str', required=True, no_log=True), device_sudo_password=dict(type='str', required=False, no_log=True), device_new_password=dict(type='str', required=False, no_log=True), device_ip=dict(type='str', required=False), device_netmask=dict(type='str', required=False), device_gateway=dict(type='str', required=False), device_model=dict(type='str', required=False, choices=FtdModel.supported_models()), dns_server=dict(type='str', required=False), search_domains=dict(type='str', required=False, default='cisco.com'), console_ip=dict(type='str', required=True), console_port=dict(type='str', required=True), console_username=dict(type='str', required=True), console_password=dict(type='str', required=True, no_log=True), rommon_file_location=dict(type='str', required=True), image_file_location=dict(type='str', required=True), image_version=dict(type='str', required=True), force_install=dict(type='bool', required=False, default=False)) module = AnsibleModule(argument_spec=fields) assert_kick_is_installed(module) use_local_connection = module._socket_path is None if use_local_connection: check_required_params_for_local_connection(module, module.params) platform_model = module.params['device_model'] check_that_model_is_supported(module, platform_model) else: connection = Connection(module._socket_path) resource = BaseConfigurationResource(connection, module.check_mode) system_info = get_system_info(resource) platform_model = module.params['device_model'] or system_info[ 'platformModel'] check_that_model_is_supported(module, platform_model) check_that_update_is_needed(module, system_info) check_management_and_dns_params(resource, module.params) ftd_platform = FtdPlatformFactory.create(platform_model, module.params) ftd_platform.install_ftd_image(module.params) module.exit_json( changed=True, msg='Successfully installed FTD image %s on the firewall device.' % module.params["image_version"])
def test_get_objects_by_filter_with_multiple_filters(self, send_request_mock): objects = [ {'name': 'obj1', 'type': 1, 'foo': {'bar': 'buzz'}}, {'name': 'obj2', 'type': 1, 'foo': {'bar': 'buz'}}, {'name': 'obj3', 'type': 2, 'foo': {'bar': 'buzz'}} ] resource = BaseConfigurationResource(None) send_request_mock.side_effect = [{'items': objects}, {'items': []}] assert objects == resource.get_objects_by_filter('/objects', {}) send_request_mock.side_effect = [{'items': objects}, {'items': []}] assert [objects[0]] == resource.get_objects_by_filter('/objects', {'name': 'obj1'}) send_request_mock.side_effect = [{'items': objects}, {'items': []}] assert [objects[1]] == resource.get_objects_by_filter('/objects', {'type': 1, 'foo': {'bar': 'buz'}})
def main(): fields = dict(operation=dict(type='str', required=True), data=dict(type='dict'), query_params=dict(type='dict'), path_params=dict(type='dict'), register_as=dict(type='str'), filters=dict(type='dict')) module = AnsibleModule(argument_spec=fields, supports_check_mode=True) params = module.params connection = Connection(module._socket_path) op_name = params['operation'] op_spec = connection.get_operation_spec(op_name) if op_spec is None: module.fail_json(msg='Invalid operation name provided: %s' % op_name) data, query_params, path_params = params['data'], params[ 'query_params'], params['path_params'] try: validate_params(connection, op_name, query_params, path_params, data, op_spec) except ValidationError as e: module.fail_json(msg=e.args[0]) try: if module.check_mode: module.exit_json(changed=False) resource = BaseConfigurationResource(connection) url = op_spec[OperationField.URL] if is_add_operation(op_name, op_spec): resp = resource.add_object(url, data, path_params, query_params) elif is_edit_operation(op_name, op_spec): resp = resource.edit_object(url, data, path_params, query_params) elif is_delete_operation(op_name, op_spec): resp = resource.delete_object(url, path_params) elif is_find_by_filter_operation(op_name, op_spec, params): resp = resource.get_objects_by_filter(url, params['filters'], path_params, query_params) else: resp = resource.send_request(url, op_spec[OperationField.METHOD], data, path_params, query_params) module.exit_json(changed=resource.config_changed, response=resp, ansible_facts=construct_ansible_facts( resp, module.params)) except FtdConfigurationError as e: module.fail_json( msg= 'Failed to execute %s operation because of the configuration error: %s' % (op_name, e)) except FtdServerError as e: module.fail_json( msg= 'Server returned an error trying to execute %s operation. Status code: %s. ' 'Server response: %s' % (op_name, e.code, e.response))
def test_module_should_fail_if_validation_error_in_all_params( self, connection_mock): connection_mock.get_operation_spec.return_value = { 'method': HTTPMethod.POST, 'url': '/test' } report = { 'data': { 'required': ['objects[0].type'], 'invalid_type': [{ 'path': 'objects[3].id', 'expected_type': 'string', 'actually_value': 1 }] }, 'path_params': { 'required': ['some_param'], 'invalid_type': [{ 'path': 'name', 'expected_type': 'string', 'actually_value': True }] }, 'query_params': { 'required': ['other_param'], 'invalid_type': [{ 'path': 'f_integer', 'expected_type': 'integer', 'actually_value': "test" }] } } connection_mock.validate_data.return_value = (False, json.dumps( report['data'], sort_keys=True, indent=4)) connection_mock.validate_query_params.return_value = ( False, json.dumps(report['query_params'], sort_keys=True, indent=4)) connection_mock.validate_path_params.return_value = ( False, json.dumps(report['path_params'], sort_keys=True, indent=4)) with pytest.raises(ValidationError) as e_info: resource = BaseConfigurationResource(connection_mock, False) resource.crud_operation('putTest', {'data': {}}) result = e_info.value.args[0] key_data = 'Invalid data provided' assert result[key_data] result[key_data] = json.loads(result[key_data]) key_path_params = 'Invalid path_params provided' assert result[key_path_params] result[key_path_params] = json.loads(result[key_path_params]) key_query_params = 'Invalid query_params provided' assert result[key_query_params] result[key_query_params] = json.loads(result[key_query_params]) assert result == { key_data: { 'invalid_type': [{ 'actually_value': 1, 'expected_type': 'string', 'path': 'objects[3].id' }], 'required': ['objects[0].type'] }, key_path_params: { 'invalid_type': [{ 'actually_value': True, 'expected_type': 'string', 'path': 'name' }], 'required': ['some_param'] }, key_query_params: { 'invalid_type': [{ 'actually_value': 'test', 'expected_type': 'integer', 'path': 'f_integer' }], 'required': ['other_param'] } }
def setUp(self): self._conn = mock.MagicMock() self._resource = BaseConfigurationResource(self._conn)
class TestUpsertOperationUnitTests(unittest.TestCase): def setUp(self): self._conn = mock.MagicMock() self._resource = BaseConfigurationResource(self._conn) def test_get_operation_name(self): operation_a = mock.MagicMock() operation_b = mock.MagicMock() def checker_wrapper(expected_object): def checker(obj, *args, **kwargs): return obj == expected_object return checker operations = { operation_a: "spec", operation_b: "spec" } assert operation_a == self._resource._get_operation_name(checker_wrapper(operation_a), operations) assert operation_b == self._resource._get_operation_name(checker_wrapper(operation_b), operations) assert self._resource._get_operation_name(checker_wrapper(None), operations) is None @mock.patch.object(BaseConfigurationResource, "_get_operation_name") @mock.patch.object(BaseConfigurationResource, "add_object") def test_add_upserted_object(self, add_object_mock, get_operation_mock): model_operations = mock.MagicMock() params = mock.MagicMock() add_op_name = get_operation_mock.return_value assert add_object_mock.return_value == self._resource._add_upserted_object(model_operations, params) get_operation_mock.assert_called_once_with( self._resource._operation_checker.is_add_operation, model_operations) add_object_mock.assert_called_once_with(add_op_name, params) @mock.patch.object(BaseConfigurationResource, "_get_operation_name") @mock.patch.object(BaseConfigurationResource, "add_object") def test_add_upserted_object_with_no_add_operation(self, add_object_mock, get_operation_mock): model_operations = mock.MagicMock() get_operation_mock.return_value = None with pytest.raises(FtdConfigurationError) as exc_info: self._resource._add_upserted_object(model_operations, mock.MagicMock()) assert ADD_OPERATION_NOT_SUPPORTED_ERROR in str(exc_info.value) get_operation_mock.assert_called_once_with(self._resource._operation_checker.is_add_operation, model_operations) add_object_mock.assert_not_called() @mock.patch.object(BaseConfigurationResource, "_get_operation_name") @mock.patch.object(BaseConfigurationResource, "edit_object") @mock.patch("ansible.module_utils.network.ftd.configuration.copy_identity_properties") @mock.patch("ansible.module_utils.network.ftd.configuration._set_default") def test_edit_upserted_object(self, _set_default_mock, copy_properties_mock, edit_object_mock, get_operation_mock): model_operations = mock.MagicMock() existing_object = mock.MagicMock() params = { 'path_params': {}, 'data': {} } result = self._resource._edit_upserted_object(model_operations, existing_object, params) assert result == edit_object_mock.return_value _set_default_mock.assert_has_calls([ mock.call(params, 'path_params', {}), mock.call(params, 'data', {}) ]) get_operation_mock.assert_called_once_with( self._resource._operation_checker.is_edit_operation, model_operations ) copy_properties_mock.assert_called_once_with( existing_object, params['data'] ) edit_object_mock.assert_called_once_with( get_operation_mock.return_value, params ) @mock.patch("ansible.module_utils.network.ftd.configuration.OperationChecker.is_upsert_operation_supported") @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name") @mock.patch.object(BaseConfigurationResource, "_find_object_matching_params") @mock.patch.object(BaseConfigurationResource, "_add_upserted_object") @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object") def test_upsert_object_successfully_added(self, edit_mock, add_mock, find_object, get_operation_mock, is_upsert_supported_mock): params = mock.MagicMock() is_upsert_supported_mock.return_value = True find_object.return_value = None result = self._resource.upsert_object('upsertFoo', params) assert result == add_mock.return_value self._conn.get_model_spec.assert_called_once_with('Foo') is_upsert_supported_mock.assert_called_once_with(get_operation_mock.return_value) get_operation_mock.assert_called_once_with('Foo') find_object.assert_called_once_with('Foo', params) add_mock.assert_called_once_with(get_operation_mock.return_value, params) edit_mock.assert_not_called() @mock.patch("ansible.module_utils.network.ftd.configuration.equal_objects") @mock.patch("ansible.module_utils.network.ftd.configuration.OperationChecker.is_upsert_operation_supported") @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name") @mock.patch.object(BaseConfigurationResource, "_find_object_matching_params") @mock.patch.object(BaseConfigurationResource, "_add_upserted_object") @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object") def test_upsert_object_successfully_edited(self, edit_mock, add_mock, find_object, get_operation_mock, is_upsert_supported_mock, equal_objects_mock): params = mock.MagicMock() existing_obj = mock.MagicMock() is_upsert_supported_mock.return_value = True find_object.return_value = existing_obj equal_objects_mock.return_value = False result = self._resource.upsert_object('upsertFoo', params) assert result == edit_mock.return_value self._conn.get_model_spec.assert_called_once_with('Foo') get_operation_mock.assert_called_once_with('Foo') is_upsert_supported_mock.assert_called_once_with(get_operation_mock.return_value) add_mock.assert_not_called() equal_objects_mock.assert_called_once_with(existing_obj, params[ParamName.DATA]) edit_mock.assert_called_once_with(get_operation_mock.return_value, existing_obj, params) @mock.patch("ansible.module_utils.network.ftd.configuration.equal_objects") @mock.patch("ansible.module_utils.network.ftd.configuration.OperationChecker.is_upsert_operation_supported") @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name") @mock.patch.object(BaseConfigurationResource, "_find_object_matching_params") @mock.patch.object(BaseConfigurationResource, "_add_upserted_object") @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object") def test_upsert_object_returned_without_modifications(self, edit_mock, add_mock, find_object, get_operation_mock, is_upsert_supported_mock, equal_objects_mock): params = mock.MagicMock() existing_obj = mock.MagicMock() is_upsert_supported_mock.return_value = True find_object.return_value = existing_obj equal_objects_mock.return_value = True result = self._resource.upsert_object('upsertFoo', params) assert result == existing_obj self._conn.get_model_spec.assert_called_once_with('Foo') get_operation_mock.assert_called_once_with('Foo') is_upsert_supported_mock.assert_called_once_with(get_operation_mock.return_value) add_mock.assert_not_called() equal_objects_mock.assert_called_once_with(existing_obj, params[ParamName.DATA]) edit_mock.assert_not_called() @mock.patch("ansible.module_utils.network.ftd.configuration.OperationChecker.is_upsert_operation_supported") @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name") @mock.patch.object(BaseConfigurationResource, "_find_object_matching_params") @mock.patch.object(BaseConfigurationResource, "_add_upserted_object") @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object") def test_upsert_object_not_supported(self, edit_mock, add_mock, find_object, get_operation_mock, is_upsert_supported_mock): params = mock.MagicMock() is_upsert_supported_mock.return_value = False self.assertRaises( FtdInvalidOperationNameError, self._resource.upsert_object, 'upsertFoo', params ) self._conn.get_model_spec.assert_called_once_with('Foo') get_operation_mock.assert_called_once_with('Foo') is_upsert_supported_mock.assert_called_once_with(get_operation_mock.return_value) find_object.assert_not_called() add_mock.assert_not_called() edit_mock.assert_not_called() @mock.patch("ansible.module_utils.network.ftd.configuration.OperationChecker.is_upsert_operation_supported") @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name") @mock.patch.object(BaseConfigurationResource, "_find_object_matching_params") @mock.patch.object(BaseConfigurationResource, "_add_upserted_object") @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object") def test_upsert_object_when_model_not_supported(self, edit_mock, add_mock, find_object, get_operation_mock, is_upsert_supported_mock): params = mock.MagicMock() self._conn.get_model_spec.return_value = None self.assertRaises( FtdInvalidOperationNameError, self._resource.upsert_object, 'upsertNonExisting', params ) self._conn.get_model_spec.assert_called_once_with('NonExisting') get_operation_mock.assert_not_called() is_upsert_supported_mock.assert_not_called() find_object.assert_not_called() add_mock.assert_not_called() edit_mock.assert_not_called() @mock.patch("ansible.module_utils.network.ftd.configuration.equal_objects") @mock.patch("ansible.module_utils.network.ftd.configuration.OperationChecker.is_upsert_operation_supported") @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name") @mock.patch.object(BaseConfigurationResource, "_find_object_matching_params") @mock.patch.object(BaseConfigurationResource, "_add_upserted_object") @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object") def test_upsert_object_with_fatal_error_during_edit(self, edit_mock, add_mock, find_object, get_operation_mock, is_upsert_supported_mock, equal_objects_mock): params = mock.MagicMock() existing_obj = mock.MagicMock() is_upsert_supported_mock.return_value = True find_object.return_value = existing_obj equal_objects_mock.return_value = False edit_mock.side_effect = FtdConfigurationError("Some object edit error") self.assertRaises( FtdConfigurationError, self._resource.upsert_object, 'upsertFoo', params ) is_upsert_supported_mock.assert_called_once_with(get_operation_mock.return_value) self._conn.get_model_spec.assert_called_once_with('Foo') get_operation_mock.assert_called_once_with('Foo') find_object.assert_called_once_with('Foo', params) add_mock.assert_not_called() edit_mock.assert_called_once_with(get_operation_mock.return_value, existing_obj, params) @mock.patch("ansible.module_utils.network.ftd.configuration.OperationChecker.is_upsert_operation_supported") @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name") @mock.patch.object(BaseConfigurationResource, "_find_object_matching_params") @mock.patch.object(BaseConfigurationResource, "_add_upserted_object") @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object") def test_upsert_object_with_fatal_error_during_add(self, edit_mock, add_mock, find_object, get_operation_mock, is_upsert_supported_mock): params = mock.MagicMock() is_upsert_supported_mock.return_value = True find_object.return_value = None error = FtdConfigurationError("Obj duplication error") add_mock.side_effect = error self.assertRaises( FtdConfigurationError, self._resource.upsert_object, 'upsertFoo', params ) is_upsert_supported_mock.assert_called_once_with(get_operation_mock.return_value) self._conn.get_model_spec.assert_called_once_with('Foo') get_operation_mock.assert_called_once_with('Foo') find_object.assert_called_once_with('Foo', params) add_mock.assert_called_once_with(get_operation_mock.return_value, params) edit_mock.assert_not_called()
class TestUpsertOperationUnitTests(unittest.TestCase): def setUp(self): conn = mock.MagicMock() self._resource = BaseConfigurationResource(conn) def test_get_operation_name(self): operation_a = mock.MagicMock() operation_b = mock.MagicMock() def checker_wrapper(expected_object): def checker(obj, *args, **kwargs): return obj == expected_object return checker operations = { operation_a: "spec", operation_b: "spec" } assert operation_a == self._resource._get_operation_name(checker_wrapper(operation_a), operations) assert operation_b == self._resource._get_operation_name(checker_wrapper(operation_b), operations) self.assertRaises( FtdConfigurationError, self._resource._get_operation_name, checker_wrapper(None), operations ) @mock.patch.object(BaseConfigurationResource, "_get_operation_name") @mock.patch.object(BaseConfigurationResource, "add_object") def test_add_upserted_object(self, add_object_mock, get_operation_mock): model_operations = mock.MagicMock() params = mock.MagicMock() add_op_name = get_operation_mock.return_value assert add_object_mock.return_value == self._resource._add_upserted_object(model_operations, params) get_operation_mock.assert_called_once_with( self._resource._operation_checker.is_add_operation, model_operations) add_object_mock.assert_called_once_with(add_op_name, params) @mock.patch.object(BaseConfigurationResource, "_get_operation_name") @mock.patch.object(BaseConfigurationResource, "edit_object") @mock.patch("ansible.module_utils.network.ftd.configuration.copy_identity_properties") @mock.patch("ansible.module_utils.network.ftd.configuration._set_default") def test_edit_upserted_object(self, _set_default_mock, copy_properties_mock, edit_object_mock, get_operation_mock): model_operations = mock.MagicMock() existing_object = mock.MagicMock() params = { 'path_params': {}, 'data': {} } result = self._resource._edit_upserted_object(model_operations, existing_object, params) assert result == edit_object_mock.return_value _set_default_mock.assert_has_calls([ mock.call(params, 'path_params', {}), mock.call(params, 'data', {}) ]) get_operation_mock.assert_called_once_with( self._resource._operation_checker.is_edit_operation, model_operations ) copy_properties_mock.assert_called_once_with( existing_object, params['data'] ) edit_object_mock.assert_called_once_with( get_operation_mock.return_value, params ) @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name") @mock.patch("ansible.module_utils.network.ftd.configuration.OperationChecker.is_upsert_operation_supported") @mock.patch("ansible.module_utils.network.ftd.configuration._extract_model_from_upsert_operation") def test_is_upsert_operation_supported(self, extract_model_mock, is_upsert_supported_mock, get_operation_spec_mock): op_name = mock.MagicMock() result = self._resource.is_upsert_operation_supported(op_name) assert result == is_upsert_supported_mock.return_value extract_model_mock.assert_called_once_with(op_name) get_operation_spec_mock.assert_called_once_with(extract_model_mock.return_value) is_upsert_supported_mock.assert_called_once_with(get_operation_spec_mock.return_value) @mock.patch.object(BaseConfigurationResource, "is_upsert_operation_supported") @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name") @mock.patch.object(BaseConfigurationResource, "_add_upserted_object") @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object") @mock.patch("ansible.module_utils.network.ftd.configuration._extract_model_from_upsert_operation") def test_upsert_object_succesfully_added(self, extract_model_mock, edit_mock, add_mock, get_operation_mock, is_upsert_supported_mock): op_name = mock.MagicMock() params = mock.MagicMock() is_upsert_supported_mock.return_value = True result = self._resource.upsert_object(op_name, params) assert result == add_mock.return_value is_upsert_supported_mock.assert_called_once_with(op_name) extract_model_mock.assert_called_once_with(op_name) get_operation_mock.assert_called_once_with(extract_model_mock.return_value) add_mock.assert_called_once_with(get_operation_mock.return_value, params) edit_mock.assert_not_called() @mock.patch.object(BaseConfigurationResource, "is_upsert_operation_supported") @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name") @mock.patch.object(BaseConfigurationResource, "_add_upserted_object") @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object") @mock.patch("ansible.module_utils.network.ftd.configuration._extract_model_from_upsert_operation") def test_upsert_object_succesfully_edited(self, extract_model_mock, edit_mock, add_mock, get_operation_mock, is_upsert_supported_mock): op_name = mock.MagicMock() params = mock.MagicMock() is_upsert_supported_mock.return_value = True error = FtdConfigurationError("Obj duplication error") error.obj = mock.MagicMock() add_mock.side_effect = error result = self._resource.upsert_object(op_name, params) assert result == edit_mock.return_value is_upsert_supported_mock.assert_called_once_with(op_name) extract_model_mock.assert_called_once_with(op_name) get_operation_mock.assert_called_once_with(extract_model_mock.return_value) add_mock.assert_called_once_with(get_operation_mock.return_value, params) edit_mock.assert_called_once_with(get_operation_mock.return_value, error.obj, params) @mock.patch.object(BaseConfigurationResource, "is_upsert_operation_supported") @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name") @mock.patch.object(BaseConfigurationResource, "_add_upserted_object") @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object") @mock.patch("ansible.module_utils.network.ftd.configuration._extract_model_from_upsert_operation") def test_upsert_object_not_supported(self, extract_model_mock, edit_mock, add_mock, get_operation_mock, is_upsert_supported_mock): op_name = mock.MagicMock() params = mock.MagicMock() is_upsert_supported_mock.return_value = False self.assertRaises( FtdInvalidOperationNameError, self._resource.upsert_object, op_name, params ) is_upsert_supported_mock.assert_called_once_with(op_name) extract_model_mock.assert_not_called() get_operation_mock.assert_not_called() add_mock.assert_not_called() edit_mock.assert_not_called() @mock.patch.object(BaseConfigurationResource, "is_upsert_operation_supported") @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name") @mock.patch.object(BaseConfigurationResource, "_add_upserted_object") @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object") @mock.patch("ansible.module_utils.network.ftd.configuration._extract_model_from_upsert_operation") def test_upsert_object_neither_added_nor_edited(self, extract_model_mock, edit_mock, add_mock, get_operation_mock, is_upsert_supported_mock): op_name = mock.MagicMock() params = mock.MagicMock() is_upsert_supported_mock.return_value = True error = FtdConfigurationError("Obj duplication error") error.obj = mock.MagicMock() add_mock.side_effect = error edit_mock.side_effect = FtdConfigurationError("Some object edit error") self.assertRaises( FtdConfigurationError, self._resource.upsert_object, op_name, params ) is_upsert_supported_mock.assert_called_once_with(op_name) extract_model_mock.assert_called_once_with(op_name) get_operation_mock.assert_called_once_with(extract_model_mock.return_value) add_mock.assert_called_once_with(get_operation_mock.return_value, params) edit_mock.assert_called_once_with(get_operation_mock.return_value, error.obj, params) @mock.patch.object(BaseConfigurationResource, "is_upsert_operation_supported") @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name") @mock.patch.object(BaseConfigurationResource, "_add_upserted_object") @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object") @mock.patch("ansible.module_utils.network.ftd.configuration._extract_model_from_upsert_operation") def test_upsert_object_with_fatal_error_during_add(self, extract_model_mock, edit_mock, add_mock, get_operation_mock, is_upsert_supported_mock): op_name = mock.MagicMock() params = mock.MagicMock() is_upsert_supported_mock.return_value = True error = FtdConfigurationError("Obj duplication error") add_mock.side_effect = error self.assertRaises( FtdConfigurationError, self._resource.upsert_object, op_name, params ) is_upsert_supported_mock.assert_called_once_with(op_name) extract_model_mock.assert_called_once_with(op_name) get_operation_mock.assert_called_once_with(extract_model_mock.return_value) add_mock.assert_called_once_with(get_operation_mock.return_value, params) edit_mock.assert_not_called()