def test_delete_cgsnapshot_available_used_as_source(self): consistencygroup = utils.create_consistencygroup(self.context) volume_id = utils.create_volume( self.context, consistencygroup_id=consistencygroup.id)['id'] cgsnapshot = utils.create_cgsnapshot( self.context, consistencygroup_id=consistencygroup.id, status='available') cg2 = utils.create_consistencygroup( self.context, status='creating', cgsnapshot_id=cgsnapshot.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.CGSnapshot.get_by_id(self.context, cgsnapshot.id) self.assertEqual(400, res.status_int) self.assertEqual('available', cgsnapshot.status) cgsnapshot.destroy() db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy() cg2.destroy()
def setUp(self): super(VolumeRpcAPITestCase, self).setUp() self.context = context.get_admin_context() vol = {} vol["host"] = "fake_host" vol["availability_zone"] = CONF.storage_availability_zone vol["status"] = "available" vol["attach_status"] = "detached" vol["metadata"] = {"test_key": "test_val"} volume = db.volume_create(self.context, vol) snpshot = { "id": 1, "volume_id": "fake_id", "status": "creating", "progress": "0%", "volume_size": 0, "display_name": "fake_name", "display_description": "fake_description", } snapshot = db.snapshot_create(self.context, snpshot) source_group = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type="type1,type2", host="fakehost@fakedrv#fakepool", ) cgsnapshot = tests_utils.create_cgsnapshot(self.context, consistencygroup_id=source_group["id"]) group = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type="type1,type2", host="fakehost@fakedrv#fakepool", cgsnapshot_id=cgsnapshot["id"], ) group2 = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type="type1,type2", host="fakehost@fakedrv#fakepool", source_cgid=source_group["id"], ) group = objects.ConsistencyGroup.get_by_id(self.context, group.id) group2 = objects.ConsistencyGroup.get_by_id(self.context, group2.id) self.fake_volume = jsonutils.to_primitive(volume) self.fake_volume_obj = fake_volume.fake_volume_obj(self.context, **vol) self.fake_volume_metadata = volume["volume_metadata"] self.fake_snapshot = jsonutils.to_primitive(snapshot) self.fake_snapshot_obj = fake_snapshot.fake_snapshot_obj(self.context, **snpshot) self.fake_reservations = ["RESERVATION"] self.fake_cg = group self.fake_cg2 = group2 self.fake_src_cg = jsonutils.to_primitive(source_group) self.fake_cgsnap = jsonutils.to_primitive(cgsnapshot)
def setUp(self): super(VolumeRpcAPITestCase, self).setUp() self.context = context.get_admin_context() vol = {} vol['host'] = 'fake_host' vol['availability_zone'] = CONF.storage_availability_zone vol['status'] = "available" vol['attach_status'] = "detached" vol['metadata'] = {"test_key": "test_val"} volume = db.volume_create(self.context, vol) snpshot = { 'id': 1, 'volume_id': 'fake_id', 'status': "creating", 'progress': '0%', 'volume_size': 0, 'display_name': 'fake_name', 'display_description': 'fake_description'} snapshot = db.snapshot_create(self.context, snpshot) source_group = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2', host='fakehost@fakedrv#fakepool') cgsnapshot = tests_utils.create_cgsnapshot( self.context, consistencygroup_id=source_group['id']) group = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2', host='fakehost@fakedrv#fakepool', cgsnapshot_id=cgsnapshot['id']) group2 = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2', host='fakehost@fakedrv#fakepool', source_cgid=source_group['id']) group = objects.ConsistencyGroup.get_by_id(self.context, group.id) group2 = objects.ConsistencyGroup.get_by_id(self.context, group2.id) self.fake_volume = jsonutils.to_primitive(volume) self.fake_volume_metadata = volume["volume_metadata"] self.fake_snapshot = jsonutils.to_primitive(snapshot) self.fake_snapshot_obj = fake_snapshot.fake_snapshot_obj(self.context, **snpshot) self.fake_reservations = ["RESERVATION"] self.fake_cg = group self.fake_cg2 = group2 self.fake_src_cg = jsonutils.to_primitive(source_group) self.fake_cgsnap = jsonutils.to_primitive(cgsnapshot)
def test_create_consistencygroup_from_src_cgsnapshot_notfound(self): ctxt = context.RequestContext('fake', 'fake', auth_token=True) consistencygroup_id = utils.create_consistencygroup( ctxt)['id'] volume_id = utils.create_volume( ctxt, consistencygroup_id=consistencygroup_id)['id'] test_cg_name = 'test cg' body = {"consistencygroup-from-src": {"name": test_cg_name, "description": "Consistency Group 1", "cgsnapshot_id": "fake_cgsnap"}} req = webob.Request.blank('/v2/fake/consistencygroups/create_from_src') req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(404, res.status_int) self.assertEqual(404, res_dict['itemNotFound']['code']) self.assertIsNotNone(res_dict['itemNotFound']['message']) db.volume_destroy(ctxt.elevated(), volume_id) db.consistencygroup_destroy(ctxt.elevated(), consistencygroup_id)
def test_create_consistencygroup_from_src_cg_create_volume_failed(self, mock_create): source_cg = utils.create_consistencygroup(self.ctxt) volume_id = utils.create_volume(self.ctxt, consistencygroup_id=source_cg.id)["id"] test_cg_name = "test cg" body = { "consistencygroup-from-src": { "name": test_cg_name, "description": "Consistency Group 1", "source_cgid": source_cg.id, } } req = webob.Request.blank("/v2/fake/consistencygroups/create_from_src") req.method = "POST" req.headers["Content-Type"] = "application/json" req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(400, res.status_int) self.assertEqual(400, res_dict["badRequest"]["code"]) self.assertIsNotNone(res_dict["badRequest"]["message"]) db.volume_destroy(self.ctxt.elevated(), volume_id) source_cg.destroy()
def test_create_cgsnapshot_with_bootable_volumes(self, mock_create_cgsnap): """Test cgsnapshot can be created and deleted.""" group = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2') volume = tests_utils.create_volume( self.context, consistencygroup_id=group.id, **self.volume_params) 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, consistencygroup_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] cgsnapshot_returns = self._create_cgsnapshot(group.id, volume_ids) cgsnapshot = cgsnapshot_returns[0] self.volume.create_cgsnapshot(self.context, cgsnapshot) self.assertEqual(cgsnapshot.id, objects.CGSnapshot.get_by_id( context.get_admin_context(), cgsnapshot.id).id) self.assertTrue(mock_create_cgsnap.called)
def test_create_consistencygroup_from_src_cgsnapshot_empty(self): ctxt = context.RequestContext('fake', 'fake', auth_token=True) consistencygroup_id = utils.create_consistencygroup( ctxt)['id'] volume_id = utils.create_volume( ctxt, consistencygroup_id=consistencygroup_id)['id'] cgsnapshot_id = utils.create_cgsnapshot( ctxt, consistencygroup_id=consistencygroup_id)['id'] test_cg_name = 'test cg' body = {"consistencygroup-from-src": {"name": test_cg_name, "description": "Consistency Group 1", "cgsnapshot_id": cgsnapshot_id}} req = webob.Request.blank('/v2/fake/consistencygroups/create_from_src') req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(400, res.status_int) self.assertEqual(400, res_dict['badRequest']['code']) msg = _("Invalid ConsistencyGroup: Cgsnahost is empty. No " "consistency group will be created.") self.assertIn(msg, res_dict['badRequest']['message']) db.cgsnapshot_destroy(ctxt.elevated(), cgsnapshot_id) db.volume_destroy(ctxt.elevated(), volume_id) db.consistencygroup_destroy(ctxt.elevated(), consistencygroup_id)
def test_create_cgsnapshot_json(self, mock_validate): consistencygroup = utils.create_consistencygroup(self.context) utils.create_volume( self.context, consistencygroup_id=consistencygroup.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(202, res.status_int) self.assertIn('id', res_dict['cgsnapshot']) self.assertTrue(mock_validate.called) consistencygroup.destroy() cgsnapshot = objects.CGSnapshot.get_by_id( context.get_admin_context(), res_dict['cgsnapshot']['id']) cgsnapshot.destroy()
def test_create_cgsnapshot_when_volume_in_error_status(self, mock_validate): consistencygroup = utils.create_consistencygroup(self.context) utils.create_volume( self.context, status='error', consistencygroup_id=consistencygroup.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(400, res.status_int) self.assertEqual(400, res_dict['badRequest']['code']) self.assertEqual( "Invalid volume: The snapshot cannot be created when the volume " "is in error status.", res_dict['badRequest']['message'] ) self.assertTrue(mock_validate.called) consistencygroup.destroy()
def test_list_cgsnapshots_detail_json(self): consistencygroup = utils.create_consistencygroup(self.context) volume_id = utils.create_volume(self.context, consistencygroup_id=consistencygroup.id)["id"] cgsnapshot_id1 = self._create_cgsnapshot(consistencygroup_id=consistencygroup.id) cgsnapshot_id2 = self._create_cgsnapshot(consistencygroup_id=consistencygroup.id) cgsnapshot_id3 = self._create_cgsnapshot(consistencygroup_id=consistencygroup.id) req = webob.Request.blank("/v2/fake/cgsnapshots/detail") req.method = "GET" req.headers["Content-Type"] = "application/json" req.headers["Accept"] = "application/json" res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(200, res.status_int) self.assertEqual("this is a test cgsnapshot", res_dict["cgsnapshots"][0]["description"]) self.assertEqual("test_cgsnapshot", res_dict["cgsnapshots"][0]["name"]) self.assertEqual(res_dict["cgsnapshots"][0]["id"], cgsnapshot_id1) self.assertEqual("creating", res_dict["cgsnapshots"][0]["status"]) self.assertEqual("this is a test cgsnapshot", res_dict["cgsnapshots"][1]["description"]) self.assertEqual("test_cgsnapshot", res_dict["cgsnapshots"][1]["name"]) self.assertEqual(res_dict["cgsnapshots"][1]["id"], cgsnapshot_id2) self.assertEqual("creating", res_dict["cgsnapshots"][1]["status"]) self.assertEqual("this is a test cgsnapshot", res_dict["cgsnapshots"][2]["description"]) self.assertEqual(res_dict["cgsnapshots"][2]["name"], "test_cgsnapshot") self.assertEqual(res_dict["cgsnapshots"][2]["id"], cgsnapshot_id3) self.assertEqual("creating", res_dict["cgsnapshots"][2]["status"]) db.cgsnapshot_destroy(context.get_admin_context(), cgsnapshot_id3) db.cgsnapshot_destroy(context.get_admin_context(), cgsnapshot_id2) db.cgsnapshot_destroy(context.get_admin_context(), cgsnapshot_id1) db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_list_cgsnapshots_xml(self): consistencygroup = utils.create_consistencygroup(self.context) volume_id = utils.create_volume(self.context, consistencygroup_id=consistencygroup.id)["id"] cgsnapshot_id1 = self._create_cgsnapshot(consistencygroup_id=consistencygroup.id) cgsnapshot_id2 = self._create_cgsnapshot(consistencygroup_id=consistencygroup.id) cgsnapshot_id3 = self._create_cgsnapshot(consistencygroup_id=consistencygroup.id) req = webob.Request.blank("/v2/fake/cgsnapshots") req.method = "GET" req.headers["Content-Type"] = "application/xml" req.headers["Accept"] = "application/xml" res = req.get_response(fakes.wsgi_app()) self.assertEqual(200, res.status_int) dom = minidom.parseString(res.body) cgsnapshot_list = dom.getElementsByTagName("cgsnapshot") self.assertEqual(cgsnapshot_list.item(0).getAttribute("id"), cgsnapshot_id1) self.assertEqual(cgsnapshot_list.item(1).getAttribute("id"), cgsnapshot_id2) self.assertEqual(cgsnapshot_list.item(2).getAttribute("id"), cgsnapshot_id3) db.cgsnapshot_destroy(context.get_admin_context(), cgsnapshot_id3) db.cgsnapshot_destroy(context.get_admin_context(), cgsnapshot_id2) db.cgsnapshot_destroy(context.get_admin_context(), cgsnapshot_id1) db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_delete_consistencygroup_wrong_host(self, *_mock_create_cg): """Test consistencygroup cannot be deleted. Test consistencygroup cannot be deleted when volumes in the group are not local to the volume node. """ group = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2') volume = tests_utils.create_volume( self.context, consistencygroup_id=group.id, host='host1@backend1#pool1', status='creating', size=1) self.volume.host = 'host1@backend2' self.volume.create_volume(self.context, volume.id, volume=volume) self.assertRaises(exception.InvalidVolume, self.volume.delete_consistencygroup, self.context, group) cg = objects.ConsistencyGroup.get_by_id(self.context, group.id) # Group is not deleted self.assertEqual(fields.ConsistencyGroupStatus.AVAILABLE, cg.status)
def test_create_cgsnapshot_from_empty_consistencygroup(self): consistencygroup = utils.create_consistencygroup(self.context) 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(400, res.status_int) self.assertEqual(400, res_dict['badRequest']['code']) expected = ("Invalid ConsistencyGroup: Source CG cannot be empty or " "in 'creating' or 'updating' state. No cgsnapshot will be " "created.") self.assertEqual(expected, res_dict['badRequest']['message']) # If failed to create cgsnapshot, its DB object should not be created self.assertListEqual( [], list(objects.CGSnapshotList.get_all(self.context))) consistencygroup.destroy()
def test_create_consistencygroup_from_src_cgsnapshot_notfound(self): consistencygroup = utils.create_consistencygroup(self.ctxt) volume_id = utils.create_volume(self.ctxt, consistencygroup_id=consistencygroup.id)["id"] test_cg_name = "test cg" body = { "consistencygroup-from-src": { "name": test_cg_name, "description": "Consistency Group 1", "cgsnapshot_id": "fake_cgsnap", } } req = webob.Request.blank("/v2/fake/consistencygroups/create_from_src") req.method = "POST" req.headers["Content-Type"] = "application/json" req.body = jsonutils.dump_as_bytes(body) res = req.get_response(fakes.wsgi_app()) res_dict = jsonutils.loads(res.body) self.assertEqual(404, res.status_int) self.assertEqual(404, res_dict["itemNotFound"]["code"]) self.assertIsNotNone(res_dict["itemNotFound"]["message"]) db.volume_destroy(self.ctxt.elevated(), volume_id) consistencygroup.destroy()
def test_create_consistencygroup_from_src_cg(self): self.mock_object(volume_api.API, "create", stubs.stub_volume_create) source_cg = utils.create_consistencygroup(self.ctxt) volume_id = utils.create_volume( self.ctxt, consistencygroup_id=source_cg.id)['id'] test_cg_name = 'test cg' body = {"consistencygroup-from-src": {"name": test_cg_name, "description": "Consistency Group 1", "source_cgid": source_cg.id}} req = webob.Request.blank('/v2/fake/consistencygroups/create_from_src') req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(202, res.status_int) self.assertIn('id', res_dict['consistencygroup']) self.assertEqual(test_cg_name, res_dict['consistencygroup']['name']) cg = objects.ConsistencyGroup.get_by_id( self.ctxt, res_dict['consistencygroup']['id']) cg.destroy db.volume_destroy(self.ctxt.elevated(), volume_id) source_cg.destroy()
def test_list_cgsnapshots_xml(self): consistencygroup = utils.create_consistencygroup(self.context) volume_id = utils.create_volume(self.context, consistencygroup_id= consistencygroup.id)['id'] cgsnapshot1 = utils.create_cgsnapshot( self.context, consistencygroup_id=consistencygroup.id) cgsnapshot2 = utils.create_cgsnapshot( self.context, consistencygroup_id=consistencygroup.id) cgsnapshot3 = utils.create_cgsnapshot( self.context, consistencygroup_id=consistencygroup.id) req = webob.Request.blank('/v2/fake/cgsnapshots') req.method = 'GET' req.headers['Content-Type'] = 'application/xml' req.headers['Accept'] = 'application/xml' res = req.get_response(fakes.wsgi_app()) self.assertEqual(200, res.status_int) dom = minidom.parseString(res.body) cgsnapshot_list = dom.getElementsByTagName('cgsnapshot') self.assertEqual(cgsnapshot1.id, cgsnapshot_list.item(0).getAttribute('id')) self.assertEqual(cgsnapshot2.id, cgsnapshot_list.item(1).getAttribute('id')) self.assertEqual(cgsnapshot3.id, cgsnapshot_list.item(2).getAttribute('id')) cgsnapshot3.destroy() cgsnapshot2.destroy() cgsnapshot1.destroy() db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_delete_consistencygroup_correct_host(self, mock_del_cg, _mock_create_cg): """Test consistencygroup can be deleted. Test consistencygroup can be deleted when volumes are on the correct volume node. """ group = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2') volume = tests_utils.create_volume( self.context, consistencygroup_id=group.id, host='host1@backend1#pool1', status='creating', size=1) self.volume.host = 'host1@backend1' self.volume.create_volume(self.context, volume.id, volume=volume) self.volume.delete_consistencygroup(self.context, group) cg = objects.ConsistencyGroup.get_by_id( context.get_admin_context(read_deleted='yes'), group.id) self.assertEqual(fields.ConsistencyGroupStatus.DELETED, cg.status) self.assertRaises(exception.NotFound, objects.ConsistencyGroup.get_by_id, self.context, group.id) self.assertTrue(mock_del_cg.called)
def test_create_consistencygroup_from_src_create_volume_failed(self, mock_create): ctxt = context.RequestContext("fake", "fake", auth_token=True) consistencygroup_id = utils.create_consistencygroup(ctxt)["id"] volume_id = utils.create_volume(ctxt, consistencygroup_id=consistencygroup_id)["id"] cgsnapshot_id = utils.create_cgsnapshot(ctxt, consistencygroup_id=consistencygroup_id)["id"] snapshot_id = utils.create_snapshot(ctxt, volume_id, cgsnapshot_id=cgsnapshot_id, status="available")["id"] test_cg_name = "test cg" body = { "consistencygroup-from-src": { "name": test_cg_name, "description": "Consistency Group 1", "cgsnapshot_id": cgsnapshot_id, } } req = webob.Request.blank("/v2/fake/consistencygroups/create_from_src") req.method = "POST" req.headers["Content-Type"] = "application/json" req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(400, res.status_int) self.assertEqual(400, res_dict["badRequest"]["code"]) msg = _("Create volume failed.") self.assertEqual(msg, res_dict["badRequest"]["message"]) db.snapshot_destroy(ctxt.elevated(), snapshot_id) db.cgsnapshot_destroy(ctxt.elevated(), cgsnapshot_id) db.volume_destroy(ctxt.elevated(), volume_id) db.consistencygroup_destroy(ctxt.elevated(), consistencygroup_id)
def test_create_cgsnapshot_from_empty_consistencygroup( self, mock_cgsnapshot_create): consistencygroup = utils.create_consistencygroup(self.context) body = {"cgsnapshot": {"name": "cg1", "description": "CG Snapshot 1", "consistencygroup_id": consistencygroup.id}} req = webob.Request.blank('/v2/fake/cgsnapshots') req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) res = req.get_response(fakes.wsgi_app()) res_dict = jsonutils.loads(res.body) self.assertEqual(400, res.status_int) self.assertEqual(400, res_dict['badRequest']['code']) self.assertEqual('Invalid ConsistencyGroup: Consistency group is ' 'empty. No cgsnapshot will be created.', res_dict['badRequest']['message']) # If failed to create cgsnapshot, its DB object should not be created self.assertFalse(mock_cgsnapshot_create.called) consistencygroup.destroy()
def test_create_consistencygroup_from_src_no_host(self): consistencygroup = utils.create_consistencygroup(self.ctxt, host=None) volume_id = utils.create_volume(self.ctxt, consistencygroup_id=consistencygroup.id)["id"] cgsnapshot = utils.create_cgsnapshot(self.ctxt, consistencygroup_id=consistencygroup.id) snapshot = utils.create_snapshot(self.ctxt, volume_id, cgsnapshot_id=cgsnapshot.id, status="available") test_cg_name = "test cg" body = { "consistencygroup-from-src": { "name": test_cg_name, "description": "Consistency Group 1", "cgsnapshot_id": cgsnapshot.id, } } req = webob.Request.blank("/v2/fake/consistencygroups/create_from_src") req.method = "POST" req.headers["Content-Type"] = "application/json" req.body = jsonutils.dump_as_bytes(body) res = req.get_response(fakes.wsgi_app()) res_dict = jsonutils.loads(res.body) self.assertEqual(400, res.status_int) self.assertEqual(400, res_dict["badRequest"]["code"]) msg = _("Invalid ConsistencyGroup: No host to create consistency " "group") self.assertIn(msg, res_dict["badRequest"]["message"]) snapshot.destroy() db.volume_destroy(self.ctxt.elevated(), volume_id) consistencygroup.destroy() cgsnapshot.destroy()
def test_create_consistencygroup_from_src_cgsnapshot_empty(self): consistencygroup = utils.create_consistencygroup(self.ctxt) volume_id = utils.create_volume( self.ctxt, consistencygroup_id=consistencygroup.id)['id'] cgsnapshot = utils.create_cgsnapshot( self.ctxt, consistencygroup_id=consistencygroup.id) test_cg_name = 'test cg' body = {"consistencygroup-from-src": {"name": test_cg_name, "description": "Consistency Group 1", "cgsnapshot_id": cgsnapshot.id}} req = webob.Request.blank('/v2/fake/consistencygroups/create_from_src') req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(400, res.status_int) self.assertEqual(400, res_dict['badRequest']['code']) self.assertIsNotNone(res_dict['badRequest']['message']) db.volume_destroy(self.ctxt.elevated(), volume_id) consistencygroup.destroy() cgsnapshot.destroy()
def test_show_cgsnapshot(self): consistencygroup = utils.create_consistencygroup(self.context) volume_id = utils.create_volume(self.context, consistencygroup_id= consistencygroup.id)['id'] cgsnapshot_id = self._create_cgsnapshot( consistencygroup_id=consistencygroup.id) req = webob.Request.blank('/v2/fake/cgsnapshots/%s' % cgsnapshot_id) req.method = 'GET' req.headers['Content-Type'] = 'application/json' res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(200, res.status_int) self.assertEqual('this is a test cgsnapshot', res_dict['cgsnapshot']['description']) self.assertEqual('test_cgsnapshot', res_dict['cgsnapshot']['name']) self.assertEqual('creating', res_dict['cgsnapshot']['status']) db.cgsnapshot_destroy(context.get_admin_context(), cgsnapshot_id) db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_delete_cgsnapshot_available(self): consistencygroup_id = utils.create_consistencygroup(self.context)['id'] volume_id = utils.create_volume( self.context, consistencygroup_id=consistencygroup_id)['id'] cgsnapshot_id = self._create_cgsnapshot( consistencygroup_id=consistencygroup_id, status='available') 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()) self.assertEqual(res.status_int, 202) self.assertEqual(self._get_cgsnapshot_attrib(cgsnapshot_id, 'status'), 'deleting') db.cgsnapshot_destroy(context.get_admin_context(), cgsnapshot_id) db.volume_destroy(context.get_admin_context(), volume_id) db.consistencygroup_destroy(context.get_admin_context(), consistencygroup_id)
def test_create_consistencygroup_from_src(self, mock_validate): self.stubs.Set(volume_api.API, "create", stubs.stub_volume_create) consistencygroup = utils.create_consistencygroup(self.ctxt) volume_id = utils.create_volume(self.ctxt, consistencygroup_id=consistencygroup.id)["id"] cgsnapshot = utils.create_cgsnapshot(self.ctxt, consistencygroup_id=consistencygroup.id) snapshot = utils.create_snapshot(self.ctxt, volume_id, cgsnapshot_id=cgsnapshot.id, status="available") test_cg_name = "test cg" body = { "consistencygroup-from-src": { "name": test_cg_name, "description": "Consistency Group 1", "cgsnapshot_id": cgsnapshot.id, } } req = webob.Request.blank("/v2/fake/consistencygroups/create_from_src") req.method = "POST" req.headers["Content-Type"] = "application/json" req.body = jsonutils.dump_as_bytes(body) res = req.get_response(fakes.wsgi_app()) res_dict = jsonutils.loads(res.body) self.assertEqual(202, res.status_int) self.assertIn("id", res_dict["consistencygroup"]) self.assertEqual(test_cg_name, res_dict["consistencygroup"]["name"]) self.assertTrue(mock_validate.called) cg_ref = objects.ConsistencyGroup.get_by_id(self.ctxt.elevated(), res_dict["consistencygroup"]["id"]) cg_ref.destroy() snapshot.destroy() db.volume_destroy(self.ctxt.elevated(), volume_id) consistencygroup.destroy() cgsnapshot.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_create_consistencygroup_from_src_cg(self): self.mock_object(volume_api.API, "create", stubs.stub_volume_create) source_cg = utils.create_consistencygroup(self.ctxt) volume_id = utils.create_volume(self.ctxt, consistencygroup_id=source_cg.id)["id"] test_cg_name = "test cg" body = { "consistencygroup-from-src": { "name": test_cg_name, "description": "Consistency Group 1", "source_cgid": source_cg.id, } } req = webob.Request.blank("/v2/fake/consistencygroups/create_from_src") req.method = "POST" req.headers["Content-Type"] = "application/json" req.body = jsonutils.dump_as_bytes(body) res = req.get_response(fakes.wsgi_app()) res_dict = jsonutils.loads(res.body) self.assertEqual(202, res.status_int) self.assertIn("id", res_dict["consistencygroup"]) self.assertEqual(test_cg_name, res_dict["consistencygroup"]["name"]) cg = objects.ConsistencyGroup.get_by_id(self.ctxt, res_dict["consistencygroup"]["id"]) cg.destroy db.volume_destroy(self.ctxt.elevated(), volume_id) source_cg.destroy()
def test_delete_cgsnapshot_with_Invalidcgsnapshot(self): consistencygroup = utils.create_consistencygroup(self.context) volume_id = utils.create_volume( self.context, consistencygroup_id=consistencygroup.id)['id'] cgsnapshot = utils.create_cgsnapshot( self.context, consistencygroup_id=consistencygroup.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(400, res.status_int) self.assertEqual(400, res_dict['badRequest']['code']) expected = ('Invalid CgSnapshot: CgSnapshot status must be available ' 'or error, and no CG can be currently using it as source ' 'for its creation.') self.assertEqual(expected, res_dict['badRequest']['message']) cgsnapshot.destroy() db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_create_consistencygroup_from_src_both_snap_cg(self): self.stubs.Set(volume_api.API, "create", stubs.stub_volume_create) consistencygroup = utils.create_consistencygroup(self.ctxt) volume_id = utils.create_volume(self.ctxt, consistencygroup_id=consistencygroup.id)["id"] cgsnapshot_id = utils.create_cgsnapshot(self.ctxt, consistencygroup_id=consistencygroup.id)["id"] snapshot = utils.create_snapshot(self.ctxt, volume_id, cgsnapshot_id=cgsnapshot_id, status="available") test_cg_name = "test cg" body = { "consistencygroup-from-src": { "name": test_cg_name, "description": "Consistency Group 1", "cgsnapshot_id": cgsnapshot_id, "source_cgid": consistencygroup.id, } } req = webob.Request.blank("/v2/fake/consistencygroups/create_from_src") req.method = "POST" req.headers["Content-Type"] = "application/json" req.body = jsonutils.dump_as_bytes(body) res = req.get_response(fakes.wsgi_app()) res_dict = jsonutils.loads(res.body) self.assertEqual(400, res.status_int) self.assertEqual(400, res_dict["badRequest"]["code"]) self.assertIsNotNone(res_dict["badRequest"]["message"]) snapshot.destroy() db.cgsnapshot_destroy(self.ctxt.elevated(), cgsnapshot_id) db.volume_destroy(self.ctxt.elevated(), volume_id) consistencygroup.destroy()
def test_delete_cgsnapshot_with_Invalidcgsnapshot(self): consistencygroup = utils.create_consistencygroup(self.context) volume_id = utils.create_volume( self.context, consistencygroup_id=consistencygroup.id)['id'] cgsnapshot = utils.create_cgsnapshot( self.context, consistencygroup_id=consistencygroup.id, status='invalid') 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()) res_dict = jsonutils.loads(res.body) self.assertEqual(400, res.status_int) self.assertEqual(400, res_dict['badRequest']['code']) self.assertEqual('Invalid cgsnapshot', res_dict['badRequest']['message']) cgsnapshot.destroy() db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_create_cgsnapshot_json(self, mock_validate): cgsnapshot_id = "1" consistencygroup = utils.create_consistencygroup(self.context) utils.create_volume( self.context, consistencygroup_id=consistencygroup.id) body = {"cgsnapshot": {"name": "cg1", "description": "CG Snapshot 1", "consistencygroup_id": consistencygroup.id}} req = webob.Request.blank('/v2/fake/cgsnapshots') req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(202, res.status_int) self.assertIn('id', res_dict['cgsnapshot']) self.assertTrue(mock_validate.called) db.cgsnapshot_destroy(context.get_admin_context(), cgsnapshot_id) consistencygroup.destroy()
def test_create_consistencygroup_from_src_cgsnapshot(self): self.stubs.Set(volume_api.API, "create", stubs.stub_volume_create) ctxt = context.RequestContext('fake', 'fake', auth_token=True) consistencygroup_id = utils.create_consistencygroup(ctxt)['id'] volume_id = utils.create_volume( ctxt, consistencygroup_id=consistencygroup_id)['id'] cgsnapshot_id = utils.create_cgsnapshot( ctxt, consistencygroup_id=consistencygroup_id)['id'] snapshot_id = utils.create_snapshot(ctxt, volume_id, cgsnapshot_id=cgsnapshot_id, status='available')['id'] test_cg_name = 'test cg' body = { "consistencygroup-from-src": { "name": test_cg_name, "description": "Consistency Group 1", "cgsnapshot_id": cgsnapshot_id } } req = webob.Request.blank('/v2/fake/consistencygroups/create_from_src') req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(202, res.status_int) self.assertIn('id', res_dict['consistencygroup']) self.assertEqual(test_cg_name, res_dict['consistencygroup']['name']) db.consistencygroup_destroy(ctxt.elevated(), res_dict['consistencygroup']['id']) db.snapshot_destroy(ctxt.elevated(), snapshot_id) db.cgsnapshot_destroy(ctxt.elevated(), cgsnapshot_id) db.volume_destroy(ctxt.elevated(), volume_id) db.consistencygroup_destroy(ctxt.elevated(), consistencygroup_id)
def test_show_cgsnapshot(self): consistencygroup_id = utils.create_consistencygroup(self.context)['id'] volume_id = utils.create_volume( self.context, consistencygroup_id=consistencygroup_id)['id'] cgsnapshot_id = self._create_cgsnapshot( consistencygroup_id=consistencygroup_id) req = webob.Request.blank('/v2/fake/cgsnapshots/%s' % cgsnapshot_id) req.method = 'GET' req.headers['Content-Type'] = 'application/json' res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(res.status_int, 200) self.assertEqual(res_dict['cgsnapshot']['description'], 'this is a test cgsnapshot') self.assertEqual(res_dict['cgsnapshot']['name'], 'test_cgsnapshot') self.assertEqual(res_dict['cgsnapshot']['status'], 'creating') db.cgsnapshot_destroy(context.get_admin_context(), cgsnapshot_id) db.volume_destroy(context.get_admin_context(), volume_id) db.consistencygroup_destroy(context.get_admin_context(), consistencygroup_id)
def test_create_with_cgsnapshot_not_found(self, mock_create_cgsnapshot): consistencygroup = utils.create_consistencygroup(self.context) utils.create_volume( self.context, consistencygroup_id=consistencygroup.id) body = {"cgsnapshot": {"name": "cg1", "description": "CG Snapshot 1", "consistencygroup_id": consistencygroup.id}} req = webob.Request.blank('/v2/fake/cgsnapshots') req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(404, res.status_int) self.assertEqual(404, res_dict['itemNotFound']['code']) self.assertEqual('CgSnapshot invalid_id could not be found.', res_dict['itemNotFound']['message']) consistencygroup.destroy()
def test_delete_cgsnapshot_available(self): consistencygroup = utils.create_consistencygroup(self.context) volume_id = utils.create_volume( self.context, consistencygroup_id=consistencygroup.id)['id'] cgsnapshot = utils.create_cgsnapshot( self.context, consistencygroup_id=consistencygroup.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.CGSnapshot.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_with_invalid_cgsnapshot(self, mock_create_cgsnapshot): consistencygroup = utils.create_consistencygroup(self.context) utils.create_volume( self.context, consistencygroup_id=consistencygroup.id) body = {"cgsnapshot": {"name": "cg1", "description": "CG Snapshot 1", "consistencygroup_id": consistencygroup.id}} req = webob.Request.blank('/v2/%s/cgsnapshots' % fake.PROJECT_ID) req.body = jsonutils.dump_as_bytes(body) req.method = 'POST' 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(400, res.status_int) self.assertEqual(400, res_dict['badRequest']['code']) self.assertEqual('Invalid CgSnapshot: invalid cgsnapshot', res_dict['badRequest']['message']) consistencygroup.destroy()
def test_list_cgsnapshots_json(self): consistencygroup = utils.create_consistencygroup(self.context) volume_id = utils.create_volume(self.context, consistencygroup_id= consistencygroup.id)['id'] cgsnapshot1 = utils.create_cgsnapshot( self.context, consistencygroup_id=consistencygroup.id) cgsnapshot2 = utils.create_cgsnapshot( self.context, consistencygroup_id=consistencygroup.id) cgsnapshot3 = utils.create_cgsnapshot( self.context, consistencygroup_id=consistencygroup.id) req = webob.Request.blank('/v2/%s/cgsnapshots' % fake.PROJECT_ID) req.method = 'GET' 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(200, res.status_int) self.assertEqual(cgsnapshot1.id, res_dict['cgsnapshots'][0]['id']) self.assertEqual('test_cgsnapshot', res_dict['cgsnapshots'][0]['name']) self.assertEqual(cgsnapshot2.id, res_dict['cgsnapshots'][1]['id']) self.assertEqual('test_cgsnapshot', res_dict['cgsnapshots'][1]['name']) self.assertEqual(cgsnapshot3.id, res_dict['cgsnapshots'][2]['id']) self.assertEqual('test_cgsnapshot', res_dict['cgsnapshots'][2]['name']) cgsnapshot3.destroy() cgsnapshot2.destroy() cgsnapshot1.destroy() db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_list_cgsnapshots_xml(self): consistencygroup = utils.create_consistencygroup(self.context) volume_id = utils.create_volume(self.context, consistencygroup_id= consistencygroup.id)['id'] cgsnapshot_id1 = self._create_cgsnapshot(consistencygroup_id= consistencygroup.id) cgsnapshot_id2 = self._create_cgsnapshot(consistencygroup_id= consistencygroup.id) cgsnapshot_id3 = self._create_cgsnapshot(consistencygroup_id= consistencygroup.id) req = webob.Request.blank('/v2/fake/cgsnapshots') req.method = 'GET' req.headers['Content-Type'] = 'application/xml' req.headers['Accept'] = 'application/xml' res = req.get_response(fakes.wsgi_app()) self.assertEqual(200, res.status_int) dom = minidom.parseString(res.body) cgsnapshot_list = dom.getElementsByTagName('cgsnapshot') self.assertEqual(cgsnapshot_id1, cgsnapshot_list.item(0).getAttribute('id')) self.assertEqual(cgsnapshot_id2, cgsnapshot_list.item(1).getAttribute('id')) self.assertEqual(cgsnapshot_id3, cgsnapshot_list.item(2).getAttribute('id')) db.cgsnapshot_destroy(context.get_admin_context(), cgsnapshot_id3) db.cgsnapshot_destroy(context.get_admin_context(), cgsnapshot_id2) db.cgsnapshot_destroy(context.get_admin_context(), cgsnapshot_id1) db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_create_consistencygroup_from_src_no_host(self): ctxt = context.RequestContext('fake', 'fake', auth_token=True) consistencygroup_id = utils.create_consistencygroup(ctxt, host=None)['id'] volume_id = utils.create_volume( ctxt, consistencygroup_id=consistencygroup_id)['id'] cgsnapshot_id = utils.create_cgsnapshot( ctxt, consistencygroup_id=consistencygroup_id)['id'] snapshot_id = utils.create_snapshot(ctxt, volume_id, cgsnapshot_id=cgsnapshot_id, status='available')['id'] test_cg_name = 'test cg' body = { "consistencygroup-from-src": { "name": test_cg_name, "description": "Consistency Group 1", "cgsnapshot_id": cgsnapshot_id } } req = webob.Request.blank('/v2/fake/consistencygroups/create_from_src') req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(400, res.status_int) self.assertEqual(400, res_dict['badRequest']['code']) msg = _('Invalid ConsistencyGroup: No host to create consistency ' 'group') self.assertIn(msg, res_dict['badRequest']['message']) db.snapshot_destroy(ctxt.elevated(), snapshot_id) db.cgsnapshot_destroy(ctxt.elevated(), cgsnapshot_id) db.volume_destroy(ctxt.elevated(), volume_id) db.consistencygroup_destroy(ctxt.elevated(), consistencygroup_id)
def test_create_with_invalid_cgsnapshot(self, mock_create_cgsnapshot): consistencygroup_id = utils.create_consistencygroup(self.context)['id'] utils.create_volume(self.context, consistencygroup_id=consistencygroup_id)['id'] body = { "cgsnapshot": { "name": "cg1", "description": "CG Snapshot 1", "consistencygroup_id": consistencygroup_id } } req = webob.Request.blank('/v2/fake/cgsnapshots') req.body = json.dumps(body) req.method = 'POST' req.headers['Content-Type'] = 'application/json' res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(400, res.status_int) self.assertEqual(400, res_dict['badRequest']['code']) self.assertEqual('Invalid CgSnapshot: invalid cgsnapshot', res_dict['badRequest']['message'])
def test_create_consistencygroup_from_src_source_cg_empty(self): source_cg = utils.create_consistencygroup(self.ctxt) test_cg_name = 'test cg' body = { "consistencygroup-from-src": { "name": test_cg_name, "description": "Consistency Group 1", "source_cgid": source_cg.id } } req = webob.Request.blank('/v2/fake/consistencygroups/create_from_src') req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(400, res.status_int) self.assertEqual(400, res_dict['badRequest']['code']) self.assertIsNotNone(res_dict['badRequest']['message']) source_cg.destroy()
def test_delete_cgsnapshot_available(self): consistencygroup = utils.create_consistencygroup(self.context) volume_id = utils.create_volume( self.context, consistencygroup_id=consistencygroup.id)['id'] cgsnapshot_id = self._create_cgsnapshot( consistencygroup_id=consistencygroup.id, status='available') 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()) self.assertEqual(202, res.status_int) self.assertEqual('deleting', self._get_cgsnapshot_attrib(cgsnapshot_id, 'status')) db.cgsnapshot_destroy(context.get_admin_context(), cgsnapshot_id) db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_create_consistencygroup_from_src_both_snap_cg(self): self.stubs.Set(volume_api.API, "create", stubs.stub_volume_create) consistencygroup = utils.create_consistencygroup(self.ctxt) volume_id = utils.create_volume( self.ctxt, consistencygroup_id=consistencygroup.id)['id'] cgsnapshot_id = utils.create_cgsnapshot( self.ctxt, consistencygroup_id=consistencygroup.id)['id'] snapshot = utils.create_snapshot(self.ctxt, volume_id, cgsnapshot_id=cgsnapshot_id, status='available') test_cg_name = 'test cg' body = { "consistencygroup-from-src": { "name": test_cg_name, "description": "Consistency Group 1", "cgsnapshot_id": cgsnapshot_id, "source_cgid": consistencygroup.id } } req = webob.Request.blank('/v2/fake/consistencygroups/create_from_src') req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(400, res.status_int) self.assertEqual(400, res_dict['badRequest']['code']) self.assertIsNotNone(res_dict['badRequest']['message']) snapshot.destroy() db.cgsnapshot_destroy(self.ctxt.elevated(), cgsnapshot_id) db.volume_destroy(self.ctxt.elevated(), volume_id) consistencygroup.destroy()
def test_delete_consistencygroup_cluster(self, mock_del_cg): """Test consistencygroup can be deleted. Test consistencygroup can be deleted when volumes are on the correct volume node. """ cluster_name = 'cluster@backend1' self.volume.host = 'host2@backend1' self.volume.cluster = cluster_name group = tests_utils.create_consistencygroup( self.context, host=CONF.host + 'fake', cluster_name=cluster_name, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2') volume = tests_utils.create_volume( self.context, consistencygroup_id=group.id, host='host1@backend1#pool1', cluster_name=cluster_name, status='creating', size=1) self.volume.create_volume(self.context, volume) self.volume.delete_consistencygroup(self.context, group) cg = objects.ConsistencyGroup.get_by_id( context.get_admin_context(read_deleted='yes'), group.id) self.assertEqual(fields.ConsistencyGroupStatus.DELETED, cg.status) self.assertRaises(exception.NotFound, objects.ConsistencyGroup.get_by_id, self.context, group.id) self.assertTrue(mock_del_cg.called)
def test_show_cgsnapshot(self): consistencygroup = utils.create_consistencygroup(self.context) volume_id = utils.create_volume( self.context, consistencygroup_id=consistencygroup.id)['id'] cgsnapshot = utils.create_cgsnapshot( self.context, consistencygroup_id=consistencygroup.id) req = webob.Request.blank('/v2/%s/cgsnapshots/%s' % (fake.PROJECT_ID, cgsnapshot.id)) req.method = 'GET' 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.OK, res.status_int) self.assertEqual('this is a test cgsnapshot', res_dict['cgsnapshot']['description']) self.assertEqual('test_cgsnapshot', res_dict['cgsnapshot']['name']) self.assertEqual('creating', res_dict['cgsnapshot']['status']) cgsnapshot.destroy() db.volume_destroy(context.get_admin_context(), volume_id) consistencygroup.destroy()
def test_create_consistencygroup_from_src_cgsnapshot_create_volume_failed( self, mock_create): consistencygroup = utils.create_consistencygroup(self.ctxt) volume_id = utils.create_volume( self.ctxt, consistencygroup_id=consistencygroup.id)['id'] cgsnapshot_id = utils.create_cgsnapshot( self.ctxt, consistencygroup_id=consistencygroup.id)['id'] snapshot_id = utils.create_snapshot(self.ctxt, volume_id, cgsnapshot_id=cgsnapshot_id, status='available')['id'] test_cg_name = 'test cg' body = { "consistencygroup-from-src": { "name": test_cg_name, "description": "Consistency Group 1", "cgsnapshot_id": cgsnapshot_id } } req = webob.Request.blank('/v2/fake/consistencygroups/create_from_src') req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) self.assertEqual(400, res.status_int) self.assertEqual(400, res_dict['badRequest']['code']) msg = _("Create volume failed.") self.assertEqual(msg, res_dict['badRequest']['message']) db.snapshot_destroy(self.ctxt.elevated(), snapshot_id) db.cgsnapshot_destroy(self.ctxt.elevated(), cgsnapshot_id) db.volume_destroy(self.ctxt.elevated(), volume_id) consistencygroup.destroy()
def setUp(self): super(VolumeRPCAPITestCase, self).setUp() self.rpcapi = volume_rpcapi.VolumeAPI self.base_version = '3.0' vol = {} vol['host'] = 'fake_host' vol['availability_zone'] = CONF.storage_availability_zone vol['status'] = "available" vol['attach_status'] = "detached" vol['metadata'] = {"test_key": "test_val"} vol['size'] = 1 volume = db.volume_create(self.context, vol) kwargs = { 'status': fields.SnapshotStatus.CREATING, 'progress': '0%', 'display_name': 'fake_name', 'display_description': 'fake_description' } snapshot = tests_utils.create_snapshot(self.context, vol['id'], **kwargs) source_group = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2', host='fakehost@fakedrv#fakepool') cgsnapshot = tests_utils.create_cgsnapshot( self.context, consistencygroup_id=source_group.id) cg = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2', host='fakehost@fakedrv#fakepool', cgsnapshot_id=cgsnapshot.id) generic_group = tests_utils.create_group( self.context, availability_zone=CONF.storage_availability_zone, group_type_id='group_type1', host='fakehost@fakedrv#fakepool') group_snapshot = tests_utils.create_group_snapshot( self.context, group_id=generic_group.id, group_type_id=fake.GROUP_TYPE_ID) cg = objects.ConsistencyGroup.get_by_id(self.context, cg.id) cgsnapshot = objects.CGSnapshot.get_by_id(self.context, cgsnapshot.id) self.fake_volume = jsonutils.to_primitive(volume) self.fake_volume_obj = fake_volume.fake_volume_obj(self.context, **vol) self.fake_snapshot = snapshot self.fake_reservations = ["RESERVATION"] self.fake_cg = cg self.fake_src_cg = source_group self.fake_cgsnap = cgsnapshot self.fake_backup_obj = fake_backup.fake_backup_obj(self.context) self.fake_group = generic_group self.fake_group_snapshot = group_snapshot self.can_send_version_mock = self.patch( 'oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_create_delete_consistencygroup(self, fake_delete_cg, fake_rollback, fake_commit, fake_reserve): """Test consistencygroup can be created and deleted.""" def fake_driver_create_cg(context, group): """Make sure that the pool is part of the host.""" self.assertIn('host', group) host = group.host pool = volutils.extract_host(host, level='pool') self.assertEqual('fakepool', pool) return {'status': 'available'} self.stubs.Set(self.volume.driver, 'create_consistencygroup', fake_driver_create_cg) group = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2', host='fakehost@fakedrv#fakepool') group = objects.ConsistencyGroup.get_by_id(self.context, group.id) self.assertEqual(0, len(self.notifier.notifications), self.notifier.notifications) self.volume.create_consistencygroup(self.context, group) self.assertEqual(2, len(self.notifier.notifications), self.notifier.notifications) msg = self.notifier.notifications[0] self.assertEqual('consistencygroup.create.start', msg['event_type']) expected = { 'status': fields.ConsistencyGroupStatus.AVAILABLE, 'name': 'test_cg', 'availability_zone': 'nova', 'tenant_id': self.context.project_id, 'created_at': 'DONTCARE', 'user_id': fake.USER_ID, 'consistencygroup_id': group.id } self.assertDictMatch(expected, msg['payload']) msg = self.notifier.notifications[1] self.assertEqual('consistencygroup.create.end', msg['event_type']) self.assertDictMatch(expected, msg['payload']) self.assertEqual( group.id, objects.ConsistencyGroup.get_by_id(context.get_admin_context(), group.id).id) self.volume.delete_consistencygroup(self.context, group) cg = objects.ConsistencyGroup.get_by_id( context.get_admin_context(read_deleted='yes'), group.id) self.assertEqual(fields.ConsistencyGroupStatus.DELETED, cg.status) self.assertEqual(4, len(self.notifier.notifications), self.notifier.notifications) msg = self.notifier.notifications[2] self.assertEqual('consistencygroup.delete.start', msg['event_type']) self.assertDictMatch(expected, msg['payload']) msg = self.notifier.notifications[3] self.assertEqual('consistencygroup.delete.end', msg['event_type']) expected['status'] = fields.ConsistencyGroupStatus.DELETED self.assertDictMatch(expected, msg['payload']) self.assertRaises(exception.NotFound, objects.ConsistencyGroup.get_by_id, self.context, group.id)
def test_create_delete_cgsnapshot(self, mock_del_cgsnap, mock_create_cgsnap, mock_del_cg, _mock_create_cg): """Test cgsnapshot can be created and deleted.""" group = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2') volume = tests_utils.create_volume( self.context, consistencygroup_id=group.id, **self.volume_params) volume_id = volume['id'] self.volume.create_volume(self.context, volume_id) if len(self.notifier.notifications) > 2: self.assertFalse(self.notifier.notifications[2], self.notifier.notifications) self.assertEqual(2, len(self.notifier.notifications), self.notifier.notifications) cgsnapshot_returns = self._create_cgsnapshot(group.id, volume_id) cgsnapshot = cgsnapshot_returns[0] self.volume.create_cgsnapshot(self.context, cgsnapshot) self.assertEqual(cgsnapshot.id, objects.CGSnapshot.get_by_id( context.get_admin_context(), cgsnapshot.id).id) if len(self.notifier.notifications) > 6: self.assertFalse(self.notifier.notifications[6], self.notifier.notifications) msg = self.notifier.notifications[2] self.assertEqual('cgsnapshot.create.start', msg['event_type']) expected = { 'created_at': 'DONTCARE', 'name': None, 'cgsnapshot_id': cgsnapshot.id, 'status': 'creating', 'tenant_id': fake.PROJECT_ID, 'user_id': fake.USER_ID, 'consistencygroup_id': group.id } self.assertDictMatch(expected, msg['payload']) msg = self.notifier.notifications[3] self.assertEqual('snapshot.create.start', msg['event_type']) msg = self.notifier.notifications[4] expected['status'] = 'available' self.assertEqual('cgsnapshot.create.end', msg['event_type']) self.assertDictMatch(expected, msg['payload']) msg = self.notifier.notifications[5] self.assertEqual('snapshot.create.end', msg['event_type']) self.assertEqual(6, len(self.notifier.notifications), self.notifier.notifications) self.volume.delete_cgsnapshot(self.context, cgsnapshot) if len(self.notifier.notifications) > 10: self.assertFalse(self.notifier.notifications[10], self.notifier.notifications) msg = self.notifier.notifications[6] self.assertEqual('cgsnapshot.delete.start', msg['event_type']) expected['status'] = 'available' self.assertDictMatch(expected, msg['payload']) msg = self.notifier.notifications[8] self.assertEqual('cgsnapshot.delete.end', msg['event_type']) expected['status'] = 'deleted' self.assertDictMatch(expected, msg['payload']) self.assertEqual(10, len(self.notifier.notifications), self.notifier.notifications) cgsnap = objects.CGSnapshot.get_by_id( context.get_admin_context(read_deleted='yes'), cgsnapshot.id) self.assertEqual('deleted', cgsnap.status) self.assertRaises(exception.NotFound, objects.CGSnapshot.get_by_id, self.context, cgsnapshot.id) self.volume.delete_consistencygroup(self.context, group) self.assertTrue(mock_create_cgsnap.called) self.assertTrue(mock_del_cgsnap.called) self.assertTrue(mock_del_cg.called)
def test_create_consistencygroup_from_src(self, mock_create_cloned_vol, mock_create_vol_from_snap, mock_create_from_src, mock_delete_cgsnap, mock_create_cgsnap, mock_delete_cg, mock_create_cg): """Test consistencygroup can be created and deleted.""" group = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2', status=fields.ConsistencyGroupStatus.AVAILABLE) volume = tests_utils.create_volume( self.context, consistencygroup_id=group.id, status='available', host=CONF.host, size=1) volume_id = volume['id'] cgsnapshot_returns = self._create_cgsnapshot(group.id, volume_id) cgsnapshot = cgsnapshot_returns[0] snapshot_id = cgsnapshot_returns[1]['id'] # Create CG from source CG snapshot. group2 = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2', cgsnapshot_id=cgsnapshot.id) group2 = objects.ConsistencyGroup.get_by_id(self.context, group2.id) volume2 = tests_utils.create_volume( self.context, consistencygroup_id=group2.id, snapshot_id=snapshot_id, **self.volume_params) self.volume.create_volume(self.context, volume2.id, volume=volume2) self.volume.create_consistencygroup_from_src( self.context, group2, cgsnapshot=cgsnapshot) cg2 = objects.ConsistencyGroup.get_by_id(self.context, group2.id) expected = { 'status': fields.ConsistencyGroupStatus.AVAILABLE, 'name': 'test_cg', 'availability_zone': 'nova', 'tenant_id': self.context.project_id, 'created_at': 'DONTCARE', 'user_id': fake.USER_ID, 'consistencygroup_id': group2.id, } self.assertEqual(fields.ConsistencyGroupStatus.AVAILABLE, cg2.status) self.assertEqual(group2.id, cg2['id']) self.assertEqual(cgsnapshot.id, cg2['cgsnapshot_id']) self.assertIsNone(cg2['source_cgid']) msg = self.notifier.notifications[2] self.assertEqual('consistencygroup.create.start', msg['event_type']) self.assertDictMatch(expected, msg['payload']) msg = self.notifier.notifications[4] self.assertEqual('consistencygroup.create.end', msg['event_type']) self.assertDictMatch(expected, msg['payload']) if len(self.notifier.notifications) > 6: self.assertFalse(self.notifier.notifications[6], self.notifier.notifications) self.assertEqual(6, len(self.notifier.notifications), self.notifier.notifications) self.volume.delete_consistencygroup(self.context, group2) if len(self.notifier.notifications) > 10: self.assertFalse(self.notifier.notifications[10], self.notifier.notifications) self.assertEqual(10, len(self.notifier.notifications), self.notifier.notifications) msg = self.notifier.notifications[6] self.assertEqual('consistencygroup.delete.start', msg['event_type']) expected['status'] = fields.ConsistencyGroupStatus.AVAILABLE self.assertDictMatch(expected, msg['payload']) msg = self.notifier.notifications[8] self.assertEqual('consistencygroup.delete.end', msg['event_type']) expected['status'] = fields.ConsistencyGroupStatus.DELETED self.assertDictMatch(expected, msg['payload']) cg2 = objects.ConsistencyGroup.get_by_id( context.get_admin_context(read_deleted='yes'), group2.id) self.assertEqual(fields.ConsistencyGroupStatus.DELETED, cg2.status) self.assertRaises(exception.NotFound, objects.ConsistencyGroup.get_by_id, self.context, group2.id) # Create CG from source CG. group3 = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2', source_cgid=group.id) volume3 = tests_utils.create_volume( self.context, consistencygroup_id=group3.id, source_volid=volume_id, **self.volume_params) self.volume.create_volume(self.context, volume3.id, volume=volume3) self.volume.create_consistencygroup_from_src( self.context, group3, source_cg=group) cg3 = objects.ConsistencyGroup.get_by_id(self.context, group3.id) self.assertEqual(fields.ConsistencyGroupStatus.AVAILABLE, cg3.status) self.assertEqual(group3.id, cg3.id) self.assertEqual(group.id, cg3.source_cgid) self.assertIsNone(cg3.cgsnapshot_id) self.volume.delete_cgsnapshot(self.context, cgsnapshot) self.volume.delete_consistencygroup(self.context, group)
def test_update_consistencygroup(self, fake_update_cg, fake_create_cg, fake_rollback, fake_commit, fake_reserve): """Test consistencygroup can be updated.""" group = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2') self.volume.create_consistencygroup(self.context, group) volume = tests_utils.create_volume( self.context, consistencygroup_id=group.id, **self.volume_params) volume_id = volume['id'] self.volume.create_volume(self.context, volume_id) volume2 = tests_utils.create_volume( self.context, consistencygroup_id=None, **self.volume_params) volume_id2 = volume2['id'] self.volume.create_volume(self.context, volume_id2) fake_update_cg.return_value = ( {'status': fields.ConsistencyGroupStatus.AVAILABLE}, [{'id': volume_id2, 'status': 'available'}], [{'id': volume_id, 'status': 'available'}]) self.volume.update_consistencygroup(self.context, group, add_volumes=volume_id2, remove_volumes=volume_id) cg = objects.ConsistencyGroup.get_by_id(self.context, group.id) expected = { 'status': fields.ConsistencyGroupStatus.AVAILABLE, 'name': 'test_cg', 'availability_zone': 'nova', 'tenant_id': self.context.project_id, 'created_at': 'DONTCARE', 'user_id': fake.USER_ID, 'consistencygroup_id': group.id } self.assertEqual(fields.ConsistencyGroupStatus.AVAILABLE, cg.status) self.assertEqual(10, len(self.notifier.notifications), self.notifier.notifications) msg = self.notifier.notifications[6] self.assertEqual('consistencygroup.update.start', msg['event_type']) self.assertDictMatch(expected, msg['payload']) msg = self.notifier.notifications[8] self.assertEqual('consistencygroup.update.end', msg['event_type']) self.assertDictMatch(expected, msg['payload']) cgvolumes = db.volume_get_all_by_group(self.context, group.id) cgvol_ids = [cgvol['id'] for cgvol in cgvolumes] # Verify volume is removed. self.assertNotIn(volume_id, cgvol_ids) # Verify volume is added. self.assertIn(volume_id2, cgvol_ids) self.volume_params['status'] = 'wrong-status' volume3 = tests_utils.create_volume( self.context, consistencygroup_id=None, **self.volume_params) 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_consistencygroup, 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 setUp(self): super(VolumeRpcAPITestCase, self).setUp() self.context = context.get_admin_context() vol = {} vol['host'] = 'fake_host' vol['availability_zone'] = CONF.storage_availability_zone vol['status'] = "available" vol['attach_status'] = "detached" vol['metadata'] = {"test_key": "test_val"} vol['size'] = 1 volume = db.volume_create(self.context, vol) kwargs = { 'status': fields.SnapshotStatus.CREATING, 'progress': '0%', 'display_name': 'fake_name', 'display_description': 'fake_description'} snapshot = tests_utils.create_snapshot(self.context, vol['id'], **kwargs) source_group = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2', host='fakehost@fakedrv#fakepool') cgsnapshot = tests_utils.create_cgsnapshot( self.context, consistencygroup_id=source_group.id) cg = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2', host='fakehost@fakedrv#fakepool', cgsnapshot_id=cgsnapshot.id) cg2 = tests_utils.create_consistencygroup( self.context, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2', host='fakehost@fakedrv#fakepool', source_cgid=source_group.id) generic_group = tests_utils.create_group( self.context, availability_zone=CONF.storage_availability_zone, group_type_id='group_type1', host='fakehost@fakedrv#fakepool') group_snapshot = tests_utils.create_group_snapshot( self.context, group_id=generic_group.id, group_type_id='group_type1') cg = objects.ConsistencyGroup.get_by_id(self.context, cg.id) cg2 = objects.ConsistencyGroup.get_by_id(self.context, cg2.id) cgsnapshot = objects.CGSnapshot.get_by_id(self.context, cgsnapshot.id) self.fake_volume = jsonutils.to_primitive(volume) self.fake_volume_obj = fake_volume.fake_volume_obj(self.context, **vol) self.fake_volume_metadata = volume["volume_metadata"] self.fake_snapshot = snapshot self.fake_reservations = ["RESERVATION"] self.fake_cg = cg self.fake_cg2 = cg2 self.fake_src_cg = jsonutils.to_primitive(source_group) self.fake_cgsnap = cgsnapshot self.fake_backup_obj = fake_backup.fake_backup_obj(self.context) self.fake_group = generic_group self.fake_group_snapshot = group_snapshot self.addCleanup(self._cleanup)
def test_create_delete_cgsnapshot(self, host, cluster, mock_del_cgsnap, mock_create_cgsnap, mock_del_cg, _mock_create_cg, mock_notify): """Test cgsnapshot can be created and deleted.""" self.volume.cluster = cluster group = tests_utils.create_consistencygroup( self.context, host=host, cluster_name=cluster, availability_zone=CONF.storage_availability_zone, volume_type='type1,type2') self.volume_params['host'] = host volume = tests_utils.create_volume(self.context, cluster_name=cluster, consistencygroup_id=group.id, **self.volume_params) self.volume.create_volume(self.context, volume) self.assert_notify_called( mock_notify, (['INFO', 'volume.create.start'], ['INFO', 'volume.create.end'])) cgsnapshot_returns = self._create_cgsnapshot(group.id, [volume.id]) cgsnapshot = cgsnapshot_returns[0] self.volume.create_cgsnapshot(self.context, cgsnapshot) self.assertEqual( cgsnapshot.id, objects.CGSnapshot.get_by_id(context.get_admin_context(), cgsnapshot.id).id) self.assert_notify_called( mock_notify, (['INFO', 'volume.create.start'], ['INFO', 'volume.create.end'], [ 'INFO', 'cgsnapshot.create.start' ], ['INFO', 'snapshot.create.start'], [ 'INFO', 'cgsnapshot.create.end' ], ['INFO', 'snapshot.create.end'])) self.volume.delete_cgsnapshot(self.context, cgsnapshot) self.assert_notify_called( mock_notify, (['INFO', 'volume.create.start'], ['INFO', 'volume.create.end'], [ 'INFO', 'cgsnapshot.create.start' ], ['INFO', 'snapshot.create.start'], [ 'INFO', 'cgsnapshot.create.end' ], ['INFO', 'snapshot.create.end'], [ 'INFO', 'cgsnapshot.delete.start' ], ['INFO', 'snapshot.delete.start'], [ 'INFO', 'cgsnapshot.delete.end' ], ['INFO', 'snapshot.delete.end'])) cgsnap = objects.CGSnapshot.get_by_id( context.get_admin_context(read_deleted='yes'), cgsnapshot.id) self.assertEqual('deleted', cgsnap.status) self.assertRaises(exception.NotFound, objects.CGSnapshot.get_by_id, self.context, cgsnapshot.id) self.volume.delete_consistencygroup(self.context, group) self.assertTrue(mock_create_cgsnap.called) self.assertTrue(mock_del_cgsnap.called) self.assertTrue(mock_del_cg.called)