diff --git a/keystone/tests/_test_import_auth_token.py b/keystone/tests/_test_import_auth_token.py index 4e16f9a47e..25d2a9df80 100644 --- a/keystone/tests/_test_import_auth_token.py +++ b/keystone/tests/_test_import_auth_token.py @@ -8,10 +8,10 @@ """ -import unittest +import testtools -class TestAuthToken(unittest.TestCase): +class TestAuthToken(testtools.TestCase): def test_import(self): # a consuming service like nova would import oslo.config first from oslo.config import cfg diff --git a/keystone/tests/core.py b/keystone/tests/core.py index 9ecc647543..c653d5c64c 100644 --- a/keystone/tests/core.py +++ b/keystone/tests/core.py @@ -14,9 +14,9 @@ # License for the specific language governing permissions and limitations # under the License. -import datetime import errno import os +import re import shutil import socket import StringIO @@ -28,7 +28,7 @@ import nose.exc from paste import deploy import stubout -import unittest2 as unittest +import testtools from keystone.common import environment environment.use_eventlet() @@ -203,7 +203,7 @@ def find_module(self, fullname, path): sys.meta_path.insert(0, finder) -class TestCase(NoModule, unittest.TestCase): +class TestCase(NoModule, testtools.TestCase): def __init__(self, *args, **kw): super(TestCase, self).__init__(*args, **kw) self._paths = [] @@ -377,14 +377,51 @@ def assertCloseEnoughForGovernmentWork(self, a, b, delta=3): :param delta: Maximum allowable time delta, defined in seconds. """ - self.assertAlmostEqual(a, b, delta=datetime.timedelta(seconds=delta)) + msg = '%s != %s within %s delta' % (a, b, delta) + + self.assertTrue(abs(a - b).seconds <= delta, msg) def assertNotEmpty(self, l): self.assertTrue(len(l)) + def assertDictEqual(self, d1, d2, msg=None): + self.assert_(isinstance(d1, dict), 'First argument is not a dict') + self.assert_(isinstance(d2, dict), 'Second argument is not a dict') + self.assertEqual(d1, d2, msg) + + def assertRaisesRegexp(self, expected_exception, expected_regexp, + callable_obj, *args, **kwargs): + """Asserts that the message in a raised exception matches a regexp. + """ + try: + callable_obj(*args, **kwargs) + except expected_exception as exc_value: + if isinstance(expected_regexp, basestring): + expected_regexp = re.compile(expected_regexp) + if not expected_regexp.search(str(exc_value)): + raise self.failureException( + '"%s" does not match "%s"' % + (expected_regexp.pattern, str(exc_value))) + else: + if hasattr(expected_exception, '__name__'): + excName = expected_exception.__name__ + else: + excName = str(expected_exception) + raise self.failureException, "%s not raised" % excName + def assertDictContainsSubset(self, expected, actual, msg=None): """Checks whether actual is a superset of expected.""" - safe_repr = unittest.util.safe_repr + + def safe_repr(obj, short=False): + _MAX_LENGTH = 80 + try: + result = repr(obj) + except Exception: + result = object.__repr__(obj) + if not short or len(result) < _MAX_LENGTH: + return result + return result[:_MAX_LENGTH] + ' [truncated]...' + missing = [] mismatched = [] for key, value in expected.iteritems(): diff --git a/keystone/tests/test_backend.py b/keystone/tests/test_backend.py index 0b0d77c4a1..c7c5931ee7 100644 --- a/keystone/tests/test_backend.py +++ b/keystone/tests/test_backend.py @@ -2634,16 +2634,22 @@ def test_list_trusts(self): class CommonHelperTests(test.TestCase): def test_format_helper_raises_malformed_on_missing_key(self): - with self.assertRaises(exception.MalformedEndpoint): - core.format_url("http://%(foo)s/%(bar)s", {"foo": "1"}) + self.assertRaises(exception.MalformedEndpoint, + core.format_url, + "http://%(foo)s/%(bar)s", + {"foo": "1"}) def test_format_helper_raises_malformed_on_wrong_type(self): - with self.assertRaises(exception.MalformedEndpoint): - core.format_url("http://%foo%s", {"foo": "1"}) + self.assertRaises(exception.MalformedEndpoint, + core.format_url, + "http://%foo%s", + {"foo": "1"}) def test_format_helper_raises_malformed_on_incomplete_format(self): - with self.assertRaises(exception.MalformedEndpoint): - core.format_url("http://%(foo)", {"foo": "1"}) + self.assertRaises(exception.MalformedEndpoint, + core.format_url, + "http://%(foo)", + {"foo": "1"}) class CatalogTests(object): diff --git a/keystone/tests/test_backend_ldap.py b/keystone/tests/test_backend_ldap.py index 2337971216..94a977f41f 100644 --- a/keystone/tests/test_backend_ldap.py +++ b/keystone/tests/test_backend_ldap.py @@ -584,25 +584,36 @@ def test_parse_extra_attribute_mapping(self): def test_domain_crud(self): domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, 'enabled': True, 'description': uuid.uuid4().hex} - with self.assertRaises(exception.Forbidden): - self.identity_api.create_domain(domain['id'], domain) - with self.assertRaises(exception.Conflict): - self.identity_api.create_domain( - CONF.identity.default_domain_id, domain) - with self.assertRaises(exception.DomainNotFound): - self.identity_api.get_domain(domain['id']) - with self.assertRaises(exception.DomainNotFound): - domain['description'] = uuid.uuid4().hex - self.identity_api.update_domain(domain['id'], domain) - with self.assertRaises(exception.Forbidden): - self.identity_api.update_domain( - CONF.identity.default_domain_id, domain) - with self.assertRaises(exception.DomainNotFound): - self.identity_api.get_domain(domain['id']) - with self.assertRaises(exception.DomainNotFound): - self.identity_api.delete_domain(domain['id']) - with self.assertRaises(exception.Forbidden): - self.identity_api.delete_domain(CONF.identity.default_domain_id) + self.assertRaises(exception.Forbidden, + self.identity_api.create_domain, + domain['id'], + domain) + self.assertRaises(exception.Conflict, + self.identity_api.create_domain, + CONF.identity.default_domain_id, + domain) + self.assertRaises(exception.DomainNotFound, + self.identity_api.get_domain, + domain['id']) + + domain['description'] = uuid.uuid4().hex + self.assertRaises(exception.DomainNotFound, + self.identity_api.update_domain, + domain['id'], + domain) + self.assertRaises(exception.Forbidden, + self.identity_api.update_domain, + CONF.identity.default_domain_id, + domain) + self.assertRaises(exception.DomainNotFound, + self.identity_api.get_domain, + domain['id']) + self.assertRaises(exception.DomainNotFound, + self.identity_api.delete_domain, + domain['id']) + self.assertRaises(exception.Forbidden, + self.identity_api.delete_domain, + CONF.identity.default_domain_id) self.assertRaises(exception.DomainNotFound, self.identity_api.get_domain, domain['id']) @@ -770,6 +781,7 @@ def _set_config(self): test.testsdir('backend_ldap_sql.conf')]) def setUp(self): + super(LdapIdentitySqlAssignment, self).setUp() self._set_config() self.clear_database() self.load_backends() @@ -783,6 +795,7 @@ def tearDown(self): sql.ModelBase.metadata.drop_all(bind=self.engine) self.engine.dispose() sql.set_global_engine(None) + super(LdapIdentitySqlAssignment, self).tearDown() def test_domain_crud(self): pass diff --git a/keystone/tests/test_backend_memcache.py b/keystone/tests/test_backend_memcache.py index 512b4f2d68..a77fdba0b1 100644 --- a/keystone/tests/test_backend_memcache.py +++ b/keystone/tests/test_backend_memcache.py @@ -138,8 +138,8 @@ def test_list_tokens_unicode_user_id(self): self.token_api.list_tokens(user_id) def test_flush_expired_token(self): - with self.assertRaises(exception.NotImplemented): - self.token_api.flush_expired_tokens() + self.assertRaises(exception.NotImplemented, + self.token_api.flush_expired_tokens) def test_cleanup_user_index_on_create(self): valid_token_id = uuid.uuid4().hex diff --git a/keystone/tests/test_backend_sql.py b/keystone/tests/test_backend_sql.py index 24159eb604..a233435574 100644 --- a/keystone/tests/test_backend_sql.py +++ b/keystone/tests/test_backend_sql.py @@ -357,8 +357,10 @@ def test_malformed_catalog_throws_error(self): } self.catalog_api.create_endpoint(endpoint['id'], endpoint.copy()) - with self.assertRaises(exception.MalformedEndpoint): - self.catalog_api.get_catalog('fake-user', 'fake-tenant') + self.assertRaises(exception.MalformedEndpoint, + self.catalog_api.get_catalog, + 'fake-user', + 'fake-tenant') def test_get_catalog_with_empty_public_url(self): service = { @@ -403,8 +405,10 @@ def test_create_endpoint_400(self): 'url': uuid.uuid4().hex, } - with self.assertRaises(exception.StringLengthExceeded): - self.catalog_api.create_endpoint(endpoint['id'], endpoint.copy()) + self.assertRaises(exception.StringLengthExceeded, + self.catalog_api.create_endpoint, + endpoint['id'], + endpoint.copy()) class SqlPolicy(SqlTests, test_backend.PolicyTests): diff --git a/keystone/tests/test_backend_templated.py b/keystone/tests/test_backend_templated.py index 603ad82a19..d7681614f4 100644 --- a/keystone/tests/test_backend_templated.py +++ b/keystone/tests/test_backend_templated.py @@ -63,5 +63,7 @@ def test_malformed_catalog_throws_error(self): (self.catalog_api.driver.templates ['RegionOne']['compute']['adminURL']) = \ 'http://localhost:$(compute_port)s/v1.1/$(tenant)s' - with self.assertRaises(exception.MalformedEndpoint): - self.catalog_api.get_catalog('fake-user', 'fake-tenant') + self.assertRaises(exception.MalformedEndpoint, + self.catalog_api.get_catalog, + 'fake-user', + 'fake-tenant') diff --git a/keystone/tests/test_drivers.py b/keystone/tests/test_drivers.py index c6fa0c9019..70d94f5aa6 100644 --- a/keystone/tests/test_drivers.py +++ b/keystone/tests/test_drivers.py @@ -1,5 +1,5 @@ import inspect -import unittest2 as unittest +import testtools from keystone import assignment from keystone import catalog @@ -11,7 +11,7 @@ from keystone import token -class TestDrivers(unittest.TestCase): +class TestDrivers(testtools.TestCase): """Asserts that drivers are written as expected. Public methods on drivers should raise keystone.exception.NotImplemented, @@ -28,8 +28,7 @@ def assertMethodNotImplemented(self, f): args = inspect.getargspec(f).args args.remove('self') kwargs = dict(zip(args, [None] * len(args))) - with self.assertRaises(exception.NotImplemented): - f(**kwargs) + self.assertRaises(exception.NotImplemented, f, **kwargs) def assertInterfaceNotImplemented(self, interface): """Public methods on an interface class should not be implemented.""" diff --git a/keystone/tests/test_exception.py b/keystone/tests/test_exception.py index 9658ed1910..b6b1a080ff 100644 --- a/keystone/tests/test_exception.py +++ b/keystone/tests/test_exception.py @@ -28,12 +28,6 @@ class ExceptionTestCase(test.TestCase): - def setUp(self): - pass - - def tearDown(self): - pass - def assertValidJsonRendering(self, e): resp = wsgi.render_exception(e) self.assertEqual(resp.status_int, e.code) diff --git a/keystone/tests/test_injection.py b/keystone/tests/test_injection.py index 36cd0126d3..02accb5623 100644 --- a/keystone/tests/test_injection.py +++ b/keystone/tests/test_injection.py @@ -14,13 +14,13 @@ # License for the specific language governing permissions and limitations # under the License. -import unittest2 as unittest +import testtools import uuid from keystone.common import dependency -class TestDependencyInjection(unittest.TestCase): +class TestDependencyInjection(testtools.TestCase): def tearDown(self): dependency.reset() super(TestDependencyInjection, self).tearDown() @@ -167,10 +167,12 @@ def test_unresolvable_dependency(self): class Consumer(object): pass - with self.assertRaises(dependency.UnresolvableDependencyException): + def for_test(): Consumer() dependency.resolve_future_dependencies() + self.assertRaises(dependency.UnresolvableDependencyException, for_test) + def test_circular_dependency(self): p1_name = uuid.uuid4().hex p2_name = uuid.uuid4().hex diff --git a/keystone/tests/test_no_admin_token_auth.py b/keystone/tests/test_no_admin_token_auth.py index 3a7113d8b9..86424200ea 100644 --- a/keystone/tests/test_no_admin_token_auth.py +++ b/keystone/tests/test_no_admin_token_auth.py @@ -32,6 +32,7 @@ def setUp(self): def tearDown(self): self.admin_app = None os.remove(test.tmpdir('no_admin_token_auth-paste.ini')) + super(TestNoAdminTokenAuth, self).tearDown() def test_request_no_admin_token_auth(self): # This test verifies that if the admin_token_auth middleware isn't diff --git a/keystone/tests/test_policy.py b/keystone/tests/test_policy.py index bdf91c949e..5be7fc105a 100644 --- a/keystone/tests/test_policy.py +++ b/keystone/tests/test_policy.py @@ -175,7 +175,7 @@ def _set_rules(self, default_rule): common_policy.set_rules(these_rules) def tearDown(self): - super(DefaultPolicyTestCase, self).setUp() + super(DefaultPolicyTestCase, self).tearDown() rules.reset() def test_policy_called(self): diff --git a/keystone/tests/test_s3_token_middleware.py b/keystone/tests/test_s3_token_middleware.py index 2d561c10f7..8152ae7594 100644 --- a/keystone/tests/test_s3_token_middleware.py +++ b/keystone/tests/test_s3_token_middleware.py @@ -14,7 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. -import unittest2 as unittest +import testtools import webob from keystone.middleware import s3_token @@ -53,7 +53,7 @@ def request(self, method, path, **kwargs): pass -class S3TokenMiddlewareTestBase(unittest.TestCase): +class S3TokenMiddlewareTestBase(testtools.TestCase): def setUp(self): super(S3TokenMiddlewareTestBase, self).setUp() @@ -194,7 +194,7 @@ def request(self, method, path, **kwargs): self.assertEqual(resp.status_int, s3_invalid_req.status_int) -class S3TokenMiddlewareTestUtil(unittest.TestCase): +class S3TokenMiddlewareTestUtil(testtools.TestCase): def test_split_path_failed(self): self.assertRaises(ValueError, s3_token.split_path, '') self.assertRaises(ValueError, s3_token.split_path, '/') diff --git a/keystone/tests/test_v3.py b/keystone/tests/test_v3.py index b8c4c79171..7d85ecca07 100644 --- a/keystone/tests/test_v3.py +++ b/keystone/tests/test_v3.py @@ -45,6 +45,7 @@ def setUp(self, load_sample_data=True, app_conf='keystone'): load_sample_data should be set to false. """ + super(RestfulTestCase, self).setUp() self.config(self.config_files()) self.setup_database() @@ -130,15 +131,12 @@ def tearDown(self): self.public_server = None self.admin_server = None self.teardown_database() - # NOTE(morganfainberg): The only way to reconfigure the - # CacheRegion object on each setUp() call is to remove the - # .backend property. - del cache.REGION.backend # need to reset the plug-ins auth.controllers.AUTH_METHODS = {} #drop the policy rules CONF.reset() rules.reset() + super(RestfulTestCase, self).tearDown() def new_ref(self): """Populates a ref with attributes common to all API entities.""" diff --git a/keystone/tests/test_v3_identity.py b/keystone/tests/test_v3_identity.py index f1e19c4256..15bed86acd 100644 --- a/keystone/tests/test_v3_identity.py +++ b/keystone/tests/test_v3_identity.py @@ -16,7 +16,6 @@ import uuid -from keystone import config from keystone import exception import test_v3 @@ -1107,17 +1106,12 @@ def test_filtered_role_assignments(self): link_url=gp1_url) -class IdentityIneritanceTestCase(test_v3.RestfulTestCase): +class IdentityInheritanceTestCase(test_v3.RestfulTestCase): """Test inheritance crud and its effects.""" def setUp(self): - self.orig_extension_enablement = config.CONF.os_inherit.enabled self.opt_in_group('os_inherit', enabled=True) - super(IdentityIneritanceTestCase, self).setUp() - - def tearDown(self): - super(IdentityIneritanceTestCase, self).tearDown() - self.opt_in_group('os_inherit', enabled=self.orig_extension_enablement) + super(IdentityInheritanceTestCase, self).setUp() def test_crud_user_inherited_domain_role_grants(self): role_list = [] @@ -1154,28 +1148,6 @@ def test_crud_user_inherited_domain_role_grants(self): self.assertValidRoleListResponse(r, expected_length=0) self.assertIn(collection_url, r.result['links']['self']) - def test_crud_inherited_role_grants_failed_if_disabled(self): - # Disable the extension and check no API calls can be issued - self.opt_in_group('os_inherit', enabled=False) - super(IdentityIneritanceTestCase, self).setUp() - - role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} - self.assignment_api.create_role(role['id'], role) - - base_collection_url = ( - '/OS-INHERIT/domains/%(domain_id)s/users/%(user_id)s/roles' % { - 'domain_id': self.domain_id, - 'user_id': self.user['id']}) - member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { - 'collection_url': base_collection_url, - 'role_id': role['id']} - collection_url = base_collection_url + '/inherited_to_projects' - - self.put(member_url, expected_status=404) - self.head(member_url, expected_status=404) - self.get(collection_url, expected_status=404) - self.delete(member_url, expected_status=404) - def test_list_role_assignments_for_inherited_domain_grants(self): """Call ``GET /role_assignments with inherited domain grants``. @@ -1555,3 +1527,29 @@ def test_filtered_role_assignments_for_inherited_grants(self): role_id=role_list[4]['id'], inherited_to_projects=True) self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url) self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) + + +class IdentityInheritanceDisabledTestCase(test_v3.RestfulTestCase): + """Test inheritance crud and its effects.""" + + def setUp(self): + self.opt_in_group('os_inherit', enabled=False) + super(IdentityInheritanceDisabledTestCase, self).setUp() + + def test_crud_inherited_role_grants_failed_if_disabled(self): + role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.assignment_api.create_role(role['id'], role) + + base_collection_url = ( + '/OS-INHERIT/domains/%(domain_id)s/users/%(user_id)s/roles' % { + 'domain_id': self.domain_id, + 'user_id': self.user['id']}) + member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { + 'collection_url': base_collection_url, + 'role_id': role['id']} + collection_url = base_collection_url + '/inherited_to_projects' + + self.put(member_url, expected_status=404) + self.head(member_url, expected_status=404) + self.get(collection_url, expected_status=404) + self.delete(member_url, expected_status=404) diff --git a/keystone/tests/test_v3_oauth1.py b/keystone/tests/test_v3_oauth1.py index 742fd1abe3..829c3fad01 100644 --- a/keystone/tests/test_v3_oauth1.py +++ b/keystone/tests/test_v3_oauth1.py @@ -48,6 +48,7 @@ def setUp(self): def tearDown(self): os.remove(OAUTH_PASTE_FILE) + super(OAuth1Tests, self).tearDown() def _generate_paste_config(self): # Generate a file, based on keystone-paste.ini, diff --git a/test-requirements.txt b/test-requirements.txt index 223c445633..91be0d1529 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -26,8 +26,7 @@ openstack.nose_plugin nosehtmloutput # required to build documentation Sphinx>=1.1.2 -# backport of unittest lib in python 2.7 -unittest2 +testtools>=0.9.32 # test wsgi apps without starting an http server webtest