From fb3a51a2b411f05f16a563eadd03eadcf6f17a80 Mon Sep 17 00:00:00 2001 From: Nitin Madhok Date: Mon, 11 Jul 2016 16:26:41 -0400 Subject: [PATCH] Fixes consistency snapshot creation This fixes the bug where creation of consistency snapshot would pass even if the volume is in error state. Also adding unit test to ensure that the creation of consistency snapshot fails when volume is in error status. Closes-Bug: #1592451 Change-Id: I482a7e01f32d72196568348225eb3c77a432a539 Signed-off-by: Nitin Madhok --- .../unit/api/contrib/test_cgsnapshots.py | 33 +++++++++++++++++++ cinder/volume/api.py | 5 +++ 2 files changed, 38 insertions(+) diff --git a/cinder/tests/unit/api/contrib/test_cgsnapshots.py b/cinder/tests/unit/api/contrib/test_cgsnapshots.py index 6d1c98a16..9f30855e8 100644 --- a/cinder/tests/unit/api/contrib/test_cgsnapshots.py +++ b/cinder/tests/unit/api/contrib/test_cgsnapshots.py @@ -214,6 +214,39 @@ class CgsnapshotsAPITestCase(test.TestCase): context.get_admin_context(), res_dict['cgsnapshot']['id']) cgsnapshot.destroy() + @mock.patch( + 'cinder.api.openstack.wsgi.Controller.validate_name_and_description') + 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_create_cgsnapshot_with_no_body(self): # omit body from the request req = webob.Request.blank('/v2/%s/cgsnapshots' % fake.PROJECT_ID) diff --git a/cinder/volume/api.py b/cinder/volume/api.py index 2162ed642..3945238dd 100644 --- a/cinder/volume/api.py +++ b/cinder/volume/api.py @@ -797,6 +797,11 @@ class API(base.Base): snapshot_list = [] for volume in volume_list: self._create_snapshot_in_db_validate(context, volume, force) + if volume['status'] == 'error': + msg = _("The snapshot cannot be created when the volume is " + "in error status.") + LOG.error(msg) + raise exception.InvalidVolume(reason=msg) reservations = self._create_snapshots_in_db_reserve( context, volume_list)