def execute(self, context, **kwargs): scheduler_hints = kwargs.pop('scheduler_hints', None) db_vt = kwargs.pop('volume_type') kwargs['volume_type'] = None if db_vt: kwargs['volume_type'] = objects.VolumeType() objects.VolumeType()._from_db_object(context, kwargs['volume_type'], db_vt) request_spec = objects.RequestSpec(**kwargs) filter_properties = {} if scheduler_hints: filter_properties['scheduler_hints'] = scheduler_hints self._cast_create_volume(context, request_spec, filter_properties)
def test_list_groups_detail_json(self, mock_vol_type_get_all_by_group): volume_type_ids = [fake.VOLUME_TYPE_ID, fake.VOLUME_TYPE2_ID] vol_type_objs = [objects.VolumeType(context=self.ctxt, id=i) for i in volume_type_ids] vol_types = objects.VolumeTypeList(context=self.ctxt, objects=vol_type_objs) mock_vol_type_get_all_by_group.return_value = vol_types # TODO(geguileo): One `volume_type_ids` gets sorted out make proper # changes here # self.group1.volume_type_ids = volume_type_ids # self.group1.save() # self.group2.volume_type_ids = volume_type_ids # self.group2.save() # self.group3.volume_type_ids = volume_type_ids # self.group3.save() req = fakes.HTTPRequest.blank('/v3/%s/groups/detail' % fake.PROJECT_ID, version=GROUP_MICRO_VERSION) res_dict = self.controller.detail(req) self.assertEqual(1, len(res_dict)) index = 0 for group in [self.group3, self.group2, self.group1]: self.assertEqual(group.id, res_dict['groups'][index]['id']) self.assertEqual([fake.VOLUME_TYPE_ID, fake.VOLUME_TYPE2_ID], res_dict['groups'][index]['volume_types']) self.assertEqual('test_group', res_dict['groups'][index]['name']) self.assertTrue({'availability_zone', 'description', 'status'}.issubset( set(res_dict['groups'][index].keys()))) index += 1
def test_show_group(self, mock_vol_get_all_by_group, mock_vol_type_get_all_by_group): volume_objs = [ objects.Volume(context=self.ctxt, id=i) for i in [fake.VOLUME_ID] ] volumes = objects.VolumeList(context=self.ctxt, objects=volume_objs) mock_vol_get_all_by_group.return_value = volumes vol_type_objs = [ objects.VolumeType(context=self.ctxt, id=i) for i in [fake.VOLUME_TYPE_ID] ] vol_types = objects.VolumeTypeList(context=self.ctxt, objects=vol_type_objs) mock_vol_type_get_all_by_group.return_value = vol_types req = fakes.HTTPRequest.blank('/v3/%s/groups/%s' % (fake.PROJECT_ID, self.group1.id), version=GROUP_MICRO_VERSION) res_dict = self.controller.show(req, self.group1.id) self.assertEqual(1, len(res_dict)) self.assertEqual('az1', res_dict['group']['availability_zone']) self.assertEqual('this is a test group', res_dict['group']['description']) self.assertEqual('test_group', res_dict['group']['name']) self.assertEqual('creating', res_dict['group']['status']) self.assertEqual([fake.VOLUME_TYPE_ID], res_dict['group']['volume_types'])
def test_obj_make_compatible(self): volume_type = objects.VolumeType(context=self.context) volume_type.extra_specs = {'foo': None, 'bar': 'baz'} primitive = volume_type.obj_to_primitive('1.0') volume_type = objects.VolumeType.obj_from_primitive(primitive) self.assertEqual('', volume_type.extra_specs['foo']) self.assertEqual('baz', volume_type.extra_specs['bar'])
def from_primitives(cls, spec): """Returns RequestSpec object creating it from legacy dictionary. FIXME(dulek): This should go away in early O as we stop supporting backward compatibility with M. """ spec = spec.copy() spec_obj = cls() vol_props = spec.pop('volume_properties', {}) if vol_props is not None: vol_props = VolumeProperties(**vol_props) spec_obj.volume_properties = vol_props if 'volume' in spec: vol = spec.pop('volume', {}) vol.pop('name', None) if vol is not None: vol = objects.Volume(**vol) spec_obj.volume = vol if 'volume_type' in spec: vol_type = spec.pop('volume_type', {}) if vol_type is not None: vol_type = objects.VolumeType(**vol_type) spec_obj.volume_type = vol_type spec.pop('resource_properties', None) for k, v in spec.items(): setattr(spec_obj, k, v) return spec_obj
def test_update(self, mock_policy, mock_volume_types_get, mock_group_type_get, mock_group, mock_update_quota, mock_cast_create_group, mock_volume_get_all, mock_rpc_update_group): vol_type_dict = {'id': fake.VOLUME_TYPE_ID, 'name': 'fake_volume_type'} vol_type = objects.VolumeType(self.ctxt, **vol_type_dict) mock_volume_types_get.return_value = [{'id': fake.VOLUME_TYPE_ID}] mock_group_type_get.return_value = {'id': fake.GROUP_TYPE_ID} name = "test_group" description = "this is a test group" grp = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID], availability_zone='nova', host=None, name=name, description=description, status=fields.GroupStatus.CREATING) mock_group.return_value = grp ret_group = self.group_api.create(self.ctxt, name, description, fake.GROUP_TYPE_ID, [fake.VOLUME_TYPE_ID], availability_zone='nova') self.assertEqual(grp.obj_to_primitive(), ret_group.obj_to_primitive()) ret_group.volume_types = [vol_type] ret_group.host = "test_host@fakedrv#fakepool" ret_group.status = fields.GroupStatus.AVAILABLE ret_group.id = fake.GROUP_ID vol1 = utils.create_volume( self.ctxt, host=ret_group.host, availability_zone=ret_group.availability_zone, volume_type_id=fake.VOLUME_TYPE_ID) vol2 = utils.create_volume( self.ctxt, host=ret_group.host, availability_zone=ret_group.availability_zone, volume_type_id=fake.VOLUME_TYPE_ID, group_id=fake.GROUP_ID) vol2_dict = { 'id': vol2.id, 'group_id': fake.GROUP_ID, 'volume_type_id': fake.VOLUME_TYPE_ID, 'availability_zone': ret_group.availability_zone, 'host': ret_group.host, 'status': 'available', } mock_volume_get_all.return_value = [vol2_dict] new_name = "new_group_name" new_desc = "this is a new group" self.group_api.update(self.ctxt, ret_group, new_name, new_desc, vol1.id, vol2.id) mock_volume_get_all.assert_called_once_with(mock.ANY, ret_group.id) mock_rpc_update_group.assert_called_once_with(self.ctxt, ret_group, add_volumes=vol1.id, remove_volumes=vol2.id) mock_policy.assert_called_with(self.ctxt, 'update', mock.ANY)
def _from_db_object(context, volume, db_volume, expected_attrs=None): if expected_attrs is None: expected_attrs = [] for name, field in volume.fields.items(): if name in Volume.OPTIONAL_FIELDS: continue value = db_volume.get(name) if isinstance(field, fields.IntegerField): value = value or 0 volume[name] = value # Get data from db_volume object that was queried by joined query # from DB if 'metadata' in expected_attrs: metadata = db_volume.get('volume_metadata', []) volume.metadata = {item['key']: item['value'] for item in metadata} if 'admin_metadata' in expected_attrs: metadata = db_volume.get('volume_admin_metadata', []) volume.admin_metadata = { item['key']: item['value'] for item in metadata } if 'glance_metadata' in expected_attrs: metadata = db_volume.get('volume_glance_metadata', []) volume.glance_metadata = { item['key']: item['value'] for item in metadata } if 'volume_type' in expected_attrs: db_volume_type = db_volume.get('volume_type') if db_volume_type: vt_expected_attrs = [] if 'volume_type.extra_specs' in expected_attrs: vt_expected_attrs.append('extra_specs') volume.volume_type = objects.VolumeType._from_db_object( context, objects.VolumeType(), db_volume_type, expected_attrs=vt_expected_attrs) if 'volume_attachment' in expected_attrs: attachments = base.obj_make_list( context, objects.VolumeAttachmentList(context), objects.VolumeAttachment, db_volume.get('volume_attachment')) volume.volume_attachment = attachments if 'consistencygroup' in expected_attrs: consistencygroup = objects.ConsistencyGroup(context) consistencygroup._from_db_object(context, consistencygroup, db_volume['consistencygroup']) volume.consistencygroup = consistencygroup if 'snapshots' in expected_attrs: snapshots = base.obj_make_list(context, objects.SnapshotList(context), objects.Snapshot, db_volume['snapshots']) volume.snapshots = snapshots volume._context = context volume.obj_reset_changes() return volume
def test_destroy(self, volume_type_destroy): db_volume_type = fake_volume.fake_db_volume_type() volume_type = objects.VolumeType._from_db_object( self.context, objects.VolumeType(), db_volume_type) volume_type.destroy() self.assertTrue(volume_type_destroy.called) admin_context = volume_type_destroy.call_args[0][0] self.assertTrue(admin_context.is_admin)
def __init__(self, backend_or_vol, pool_name=None, **kwargs): # Accept backend name for convenience if isinstance(backend_or_vol, six.string_types): backend_name = backend_or_vol backend_or_vol = self._get_backend(backend_or_vol) elif isinstance(backend_or_vol, self.backend_class): backend_name = backend_or_vol.id elif isinstance(backend_or_vol, Volume): backend_name, pool = backend_or_vol._ovo.host.split('#') pool_name = pool_name or pool for key in backend_or_vol._ovo.fields: if (backend_or_vol._ovo.obj_attr_is_set(key) and key not in self._ignore_keys): kwargs.setdefault(key, getattr(backend_or_vol._ovo, key)) backend_or_vol = backend_or_vol.backend if '__ovo' not in kwargs: kwargs[CONNECTIONS_OVO_FIELD] = ( volume_cmd.objects.VolumeAttachmentList(context=self.CONTEXT)) kwargs['snapshots'] = ( volume_cmd.objects.SnapshotList(context=self.CONTEXT)) self._snapshots = [] self._connections = [] qos_specs = kwargs.pop('qos_specs', None) extra_specs = kwargs.pop('extra_specs', {}) super(Volume, self).__init__(backend_or_vol, **kwargs) self._populate_data() self.local_attach = None # If we overwrote the host, then we ignore pool_name and don't set a # default value or copy the one from the source either. if 'host' not in kwargs and '__ovo' not in kwargs: pool_name = pool_name or backend_or_vol.pool_names[0] self._ovo.host = ('%s@%s#%s' % (CONFIGURED_HOST, backend_name, pool_name)) if qos_specs or extra_specs: if qos_specs: qos_specs = cinder_objs.QualityOfServiceSpecs( id=self.id, name=self.id, consumer='back-end', specs=qos_specs) qos_specs_id = self.id else: qos_specs = qos_specs_id = None self._ovo.volume_type = cinder_objs.VolumeType( context=self.CONTEXT, is_public=True, id=self.id, name=self.id, qos_specs_id=qos_specs_id, extra_specs=extra_specs, qos_specs=qos_specs) self._ovo.volume_type_id = self.id
def _create_volume_type(self, ctxt, volume_type_name, extra_specs=None, is_public=True, projects=None): vol_type = objects.VolumeType(ctxt, name=volume_type_name, is_public=is_public, description='', extra_specs=extra_specs, projects=projects) vol_type.create() return vol_type
def test_save(self, volume_type_update): db_volume_type = fake_volume.fake_db_volume_type() volume_type = objects.VolumeType._from_db_object( self.context, objects.VolumeType(), db_volume_type) volume_type.description = 'foobar' volume_type.save() volume_type_update.assert_called_once_with(self.context, volume_type.id, volume_type.name, volume_type.description)
def test_obj_make_compatible(self, version): volume_type = objects.VolumeType(context=self.context) volume_type.extra_specs = {'foo': None, 'bar': 'baz'} volume_type.qos_specs_id = fake.QOS_SPEC_ID primitive = volume_type.obj_to_primitive(version) volume_type = objects.VolumeType.obj_from_primitive(primitive) foo = '' if version == '1.0' else None self.assertEqual(foo, volume_type.extra_specs['foo']) self.assertEqual('baz', volume_type.extra_specs['bar']) self.assertFalse(volume_type.obj_attr_is_set('qos_specs_id'))
def _create_fake_type(self, context): vol_type = { 'name': 'fake_volume1', 'extra_specs': {}, 'is_public': True, 'projects': [], 'description': 'A fake volume type' } volume_type = objects.VolumeType(context=context, **vol_type) volume_type.create() return volume_type
def test_destroy_with_vol_types(self, fake_get_vol_types, qos_fake_disassociate, qos_fake_delete): qos_object = objects.QualityOfServiceSpecs._from_db_object( self.context, objects.QualityOfServiceSpecs(), fake_qos) fake_get_vol_types.return_value = objects.VolumeTypeList( objects=[objects.VolumeType(id=fake.VOLUME_TYPE_ID)]) self.assertRaises(exception.QoSSpecsInUse, qos_object.destroy) qos_object.destroy(force=True) qos_fake_delete.assert_called_once_with(mock.ANY, fake_qos['id']) qos_fake_disassociate.assert_called_once_with(self.context, fake_qos['id'])
def test_destroy(self, volume_type_destroy, utcnow_mock): volume_type_destroy.return_value = { 'deleted': True, 'deleted_at': utcnow_mock.return_value } db_volume_type = fake_volume.fake_db_volume_type() volume_type = objects.VolumeType._from_db_object( self.context, objects.VolumeType(), db_volume_type) volume_type.destroy() self.assertTrue(volume_type_destroy.called) admin_context = volume_type_destroy.call_args[0][0] self.assertTrue(admin_context.is_admin) self.assertTrue(volume_type.deleted) self.assertEqual(utcnow_mock.return_value.replace(tzinfo=pytz.UTC), volume_type.deleted_at)
def test_create(self, volume_type_create): db_volume_type = fake_volume.fake_db_volume_type() volume_type_create.return_value = db_volume_type volume_type = objects.VolumeType(context=self.context) volume_type.name = db_volume_type['name'] volume_type.extra_specs = db_volume_type['extra_specs'] volume_type.is_public = db_volume_type['is_public'] volume_type.projects = db_volume_type['projects'] volume_type.description = db_volume_type['description'] volume_type.create() volume_type_create.assert_called_once_with( self.context, db_volume_type['name'], db_volume_type['extra_specs'], db_volume_type['is_public'], db_volume_type['projects'], db_volume_type['description'])
def test_list_groups_detail_json(self, mock_vol_type_get_all_by_group): volume_type_ids = [fake.VOLUME_TYPE_ID, fake.VOLUME_TYPE2_ID] vol_type_objs = [ objects.VolumeType(context=self.ctxt, id=i) for i in volume_type_ids ] vol_types = objects.VolumeTypeList(context=self.ctxt, objects=vol_type_objs) mock_vol_type_get_all_by_group.return_value = vol_types self.group1.volume_type_ids = volume_type_ids self.group1.save() self.group2.volume_type_ids = volume_type_ids self.group2.save() self.group3.volume_type_ids = volume_type_ids self.group3.save() req = fakes.HTTPRequest.blank('/v3/%s/groups/detail' % fake.PROJECT_ID, version=GROUP_MICRO_VERSION) res_dict = self.controller.detail(req) self.assertEqual(1, len(res_dict)) self.assertEqual('az1', res_dict['groups'][0]['availability_zone']) self.assertEqual('this is a test group', res_dict['groups'][0]['description']) self.assertEqual('test_group', res_dict['groups'][0]['name']) self.assertEqual(self.group3.id, res_dict['groups'][0]['id']) self.assertEqual('creating', res_dict['groups'][0]['status']) self.assertEqual([fake.VOLUME_TYPE_ID, fake.VOLUME_TYPE2_ID], res_dict['groups'][0]['volume_types']) self.assertEqual('az1', res_dict['groups'][1]['availability_zone']) self.assertEqual('this is a test group', res_dict['groups'][1]['description']) self.assertEqual('test_group', res_dict['groups'][1]['name']) self.assertEqual(self.group2.id, res_dict['groups'][1]['id']) self.assertEqual('creating', res_dict['groups'][1]['status']) self.assertEqual([fake.VOLUME_TYPE_ID, fake.VOLUME_TYPE2_ID], res_dict['groups'][1]['volume_types']) self.assertEqual('az1', res_dict['groups'][2]['availability_zone']) self.assertEqual('this is a test group', res_dict['groups'][2]['description']) self.assertEqual('test_group', res_dict['groups'][2]['name']) self.assertEqual(self.group1.id, res_dict['groups'][2]['id']) self.assertEqual('creating', res_dict['groups'][2]['status']) self.assertEqual([fake.VOLUME_TYPE_ID, fake.VOLUME_TYPE2_ID], res_dict['groups'][2]['volume_types'])
def _from_db_object(context, volume, db_volume, expected_attrs=None): if expected_attrs is None: expected_attrs = [] for name, field in volume.fields.items(): if name in OPTIONAL_FIELDS: continue value = db_volume.get(name) if isinstance(field, fields.IntegerField): value = value or 0 volume[name] = value # Get data from db_volume object that was queried by joined query # from DB if 'metadata' in expected_attrs: volume.metadata = {} metadata = db_volume.get('volume_metadata', []) if metadata: volume.metadata = { item['key']: item['value'] for item in metadata } if 'admin_metadata' in expected_attrs: volume.admin_metadata = {} metadata = db_volume.get('volume_admin_metadata', []) if metadata: volume.admin_metadata = { item['key']: item['value'] for item in metadata } if 'volume_type' in expected_attrs: db_volume_type = db_volume.get('volume_type') if db_volume_type: volume.volume_type = objects.VolumeType._from_db_object( context, objects.VolumeType(), db_volume_type, expected_attrs='extra_specs') if 'volume_attachment' in expected_attrs: attachments = base.obj_make_list( context, objects.VolumeAttachmentList(context), objects.VolumeAttachment, db_volume.get('volume_attachment')) volume.volume_attachment = attachments.objects volume._context = context volume.obj_reset_changes() return volume
def setUp(self, enforce_scope=False, enforce_new_defaults=False, *args, **kwargs): super().setUp(enforce_scope, enforce_new_defaults, *args, **kwargs) self.controller = vta.VolumeTypeAccessController() self.volume_type = objects.VolumeType( self.project_admin_context, name='private_volume_type', is_public=False, description='volume type for srbac testing', extra_specs=None, projects=[self.project_id, self.project_id_other]) self.volume_type.create() self.addCleanup(self.volume_type.destroy) self.api_version = mv.BASE_VERSION self.api_path = (f'/v3/{self.project_id}/types/' f'{self.volume_type.id}/os-volume-type-access')
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_show_group_with_list_volume(self, mock_vol_get_all_by_group, mock_vol_type_get_all_by_group): volume_objs = [ objects.Volume(context=self.ctxt, id=i) for i in [fake.VOLUME_ID] ] volumes = objects.VolumeList(context=self.ctxt, objects=volume_objs) mock_vol_get_all_by_group.return_value = volumes vol_type_objs = [ objects.VolumeType(context=self.ctxt, id=i) for i in [fake.VOLUME_TYPE_ID] ] vol_types = objects.VolumeTypeList(context=self.ctxt, objects=vol_type_objs) mock_vol_type_get_all_by_group.return_value = vol_types # If the microversion >= 3.25 and "list_volume=True", "volumes" should # be contained in the response body. req = fakes.HTTPRequest.blank('/v3/%s/groups/%s?list_volume=True' % (fake.PROJECT_ID, self.group1.id), version='3.25') res_dict = self.controller.show(req, self.group1.id) self.assertEqual(1, len(res_dict)) self.assertEqual([fake.VOLUME_ID], res_dict['group']['volumes']) # If the microversion >= 3.25 but "list_volume" is missing, "volumes" # should not be contained in the response body. req = fakes.HTTPRequest.blank('/v3/%s/groups/%s' % (fake.PROJECT_ID, self.group1.id), version='3.25') res_dict = self.controller.show(req, self.group1.id) self.assertEqual(1, len(res_dict)) self.assertIsNone(res_dict['group'].get('volumes', None)) # If the microversion < 3.25, "volumes" should not be contained in the # response body. req = fakes.HTTPRequest.blank('/v3/%s/groups/%s?list_volume=True' % (fake.PROJECT_ID, self.group1.id), version='3.24') res_dict = self.controller.show(req, self.group1.id) self.assertEqual(1, len(res_dict)) self.assertIsNone(res_dict['group'].get('volumes', None))
def test_list_group_with_list_volume(self, version, has_list_volume, mock_vol_get_all_by_group, mock_vol_type_get_all_by_group): volume_objs = [ objects.Volume(context=self.ctxt, id=i) for i in [fake.VOLUME_ID] ] volumes = objects.VolumeList(context=self.ctxt, objects=volume_objs) mock_vol_get_all_by_group.return_value = volumes vol_type_objs = [ objects.VolumeType(context=self.ctxt, id=i) for i in [fake.VOLUME_TYPE_ID] ] vol_types = objects.VolumeTypeList(context=self.ctxt, objects=vol_type_objs) mock_vol_type_get_all_by_group.return_value = vol_types if has_list_volume: req = fakes.HTTPRequest.blank( '/v3/%s/groups/detail?list_volume=True' % fake.PROJECT_ID, version=version) else: req = fakes.HTTPRequest.blank('/v3/%s/groups/detail' % fake.PROJECT_ID, version=version) res_dict = self.controller.detail(req) # If the microversion >= 3.25 and "list_volume=True", "volumes" should # be contained in the response body. Else,"volumes" should not be # contained in the response body. self.assertEqual(3, len(res_dict['groups'])) if (version, has_list_volume) == ('3.25', True): self.assertEqual([fake.VOLUME_ID], res_dict['groups'][0]['volumes']) else: self.assertIsNone(res_dict['groups'][0].get('volumes', None)) # "volumes" should not be contained in the response body when list # groups without detail. res_dict = self.controller.index(req) self.assertIsNone(res_dict['groups'][0].get('volumes', None))
def test_obj_load_attr(self, mock_sl_get_all_for_volume, mock_cg_get_by_id, mock_va_get_all_by_vol, mock_vt_get_by_id, mock_admin_metadata_get, mock_glance_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 glance_metadata lazy-loaded field glance_metadata = [{'key': 'foo', 'value': 'bar'}] mock_glance_metadata_get.return_value = glance_metadata self.assertEqual({'foo': 'bar'}, volume.glance_metadata) mock_glance_metadata_get.assert_called_once_with( self.context, volume.id) # Test volume_type lazy-loaded field # Case1. volume.volume_type_id = None self.assertIsNone(volume.volume_type) # Case2. volume2.volume_type_id = 1 fake2 = fake_volume.fake_db_volume() fake2.update({'volume_type_id': fake.volume_id}) volume2 = objects.Volume._from_db_object(self.context, objects.Volume(), fake2) volume_type = objects.VolumeType(context=self.context, id=fake.volume_type_id) mock_vt_get_by_id.return_value = volume_type self.assertEqual(volume_type, volume2.volume_type) mock_vt_get_by_id.assert_called_once_with(self.context, volume2.volume_type_id) # Test consistencygroup lazy-loaded field consistencygroup = objects.ConsistencyGroup( context=self.context, id=fake.consistency_group_id) mock_cg_get_by_id.return_value = consistencygroup self.assertEqual(consistencygroup, volume.consistencygroup) mock_cg_get_by_id.assert_called_once_with(self.context, volume.consistencygroup_id) # Test snapshots lazy-loaded field snapshots = objects.SnapshotList(context=self.context, id=fake.snapshot_id) mock_sl_get_all_for_volume.return_value = snapshots self.assertEqual(snapshots, volume.snapshots) mock_sl_get_all_for_volume.assert_called_once_with( self.context, volume.id) # Test volume_attachment lazy-loaded field va_objs = [ objects.VolumeAttachment(context=self.context, id=i) for i in [fake.object_id, fake.object2_id, fake.object3_id] ] 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 _from_db_object(cls, context, volume, db_volume, expected_attrs=None): if expected_attrs is None: expected_attrs = [] for name, field in volume.fields.items(): if name in cls.OPTIONAL_FIELDS: continue value = db_volume.get(name) if isinstance(field, fields.IntegerField): value = value or 0 volume[name] = value # Get data from db_volume object that was queried by joined query # from DB if 'metadata' in expected_attrs: metadata = db_volume.get('volume_metadata', []) volume.metadata = {item['key']: item['value'] for item in metadata} if 'admin_metadata' in expected_attrs: metadata = db_volume.get('volume_admin_metadata', []) volume.admin_metadata = {item['key']: item['value'] for item in metadata} if 'glance_metadata' in expected_attrs: metadata = db_volume.get('volume_glance_metadata', []) volume.glance_metadata = {item['key']: item['value'] for item in metadata} if 'volume_type' in expected_attrs: db_volume_type = db_volume.get('volume_type') if db_volume_type: vt_expected_attrs = [] if 'volume_type.extra_specs' in expected_attrs: vt_expected_attrs.append('extra_specs') volume.volume_type = objects.VolumeType._from_db_object( context, objects.VolumeType(), db_volume_type, expected_attrs=vt_expected_attrs) if 'volume_attachment' in expected_attrs: attachments = base.obj_make_list( context, objects.VolumeAttachmentList(context), objects.VolumeAttachment, db_volume.get('volume_attachment')) volume.volume_attachment = attachments if volume.consistencygroup_id and 'consistencygroup' in expected_attrs: consistencygroup = objects.ConsistencyGroup(context) consistencygroup._from_db_object(context, consistencygroup, db_volume['consistencygroup']) volume.consistencygroup = consistencygroup if 'snapshots' in expected_attrs: snapshots = base.obj_make_list( context, objects.SnapshotList(context), objects.Snapshot, db_volume['snapshots']) volume.snapshots = snapshots if 'cluster' in expected_attrs: db_cluster = db_volume.get('cluster') # If this volume doesn't belong to a cluster the cluster field in # the ORM instance will have value of None. if db_cluster: volume.cluster = objects.Cluster(context) objects.Cluster._from_db_object(context, volume.cluster, db_cluster) else: volume.cluster = None if volume.group_id and 'group' in expected_attrs: group = objects.Group(context) group._from_db_object(context, group, db_volume['group']) volume.group = group volume._context = context volume.obj_reset_changes() return volume
def fake_volume_type_obj(context, **updates): return objects.VolumeType._from_db_object(context, objects.VolumeType(), fake_db_volume_type(**updates))