# Copyright (c) 2014 Alex Meade # Copyright (c) 2015 Yogesh Kshirsagar # Copyright (c) 2015 Michael Price # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import copy import ddt import mock from cinder import exception from cinder import test from cinder.tests.unit.volume.drivers.netapp.eseries import fakes as \ eseries_fake from cinder.volume.drivers.netapp.eseries import exception as es_exception from cinder.volume.drivers.netapp.eseries import client from cinder.volume.drivers.netapp import utils as na_utils @ddt.ddt class NetAppEseriesClientDriverTestCase(test.TestCase): """Test case for NetApp e-series client.""" def setUp(self): super(NetAppEseriesClientDriverTestCase, self).setUp() self.mock_log = mock.Mock() self.mock_object(client, 'LOG', self.mock_log) self.fake_password = 'mysecret' self.my_client = client.RestClient('http', 'host', '80', '/test', 'user', self.fake_password, system_id='fake_sys_id') self.my_client._endpoint = eseries_fake.FAKE_ENDPOINT_HTTP fake_response = mock.Mock() fake_response.status_code = 200 self.my_client.invoke_service = mock.Mock(return_value=fake_response) self.my_client.api_version = '01.52.9000.1' @ddt.data(200, 201, 203, 204) def test_eval_response_success(self, status_code): fake_resp = mock.Mock() fake_resp.status_code = status_code self.assertIsNone(self.my_client._eval_response(fake_resp)) @ddt.data(300, 400, 404, 500) def test_eval_response_failure(self, status_code): fake_resp = mock.Mock() fake_resp.status_code = status_code expected_msg = "Response error code - %s." % status_code with self.assertRaisesRegex(es_exception.WebServiceException, expected_msg) as exc: self.my_client._eval_response(fake_resp) self.assertEqual(status_code, exc.status_code) def test_eval_response_422(self): status_code = 422 resp_text = "Fake Error Message" fake_resp = mock.Mock() fake_resp.status_code = status_code fake_resp.text = resp_text expected_msg = "Response error - %s." % resp_text with self.assertRaisesRegex(es_exception.WebServiceException, expected_msg) as exc: self.my_client._eval_response(fake_resp) self.assertEqual(status_code, exc.status_code) def test_register_storage_system_does_not_log_password(self): self.my_client._eval_response = mock.Mock() self.my_client.register_storage_system([], password=self.fake_password) for call in self.mock_log.debug.mock_calls: __, args, __ = call self.assertNotIn(self.fake_password, args[0]) def test_update_stored_system_password_does_not_log_password(self): self.my_client._eval_response = mock.Mock() self.my_client.update_stored_system_password( password=self.fake_password) for call in self.mock_log.debug.mock_calls: __, args, __ = call self.assertNotIn(self.fake_password, args[0]) def test_list_target_wwpns(self): fake_hardware_inventory = copy.deepcopy( eseries_fake.HARDWARE_INVENTORY) mock_hardware_inventory = mock.Mock( return_value=fake_hardware_inventory) self.mock_object(self.my_client, 'list_hardware_inventory', mock_hardware_inventory) expected_wwpns = [eseries_fake.WWPN, eseries_fake.WWPN_2] actual_wwpns = self.my_client.list_target_wwpns() self.assertEqual(expected_wwpns, actual_wwpns) def test_list_target_wwpns_single_wwpn(self): fake_hardware_inventory = copy.deepcopy( eseries_fake.HARDWARE_INVENTORY) fake_hardware_inventory['fibrePorts'] = [ fake_hardware_inventory['fibrePorts'][0] ] mock_hardware_inventory = mock.Mock( return_value=fake_hardware_inventory) self.mock_object(self.my_client, 'list_hardware_inventory', mock_hardware_inventory) expected_wwpns = [eseries_fake.WWPN] actual_wwpns = self.my_client.list_target_wwpns() self.assertEqual(expected_wwpns, actual_wwpns) def test_list_target_wwpns_no_wwpn(self): fake_hardware_inventory = copy.deepcopy( eseries_fake.HARDWARE_INVENTORY) fake_hardware_inventory['fibrePorts'] = [] mock_hardware_inventory = mock.Mock( return_value=fake_hardware_inventory) self.mock_object(self.my_client, 'list_hardware_inventory', mock_hardware_inventory) expected_wwpns = [] actual_wwpns = self.my_client.list_target_wwpns() self.assertEqual(expected_wwpns, actual_wwpns) def test_create_host_from_ports_fc(self): label = 'fake_host' host_type = 'linux' port_type = 'fc' port_ids = [eseries_fake.WWPN, eseries_fake.WWPN_2] expected_ports = [ {'type': port_type, 'port': eseries_fake.WWPN, 'label': mock.ANY}, {'type': port_type, 'port': eseries_fake.WWPN_2, 'label': mock.ANY}] mock_create_host = self.mock_object(self.my_client, 'create_host') self.my_client.create_host_with_ports(label, host_type, port_ids, port_type) mock_create_host.assert_called_once_with(label, host_type, expected_ports, None) def test_host_from_ports_with_no_ports_provided_fc(self): label = 'fake_host' host_type = 'linux' port_type = 'fc' port_ids = [] expected_ports = [] mock_create_host = self.mock_object(self.my_client, 'create_host') self.my_client.create_host_with_ports(label, host_type, port_ids, port_type) mock_create_host.assert_called_once_with(label, host_type, expected_ports, None) def test_create_host_from_ports_iscsi(self): label = 'fake_host' host_type = 'linux' port_type = 'iscsi' port_ids = [eseries_fake.INITIATOR_NAME, eseries_fake.INITIATOR_NAME_2] expected_ports = [ {'type': port_type, 'port': eseries_fake.INITIATOR_NAME, 'label': mock.ANY}, {'type': port_type, 'port': eseries_fake.INITIATOR_NAME_2, 'label': mock.ANY}] mock_create_host = self.mock_object(self.my_client, 'create_host') self.my_client.create_host_with_ports(label, host_type, port_ids, port_type) mock_create_host.assert_called_once_with(label, host_type, expected_ports, None) def test_get_volume_mappings_for_volume(self): volume_mapping_1 = copy.deepcopy(eseries_fake.VOLUME_MAPPING) volume_mapping_2 = copy.deepcopy(eseries_fake.VOLUME_MAPPING) volume_mapping_2['volumeRef'] = '2' self.mock_object(self.my_client, 'get_volume_mappings', mock.Mock(return_value=[volume_mapping_1, volume_mapping_2])) mappings = self.my_client.get_volume_mappings_for_volume( eseries_fake.VOLUME) self.assertEqual([volume_mapping_1], mappings) def test_get_volume_mappings_for_host(self): volume_mapping_1 = copy.deepcopy( eseries_fake.VOLUME_MAPPING) volume_mapping_2 = copy.deepcopy(eseries_fake.VOLUME_MAPPING) volume_mapping_2['volumeRef'] = '2' volume_mapping_2['mapRef'] = 'hostRef' self.mock_object(self.my_client, 'get_volume_mappings', mock.Mock(return_value=[volume_mapping_1, volume_mapping_2])) mappings = self.my_client.get_volume_mappings_for_host( 'hostRef') self.assertEqual([volume_mapping_2], mappings) def test_get_volume_mappings_for_hostgroup(self): volume_mapping_1 = copy.deepcopy( eseries_fake.VOLUME_MAPPING) volume_mapping_2 = copy.deepcopy(eseries_fake.VOLUME_MAPPING) volume_mapping_2['volumeRef'] = '2' volume_mapping_2['mapRef'] = 'hostGroupRef' self.mock_object(self.my_client, 'get_volume_mappings', mock.Mock(return_value=[volume_mapping_1, volume_mapping_2])) mappings = self.my_client.get_volume_mappings_for_host_group( 'hostGroupRef') self.assertEqual([volume_mapping_2], mappings) def test_to_pretty_dict_string(self): dict = { 'foo': 'bar', 'fu': { 'nested': 'boo' } } expected_dict_string = ("""{ "foo": "bar", "fu": { "nested": "boo" } }""") dict_string = self.my_client._to_pretty_dict_string(dict) self.assertEqual(expected_dict_string, dict_string) def test_log_http_request(self): mock_log = self.mock_object(client, 'LOG') verb = "POST" url = "/v2/test/me" headers = {"Content-Type": "application/json"} headers_string = """{ "Content-Type": "application/json" }""" body = {} body_string = "{}" self.my_client._log_http_request(verb, url, headers, body) args = mock_log.debug.call_args log_message, log_params = args[0] final_msg = log_message % log_params self.assertIn(verb, final_msg) self.assertIn(url, final_msg) self.assertIn(headers_string, final_msg) self.assertIn(body_string, final_msg) def test_log_http_request_no_body(self): mock_log = self.mock_object(client, 'LOG') verb = "POST" url = "/v2/test/me" headers = {"Content-Type": "application/json"} headers_string = """{ "Content-Type": "application/json" }""" body = None body_string = "" self.my_client._log_http_request(verb, url, headers, body) args = mock_log.debug.call_args log_message, log_params = args[0] final_msg = log_message % log_params self.assertIn(verb, final_msg) self.assertIn(url, final_msg) self.assertIn(headers_string, final_msg) self.assertIn(body_string, final_msg) def test_log_http_response(self): mock_log = self.mock_object(client, 'LOG') status = "200" headers = {"Content-Type": "application/json"} headers_string = """{ "Content-Type": "application/json" }""" body = {} body_string = "{}" self.my_client._log_http_response(status, headers, body) args = mock_log.debug.call_args log_message, log_params = args[0] final_msg = log_message % log_params self.assertIn(status, final_msg) self.assertIn(headers_string, final_msg) self.assertIn(body_string, final_msg) def test_log_http_response_no_body(self): mock_log = self.mock_object(client, 'LOG') status = "200" headers = {"Content-Type": "application/json"} headers_string = """{ "Content-Type": "application/json" }""" body = None body_string = "" self.my_client._log_http_response(status, headers, body) args = mock_log.debug.call_args log_message, log_params = args[0] final_msg = log_message % log_params self.assertIn(status, final_msg) self.assertIn(headers_string, final_msg) self.assertIn(body_string, final_msg) def test_add_autosupport_data(self): self.mock_object( client.RestClient, 'get_eseries_api_info', mock.Mock(return_value=( eseries_fake.FAKE_ASUP_DATA['operating-mode'], eseries_fake.FAKE_ABOUT_RESPONSE['version']))) self.mock_object( self.my_client, 'get_firmware_version', mock.Mock( return_value=eseries_fake.FAKE_ABOUT_RESPONSE['version'])) self.mock_object( self.my_client, 'get_serial_numbers', mock.Mock(return_value=eseries_fake.FAKE_SERIAL_NUMBERS)) self.mock_object( self.my_client, 'get_model_name', mock.Mock( return_value=eseries_fake.FAKE_CONTROLLERS[0]['modelName'])) self.mock_object( self.my_client, 'set_counter', mock.Mock(return_value={'value': 1})) mock_invoke = self.mock_object( self.my_client, '_invoke', mock.Mock(return_value=eseries_fake.FAKE_ASUP_DATA)) client.RestClient.add_autosupport_data( self.my_client, eseries_fake.FAKE_KEY, eseries_fake.FAKE_ASUP_DATA ) mock_invoke.assert_called_with(*eseries_fake.FAKE_POST_INVOKE_DATA) @ddt.data((eseries_fake.FAKE_SERIAL_NUMBERS, eseries_fake.FAKE_CONTROLLERS), (eseries_fake.FAKE_DEFAULT_SERIAL_NUMBER, []), (eseries_fake.FAKE_SERIAL_NUMBER, eseries_fake.FAKE_SINGLE_CONTROLLER)) @ddt.unpack def test_get_serial_numbers(self, expected_serial_numbers, controllers): self.mock_object( client.RestClient, '_get_controllers', mock.Mock(return_value=controllers)) serial_numbers = client.RestClient.get_serial_numbers(self.my_client) self.assertEqual(expected_serial_numbers, serial_numbers) def test_get_model_name(self): self.mock_object( client.RestClient, '_get_controllers', mock.Mock(return_value=eseries_fake.FAKE_CONTROLLERS)) model = client.RestClient.get_model_name(self.my_client) self.assertEqual(eseries_fake.FAKE_CONTROLLERS[0]['modelName'], model) def test_get_model_name_empty_controllers_list(self): self.mock_object( client.RestClient, '_get_controllers', mock.Mock(return_value=[])) model = client.RestClient.get_model_name(self.my_client) self.assertEqual(eseries_fake.FAKE_DEFAULT_MODEL, model) def test_get_eseries_api_info(self): fake_invoke_service = mock.Mock() fake_invoke_service.json = mock.Mock( return_value=eseries_fake.FAKE_ABOUT_RESPONSE) self.mock_object( client.RestClient, '_get_resource_url', mock.Mock(return_value=eseries_fake.FAKE_RESOURCE_URL)) self.mock_object( self.my_client, 'invoke_service', mock.Mock(return_value=fake_invoke_service)) eseries_info = client.RestClient.get_eseries_api_info( self.my_client, verify=False) self.assertEqual((eseries_fake.FAKE_ASUP_DATA['operating-mode'], eseries_fake.FAKE_ABOUT_RESPONSE['version']), eseries_info) def test_list_ssc_storage_pools(self): self.my_client.features = mock.Mock() self.my_client._invoke = mock.Mock( return_value=eseries_fake.SSC_POOLS) pools = client.RestClient.list_ssc_storage_pools(self.my_client) self.assertEqual(eseries_fake.SSC_POOLS, pools) def test_get_ssc_storage_pool(self): fake_pool = eseries_fake.SSC_POOLS[0] self.my_client.features = mock.Mock() self.my_client._invoke = mock.Mock( return_value=fake_pool) pool = client.RestClient.get_ssc_storage_pool(self.my_client, fake_pool['poolId']) self.assertEqual(fake_pool, pool) @ddt.data(('volumes', True), ('volumes', False), ('volume', True), ('volume', False)) @ddt.unpack def test_get_volume_api_path(self, path_key, ssc_available): self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=ssc_available) expected_key = 'ssc_' + path_key if ssc_available else path_key expected = self.my_client.RESOURCE_PATHS.get(expected_key) actual = self.my_client._get_volume_api_path(path_key) self.assertEqual(expected, actual) @ddt.data(True, False) def test_get_volume_api_path_invalid(self, ssc_available): key = 'invalidKey' self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=ssc_available) self.assertRaises(KeyError, self.my_client._get_volume_api_path, key) def test_list_volumes(self): url = client.RestClient.RESOURCE_PATHS['ssc_volumes'] self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=True) self.my_client._invoke = mock.Mock( return_value=eseries_fake.VOLUMES) volumes = client.RestClient.list_volumes(self.my_client) self.assertEqual(eseries_fake.VOLUMES, volumes) self.my_client._invoke.assert_called_once_with('GET', url) @ddt.data(client.RestClient.ID, client.RestClient.WWN, client.RestClient.NAME) def test_list_volume_v1(self, uid_field_name): url = client.RestClient.RESOURCE_PATHS['volumes'] self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=False) fake_volume = copy.deepcopy(eseries_fake.VOLUME) self.my_client._invoke = mock.Mock( return_value=eseries_fake.VOLUMES) volume = client.RestClient.list_volume(self.my_client, fake_volume[uid_field_name]) self.my_client._invoke.assert_called_once_with('GET', url) self.assertEqual(fake_volume, volume) def test_list_volume_v1_not_found(self): url = client.RestClient.RESOURCE_PATHS['volumes'] self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=False) self.my_client._invoke = mock.Mock( return_value=eseries_fake.VOLUMES) self.assertRaises(exception.VolumeNotFound, client.RestClient.list_volume, self.my_client, 'fakeId') self.my_client._invoke.assert_called_once_with('GET', url) def test_list_volume_v2(self): url = client.RestClient.RESOURCE_PATHS['ssc_volume'] self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=True) fake_volume = copy.deepcopy(eseries_fake.VOLUME) self.my_client._invoke = mock.Mock(return_value=fake_volume) volume = client.RestClient.list_volume(self.my_client, fake_volume['id']) self.my_client._invoke.assert_called_once_with('GET', url, **{'object-id': mock.ANY}) self.assertEqual(fake_volume, volume) def test_list_volume_v2_not_found(self): status_code = 404 url = client.RestClient.RESOURCE_PATHS['ssc_volume'] self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=True) msg = "Response error code - %s." % status_code self.my_client._invoke = mock.Mock( side_effect=es_exception.WebServiceException(message=msg, status_code= status_code)) self.assertRaises(exception.VolumeNotFound, client.RestClient.list_volume, self.my_client, 'fakeId') self.my_client._invoke.assert_called_once_with('GET', url, **{'object-id': mock.ANY}) def test_list_volume_v2_failure(self): status_code = 422 url = client.RestClient.RESOURCE_PATHS['ssc_volume'] self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=True) msg = "Response error code - %s." % status_code self.my_client._invoke = mock.Mock( side_effect=es_exception.WebServiceException(message=msg, status_code= status_code)) self.assertRaises(es_exception.WebServiceException, client.RestClient.list_volume, self.my_client, 'fakeId') self.my_client._invoke.assert_called_once_with('GET', url, **{'object-id': mock.ANY}) def test_create_volume_V1(self): self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=False) create_volume = self.my_client._invoke = mock.Mock( return_value=eseries_fake.VOLUME) volume = client.RestClient.create_volume(self.my_client, 'fakePool', '1', 1) args, kwargs = create_volume.call_args verb, url, body = args # Ensure the correct API was used self.assertEqual('/storage-systems/{system-id}/volumes', url) self.assertEqual(eseries_fake.VOLUME, volume) def test_create_volume_V2(self): self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=True) create_volume = self.my_client._invoke = mock.Mock( return_value=eseries_fake.VOLUME) volume = client.RestClient.create_volume(self.my_client, 'fakePool', '1', 1) args, kwargs = create_volume.call_args verb, url, body = args # Ensure the correct API was used self.assertIn('/storage-systems/{system-id}/ssc/volumes', url, 'The legacy API was used!') self.assertEqual(eseries_fake.VOLUME, volume) def test_create_volume_unsupported_specs(self): self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=False) self.my_client.api_version = '01.52.9000.1' self.assertRaises(exception.NetAppDriverException, client.RestClient.create_volume, self.my_client, '1', 'label', 1, read_cache=True) @ddt.data(True, False) def test_update_volume(self, ssc_api_enabled): label = 'updatedName' fake_volume = copy.deepcopy(eseries_fake.VOLUME) expected_volume = copy.deepcopy(fake_volume) expected_volume['name'] = label self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=ssc_api_enabled) self.my_client._invoke = mock.Mock(return_value=expected_volume) updated_volume = self.my_client.update_volume(fake_volume['id'], label) if ssc_api_enabled: url = self.my_client.RESOURCE_PATHS.get('ssc_volume') else: url = self.my_client.RESOURCE_PATHS.get('volume') self.my_client._invoke.assert_called_once_with('POST', url, {'name': label}, **{'object-id': fake_volume['id']} ) self.assertDictMatch(expected_volume, updated_volume) def test_extend_volume(self): new_capacity = 10 fake_volume = copy.deepcopy(eseries_fake.VOLUME) self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=True) self.my_client._invoke = mock.Mock(return_value=fake_volume) expanded_volume = self.my_client.expand_volume(fake_volume['id'], new_capacity) url = self.my_client.RESOURCE_PATHS.get('ssc_volume') body = {'newSize': new_capacity, 'sizeUnit': 'gb'} self.my_client._invoke.assert_called_once_with('POST', url, body, **{'object-id': fake_volume['id']}) self.assertEqual(fake_volume, expanded_volume) def test_extend_volume_unsupported(self): new_capacity = 10 min_version = 1 fake_volume = copy.deepcopy(eseries_fake.VOLUME) self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=False, minimum_version=min_version) self.my_client._invoke = mock.Mock(return_value=fake_volume) self.assertRaises(exception.NetAppDriverException, self.my_client.expand_volume, fake_volume['id'], new_capacity) @ddt.data(True, False) def test_delete_volume(self, ssc_api_enabled): fake_volume = copy.deepcopy(eseries_fake.VOLUME) self.my_client.features = mock.Mock() self.my_client.features.SSC_API_V2 = na_utils.FeatureState( supported=ssc_api_enabled) self.my_client._invoke = mock.Mock() self.my_client.delete_volume(fake_volume['id']) if ssc_api_enabled: url = self.my_client.RESOURCE_PATHS.get('ssc_volume') else: url = self.my_client.RESOURCE_PATHS.get('volume') self.my_client._invoke.assert_called_once_with('DELETE', url, **{'object-id': fake_volume['id']} ) @ddt.data('00.00.00.00', '01.52.9000.2', '01.52.9001.2', '01.51.9000.3', '01.51.9001.3', '01.51.9010.5', '0.53.9000.3', '0.53.9001.4') def test_api_version_not_support_asup(self, api_version): self.mock_object(client.RestClient, 'get_eseries_api_info', mock.Mock(return_value=('proxy', api_version))) client.RestClient._init_features(self.my_client) self.assertFalse(self.my_client.features.AUTOSUPPORT.supported) @ddt.data('01.52.9000.3', '01.52.9000.4', '01.52.8999.2', '01.52.8999.3', '01.53.8999.3', '01.53.9000.2', '02.51.9000.3', '02.52.8999.3', '02.51.8999.2') def test_api_version_supports_asup(self, api_version): self.mock_object(client.RestClient, 'get_eseries_api_info', mock.Mock(return_value=('proxy', api_version))) client.RestClient._init_features(self.my_client) self.assertTrue(self.my_client.features.AUTOSUPPORT.supported) @ddt.data('00.00.00.00', '01.52.9000.1', '01.52.9001.2', '00.53.9001.3', '01.53.9090.1', '1.53.9010.14', '0.53.9011.15') def test_api_version_not_support_ssc_api(self, api_version): self.mock_object(client.RestClient, 'get_eseries_api_info', mock.Mock(return_value=('proxy', api_version))) client.RestClient._init_features(self.my_client) self.assertFalse(self.my_client.features.SSC_API_V2.supported) @ddt.data('01.53.9000.1', '01.53.9000.5', '01.53.8999.1', '01.53.9010.20', '01.53.9010.17', '01.54.9000.1', '02.51.9000.3', '02.52.8999.3', '02.51.8999.2') def test_api_version_supports_ssc_api(self, api_version): self.mock_object(client.RestClient, 'get_eseries_api_info', mock.Mock(return_value=('proxy', api_version))) client.RestClient._init_features(self.my_client) self.assertTrue(self.my_client.features.SSC_API_V2.supported) @ddt.ddt class TestWebserviceClientTestCase(test.TestCase): def setUp(self): """sets up the mock tests""" super(TestWebserviceClientTestCase, self).setUp() self.mock_log = mock.Mock() self.mock_object(client, 'LOG', self.mock_log) self.webclient = client.WebserviceClient('http', 'host', '80', '/test', 'user', '****') @ddt.data({'params': {'host': None, 'scheme': 'https', 'port': '80'}}, {'params': {'host': 'host', 'scheme': None, 'port': '80'}}, {'params': {'host': 'host', 'scheme': 'http', 'port': None}}) @ddt.unpack def test__validate_params_value_error(self, params): """Tests various scenarios for ValueError in validate method""" self.assertRaises(exception.InvalidInput, self.webclient._validate_params, **params) def test_invoke_service_no_endpoint_error(self): """Tests Exception and Log error if no endpoint is provided""" self.webclient._endpoint = None log_error = 'Unexpected error while invoking web service' self.assertRaises(exception.NetAppDriverException, self.webclient.invoke_service) self.assertTrue(self.mock_log.exception.find(log_error)) def test_invoke_service(self): """Tests if invoke_service evaluates the right response""" self.webclient._endpoint = eseries_fake.FAKE_ENDPOINT_HTTP self.mock_object(self.webclient.conn, 'request', mock.Mock(return_value=eseries_fake.FAKE_INVOC_MSG)) result = self.webclient.invoke_service() self.assertIsNotNone(result)