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_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_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_set_iscsi_boot_target_missed_properties(self): with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: vol_id = uuidutils.generate_uuid() obj_utils.create_test_volume_target(self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234', uuid=vol_id, properties={ 'target_iqn': 'fake_iqn', 'auth_username': '******', 'auth_password': '******' }) driver_internal_info = task.node.driver_internal_info driver_internal_info['boot_from_volume'] = vol_id task.node.driver_internal_info = driver_internal_info task.node.save() self.assertRaises(exception.MissingParameterValue, task.driver.management.set_iscsi_boot_target, task)
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_set_iscsi_boot_target_in_bios(self, get_ilo_object_mock): with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: vol_id = uuidutils.generate_uuid() obj_utils.create_test_volume_target(self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234', uuid=vol_id, properties={ 'target_lun': 0, 'target_portal': 'fake_host:3260', 'target_iqn': 'fake_iqn', 'auth_username': '******', 'auth_password': '******' }) driver_internal_info = task.node.driver_internal_info driver_internal_info['boot_from_volume'] = vol_id task.node.driver_internal_info = driver_internal_info task.node.save() ilo_object_mock = get_ilo_object_mock.return_value ilo_object_mock.set_iscsi_info.side_effect = ( ilo_error.IloCommandNotSupportedInBiosError('error')) self.assertRaises(exception.IloOperationNotSupported, task.driver.management.set_iscsi_boot_target, task)
def test_detail_sepecified_by_path(self): obj_utils.create_test_volume_target(self.context, node_id=self.node.id) response = self.get_json( '/volume/targets/detail', headers=self.headers, expect_errors=True) self.assertEqual(http_client.BAD_REQUEST, response.status_int)
def test_set_iscsi_boot_target_without_auth(self, get_ilo_object_mock): with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: vol_id = uuidutils.generate_uuid() obj_utils.create_test_volume_target(self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234', uuid=vol_id, properties={ 'target_lun': 0, 'target_portal': 'fake_host:3260', 'target_iqn': 'fake_iqn' }) driver_internal_info = task.node.driver_internal_info driver_internal_info['boot_from_volume'] = vol_id task.node.driver_internal_info = driver_internal_info task.node.save() ilo_object_mock = get_ilo_object_mock.return_value task.driver.management.set_iscsi_boot_target(task) ilo_object_mock.set_iscsi_info.assert_called_once_with( 'fake_iqn', 0, 'fake_host', '3260', auth_method=None, password=None, username=None)
def test_detail_sepecified_by_path(self): obj_utils.create_test_volume_target(self.context, node_id=self.node.id) response = self.get_json( '/volume/targets/detail', headers=self.headers, expect_errors=True) self.assertEqual(http_client.BAD_REQUEST, response.status_int)
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(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_one_invalid_api_version(self): obj_utils.create_test_volume_target(self.context, node_id=self.node.id) response = self.get_json( '/volume/targets', 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_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_one_invalid_api_version(self): obj_utils.create_test_volume_target( self.context, node_id=self.node.id) response = self.get_json( '/volume/targets', headers={api_base.Version.string: str(api_v1.min_version())}, expect_errors=True) self.assertEqual(http_client.NOT_FOUND, response.status_int)
def test_prepare_instance_netboot_iscsi(self, get_image_info_mock, cache_mock, dhcp_factory_mock, switch_pxe_config_mock, set_boot_device_mock, create_pxe_config_mock): http_url = 'http://192.1.2.3:1234' self.config(http_url=http_url, group='deploy') provider_mock = mock.MagicMock() dhcp_factory_mock.return_value = provider_mock vol_id = uuidutils.generate_uuid() obj_utils.create_test_volume_target(self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234', uuid=vol_id, properties={ 'target_lun': 0, 'target_portal': 'fake_host:3260', 'target_iqn': 'fake_iqn', 'auth_username': '******', 'auth_password': '******' }) with task_manager.acquire(self.context, self.node.uuid) as task: task.node.driver_internal_info = {'boot_from_volume': vol_id} dhcp_opts = pxe_utils.dhcp_options_for_instance(task, ipxe_enabled=True) dhcp_opts += pxe_utils.dhcp_options_for_instance(task, ipxe_enabled=True, ip_version=6) pxe_config_path = pxe_utils.get_pxe_config_file_path( task.node.uuid, ipxe_enabled=True) task.node.properties['capabilities'] = 'boot_mode:bios' task.driver.boot.prepare_instance(task) self.assertFalse(get_image_info_mock.called) self.assertFalse(cache_mock.called) provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts) create_pxe_config_mock.assert_called_once_with( task, mock.ANY, CONF.pxe.pxe_config_template, ipxe_enabled=True) switch_pxe_config_mock.assert_called_once_with( pxe_config_path, None, boot_modes.LEGACY_BIOS, False, ipxe_enabled=True, iscsi_boot=True, ramdisk_boot=False) set_boot_device_mock.assert_called_once_with(task, boot_devices.PXE, persistent=True)
def test_should_write_image(self): 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: self.assertFalse(self.interface.should_write_image(task)) self.node.instance_info = {'image_source': 'fake-value'} self.node.save() with task_manager.acquire(self.context, self.node.id) as task: self.assertTrue(self.interface.should_write_image(task))
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_should_write_image(self): 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: self.assertFalse(self.interface.should_write_image(task)) self.node.instance_info = {'image_source': 'fake-value'} self.node.save() with task_manager.acquire(self.context, self.node.id) as task: self.assertTrue(self.interface.should_write_image(task))
def test_get_all_by_node_name_ok(self, mock_get_rpc_node): # GET /v1/volume/targets 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_target( self.context, node_id=node_id, uuid=uuidutils.generate_uuid(), boot_index=i) data = self.get_json("/volume/targets?node=%s" % 'test-node', headers=self.headers) self.assertEqual(3, len(data['targets']))
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_target(self.context, uuid=uuid, node_id=self.node.id) data = self.get_json('/volume/targets/%s' % uuid, headers=self.headers) self.assertIn('links', data) 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_links(self): uuid = uuidutils.generate_uuid() obj_utils.create_test_volume_target(self.context, uuid=uuid, node_id=self.node.id) data = self.get_json('/volume/targets/%s' % uuid, headers=self.headers) self.assertIn('links', data) 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_get_all_by_node_name_ok(self, mock_get_rpc_node): # GET /v1/volume/targets 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_target( self.context, node_id=node_id, uuid=uuidutils.generate_uuid(), boot_index=i) data = self.get_json("/volume/targets?node=%s" % 'test-node', headers=self.headers) self.assertEqual(3, len(data['targets']))
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_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_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_get_collection_custom_fields(self): fields = 'uuid,extra' for i in range(3): obj_utils.create_test_volume_target( self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), boot_index=i) data = self.get_json( '/volume/targets?fields=%s' % fields, headers=self.headers) self.assertEqual(3, len(data['targets'])) for target in data['targets']: # We always append "links" self.assertItemsEqual(['uuid', 'extra', 'links'], target)
def test_get_collection_custom_fields(self): fields = 'uuid,extra' for i in range(3): obj_utils.create_test_volume_target( self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), boot_index=i) data = self.get_json( '/volume/targets?fields=%s' % fields, headers=self.headers) self.assertEqual(3, len(data['targets'])) for target in data['targets']: # We always append "links" self.assertItemsEqual(['uuid', 'extra', 'links'], target)
def test_attach_detach_volumes_fails_without_connectors(self, mock_attach, mock_detach): """Without connectors, attach and detach should fail.""" 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: self.assertRaises(exception.StorageError, self.interface.attach_volumes, task) self.assertFalse(mock_attach.called) self.assertRaises(exception.StorageError, self.interface.detach_volumes, task) self.assertFalse(mock_detach.called)
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_attach_detach_volumes_fails_without_connectors(self, mock_attach, mock_detach): """Without connectors, attach and detach should fail.""" 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: self.assertRaises(exception.StorageError, self.interface.attach_volumes, task) self.assertFalse(mock_attach.called) self.assertRaises(exception.StorageError, self.interface.detach_volumes, task) self.assertFalse(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_set_iscsi_boot_target_missed_properties(self): with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: vol_id = uuidutils.generate_uuid() obj_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234', uuid=vol_id, properties={'target_iqn': 'fake_iqn', 'auth_username': '******', 'auth_password': '******'}) driver_internal_info = task.node.driver_internal_info driver_internal_info['boot_from_volume'] = vol_id task.node.driver_internal_info = driver_internal_info task.node.save() self.assertRaises(exception.MissingParameterValue, task.driver.management.set_iscsi_boot_target, task)
def test_detail_against_single(self): target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id) response = self.get_json('/volume/targets/%s?detail=True' % target.uuid, headers=self.headers, expect_errors=True) self.assertEqual(http_client.BAD_REQUEST, response.status_int)
def test_one(self): target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id) data = self.get_json('/volume/targets', headers=self.headers) self.assertEqual(target.uuid, data['targets'][0]["uuid"]) self.assertNotIn('extra', data['targets'][0]) # never expose the node_id self.assertNotIn('node_id', data['targets'][0])
def test_one(self): target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id) data = self.get_json('/volume/targets', headers=self.headers) self.assertEqual(target.uuid, data['targets'][0]["uuid"]) self.assertNotIn('extra', data['targets'][0]) # never expose the node_id self.assertNotIn('node_id', data['targets'][0])
def test_detail_against_single(self): target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id) response = self.get_json('/volume/targets/%s?detail=True' % target.uuid, headers=self.headers, expect_errors=True) self.assertEqual(http_client.BAD_REQUEST, response.status_int)
def test_detail_and_fields(self): target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id) fields = 'boot_index,extra' response = self.get_json('/volume/targets/%s?detail=True&fields=%s' % (target.uuid, fields), headers=self.headers, expect_errors=True) self.assertEqual(http_client.BAD_REQUEST, response.status_int)
def test_get_one_custom_fields(self): target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id) fields = 'boot_index,extra' data = self.get_json( '/volume/targets/%s?fields=%s' % (target.uuid, fields), headers=self.headers) # We always append "links" self.assertItemsEqual(['boot_index', 'extra', 'links'], data)
def test_detail_and_fields(self): target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id) fields = 'boot_index,extra' response = self.get_json('/volume/targets/%s?detail=True&fields=%s' % (target.uuid, fields), headers=self.headers, expect_errors=True) self.assertEqual(http_client.BAD_REQUEST, response.status_int)
def test_get_one_custom_fields(self): target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id) fields = 'boot_index,extra' data = self.get_json( '/volume/targets/%s?fields=%s' % (target.uuid, fields), headers=self.headers) # We always append "links" self.assertItemsEqual(['boot_index', 'extra', 'links'], data)
def test_tear_down(self, node_power_action_mock, unconfigure_tenant_nets_mock, storage_detach_volumes_mock): obj_utils.create_test_volume_target( self.context, node_id=self.node.id) with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: state = task.driver.deploy.tear_down(task) self.assertEqual(state, states.DELETED) node_power_action_mock.assert_called_once_with(task, states.POWER_OFF) unconfigure_tenant_nets_mock.assert_called_once_with(mock.ANY, task) storage_detach_volumes_mock.assert_called_once_with( task.driver.storage, task) # Verify no volumes exist for new task instances. with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: self.assertEqual(0, len(task.volume_targets))
def setUp(self): super(TestDelete, self).setUp() self.node = obj_utils.create_test_node(self.context) self.target = obj_utils.create_test_volume_target( 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/targets/?detail=True specifying node_name - success mock_get_rpc_node.return_value = self.node target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id) data = self.get_json('/volume/targets?detail=True&node=%s' % 'test-node', headers=self.headers) self.assertEqual(target.uuid, data['targets'][0]['uuid']) self.assertEqual(self.node.uuid, data['targets'][0]['node_uuid'])
def test_set_iscsi_boot_target_without_auth(self, get_ilo_object_mock): with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: vol_id = uuidutils.generate_uuid() obj_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234', uuid=vol_id, properties={'target_lun': 0, 'target_portal': 'fake_host:3260', 'target_iqn': 'fake_iqn'}) driver_internal_info = task.node.driver_internal_info driver_internal_info['boot_from_volume'] = vol_id task.node.driver_internal_info = driver_internal_info task.node.save() ilo_object_mock = get_ilo_object_mock.return_value task.driver.management.set_iscsi_boot_target(task) ilo_object_mock.set_iscsi_info.assert_called_once_with( 'fake_iqn', 0, 'fake_host', '3260', auth_method=None, password=None, username=None)
def test_detail_by_node_name_ok(self, mock_get_rpc_node): # GET /v1/volume/targets/?detail=True specifying node_name - success mock_get_rpc_node.return_value = self.node target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id) data = self.get_json('/volume/targets?detail=True&node=%s' % 'test-node', headers=self.headers) self.assertEqual(target.uuid, data['targets'][0]['uuid']) self.assertEqual(self.node.uuid, data['targets'][0]['node_uuid'])
def test_tear_down(self, node_power_action_mock, unconfigure_tenant_nets_mock, storage_detach_volumes_mock): obj_utils.create_test_volume_target( self.context, node_id=self.node.id) with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: state = task.driver.deploy.tear_down(task) self.assertEqual(state, states.DELETED) node_power_action_mock.assert_called_once_with(task, states.POWER_OFF) unconfigure_tenant_nets_mock.assert_called_once_with(mock.ANY, task) storage_detach_volumes_mock.assert_called_once_with( task.driver.storage, task) # Verify no volumes exist for new task instances. with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: self.assertEqual(0, len(task.volume_targets))
def test_get_custom_fields_invalid_fields(self): target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id) fields = 'uuid,spongebob' response = self.get_json( '/volume/targets/%s?fields=%s' % (target.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): target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id) fields = 'uuid,spongebob' response = self.get_json( '/volume/targets/%s?fields=%s' % (target.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 setUp(self): super(TestDelete, self).setUp() self.node = obj_utils.create_test_node(self.context) self.target = obj_utils.create_test_volume_target( 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_sort_key(self): targets = [] for id_ in range(3): target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), boot_index=id_) targets.append(target.uuid) data = self.get_json('/volume/targets?sort_key=uuid', headers=self.headers) uuids = [n['uuid'] for n in data['targets']] self.assertEqual(sorted(targets), uuids)
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)
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_sort_key(self): targets = [] for id_ in range(3): target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), boot_index=id_) targets.append(target.uuid) data = self.get_json('/volume/targets?sort_key=uuid', headers=self.headers) uuids = [n['uuid'] for n in data['targets']] self.assertEqual(sorted(targets), uuids)
def test_validate_success_fc_targets(self, mock_log, mock_fail): """Validate success with full fc 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='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_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)
def test_many(self): targets = [] for id_ in range(5): target = obj_utils.create_test_volume_target( self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), boot_index=id_) targets.append(target.uuid) data = self.get_json('/volume/targets', headers=self.headers) self.assertEqual(len(targets), len(data['targets'])) uuids = [n['uuid'] for n in data['targets']] six.assertCountEqual(self, targets, uuids)
def test_prepare_instance_netboot_iscsi( self, get_image_info_mock, cache_mock, dhcp_factory_mock, switch_pxe_config_mock, set_boot_device_mock, create_pxe_config_mock): http_url = 'http://192.1.2.3:1234' self.config(ipxe_enabled=False, group='pxe') self.config(http_url=http_url, group='deploy') provider_mock = mock.MagicMock() dhcp_factory_mock.return_value = provider_mock vol_id = uuidutils.generate_uuid() obj_utils.create_test_volume_target( self.context, node_id=self.node.id, volume_type='iscsi', boot_index=0, volume_id='1234', uuid=vol_id, properties={'target_lun': 0, 'target_portal': 'fake_host:3260', 'target_iqn': 'fake_iqn', 'auth_username': '******', 'auth_password': '******'}) with task_manager.acquire(self.context, self.node.uuid) as task: task.node.driver_internal_info = { 'boot_from_volume': vol_id} dhcp_opts = pxe_utils.dhcp_options_for_instance(task, ipxe_enabled=True) pxe_config_path = pxe_utils.get_pxe_config_file_path( task.node.uuid) task.node.properties['capabilities'] = 'boot_mode:bios' task.driver.boot.prepare_instance(task) self.assertFalse(get_image_info_mock.called) self.assertFalse(cache_mock.called) provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts) create_pxe_config_mock.assert_called_once_with( task, mock.ANY, CONF.pxe.pxe_config_template, ipxe_enabled=True) switch_pxe_config_mock.assert_called_once_with( pxe_config_path, None, boot_modes.LEGACY_BIOS, False, ipxe_enabled=True, iscsi_boot=True, ramdisk_boot=False) set_boot_device_mock.assert_called_once_with(task, boot_devices.PXE, persistent=True)