Example #1
0
    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)
Example #3
0
    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()
Example #6
0
    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)
Example #8
0
    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()
Example #9
0
    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()
Example #10
0
    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()
Example #11
0
    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()
Example #12
0
    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)
Example #13
0
    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()
Example #14
0
    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()
Example #15
0
    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()
Example #17
0
    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)
Example #18
0
    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)
Example #19
0
    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()
Example #20
0
    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()
Example #21
0
    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()
Example #22
0
    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()
Example #23
0
    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)
Example #24
0
    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()
Example #26
0
    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()
Example #27
0
    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()
Example #28
0
    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()
Example #29
0
    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()
Example #30
0
    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()
Example #31
0
    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)
Example #32
0
    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()
Example #34
0
    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()
Example #35
0
    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()
Example #36
0
    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()
Example #37
0
    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()
Example #38
0
    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()
Example #39
0
    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)
Example #40
0
    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'])
Example #41
0
    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()
Example #42
0
    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()
Example #43
0
    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()
Example #44
0
    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)
Example #45
0
    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()
Example #46
0
    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()
Example #47
0
    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)
Example #48
0
    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)
Example #49
0
    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)
Example #50
0
    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)
Example #51
0
    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
Example #52
0
    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)
Example #53
0
    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)