diff options
author | Ankit Agrawal <ankit11.agrawal@nttdata.com> | 2015-12-13 23:25:04 -0800 |
---|---|---|
committer | Ankit Agrawal <ankit11.agrawal@nttdata.com> | 2016-01-28 23:19:57 -0800 |
commit | ef151618e1f3b9ce8cb82ca7b1c6266e6cb3a53e (patch) | |
tree | 65946ca266724f5ec1f566ef9a23a3e1039d8f6a | |
parent | 1619f11b9c191d44303977fd1b07fea28da9bc7c (diff) | |
download | python-cinderclient-ef151618e1f3b9ce8cb82ca7b1c6266e6cb3a53e.tar.gz |
Return wrapper classes with request_ids attribute
Return appropriate wrapper classes with request_ids attribute from
base class.
Note:
In cinderclient/base.py->_update method will return None for
qos_specs->unset_keys method and for all other cases it returns body
of type dict. At few places, wherever the _update method is called,
it converts the return value back to the resource class and in all
other cases the same return value is returned back to the caller.
It's not possible to return request_ids with None so for all cases
object of DictWithMeta will be returned from this method. Second
approach would be to return (resp, body) tuple from _update method
and wherever this method is called, return the appropriate object.
These changes will affect v1 version and since v1 is already
deprecated the above approach sounds logical.
This change is required to return 'request_id' from client to log
request_id mappings of cross projects.
Change-Id: If73c47ae2c99dea2a0b1f25771f081bb4bbc26f1
Partial-Implements: blueprint return-request-id-to-caller
-rw-r--r-- | cinderclient/base.py | 25 | ||||
-rw-r--r-- | cinderclient/tests/unit/utils.py | 7 | ||||
-rw-r--r-- | cinderclient/tests/unit/v1/test_volume_encryption_types.py | 3 | ||||
-rw-r--r-- | cinderclient/tests/unit/v2/fakes.py | 5 | ||||
-rw-r--r-- | cinderclient/tests/unit/v2/test_volume_encryption_types.py | 3 |
5 files changed, 33 insertions, 10 deletions
diff --git a/cinderclient/base.py b/cinderclient/base.py index b975f11..36e7df8 100644 --- a/cinderclient/base.py +++ b/cinderclient/base.py @@ -94,7 +94,7 @@ class Manager(common_base.HookableMixin): if margin <= len(items_new): # If the limit is reached, return the items. items = items + items_new[:margin] - return items + return common_base.ListWithMeta(items, resp) else: items = items + items_new else: @@ -116,7 +116,7 @@ class Manager(common_base.HookableMixin): # till there is no more items. items = self._list(next, response_key, obj_class, None, limit, items) - return items + return common_base.ListWithMeta(items, resp) def _build_list_url(self, resource_type, detailed=True, search_opts=None, marker=None, limit=None, sort_key=None, sort_dir=None, @@ -290,29 +290,38 @@ class Manager(common_base.HookableMixin): def _get(self, url, response_key=None): resp, body = self.api.client.get(url) if response_key: - return self.resource_class(self, body[response_key], loaded=True) + return self.resource_class(self, body[response_key], loaded=True, + resp=resp) else: - return self.resource_class(self, body, loaded=True) + return self.resource_class(self, body, loaded=True, resp=resp) def _create(self, url, body, response_key, return_raw=False, **kwargs): self.run_hooks('modify_body_for_create', body, **kwargs) resp, body = self.api.client.post(url, body=body) if return_raw: - return body[response_key] + return common_base.DictWithMeta(body[response_key], resp) with self.completion_cache('human_id', self.resource_class, mode="a"): with self.completion_cache('uuid', self.resource_class, mode="a"): - return self.resource_class(self, body[response_key]) + return self.resource_class(self, body[response_key], resp=resp) def _delete(self, url): resp, body = self.api.client.delete(url) + return common_base.TupleWithMeta(resp, body) def _update(self, url, body, response_key=None, **kwargs): self.run_hooks('modify_body_for_update', body, **kwargs) resp, body = self.api.client.put(url, body=body) if response_key: - return self.resource_class(self, body[response_key], loaded=True) - return body + return self.resource_class(self, body[response_key], loaded=True, + resp=resp) + + # (NOTE)ankit: In case of qos_specs.unset_keys method, None is + # returned back to the caller and in all other cases dict is + # returned but in order to return request_ids to the caller, it's + # not possible to return None so returning DictWithMeta for all cases. + body = body or {} + return common_base.DictWithMeta(body, resp) class ManagerWithFind(six.with_metaclass(abc.ABCMeta, Manager)): diff --git a/cinderclient/tests/unit/utils.py b/cinderclient/tests/unit/utils.py index 25e7ee0..ddf8972 100644 --- a/cinderclient/tests/unit/utils.py +++ b/cinderclient/tests/unit/utils.py @@ -21,6 +21,9 @@ import six import testtools +REQUEST_ID = ['req-test-request-id'] + + class TestCase(testtools.TestCase): TEST_REQUEST_BASE = { 'verify': True, @@ -37,6 +40,10 @@ class TestCase(testtools.TestCase): stderr = self.useFixture(fixtures.StringStream('stderr')).stream self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr)) + def _assert_request_id(self, obj): + self.assertTrue(hasattr(obj, 'request_ids')) + self.assertEqual(REQUEST_ID, obj.request_ids) + class FixturedTestCase(TestCase): diff --git a/cinderclient/tests/unit/v1/test_volume_encryption_types.py b/cinderclient/tests/unit/v1/test_volume_encryption_types.py index 04093ae..76a81c2 100644 --- a/cinderclient/tests/unit/v1/test_volume_encryption_types.py +++ b/cinderclient/tests/unit/v1/test_volume_encryption_types.py @@ -96,4 +96,5 @@ class VolumeEncryptionTypesTest(utils.TestCase): """ result = cs.volume_encryption_types.delete(1) cs.assert_called('DELETE', '/types/1/encryption/provider') - self.assertIsNone(result, "delete result must be None") + self.assertIsInstance(result, tuple) + self.assertEqual(202, result[0].status_code) diff --git a/cinderclient/tests/unit/v2/fakes.py b/cinderclient/tests/unit/v2/fakes.py index b787e2d..ffed52e 100644 --- a/cinderclient/tests/unit/v2/fakes.py +++ b/cinderclient/tests/unit/v2/fakes.py @@ -25,6 +25,9 @@ import cinderclient.tests.unit.utils as utils from cinderclient.v2 import client +REQUEST_ID = 'req-test-request-id' + + def _stub_volume(*args, **kwargs): volume = { "migration_status": None, @@ -305,6 +308,8 @@ class FakeHTTPClient(base_client.HTTPClient): # Note the call self.callstack.append((method, url, kwargs.get('body', None))) status, headers, body = getattr(self, callback)(**kwargs) + # add fake request-id header + headers['x-openstack-request-id'] = REQUEST_ID r = utils.TestResponse({ "status_code": status, "text": body, diff --git a/cinderclient/tests/unit/v2/test_volume_encryption_types.py b/cinderclient/tests/unit/v2/test_volume_encryption_types.py index 37bd3a7..b1baf98 100644 --- a/cinderclient/tests/unit/v2/test_volume_encryption_types.py +++ b/cinderclient/tests/unit/v2/test_volume_encryption_types.py @@ -106,4 +106,5 @@ class VolumeEncryptionTypesTest(utils.TestCase): """ result = cs.volume_encryption_types.delete(1) cs.assert_called('DELETE', '/types/1/encryption/provider') - self.assertIsNone(result, "delete result must be None") + self.assertIsInstance(result, tuple) + self.assertEqual(202, result[0].status_code) |