def test_delete_group_snapshot_available_used_as_source(self): group = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID], ) volume_id = utils.create_volume( self.context, group_id=group.id, volume_type_id=fake.VOLUME_TYPE_ID)['id'] group_snapshot = utils.create_group_snapshot(self.context, group_id=group.id, status='available') group2 = utils.create_group( self.context, status='creating', group_snapshot_id=group_snapshot.id, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID], ) req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots/%s' % (fake.PROJECT_ID, group_snapshot.id), version=GROUP_MICRO_VERSION) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.delete, req, group_snapshot.id) group_snapshot.destroy() db.volume_destroy(context.get_admin_context(), volume_id) group.destroy() group2.destroy()
def _test_failover_model_updates(self, in_volumes, in_snapshots, driver_volumes, driver_result, out_volumes, out_snapshots, in_groups=None, out_groups=None, driver_group_result=None, secondary_id=None): host = vol_utils.extract_host(self.manager.host) utils.create_service(self.context, {'host': host, 'binary': constants.VOLUME_BINARY}) for volume in in_volumes: utils.create_volume(self.context, self.manager.host, **volume) for snapshot in in_snapshots: utils.create_snapshot(self.context, **snapshot) for group in in_groups: utils.create_group(self.context, self.manager.host, **group) with mock.patch.object( self.manager.driver, 'failover_host', return_value=(secondary_id, driver_result, driver_group_result)) as driver_mock: self.manager.failover_host(self.context, secondary_id) self.assertSetEqual(driver_volumes, {v.id for v in driver_mock.call_args[0][1]}) self._check_failover_db(objects.VolumeList, out_volumes) self._check_failover_db(objects.SnapshotList, out_snapshots) self._check_failover_db(objects.GroupList, out_groups)
def _test_failover_model_updates(self, in_volumes, in_snapshots, driver_volumes, driver_result, out_volumes, out_snapshots, in_groups=None, out_groups=None, driver_group_result=None, secondary_id=None): host = vol_utils.extract_host(self.manager.host) utils.create_service(self.context, {'host': host, 'binary': 'cinder-volume'}) for volume in in_volumes: utils.create_volume(self.context, self.manager.host, **volume) for snapshot in in_snapshots: utils.create_snapshot(self.context, **snapshot) for group in in_groups: utils.create_group(self.context, self.manager.host, **group) with mock.patch.object( self.manager.driver, 'failover_host', return_value=(secondary_id, driver_result, driver_group_result)) as driver_mock: self.manager.failover_host(self.context, secondary_id) self.assertSetEqual(driver_volumes, {v.id for v in driver_mock.call_args[0][1]}) self._check_failover_db(objects.VolumeList, out_volumes) self._check_failover_db(objects.SnapshotList, out_snapshots) self._check_failover_db(objects.GroupList, out_groups)
def test_create_group_from_group(self, mock_volume_get_all, mock_rpc_create_group_from_src, mock_group_get, mock_volume_api_create, mock_mapping_create, mock_get_volume_type, mock_update_volumes_host): vol_type = fake_volume.fake_volume_type_obj(self.ctxt, id=fake.VOLUME_TYPE_ID, name='fake_volume_type') mock_get_volume_type.return_value = vol_type grp = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']], availability_zone='nova', status=fields.GroupStatus.CREATING) mock_group_get.return_value = grp vol = utils.create_volume(self.ctxt, availability_zone=grp.availability_zone, volume_type_id=fake.VOLUME_TYPE_ID, group_id=grp.id) mock_volume_get_all.return_value = [vol] grp2 = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']], availability_zone='nova', source_group_id=grp.id, status=fields.GroupStatus.CREATING) vol2 = utils.create_volume(self.ctxt, availability_zone=grp.availability_zone, volume_type_id=vol_type['id'], group_id=grp2.id, source_volid=vol.id) self.group_api._create_group_from_source_group(self.ctxt, grp2, grp.id) mock_volume_api_create.assert_called_once_with( self.ctxt, 1, None, None, availability_zone=grp.availability_zone, source_group=grp, group=grp2, source_volume=vol, volume_type=vol_type) mock_rpc_create_group_from_src.assert_called_once_with( self.ctxt, grp2, None, grp) mock_update_volumes_host.assert_called_once_with(self.ctxt, grp2) vol2.destroy() grp2.destroy() vol.destroy() grp.destroy()
def test_create_group_from_group(self, mock_volume_get_all, mock_rpc_create_group_from_src, mock_group_get, mock_volume_api_create, mock_mapping_create, mock_get_volume_type): vol_type = fake_volume.fake_volume_type_obj( self.ctxt, id=fake.VOLUME_TYPE_ID, name='fake_volume_type') mock_get_volume_type.return_value = vol_type grp = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']], availability_zone='nova', status=fields.GroupStatus.CREATING) mock_group_get.return_value = grp vol = utils.create_volume( self.ctxt, availability_zone=grp.availability_zone, volume_type_id=fake.VOLUME_TYPE_ID, group_id=grp.id) mock_volume_get_all.return_value = [vol] grp2 = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']], availability_zone='nova', source_group_id=grp.id, status=fields.GroupStatus.CREATING) vol2 = utils.create_volume( self.ctxt, availability_zone=grp.availability_zone, volume_type_id=vol_type['id'], group_id=grp2.id, source_volid=vol.id) self.group_api._create_group_from_source_group(self.ctxt, grp2, grp.id) mock_volume_api_create.assert_called_once_with( self.ctxt, 1, None, None, availability_zone=grp.availability_zone, source_group=grp, group=grp2, source_volume=vol, volume_type=vol_type) mock_rpc_create_group_from_src.assert_called_once_with( self.ctxt, grp2, None, grp) vol2.destroy() grp2.destroy() vol.destroy() grp.destroy()
def test_create_from_src(self, mock_validate_host, mock_snap_get_all, mock_group_snap_get, mock_update_quota, mock_create_from_group, mock_create_from_snap): name = "test_group" description = "this is a test group" grp = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID], availability_zone='nova', name=name, description=description, status=fields.GroupStatus.AVAILABLE,) vol1 = utils.create_volume( self.ctxt, availability_zone='nova', volume_type_id=fake.VOLUME_TYPE_ID, group_id=grp.id) snap = utils.create_snapshot(self.ctxt, vol1.id, volume_type_id=fake.VOLUME_TYPE_ID, status=fields.SnapshotStatus.AVAILABLE) mock_snap_get_all.return_value = [snap] mock_validate_host.return_host = True grp_snap = utils.create_group_snapshot( self.ctxt, grp.id, group_type_id=fake.GROUP_TYPE_ID, status=fields.GroupStatus.AVAILABLE) mock_group_snap_get.return_value = grp_snap grp2 = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID], availability_zone='nova', name=name, description=description, status=fields.GroupStatus.CREATING, group_snapshot_id=grp_snap.id) with mock.patch('cinder.objects.Group') as mock_group: mock_group.return_value = grp2 with mock.patch('cinder.objects.group.Group.create'): ret_group = self.group_api.create_from_src( self.ctxt, name, description, group_snapshot_id=grp_snap.id, source_group_id=None) self.assertEqual(grp2.obj_to_primitive(), ret_group.obj_to_primitive()) mock_create_from_snap.assert_called_once_with( self.ctxt, grp2, grp_snap.id) snap.destroy() grp_snap.destroy() vol1.destroy() grp.destroy() grp2.destroy()
def test_create_group_from_group_create_volume_failed( self, mock_volume_get_all, mock_rpc_create_group_from_src, mock_group_get, mock_volume_api_create, mock_mapping_create, mock_get_volume_type, mock_volume_delete): vol_type = fake_volume.fake_volume_type_obj( self.ctxt, id=fake.VOLUME_TYPE_ID, name='fake_volume_type') mock_get_volume_type.return_value = vol_type grp = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']], availability_zone='nova', status=fields.GroupStatus.CREATING) mock_group_get.return_value = grp vol1 = utils.create_volume( self.ctxt, availability_zone=grp.availability_zone, volume_type_id=fake.VOLUME_TYPE_ID, group_id=grp.id) vol2 = utils.create_volume( self.ctxt, availability_zone=grp.availability_zone, volume_type_id=fake.VOLUME_TYPE_ID, group_id=grp.id) mock_volume_get_all.side_effect = [[vol1, vol2], [vol1]] grp2 = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']], availability_zone='nova', source_group_id=grp.id, status=fields.GroupStatus.CREATING) mock_volume_api_create.side_effect = [None, exception.CinderException] self.assertRaises( exception.CinderException, self.group_api._create_group_from_source_group, self.ctxt, grp2, grp.id) mock_rpc_create_group_from_src.assert_not_called() mock_volume_delete.assert_called_once_with(self.ctxt, vol1) grp2.destroy() vol2.destroy() vol1.destroy() grp.destroy()
def test_delete_group_correct_host(self, mock_del_grp, _mock_create_grp): """Test group can be deleted. Test group can be deleted when volumes are on the correct volume node. """ 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) volume = tests_utils.create_volume( self.context, group_id=group.id, host='host1@backend1#pool1', status='creating', volume_type_id=fake.VOLUME_TYPE_ID, size=1) self.volume.host = 'host1@backend1' self.volume.create_volume(self.context, volume) self.volume.delete_group(self.context, group) grp = objects.Group.get_by_id( context.get_admin_context(read_deleted='yes'), group.id) self.assertEqual(fields.GroupStatus.DELETED, grp.status) self.assertRaises(exception.NotFound, objects.Group.get_by_id, self.context, group.id) self.assertTrue(mock_del_grp.called)
def test_show_group_snapshot(self): group = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID], ) volume_id = utils.create_volume( self.context, group_id=group.id, volume_type_id=fake.VOLUME_TYPE_ID)['id'] group_snapshot = utils.create_group_snapshot(self.context, group_id=group.id) req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots/%s' % (fake.PROJECT_ID, group_snapshot.id), version=GROUP_MICRO_VERSION) res_dict = self.controller.show(req, group_snapshot.id) self.assertEqual(1, len(res_dict)) self.assertEqual('this is a test group snapshot', res_dict['group_snapshot']['description']) self.assertEqual('test_group_snapshot', res_dict['group_snapshot']['name']) self.assertEqual('creating', res_dict['group_snapshot']['status']) group_snapshot.destroy() db.volume_destroy(context.get_admin_context(), volume_id) group.destroy()
def test_delete_group_cluster(self, mock_del_grp): """Test group can be deleted on another service in the cluster.""" cluster_name = 'cluster@backend1' self.volume.host = 'host2@backend1' self.volume.cluster = cluster_name group = tests_utils.create_group( self.context, host=CONF.host + 'fake', cluster_name=cluster_name, availability_zone=CONF.storage_availability_zone, volume_type_ids=[fake.VOLUME_TYPE_ID], group_type_id=fake.GROUP_TYPE_ID) volume = tests_utils.create_volume( self.context, group_id=group.id, host='host1@backend1#pool1', cluster_name=cluster_name, status='creating', volume_type_id=fake.VOLUME_TYPE_ID, size=1) self.volume.host = 'host2@backend1' self.volume.create_volume(self.context, volume) self.volume.delete_group(self.context, group) grp = objects.Group.get_by_id( context.get_admin_context(read_deleted='yes'), group.id) self.assertEqual(fields.GroupStatus.DELETED, grp.status) self.assertRaises(exception.NotFound, objects.Group.get_by_id, self.context, group.id) self.assertTrue(mock_del_grp.called)
def test_create_volume_with_group_invalid_type(self): """Test volume creation with group & invalid volume type.""" db_vol_type = db.volume_type_get_by_name(context.get_admin_context(), '__DEFAULT__') grp = tests_utils.create_group( self.context, availability_zone=CONF.storage_availability_zone, status=fields.GroupStatus.AVAILABLE, volume_type_ids=[db_vol_type['id']], group_type_id=fake.GROUP_TYPE_ID, host=CONF.host) fake_type = fake_volume.fake_volume_type_obj( self.context, id=fake.VOLUME_TYPE_ID, name='fake') # Volume type must be provided when creating a volume in a # group. self.assertRaises(exception.InvalidInput, self.volume_api.create, self.context, 1, 'vol1', 'volume 1', group=grp) # Volume type must be valid. self.assertRaises(exception.InvalidInput, self.volume_api.create, self.context, 1, 'vol1', 'volume 1', volume_type=fake_type, group=grp)
def test_list_replication_targets_group_policy(self, user_id, mock_list_targets): """Test list replication targets for a group policy.""" # FIXME: this is a very fragile approach def fake_list_targets(context, group): context.authorize(group_policies.LIST_REP, target_obj=group) volume_type = test_utils.create_volume_type(self.project_admin_context, name='test_group_policy') group_2 = test_utils.create_group(self.project_admin_context, status=fields.GroupStatus.AVAILABLE, group_type_id=self.group_type.id, volume_type_ids=[volume_type.id]) mock_list_targets.side_effect = fake_list_targets rule_name = group_policies.LIST_REP url = '%s/%s/action' % (self.api_path, group_2.id) req = fake_api.HTTPRequest.blank(url, version=mv.GROUP_REPLICATION) req.method = 'POST' body = {"list_replication_targets": {}} unauthorized_exceptions = [exception.GroupNotFound] self.common_policy_check(user_id, self.authorized_members, self.unauthorized_members, unauthorized_exceptions, rule_name, self.controller.list_replication_targets, req, id=group_2.id, body=body) group_2.destroy()
def test_create_group_snapshot_with_bootable_volumes(self, mock_create_grpsnap): """Test group_snapshot can be created and deleted.""" 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) volume = tests_utils.create_volume( self.context, group_id=group.id, host=group.host, volume_type_id=fake.VOLUME_TYPE_ID) self.volume.create_volume(self.context, volume) # Create a bootable volume bootable_vol_params = {'status': 'creating', 'host': CONF.host, 'size': 1, 'bootable': True} bootable_vol = tests_utils.create_volume(self.context, group_id=group.id, **bootable_vol_params) # Create a common volume self.volume.create_volume(self.context, bootable_vol) volume_ids = [volume.id, bootable_vol.id] group_snapshot_returns = self._create_group_snapshot(group.id, volume_ids) group_snapshot = group_snapshot_returns[0] self.volume.create_group_snapshot(self.context, group_snapshot) self.assertEqual(group_snapshot.id, objects.GroupSnapshot.get_by_id( context.get_admin_context(), group_snapshot.id).id) self.assertTrue(mock_create_grpsnap.called)
def test_delete_group_wrong_host(self, *_mock_create_grp): """Test group cannot be deleted. Test group cannot be deleted when volumes in the group are not local to the volume node. """ 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) volume = tests_utils.create_volume( self.context, group_id=group.id, host='host1@backend1#pool1', status='creating', volume_type_id=fake.VOLUME_TYPE_ID, size=1) self.volume.host = 'host1@backend2' self.volume.create_volume(self.context, volume) self.assertRaises(exception.InvalidVolume, self.volume.delete_group, self.context, group) grp = objects.Group.get_by_id(self.context, group.id) # Group is not deleted self.assertEqual(fields.GroupStatus.AVAILABLE, grp.status)
def test_list_group_snapshots_json(self): group = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID] ) volume_id = utils.create_volume(self.context, group_id=group.id, volume_type_id=fake.VOLUME_TYPE_ID)["id"] group_snapshot1 = utils.create_group_snapshot( self.context, group_id=group.id, group_type_id=group.group_type_id ) group_snapshot2 = utils.create_group_snapshot( self.context, group_id=group.id, group_type_id=group.group_type_id ) group_snapshot3 = utils.create_group_snapshot( self.context, group_id=group.id, group_type_id=group.group_type_id ) req = fakes.HTTPRequest.blank("/v3/%s/group_snapshots" % fake.PROJECT_ID, version=GROUP_MICRO_VERSION) res_dict = self.controller.index(req) self.assertEqual(1, len(res_dict)) self.assertEqual(group_snapshot1.id, res_dict["group_snapshots"][0]["id"]) self.assertEqual("test_group_snapshot", res_dict["group_snapshots"][0]["name"]) self.assertEqual(group_snapshot2.id, res_dict["group_snapshots"][1]["id"]) self.assertEqual("test_group_snapshot", res_dict["group_snapshots"][1]["name"]) self.assertEqual(group_snapshot3.id, res_dict["group_snapshots"][2]["id"]) self.assertEqual("test_group_snapshot", res_dict["group_snapshots"][2]["name"]) group_snapshot3.destroy() group_snapshot2.destroy() group_snapshot1.destroy() db.volume_destroy(context.get_admin_context(), volume_id) group.destroy()
def test_create_volume_with_group_invalid_type(self): """Test volume creation with group & invalid volume type.""" vol_type = db.volume_type_create( context.get_admin_context(), dict(name=conf_fixture.def_vol_type, extra_specs={}) ) db_vol_type = db.volume_type_get(context.get_admin_context(), vol_type.id) grp = tests_utils.create_group( self.context, availability_zone=CONF.storage_availability_zone, status=fields.GroupStatus.AVAILABLE, volume_type_ids=[db_vol_type['id']], group_type_id=fake.GROUP_TYPE_ID, host=CONF.host) fake_type = { 'id': '9999', 'name': 'fake', } # Volume type must be provided when creating a volume in a # group. self.assertRaises(exception.InvalidInput, self.volume_api.create, self.context, 1, 'vol1', 'volume 1', group=grp) # Volume type must be valid. self.assertRaises(exception.InvalidInput, self.volume_api.create, self.context, 1, 'vol1', 'volume 1', volume_type=fake_type, group=grp)
def test_create_group_snapshot_when_volume_in_error_status( self, mock_vol_type, mock_validate): group = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID],) volume_id = utils.create_volume( self.context, status='error', group_id=group.id, volume_type_id=fake.VOLUME_TYPE_ID)['id'] body = {"group_snapshot": {"name": "group_snapshot1", "description": "Group Snapshot 1", "group_id": group.id}} req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots' % fake.PROJECT_ID, version=GROUP_MICRO_VERSION) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create, req, body) self.assertTrue(mock_validate.called) group.destroy() db.volume_destroy(context.get_admin_context(), volume_id)
def test_update_volumes_host(self, mock_volume_get_all, mock_cluster_name, mock_host): vol_type = utils.create_volume_type(self.ctxt, name='test_vol_type') grp = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']], availability_zone='nova', status=fields.GroupStatus.CREATING, cluster_name='fake_cluster') vol1 = utils.create_volume( self.ctxt, availability_zone=grp.availability_zone, volume_type_id=fake.VOLUME_TYPE_ID, group_id=grp.id) mock_volume = mock.Mock() mock_volume_get_all.return_value = [mock_volume] group_api = cinder.group.api.API() group_api._update_volumes_host(None, grp) mock_cluster_name.assert_called() mock_host.assert_called() self.assertEqual(grp.host, mock_volume.host) self.assertEqual(grp.cluster_name, mock_volume.cluster_name) mock_volume.save.assert_called_once_with() vol1.destroy() grp.destroy()
def test_delete_cgsnapshot_delete_policy_not_auth(self, mock_delete): vol_type = utils.create_volume_type(context.get_admin_context(), self, name='my_vol_type') consistencygroup = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']]) volume_id = utils.create_volume(self.context, volume_type_id=vol_type['id'], group_id= consistencygroup.id)['id'] cgsnapshot = utils.create_group_snapshot( self.context, group_id=consistencygroup.id, group_type_id=fake.GROUP_TYPE_ID, status='available') mock_delete.side_effect = exception.PolicyNotAuthorized( message='PolicyNotAuthorized') req = webob.Request.blank('/v2/%s/cgsnapshots/%s' % (fake.PROJECT_ID, cgsnapshot.id)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' res = req.get_response(fakes.wsgi_app( fake_auth_context=self.user_ctxt)) res_dict = jsonutils.loads(res.body) self.assertEqual('PolicyNotAuthorized', res_dict['forbidden']['message']) cgsnapshot.destroy() db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_delete_group_policy(self, user_id): """Test delete group policy.""" volume_type = test_utils.create_volume_type(self.project_admin_context, name='test_group_policy') group_1 = test_utils.create_group(self.project_admin_context, status=fields.GroupStatus.AVAILABLE, group_type_id=self.group_type.id, volume_type_ids=[volume_type.id]) rule_name = group_policies.DELETE_POLICY url = '%s/%s' % (self.api_path, group_1.id) req = fake_api.HTTPRequest.blank(url, version=mv.GROUP_VOLUME) req.method = 'POST' body = {"delete": {"delete-volumes": "false"}} unauthorized_exceptions = [exception.GroupNotFound] self.common_policy_check(user_id, self.authorized_members, self.unauthorized_members, unauthorized_exceptions, rule_name, self.controller.delete_group, req, id=group_1.id, body=body)
def test_create_group_failed_update_quota(self, mock_policy, mock_volume_types_get, mock_group_type_get, mock_group, mock_group_quota_reserve): mock_volume_types_get.return_value = [{'id': fake.VOLUME_TYPE_ID}] mock_group_type_get.return_value = {'id': fake.GROUP_TYPE_ID} fake_overs = ['groups'] fake_quotas = {'groups': 1} fake_usages = {'groups': {'reserved': 0, 'in_use': 1}} mock_group_quota_reserve.side_effect = exception.OverQuota( overs=fake_overs, quotas=fake_quotas, usages=fake_usages) name = "test_group" description = "this is a test group" grp = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID], availability_zone='nova', host=None, name=name, description=description, status=fields.GroupStatus.CREATING) mock_group.return_value = grp self.assertRaises(exception.GroupLimitExceeded, self.group_api.create, self.ctxt, name, description, "fake-grouptype-name", [fake.VOLUME_TYPE_ID], availability_zone='nova')
def test_create_group_snapshot_when_volume_in_error_status( self, mock_vol_type): group = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID], ) volume_id = utils.create_volume( self.context, status='error', group_id=group.id, volume_type_id=fake.VOLUME_TYPE_ID)['id'] body = { "group_snapshot": { "name": "group_snapshot1", "description": "Group Snapshot 1", "group_id": group.id } } req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots' % fake.PROJECT_ID, version=mv.GROUP_SNAPSHOTS) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create, req, body=body) group.destroy() db.volume_destroy(context.get_admin_context(), volume_id)
def test_create_volume_of_group(self): group_type = group_types.create( self.context, 'group', {'consistent_group_snapshot_enabled': '<is> True'}) group = test_utils.create_group(self.context, id=fake_constants.CONSISTENCY_GROUP_ID, host='host@backend#unit_test_pool', group_type_id=group_type.id) self.DPL_MOCK.create_vdev.return_value = DATA_OUTPUT self.DPL_MOCK.join_vg.return_value = DATA_OUTPUT volume = test_utils.create_volume( self.context, id=DATA_IN_VOLUME_VG['id'], display_name=DATA_IN_VOLUME_VG['display_name'], size=DATA_IN_VOLUME_VG['size'], group_id=group.id, host=DATA_IN_VOLUME_VG['host']) self.dpldriver.create_volume(volume) self.DPL_MOCK.create_vdev.assert_called_once_with( self._conver_uuid2hex(volume.id), volume.display_name, volume.display_description, self.configuration.dpl_pool, int(volume.size) * units.Gi, True) self.DPL_MOCK.join_vg.assert_called_once_with( self._conver_uuid2hex(volume.id), self._conver_uuid2hex(volume.group_id))
def test_delete_group_snapshot_available(self): group = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID], ) volume_id = utils.create_volume( self.context, group_id=group.id, volume_type_id=fake.VOLUME_TYPE_ID)['id'] group_snapshot = utils.create_group_snapshot(self.context, group_id=group.id, status='available') req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots/%s' % (fake.PROJECT_ID, group_snapshot.id), version=GROUP_MICRO_VERSION) res_dict = self.controller.delete(req, group_snapshot.id) group_snapshot = objects.GroupSnapshot.get_by_id( self.context, group_snapshot.id) self.assertEqual(202, res_dict.status_int) self.assertEqual('deleting', group_snapshot.status) group_snapshot.destroy() db.volume_destroy(context.get_admin_context(), volume_id) group.destroy()
def test_delete_cgsnapshot_delete_policy_not_auth(self, mock_delete): vol_type = utils.create_volume_type(context.get_admin_context(), self, name='my_vol_type') consistencygroup = utils.create_group(self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']]) volume_id = utils.create_volume(self.context, volume_type_id=vol_type['id'], group_id=consistencygroup.id)['id'] cgsnapshot = utils.create_group_snapshot( self.context, group_id=consistencygroup.id, group_type_id=fake.GROUP_TYPE_ID, status='available') mock_delete.side_effect = exception.PolicyNotAuthorized( message='PolicyNotAuthorized') req = webob.Request.blank('/v2/%s/cgsnapshots/%s' % (fake.PROJECT_ID, cgsnapshot.id)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' res = req.get_response( fakes.wsgi_app(fake_auth_context=self.user_ctxt)) res_dict = jsonutils.loads(res.body) self.assertEqual('PolicyNotAuthorized', res_dict['forbidden']['message']) cgsnapshot.destroy() db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_delete_group_frozen(self): service = utils.create_service(self.ctxt, {'frozen': True}) group = utils.create_group(self.ctxt, host=service.host, group_type_id='gt') group_api = cinder.group.api.API() self.assertRaises(exception.InvalidInput, group_api.delete, self.ctxt, group)
def test_delete_volume_of_group(self): group_type = group_types.create( self.context, 'group', {'consistent_group_snapshot_enabled': '<is> True'} ) group = test_utils.create_group( self.context, id=fake_constants.CONSISTENCY_GROUP_ID, host='host@backend#unit_test_pool', group_type_id=group_type.id) volume = test_utils.create_volume( self.context, id=DATA_IN_VOLUME_VG['id'], display_name=DATA_IN_VOLUME_VG['display_name'], size=DATA_IN_VOLUME_VG['size'], group_id=group.id, host=DATA_IN_VOLUME_VG['host']) self.DPL_MOCK.delete_vdev.return_value = DATA_OUTPUT self.DPL_MOCK.leave_vg.return_volume = DATA_OUTPUT self.dpldriver.delete_volume(volume) self.DPL_MOCK.leave_vg.assert_called_once_with( self._conver_uuid2hex(volume.id), self._conver_uuid2hex(volume.group_id) ) self.DPL_MOCK.delete_vdev.assert_called_once_with( self._conver_uuid2hex(volume.id))
def test_update_group_exception_leave(self): group_type = group_types.create( self.context, 'group', {'consistent_group_snapshot_enabled': '<is> True'} ) self.DPL_MOCK.get_vg.return_value = (0, DATA_OUT_CG) self.DPL_MOCK.leave_vg.return_value = -1, None volume = test_utils.create_volume( self.context, id='fe2dbc51-5810-451d-ab2f-8c8a48d15bee', display_name=DATA_IN_VOLUME_VG['display_name'], size=DATA_IN_VOLUME_VG['size'], host=DATA_IN_VOLUME_VG['host']) group = test_utils.create_group( self.context, id=fake_constants.CONSISTENCY_GROUP_ID, host='host@backend#unit_test_pool', group_type_id=group_type.id) self.assertRaises(exception.VolumeBackendAPIException, self.dpldriver.update_group, context=None, group=group, add_volumes=None, remove_volumes=[volume])
def test_create_delete(self, mock_volume_types_get, mock_group_type_get, mock_group, mock_update_quota, mock_cast_create_group, mock_volumes_update, mock_volume_get_all, mock_rpc_delete_group): mock_volume_types_get.return_value = [{'id': fake.VOLUME_TYPE_ID}] mock_group_type_get.return_value = {'id': fake.GROUP_TYPE_ID} name = "test_group" description = "this is a test group" grp = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID], availability_zone='nova', host=None, name=name, description=description, status=fields.GroupStatus.CREATING) mock_group.return_value = grp ret_group = self.group_api.create(self.ctxt, name, description, fake.GROUP_TYPE_ID, [fake.VOLUME_TYPE_ID], availability_zone='nova') self.assertEqual(grp.obj_to_primitive(), ret_group.obj_to_primitive()) ret_group.host = "test_host@fakedrv#fakepool" ret_group.status = fields.GroupStatus.AVAILABLE ret_group.assert_not_frozen = mock.Mock(return_value=True) ret_group.group_snapshots = [] self.group_api.delete(self.ctxt, ret_group, delete_volumes=True) mock_volume_get_all.assert_called_once_with(mock.ANY, ret_group.id) mock_volumes_update.assert_called_once_with(self.ctxt, []) mock_rpc_delete_group.assert_called_once_with(self.ctxt, ret_group)
def test_create_group_from_src_grp(self): self.mock_object(volume_api.API, "create", v3_fakes.fake_volume_create) source_grp = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID]) volume = utils.create_volume(self.ctxt, group_id=source_grp.id, volume_type_id=fake.VOLUME_TYPE_ID) test_grp_name = 'test cg' body = { "create-from-src": { "name": test_grp_name, "description": "Consistency Group 1", "source_group_id": source_grp.id } } req = fakes.HTTPRequest.blank('/v3/%s/groups/action' % fake.PROJECT_ID, version=GROUP_FROM_SRC_MICRO_VERSION) res_dict = self.controller.create_from_src(req, body) self.assertIn('id', res_dict['group']) self.assertEqual(test_grp_name, res_dict['group']['name']) grp = objects.Group.get_by_id(self.ctxt, res_dict['group']['id']) grp.destroy() volume.destroy() source_grp.destroy()
def test_delete_cgsnapshot_available_used_as_source(self): vol_type = utils.create_volume_type(context.get_admin_context(), self, name='my_vol_type') consistencygroup = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']]) volume_id = utils.create_volume(self.context, volume_type_id=vol_type['id'], group_id= consistencygroup.id)['id'] cgsnapshot = utils.create_group_snapshot( self.context, group_id=consistencygroup.id, group_type_id=fake.GROUP_TYPE_ID, status='available') cg2 = utils.create_consistencygroup( self.context, status='creating', group_snapshot_id=cgsnapshot.id, group_type_id=fake.GROUP_TYPE_ID) req = webob.Request.blank('/v2/fake/cgsnapshots/%s' % cgsnapshot.id) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' res = req.get_response(fakes.wsgi_app()) cgsnapshot = objects.GroupSnapshot.get_by_id(self.context, cgsnapshot.id) self.assertEqual(http_client.BAD_REQUEST, res.status_int) self.assertEqual('available', cgsnapshot.status) cgsnapshot.destroy() db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy() cg2.destroy()
def test_delete_cgsnapshot_with_invalid_cgsnapshot(self): vol_type = utils.create_volume_type(context.get_admin_context(), self, name='my_vol_type') consistencygroup = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']]) volume_id = utils.create_volume(self.context, volume_type_id=vol_type['id'], group_id= consistencygroup.id)['id'] cgsnapshot = utils.create_group_snapshot( self.context, group_id=consistencygroup.id, group_type_id=fake.GROUP_TYPE_ID, status='invalid') req = webob.Request.blank('/v2/%s/cgsnapshots/%s' % ( fake.PROJECT_ID, cgsnapshot.id)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' res = req.get_response(fakes.wsgi_app( fake_auth_context=self.user_ctxt)) res_dict = jsonutils.loads(res.body) self.assertEqual(http_client.BAD_REQUEST, res.status_int) self.assertEqual(http_client.BAD_REQUEST, res_dict['badRequest']['code']) self.assertIsNotNone(res_dict['badRequest']['message']) cgsnapshot.destroy() db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_delete_cgsnapshot_available(self): vol_type = utils.create_volume_type(context.get_admin_context(), self, name='my_vol_type') consistencygroup = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']]) volume_id = utils.create_volume(self.context, volume_type_id=vol_type['id'], group_id= consistencygroup.id)['id'] cgsnapshot = utils.create_group_snapshot( self.context, group_id=consistencygroup.id, group_type_id=fake.GROUP_TYPE_ID, status='available') req = webob.Request.blank('/v2/%s/cgsnapshots/%s' % (fake.PROJECT_ID, cgsnapshot.id)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' res = req.get_response(fakes.wsgi_app( fake_auth_context=self.user_ctxt)) cgsnapshot = objects.GroupSnapshot.get_by_id(self.context, cgsnapshot.id) self.assertEqual(http_client.ACCEPTED, res.status_int) self.assertEqual('deleting', cgsnapshot.status) cgsnapshot.destroy() db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_create_cgsnapshot_from_empty_consistencygroup(self): vol_type = utils.create_volume_type(context.get_admin_context(), self, name='my_vol_type') consistencygroup = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']]) body = {"cgsnapshot": {"name": "cg1", "description": "CG Snapshot 1", "consistencygroup_id": consistencygroup.id}} req = webob.Request.blank('/v2/%s/cgsnapshots' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) res = req.get_response(fakes.wsgi_app( fake_auth_context=self.user_ctxt)) res_dict = jsonutils.loads(res.body) self.assertEqual(http_client.BAD_REQUEST, res.status_int) self.assertEqual(http_client.BAD_REQUEST, res_dict['badRequest']['code']) self.assertIsNotNone(res_dict['badRequest']['message']) # If failed to create cgsnapshot, its DB object should not be created self.assertListEqual( [], list(objects.GroupSnapshotList.get_all(self.context))) consistencygroup.destroy()
def test_create_with_cgsnapshot_not_found(self, mock_create_cgsnapshot): vol_type = utils.create_volume_type(context.get_admin_context(), self, name='my_vol_type') consistencygroup = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']]) volume_id = utils.create_volume(self.context, volume_type_id=vol_type['id'], group_id=consistencygroup.id)['id'] body = {"cgsnapshot": {"name": "cg1", "description": "CG Snapshot 1", "consistencygroup_id": consistencygroup.id}} req = webob.Request.blank('/v2/%s/cgsnapshots' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) res = req.get_response(fakes.wsgi_app( fake_auth_context=self.user_ctxt)) res_dict = jsonutils.loads(res.body) self.assertEqual(http_client.NOT_FOUND, res.status_int) self.assertEqual(http_client.NOT_FOUND, res_dict['itemNotFound']['code']) self.assertEqual('GroupSnapshot invalid_id could not be found.', res_dict['itemNotFound']['message']) db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_create_cgsnapshot_json(self, mock_validate): vol_type = utils.create_volume_type(context.get_admin_context(), self, name='my_vol_type') consistencygroup = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[vol_type['id']]) volume_id = utils.create_volume(self.context, volume_type_id=vol_type['id'], group_id= consistencygroup.id)['id'] body = {"cgsnapshot": {"name": "cg1", "description": "CG Snapshot 1", "consistencygroup_id": consistencygroup.id}} req = webob.Request.blank('/v2/%s/cgsnapshots' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) res = req.get_response(fakes.wsgi_app( fake_auth_context=self.user_ctxt)) res_dict = jsonutils.loads(res.body) self.assertEqual(http_client.ACCEPTED, res.status_int) self.assertIn('id', res_dict['cgsnapshot']) self.assertTrue(mock_validate.called) cgsnapshot = objects.GroupSnapshot.get_by_id( context.get_admin_context(), res_dict['cgsnapshot']['id']) cgsnapshot.destroy() db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_create_group_from_src_grp(self): self.mock_object(volume_api.API, "create", v3_fakes.fake_volume_create) source_grp = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID]) volume = utils.create_volume( self.ctxt, group_id=source_grp.id, volume_type_id=fake.VOLUME_TYPE_ID) test_grp_name = 'test cg' body = {"create-from-src": {"name": test_grp_name, "description": "Consistency Group 1", "source_group_id": source_grp.id}} req = fakes.HTTPRequest.blank('/v3/%s/groups/action' % fake.PROJECT_ID, version=GROUP_FROM_SRC_MICRO_VERSION) res_dict = self.controller.create_from_src(req, body) self.assertIn('id', res_dict['group']) self.assertEqual(test_grp_name, res_dict['group']['name']) grp = objects.Group.get_by_id( self.ctxt, res_dict['group']['id']) grp.destroy() volume.destroy() source_grp.destroy()
def test_create_delete(self, mock_policy, mock_volume_types_get, mock_group_type_get, mock_group, mock_update_quota, mock_cast_create_group, mock_volumes_update, mock_volume_get_all, mock_rpc_delete_group): mock_volume_types_get.return_value = [{'id': fake.VOLUME_TYPE_ID}] mock_group_type_get.return_value = {'id': fake.GROUP_TYPE_ID} name = "test_group" description = "this is a test group" grp = utils.create_group(self.ctxt, group_type_id = fake.GROUP_TYPE_ID, volume_type_ids = [fake.VOLUME_TYPE_ID], availability_zone = 'nova', host = None, name = name, description = description, status = fields.GroupStatus.CREATING) mock_group.return_value = grp ret_group = self.group_api.create(self.ctxt, name, description, fake.GROUP_TYPE_ID, [fake.VOLUME_TYPE_ID], availability_zone = 'nova') self.assertEqual(grp.obj_to_primitive(), ret_group.obj_to_primitive()) ret_group.host = "test_host@fakedrv#fakepool" ret_group.status = fields.GroupStatus.AVAILABLE self.group_api.delete(self.ctxt, ret_group, delete_volumes = True) mock_volume_get_all.assert_called_once_with(mock.ANY, ret_group.id) mock_volumes_update.assert_called_once_with(self.ctxt, []) mock_rpc_delete_group.assert_called_once_with(self.ctxt, ret_group)
def test_create_with_group_name(self, mock_volume_types_get, mock_group_type_get, mock_group, mock_update_quota, mock_cast_create_group): mock_volume_types_get.return_value = [{'id': fake.VOLUME_TYPE_ID}] mock_group_type_get.return_value = {'id': fake.GROUP_TYPE_ID} name = "test_group" description = "this is a test group" grp = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID], availability_zone='nova', host=None, name=name, description=description, status=fields.GroupStatus.CREATING) mock_group.return_value = grp ret_group = self.group_api.create(self.ctxt, name, description, "fake-grouptype-name", [fake.VOLUME_TYPE_ID], availability_zone='nova') self.assertEqual(grp.obj_to_primitive(), ret_group.obj_to_primitive()) mock_group_type_get.assert_called_once_with(self.ctxt, "fake-grouptype-name")
def test_create_group_failed_update_quota(self, mock_volume_types_get, mock_group_type_get, mock_group, mock_group_quota_reserve): mock_volume_types_get.return_value = [{'id': fake.VOLUME_TYPE_ID}] mock_group_type_get.return_value = {'id': fake.GROUP_TYPE_ID} fake_overs = ['groups'] fake_quotas = {'groups': 1} fake_usages = {'groups': {'reserved': 0, 'in_use': 1}} mock_group_quota_reserve.side_effect = exception.OverQuota( overs=fake_overs, quotas=fake_quotas, usages=fake_usages) name = "test_group" description = "this is a test group" grp = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID], availability_zone='nova', host=None, name=name, description=description, status=fields.GroupStatus.CREATING) mock_group.return_value = grp self.assertRaises(exception.GroupLimitExceeded, self.group_api.create, self.ctxt, name, description, "fake-grouptype-name", [fake.VOLUME_TYPE_ID], availability_zone='nova')
def test_delete_group_wrong_host(self, *_mock_create_grp): """Test group cannot be deleted. Test group cannot be deleted when volumes in the group are not local to the volume node. """ 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) volume = tests_utils.create_volume(self.context, group_id=group.id, host='host1@backend1#pool1', status='creating', volume_type_id=fake.VOLUME_TYPE_ID, size=1) self.volume.host = 'host1@backend2' self.volume.create_volume(self.context, volume) self.assertRaises(exception.Invalid, self.volume.delete_group, self.context, group) grp = objects.Group.get_by_id(self.context, group.id) # Group is not deleted self.assertEqual(fields.GroupStatus.AVAILABLE, grp.status)
def test_delete_group_cluster(self, mock_del_grp): """Test group can be deleted on another service in the cluster.""" cluster_name = 'cluster@backend1' self.volume.host = 'host2@backend1' self.volume.cluster = cluster_name group = tests_utils.create_group( self.context, host=CONF.host + 'fake', cluster_name=cluster_name, availability_zone=CONF.storage_availability_zone, volume_type_ids=[fake.VOLUME_TYPE_ID], group_type_id=fake.GROUP_TYPE_ID) volume = tests_utils.create_volume(self.context, group_id=group.id, host='host1@backend1#pool1', cluster_name=cluster_name, status='creating', volume_type_id=fake.VOLUME_TYPE_ID, size=1) self.volume.host = 'host2@backend1' self.volume.create_volume(self.context, volume) self.volume.delete_group(self.context, group) grp = objects.Group.get_by_id( context.get_admin_context(read_deleted='yes'), group.id) self.assertEqual(fields.GroupStatus.DELETED, grp.status) self.assertRaises(exception.NotFound, objects.Group.get_by_id, self.context, group.id) self.assertTrue(mock_del_grp.called)
def test_delete_group_correct_host(self, mock_del_grp, _mock_create_grp): """Test group can be deleted. Test group can be deleted when volumes are on the correct volume node. """ 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) volume = tests_utils.create_volume(self.context, group_id=group.id, host='host1@backend1#pool1', status='creating', volume_type_id=fake.VOLUME_TYPE_ID, size=1) self.volume.host = 'host1@backend1' self.volume.create_volume(self.context, volume) self.volume.delete_group(self.context, group) grp = objects.Group.get_by_id( context.get_admin_context(read_deleted='yes'), group.id) self.assertEqual(fields.GroupStatus.DELETED, grp.status) self.assertRaises(exception.NotFound, objects.Group.get_by_id, self.context, group.id) self.assertTrue(mock_del_grp.called)
def test_update(self, mock_policy, mock_volume_types_get, mock_group_type_get, mock_group, mock_update_quota, mock_cast_create_group, mock_volume_get_all, mock_rpc_update_group): vol_type_dict = {'id': fake.VOLUME_TYPE_ID, 'name': 'fake_volume_type'} vol_type = objects.VolumeType(self.ctxt, **vol_type_dict) mock_volume_types_get.return_value = [{'id': fake.VOLUME_TYPE_ID}] mock_group_type_get.return_value = {'id': fake.GROUP_TYPE_ID} name = "test_group" description = "this is a test group" grp = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID], availability_zone='nova', host=None, name=name, description=description, status=fields.GroupStatus.CREATING) mock_group.return_value = grp ret_group = self.group_api.create(self.ctxt, name, description, fake.GROUP_TYPE_ID, [fake.VOLUME_TYPE_ID], availability_zone='nova') self.assertEqual(grp.obj_to_primitive(), ret_group.obj_to_primitive()) ret_group.volume_types = [vol_type] ret_group.host = "test_host@fakedrv#fakepool" ret_group.status = fields.GroupStatus.AVAILABLE ret_group.id = fake.GROUP_ID vol1 = utils.create_volume( self.ctxt, host=ret_group.host, availability_zone=ret_group.availability_zone, volume_type_id=fake.VOLUME_TYPE_ID) vol2 = utils.create_volume( self.ctxt, host=ret_group.host, availability_zone=ret_group.availability_zone, volume_type_id=fake.VOLUME_TYPE_ID, group_id=fake.GROUP_ID) vol2_dict = { 'id': vol2.id, 'group_id': fake.GROUP_ID, 'volume_type_id': fake.VOLUME_TYPE_ID, 'availability_zone': ret_group.availability_zone, 'host': ret_group.host, 'status': 'available', } mock_volume_get_all.return_value = [vol2_dict] new_name = "new_group_name" new_desc = "this is a new group" self.group_api.update(self.ctxt, ret_group, new_name, new_desc, vol1.id, vol2.id) mock_volume_get_all.assert_called_once_with(mock.ANY, ret_group.id) mock_rpc_update_group.assert_called_once_with(self.ctxt, ret_group, add_volumes=vol1.id, remove_volumes=vol2.id) mock_policy.assert_called_with(self.ctxt, 'update', mock.ANY)
def test_create_group_snapshot_from_empty_group(self): group = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID] ) body = {"group_snapshot": {"name": "group_snapshot1", "description": "Group Snapshot 1", "group_id": group.id}} req = fakes.HTTPRequest.blank("/v3/%s/group_snapshots" % fake.PROJECT_ID, version=GROUP_MICRO_VERSION) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create, req, body) group.destroy()
def test_create_vol_with_group_id_driver_exception(self, mock_create_volume, mock_create_from_snap, mock_create_cloned_vol): """Test create a volume with group_id but driver exception.""" # create_raw_volume with group id, but driver exception mock_create_volume.side_effect = exception.CinderException 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.assertRaises(exception.CinderException, self.volume.create_volume, self.context, volume) self.assertIsNone(volume.consistencygroup_id) # create volume from_snapshot with group id but driver exception mock_create_from_snap.side_effect = exception.CinderException snapshot = tests_utils.create_snapshot(self.context, volume.id) volume2 = tests_utils.create_volume( self.context, group_id=group.id, snapshot_id=snapshot.id, status='available', host=group.host, volume_type_id=fake.VOLUME_TYPE_ID) self.assertRaises(exception.CinderException, self.volume.create_volume, self.context, volume2) self.assertIsNone(volume2.consistencygroup_id) # create cloned volume with group_id but driver exception mock_create_cloned_vol.side_effect = exception.CinderException volume3 = tests_utils.create_volume( self.context, group_id=group.id, source_volid=volume.id, status='available', host=group.host, volume_type_id=fake.VOLUME_TYPE_ID) self.assertRaises(exception.CinderException, self.volume.create_volume, self.context, volume3) self.assertIsNone(volume3.consistencygroup_id)
def test_create_group_from_src_frozen(self): service = utils.create_service(self.ctxt, {'frozen': True}) group = utils.create_group(self.ctxt, host=service.host, group_type_id='gt') group_api = cinder.group.api.API() self.assertRaises(exception.InvalidInput, group_api.create_from_src, self.ctxt, 'group', 'desc', group_snapshot_id=None, source_group_id=group.id)
def test__validate_add_volumes(self, mock_volume_get, mock_group): grp = utils.create_group(self.ctxt, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID], availability_zone='nova', host=None, name="name", description="description", status=fields.GroupStatus.CREATING) mock_group.return_value = grp fake_volume_obj = fake_volume.fake_volume_obj(self.ctxt) mock_volume_get.return_value = fake_volume_obj self.assertRaises(exception.InvalidVolume, self.group_api._validate_add_volumes, self.ctxt, [], ['123456789'], grp)
def test_reset_group_snapshot_status_invalid_status(self): group = utils.create_group( self.context, group_type_id=fake.GROUP_TYPE_ID, volume_type_ids=[fake.VOLUME_TYPE_ID] ) group_snapshot = utils.create_group_snapshot( self.context, group_id=group.id, status=fields.GroupSnapshotStatus.CREATING ) req = fakes.HTTPRequest.blank( "/v3/%s/group_snapshots/%s/action" % (fake.PROJECT_ID, group_snapshot.id), version="3.19" ) body = {"reset_status": {"status": "invalid_test_status"}} self.assertRaises(webob.exc.HTTPBadRequest, self.controller.reset_status, req, group_snapshot.id, body)