def test_save_with_admin_metadata(self, volume_update, admin_metadata_update): # Test with no admin context db_volume = fake_volume.fake_db_volume() volume = objects.Volume._from_db_object(self.context, objects.Volume(), db_volume) volume.admin_metadata = {'key1': 'value1'} volume.save() self.assertFalse(admin_metadata_update.called) # Test with admin context admin_context = context.RequestContext(self.user_id, self.project_id, is_admin=True) volume = objects.Volume._from_db_object(admin_context, objects.Volume(), db_volume) volume.admin_metadata = {'key1': 'value1'} volume.save() admin_metadata_update.assert_called_once_with( admin_context, volume.id, {'key1': 'value1'}, True)
def test_obj_make_compatible_use_quota_added(self, version, ovo, expected): volume = objects.Volume(self.context, **ovo) # When serializing to v1.38 we'll lose the use_quota value so it will # be recalculated based on the Volume values serializer = ovo_base.CinderObjectSerializer(version) primitive = serializer.serialize_entity(self.context, volume) converted_volume = objects.Volume.obj_from_primitive(primitive) self.assertIs(expected, converted_volume.use_quota)
def test_create(self, ovo, expected, volume_create): db_volume = fake_volume.fake_db_volume() volume_create.return_value = db_volume volume = objects.Volume(context=self.context, **ovo) volume.create() self.assertEqual(db_volume['id'], volume.id) use_quota = volume_create.call_args[0][1]['use_quota'] # TODO: (Y release) remove next line self.assertIs(expected, use_quota)
def test_obj_fields(self): volume = objects.Volume(context=self.context, id=fake.VOLUME_ID, name_id=fake.VOLUME_NAME_ID) self.assertEqual([ 'name', 'name_id', 'volume_metadata', 'volume_admin_metadata', 'volume_glance_metadata' ], volume.obj_extra_fields) self.assertEqual('volume-%s' % fake.VOLUME_NAME_ID, volume.name) self.assertEqual(fake.VOLUME_NAME_ID, volume.name_id)
def test_finish_volume_migration(self, volume_update, metadata_update, src_vol_type_id, dest_vol_type_id): src_volume_db = fake_volume.fake_db_volume( **{'id': fake.VOLUME_ID, 'volume_type_id': src_vol_type_id}) if src_vol_type_id: src_volume_db['volume_type'] = fake_volume.fake_db_volume_type( id=src_vol_type_id) dest_volume_db = fake_volume.fake_db_volume( **{'id': fake.VOLUME2_ID, 'volume_type_id': dest_vol_type_id}) if dest_vol_type_id: dest_volume_db['volume_type'] = fake_volume.fake_db_volume_type( id=dest_vol_type_id) expected_attrs = objects.Volume._get_expected_attrs(self.context) src_volume = objects.Volume._from_db_object( self.context, objects.Volume(), src_volume_db, expected_attrs=expected_attrs) dest_volume = objects.Volume._from_db_object( self.context, objects.Volume(), dest_volume_db, expected_attrs=expected_attrs) updated_dest_volume = src_volume.finish_volume_migration( dest_volume) self.assertEqual('deleting', updated_dest_volume.migration_status) self.assertEqual('migration src for ' + src_volume.id, updated_dest_volume.display_description) self.assertEqual(src_volume.id, updated_dest_volume._name_id) self.assertTrue(volume_update.called) ctxt, vol_id, updates = volume_update.call_args[0] self.assertNotIn('volume_type', updates) # Ensure that the destination volume type has not been overwritten self.assertEqual(dest_vol_type_id, getattr(updated_dest_volume, 'volume_type_id')) # Ignore these attributes, since they were updated by # finish_volume_migration ignore_keys = ('id', 'provider_location', '_name_id', 'migration_status', 'display_description', 'status', 'volume_glance_metadata', 'volume_type') dest_vol_dict = {k: updated_dest_volume[k] for k in updated_dest_volume.keys() if k not in ignore_keys} src_vol_dict = {k: src_volume[k] for k in src_volume.keys() if k not in ignore_keys} self.assertEqual(src_vol_dict, dest_vol_dict)
def test_extend_volume(self, mock__check_volume_exist, mock_extend_lun): """Test resize volume.""" volume = objects.Volume(_name_id=uuid.uuid4(), size=1) new_size = 3 mock__check_volume_exist.return_value = { 'capacity_bytes': units.Gi * 1 } mock_extend_lun.return_value = {'success': 1} retval = self.fake_driver.extend_volume(volume, new_size) self.assertIsNone(retval)
def test_save(self, test_cg, volume_update): db_volume = fake_volume.fake_db_volume() volume = objects.Volume._from_db_object(self.context, objects.Volume(), db_volume) volume.display_name = 'foobar' if test_cg: volume.consistencygroup = None volume.save() volume_update.assert_called_once_with(self.context, volume.id, {'display_name': 'foobar'})
def _create_volume(self, ctxt=None, display_name=None, project_id=None): """Create a volume object.""" ctxt = ctxt or self.ctxt volume = objects.Volume(ctxt) volume.display_name = display_name volume.project_id = project_id volume.status = 'available' volume.attach_status = 'attached' volume.create() return volume
def test_lazy_load_volume(self, volume_get_mock): volume = objects.Volume(self.context, id=fake.VOLUME_ID) volume_get_mock.return_value = volume attach = objects.VolumeAttachment(self.context, id=fake.ATTACHMENT_ID, volume_id=volume.id) r = attach.volume self.assertEqual(volume, r) volume_get_mock.assert_called_once_with(self.context, volume.id)
def test_create_volume_from_snapshot(self, mock_create_volume_from_snapshot, mock_check_snapshot_exist, mock_check_volume_exist): result1 = True result2 = False self.fake_driver.client = fs_client.RestCommon( 'https://fake_rest_site', 'user', 'password') volume = objects.Volume(_name_id=uuid.uuid4()) snapshot = objects.Snapshot(id=uuid.uuid4(), volume_size=2, volume=volume) volume1 = objects.Volume(_name_id=uuid.uuid4(), size=2) volume2 = objects.Volume(_name_id=uuid.uuid4(), size=1) mock_create_volume_from_snapshot.return_value = {'result': 0} mock_check_volume_exist.return_value = result2 mock_check_snapshot_exist.return_value = result1 retval = self.fake_driver.create_volume_from_snapshot( volume1, snapshot) self.assertIsNone(retval) mock_check_volume_exist.return_value = result1 try: self.fake_driver.create_volume_from_snapshot(volume1, snapshot) except Exception as e: self.assertEqual(exception.VolumeBackendAPIException, type(e)) mock_check_volume_exist.return_value = result2 mock_check_snapshot_exist.return_value = result2 try: self.fake_driver.create_volume_from_snapshot(volume1, snapshot) except Exception as e: self.assertEqual(exception.VolumeBackendAPIException, type(e)) mock_check_volume_exist.return_value = result2 mock_check_snapshot_exist.return_value = result1 try: self.fake_driver.create_volume_from_snapshot(volume2, snapshot) except Exception as e: self.assertEqual(exception.VolumeBackendAPIException, type(e))
def create_volume(ctxt, host='test_host', display_name='test_volume', display_description='this is a test volume', status='available', migration_status=None, size=1, availability_zone='fake_az', volume_type_id=None, replication_status='disabled', replication_extended_status=None, replication_driver_data=None, consistencygroup_id=None, group_id=None, previous_status=None, testcase_instance=None, **kwargs): """Create a volume object in the DB.""" vol = {} vol['size'] = size vol['host'] = host vol['user_id'] = ctxt.user_id vol['project_id'] = ctxt.project_id vol['status'] = status if migration_status: vol['migration_status'] = migration_status vol['display_name'] = display_name vol['display_description'] = display_description vol['attach_status'] = fields.VolumeAttachStatus.DETACHED vol['availability_zone'] = availability_zone if consistencygroup_id: vol['consistencygroup_id'] = consistencygroup_id if group_id: vol['group_id'] = group_id if volume_type_id: vol['volume_type_id'] = volume_type_id for key in kwargs: vol[key] = kwargs[key] vol['replication_status'] = replication_status if replication_extended_status: vol['replication_extended_status'] = replication_extended_status if replication_driver_data: vol['replication_driver_data'] = replication_driver_data if previous_status: vol['previous_status'] = previous_status volume = objects.Volume(ctxt, **vol) volume.create() # If we get a TestCase instance we add cleanup if testcase_instance: testcase_instance.addCleanup(volume.destroy) return volume
def test_delete_snapshot(self, mock__check_snapshot_exist, mock_delete_snapshot): """Test delete snapshot.""" volume = objects.Volume(_name_id=uuid.uuid4(), size=1) snapshot = objects.Snapshot(id=uuid.uuid4(), volume_size=2, volume=volume) mock__check_snapshot_exist.return_value = True mock_delete_snapshot.return_value = {'success': 1} retval = self.fake_driver.delete_snapshot(snapshot) self.assertIsNone(retval)
def test_create_volume_from_snapshot(self, mock_lun_from_snapshot, mock_extend_lun): """Test create new volume from snapshot of src volume.""" volume = objects.Volume(_name_id=uuid.uuid4(), size=1) snapshot = objects.Snapshot(id=uuid.uuid4(), volume_size=2, volume=volume) mock_lun_from_snapshot.return_value = {'success': 1} mock_extend_lun.return_value = {'success': 1} retval = self.fake_driver.create_volume_from_snapshot(volume, snapshot) self.assertIsNone(retval)
def test_obj_fields(self): volume = objects.Volume(context=self.context, id=fake.VOLUME_ID, _name_id=fake.VOLUME_NAME_ID) snapshot = objects.Snapshot(context=self.context, id=fake.VOLUME_ID, volume=volume) self.assertEqual(['name', 'volume_name'], snapshot.obj_extra_fields) self.assertEqual('snapshot-%s' % fake.VOLUME_ID, snapshot.name) self.assertEqual('volume-%s' % fake.VOLUME_NAME_ID, snapshot.volume_name)
def test_create_snapshot(self, mock_create_snapshot): self.fake_driver.client = fs_client.RestCommon( 'https://fake_rest_site', 'user', 'password') volume = objects.Volume(_name_id=uuid.uuid4()) snapshot = objects.Snapshot(id=uuid.uuid4(), volume_id=uuid.uuid4(), volume=volume) retval = self.fake_driver.create_snapshot(snapshot) self.assertIsNone(retval) mock_create_snapshot.assert_called_once_with( snapshot_name=snapshot.name, vol_name=volume.name)
def fake_volume_obj(context, **updates): if updates.get('encryption_key_id'): assert is_uuid_like(updates['encryption_key_id']) expected_attrs = updates.pop('expected_attrs', ['metadata', 'admin_metadata']) vol = objects.Volume._from_db_object(context, objects.Volume(), fake_db_volume(**updates), expected_attrs=expected_attrs) return vol
def _create_volume(self, context, updates=None): db_volume = {'status': 'available', 'host': 'test', 'availability_zone': 'fake_zone', 'attach_status': 'detached'} if updates: db_volume.update(updates) volume = objects.Volume(context=context, **db_volume) volume.create() return volume
def test_obj_load_attr(self, mock_va_get_all_by_vol, mock_vt_get_by_id, mock_admin_metadata_get, mock_metadata_get): volume = objects.Volume._from_db_object( self.context, objects.Volume(), fake_volume.fake_db_volume()) # Test metadata lazy-loaded field metadata = {'foo': 'bar'} mock_metadata_get.return_value = metadata self.assertEqual(metadata, volume.metadata) mock_metadata_get.assert_called_once_with(self.context, volume.id) # Test volume_type lazy-loaded field volume_type = objects.VolumeType(context=self.context, id=5) mock_vt_get_by_id.return_value = volume_type self.assertEqual(volume_type, volume.volume_type) mock_vt_get_by_id.assert_called_once_with(self.context, volume.volume_type_id) # Test volume_attachment lazy-loaded field va_objs = [objects.VolumeAttachment(context=self.context, id=i) for i in [3, 4, 5]] va_list = objects.VolumeAttachmentList(context=self.context, objects=va_objs) mock_va_get_all_by_vol.return_value = va_list self.assertEqual(va_list, volume.volume_attachment) mock_va_get_all_by_vol.assert_called_once_with(self.context, volume.id) # Test admin_metadata lazy-loaded field - user context adm_metadata = {'bar': 'foo'} mock_admin_metadata_get.return_value = adm_metadata self.assertEqual({}, volume.admin_metadata) self.assertFalse(mock_admin_metadata_get.called) # Test admin_metadata lazy-loaded field - admin context adm_context = self.context.elevated() volume = objects.Volume._from_db_object(adm_context, objects.Volume(), fake_volume.fake_db_volume()) adm_metadata = {'bar': 'foo'} mock_admin_metadata_get.return_value = adm_metadata self.assertEqual(adm_metadata, volume.admin_metadata) mock_admin_metadata_get.assert_called_once_with(adm_context, volume.id)
def test_cloned_volume( self, mock_create_volume_from_volume, mock__check_volume_exist): self.fake_driver.client = fs_client.RestCommon( 'https://fake_rest_site', 'user', 'password') volume = objects.Volume(_name_id=uuid.uuid4(), size=1) src_volume = objects.Volume(_name_id=uuid.uuid4()) result1 = True result2 = False mock__check_volume_exist.return_value = result1 retval = self.fake_driver.create_cloned_volume(volume, src_volume) self.assertIsNone(retval) mock_create_volume_from_volume.assert_called_once_with( vol_name=volume.name, vol_size=volume.size * 1024, src_vol_name=src_volume.name) mock__check_volume_exist.return_value = result2 try: self.fake_driver.create_cloned_volume(volume, src_volume) except Exception as e: self.assertEqual(exception.VolumeBackendAPIException, type(e))
def test_obj_make_compatible_groups_added(self, version): extra_data = {'group_id': fake.GROUP_ID, 'group': objects.Group()} volume = objects.Volume(self.context, host='host', **extra_data) serializer = ovo_base.CinderObjectSerializer(version) primitive = serializer.serialize_entity(self.context, volume) converted_volume = objects.Volume.obj_from_primitive(primitive) is_set = version == '1.10' for key in extra_data: self.assertEqual(is_set, converted_volume.obj_attr_is_set(key)) self.assertEqual('host', converted_volume.host)
def setUp(self): super(ImageVolumeCacheTestCase, self).setUp() self.mock_db = mock.Mock() self.mock_volume_api = mock.Mock() self.context = ctxt.get_admin_context() self.volume = models.Volume() vol_params = {'id': fake.VOLUME_ID, 'host': 'foo@bar#whatever', 'cluster_name': 'cluster', 'size': 0} self.volume.update(vol_params) self.volume_ovo = objects.Volume(self.context, **vol_params)
def _create_volume(self): vol = { 'display_description': 'Test Desc', 'size': 1, 'status': 'available', 'availability_zone': 'az', 'host': 'dummy', 'attach_status': 'no', } volume = objects.Volume(context=self.context, **vol) volume.create() return volume
def test_save_with_volumes(self): consistencygroup = objects.ConsistencyGroup._from_db_object( self.context, objects.ConsistencyGroup(), fake_consistencygroup) volumes_objs = [objects.Volume(context=self.context, id=i) for i in [3, 4, 5]] volumes = objects.VolumeList(objects=volumes_objs) consistencygroup.name = 'foobar' consistencygroup.volumes = volumes self.assertEqual({'name': 'foobar', 'volumes': volumes}, consistencygroup.obj_get_changes()) self.assertRaises(exception.ObjectActionError, consistencygroup.save)
def finish_attach(self, instance_uuid, host_name, mount_point, attach_mode='rw'): with self.obj_as_admin(): db_volume, updated_values = db.volume_attached( self._context, self.id, instance_uuid, host_name, mount_point, attach_mode) self.update(updated_values) self.obj_reset_changes(updated_values.keys()) return objects.Volume._from_db_object(self._context, objects.Volume(), db_volume)
def execute(self, context, optional_args, **kwargs): """Creates a database entry for the given inputs and returns details. Accesses the database and creates a new entry for the to be created volume using the given volume properties which are extracted from the input kwargs (and associated requirements this task needs). These requirements should be previously satisfied and validated by a pre-cursor task. """ volume_properties = { 'size': kwargs.pop('size'), 'user_id': context.user_id, 'project_id': context.project_id, 'status': 'creating', 'attach_status': 'detached', 'encryption_key_id': kwargs.pop('encryption_key_id'), # Rename these to the internal name. 'display_description': kwargs.pop('description'), 'display_name': kwargs.pop('name'), 'replication_status': 'disabled', 'multiattach': kwargs.pop('multiattach'), } # Merge in the other required arguments which should provide the rest # of the volume property fields (if applicable). volume_properties.update(kwargs) volume = objects.Volume(context=context, **volume_properties) volume.create() # FIXME(dulek): We're passing this volume_properties dict through RPC # in request_spec. This shouldn't be needed, most data is replicated # in both volume and other places. We should make Newton read data # from just one correct place and leave just compatibility code. # # Right now - let's move it to versioned objects to be able to make # non-backward compatible changes. volume_properties = objects.VolumeProperties(**volume_properties) return { 'volume_id': volume['id'], 'volume_properties': volume_properties, # NOTE(harlowja): it appears like further usage of this volume # result actually depend on it being a sqlalchemy object and not # just a plain dictionary so that's why we are storing this here. # # In the future where this task results can be serialized and # restored automatically for continued running we will need to # resolve the serialization & recreation of this object since raw # sqlalchemy objects can't be serialized. 'volume': volume, }
def test_obj_make_compatible_cluster_added(self, version): extra_data = {'cluster_name': 'cluster_name', 'cluster': objects.Cluster()} volume = objects.Volume(self.context, host='host', **extra_data) serializer = ovo_base.CinderObjectSerializer(version) primitive = serializer.serialize_entity(self.context, volume) converted_volume = objects.Volume.obj_from_primitive(primitive) is_set = version == '1.7' for key in extra_data: self.assertEqual(is_set, converted_volume.obj_attr_is_set(key)) self.assertEqual('host', converted_volume.host)
def test_initialize_connection(self): with mock.patch.object(self.driver, "_rpc_call", self.jsonrpcclient.call): db_volume = fake_volume.fake_db_volume() db_volume['provider_location'] = "127.0.0.1:3262 RDMA " \ "2016-06.io.spdk:cnode2 1" ctxt = context.get_admin_context() db_volume = objects.Volume._from_db_object(ctxt, objects.Volume(), db_volume) target_connector = \ connector.InitiatorConnector.factory(initiator.NVME, utils.get_root_helper()) self.driver.initialize_connection(db_volume, target_connector)
def test_remove_export(self): with mock.patch.object(self.driver, "_rpc_call", self.jsonrpcclient.call): db_volume = fake_volume.fake_db_volume() db_volume['provider_location'] = "127.0.0.1:4420 rdma " \ "2016-06.io.spdk:cnode2" ctxt = context.get_admin_context() db_volume = objects.Volume._from_db_object(ctxt, objects.Volume(), db_volume) with mock.patch.object(self.driver.target_driver, "_rpc_call", self.jsonrpcclient.call): self.driver.create_export(ctxt, db_volume, None) self.assertIsNone(self.driver.remove_export(ctxt, db_volume))
def test_copy_image_to_volume(self, volume_get): with mock.patch.object(self.driver, "_rpc_call", self.jsonrpcclient.call): db_volume = fake_volume.fake_db_volume() db_volume['provider_location'] = "127.0.0.1:3262 RDMA " \ "2016-06.io.spdk:cnode2" ctxt = context.get_admin_context() db_volume = objects.Volume._from_db_object(ctxt, objects.Volume(), db_volume) volume_get.return_value = db_volume with mock.patch.object(self.driver.target_driver, "_rpc_call", self.jsonrpcclient.call): self.driver.copy_image_to_volume(ctxt, db_volume, None, None)
def test_save_with_volumes(self): group = objects.Group._from_db_object( self.context, objects.Group(), fake_group) volumes_objs = [objects.Volume(context=self.context, id=i) for i in [fake.VOLUME_ID, fake.VOLUME2_ID, fake.VOLUME3_ID]] volumes = objects.VolumeList(objects=volumes_objs) group.name = 'foobar' group.volumes = volumes self.assertEqual({'name': 'foobar', 'volumes': volumes}, group.obj_get_changes()) self.assertRaises(exception.ObjectActionError, group.save)