Exemplo n.º 1
0
 def test_quota_usage_get(self):
     reservations = _quota_reserve(self.ctxt, 'p1')
     quota_usage = db.quota_usage_get(self.ctxt, 'p1', 'gigabytes')
     expected = {'resource': 'gigabytes', 'project_id': 'p1',
                 'in_use': 0, 'reserved': 2, 'total': 2}
     for key, value in expected.iteritems():
         self.assertEqual(value, quota_usage[key], key)
    def test_manage_volume_raise_driver_exception(self, mock_execute,
                                                  mock_driver_get_size):
        elevated = context.get_admin_context()
        project_id = self.context.project_id
        db.volume_type_create(elevated, {'name': 'type1', 'extra_specs': {}})
        vol_type = db.volume_type_get_by_name(elevated, 'type1')
        # create source volume
        self.volume_params['volume_type_id'] = vol_type['id']
        self.volume_params['status'] = 'managing'
        test_vol = tests_utils.create_volume(self.context,
                                             **self.volume_params)
        mock_execute.side_effect = exception.VolumeBackendAPIException(
            data="volume driver got exception")
        mock_driver_get_size.return_value = 1
        # Set quota usage
        reserve_opts = {'volumes': 1, 'gigabytes': 1}
        reservations = QUOTAS.reserve(self.context, project_id=project_id,
                                      **reserve_opts)
        QUOTAS.commit(self.context, reservations)
        usage = db.quota_usage_get(self.context, project_id, 'volumes')
        volumes_in_use = usage.in_use
        usage = db.quota_usage_get(self.context, project_id, 'gigabytes')
        gigabytes_in_use = usage.in_use

        self.assertRaises(exception.VolumeBackendAPIException,
                          self.volume.manage_existing,
                          self.context, test_vol,
                          'volume_ref')
        # check volume status
        volume = objects.Volume.get_by_id(context.get_admin_context(),
                                          test_vol.id)
        self.assertEqual('error_managing', volume.status)
        # Delete this volume with 'error_managing_deleting' status in c-vol.
        test_vol.status = 'error_managing_deleting'
        test_vol.save()
        self.volume.delete_volume(self.context, test_vol)
        ctxt = context.get_admin_context(read_deleted='yes')
        volume = objects.Volume.get_by_id(ctxt, test_vol.id)
        self.assertEqual('deleted', volume.status)
        # Get in_use number after deleting error_managing volume
        usage = db.quota_usage_get(self.context, project_id, 'volumes')
        volumes_in_use_new = usage.in_use
        self.assertEqual(volumes_in_use, volumes_in_use_new)
        usage = db.quota_usage_get(self.context, project_id, 'gigabytes')
        gigabytes_in_use_new = usage.in_use
        self.assertEqual(gigabytes_in_use, gigabytes_in_use_new)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
 def test_quota_usage_get(self):
     _quota_reserve(self.ctxt, "p1")
     quota_usage = db.quota_usage_get(self.ctxt, "p1", "gigabytes")
     expected = {"resource": "gigabytes", "project_id": "p1", "in_use": 0, "reserved": 2, "total": 2}
     for key, value in expected.iteritems():
         self.assertEqual(value, quota_usage[key], key)
Exemplo n.º 5
0
    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)