From b939dd9922abdb5257f785fca4e1d41741ddb078 Mon Sep 17 00:00:00 2001 From: Jamie Lennox Date: Wed, 27 Aug 2014 12:32:16 +1000 Subject: [PATCH] Make tests run against original client and sessions The managers have a bad habit of reaching back into the client and making assumptions about the values that are saved there. These assumptions are not always correct when we use the session object. Test all the versioned managers against a client that was constructed with the old method and with a keystoneclient session object and a keystoneauth1 session object. Change-Id: I93a26db7ae7e4d887aa815108be71c72b4a1f2bb --- keystoneclient/tests/unit/client_fixtures.py | 164 ++++++++++++++++++ keystoneclient/tests/unit/utils.py | 25 +++ .../tests/unit/v2_0/test_tenants.py | 4 +- keystoneclient/tests/unit/v2_0/test_tokens.py | 4 +- keystoneclient/tests/unit/v2_0/test_users.py | 6 +- keystoneclient/tests/unit/v2_0/utils.py | 20 +-- keystoneclient/tests/unit/v3/utils.py | 45 ++++- test-requirements.txt | 1 + 8 files changed, 243 insertions(+), 26 deletions(-) diff --git a/keystoneclient/tests/unit/client_fixtures.py b/keystoneclient/tests/unit/client_fixtures.py index 9ede861f..94589e36 100644 --- a/keystoneclient/tests/unit/client_fixtures.py +++ b/keystoneclient/tests/unit/client_fixtures.py @@ -14,18 +14,28 @@ import contextlib import os +import uuid import warnings import fixtures +from keystoneauth1 import identity as ksa_identity +from keystoneauth1 import session as ksa_session from oslo_serialization import jsonutils from oslo_utils import timeutils import six import testresources +from keystoneclient.auth import identity as ksc_identity from keystoneclient.common import cms +from keystoneclient import fixture +from keystoneclient import session as ksc_session from keystoneclient import utils +from keystoneclient.v2_0 import client as v2_client +from keystoneclient.v3 import client as v3_client +TEST_ROOT_URL = 'http://127.0.0.1:5000/' + TESTDIR = os.path.dirname(os.path.abspath(__file__)) ROOTDIR = os.path.normpath(os.path.join(TESTDIR, '..', '..', '..')) CERTDIR = os.path.join(ROOTDIR, 'examples', 'pki', 'certs') @@ -33,6 +43,160 @@ CMSDIR = os.path.join(ROOTDIR, 'examples', 'pki', 'cms') KEYDIR = os.path.join(ROOTDIR, 'examples', 'pki', 'private') +class BaseFixture(fixtures.Fixture): + + TEST_ROOT_URL = TEST_ROOT_URL + + def __init__(self, requests, deprecations): + super(BaseFixture, self).__init__() + self.requests = requests + self.deprecations = deprecations + self.user_id = uuid.uuid4().hex + self.client = self.new_client() + + +class BaseV2(BaseFixture): + + TEST_URL = '%s%s' % (TEST_ROOT_URL, 'v2.0') + + +class OriginalV2(BaseV2): + + def new_client(self): + # Creating a Client not using session is deprecated. + with self.deprecations.expect_deprecations_here(): + return v2_client.Client(username=uuid.uuid4().hex, + user_id=self.user_id, + token=uuid.uuid4().hex, + tenant_name=uuid.uuid4().hex, + auth_url=self.TEST_URL, + endpoint=self.TEST_URL) + + +class KscSessionV2(BaseV2): + + def new_client(self): + t = fixture.V2Token(user_id=self.user_id) + t.set_scope() + + s = t.add_service('identity') + s.add_endpoint(self.TEST_URL) + + d = fixture.V2Discovery(self.TEST_URL) + + self.requests.register_uri('POST', self.TEST_URL + '/tokens', json=t) + + # NOTE(jamielennox): Because of the versioned URL hack here even though + # the V2 URL will be in the service catalog it will be the root URL + # that will be queried for discovery. + self.requests.register_uri('GET', self.TEST_ROOT_URL, + json={'version': d}) + + a = ksc_identity.V2Password(username=uuid.uuid4().hex, + password=uuid.uuid4().hex, + auth_url=self.TEST_URL) + s = ksc_session.Session(auth=a) + return v2_client.Client(session=s) + + +class KsaSessionV2(BaseV2): + + def new_client(self): + t = fixture.V2Token(user_id=self.user_id) + t.set_scope() + + s = t.add_service('identity') + s.add_endpoint(self.TEST_URL) + + d = fixture.V2Discovery(self.TEST_URL) + + self.requests.register_uri('POST', self.TEST_URL + '/tokens', json=t) + + # NOTE(jamielennox): Because of the versioned URL hack here even though + # the V2 URL will be in the service catalog it will be the root URL + # that will be queried for discovery. + self.requests.register_uri('GET', self.TEST_ROOT_URL, + json={'version': d}) + + a = ksa_identity.V2Password(username=uuid.uuid4().hex, + password=uuid.uuid4().hex, + auth_url=self.TEST_URL) + s = ksa_session.Session(auth=a) + return v2_client.Client(session=s) + + +class BaseV3(BaseFixture): + + TEST_URL = '%s%s' % (TEST_ROOT_URL, 'v3') + + +class OriginalV3(BaseV3): + + def new_client(self): + # Creating a Client not using session is deprecated. + with self.deprecations.expect_deprecations_here(): + return v3_client.Client(username=uuid.uuid4().hex, + user_id=self.user_id, + token=uuid.uuid4().hex, + tenant_name=uuid.uuid4().hex, + auth_url=self.TEST_URL, + endpoint=self.TEST_URL) + + +class KscSessionV3(BaseV3): + + def new_client(self): + t = fixture.V3Token(user_id=self.user_id) + t.set_project_scope() + + s = t.add_service('identity') + s.add_standard_endpoints(public=self.TEST_URL, + admin=self.TEST_URL) + + d = fixture.V3Discovery(self.TEST_URL) + + headers = {'X-Subject-Token': uuid.uuid4().hex} + self.requests.register_uri('POST', + self.TEST_URL + '/auth/tokens', + headers=headers, + json=t) + self.requests.register_uri('GET', self.TEST_URL, json={'version': d}) + + a = ksc_identity.V3Password(username=uuid.uuid4().hex, + password=uuid.uuid4().hex, + user_domain_id=uuid.uuid4().hex, + auth_url=self.TEST_URL) + s = ksc_session.Session(auth=a) + return v3_client.Client(session=s) + + +class KsaSessionV3(BaseV3): + + def new_client(self): + t = fixture.V3Token(user_id=self.user_id) + t.set_project_scope() + + s = t.add_service('identity') + s.add_standard_endpoints(public=self.TEST_URL, + admin=self.TEST_URL) + + d = fixture.V3Discovery(self.TEST_URL) + + headers = {'X-Subject-Token': uuid.uuid4().hex} + self.requests.register_uri('POST', + self.TEST_URL + '/auth/tokens', + headers=headers, + json=t) + self.requests.register_uri('GET', self.TEST_URL, json={'version': d}) + + a = ksa_identity.V3Password(username=uuid.uuid4().hex, + password=uuid.uuid4().hex, + user_domain_id=uuid.uuid4().hex, + auth_url=self.TEST_URL) + s = ksa_session.Session(auth=a) + return v3_client.Client(session=s) + + def _hash_signed_token_safe(signed_text, **kwargs): if isinstance(signed_text, six.text_type): signed_text = signed_text.encode('utf-8') diff --git a/keystoneclient/tests/unit/utils.py b/keystoneclient/tests/unit/utils.py index 7c6de95b..7287c405 100644 --- a/keystoneclient/tests/unit/utils.py +++ b/keystoneclient/tests/unit/utils.py @@ -20,6 +20,7 @@ import requests from requests_mock.contrib import fixture import six from six.moves.urllib import parse as urlparse +import testscenarios import testtools from keystoneclient.tests.unit import client_fixtures @@ -189,6 +190,30 @@ class DisableModuleFixture(fixtures.Fixture): sys.meta_path.insert(0, finder) +class ClientTestCaseMixin(testscenarios.WithScenarios): + + client_fixture_class = None + data_fixture_class = None + + def setUp(self): + super(ClientTestCaseMixin, self).setUp() + + self.data_fixture = None + self.client_fixture = None + self.client = None + + if self.client_fixture_class: + fix = self.client_fixture_class(self.requests_mock, + self.deprecations) + self.client_fixture = self.useFixture(fix) + self.client = self.client_fixture.client + self.TEST_USER_ID = self.client_fixture.user_id + + if self.data_fixture_class: + fix = self.data_fixture_class(self.requests_mock) + self.data_fixture = self.useFixture(fix) + + class NoModuleFinder(object): """Disallow further imports of 'module'.""" diff --git a/keystoneclient/tests/unit/v2_0/test_tenants.py b/keystoneclient/tests/unit/v2_0/test_tenants.py index 50c3aa18..febbe9f2 100644 --- a/keystoneclient/tests/unit/v2_0/test_tenants.py +++ b/keystoneclient/tests/unit/v2_0/test_tenants.py @@ -332,9 +332,9 @@ class TenantTests(utils.ClientTestCase): def test_list_tenants_use_admin_url(self): self.stub_url('GET', ['tenants'], json=self.TEST_TENANTS) - self.assertEqual(self.TEST_URL, self.client.management_url) - tenant_list = self.client.tenants.list() + self.assertEqual(self.TEST_URL + '/tenants', + self.requests_mock.last_request.url) [self.assertIsInstance(t, tenants.Tenant) for t in tenant_list] self.assertEqual(len(self.TEST_TENANTS['tenants']['values']), diff --git a/keystoneclient/tests/unit/v2_0/test_tokens.py b/keystoneclient/tests/unit/v2_0/test_tokens.py index 1b7f2d6d..499ef181 100644 --- a/keystoneclient/tests/unit/v2_0/test_tokens.py +++ b/keystoneclient/tests/unit/v2_0/test_tokens.py @@ -139,9 +139,9 @@ class TokenTests(utils.ClientTestCase): token_fixture.set_scope() self.stub_auth(json=token_fixture) - self.assertEqual(self.TEST_URL, self.client.management_url) - token_ref = self.client.tokens.authenticate(token=uuid.uuid4().hex) + self.assertEqual(self.TEST_URL + '/tokens', + self.requests_mock.last_request.url) self.assertIsInstance(token_ref, tokens.Token) self.assertEqual(token_fixture.token_id, token_ref.id) self.assertEqual(token_fixture.expires_str, token_ref.expires) diff --git a/keystoneclient/tests/unit/v2_0/test_users.py b/keystoneclient/tests/unit/v2_0/test_users.py index 0babc081..da607f5f 100644 --- a/keystoneclient/tests/unit/v2_0/test_users.py +++ b/keystoneclient/tests/unit/v2_0/test_users.py @@ -252,10 +252,10 @@ class UserTests(utils.ClientTestCase): resp_body = { 'access': {} } - user_id = uuid.uuid4().hex - self.stub_url('PATCH', ['OS-KSCRUD', 'users', user_id], json=resp_body) + self.stub_url('PATCH', + ['OS-KSCRUD', 'users', self.TEST_USER_ID], + json=resp_body) - self.client.user_id = user_id self.client.users.update_own_password(old_password, new_password) self.assertRequestBodyIs(json=req_body) self.assertNotIn(old_password, self.logger.output) diff --git a/keystoneclient/tests/unit/v2_0/utils.py b/keystoneclient/tests/unit/v2_0/utils.py index 3dfe762a..bc239528 100644 --- a/keystoneclient/tests/unit/v2_0/utils.py +++ b/keystoneclient/tests/unit/v2_0/utils.py @@ -10,8 +10,8 @@ # License for the specific language governing permissions and limitations # under the License. +from keystoneclient.tests.unit import client_fixtures from keystoneclient.tests.unit import utils -from keystoneclient.v2_0 import client TestResponse = utils.TestResponse @@ -80,13 +80,13 @@ class TestCase(UnauthenticatedTestCase): self.stub_url('POST', ['tokens'], **kwargs) -class ClientTestCase(TestCase): +class ClientTestCase(utils.ClientTestCaseMixin, TestCase): - def setUp(self): - super(ClientTestCase, self).setUp() - - # Creating a Client not using session is deprecated. - with self.deprecations.expect_deprecations_here(): - self.client = client.Client(token=self.TEST_TOKEN, - auth_url=self.TEST_URL, - endpoint=self.TEST_URL) + scenarios = [ + ('original', + {'client_fixture_class': client_fixtures.OriginalV2}), + ('ksc-session', + {'client_fixture_class': client_fixtures.KscSessionV2}), + ('ksa-session', + {'client_fixture_class': client_fixtures.KsaSessionV2}), + ] diff --git a/keystoneclient/tests/unit/v3/utils.py b/keystoneclient/tests/unit/v3/utils.py index 5373e59a..fcb546e2 100644 --- a/keystoneclient/tests/unit/v3/utils.py +++ b/keystoneclient/tests/unit/v3/utils.py @@ -15,8 +15,8 @@ import uuid import six from six.moves.urllib import parse as urlparse +from keystoneclient.tests.unit import client_fixtures from keystoneclient.tests.unit import utils -from keystoneclient.v3 import client TestResponse = utils.TestResponse @@ -128,6 +128,7 @@ class TestCase(UnauthenticatedTestCase): }] def stub_auth(self, subject_token=None, **kwargs): + if not subject_token: subject_token = self.TEST_TOKEN @@ -144,16 +145,42 @@ class TestCase(UnauthenticatedTestCase): self.stub_url('POST', ['auth', 'tokens'], **kwargs) -class ClientTestCase(TestCase): +class ClientTestCase(utils.ClientTestCaseMixin, TestCase): - def setUp(self): - super(TestCase, self).setUp() + ORIGINAL_CLIENT_TYPE = 'original' + KSC_SESSION_CLIENT_TYPE = 'ksc-session' + KSA_SESSION_CLIENT_TYPE = 'ksa-session' - # Creating a Client not using session is deprecated. - with self.deprecations.expect_deprecations_here(): - self.client = client.Client(token=self.TEST_TOKEN, - auth_url=self.TEST_URL, - endpoint=self.TEST_URL) + scenarios = [ + ( + ORIGINAL_CLIENT_TYPE, { + 'client_fixture_class': client_fixtures.OriginalV3, + 'client_type': ORIGINAL_CLIENT_TYPE + } + ), + ( + KSC_SESSION_CLIENT_TYPE, { + 'client_fixture_class': client_fixtures.KscSessionV3, + 'client_type': KSC_SESSION_CLIENT_TYPE + } + ), + ( + KSA_SESSION_CLIENT_TYPE, { + 'client_fixture_class': client_fixtures.KsaSessionV3, + 'client_type': KSA_SESSION_CLIENT_TYPE + } + ) + + ] + + @property + def is_original_client(self): + return self.client_type == self.ORIGINAL_CLIENT_TYPE + + @property + def is_session_client(self): + return self.client_type in (self.KSC_SESSION_CLIENT_TYPE, + self.KSA_SESSION_CLIENT_TYPE) class CrudTests(object): diff --git a/test-requirements.txt b/test-requirements.txt index e3707736..e6db02b9 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -19,6 +19,7 @@ sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 tempest-lib>=0.11.0 testrepository>=0.0.18 testresources>=0.2.4 +testscenarios>=0.4 testtools>=1.4.0 # Bandit security code scanner