]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add unit tests for cinder.api.v2.volumes
authorVipin Balachandran <vbala@vmware.com>
Wed, 1 Jul 2015 06:41:19 +0000 (12:11 +0530)
committerVipin Balachandran <vbala@vmware.com>
Wed, 15 Jul 2015 09:47:23 +0000 (15:17 +0530)
Add units tests to increase coverage for
cinder.api.v2.volumes.VolumeController.create.

Change-Id: I7c4225de5d32ecd0ad78fc7c0ff847a8bee7b7da

cinder/tests/unit/api/v2/stubs.py
cinder/tests/unit/api/v2/test_volumes.py

index 50e6867de3a017fe179015bc75364808647a0c17..41763430e0a0358e050931740330d605871620c1 100644 (file)
@@ -20,6 +20,7 @@ from cinder import exception as exc
 
 FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
 FAKE_UUIDS = {}
+TEST_SNAPSHOT_UUID = '00000000-0000-0000-0000-000000000001'
 
 
 def stub_volume(id, **kwargs):
@@ -69,7 +70,8 @@ def stub_volume_create(self, context, size, name, description, snapshot,
     vol['size'] = size
     vol['display_name'] = name
     vol['display_description'] = description
-    vol['source_volid'] = None
+    source_volume = param.get('source_volume') or {}
+    vol['source_volid'] = source_volume.get('id')
     vol['bootable'] = False
     try:
         vol['snapshot_id'] = snapshot['id']
@@ -170,3 +172,14 @@ def stub_snapshot_update(self, context, *args, **param):
 
 def stub_service_get_all_by_topic(context, topic):
     return [{'availability_zone': "zone1:host1", "disabled": 0}]
+
+
+def stub_snapshot_get(self, context, snapshot_id):
+    if snapshot_id != TEST_SNAPSHOT_UUID:
+        raise exc.SnapshotNotFound(snapshot_id=snapshot_id)
+
+    return stub_snapshot(snapshot_id)
+
+
+def stub_consistencygroup_get_notfound(self, context, cg_id):
+    raise exc.ConsistencyGroupNotFound(consistencygroup_id=cg_id)
index eb766afb97d235aa6ede6d0aa441bc118a56930f..e7bdb03b5bfbe842f3a568f65da15a3a826f4652 100644 (file)
@@ -27,6 +27,7 @@ import webob
 
 from cinder.api import extensions
 from cinder.api.v2 import volumes
+from cinder import consistencygroup as consistencygroupAPI
 from cinder import context
 from cinder import db
 from cinder import exception
@@ -41,22 +42,10 @@ CONF = cfg.CONF
 
 NS = '{http://docs.openstack.org/api/openstack-block-storage/2.0/content}'
 
-TEST_SNAPSHOT_UUID = '00000000-0000-0000-0000-000000000001'
-
-
-def stub_snapshot_get(self, context, snapshot_id):
-    if snapshot_id != TEST_SNAPSHOT_UUID:
-        raise exception.NotFound
-
-    return {
-        'id': snapshot_id,
-        'volume_id': 12,
-        'status': 'available',
-        'volume_size': 100,
-        'created_at': None,
-        'name': 'Default name',
-        'description': 'Default description',
-    }
+DEFAULT_VOL_NAME = "Volume Test Name"
+DEFAULT_VOL_DESCRIPTION = "Volume Test Desc"
+DEFAULT_AZ = "zone1:host1"
+DEFAULT_VOL_SIZE = 100
 
 
 class VolumeApiTest(test.TestCase):
@@ -186,6 +175,205 @@ class VolumeApiTest(test.TestCase):
         req = fakes.HTTPRequest.blank('/v2/volumes/detail')
         res_dict = self.controller.detail(req)
 
+    def _vol_in_request_body(
+            self, size=DEFAULT_VOL_SIZE, name=DEFAULT_VOL_NAME,
+            description=DEFAULT_VOL_DESCRIPTION, availability_zone=DEFAULT_AZ,
+            snapshot_id=None, source_volid=None, source_replica=None,
+            consistencygroup_id=None):
+        return {"size": size,
+                "name": name,
+                "description": description,
+                "availability_zone": availability_zone,
+                "snapshot_id": snapshot_id,
+                "source_volid": source_volid,
+                "source_replica": source_replica,
+                "consistencygroup_id": consistencygroup_id,
+                }
+
+    def _expected_vol_from_create_api(
+            self, size=DEFAULT_VOL_SIZE, availability_zone=DEFAULT_AZ,
+            description=DEFAULT_VOL_DESCRIPTION, name=DEFAULT_VOL_NAME,
+            consistencygroup_id=None, source_volid=None, snapshot_id=None):
+        return {'volume':
+                {'attachments': [],
+                 'availability_zone': availability_zone,
+                 'bootable': 'false',
+                 'consistencygroup_id': consistencygroup_id,
+                 'created_at': datetime.datetime(1900, 1, 1, 1, 1, 1),
+                 'description': description,
+                 'id': '1',
+                 'links':
+                 [{'href': 'http://localhost/v2/fakeproject/volumes/1',
+                   'rel': 'self'},
+                  {'href': 'http://localhost/fakeproject/volumes/1',
+                   'rel': 'bookmark'}],
+                 'metadata': {},
+                 'name': name,
+                 'replication_status': 'disabled',
+                 'multiattach': False,
+                 'size': size,
+                 'snapshot_id': snapshot_id,
+                 'source_volid': source_volid,
+                 'status': 'fakestatus',
+                 'user_id': 'fakeuser',
+                 'volume_type': 'vol_type_name',
+                 'encrypted': False}}
+
+    def _expected_volume_api_create_kwargs(self, snapshot=None,
+                                           availability_zone=DEFAULT_AZ,
+                                           source_volume=None):
+        return {'metadata': None,
+                'snapshot': snapshot,
+                'source_volume': source_volume,
+                'source_replica': None,
+                'consistencygroup': None,
+                'availability_zone': availability_zone,
+                'scheduler_hints': None,
+                'multiattach': False,
+                }
+
+    @mock.patch.object(volume_api.API, 'get_snapshot', autospec=True)
+    @mock.patch.object(volume_api.API, 'create', autospec=True)
+    def test_volume_creation_from_snapshot(self, create, get_snapshot):
+
+        create.side_effect = stubs.stub_volume_create
+        get_snapshot.side_effect = stubs.stub_snapshot_get
+
+        snapshot_id = stubs.TEST_SNAPSHOT_UUID
+        vol = self._vol_in_request_body(snapshot_id=stubs.TEST_SNAPSHOT_UUID)
+        body = {"volume": vol}
+        req = fakes.HTTPRequest.blank('/v2/volumes')
+        res_dict = self.controller.create(req, body)
+
+        ex = self._expected_vol_from_create_api(snapshot_id=snapshot_id)
+        self.assertEqual(ex, res_dict)
+
+        context = req.environ['cinder.context']
+        get_snapshot.assert_called_once_with(self.controller.volume_api,
+                                             context, snapshot_id)
+
+        kwargs = self._expected_volume_api_create_kwargs(
+            stubs.stub_snapshot(snapshot_id))
+        create.assert_called_once_with(self.controller.volume_api, context,
+                                       vol['size'], DEFAULT_VOL_NAME,
+                                       DEFAULT_VOL_DESCRIPTION, **kwargs)
+
+    @mock.patch.object(volume_api.API, 'get_snapshot', autospec=True)
+    def test_volume_creation_fails_with_invalid_snapshot(self, get_snapshot):
+
+        get_snapshot.side_effect = stubs.stub_snapshot_get
+
+        snapshot_id = "fake_id"
+        vol = self._vol_in_request_body(snapshot_id=snapshot_id)
+        body = {"volume": vol}
+        req = fakes.HTTPRequest.blank('/v2/volumes')
+        # Raise 404 when snapshot cannot be found.
+        self.assertRaises(webob.exc.HTTPNotFound, self.controller.create,
+                          req, body)
+
+        context = req.environ['cinder.context']
+        get_snapshot.assert_called_once_with(self.controller.volume_api,
+                                             context, snapshot_id)
+
+    @mock.patch.object(volume_api.API, 'get_volume', autospec=True)
+    @mock.patch.object(volume_api.API, 'create', autospec=True)
+    def test_volume_creation_from_source_volume(self, create, get_volume):
+
+        get_volume.side_effect = stubs.stub_volume_get
+        create.side_effect = stubs.stub_volume_create
+
+        source_volid = '2f49aa3a-6aae-488d-8b99-a43271605af6'
+        vol = self._vol_in_request_body(source_volid=source_volid)
+        body = {"volume": vol}
+        req = fakes.HTTPRequest.blank('/v2/volumes')
+        res_dict = self.controller.create(req, body)
+
+        ex = self._expected_vol_from_create_api(source_volid=source_volid)
+        self.assertEqual(ex, res_dict)
+
+        context = req.environ['cinder.context']
+        get_volume.assert_called_once_with(self.controller.volume_api,
+                                           context, source_volid)
+
+        kwargs = self._expected_volume_api_create_kwargs(
+            source_volume=stubs.stub_volume(source_volid))
+        create.assert_called_once_with(self.controller.volume_api, context,
+                                       vol['size'], DEFAULT_VOL_NAME,
+                                       DEFAULT_VOL_DESCRIPTION, **kwargs)
+
+    @mock.patch.object(volume_api.API, 'get_volume', autospec=True)
+    def test_volume_creation_fails_with_invalid_source_volume(self,
+                                                              get_volume):
+
+        get_volume.side_effect = stubs.stub_volume_get_notfound
+
+        source_volid = "fake_id"
+        vol = self._vol_in_request_body(source_volid=source_volid)
+        body = {"volume": vol}
+        req = fakes.HTTPRequest.blank('/v2/volumes')
+        # Raise 404 when source volume cannot be found.
+        self.assertRaises(webob.exc.HTTPNotFound, self.controller.create,
+                          req, body)
+
+        context = req.environ['cinder.context']
+        get_volume.assert_called_once_with(self.controller.volume_api,
+                                           context, source_volid)
+
+    @mock.patch.object(volume_api.API, 'get_volume', autospec=True)
+    def test_volume_creation_fails_with_invalid_source_replica(self,
+                                                               get_volume):
+
+        get_volume.side_effect = stubs.stub_volume_get_notfound
+
+        source_replica = "fake_id"
+        vol = self._vol_in_request_body(source_replica=source_replica)
+        body = {"volume": vol}
+        req = fakes.HTTPRequest.blank('/v2/volumes')
+        # Raise 404 when source replica cannot be found.
+        self.assertRaises(webob.exc.HTTPNotFound, self.controller.create,
+                          req, body)
+
+        context = req.environ['cinder.context']
+        get_volume.assert_called_once_with(self.controller.volume_api,
+                                           context, source_replica)
+
+    @mock.patch.object(volume_api.API, 'get_volume', autospec=True)
+    def test_volume_creation_fails_with_invalid_source_replication_status(
+            self, get_volume):
+
+        get_volume.side_effect = stubs.stub_volume_get
+
+        source_replica = '2f49aa3a-6aae-488d-8b99-a43271605af6'
+        vol = self._vol_in_request_body(source_replica=source_replica)
+        body = {"volume": vol}
+        req = fakes.HTTPRequest.blank('/v2/volumes')
+        # Raise 404 when replication status is disabled.
+        self.assertRaises(webob.exc.HTTPNotFound, self.controller.create,
+                          req, body)
+
+        context = req.environ['cinder.context']
+        get_volume.assert_called_once_with(self.controller.volume_api,
+                                           context, source_replica)
+
+    @mock.patch.object(consistencygroupAPI.API, 'get', autospec=True)
+    def test_volume_creation_fails_with_invalid_consistency_group(self,
+                                                                  get_cg):
+
+        get_cg.side_effect = stubs.stub_consistencygroup_get_notfound
+
+        consistencygroup_id = '4f49aa3a-6aae-488d-8b99-a43271605af6'
+        vol = self._vol_in_request_body(
+            consistencygroup_id=consistencygroup_id)
+        body = {"volume": vol}
+        req = fakes.HTTPRequest.blank('/v2/volumes')
+        # Raise 404 when consistency group is not found.
+        self.assertRaises(webob.exc.HTTPNotFound, self.controller.create,
+                          req, body)
+
+        context = req.environ['cinder.context']
+        get_cg.assert_called_once_with(self.controller.consistencygroup_api,
+                                       context, consistencygroup_id)
+
     def test_volume_creation_fails_with_bad_size(self):
         vol = {"size": '',
                "name": "Volume Test Name",