Exemple #1
0
 def delete_cgsnapshot(self, context, cgsnapshot, force=False):
     if cgsnapshot.status not in ["available", "error"]:
         msg = _("Cgsnapshot status must be available or error")
         raise exception.InvalidCgSnapshot(reason=msg)
     cgsnapshot.update({'status': 'deleting'})
     cgsnapshot.save()
     self.volume_rpcapi.delete_cgsnapshot(context.elevated(), cgsnapshot)
Exemple #2
0
 def delete_cgsnapshot(self, context, cgsnapshot, force=False):
     if cgsnapshot['status'] not in ["available", "error"]:
         msg = _("Cgsnapshot status must be available or error")
         raise exception.InvalidCgSnapshot(reason=msg)
     self.db.cgsnapshot_update(context, cgsnapshot['id'],
                               {'status': 'deleting'})
     group = self.db.consistencygroup_get(context,
                                          cgsnapshot['consistencygroup_id'])
     self.volume_rpcapi.delete_cgsnapshot(context.elevated(), cgsnapshot,
                                          group['host'])
Exemple #3
0
    def delete_cgsnapshot(self, context, cgsnapshot, force=False):
        values = {'status': 'deleting'}
        expected = {'status': ('available', 'error')}
        filters = [~db.cg_creating_from_src(cgsnapshot_id=cgsnapshot.id)]
        res = cgsnapshot.conditional_update(values, expected, filters)

        if not res:
            msg = _('CgSnapshot status must be available or error, and no CG '
                    'can be currently using it as source for its creation.')
            raise exception.InvalidCgSnapshot(reason=msg)
        self.volume_rpcapi.delete_cgsnapshot(context.elevated(), cgsnapshot)
Exemple #4
0
    def _extract_cgsnapshot(cgsnapshot):
        """Extracts the cgsnapshot id from the provided cgsnapshot.

        This function validates the input cgsnapshot dict and checks that
        the status of that cgsnapshot is valid for creating a cg from.
        """

        cgsnapshot_id = None
        if cgsnapshot:
            if cgsnapshot['status'] not in CGSNAPSHOT_PROCEED_STATUS:
                msg = _("Originating CGSNAPSHOT status must be one"
                        " of '%s' values")
                msg = msg % (", ".join(CGSNAPSHOT_PROCEED_STATUS))
                raise exception.InvalidCgSnapshot(reason=msg)
            cgsnapshot_id = cgsnapshot['id']
        return cgsnapshot_id
Exemple #5
0
class CgsnapshotsAPITestCase(test.TestCase):
    """Test Case for cgsnapshots API."""
    def setUp(self):
        super(CgsnapshotsAPITestCase, self).setUp()
        self.volume_api = cinder.volume.API()
        self.context = context.get_admin_context()
        self.context.project_id = 'fake'
        self.context.user_id = 'fake'

    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/fake/cgsnapshots/%s' % cgsnapshot.id)
        req.method = 'GET'
        req.headers['Content-Type'] = 'application/json'
        res = req.get_response(fakes.wsgi_app())
        res_dict = jsonutils.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'])

        cgsnapshot.destroy()
        db.volume_destroy(context.get_admin_context(), volume_id)
        consistencygroup.destroy()

    def test_show_cgsnapshot_xml_content_type(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/fake/cgsnapshots/%s' % cgsnapshot.id)
        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)

        cgsnapshots = dom.getElementsByTagName('cgsnapshot')
        name = cgsnapshots.item(0).getAttribute('name')
        self.assertEqual("test_cgsnapshot", name.strip())
        cgsnapshot.destroy()
        db.volume_destroy(context.get_admin_context(), volume_id)
        consistencygroup.destroy()

    def test_show_cgsnapshot_with_cgsnapshot_NotFound(self):
        req = webob.Request.blank('/v2/fake/cgsnapshots/9999')
        req.method = 'GET'
        req.headers['Content-Type'] = 'application/json'
        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.assertEqual('CgSnapshot 9999 could not be found.',
                         res_dict['itemNotFound']['message'])

    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/fake/cgsnapshots')
        req.method = 'GET'
        req.headers['Content-Type'] = 'application/json'
        res = req.get_response(fakes.wsgi_app())
        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']
        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_list_cgsnapshots_detail_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/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 = jsonutils.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(cgsnapshot1.id, res_dict['cgsnapshots'][0]['id'])
        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(cgsnapshot2.id, res_dict['cgsnapshots'][1]['id'])
        self.assertEqual('creating', res_dict['cgsnapshots'][1]['status'])

        self.assertEqual('this is a test cgsnapshot',
                         res_dict['cgsnapshots'][2]['description'])
        self.assertEqual('test_cgsnapshot', res_dict['cgsnapshots'][2]['name'])
        self.assertEqual(cgsnapshot3.id, res_dict['cgsnapshots'][2]['id'])
        self.assertEqual('creating', res_dict['cgsnapshots'][2]['status'])

        cgsnapshot3.destroy()
        cgsnapshot2.destroy()
        cgsnapshot1.destroy()
        db.volume_destroy(context.get_admin_context(), volume_id)
        consistencygroup.destroy()

    def test_list_cgsnapshots_detail_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/detail')
        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_detail = dom.getElementsByTagName('cgsnapshot')

        self.assertEqual('this is a test cgsnapshot',
                         cgsnapshot_detail.item(0).getAttribute('description'))
        self.assertEqual('test_cgsnapshot',
                         cgsnapshot_detail.item(0).getAttribute('name'))
        self.assertEqual(cgsnapshot1.id,
                         cgsnapshot_detail.item(0).getAttribute('id'))
        self.assertEqual('creating',
                         cgsnapshot_detail.item(0).getAttribute('status'))

        self.assertEqual('this is a test cgsnapshot',
                         cgsnapshot_detail.item(1).getAttribute('description'))
        self.assertEqual('test_cgsnapshot',
                         cgsnapshot_detail.item(1).getAttribute('name'))
        self.assertEqual(cgsnapshot2.id,
                         cgsnapshot_detail.item(1).getAttribute('id'))
        self.assertEqual('creating',
                         cgsnapshot_detail.item(1).getAttribute('status'))

        self.assertEqual('this is a test cgsnapshot',
                         cgsnapshot_detail.item(2).getAttribute('description'))
        self.assertEqual('test_cgsnapshot',
                         cgsnapshot_detail.item(2).getAttribute('name'))
        self.assertEqual(cgsnapshot3.id,
                         cgsnapshot_detail.item(2).getAttribute('id'))
        self.assertEqual('creating',
                         cgsnapshot_detail.item(2).getAttribute('status'))

        cgsnapshot3.destroy()
        cgsnapshot2.destroy()
        cgsnapshot1.destroy()
        db.volume_destroy(context.get_admin_context(), volume_id)
        consistencygroup.destroy()

    @mock.patch(
        'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
    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/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(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()

    @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/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 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/fake/cgsnapshots')
        req.body = jsonutils.dump_as_bytes(None)
        req.method = 'POST'
        req.headers['Content-Type'] = 'application/json'
        req.headers['Accept'] = '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(
            "Missing required element 'cgsnapshot' in "
            "request body.", res_dict['badRequest']['message'])

    @mock.patch.object(
        consistencygroupAPI.API,
        'create_cgsnapshot',
        side_effect=exception.InvalidCgSnapshot(reason='invalid cgsnapshot'))
    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/fake/cgsnapshots')
        req.body = jsonutils.dump_as_bytes(body)
        req.method = 'POST'
        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: invalid cgsnapshot',
                         res_dict['badRequest']['message'])
        consistencygroup.destroy()

    @mock.patch.object(
        consistencygroupAPI.API,
        'create_cgsnapshot',
        side_effect=exception.CgSnapshotNotFound(cgsnapshot_id='invalid_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 = 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.assertEqual('CgSnapshot invalid_id could not be found.',
                         res_dict['itemNotFound']['message'])
        consistencygroup.destroy()

    @mock.patch.object(objects.CGSnapshot, 'create')
    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_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/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(202, res.status_int)
        self.assertEqual('deleting', cgsnapshot.status)

        cgsnapshot.destroy()
        db.volume_destroy(context.get_admin_context(), volume_id)
        consistencygroup.destroy()

    def test_delete_cgsnapshot_with_cgsnapshot_NotFound(self):
        req = webob.Request.blank('/v2/fake/cgsnapshots/9999')
        req.method = 'DELETE'
        req.headers['Content-Type'] = 'application/json'
        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.assertEqual('CgSnapshot 9999 could not be found.',
                         res_dict['itemNotFound']['message'])

    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()
Exemple #6
0
class CgsnapshotsAPITestCase(test.TestCase):
    """Test Case for cgsnapshots API."""

    def setUp(self):
        super(CgsnapshotsAPITestCase, self).setUp()
        self.volume_api = cinder.volume.API()
        self.context = context.get_admin_context()
        self.context.project_id = 'fake'
        self.context.user_id = 'fake'

    @staticmethod
    def _create_cgsnapshot(
            name='test_cgsnapshot',
            description='this is a test cgsnapshot',
            consistencygroup_id='1',
            status='creating'):
        """Create a cgsnapshot object."""
        cgsnapshot = {}
        cgsnapshot['user_id'] = 'fake'
        cgsnapshot['project_id'] = 'fake'
        cgsnapshot['consistencygroup_id'] = consistencygroup_id
        cgsnapshot['name'] = name
        cgsnapshot['description'] = description
        cgsnapshot['status'] = status
        return db.cgsnapshot_create(context.get_admin_context(),
                                    cgsnapshot)['id']

    @staticmethod
    def _get_cgsnapshot_attrib(cgsnapshot_id, attrib_name):
        return db.cgsnapshot_get(context.get_admin_context(),
                                 cgsnapshot_id)[attrib_name]

    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_show_cgsnapshot_xml_content_type(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/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 = dom.getElementsByTagName('cgsnapshot')
        name = cgsnapshot.item(0).getAttribute('name')
        self.assertEqual('test_cgsnapshot', name.strip())
        db.cgsnapshot_destroy(context.get_admin_context(),
                              cgsnapshot_id)
        db.volume_destroy(context.get_admin_context(),
                          volume_id)
        consistencygroup.destroy()

    def test_show_cgsnapshot_with_cgsnapshot_NotFound(self):
        req = webob.Request.blank('/v2/fake/cgsnapshots/9999')
        req.method = 'GET'
        req.headers['Content-Type'] = 'application/json'
        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 9999 could not be found.',
                         res_dict['itemNotFound']['message'])

    def test_list_cgsnapshots_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')
        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(cgsnapshot_id1,
                         res_dict['cgsnapshots'][0]['id'])
        self.assertEqual('test_cgsnapshot',
                         res_dict['cgsnapshots'][0]['name'])
        self.assertEqual(cgsnapshot_id2,
                         res_dict['cgsnapshots'][1]['id'])
        self.assertEqual('test_cgsnapshot',
                         res_dict['cgsnapshots'][1]['name'])
        self.assertEqual(cgsnapshot_id3,
                         res_dict['cgsnapshots'][2]['id'])
        self.assertEqual('test_cgsnapshot',
                         res_dict['cgsnapshots'][2]['name'])

        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_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_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(cgsnapshot_id1,
                         res_dict['cgsnapshots'][0]['id'])
        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(cgsnapshot_id2,
                         res_dict['cgsnapshots'][1]['id'])
        self.assertEqual('creating',
                         res_dict['cgsnapshots'][1]['status'])

        self.assertEqual('this is a test cgsnapshot',
                         res_dict['cgsnapshots'][2]['description'])
        self.assertEqual('test_cgsnapshot',
                         res_dict['cgsnapshots'][2]['name'])
        self.assertEqual(cgsnapshot_id3,
                         res_dict['cgsnapshots'][2]['id'])
        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_detail_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/detail')
        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_detail = dom.getElementsByTagName('cgsnapshot')

        self.assertEqual('this is a test cgsnapshot',
                         cgsnapshot_detail.item(0).getAttribute('description'))
        self.assertEqual('test_cgsnapshot',
                         cgsnapshot_detail.item(0).getAttribute('name'))
        self.assertEqual(cgsnapshot_id1,
                         cgsnapshot_detail.item(0).getAttribute('id'))
        self.assertEqual('creating',
                         cgsnapshot_detail.item(0).getAttribute('status'))

        self.assertEqual('this is a test cgsnapshot',
                         cgsnapshot_detail.item(1).getAttribute('description'))
        self.assertEqual('test_cgsnapshot',
                         cgsnapshot_detail.item(1).getAttribute('name'))
        self.assertEqual(cgsnapshot_id2,
                         cgsnapshot_detail.item(1).getAttribute('id'))
        self.assertEqual('creating',
                         cgsnapshot_detail.item(1).getAttribute('status'))

        self.assertEqual('this is a test cgsnapshot',
                         cgsnapshot_detail.item(2).getAttribute('description'))
        self.assertEqual('test_cgsnapshot',
                         cgsnapshot_detail.item(2).getAttribute('name'))
        self.assertEqual(cgsnapshot_id3,
                         cgsnapshot_detail.item(2).getAttribute('id'))
        self.assertEqual('creating',
                         cgsnapshot_detail.item(2).getAttribute('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()

    @mock.patch(
        'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
    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_cgsnapshot_with_no_body(self):
        # omit body from the request
        req = webob.Request.blank('/v2/fake/cgsnapshots')
        req.body = json.dumps(None)
        req.method = 'POST'
        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(400, res.status_int)
        self.assertEqual(400, res_dict['badRequest']['code'])
        self.assertEqual("Missing required element 'cgsnapshot' in "
                         "request body.",
                         res_dict['badRequest']['message'])

    @mock.patch.object(consistencygroupAPI.API, 'create_cgsnapshot',
                       side_effect=exception.InvalidCgSnapshot(
                           reason='invalid cgsnapshot'))
    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/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'])
        consistencygroup.destroy()

    @mock.patch.object(consistencygroupAPI.API, 'create_cgsnapshot',
                       side_effect=exception.CgSnapshotNotFound(
                           cgsnapshot_id='invalid_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_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_delete_cgsnapshot_with_cgsnapshot_NotFound(self):
        req = webob.Request.blank('/v2/fake/cgsnapshots/9999')
        req.method = 'DELETE'
        req.headers['Content-Type'] = 'application/json'
        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 9999 could not be found.',
                         res_dict['itemNotFound']['message'])

    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_id = self._create_cgsnapshot(
            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 = json.loads(res.body)

        self.assertEqual(400, res.status_int)
        self.assertEqual(400, res_dict['badRequest']['code'])
        self.assertEqual('Invalid cgsnapshot',
                         res_dict['badRequest']['message'])

        db.cgsnapshot_destroy(context.get_admin_context(),
                              cgsnapshot_id)
        db.volume_destroy(context.get_admin_context(),
                          volume_id)
        consistencygroup.destroy()
Exemple #7
0
class CgsnapshotsAPITestCase(test.TestCase):
    """Test Case for cgsnapshots API."""
    def setUp(self):
        super(CgsnapshotsAPITestCase, self).setUp()
        self.volume_api = cinder.volume.API()
        self.context = context.get_admin_context()
        self.context.project_id = fake.PROJECT_ID
        self.context.user_id = fake.USER_ID
        self.user_ctxt = context.RequestContext(fake.USER_ID,
                                                fake.PROJECT_ID,
                                                auth_token=True)

    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_show_cgsnapshot_with_cgsnapshot_NotFound(self):
        req = webob.Request.blank('/v2/%s/cgsnapshots/%s' %
                                  (fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_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.NOT_FOUND, res.status_int)
        self.assertEqual(http_client.NOT_FOUND,
                         res_dict['itemNotFound']['code'])
        self.assertEqual(
            'GroupSnapshot %s could not be found.' % fake.WILL_NOT_BE_FOUND_ID,
            res_dict['itemNotFound']['message'])

    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(http_client.OK, 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_detail_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/detail' %
                                  fake.PROJECT_ID)
        req.method = 'GET'
        req.headers['Content-Type'] = 'application/json'
        req.headers['Accept'] = '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['cgsnapshots'][0]['description'])
        self.assertEqual('test_cgsnapshot', res_dict['cgsnapshots'][0]['name'])
        self.assertEqual(cgsnapshot1.id, res_dict['cgsnapshots'][0]['id'])
        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(cgsnapshot2.id, res_dict['cgsnapshots'][1]['id'])
        self.assertEqual('creating', res_dict['cgsnapshots'][1]['status'])

        self.assertEqual('this is a test cgsnapshot',
                         res_dict['cgsnapshots'][2]['description'])
        self.assertEqual('test_cgsnapshot', res_dict['cgsnapshots'][2]['name'])
        self.assertEqual(cgsnapshot3.id, res_dict['cgsnapshots'][2]['id'])
        self.assertEqual('creating', res_dict['cgsnapshots'][2]['status'])

        cgsnapshot3.destroy()
        cgsnapshot2.destroy()
        cgsnapshot1.destroy()
        db.volume_destroy(context.get_admin_context(), volume_id)
        consistencygroup.destroy()

    @mock.patch(
        'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
    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(http_client.ACCEPTED, 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()

    @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(http_client.BAD_REQUEST, res.status_int)
        self.assertEqual(http_client.BAD_REQUEST,
                         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)
        req.body = jsonutils.dump_as_bytes(None)
        req.method = 'POST'
        req.headers['Content-Type'] = 'application/json'
        req.headers['Accept'] = '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.assertEqual(
            "Missing required element 'cgsnapshot' in "
            "request body.", res_dict['badRequest']['message'])

    @mock.patch.object(
        consistencygroupAPI.API,
        'create_cgsnapshot',
        side_effect=exception.InvalidCgSnapshot(reason='invalid cgsnapshot'))
    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(http_client.BAD_REQUEST, res.status_int)
        self.assertEqual(http_client.BAD_REQUEST,
                         res_dict['badRequest']['code'])
        self.assertEqual('Invalid CgSnapshot: invalid cgsnapshot',
                         res_dict['badRequest']['message'])
        consistencygroup.destroy()

    @mock.patch.object(
        consistencygroupAPI.API,
        'create_cgsnapshot',
        side_effect=exception.CgSnapshotNotFound(cgsnapshot_id='invalid_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/%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('CgSnapshot invalid_id could not be found.',
                         res_dict['itemNotFound']['message'])
        consistencygroup.destroy()

    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(http_client.BAD_REQUEST, res.status_int)
        self.assertEqual(http_client.BAD_REQUEST,
                         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_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_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(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_cgsnapshot_NotFound(self):
        req = webob.Request.blank('/v2/%s/cgsnapshots/%s' %
                                  (fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_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.NOT_FOUND, res.status_int)
        self.assertEqual(http_client.NOT_FOUND,
                         res_dict['itemNotFound']['code'])
        self.assertEqual(
            'GroupSnapshot %s could not be found.' % fake.WILL_NOT_BE_FOUND_ID,
            res_dict['itemNotFound']['message'])

    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(http_client.BAD_REQUEST, res.status_int)
        self.assertEqual(http_client.BAD_REQUEST,
                         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()