Fix tests using extension drivers

The tests were assuming that extension drivers (such as federation
and revoke_api) were always loaded. These drivers were only
available because a previous test had imported the module and its
factory method is stored in global state in the dependency module.

The base Testcase is changed to not set up the saml2 and oauth1
auth plugins by default. The saml2 auth plugin depends on the
federation API which is only available when the extension is
loaded; similarly for the oauth1 auth plugin.

A new method is added to base TestCase to allow the TestCase to
provide more drivers to load during setUp. The TestCases that need
to load an optional backend make use of it.

Closes-Bug: #1408389
Change-Id: I5774fbe136849b4d1e80e64f3791dc295458e446
This commit is contained in:
Brant Knudson 2014-09-27 11:27:58 -05:00
parent 7f52036bd4
commit 9e5aa70c36
10 changed files with 67 additions and 18 deletions

View File

@ -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])

View File

@ -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.

View File

@ -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',

View File

@ -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(

View File

@ -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(

View File

@ -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(

View File

@ -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'

View File

@ -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 = []

View File

@ -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']

View File

@ -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'])