def test_detach_volumes_failure(self, mock_log, mock_detach): self.node = object_utils.create_test_node(self.context, storage_interface='cinder') object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234') object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') with task_manager.acquire(self.context, self.node.id) as task: # The first attempt should succeed. # The second attempt should throw StorageError # Third attempt, should log errors but not raise an exception. mock_detach.side_effect = [None, exception.StorageError('bar'), None] # This should generate 1 mock_detach call and succeed self.interface.detach_volumes(task) task.node.provision_state = states.DELETED # This should generate the other 2 moc_detach calls and warn self.interface.detach_volumes(task) self.assertEqual(3, mock_detach.call_count) self.assertEqual(1, mock_log.warning.call_count)
def test_detach_volumes_failure(self, mock_log, mock_detach): object_utils.create_test_volume_target(self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234') object_utils.create_test_volume_connector(self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') with task_manager.acquire(self.context, self.node.id) as task: # The first attempt should succeed. # The second attempt should throw StorageError # Third attempt, should log errors but not raise an exception. mock_detach.side_effect = [ None, exception.StorageError('bar'), None ] # This should generate 1 mock_detach call and succeed self.interface.detach_volumes(task) task.node.provision_state = states.DELETED # This should generate the other 2 moc_detach calls and warn self.interface.detach_volumes(task) self.assertEqual(3, mock_detach.call_count) self.assertEqual(1, mock_log.warning.call_count)
def test_attach_volumes_failure(self, mock_log, mock_attach, mock_detach): """Verify detach is called upon attachment failing.""" self.node = object_utils.create_test_node(self.context, storage_interface='cinder') object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234') object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='iscsi', boot_index=1, volume_id='5678', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') mock_attach.side_effect = exception.StorageError('foo') with task_manager.acquire(self.context, self.node.id) as task: self.assertRaises(exception.StorageError, self.interface.attach_volumes, task) self.assertTrue(mock_attach.called) self.assertTrue(mock_detach.called) # Replacing the mock to not return an error, should still raise an # exception. mock_attach.reset_mock() mock_detach.reset_mock()
def test_validate_success_fc_targets(self, mock_log, mock_fail): """Validate success with full fc scenario.""" object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwpn', connector_id='fc.address', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwnn', connector_id='fc.address', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_target(self.context, node_id=self.node.id, volume_type='fibre_channel', boot_index=0, volume_id='1234') with task_manager.acquire(self.context, self.node.id) as task: driver_utils.add_node_capability(task, 'fibre_channel_boot', 'True') self.interface.validate(task) self.assertFalse(mock_log.called) self.assertFalse(mock_fail.called)
def test_attach_volumes_failure_no_attach_error(self, mock_log, mock_attach, mock_detach): """Verify that detach is called on volume/connector mismatch. Volume attachment fails if the number of attachments completed does not match the number of configured targets. """ self.node = object_utils.create_test_node(self.context, storage_interface='cinder') object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234') object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='iscsi', boot_index=1, volume_id='5678', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') mock_attach.return_value = {'mock_return'} with task_manager.acquire(self.context, self.node.id) as task: self.assertRaises(exception.StorageError, self.interface.attach_volumes, task) self.assertTrue(mock_attach.called) self.assertTrue(mock_detach.called)
def test_attach_detach_called_with_target_and_connector(self, mock_target_list, mock_log, mock_attach, mock_detach): target_uuid = uuidutils.generate_uuid() test_volume_target = object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234', uuid=target_uuid) object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') expected_target_properties = { 'volume_id': '1234', 'ironic_volume_uuid': target_uuid, 'new_property': 'foo'} mock_attach.return_value = [{ 'driver_volume_type': 'iscsi', 'data': expected_target_properties}] mock_target_list.return_value = [test_volume_target] with task_manager.acquire(self.context, self.node.id) as task: self.interface.attach_volumes(task) self.assertFalse(mock_log.called) self.assertTrue(mock_attach.called) task.volume_targets[0].refresh() self.assertEqual(expected_target_properties, task.volume_targets[0]['properties']) self.interface.detach_volumes(task) self.assertFalse(mock_log.called) self.assertTrue(mock_detach.called)
def test_attach_detach_called_with_target_and_connector( self, mock_target_list, mock_log, mock_attach, mock_detach): target_uuid = uuidutils.generate_uuid() test_volume_target = object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234', uuid=target_uuid) object_utils.create_test_volume_connector(self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') expected_target_properties = { 'volume_id': '1234', 'ironic_volume_uuid': target_uuid, 'new_property': 'foo' } mock_attach.return_value = [{ 'driver_volume_type': 'iscsi', 'data': expected_target_properties }] mock_target_list.return_value = [test_volume_target] with task_manager.acquire(self.context, self.node.id) as task: self.interface.attach_volumes(task) self.assertFalse(mock_log.called) self.assertTrue(mock_attach.called) task.volume_targets[0].refresh() self.assertEqual(expected_target_properties, task.volume_targets[0]['properties']) self.interface.detach_volumes(task) self.assertFalse(mock_log.called) self.assertTrue(mock_detach.called)
def test_attach_volumes_failure(self, mock_log, mock_attach, mock_detach): """Verify detach is called upon attachment failing.""" object_utils.create_test_volume_target(self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234') object_utils.create_test_volume_target(self.context, node_id=self.node.id, volume_type='iscsi', boot_index=1, volume_id='5678', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_connector(self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') mock_attach.side_effect = exception.StorageError('foo') with task_manager.acquire(self.context, self.node.id) as task: self.assertRaises(exception.StorageError, self.interface.attach_volumes, task) self.assertTrue(mock_attach.called) self.assertTrue(mock_detach.called) # Replacing the mock to not return an error, should still raise an # exception. mock_attach.reset_mock() mock_detach.reset_mock()
def test_attach_volumes_failure_no_attach_error(self, mock_log, mock_attach, mock_detach): """Verify that detach is called on volume/connector mismatch. Volume attachment fails if the number of attachments completed does not match the number of configured targets. """ object_utils.create_test_volume_target(self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234') object_utils.create_test_volume_target(self.context, node_id=self.node.id, volume_type='iscsi', boot_index=1, volume_id='5678', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_connector(self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') mock_attach.return_value = {'mock_return'} with task_manager.acquire(self.context, self.node.id) as task: self.assertRaises(exception.StorageError, self.interface.attach_volumes, task) self.assertTrue(mock_attach.called) self.assertTrue(mock_detach.called)
def test_detail_sepecified_by_path(self): obj_utils.create_test_volume_connector(self.context, node_id=self.node.id) response = self.get_json( '/volume/connectors/detail', headers=self.headers, expect_errors=True) self.assertEqual(http_client.BAD_REQUEST, response.status_int)
def test_detail_sepecified_by_path(self): obj_utils.create_test_volume_connector(self.context, node_id=self.node.id) response = self.get_json('/volume/connectors/detail', headers=self.headers, expect_errors=True) self.assertEqual(http_client.BAD_REQUEST, response.status_int)
def test_one_invalid_api_version(self): obj_utils.create_test_volume_connector(self.context, node_id=self.node.id) response = self.get_json( '/volume/connectors', headers={api_base.Version.string: str(api_v1.MIN_VER)}, expect_errors=True) self.assertEqual(http_client.NOT_FOUND, response.status_int)
def test_one_invalid_api_version(self): obj_utils.create_test_volume_connector(self.context, node_id=self.node.id) response = self.get_json( '/volume/connectors', headers={api_base.Version.string: str(api_v1.min_version())}, expect_errors=True) self.assertEqual(http_client.NOT_FOUND, response.status_int)
def test_validate_success_iscsi_connector(self, mock_log, mock_fail): """Perform validate with only an iSCSI connector in place.""" object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') with task_manager.acquire(self.context, self.node.id) as task: self.interface.validate(task) self.assertFalse(mock_log.called) self.assertFalse(mock_fail.called)
def test_validate_success_iscsi_connector(self, mock_log, mock_fail): """Perform validate with only an iSCSI connector in place.""" object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') with task_manager.acquire(self.context, self.node.id) as task: self.interface.validate(task) self.assertFalse(mock_log.called) self.assertFalse(mock_fail.called)
def test__generate_connector_single_path(self): """Validate an exception is raised with only an invalid connector.""" expected = {'initiator': 'iqn.address', 'host': self.node.uuid} object_utils.create_test_volume_connector(self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') with task_manager.acquire(self.context, self.node.id) as task: return_value = self.interface._generate_connector(task) self.assertDictEqual(expected, return_value)
def test_validate_fails_when_fc_connectors_unequal(self, mock_log): """Validate should fail with only wwnn FC connector in place""" object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwnn', connector_id='wwnn.address') with task_manager.acquire(self.context, self.node.id) as task: self.assertRaises(exception.StorageError, self.interface.validate, task) self.assertTrue(mock_log.error.called)
def test_validate_fails_when_fc_connectors_unequal(self, mock_log): """Validate should fail with only wwnn FC connector in place""" object_utils.create_test_volume_connector(self.context, node_id=self.node.id, type='wwnn', connector_id='wwnn.address') with task_manager.acquire(self.context, self.node.id) as task: self.assertRaises(exception.StorageError, self.interface.validate, task) self.assertTrue(mock_log.error.called)
def test__generate_connector_unknown_raises_excption(self, mock_log): """Validate an exception is raised with only an invalid connector.""" object_utils.create_test_volume_connector(self.context, node_id=self.node.id, type='foo', connector_id='bar') with task_manager.acquire(self.context, self.node.id) as task: self.assertRaises(exception.StorageError, self.interface._generate_connector, task) self.assertEqual(1, mock_log.warning.call_count) self.assertEqual(1, mock_log.error.call_count)
def test__generate_connector_single_path(self): """Validate an exception is raised with only an invalid connector.""" expected = { 'initiator': 'iqn.address', 'host': self.node.uuid} object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') with task_manager.acquire(self.context, self.node.id) as task: return_value = self.interface._generate_connector(task) self.assertDictEqual(expected, return_value)
def test_validate_success_fc_connectors(self, mock_log, mock_fail): """Perform validate with only FC connectors in place""" object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwpn', connector_id='wwpn.address', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwnn', connector_id='wwnn.address', uuid=uuidutils.generate_uuid()) with task_manager.acquire(self.context, self.node.id) as task: self.interface.validate(task) self.assertFalse(mock_log.called) self.assertFalse(mock_fail.called)
def test__generate_connector_unknown_raises_excption(self, mock_log): """Validate an exception is raised with only an invalid connector.""" object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='foo', connector_id='bar') with task_manager.acquire(self.context, self.node.id) as task: self.assertRaises( exception.StorageError, self.interface._generate_connector, task) self.assertEqual(1, mock_log.warning.call_count) self.assertEqual(1, mock_log.error.call_count)
def test_validate_success_fc_connectors(self, mock_log, mock_fail): """Perform validate with only FC connectors in place""" object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwpn', connector_id='wwpn.address', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwnn', connector_id='wwnn.address', uuid=uuidutils.generate_uuid()) with task_manager.acquire(self.context, self.node.id) as task: self.interface.validate(task) self.assertFalse(mock_log.called) self.assertFalse(mock_fail.called)
def test_validate_success_iscsi_targets(self, mock_log, mock_fail): """Validate success with full iscsi scenario.""" object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234') with task_manager.acquire(self.context, self.node.id) as task: driver_utils.add_node_capability(task, 'iscsi_boot', 'True') self.interface.validate(task) self.assertFalse(mock_log.called) self.assertFalse(mock_fail.called)
def test_validate_fail_on_unknown_volume_types(self, mock_log): """Ensure exception is raised when connector/target do not match.""" object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='foo.address') object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='wetcat', boot_index=0, volume_id='1234') with task_manager.acquire(self.context, self.node.id) as task: driver_utils.add_node_capability(task, 'iscsi_boot', 'True') self.assertRaises(exception.InvalidParameterValue, self.interface.validate, task) self.assertTrue(mock_log.error.called)
def test_validate_fails_iscsi_conn_fc_target(self, mock_log): """Validate failure of iSCSI connectors with FC target.""" object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='foo.address') object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='fibre_channel', boot_index=0, volume_id='1234') with task_manager.acquire(self.context, self.node.id) as task: driver_utils.add_node_capability(task, 'iscsi_boot', 'True') self.assertRaises(exception.InvalidParameterValue, self.interface.validate, task) self.assertTrue(mock_log.error.called)
def test_validate_fails_iscsi_conn_fc_target(self, mock_log): """Validate failure of iSCSI connectors with FC target.""" object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='foo.address') object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='fibre_channel', boot_index=0, volume_id='1234') with task_manager.acquire(self.context, self.node.id) as task: driver_utils.add_node_capability(task, 'iscsi_boot', 'True') self.assertRaises(exception.InvalidParameterValue, self.interface.validate, task) self.assertTrue(mock_log.error.called)
def test__generate_connector_multiple_fc_wwns(self): """Validate handling of WWPNs and WWNNs.""" expected = { 'wwpns': ['wwpn1', 'wwpn2'], 'wwnns': ['wwnn3', 'wwnn4'], 'host': self.node.uuid, 'multipath': True} object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwpn', connector_id='wwpn1', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwpn', connector_id='wwpn2', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwnn', connector_id='wwnn3', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwnn', connector_id='wwnn4', uuid=uuidutils.generate_uuid()) with task_manager.acquire(self.context, self.node.id) as task: return_value = self.interface._generate_connector(task) self.assertDictEqual(expected, return_value)
def test_links(self): uuid = uuidutils.generate_uuid() obj_utils.create_test_volume_connector(self.context, uuid=uuid, node_id=self.node.id) data = self.get_json('/volume/connectors/%s' % uuid, headers=self.headers) self.assertIn('links', data.keys()) self.assertEqual(2, len(data['links'])) self.assertIn(uuid, data['links'][0]['href']) for l in data['links']: bookmark = l['rel'] == 'bookmark' self.assertTrue(self.validate_link(l['href'], bookmark=bookmark, headers=self.headers))
def test_validate_fail_on_unknown_volume_types(self, mock_log): """Ensure exception is raised when connector/target do not match.""" object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='foo.address') object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='wetcat', boot_index=0, volume_id='1234') with task_manager.acquire(self.context, self.node.id) as task: driver_utils.add_node_capability(task, 'iscsi_boot', 'True') self.assertRaises(exception.InvalidParameterValue, self.interface.validate, task) self.assertTrue(mock_log.error.called)
def test_links(self): uuid = uuidutils.generate_uuid() obj_utils.create_test_volume_connector(self.context, uuid=uuid, node_id=self.node.id) data = self.get_json('/volume/connectors/%s' % uuid, headers=self.headers) self.assertIn('links', data.keys()) self.assertEqual(2, len(data['links'])) self.assertIn(uuid, data['links'][0]['href']) for l in data['links']: bookmark = l['rel'] == 'bookmark' self.assertTrue(self.validate_link(l['href'], bookmark=bookmark, headers=self.headers))
def test__generate_connector_multiple_fc_wwns(self): """Validate handling of WWPNs and WWNNs.""" expected = { 'wwpns': ['wwpn1', 'wwpn2'], 'wwnns': ['wwnn3', 'wwnn4'], 'host': self.node.uuid, 'multipath': True } object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwpn', connector_id='wwpn1', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwpn', connector_id='wwpn2', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwnn', connector_id='wwnn3', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='wwnn', connector_id='wwnn4', uuid=uuidutils.generate_uuid()) with task_manager.acquire(self.context, self.node.id) as task: return_value = self.interface._generate_connector(task) self.assertDictEqual(expected, return_value)
def test_get_all_by_node_name_ok(self, mock_get_rpc_node): # GET /v1/volume/connectors specifying node_name - success mock_get_rpc_node.return_value = self.node for i in range(5): if i < 3: node_id = self.node.id else: node_id = 100000 + i obj_utils.create_test_volume_connector( self.context, node_id=node_id, uuid=uuidutils.generate_uuid(), connector_id='test-value-%s' % i) data = self.get_json("/volume/connectors?node=%s" % 'test-node', headers=self.headers) self.assertEqual(3, len(data['connectors']))
def test_validate_fails_with_ipxe_not_enabled(self, mock_log): """Ensure a validation failure is raised when iPXE not enabled.""" self.node = object_utils.create_test_node( self.context, storage_interface='external', boot_interface='pxe') object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='foo.address') object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='2345') with task_manager.acquire(self.context, self.node.id) as task: self.assertRaises(exception.InvalidParameterValue, self.interface.validate, task) self.assertTrue(mock_log.error.called)
def test_get_all_by_node_name_ok(self, mock_get_rpc_node): # GET /v1/volume/connectors specifying node_name - success mock_get_rpc_node.return_value = self.node for i in range(5): if i < 3: node_id = self.node.id else: node_id = 100000 + i obj_utils.create_test_volume_connector( self.context, node_id=node_id, uuid=uuidutils.generate_uuid(), connector_id='test-value-%s' % i) data = self.get_json("/volume/connectors?node=%s" % 'test-node', headers=self.headers) self.assertEqual(3, len(data['connectors']))
def test__generate_connector_iscsi(self): expected = { 'initiator': 'iqn.address', 'ip': 'ip.address', 'host': self.node.uuid, 'multipath': True} object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='ip', connector_id='ip.address', uuid=uuidutils.generate_uuid()) with task_manager.acquire(self.context, self.node.id) as task: return_value = self.interface._generate_connector(task) self.assertDictEqual(expected, return_value)
def test__generate_connector_iscsi(self): expected = { 'initiator': 'iqn.address', 'ip': 'ip.address', 'host': self.node.uuid, 'multipath': True} object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='ip', connector_id='ip.address', uuid=uuidutils.generate_uuid()) with task_manager.acquire(self.context, self.node.id) as task: return_value = self.interface._generate_connector(task) self.assertDictEqual(expected, return_value)
def test_validate_fails_with_ipxe_not_enabled(self, mock_log): """Ensure a validation failure is raised when iPXE not enabled.""" self.config(ipxe_enabled=False, group='pxe') object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='foo.address') object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='2345') with task_manager.acquire(self.context, self.node.id) as task: driver_utils.add_node_capability(task, 'iscsi_boot', 'True') self.assertRaises(exception.InvalidParameterValue, self.interface.validate, task) self.assertTrue(mock_log.error.called)
def test_detail_against_single(self): connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) response = self.get_json('/volume/connectors/%s?detail=True' % connector.uuid, expect_errors=True, headers=self.headers) self.assertEqual(http_client.BAD_REQUEST, response.status_int)
def test_get_collection_custom_fields(self): fields = 'uuid,extra' for i in range(3): obj_utils.create_test_volume_connector( self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), connector_id='test-connector_id-%s' % i) data = self.get_json('/volume/connectors?fields=%s' % fields, headers=self.headers) self.assertEqual(3, len(data['connectors'])) for connector in data['connectors']: # We always append "links" self.assertItemsEqual(['uuid', 'extra', 'links'], connector)
def test_get_collection_custom_fields(self): fields = 'uuid,extra' for i in range(3): obj_utils.create_test_volume_connector( self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), connector_id='test-connector_id-%s' % i) data = self.get_json( '/volume/connectors?fields=%s' % fields, headers=self.headers) self.assertEqual(3, len(data['connectors'])) for connector in data['connectors']: # We always append "links" self.assertItemsEqual(['uuid', 'extra', 'links'], connector)
def test_detail_against_single(self): connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) response = self.get_json('/volume/connectors/%s?detail=True' % connector.uuid, expect_errors=True, headers=self.headers) self.assertEqual(http_client.BAD_REQUEST, response.status_int)
def test__generate_connector_iscsi_and_unknown(self, mock_log): """Validate we return and log with valid and invalid connectors.""" expected = { 'initiator': 'iqn.address', 'host': self.node.uuid, 'multipath': True} object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='foo', connector_id='bar', uuid=uuidutils.generate_uuid()) with task_manager.acquire(self.context, self.node.id) as task: return_value = self.interface._generate_connector(task) self.assertDictEqual(expected, return_value) self.assertEqual(1, mock_log.warning.call_count)
def test__generate_connector_iscsi_and_unknown(self, mock_log): """Validate we return and log with valid and invalid connectors.""" expected = { 'initiator': 'iqn.address', 'host': self.node.uuid, 'multipath': True} object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='foo', connector_id='bar', uuid=uuidutils.generate_uuid()) with task_manager.acquire(self.context, self.node.id) as task: return_value = self.interface._generate_connector(task) self.assertDictEqual(expected, return_value) self.assertEqual(1, mock_log.warning.call_count)
def test_one(self): connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) data = self.get_json('/volume/connectors', headers=self.headers) self.assertEqual(connector.uuid, data['connectors'][0]["uuid"]) self.assertNotIn('extra', data['connectors'][0]) # never expose the node_id self.assertNotIn('node_id', data['connectors'][0])
def test_detail_and_fields(self): connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) fields = 'connector_id,extra' response = self.get_json('/volume/connectors/%s?detail=True&fields=%s' % (connector.uuid, fields), expect_errors=True, headers=self.headers) self.assertEqual(http_client.BAD_REQUEST, response.status_int)
def test_one(self): connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) data = self.get_json('/volume/connectors', headers=self.headers) self.assertEqual(connector.uuid, data['connectors'][0]["uuid"]) self.assertNotIn('extra', data['connectors'][0]) # never expose the node_id self.assertNotIn('node_id', data['connectors'][0])
def test_detail_and_fields(self): connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) fields = 'connector_id,extra' response = self.get_json('/volume/connectors/%s?detail=True&fields=%s' % (connector.uuid, fields), expect_errors=True, headers=self.headers) self.assertEqual(http_client.BAD_REQUEST, response.status_int)
def test_get_one_custom_fields(self): connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) fields = 'connector_id,extra' data = self.get_json( '/volume/connectors/%s?fields=%s' % (connector.uuid, fields), headers=self.headers) # We always append "links" self.assertItemsEqual(['connector_id', 'extra', 'links'], data)
def test_get_one_custom_fields(self): connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) fields = 'connector_id,extra' data = self.get_json('/volume/connectors/%s?fields=%s' % (connector.uuid, fields), headers=self.headers) # We always append "links" self.assertItemsEqual(['connector_id', 'extra', 'links'], data)
def test_get_custom_fields_invalid_api_version(self): connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) fields = 'uuid,extra' response = self.get_json( '/volume/connectors/%s?fields=%s' % (connector.uuid, fields), headers={api_base.Version.string: str(api_v1.min_version())}, expect_errors=True) self.assertEqual(http_client.NOT_FOUND, response.status_int)
def test_get_custom_fields_invalid_api_version(self): connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) fields = 'uuid,extra' response = self.get_json( '/volume/connectors/%s?fields=%s' % (connector.uuid, fields), headers={api_base.Version.string: str(api_v1.MIN_VER)}, expect_errors=True) self.assertEqual(http_client.NOT_FOUND, response.status_int)
def test_detail_by_node_name_ok(self, mock_get_rpc_node): # GET /v1/volume/connectors?detail=True specifying node_name - success mock_get_rpc_node.return_value = self.node connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) data = self.get_json('/volume/connectors?detail=True&node=%s' % 'test-node', headers=self.headers) self.assertEqual(connector.uuid, data['connectors'][0]['uuid']) self.assertEqual(self.node.uuid, data['connectors'][0]['node_uuid'])
def setUp(self): super(TestPatch, self).setUp() self.node = obj_utils.create_test_node(self.context) self.connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) p = mock.patch.object(rpcapi.ConductorAPI, 'get_topic_for') self.mock_gtf = p.start() self.mock_gtf.return_value = 'test-topic' self.addCleanup(p.stop)
def setUp(self): super(TestDelete, self).setUp() self.node = obj_utils.create_test_node(self.context) self.connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) gtf = mock.patch.object(rpcapi.ConductorAPI, 'get_topic_for') self.mock_gtf = gtf.start() self.mock_gtf.return_value = 'test-topic' self.addCleanup(gtf.stop)
def test_detail_by_node_name_ok(self, mock_get_rpc_node): # GET /v1/volume/connectors?detail=True specifying node_name - success mock_get_rpc_node.return_value = self.node connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) data = self.get_json('/volume/connectors?detail=True&node=%s' % 'test-node', headers=self.headers) self.assertEqual(connector.uuid, data['connectors'][0]['uuid']) self.assertEqual(self.node.uuid, data['connectors'][0]['node_uuid'])
def test_get_custom_fields_invalid_fields(self): connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) fields = 'uuid,spongebob' response = self.get_json( '/volume/connectors/%s?fields=%s' % (connector.uuid, fields), headers=self.headers, expect_errors=True) self.assertEqual(http_client.BAD_REQUEST, response.status_int) self.assertEqual('application/json', response.content_type) self.assertIn('spongebob', response.json['error_message'])
def test_get_custom_fields_invalid_fields(self): connector = obj_utils.create_test_volume_connector( self.context, node_id=self.node.id) fields = 'uuid,spongebob' response = self.get_json( '/volume/connectors/%s?fields=%s' % (connector.uuid, fields), headers=self.headers, expect_errors=True) self.assertEqual(http_client.BAD_REQUEST, response.status_int) self.assertEqual('application/json', response.content_type) self.assertIn('spongebob', response.json['error_message'])
def test_validate_success_iscsi_targets(self, mock_log, mock_fail): """Validate success with full iscsi scenario.""" self.node = object_utils.create_test_node(self.context, storage_interface='cinder') object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address', uuid=uuidutils.generate_uuid()) object_utils.create_test_volume_target(self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234') with task_manager.acquire(self.context, self.node.id) as task: driver_utils.add_node_capability(task, 'iscsi_boot', 'True') self.interface.validate(task) self.assertFalse(mock_log.called) self.assertFalse(mock_fail.called)
def test_detach_volumes_failure_raises_exception(self, mock_log, mock_detach): object_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234') object_utils.create_test_volume_connector( self.context, node_id=self.node.id, type='iqn', connector_id='iqn.address') with task_manager.acquire(self.context, self.node.id) as task: mock_detach.side_effect = exception.StorageError('bar') self.assertRaises(exception.StorageError, self.interface.detach_volumes, task) # Check that we warn every retry except the last one. self.assertEqual(3, mock_log.warning.call_count) self.assertEqual(1, mock_log.error.call_count) # CONF.cinder.action_retries + 1, number of retries is set to 3. self.assertEqual(4, mock_detach.call_count)