diff --git a/keystone/common/dependency.py b/keystone/common/dependency.py index 820baafddb..ceddb4a986 100644 --- a/keystone/common/dependency.py +++ b/keystone/common/dependency.py @@ -44,8 +44,9 @@ class UnresolvableDependencyException(Exception): See ``resolve_future_dependencies()`` for more details. """ - def __init__(self, name): - msg = _('Unregistered dependency: %(name)s') % {'name': name} + def __init__(self, name, targets): + msg = _('Unregistered dependency: %(name)s for %(targets)s') % { + 'name': name, 'targets': targets} super(UnresolvableDependencyException, self).__init__(msg) @@ -271,7 +272,7 @@ def resolve_future_dependencies(__provider_name=None): REGISTRY[dependency] = provider new_providers[dependency] = provider else: - raise UnresolvableDependencyException(dependency) + raise UnresolvableDependencyException(dependency, targets) for target in targets: setattr(target, dependency, REGISTRY[dependency]) diff --git a/keystone/tests/core.py b/keystone/tests/core.py index b9f2d49edf..3762d9d638 100644 --- a/keystone/tests/core.py +++ b/keystone/tests/core.py @@ -407,14 +407,12 @@ class TestCase(BaseTestCase): def auth_plugin_config_override(self, methods=None, **method_classes): if methods is None: - methods = ['external', 'password', 'token', 'oauth1', 'saml2'] + methods = ['external', 'password', 'token', ] if not method_classes: method_classes = dict( external='keystone.auth.plugins.external.DefaultDomain', password='keystone.auth.plugins.password.Password', token='keystone.auth.plugins.token.Token', - oauth1='keystone.auth.plugins.oauth1.OAuth', - saml2='keystone.auth.plugins.saml2.Saml2', ) self.config_fixture.config(group='auth', methods=methods) common_cfg.setup_authentication() @@ -516,12 +514,24 @@ class TestCase(BaseTestCase): self.clear_auth_plugin_registry() drivers = backends.load_backends() + drivers.update(self.load_extra_backends()) + drivers.update(dependency.resolve_future_dependencies()) for manager_name, manager in six.iteritems(drivers): setattr(self, manager_name, manager) self.addCleanup(self.cleanup_instance(*drivers.keys())) + def load_extra_backends(self): + """Override to load managers that aren't loaded by default. + + This is useful to load managers initialized by extensions. No extra + backends are loaded by default. + + :return: dict of name -> manager + """ + return {} + def load_fixtures(self, fixtures): """Hacky basic and naive fixture loading based on a python module. diff --git a/keystone/tests/test_auth.py b/keystone/tests/test_auth.py index dd65e1317c..f4a442ccfd 100644 --- a/keystone/tests/test_auth.py +++ b/keystone/tests/test_auth.py @@ -24,6 +24,7 @@ from keystone import assignment from keystone import auth from keystone.common import authorization from keystone import config +from keystone.contrib import revoke from keystone import exception from keystone.models import token_model from keystone import tests @@ -221,6 +222,9 @@ class AuthBadRequests(AuthTest): class AuthWithToken(AuthTest): + def load_extra_backends(self): + return {'revoke_api': revoke.Manager()} + def test_unscoped_token(self): """Verify getting an unscoped token with password creds.""" body_dict = _build_user_auth(username='FOO', diff --git a/keystone/tests/test_content_types.py b/keystone/tests/test_content_types.py index 40e4c063bd..8834699a97 100644 --- a/keystone/tests/test_content_types.py +++ b/keystone/tests/test_content_types.py @@ -22,6 +22,7 @@ from testtools import matchers from keystone.common import extension as keystone_extension from keystone import config +from keystone.contrib import revoke from keystone.tests import rest @@ -1366,6 +1367,10 @@ class JsonTestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests): class RevokeApiJsonTestCase(JsonTestCase): + + def load_extra_backends(self): + return {'revoke_api': revoke.Manager()} + def config_overrides(self): super(RevokeApiJsonTestCase, self).config_overrides() self.config_fixture.config( diff --git a/keystone/tests/test_revoke.py b/keystone/tests/test_revoke.py index 4ad4f173de..ce9c77d1ac 100644 --- a/keystone/tests/test_revoke.py +++ b/keystone/tests/test_revoke.py @@ -18,7 +18,7 @@ import mock from oslo.utils import timeutils from testtools import matchers -from keystone.common import dependency +from keystone.contrib import revoke from keystone.contrib.revoke import model from keystone import exception from keystone import tests @@ -112,7 +112,6 @@ def _matches(event, token_values): return True -@dependency.requires('revoke_api') class RevokeTests(object): def test_list(self): self.revoke_api.revoke_by_user(user_id=1) @@ -181,6 +180,9 @@ class RevokeTests(object): class SqlRevokeTests(test_backend_sql.SqlTests, RevokeTests): + def load_extra_backends(self): + return {'revoke_api': revoke.Manager()} + def config_overrides(self): super(SqlRevokeTests, self).config_overrides() self.config_fixture.config( @@ -193,6 +195,9 @@ class SqlRevokeTests(test_backend_sql.SqlTests, RevokeTests): class KvsRevokeTests(tests.TestCase, RevokeTests): + def load_extra_backends(self): + return {'revoke_api': revoke.Manager()} + def config_overrides(self): super(KvsRevokeTests, self).config_overrides() self.config_fixture.config( diff --git a/keystone/tests/test_v3_auth.py b/keystone/tests/test_v3_auth.py index 0252f406cb..77d84bfd74 100644 --- a/keystone/tests/test_v3_auth.py +++ b/keystone/tests/test_v3_auth.py @@ -25,8 +25,8 @@ from testtools import matchers from testtools import testcase from keystone import auth -from keystone.common import dependency from keystone import config +from keystone.contrib import revoke from keystone import exception from keystone import tests from keystone.tests import test_v3 @@ -591,10 +591,12 @@ class TestTokenRevokeSelfAndAdmin(test_v3.RestfulTestCase): token=adminB_token) -@dependency.requires('revoke_api') class TestTokenRevokeById(test_v3.RestfulTestCase): """Test token revocation on the v3 Identity API.""" + def load_extra_backends(self): + return {'revoke_api': revoke.Manager()} + def config_overrides(self): super(TestTokenRevokeById, self).config_overrides() self.config_fixture.config( @@ -1306,7 +1308,6 @@ class TestTokenRevokeById(test_v3.RestfulTestCase): expected_status=200) -@dependency.requires('revoke_api') class TestTokenRevokeApi(TestTokenRevokeById): EXTENSION_NAME = 'revoke' EXTENSION_TO_ADD = 'revoke_extension' @@ -2575,11 +2576,13 @@ class TestTrustOptional(test_v3.RestfulTestCase): self.v3_authenticate_token(auth_data, expected_status=403) -@dependency.requires('revoke_api') class TestTrustAuth(test_v3.RestfulTestCase): EXTENSION_NAME = 'revoke' EXTENSION_TO_ADD = 'revoke_extension' + def load_extra_backends(self): + return {'revoke_api': revoke.Manager()} + def config_overrides(self): super(TestTrustAuth, self).config_overrides() self.config_fixture.config( diff --git a/keystone/tests/test_v3_endpoint_policy.py b/keystone/tests/test_v3_endpoint_policy.py index 805817d65d..111fa836a8 100644 --- a/keystone/tests/test_v3_endpoint_policy.py +++ b/keystone/tests/test_v3_endpoint_policy.py @@ -14,11 +14,9 @@ from testtools import matchers -from keystone.common import dependency from keystone.tests import test_v3 -@dependency.requires('endpoint_policy_api') class TestExtensionCase(test_v3.RestfulTestCase): EXTENSION_NAME = 'endpoint_policy' diff --git a/keystone/tests/test_v3_federation.py b/keystone/tests/test_v3_federation.py index ae96569a56..61f1aeaaa5 100644 --- a/keystone/tests/test_v3_federation.py +++ b/keystone/tests/test_v3_federation.py @@ -25,8 +25,8 @@ from saml2 import sigver import xmldsig from keystone.auth import controllers as auth_controllers -from keystone.common import dependency from keystone import config +from keystone.contrib import federation from keystone.contrib.federation import controllers as federation_controllers from keystone.contrib.federation import idp as keystone_idp from keystone.contrib.federation import utils as mapping_utils @@ -48,7 +48,6 @@ def dummy_validator(*args, **kwargs): pass -@dependency.requires('federation_api') class FederationTests(test_v3.RestfulTestCase): EXTENSION_NAME = 'federation' @@ -768,6 +767,15 @@ class MappingRuleEngineTests(FederationTests): class FederatedTokenTests(FederationTests): + def load_extra_backends(self): + return {'federation_api': federation.Manager()} + + def auth_plugin_config_override(self): + methods = ['saml2'] + method_classes = {'saml2': 'keystone.auth.plugins.saml2.Saml2'} + super(FederatedTokenTests, self).auth_plugin_config_override( + methods, **method_classes) + def setUp(self): super(FederatedTokenTests, self).setUp() self._notifications = [] diff --git a/keystone/tests/test_v3_oauth1.py b/keystone/tests/test_v3_oauth1.py index a1b185ad5d..569d914c12 100644 --- a/keystone/tests/test_v3_oauth1.py +++ b/keystone/tests/test_v3_oauth1.py @@ -239,6 +239,19 @@ class ConsumerCRUDTests(OAuth1Tests): class OAuthFlowTests(OAuth1Tests): + def load_extra_backends(self): + return {'oauth_api': oauth1.Manager()} + + def auth_plugin_config_override(self): + methods = ['password', 'token', 'oauth1'] + method_classes = { + 'password': 'keystone.auth.plugins.password.Password', + 'token': 'keystone.auth.plugins.token.Token', + 'oauth1': 'keystone.auth.plugins.oauth1.OAuth', + } + super(OAuthFlowTests, self).auth_plugin_config_override( + methods, **method_classes) + def test_oauth_flow(self): consumer = self._create_single_consumer() consumer_id = consumer['id'] diff --git a/keystone/tests/test_v3_os_revoke.py b/keystone/tests/test_v3_os_revoke.py index ea8680a58c..92d0b5730e 100644 --- a/keystone/tests/test_v3_os_revoke.py +++ b/keystone/tests/test_v3_os_revoke.py @@ -17,7 +17,7 @@ from oslo.utils import timeutils import six from testtools import matchers -from keystone.common import dependency +from keystone.contrib import revoke from keystone.contrib.revoke import model from keystone.tests import test_v3 from keystone.token import provider @@ -29,7 +29,6 @@ def _future_time_string(): return timeutils.isotime(future_time) -@dependency.requires('revoke_api') class OSRevokeTests(test_v3.RestfulTestCase, test_v3.JsonHomeTestMixin): EXTENSION_NAME = 'revoke' EXTENSION_TO_ADD = 'revoke_extension' @@ -41,6 +40,9 @@ class OSRevokeTests(test_v3.RestfulTestCase, test_v3.JsonHomeTestMixin): }, } + def load_extra_backends(self): + return {'revoke_api': revoke.Manager()} + def test_get_empty_list(self): resp = self.get('/OS-REVOKE/events') self.assertEqual([], resp.json_body['events'])