Exemple #1
0
    def test_update_group_success(self, mock_validate):
        volume_type_id = fake.VOLUME_TYPE_ID
        self.group1.status = fields.GroupStatus.AVAILABLE
        self.group1.host = 'test_host'
        self.group1.volume_type_ids = [volume_type_id]
        self.group1.save()

        remove_volume = utils.create_volume(self.ctxt,
                                            volume_type_id=volume_type_id,
                                            group_id=self.group1.id)
        remove_volume2 = utils.create_volume(self.ctxt,
                                             volume_type_id=volume_type_id,
                                             group_id=self.group1.id,
                                             status='error')
        remove_volume3 = utils.create_volume(self.ctxt,
                                             volume_type_id=volume_type_id,
                                             group_id=self.group1.id,
                                             status='error_deleting')

        self.assertEqual(fields.GroupStatus.AVAILABLE, self.group1.status)

        group_volumes = db.volume_get_all_by_generic_group(
            self.ctxt.elevated(), self.group1.id)
        group_vol_ids = [group_vol['id'] for group_vol in group_volumes]
        self.assertIn(remove_volume.id, group_vol_ids)
        self.assertIn(remove_volume2.id, group_vol_ids)
        self.assertIn(remove_volume3.id, group_vol_ids)

        add_volume = utils.create_volume(self.ctxt,
                                         volume_type_id=volume_type_id)
        add_volume2 = utils.create_volume(self.ctxt,
                                          volume_type_id=volume_type_id)
        req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/update' %
                                      (fake.PROJECT_ID, self.group1.id),
                                      version=GROUP_MICRO_VERSION)
        name = 'newgroup'
        description = 'New Group Description'
        add_volumes = add_volume.id + "," + add_volume2.id
        remove_volumes = ','.join(
            [remove_volume.id, remove_volume2.id, remove_volume3.id])
        body = {
            "group": {
                "name": name,
                "description": description,
                "add_volumes": add_volumes,
                "remove_volumes": remove_volumes,
            }
        }
        res_dict = self.controller.update(req, self.group1.id, body)

        group = objects.Group.get_by_id(self.ctxt, self.group1.id)
        self.assertEqual(202, res_dict.status_int)
        self.assertTrue(mock_validate.called)
        self.assertEqual(fields.GroupStatus.UPDATING, group.status)

        remove_volume.destroy()
        remove_volume2.destroy()
        remove_volume3.destroy()
        add_volume.destroy()
        add_volume2.destroy()
Exemple #2
0
 def get_all_by_generic_group(cls, context, group_id, filters=None):
     # Generic volume group
     volumes = db.volume_get_all_by_generic_group(context, group_id,
                                                  filters)
     expected_attrs = cls._get_expected_attrs(context)
     return base.obj_make_list(context, cls(context), objects.Volume,
                               volumes, expected_attrs=expected_attrs)
Exemple #3
0
 def get_all_by_generic_group(cls, context, group_id, filters=None):
     # Generic volume group
     volumes = db.volume_get_all_by_generic_group(context, group_id,
                                                  filters)
     expected_attrs = cls._get_expected_attrs(context)
     return base.obj_make_list(context, cls(context), objects.Volume,
                               volumes, expected_attrs=expected_attrs)
Exemple #4
0
def create_group_snapshot(ctxt,
                          group_id,
                          group_type_id=None,
                          name='test_group_snapshot',
                          description='this is a test group snapshot',
                          status='creating',
                          recursive_create_if_needed=True,
                          return_vo=True,
                          **kwargs):
    """Create a group snapshot object in the DB."""
    values = {
        'user_id': ctxt.user_id or fake.USER_ID,
        'project_id': ctxt.project_id or fake.PROJECT_ID,
        'status': status,
        'name': name,
        'description': description,
        'group_id': group_id,
        'group_type_id': group_type_id}
    values.update(kwargs)

    if recursive_create_if_needed and group_id:
        create_grp = False
        try:
            objects.Group.get_by_id(ctxt,
                                    group_id)
            create_vol = not db.volume_get_all_by_generic_group(
                ctxt, group_id)
        except exception.GroupNotFound:
            create_grp = True
            create_vol = True
        if create_grp:
            create_group(ctxt, id=group_id, group_type_id=group_type_id)
        if create_vol:
            create_volume(ctxt, group_id=group_id)

    if not return_vo:
        return db.group_snapshot_create(ctxt, values)
    else:
        group_snapshot = objects.GroupSnapshot(ctxt)
        new_id = values.pop('id', None)
        group_snapshot.update(values)
        group_snapshot.create()
        if new_id and new_id != group_snapshot.id:
            db.group_snapshot_update(ctxt, group_snapshot.id, {'id': new_id})
            group_snapshot = objects.GroupSnapshot.get_by_id(ctxt, new_id)
        return group_snapshot
Exemple #5
0
def create_group_snapshot(ctxt,
                          group_id,
                          group_type_id=None,
                          name='test_group_snapshot',
                          description='this is a test group snapshot',
                          status='creating',
                          recursive_create_if_needed=True,
                          return_vo=True,
                          **kwargs):
    """Create a group snapshot object in the DB."""
    values = {
        'user_id': ctxt.user_id or fake.USER_ID,
        'project_id': ctxt.project_id or fake.PROJECT_ID,
        'status': status,
        'name': name,
        'description': description,
        'group_id': group_id,
        'group_type_id': group_type_id}
    values.update(kwargs)

    if recursive_create_if_needed and group_id:
        create_grp = False
        try:
            objects.Group.get_by_id(ctxt,
                                    group_id)
            create_vol = not db.volume_get_all_by_generic_group(
                ctxt, group_id)
        except exception.GroupNotFound:
            create_grp = True
            create_vol = True
        if create_grp:
            create_group(ctxt, id=group_id, group_type_id=group_type_id)
        if create_vol:
            create_volume(ctxt, group_id=group_id)

    if not return_vo:
        return db.group_snapshot_create(ctxt, values)
    else:
        group_snapshot = objects.GroupSnapshot(ctxt)
        new_id = values.pop('id', None)
        group_snapshot.update(values)
        group_snapshot.create()
        if new_id and new_id != group_snapshot.id:
            db.group_snapshot_update(ctxt, group_snapshot.id, {'id': new_id})
            group_snapshot = objects.GroupSnapshot.get_by_id(ctxt, new_id)
        return group_snapshot
Exemple #6
0
    def test_update_group(self, raise_error, type_id, fake_update_grp,
                          fake_update_cg, fake_generic_update, fake_create_grp,
                          fake_rollback, fake_commit, fake_reserve,
                          fake_get_type):
        """Test group can be updated."""
        group = tests_utils.create_group(
            self.context,
            availability_zone=CONF.storage_availability_zone,
            volume_type_ids=[fake.VOLUME_TYPE_ID],
            group_type_id=type_id,
            host=CONF.host)
        self.volume.create_group(self.context, group)

        volume = tests_utils.create_volume(self.context,
                                           group_id=group.id,
                                           volume_type_id=fake.VOLUME_TYPE_ID,
                                           status='available',
                                           host=group.host)
        self.volume.create_volume(self.context, volume)

        volume2 = tests_utils.create_volume(self.context,
                                            group_id=None,
                                            volume_type_id=fake.VOLUME_TYPE_ID,
                                            status='available',
                                            host=group.host)
        self.volume.create_volume(self.context, volume)

        driver_result = ({
            'status': fields.GroupStatus.AVAILABLE
        }, [{
            'id': volume2.id,
            'status': 'available'
        }], [{
            'id': volume.id,
            'status': 'available'
        }])
        if raise_error:
            fake_update_grp.side_effect = [NotImplementedError]
            fake_update_cg.return_value = driver_result
            fake_generic_update.return_value = driver_result
        else:
            fake_update_grp.return_value = driver_result

        with mock.patch.object(self.volume, '_convert_group_to_cg',
                               mock.Mock()) as mock_convert, mock.patch.object(
                                   self.volume,
                                   '_remove_consistencygroup_id_from_volumes',
                                   mock.Mock()):
            mock_convert.return_value = ('fake_cg', [volume])
            self.volume.update_group(self.context,
                                     group,
                                     add_volumes=volume2.id,
                                     remove_volumes=volume.id)
        if raise_error:
            if type_id == fake.GROUP_TYPE2_ID:
                fake_update_cg.assert_called_once_with(self.context,
                                                       'fake_cg',
                                                       add_volumes=mock.ANY,
                                                       remove_volumes=[volume])
            else:
                fake_generic_update.assert_called_once_with(
                    self.context,
                    group,
                    add_volumes=mock.ANY,
                    remove_volumes=mock.ANY)

        grp = objects.Group.get_by_id(self.context, group.id)
        expected = {
            'status': fields.GroupStatus.AVAILABLE,
            'name': 'test_group',
            'availability_zone': 'nova',
            'tenant_id': self.context.project_id,
            'created_at': mock.ANY,
            'user_id': fake.USER_ID,
            'group_id': group.id,
            'group_type': type_id
        }
        self.assertEqual(fields.GroupStatus.AVAILABLE, grp.status)
        self.assertEqual(10, len(self.notifier.notifications),
                         self.notifier.notifications)
        msg = self.notifier.notifications[6]
        self.assertEqual('group.update.start', msg['event_type'])
        self.assertDictEqual(expected, msg['payload'])
        msg = self.notifier.notifications[8]
        self.assertEqual('group.update.end', msg['event_type'])
        self.assertDictEqual(expected, msg['payload'])
        grpvolumes = db.volume_get_all_by_generic_group(self.context, group.id)
        grpvol_ids = [grpvol['id'] for grpvol in grpvolumes]
        # Verify volume is removed.
        self.assertNotIn(volume.id, grpvol_ids)
        # Verify volume is added.
        self.assertIn(volume2.id, grpvol_ids)

        volume3 = tests_utils.create_volume(self.context,
                                            group_id=None,
                                            host=group.host,
                                            volume_type_id=fake.VOLUME_TYPE_ID,
                                            status='wrong-status')
        volume_id3 = volume3['id']

        volume_get_orig = self.volume.db.volume_get
        self.volume.db.volume_get = mock.Mock(return_value={
            'status': 'wrong_status',
            'id': volume_id3
        })
        # Try to add a volume in wrong status
        self.assertRaises(exception.InvalidVolume,
                          self.volume.update_group,
                          self.context,
                          group,
                          add_volumes=volume_id3,
                          remove_volumes=None)
        self.volume.db.volume_get.reset_mock()
        self.volume.db.volume_get = volume_get_orig
Exemple #7
0
    def test_update_group_success(self, mock_validate):
        volume_type_id = fake.VOLUME_TYPE_ID
        self.group1.status = fields.GroupStatus.AVAILABLE
        self.group1.host = 'test_host'
        self.group1.volume_type_ids = [volume_type_id]
        self.group1.save()

        remove_volume = utils.create_volume(
            self.ctxt,
            volume_type_id=volume_type_id,
            group_id=self.group1.id)
        remove_volume2 = utils.create_volume(
            self.ctxt,
            volume_type_id=volume_type_id,
            group_id=self.group1.id,
            status='error')
        remove_volume3 = utils.create_volume(
            self.ctxt,
            volume_type_id=volume_type_id,
            group_id=self.group1.id,
            status='error_deleting')

        self.assertEqual(fields.GroupStatus.AVAILABLE,
                         self.group1.status)

        group_volumes = db.volume_get_all_by_generic_group(
            self.ctxt.elevated(),
            self.group1.id)
        group_vol_ids = [group_vol['id'] for group_vol in group_volumes]
        self.assertIn(remove_volume.id, group_vol_ids)
        self.assertIn(remove_volume2.id, group_vol_ids)
        self.assertIn(remove_volume3.id, group_vol_ids)

        add_volume = utils.create_volume(
            self.ctxt,
            volume_type_id=volume_type_id)
        add_volume2 = utils.create_volume(
            self.ctxt,
            volume_type_id=volume_type_id)
        req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/update' %
                                      (fake.PROJECT_ID, self.group1.id),
                                      version=GROUP_MICRO_VERSION)
        name = 'newgroup'
        description = 'New Group Description'
        add_volumes = add_volume.id + "," + add_volume2.id
        remove_volumes = ','.join(
            [remove_volume.id, remove_volume2.id, remove_volume3.id])
        body = {"group": {"name": name,
                          "description": description,
                          "add_volumes": add_volumes,
                          "remove_volumes": remove_volumes, }}
        res_dict = self.controller.update(
            req, self.group1.id, body)

        group = objects.Group.get_by_id(
            self.ctxt, self.group1.id)
        self.assertEqual(202, res_dict.status_int)
        self.assertTrue(mock_validate.called)
        self.assertEqual(fields.GroupStatus.UPDATING,
                         group.status)

        remove_volume.destroy()
        remove_volume2.destroy()
        remove_volume3.destroy()
        add_volume.destroy()
        add_volume2.destroy()
Exemple #8
0
    def test_update_group(self, fake_update_grp, fake_create_grp,
                          fake_rollback, fake_commit, fake_reserve):
        """Test group can be updated."""
        group = tests_utils.create_group(
            self.context,
            availability_zone=CONF.storage_availability_zone,
            volume_type_ids=[fake.VOLUME_TYPE_ID],
            group_type_id=fake.GROUP_TYPE_ID,
            host=CONF.host)
        self.volume.create_group(self.context, group)

        volume = tests_utils.create_volume(self.context,
                                           group_id=group.id,
                                           volume_type_id=fake.VOLUME_TYPE_ID,
                                           status='available',
                                           host=group.host)
        self.volume.create_volume(self.context, volume)

        volume2 = tests_utils.create_volume(self.context,
                                            group_id=None,
                                            volume_type_id=fake.VOLUME_TYPE_ID,
                                            status='available',
                                            host=group.host)
        self.volume.create_volume(self.context, volume)

        fake_update_grp.return_value = ({
            'status': fields.GroupStatus.AVAILABLE
        }, [{
            'id': volume2.id,
            'status': 'available'
        }], [{
            'id': volume.id,
            'status': 'available'
        }])

        self.volume.update_group(self.context,
                                 group,
                                 add_volumes=volume2.id,
                                 remove_volumes=volume.id)
        grp = objects.Group.get_by_id(self.context, group.id)
        expected = {
            'status': fields.GroupStatus.AVAILABLE,
            'name': 'test_group',
            'availability_zone': 'nova',
            'tenant_id': self.context.project_id,
            'created_at': mock.ANY,
            'user_id': fake.USER_ID,
            'group_id': group.id,
            'group_type': fake.GROUP_TYPE_ID
        }
        self.assertEqual(fields.GroupStatus.AVAILABLE, grp.status)
        self.assertEqual(10, len(self.notifier.notifications),
                         self.notifier.notifications)
        msg = self.notifier.notifications[6]
        self.assertEqual('group.update.start', msg['event_type'])
        self.assertDictEqual(expected, msg['payload'])
        msg = self.notifier.notifications[8]
        self.assertEqual('group.update.end', msg['event_type'])
        self.assertDictEqual(expected, msg['payload'])
        grpvolumes = db.volume_get_all_by_generic_group(self.context, group.id)
        grpvol_ids = [grpvol['id'] for grpvol in grpvolumes]
        # Verify volume is removed.
        self.assertNotIn(volume.id, grpvol_ids)
        # Verify volume is added.
        self.assertIn(volume2.id, grpvol_ids)

        volume3 = tests_utils.create_volume(self.context,
                                            group_id=None,
                                            host=group.host,
                                            volume_type_id=fake.VOLUME_TYPE_ID,
                                            status='wrong-status')
        volume_id3 = volume3['id']

        volume_get_orig = self.volume.db.volume_get
        self.volume.db.volume_get = mock.Mock(return_value={
            'status': 'wrong_status',
            'id': volume_id3
        })
        # Try to add a volume in wrong status
        self.assertRaises(exception.InvalidVolume,
                          self.volume.update_group,
                          self.context,
                          group,
                          add_volumes=volume_id3,
                          remove_volumes=None)
        self.volume.db.volume_get.reset_mock()
        self.volume.db.volume_get = volume_get_orig
Exemple #9
0
    def test_update_group(self, fake_update_grp,
                          fake_create_grp, fake_rollback,
                          fake_commit, fake_reserve):
        """Test group can be updated."""
        group = tests_utils.create_group(
            self.context,
            availability_zone=CONF.storage_availability_zone,
            volume_type_ids=[fake.VOLUME_TYPE_ID],
            group_type_id=fake.GROUP_TYPE_ID,
            host=CONF.host)
        self.volume.create_group(self.context, group)

        volume = tests_utils.create_volume(
            self.context,
            group_id=group.id,
            volume_type_id=fake.VOLUME_TYPE_ID,
            status='available',
            host=group.host)
        self.volume.create_volume(self.context, volume)

        volume2 = tests_utils.create_volume(
            self.context,
            group_id=None,
            volume_type_id=fake.VOLUME_TYPE_ID,
            status='available',
            host=group.host)
        self.volume.create_volume(self.context, volume)

        fake_update_grp.return_value = (
            {'status': fields.GroupStatus.AVAILABLE},
            [{'id': volume2.id, 'status': 'available'}],
            [{'id': volume.id, 'status': 'available'}])

        self.volume.update_group(self.context, group,
                                 add_volumes=volume2.id,
                                 remove_volumes=volume.id)
        grp = objects.Group.get_by_id(self.context, group.id)
        expected = {
            'status': fields.GroupStatus.AVAILABLE,
            'name': 'test_group',
            'availability_zone': 'nova',
            'tenant_id': self.context.project_id,
            'created_at': 'DONTCARE',
            'user_id': fake.USER_ID,
            'group_id': group.id,
            'group_type': fake.GROUP_TYPE_ID
        }
        self.assertEqual(fields.GroupStatus.AVAILABLE, grp.status)
        self.assertEqual(10, len(self.notifier.notifications),
                         self.notifier.notifications)
        msg = self.notifier.notifications[6]
        self.assertEqual('group.update.start', msg['event_type'])
        self.assertDictMatch(expected, msg['payload'])
        msg = self.notifier.notifications[8]
        self.assertEqual('group.update.end', msg['event_type'])
        self.assertDictMatch(expected, msg['payload'])
        grpvolumes = db.volume_get_all_by_generic_group(self.context, group.id)
        grpvol_ids = [grpvol['id'] for grpvol in grpvolumes]
        # Verify volume is removed.
        self.assertNotIn(volume.id, grpvol_ids)
        # Verify volume is added.
        self.assertIn(volume2.id, grpvol_ids)

        volume3 = tests_utils.create_volume(
            self.context,
            group_id=None,
            host=group.host,
            volume_type_id=fake.VOLUME_TYPE_ID,
            status='wrong-status')
        volume_id3 = volume3['id']

        volume_get_orig = self.volume.db.volume_get
        self.volume.db.volume_get = mock.Mock(
            return_value={'status': 'wrong_status',
                          'id': volume_id3})
        # Try to add a volume in wrong status
        self.assertRaises(exception.InvalidVolume,
                          self.volume.update_group,
                          self.context,
                          group,
                          add_volumes=volume_id3,
                          remove_volumes=None)
        self.volume.db.volume_get.reset_mock()
        self.volume.db.volume_get = volume_get_orig
    def test_update_group(self, raise_error, type_id,
                          fake_update_grp, fake_update_cg,
                          fake_generic_update,
                          fake_create_grp, fake_rollback,
                          fake_commit, fake_reserve, fake_get_type):
        """Test group can be updated."""
        group = tests_utils.create_group(
            self.context,
            availability_zone=CONF.storage_availability_zone,
            volume_type_ids=[fake.VOLUME_TYPE_ID],
            group_type_id=type_id,
            host=CONF.host)
        self.volume.create_group(self.context, group)

        volume = tests_utils.create_volume(
            self.context,
            group_id=group.id,
            volume_type_id=fake.VOLUME_TYPE_ID,
            status='available',
            host=group.host)
        self.volume.create_volume(self.context, volume)

        volume2 = tests_utils.create_volume(
            self.context,
            group_id=None,
            volume_type_id=fake.VOLUME_TYPE_ID,
            status='available',
            host=group.host)
        self.volume.create_volume(self.context, volume)

        driver_result = ({'status': fields.GroupStatus.AVAILABLE},
                         [{'id': volume2.id, 'status': 'available'}],
                         [{'id': volume.id, 'status': 'available'}])
        if raise_error:
            fake_update_grp.side_effect = [NotImplementedError]
            fake_update_cg.return_value = driver_result
            fake_generic_update.return_value = driver_result
        else:
            fake_update_grp.return_value = driver_result

        with mock.patch.object(
                self.volume, '_convert_group_to_cg',
                mock.Mock()) as mock_convert, mock.patch.object(
            self.volume,
                '_remove_consistencygroup_id_from_volumes',
                mock.Mock()):
            mock_convert.return_value = ('fake_cg', [volume])
            self.volume.update_group(self.context, group,
                                     add_volumes=volume2.id,
                                     remove_volumes=volume.id)
        if raise_error:
            if type_id == fake.GROUP_TYPE2_ID:
                fake_update_cg.assert_called_once_with(
                    self.context, 'fake_cg',
                    add_volumes=mock.ANY,
                    remove_volumes=[volume])
            else:
                fake_generic_update.assert_called_once_with(
                    self.context, group,
                    add_volumes=mock.ANY,
                    remove_volumes=mock.ANY)

        grp = objects.Group.get_by_id(self.context, group.id)
        expected = {
            'status': fields.GroupStatus.AVAILABLE,
            'name': 'test_group',
            'availability_zone': 'nova',
            'tenant_id': self.context.project_id,
            'created_at': mock.ANY,
            'user_id': fake.USER_ID,
            'group_id': group.id,
            'group_type': type_id
        }
        self.assertEqual(fields.GroupStatus.AVAILABLE, grp.status)
        self.assertEqual(10, len(self.notifier.notifications),
                         self.notifier.notifications)
        msg = self.notifier.notifications[6]
        self.assertEqual('group.update.start', msg['event_type'])
        self.assertDictEqual(expected, msg['payload'])
        msg = self.notifier.notifications[8]
        self.assertEqual('group.update.end', msg['event_type'])
        self.assertDictEqual(expected, msg['payload'])
        grpvolumes = db.volume_get_all_by_generic_group(self.context, group.id)
        grpvol_ids = [grpvol['id'] for grpvol in grpvolumes]
        # Verify volume is removed.
        self.assertNotIn(volume.id, grpvol_ids)
        # Verify volume is added.
        self.assertIn(volume2.id, grpvol_ids)

        volume3 = tests_utils.create_volume(
            self.context,
            group_id=None,
            host=group.host,
            volume_type_id=fake.VOLUME_TYPE_ID,
            status='wrong-status')
        volume_id3 = volume3['id']

        volume_get_orig = self.volume.db.volume_get
        self.volume.db.volume_get = mock.Mock(
            return_value={'status': 'wrong_status',
                          'id': volume_id3})
        # Try to add a volume in wrong status
        self.assertRaises(exception.InvalidVolume,
                          self.volume.update_group,
                          self.context,
                          group,
                          add_volumes=volume_id3,
                          remove_volumes=None)
        self.volume.db.volume_get.reset_mock()
        self.volume.db.volume_get = volume_get_orig