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) volume_update.assert_has_calls([ mock.call(self.context, src_volume.id, mock.ANY), mock.call(self.context, dest_volume.id, mock.ANY) ]) 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_finish_volume_migration(self, volume_update, metadata_update, src_vol_type_id, dest_vol_type_id, src_vol_status=None): 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) if src_vol_status: src_volume_db['status'] = src_vol_status 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) volume_update.assert_has_calls([ mock.call(self.context, src_volume.id, mock.ANY), mock.call(self.context, dest_volume.id, mock.ANY)]) ctxt, vol_id, updates = volume_update.call_args[0] if src_vol_status and src_vol_status == 'retyping': self.assertIn('volume_type', updates) else: 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_copy_volume_to_image_without_core_prop(self): """Test glance_core_properties defined in cinder.conf is empty.""" id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' # Need to mock create, update, copy_volume_to_image with mock.patch.object(glance.GlanceImageService, "create") \ as mock_create: mock_create.side_effect = self.fake_image_service_create with mock.patch.object(volume_api.API, "update") \ as mock_update: mock_update.side_effect = stubs.stub_volume_update with mock.patch.object(volume_rpcapi.VolumeAPI, "copy_volume_to_image") \ as mock_copy_volume_to_image: mock_copy_volume_to_image.side_effect = \ self.fake_rpc_copy_volume_to_image self.override_config('glance_core_properties', []) req = fakes.HTTPRequest.blank( '/v2/tenant1/volumes/%s/action' % id) body = self._get_os_volume_upload_image() res_dict = self.controller._volume_upload_image( req, id, body) expected_res = { 'os-volume_upload_image': { 'id': id, 'updated_at': datetime.datetime(1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), 'status': 'uploading', 'display_description': 'displaydesc', 'size': 1, 'volume_type': fake_volume.fake_db_volume_type( name='vol_type_name'), 'image_id': 1, 'container_format': 'bare', 'disk_format': 'raw', 'image_name': 'image_name' } } self.assertDictMatch(expected_res, res_dict)
def test_from_db_object_with_all_expected_attributes(self): expected_attrs = [ 'metadata', 'admin_metadata', 'glance_metadata', 'volume_type', 'volume_attachment', 'consistencygroup' ] db_metadata = [{'key': 'foo', 'value': 'bar'}] db_admin_metadata = [{'key': 'admin_foo', 'value': 'admin_bar'}] db_glance_metadata = [{'key': 'glance_foo', 'value': 'glance_bar'}] db_volume_type = fake_volume.fake_db_volume_type() db_volume_attachments = fake_volume.fake_db_volume_attachment() db_consistencygroup = fake_consistencygroup.fake_db_consistencygroup() db_snapshots = fake_snapshot.fake_db_snapshot() db_volume = fake_volume.fake_db_volume( volume_metadata=db_metadata, volume_admin_metadata=db_admin_metadata, volume_glance_metadata=db_glance_metadata, volume_type=db_volume_type, volume_attachment=[db_volume_attachments], consistencygroup=db_consistencygroup, snapshots=[db_snapshots], ) volume = objects.Volume._from_db_object(self.context, objects.Volume(), db_volume, expected_attrs) self.assertEqual({'foo': 'bar'}, volume.metadata) self.assertEqual({'admin_foo': 'admin_bar'}, volume.admin_metadata) self.assertEqual({'glance_foo': 'glance_bar'}, volume.glance_metadata) self._compare(self, db_volume_type, volume.volume_type) self._compare(self, db_volume_attachments, volume.volume_attachment) self._compare(self, db_consistencygroup, volume.consistencygroup) self._compare(self, db_snapshots, volume.snapshots)
def test_get_by_id_null_spec(self, volume_type_get): db_volume_type = fake_volume.fake_db_volume_type( extra_specs={'foo': None}) volume_type_get.return_value = db_volume_type volume_type = objects.VolumeType.get_by_id(self.context, fake.VOLUME_TYPE_ID) self._compare(self, db_volume_type, volume_type)
def test_get_by_id_with_string_projects(self, volume_type_get): projects = [fake.PROJECT_ID, fake.PROJECT2_ID] db_volume_type = fake_volume.fake_db_volume_type(projects=projects) volume_type_get.return_value = db_volume_type volume_type = objects.VolumeType.get_by_id(self.context, fake.VOLUME_TYPE_ID) self._compare(self, db_volume_type, volume_type)
def test_copy_volume_to_image(self): self.stubs.Set(volume_api.API, "copy_volume_to_image", stub_upload_volume_to_image_service) id = fake.VOLUME_ID vol = {"container_format": 'bare', "disk_format": 'raw', "image_name": 'image_name', "force": True} body = {"os-volume_upload_image": vol} req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % (fake.PROJECT_ID, id)) res_dict = self.controller._volume_upload_image(req, id, body) expected = {'os-volume_upload_image': {'id': id, 'updated_at': datetime.datetime(1, 1, 1, 1, 1, 1), 'status': 'uploading', 'display_description': 'displaydesc', 'size': 1, 'volume_type': fake_volume.fake_db_volume_type( name='vol_type_name'), 'image_id': fake.IMAGE_ID, 'container_format': 'bare', 'disk_format': 'raw', 'image_name': 'image_name'}} self.assertDictMatch(expected, res_dict)
def stub_volume(id, **kwargs): volume = { "id": id, "user_id": fake.USER_ID, "project_id": fake.PROJECT_ID, "host": "fakehost", "size": 1, "availability_zone": "fakeaz", "attached_mode": "rw", "status": "fakestatus", "migration_status": None, "attach_status": "attached", "bootable": False, "name": "vol name", "display_name": "displayname", "display_description": "displaydesc", "updated_at": datetime.datetime(1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), "created_at": datetime.datetime(1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), "snapshot_id": None, "source_volid": None, "volume_type_id": fake.VOLUME_TYPE_ID, "volume_admin_metadata": [{"key": "attached_mode", "value": "rw"}, {"key": "readonly", "value": "False"}], "volume_type": fake_volume.fake_db_volume_type(name=DEFAULT_VOL_TYPE), "volume_attachment": [], "multiattach": False, "readonly": "False", } volume.update(kwargs) if kwargs.get("volume_glance_metadata", None): volume["bootable"] = True if kwargs.get("attach_status") == "detached": del volume["volume_admin_metadata"][0] return volume
def test_get_all(self, get_all_types): db_volume_type = fake_volume.fake_db_volume_type() get_all_types.return_value = {db_volume_type['name']: db_volume_type} volume_types = objects.VolumeTypeList.get_all(self.context) self.assertEqual(1, len(volume_types)) TestVolumeType._compare(self, db_volume_type, volume_types[0])
def test_from_db_object_with_all_expected_attributes(self): expected_attrs = ['metadata', 'admin_metadata', 'glance_metadata', 'volume_type', 'volume_attachment', 'consistencygroup'] db_metadata = [{'key': 'foo', 'value': 'bar'}] db_admin_metadata = [{'key': 'admin_foo', 'value': 'admin_bar'}] db_glance_metadata = [{'key': 'glance_foo', 'value': 'glance_bar'}] db_volume_type = fake_volume.fake_db_volume_type() db_volume_attachments = fake_volume.fake_db_volume_attachment() db_consistencygroup = fake_consistencygroup.fake_db_consistencygroup() db_snapshots = fake_snapshot.fake_db_snapshot() db_volume = fake_volume.fake_db_volume( volume_metadata=db_metadata, volume_admin_metadata=db_admin_metadata, volume_glance_metadata=db_glance_metadata, volume_type=db_volume_type, volume_attachment=[db_volume_attachments], consistencygroup=db_consistencygroup, snapshots=[db_snapshots], ) volume = objects.Volume._from_db_object(self.context, objects.Volume(), db_volume, expected_attrs) self.assertEqual({'foo': 'bar'}, volume.metadata) self.assertEqual({'admin_foo': 'admin_bar'}, volume.admin_metadata) self.assertEqual({'glance_foo': 'glance_bar'}, volume.glance_metadata) self._compare(self, db_volume_type, volume.volume_type) self._compare(self, db_volume_attachments, volume.volume_attachment) self._compare(self, db_consistencygroup, volume.consistencygroup) self._compare(self, db_snapshots, volume.snapshots)
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 test_copy_volume_to_image_with_protected_prop(self): """Test create image from volume with protected properties.""" id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' def fake_get_volume_image_metadata(*args): meta_dict = { "volume_id": id, "key": "x_billing_code_license", "value": "246254365"} return meta_dict # Need to mock get_volume_image_metadata, create, # update and copy_volume_to_image with mock.patch.object(volume_api.API, "get_volume_image_metadata") \ as mock_get_volume_image_metadata: mock_get_volume_image_metadata.side_effect = \ fake_get_volume_image_metadata with mock.patch.object(glance.GlanceImageService, "create") \ as mock_create: mock_create.side_effect = self.fake_image_service_create with mock.patch.object(volume_api.API, "update") \ as mock_update: mock_update.side_effect = stubs.stub_volume_update with mock.patch.object(volume_rpcapi.VolumeAPI, "copy_volume_to_image") \ as mock_copy_volume_to_image: mock_copy_volume_to_image.side_effect = \ self.fake_rpc_copy_volume_to_image req = fakes.HTTPRequest.blank( '/v2/tenant1/volumes/%s/action' % id) body = self._get_os_volume_upload_image() res_dict = self.controller._volume_upload_image(req, id, body) expected_res = { 'os-volume_upload_image': { 'id': id, 'updated_at': datetime.datetime( 1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), 'status': 'uploading', 'display_description': 'displaydesc', 'size': 1, 'volume_type': fake_volume.fake_db_volume_type( name='vol_type_name'), 'image_id': 1, 'container_format': 'bare', 'disk_format': 'raw', 'image_name': 'image_name' } } self.assertDictMatch(expected_res, res_dict)
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 test_get_by_id_with_projects(self, volume_type_get): projects = [models.VolumeTypeProjects(project_id=fake.PROJECT_ID), models.VolumeTypeProjects(project_id=fake.PROJECT2_ID)] db_volume_type = fake_volume.fake_db_volume_type(projects=projects) volume_type_get.return_value = db_volume_type volume_type = objects.VolumeType.get_by_id(self.context, fake.VOLUME_TYPE_ID) db_volume_type['projects'] = [p.project_id for p in projects] self._compare(self, db_volume_type, volume_type)
def test_copy_volume_to_image_without_glance_metadata(self): """Test create image from volume if volume is created without image. In this case volume glance metadata will not be available for this volume. """ id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' def fake_get_volume_image_metadata_raise(*args): raise exception.GlanceMetadataNotFound(id=id) # Need to mock get_volume_image_metadata, create, # update and copy_volume_to_image with mock.patch.object(volume_api.API, "get_volume_image_metadata") \ as mock_get_volume_image_metadata: mock_get_volume_image_metadata.side_effect = \ fake_get_volume_image_metadata_raise with mock.patch.object(glance.GlanceImageService, "create") \ as mock_create: mock_create.side_effect = self.fake_image_service_create with mock.patch.object(volume_api.API, "update") \ as mock_update: mock_update.side_effect = stubs.stub_volume_update with mock.patch.object(volume_rpcapi.VolumeAPI, "copy_volume_to_image") \ as mock_copy_volume_to_image: mock_copy_volume_to_image.side_effect = \ self.fake_rpc_copy_volume_to_image req = fakes.HTTPRequest.blank( '/v2/tenant1/volumes/%s/action' % id) body = self._get_os_volume_upload_image() res_dict = self.controller._volume_upload_image(req, id, body) expected_res = { 'os-volume_upload_image': { 'id': id, 'updated_at': datetime.datetime( 1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), 'status': 'uploading', 'display_description': 'displaydesc', 'size': 1, 'volume_type': fake_volume.fake_db_volume_type( name='vol_type_name'), 'image_id': 1, 'container_format': 'bare', 'disk_format': 'raw', 'image_name': 'image_name' } } self.assertDictMatch(expected_res, res_dict)
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_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_lazy_loading_qos(self, get_mock, qos_get_mock): qos_get_mock.return_value = objects.QualityOfServiceSpecs( id=fake.QOS_SPEC_ID) vol_type = fake_volume.fake_db_volume_type( qos_specs_id=fake.QOS_SPEC_ID) get_mock.return_value = vol_type volume_type = objects.VolumeType.get_by_id(self.context, vol_type['id']) self._compare(self, qos_get_mock.return_value, volume_type.qos_specs) qos_get_mock.assert_called_once_with(self.context, fake.QOS_SPEC_ID)
def test_lazy_loading_extra_specs(self, get_mock, get_specs_mock): get_specs_mock.return_value = {'key': 'value', 'key2': 'value2'} vol_type = fake_volume.fake_db_volume_type( qos_specs_id=fake.QOS_SPEC_ID) get_mock.return_value = vol_type volume_type = objects.VolumeType.get_by_id(self.context, vol_type['id']) # Simulate this type has been loaded by a volume get_all method del volume_type.extra_specs self.assertEqual(get_specs_mock.return_value, volume_type.extra_specs) get_specs_mock.assert_called_once_with(self.context, vol_type['id'])
def test_copy_volume_to_image_version_3_1( self, mock_copy_volume_to_image, mock_update, mock_create, mock_get_volume_image_metadata): """Test create image from volume with protected properties.""" id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' mock_get_volume_image_metadata.return_value = { "volume_id": id, "key": "x_billing_code_license", "value": "246254365"} mock_create.side_effect = self.fake_image_service_create_3_1 mock_update.side_effect = stubs.stub_volume_update mock_copy_volume_to_image.side_effect = \ self.fake_rpc_copy_volume_to_image self.override_config('glance_api_version', 2) req = fakes.HTTPRequest.blank('/v3/tenant1/volumes/%s/action' % id) req.environ['cinder.context'].is_admin = True req.headers = {'OpenStack-API-Version': 'volume 3.1'} req.api_version_request = api_version.APIVersionRequest('3.1') body = self._get_os_volume_upload_image() body['os-volume_upload_image']['visibility'] = 'public' body['os-volume_upload_image']['protected'] = True res_dict = self.controller._volume_upload_image(req, id, body) expected_res = { 'os-volume_upload_image': { 'id': id, 'updated_at': datetime.datetime( 1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), 'status': 'uploading', 'display_description': 'displaydesc', 'size': 1, 'visibility': 'public', 'protected': True, 'volume_type': fake_volume.fake_db_volume_type( name='vol_type_name'), 'image_id': 1, 'container_format': 'bare', 'disk_format': 'raw', 'image_name': 'image_name' } } self.assertDictMatch(expected_res, res_dict)
def test_get_all_with_pagination(self, get_all_types): db_volume_type = fake_volume.fake_db_volume_type() get_all_types.return_value = {db_volume_type['name']: db_volume_type} volume_types = objects.VolumeTypeList.get_all(self.context, filters={'is_public': True}, marker=None, limit=1, sort_keys='id', sort_dirs='desc', offset=None) self.assertEqual(1, len(volume_types)) TestVolumeType._compare(self, db_volume_type, volume_types[0])
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_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_copy_volume_to_image_without_core_prop(self): """Test glance_core_properties defined in cinder.conf is empty.""" id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' # Need to mock create, update, copy_volume_to_image with mock.patch.object(glance.GlanceImageService, "create") \ as mock_create: mock_create.side_effect = self.fake_image_service_create with mock.patch.object(volume_api.API, "update") \ as mock_update: mock_update.side_effect = stubs.stub_volume_update with mock.patch.object(volume_rpcapi.VolumeAPI, "copy_volume_to_image") \ as mock_copy_volume_to_image: mock_copy_volume_to_image.side_effect = \ self.fake_rpc_copy_volume_to_image self.override_config('glance_core_properties', []) req = fakes.HTTPRequest.blank( '/v2/tenant1/volumes/%s/action' % id) body = self._get_os_volume_upload_image() res_dict = self.controller._volume_upload_image(req, id, body) expected_res = { 'os-volume_upload_image': { 'id': id, 'updated_at': datetime.datetime( 1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), 'status': 'uploading', 'display_description': 'displaydesc', 'size': 1, 'volume_type': fake_volume.fake_db_volume_type( name='vol_type_name'), 'image_id': 1, 'container_format': 'bare', 'disk_format': 'raw', 'image_name': 'image_name' } } self.assertDictMatch(expected_res, res_dict)
def test_lazy_loading_projects(self, get_mock, get_projects_mock): vol_type = fake_volume.fake_db_volume_type( qos_specs_id=fake.QOS_SPEC_ID) get_mock.return_value = vol_type projects = [models.VolumeTypeProjects(project_id=fake.PROJECT_ID), models.VolumeTypeProjects(project_id=fake.PROJECT2_ID)] get_projects_mock.return_value = projects volume_type = objects.VolumeType.get_by_id(self.context, vol_type['id']) # Simulate this type has been loaded by a volume get_all method del volume_type.projects self.assertEqual([p.project_id for p in projects], volume_type.projects) get_projects_mock.assert_called_once_with(self.context, vol_type['id'])
def test_refresh(self, volume_type_get): db_type1 = fake_volume.fake_db_volume_type() db_type2 = db_type1.copy() db_type2['description'] = 'foobar' # On the second _volume_type_get_full, return the volume type with an # updated description volume_type_get.side_effect = [db_type1, db_type2] volume_type = objects.VolumeType.get_by_id(self.context, '1') self._compare(self, db_type1, volume_type) # description was updated, so a volume type refresh should have a new # value for that field volume_type.refresh() self._compare(self, db_type2, volume_type) volume_type_get.assert_has_calls([mock.call(self.context, '1'), mock.call.__nonzero__(), mock.call(self.context, '1')])
def create_volume(id, **kwargs): volume = { 'id': id, 'user_id': fake.USER_ID, 'project_id': fake.PROJECT_ID, 'host': 'fakehost', 'size': DEFAULT_VOL_SIZE, 'availability_zone': DEFAULT_AZ, 'status': DEFAULT_VOL_STATUS, 'migration_status': None, 'attach_status': 'attached', 'name': 'vol name', 'display_name': DEFAULT_VOL_NAME, 'display_description': DEFAULT_VOL_DESCRIPTION, 'updated_at': datetime.datetime(1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), 'created_at': datetime.datetime(1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), 'snapshot_id': None, 'source_volid': None, 'volume_type_id': '3e196c20-3c06-11e2-81c1-0800200c9a66', 'encryption_key_id': None, 'volume_admin_metadata': [{'key': 'attached_mode', 'value': 'rw'}, {'key': 'readonly', 'value': 'False'}], 'bootable': False, 'launched_at': datetime.datetime(1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), 'volume_type': fake_volume.fake_db_volume_type(name=DEFAULT_VOL_TYPE), 'replication_status': 'disabled', 'replication_extended_status': None, 'replication_driver_data': None, 'volume_attachment': [], 'multiattach': False, 'group_id': fake.GROUP_ID, } volume.update(kwargs) if kwargs.get('volume_glance_metadata', None): volume['bootable'] = True if kwargs.get('attach_status') == 'detached': del volume['volume_admin_metadata'][0] return volume
def test_refresh(self, volume_type_get): db_type1 = fake_volume.fake_db_volume_type() db_type2 = db_type1.copy() db_type2['description'] = 'foobar' # On the second _volume_type_get_full, return the volume type with an # updated description volume_type_get.side_effect = [db_type1, db_type2] volume_type = objects.VolumeType.get_by_id(self.context, '1') self._compare(self, db_type1, volume_type) # description was updated, so a volume type refresh should have a new # value for that field volume_type.refresh() self._compare(self, db_type2, volume_type) volume_type_get.assert_has_calls([ mock.call(self.context, '1'), mock.call.__nonzero__(), mock.call(self.context, '1') ])
def test_refresh(self, volume_type_get): db_type1 = fake_volume.fake_db_volume_type() db_type2 = db_type1.copy() db_type2['description'] = 'foobar' # updated description volume_type_get.side_effect = [db_type1, db_type2] volume_type = objects.VolumeType.get_by_id(self.context, fake.VOLUME_TYPE_ID) self._compare(self, db_type1, volume_type) # description was updated, so a volume type refresh should have a new # value for that field volume_type.refresh() self._compare(self, db_type2, volume_type) volume_type_get.assert_has_calls([ mock.call(self.context, fake.VOLUME_TYPE_ID), mock.call.__bool__(), mock.call(self.context, fake.VOLUME_TYPE_ID) ])
def test_copy_volume_to_image(self): self.stubs.Set(volume_api.API, "copy_volume_to_image", stub_upload_volume_to_image_service) id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' vol = { "container_format": 'bare', "disk_format": 'raw', "image_name": 'image_name', "force": True } body = {"os-volume_upload_image": vol} req = fakes.HTTPRequest.blank('/v2/tenant1/volumes/%s/action' % id) res_dict = self.controller._volume_upload_image(req, id, body) expected = { 'os-volume_upload_image': { 'id': id, 'updated_at': datetime.datetime(1, 1, 1, 1, 1, 1), 'status': 'uploading', 'display_description': 'displaydesc', 'size': 1, 'volume_type': fake_volume.fake_db_volume_type(name='vol_type_name'), 'image_id': 1, 'container_format': 'bare', 'disk_format': 'raw', 'image_name': 'image_name' } } self.assertDictMatch(expected, res_dict)
def stub_volume(id, **kwargs): volume = { "id": id, "user_id": fake.USER_ID, "project_id": fake.PROJECT_ID, "host": "fakehost", "size": DEFAULT_VOL_SIZE, "availability_zone": DEFAULT_AZ, "status": DEFAULT_VOL_STATUS, "migration_status": None, "attach_status": "attached", "name": "vol name", "display_name": DEFAULT_VOL_NAME, "display_description": DEFAULT_VOL_DESCRIPTION, "updated_at": datetime.datetime(1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), "created_at": datetime.datetime(1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), "snapshot_id": None, "source_volid": None, "volume_type_id": "3e196c20-3c06-11e2-81c1-0800200c9a66", "encryption_key_id": None, "volume_admin_metadata": [{"key": "attached_mode", "value": "rw"}, {"key": "readonly", "value": "False"}], "bootable": False, "launched_at": datetime.datetime(1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), "volume_type": fake_volume.fake_db_volume_type(name=DEFAULT_VOL_TYPE), "replication_status": "disabled", "replication_extended_status": None, "replication_driver_data": None, "volume_attachment": [], "multiattach": False, } volume.update(kwargs) if kwargs.get("volume_glance_metadata", None): volume["bootable"] = True if kwargs.get("attach_status") == "detached": del volume["volume_admin_metadata"][0] return volume
def stub_volume(id, **kwargs): volume = { 'id': id, 'user_id': fake.USER_ID, 'project_id': fake.PROJECT_ID, 'host': 'fakehost', 'size': 1, 'availability_zone': 'fakeaz', 'attached_mode': 'rw', 'status': 'fakestatus', 'migration_status': None, 'attach_status': 'attached', 'bootable': False, 'name': 'vol name', 'display_name': 'displayname', 'display_description': 'displaydesc', 'updated_at': datetime.datetime(1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), 'created_at': datetime.datetime(1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), 'snapshot_id': None, 'source_volid': None, 'volume_type_id': fake.VOLUME_TYPE_ID, 'volume_admin_metadata': [{'key': 'attached_mode', 'value': 'rw'}, {'key': 'readonly', 'value': 'False'}], 'volume_type': fake_volume.fake_db_volume_type(name=DEFAULT_VOL_TYPE), 'volume_attachment': [], 'multiattach': False, 'readonly': 'False'} volume.update(kwargs) if kwargs.get('volume_glance_metadata', None): volume['bootable'] = True if kwargs.get('attach_status') == 'detached': del volume['volume_admin_metadata'][0] return volume
def test_from_db_object_with_all_expected_attributes(self): expected_attrs = [ "metadata", "admin_metadata", "glance_metadata", "volume_type", "volume_attachment", "consistencygroup", ] db_metadata = [{"key": "foo", "value": "bar"}] db_admin_metadata = [{"key": "admin_foo", "value": "admin_bar"}] db_glance_metadata = [{"key": "glance_foo", "value": "glance_bar"}] db_volume_type = fake_volume.fake_db_volume_type() db_volume_attachments = fake_volume.fake_db_volume_attachment() db_consistencygroup = fake_consistencygroup.fake_db_consistencygroup() db_snapshots = fake_snapshot.fake_db_snapshot() db_volume = fake_volume.fake_db_volume( volume_metadata=db_metadata, volume_admin_metadata=db_admin_metadata, volume_glance_metadata=db_glance_metadata, volume_type=db_volume_type, volume_attachment=[db_volume_attachments], consistencygroup=db_consistencygroup, snapshots=[db_snapshots], ) volume = objects.Volume._from_db_object(self.context, objects.Volume(), db_volume, expected_attrs) self.assertEqual({"foo": "bar"}, volume.metadata) self.assertEqual({"admin_foo": "admin_bar"}, volume.admin_metadata) self.assertEqual({"glance_foo": "glance_bar"}, volume.glance_metadata) self._compare(self, db_volume_type, volume.volume_type) self._compare(self, db_volume_attachments, volume.volume_attachment) self._compare(self, db_consistencygroup, volume.consistencygroup) self._compare(self, db_snapshots, volume.snapshots)
def test_refresh(self, volume_type_get): db_type1 = fake_volume.fake_db_volume_type() db_type2 = db_type1.copy() db_type2['description'] = 'foobar' # updated description volume_type_get.side_effect = [db_type1, db_type2] volume_type = objects.VolumeType.get_by_id(self.context, fake.volume_type_id) self._compare(self, db_type1, volume_type) # description was updated, so a volume type refresh should have a new # value for that field volume_type.refresh() self._compare(self, db_type2, volume_type) if six.PY3: call_bool = mock.call.__bool__() else: call_bool = mock.call.__nonzero__() volume_type_get.assert_has_calls([mock.call(self.context, fake.volume_type_id), call_bool, mock.call(self.context, fake.volume_type_id)])
def test_copy_volume_to_image_without_protected_prop(self): """Test protected property is not defined with the root image.""" id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' def fake_get_volume_image_metadata(*args): return [] # Need to mock get_volume_image_metadata, create, # update and copy_volume_to_image with mock.patch.object(volume_api.API, "get_volume_image_metadata") \ as mock_get_volume_image_metadata: mock_get_volume_image_metadata.side_effect = \ fake_get_volume_image_metadata with mock.patch.object(glance.GlanceImageService, "create") \ as mock_create: mock_create.side_effect = self.fake_image_service_create with mock.patch.object(volume_api.API, "update") \ as mock_update: mock_update.side_effect = stubs.stub_volume_update with mock.patch.object(volume_rpcapi.VolumeAPI, "copy_volume_to_image") \ as mock_copy_volume_to_image: mock_copy_volume_to_image.side_effect = \ self.fake_rpc_copy_volume_to_image req = fakes.HTTPRequest.blank( '/v2/tenant1/volumes/%s/action' % id) body = self._get_os_volume_upload_image() res_dict = self.controller._volume_upload_image( req, id, body) expected_res = { 'os-volume_upload_image': { 'id': id, 'updated_at': datetime.datetime( 1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), 'status': 'uploading', 'display_description': 'displaydesc', 'size': 1, 'volume_type': fake_volume.fake_db_volume_type( name='vol_type_name'), 'image_id': 1, 'container_format': 'bare', 'disk_format': 'raw', 'image_name': 'image_name' } } self.assertDictMatch(expected_res, res_dict)
def test_get_by_name_or_id(self, volume_type_get): db_volume_type = fake_volume.fake_db_volume_type() volume_type_get.return_value = db_volume_type volume_type = objects.VolumeType.get_by_name_or_id( self.context, fake.VOLUME_TYPE_ID) self._compare(self, db_volume_type, volume_type)
def test_copy_volume_to_image_version_3_1(self, mock_copy_volume_to_image, mock_update, mock_create, mock_get_volume_image_metadata): """Test create image from volume with protected properties.""" id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' mock_get_volume_image_metadata.return_value = { "volume_id": id, "key": "x_billing_code_license", "value": "246254365" } mock_create.side_effect = self.fake_image_service_create_3_1 mock_update.side_effect = stubs.stub_volume_update mock_copy_volume_to_image.side_effect = \ self.fake_rpc_copy_volume_to_image self.override_config('glance_api_version', 2) req = fakes.HTTPRequest.blank('/v3/tenant1/volumes/%s/action' % id) req.environ['cinder.context'].is_admin = True req.headers = {'OpenStack-API-Version': 'volume 3.1'} req.api_version_request = api_version.APIVersionRequest('3.1') body = self._get_os_volume_upload_image() body['os-volume_upload_image']['visibility'] = 'public' body['os-volume_upload_image']['protected'] = True res_dict = self.controller._volume_upload_image(req, id, body) expected_res = { 'os-volume_upload_image': { 'id': id, 'updated_at': datetime.datetime(1900, 1, 1, 1, 1, 1, tzinfo=iso8601.iso8601.Utc()), 'status': 'uploading', 'display_description': 'displaydesc', 'size': 1, 'visibility': 'public', 'protected': True, 'volume_type': fake_volume.fake_db_volume_type(name='vol_type_name'), 'image_id': 1, 'container_format': 'bare', 'disk_format': 'raw', 'image_name': 'image_name' } } self.assertDictMatch(expected_res, res_dict)
def test_get_by_id(self, volume_type_get): db_volume_type = fake_volume.fake_db_volume_type() volume_type_get.return_value = db_volume_type volume_type = objects.VolumeType.get_by_id(self.context, fake.volume_type_id) self._compare(self, db_volume_type, volume_type)