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()
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)
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)
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
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
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
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()
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
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