def test_delete_image_volume(self): volume_params = { 'status': 'creating', 'host': 'some_host', 'cluster_name': 'some_cluster', 'size': 1 } volume_api = cinder.volume.api.API() volume = tests_utils.create_volume(self.context, **volume_params) volume.status = 'available' volume.save() image_id = '70a599e0-31e7-49b7-b260-868f441e862b' db.image_volume_cache_create(self.context, volume['host'], volume_params['cluster_name'], image_id, datetime.datetime.utcnow(), volume['id'], volume['size']) volume_api.delete(self.context, volume) entry = db.image_volume_cache_get_by_volume_id(self.context, volume['id']) self.assertIsNone(entry)
def _retype_volume_exec(self, driver, mock_notify, snap=False, policy='on-demand', migrate_exc=False, exc=None, diff_equal=False, replica=False, reserve_vol_type_only=False, encryption_changed=False, replica_new=None): elevated = context.get_admin_context() project_id = self.context.project_id if replica: rep_status = 'enabled' extra_specs = {'replication_enabled': '<is> True'} else: rep_status = 'disabled' extra_specs = {} if replica_new is None: replica_new = replica new_specs = {'replication_enabled': '<is> True'} if replica_new else {} db.volume_type_create(elevated, { 'name': 'old', 'extra_specs': extra_specs }) old_vol_type = db.volume_type_get_by_name(elevated, 'old') db.volume_type_create(elevated, { 'name': 'new', 'extra_specs': new_specs }) vol_type = db.volume_type_get_by_name(elevated, 'new') db.quota_create(elevated, project_id, 'volumes_new', 10) volume = tests_utils.create_volume(self.context, size=1, host=CONF.host, status='retyping', volume_type_id=old_vol_type['id'], replication_status=rep_status) volume.previous_status = 'available' volume.save() if snap: create_snapshot(volume.id, size=volume.size) if driver or diff_equal: host_obj = {'host': CONF.host, 'capabilities': {}} else: host_obj = {'host': 'newhost', 'capabilities': {}} reserve_opts = {'volumes': 1, 'gigabytes': volume.size} QUOTAS.add_volume_type_opts(self.context, reserve_opts, vol_type['id']) if reserve_vol_type_only: reserve_opts.pop('volumes') reserve_opts.pop('gigabytes') try: usage = db.quota_usage_get(elevated, project_id, 'volumes') total_volumes_in_use = usage.in_use usage = db.quota_usage_get(elevated, project_id, 'gigabytes') total_gigabytes_in_use = usage.in_use except exception.QuotaUsageNotFound: total_volumes_in_use = 0 total_gigabytes_in_use = 0 reservations = QUOTAS.reserve(self.context, project_id=project_id, **reserve_opts) old_reserve_opts = {'volumes': -1, 'gigabytes': -volume.size} QUOTAS.add_volume_type_opts(self.context, old_reserve_opts, old_vol_type['id']) old_reservations = QUOTAS.reserve(self.context, project_id=project_id, **old_reserve_opts) with mock.patch.object(self.volume.driver, 'retype') as _retype,\ mock.patch.object(volume_types, 'volume_types_diff') as _diff,\ mock.patch.object(self.volume, 'migrate_volume') as _mig,\ mock.patch.object(db.sqlalchemy.api, 'volume_get') as mock_get: mock_get.return_value = volume _retype.return_value = driver returned_diff = { 'encryption': {}, 'qos_specs': {}, 'extra_specs': {}, } if replica != replica_new: returned_diff['extra_specs']['replication_enabled'] = ( extra_specs.get('replication_enabled'), new_specs.get('replication_enabled')) expected_replica_status = 'enabled' if replica_new else 'disabled' if encryption_changed: returned_diff['encryption'] = 'fake' _diff.return_value = (returned_diff, diff_equal) if migrate_exc: _mig.side_effect = KeyError else: _mig.return_value = True if not exc: self.volume.retype(self.context, volume, vol_type['id'], host_obj, migration_policy=policy, reservations=reservations, old_reservations=old_reservations) else: self.assertRaises(exc, self.volume.retype, self.context, volume, vol_type['id'], host_obj, migration_policy=policy, reservations=reservations, old_reservations=old_reservations) if host_obj['host'] != CONF.host: _retype.assert_not_called() # get volume/quota properties volume = objects.Volume.get_by_id(elevated, volume.id) try: usage = db.quota_usage_get(elevated, project_id, 'volumes_new') volumes_in_use = usage.in_use except exception.QuotaUsageNotFound: volumes_in_use = 0 # Get new in_use after retype, it should not be changed. if reserve_vol_type_only: try: usage = db.quota_usage_get(elevated, project_id, 'volumes') new_total_volumes_in_use = usage.in_use usage = db.quota_usage_get(elevated, project_id, 'gigabytes') new_total_gigabytes_in_use = usage.in_use except exception.QuotaUsageNotFound: new_total_volumes_in_use = 0 new_total_gigabytes_in_use = 0 self.assertEqual(total_volumes_in_use, new_total_volumes_in_use) self.assertEqual(total_gigabytes_in_use, new_total_gigabytes_in_use) # check properties if driver or diff_equal: self.assertEqual(vol_type['id'], volume.volume_type_id) self.assertEqual('available', volume.status) self.assertEqual(CONF.host, volume.host) self.assertEqual(1, volumes_in_use) self.assert_notify_called(mock_notify, (['INFO', 'volume.retype'], )) elif not exc: self.assertEqual(old_vol_type['id'], volume.volume_type_id) self.assertEqual('retyping', volume.status) self.assertEqual(CONF.host, volume.host) self.assertEqual(1, volumes_in_use) self.assert_notify_called(mock_notify, (['INFO', 'volume.retype'], )) else: self.assertEqual(old_vol_type['id'], volume.volume_type_id) self.assertEqual('available', volume.status) self.assertEqual(CONF.host, volume.host) self.assertEqual(0, volumes_in_use) mock_notify.assert_not_called() if encryption_changed: self.assertTrue(_mig.called) self.assertEqual(expected_replica_status, volume.replication_status)
def _retype_volume_exec(self, driver, mock_notify, snap=False, policy='on-demand', migrate_exc=False, exc=None, diff_equal=False, replica=False, reserve_vol_type_only=False, encryption_changed=False, replica_new=None): elevated = context.get_admin_context() project_id = self.context.project_id if replica: rep_status = 'enabled' extra_specs = {'replication_enabled': '<is> True'} else: rep_status = 'disabled' extra_specs = {} if replica_new is None: replica_new = replica new_specs = {'replication_enabled': '<is> True'} if replica_new else {} db.volume_type_create(elevated, {'name': 'old', 'extra_specs': extra_specs}) old_vol_type = db.volume_type_get_by_name(elevated, 'old') db.volume_type_create(elevated, {'name': 'new', 'extra_specs': new_specs}) vol_type = db.volume_type_get_by_name(elevated, 'new') db.quota_create(elevated, project_id, 'volumes_new', 10) volume = tests_utils.create_volume(self.context, size=1, host=CONF.host, status='retyping', volume_type_id=old_vol_type['id'], replication_status=rep_status) volume.previous_status = 'available' volume.save() if snap: create_snapshot(volume.id, size=volume.size, user_id=self.user_context.user_id, project_id=self.user_context.project_id, ctxt=self.user_context) if driver or diff_equal: host_obj = {'host': CONF.host, 'capabilities': {}} else: host_obj = {'host': 'newhost', 'capabilities': {}} reserve_opts = {'volumes': 1, 'gigabytes': volume.size} QUOTAS.add_volume_type_opts(self.context, reserve_opts, vol_type['id']) if reserve_vol_type_only: reserve_opts.pop('volumes') reserve_opts.pop('gigabytes') try: usage = db.quota_usage_get(elevated, project_id, 'volumes') total_volumes_in_use = usage.in_use usage = db.quota_usage_get(elevated, project_id, 'gigabytes') total_gigabytes_in_use = usage.in_use except exception.QuotaUsageNotFound: total_volumes_in_use = 0 total_gigabytes_in_use = 0 reservations = QUOTAS.reserve(self.context, project_id=project_id, **reserve_opts) old_reserve_opts = {'volumes': -1, 'gigabytes': -volume.size} QUOTAS.add_volume_type_opts(self.context, old_reserve_opts, old_vol_type['id']) old_reservations = QUOTAS.reserve(self.context, project_id=project_id, **old_reserve_opts) with mock.patch.object(self.volume.driver, 'retype') as _retype,\ mock.patch.object(volume_types, 'volume_types_diff') as _diff,\ mock.patch.object(self.volume, 'migrate_volume') as _mig,\ mock.patch.object(db.sqlalchemy.api, 'volume_get') as _vget,\ mock.patch.object(context.RequestContext, 'elevated') as _ctx: _vget.return_value = volume _retype.return_value = driver _ctx.return_value = self.context returned_diff = { 'encryption': {}, 'qos_specs': {}, 'extra_specs': {}, } if replica != replica_new: returned_diff['extra_specs']['replication_enabled'] = ( extra_specs.get('replication_enabled'), new_specs.get('replication_enabled')) expected_replica_status = 'enabled' if replica_new else 'disabled' if encryption_changed: returned_diff['encryption'] = 'fake' _diff.return_value = (returned_diff, diff_equal) if migrate_exc: _mig.side_effect = KeyError else: _mig.return_value = True if not exc: self.volume.retype(self.context, volume, vol_type['id'], host_obj, migration_policy=policy, reservations=reservations, old_reservations=old_reservations) else: self.assertRaises(exc, self.volume.retype, self.context, volume, vol_type['id'], host_obj, migration_policy=policy, reservations=reservations, old_reservations=old_reservations) if host_obj['host'] != CONF.host: _retype.assert_not_called() # get volume/quota properties volume = objects.Volume.get_by_id(elevated, volume.id) try: usage = db.quota_usage_get(elevated, project_id, 'volumes_new') volumes_in_use = usage.in_use except exception.QuotaUsageNotFound: volumes_in_use = 0 # Get new in_use after retype, it should not be changed. if reserve_vol_type_only: try: usage = db.quota_usage_get(elevated, project_id, 'volumes') new_total_volumes_in_use = usage.in_use usage = db.quota_usage_get(elevated, project_id, 'gigabytes') new_total_gigabytes_in_use = usage.in_use except exception.QuotaUsageNotFound: new_total_volumes_in_use = 0 new_total_gigabytes_in_use = 0 self.assertEqual(total_volumes_in_use, new_total_volumes_in_use) self.assertEqual(total_gigabytes_in_use, new_total_gigabytes_in_use) # check properties if driver or diff_equal: self.assertEqual(vol_type['id'], volume.volume_type_id) self.assertEqual('available', volume.status) self.assertEqual(CONF.host, volume.host) self.assertEqual(1, volumes_in_use) self.assert_notify_called(mock_notify, (['INFO', 'volume.retype'],)) elif not exc: self.assertEqual(old_vol_type['id'], volume.volume_type_id) self.assertEqual('retyping', volume.status) self.assertEqual(CONF.host, volume.host) self.assertEqual(1, volumes_in_use) self.assert_notify_called(mock_notify, (['INFO', 'volume.retype'],)) else: self.assertEqual(old_vol_type['id'], volume.volume_type_id) self.assertEqual('available', volume.status) self.assertEqual(CONF.host, volume.host) self.assertEqual(0, volumes_in_use) mock_notify.assert_not_called() if encryption_changed: self.assertTrue(_mig.called) self.assertEqual(expected_replica_status, volume.replication_status)