aboutsummaryrefslogtreecommitdiffstats
path: root/keystone-moon/keystone/tests
diff options
context:
space:
mode:
Diffstat (limited to 'keystone-moon/keystone/tests')
-rw-r--r--keystone-moon/keystone/tests/unit/__init__.py16
-rw-r--r--keystone-moon/keystone/tests/unit/backend/core_ldap.py8
-rw-r--r--keystone-moon/keystone/tests/unit/backend/core_sql.py6
-rw-r--r--keystone-moon/keystone/tests/unit/backend/domain_config/core.py54
-rw-r--r--keystone-moon/keystone/tests/unit/backend/role/core.py4
-rw-r--r--keystone-moon/keystone/tests/unit/backend/role/test_ldap.py6
-rw-r--r--keystone-moon/keystone/tests/unit/common/test_base64utils.py8
-rw-r--r--keystone-moon/keystone/tests/unit/common/test_injection.py4
-rw-r--r--keystone-moon/keystone/tests/unit/common/test_json_home.py4
-rw-r--r--keystone-moon/keystone/tests/unit/common/test_ldap.py18
-rw-r--r--keystone-moon/keystone/tests/unit/common/test_manager.py39
-rw-r--r--keystone-moon/keystone/tests/unit/common/test_notifications.py4
-rw-r--r--keystone-moon/keystone/tests/unit/common/test_sql_core.py4
-rw-r--r--keystone-moon/keystone/tests/unit/common/test_utils.py8
-rw-r--r--keystone-moon/keystone/tests/unit/contrib/federation/test_utils.py23
-rw-r--r--keystone-moon/keystone/tests/unit/core.py193
-rw-r--r--keystone-moon/keystone/tests/unit/identity/test_core.py8
-rw-r--r--keystone-moon/keystone/tests/unit/ksfixtures/database.py4
-rw-r--r--keystone-moon/keystone/tests/unit/mapping_fixtures.py284
-rw-r--r--keystone-moon/keystone/tests/unit/rest.py13
-rw-r--r--keystone-moon/keystone/tests/unit/test_associate_project_endpoint_extension.py110
-rw-r--r--keystone-moon/keystone/tests/unit/test_auth.py41
-rw-r--r--keystone-moon/keystone/tests/unit/test_auth_plugin.py10
-rw-r--r--keystone-moon/keystone/tests/unit/test_backend.py1019
-rw-r--r--keystone-moon/keystone/tests/unit/test_backend_kvs.py8
-rw-r--r--keystone-moon/keystone/tests/unit/test_backend_ldap.py182
-rw-r--r--keystone-moon/keystone/tests/unit/test_backend_ldap_pool.py6
-rw-r--r--keystone-moon/keystone/tests/unit/test_backend_rules.py4
-rw-r--r--keystone-moon/keystone/tests/unit/test_backend_sql.py10
-rw-r--r--keystone-moon/keystone/tests/unit/test_backend_templated.py16
-rw-r--r--keystone-moon/keystone/tests/unit/test_cache.py6
-rw-r--r--keystone-moon/keystone/tests/unit/test_cache_backend_mongo.py4
-rw-r--r--keystone-moon/keystone/tests/unit/test_catalog.py52
-rw-r--r--keystone-moon/keystone/tests/unit/test_cert_setup.py19
-rw-r--r--keystone-moon/keystone/tests/unit/test_cli.py12
-rw-r--r--keystone-moon/keystone/tests/unit/test_config.py18
-rw-r--r--keystone-moon/keystone/tests/unit/test_contrib_ec2.py4
-rw-r--r--keystone-moon/keystone/tests/unit/test_contrib_s3_core.py4
-rw-r--r--keystone-moon/keystone/tests/unit/test_contrib_simple_cert.py6
-rw-r--r--keystone-moon/keystone/tests/unit/test_exception.py4
-rw-r--r--keystone-moon/keystone/tests/unit/test_ipv6.py4
-rw-r--r--keystone-moon/keystone/tests/unit/test_kvs.py6
-rw-r--r--keystone-moon/keystone/tests/unit/test_ldap_livetest.py4
-rw-r--r--keystone-moon/keystone/tests/unit/test_ldap_pool_livetest.py5
-rw-r--r--keystone-moon/keystone/tests/unit/test_ldap_tls_livetest.py4
-rw-r--r--keystone-moon/keystone/tests/unit/test_middleware.py647
-rw-r--r--keystone-moon/keystone/tests/unit/test_no_admin_token_auth.py13
-rw-r--r--keystone-moon/keystone/tests/unit/test_policy.py14
-rw-r--r--keystone-moon/keystone/tests/unit/test_revoke.py6
-rw-r--r--keystone-moon/keystone/tests/unit/test_sql_livetest.py12
-rw-r--r--keystone-moon/keystone/tests/unit/test_sql_upgrade.py19
-rw-r--r--keystone-moon/keystone/tests/unit/test_ssl.py8
-rw-r--r--keystone-moon/keystone/tests/unit/test_token_bind.py4
-rw-r--r--keystone-moon/keystone/tests/unit/test_token_provider.py8
-rw-r--r--keystone-moon/keystone/tests/unit/test_url_middleware.py4
-rw-r--r--keystone-moon/keystone/tests/unit/test_v2.py135
-rw-r--r--keystone-moon/keystone/tests/unit/test_v2_controller.py4
-rw-r--r--keystone-moon/keystone/tests/unit/test_v2_keystoneclient.py20
-rw-r--r--keystone-moon/keystone/tests/unit/test_v3.py177
-rw-r--r--keystone-moon/keystone/tests/unit/test_v3_assignment.py179
-rw-r--r--keystone-moon/keystone/tests/unit/test_v3_auth.py548
-rw-r--r--keystone-moon/keystone/tests/unit/test_v3_catalog.py95
-rw-r--r--keystone-moon/keystone/tests/unit/test_v3_controller.py4
-rw-r--r--keystone-moon/keystone/tests/unit/test_v3_credential.py66
-rw-r--r--keystone-moon/keystone/tests/unit/test_v3_domain_config.py30
-rw-r--r--keystone-moon/keystone/tests/unit/test_v3_endpoint_policy.py61
-rw-r--r--keystone-moon/keystone/tests/unit/test_v3_federation.py293
-rw-r--r--keystone-moon/keystone/tests/unit/test_v3_identity.py74
-rw-r--r--keystone-moon/keystone/tests/unit/test_v3_oauth1.py75
-rw-r--r--keystone-moon/keystone/tests/unit/test_v3_os_revoke.py4
-rw-r--r--keystone-moon/keystone/tests/unit/test_v3_protection.py53
-rw-r--r--keystone-moon/keystone/tests/unit/test_versions.py107
-rw-r--r--keystone-moon/keystone/tests/unit/test_wsgi.py26
-rw-r--r--keystone-moon/keystone/tests/unit/tests/test_core.py10
-rw-r--r--keystone-moon/keystone/tests/unit/token/test_fernet_provider.py28
-rw-r--r--keystone-moon/keystone/tests/unit/token/test_pki_provider.py4
-rw-r--r--keystone-moon/keystone/tests/unit/token/test_pkiz_provider.py4
-rw-r--r--keystone-moon/keystone/tests/unit/token/test_token_data_helper.py4
-rw-r--r--keystone-moon/keystone/tests/unit/token/test_token_model.py1
-rw-r--r--keystone-moon/keystone/tests/unit/token/test_uuid_provider.py4
80 files changed, 3558 insertions, 1449 deletions
diff --git a/keystone-moon/keystone/tests/unit/__init__.py b/keystone-moon/keystone/tests/unit/__init__.py
index 837afe69..52af8dfc 100644
--- a/keystone-moon/keystone/tests/unit/__init__.py
+++ b/keystone-moon/keystone/tests/unit/__init__.py
@@ -13,22 +13,6 @@
# under the License.
import oslo_i18n
-import six
-
-
-if six.PY3:
- # NOTE(dstanek): This block will monkey patch libraries that are not
- # yet supported in Python3. We do this that that it is possible to
- # execute any tests at all. Without monkey patching modules the
- # tests will fail with import errors.
-
- import sys
- from unittest import mock # noqa: our import detection is naive?
-
- sys.modules['ldappool'] = mock.Mock()
- sys.modules['memcache'] = mock.Mock()
- sys.modules['oslo_messaging'] = mock.Mock()
- sys.modules['paste'] = mock.Mock()
# NOTE(dstanek): oslo_i18n.enable_lazy() must be called before
# keystone.i18n._() is called to ensure it has the desired lazy lookup
diff --git a/keystone-moon/keystone/tests/unit/backend/core_ldap.py b/keystone-moon/keystone/tests/unit/backend/core_ldap.py
index a6cd0802..869bb620 100644
--- a/keystone-moon/keystone/tests/unit/backend/core_ldap.py
+++ b/keystone-moon/keystone/tests/unit/backend/core_ldap.py
@@ -17,7 +17,7 @@ from oslo_config import cfg
from keystone.common import cache
from keystone.common import ldap as common_ldap
from keystone.common.ldap import core as common_ldap_core
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import default_fixtures
from keystone.tests.unit import fakeldap
from keystone.tests.unit.ksfixtures import database
@@ -66,7 +66,7 @@ class BaseBackendLdapCommon(object):
def config_files(self):
config_files = super(BaseBackendLdapCommon, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_ldap.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_ldap.conf'))
return config_files
def get_user_enabled_vals(self, user):
@@ -99,13 +99,13 @@ class BaseBackendLdap(object):
super(BaseBackendLdap, self).load_fixtures(fixtures)
-class BaseBackendLdapIdentitySqlEverythingElse(tests.SQLDriverOverrides):
+class BaseBackendLdapIdentitySqlEverythingElse(unit.SQLDriverOverrides):
"""Mixin base for Identity LDAP, everything else SQL backend tests."""
def config_files(self):
config_files = super(BaseBackendLdapIdentitySqlEverythingElse,
self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_ldap_sql.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_ldap_sql.conf'))
return config_files
def setUp(self):
diff --git a/keystone-moon/keystone/tests/unit/backend/core_sql.py b/keystone-moon/keystone/tests/unit/backend/core_sql.py
index 9cbd858e..8c9f4957 100644
--- a/keystone-moon/keystone/tests/unit/backend/core_sql.py
+++ b/keystone-moon/keystone/tests/unit/backend/core_sql.py
@@ -13,12 +13,12 @@
import sqlalchemy
from keystone.common import sql
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import default_fixtures
from keystone.tests.unit.ksfixtures import database
-class BaseBackendSqlTests(tests.SQLDriverOverrides, tests.TestCase):
+class BaseBackendSqlTests(unit.SQLDriverOverrides, unit.TestCase):
def setUp(self):
super(BaseBackendSqlTests, self).setUp()
@@ -32,7 +32,7 @@ class BaseBackendSqlTests(tests.SQLDriverOverrides, tests.TestCase):
def config_files(self):
config_files = super(BaseBackendSqlTests, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_sql.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_sql.conf'))
return config_files
diff --git a/keystone-moon/keystone/tests/unit/backend/domain_config/core.py b/keystone-moon/keystone/tests/unit/backend/domain_config/core.py
index c53d99b7..7bbbf313 100644
--- a/keystone-moon/keystone/tests/unit/backend/domain_config/core.py
+++ b/keystone-moon/keystone/tests/unit/backend/domain_config/core.py
@@ -17,7 +17,7 @@ import mock
from testtools import matchers
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
class DomainConfigTests(object):
@@ -523,7 +523,7 @@ class DomainConfigTests(object):
# The escaping '%' should have been removed
self.assertEqual('my_url/%(password)s', res['ldap']['url'])
- @tests.skip_if_cache_disabled('domain_config')
+ @unit.skip_if_cache_disabled('domain_config')
def test_cache_layer_get_sensitive_config(self):
config = {'ldap': {'url': uuid.uuid4().hex,
'user_tree_dn': uuid.uuid4().hex,
@@ -549,3 +549,53 @@ class DomainConfigTests(object):
{},
self.domain_config_api.get_config_with_sensitive_info(
self.domain['id']))
+
+ def test_config_registration(self):
+ type = uuid.uuid4().hex
+ self.domain_config_api.obtain_registration(
+ self.domain['id'], type)
+ self.domain_config_api.release_registration(
+ self.domain['id'], type=type)
+
+ # Make sure that once someone has it, nobody else can get it.
+ # This includes the domain who already has it.
+ self.domain_config_api.obtain_registration(
+ self.domain['id'], type)
+ self.assertFalse(
+ self.domain_config_api.obtain_registration(
+ self.domain['id'], type))
+
+ # Make sure we can read who does have it
+ self.assertEqual(
+ self.domain['id'],
+ self.domain_config_api.read_registration(type))
+
+ # Make sure releasing it is silent if the domain specified doesn't
+ # have the registration
+ domain2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex}
+ self.resource_api.create_domain(domain2['id'], domain2)
+ self.domain_config_api.release_registration(
+ domain2['id'], type=type)
+
+ # If nobody has the type registered, then trying to read it should
+ # raise ConfigRegistrationNotFound
+ self.domain_config_api.release_registration(
+ self.domain['id'], type=type)
+ self.assertRaises(exception.ConfigRegistrationNotFound,
+ self.domain_config_api.read_registration,
+ type)
+
+ # Finally check multiple registrations are cleared if you free the
+ # registration without specifying the type
+ type2 = uuid.uuid4().hex
+ self.domain_config_api.obtain_registration(
+ self.domain['id'], type)
+ self.domain_config_api.obtain_registration(
+ self.domain['id'], type2)
+ self.domain_config_api.release_registration(self.domain['id'])
+ self.assertRaises(exception.ConfigRegistrationNotFound,
+ self.domain_config_api.read_registration,
+ type)
+ self.assertRaises(exception.ConfigRegistrationNotFound,
+ self.domain_config_api.read_registration,
+ type2)
diff --git a/keystone-moon/keystone/tests/unit/backend/role/core.py b/keystone-moon/keystone/tests/unit/backend/role/core.py
index f6e47fe9..d6e0d65c 100644
--- a/keystone-moon/keystone/tests/unit/backend/role/core.py
+++ b/keystone-moon/keystone/tests/unit/backend/role/core.py
@@ -16,7 +16,7 @@ import copy
import uuid
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import default_fixtures
@@ -87,7 +87,7 @@ class RoleTests(object):
expected_role_ids = set(role['id'] for role in default_fixtures.ROLES)
self.assertEqual(expected_role_ids, role_ids)
- @tests.skip_if_cache_disabled('role')
+ @unit.skip_if_cache_disabled('role')
def test_cache_layer_role_crud(self):
role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex}
role_id = role['id']
diff --git a/keystone-moon/keystone/tests/unit/backend/role/test_ldap.py b/keystone-moon/keystone/tests/unit/backend/role/test_ldap.py
index ba4b7c6e..44f2b612 100644
--- a/keystone-moon/keystone/tests/unit/backend/role/test_ldap.py
+++ b/keystone-moon/keystone/tests/unit/backend/role/test_ldap.py
@@ -16,7 +16,7 @@ import uuid
from oslo_config import cfg
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit.backend import core_ldap
from keystone.tests.unit.backend.role import core as core_role
from keystone.tests.unit import default_fixtures
@@ -35,7 +35,7 @@ class LdapRoleCommon(core_ldap.BaseBackendLdapCommon, core_role.RoleTests):
pass
-class LdapRole(LdapRoleCommon, core_ldap.BaseBackendLdap, tests.TestCase):
+class LdapRole(LdapRoleCommon, core_ldap.BaseBackendLdap, unit.TestCase):
"""Test in an all-LDAP configuration.
Include additional tests that are unique to LDAP (or need to be overridden)
@@ -149,7 +149,7 @@ class LdapRole(LdapRoleCommon, core_ldap.BaseBackendLdap, tests.TestCase):
class LdapIdentitySqlEverythingElseRole(
core_ldap.BaseBackendLdapIdentitySqlEverythingElse, LdapRoleCommon,
- tests.TestCase):
+ unit.TestCase):
"""Test Identity in LDAP, Everything else in SQL."""
pass
diff --git a/keystone-moon/keystone/tests/unit/common/test_base64utils.py b/keystone-moon/keystone/tests/unit/common/test_base64utils.py
index b0b75578..355a2e03 100644
--- a/keystone-moon/keystone/tests/unit/common/test_base64utils.py
+++ b/keystone-moon/keystone/tests/unit/common/test_base64utils.py
@@ -13,7 +13,7 @@
# under the License.
from keystone.common import base64utils
-from keystone.tests import unit as tests
+from keystone.tests import unit
base64_alphabet = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'abcdefghijklmnopqrstuvwxyz'
@@ -26,7 +26,7 @@ base64url_alphabet = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'-_=') # includes pad char
-class TestValid(tests.BaseTestCase):
+class TestValid(unit.BaseTestCase):
def test_valid_base64(self):
self.assertTrue(base64utils.is_valid_base64('+/=='))
self.assertTrue(base64utils.is_valid_base64('+/+='))
@@ -68,7 +68,7 @@ class TestValid(tests.BaseTestCase):
self.assertTrue(base64utils.is_valid_base64url('-_=='))
-class TestBase64Padding(tests.BaseTestCase):
+class TestBase64Padding(unit.BaseTestCase):
def test_filter(self):
self.assertEqual('', base64utils.filter_formatting(''))
@@ -189,7 +189,7 @@ class TestBase64Padding(tests.BaseTestCase):
base64utils.base64url_percent_decode, 'AB%3D%3')
-class TestTextWrap(tests.BaseTestCase):
+class TestTextWrap(unit.BaseTestCase):
def test_wrapping(self):
raw_text = 'abcdefgh'
diff --git a/keystone-moon/keystone/tests/unit/common/test_injection.py b/keystone-moon/keystone/tests/unit/common/test_injection.py
index b4c23a84..9a5d1e7d 100644
--- a/keystone-moon/keystone/tests/unit/common/test_injection.py
+++ b/keystone-moon/keystone/tests/unit/common/test_injection.py
@@ -15,10 +15,10 @@
import uuid
from keystone.common import dependency
-from keystone.tests import unit as tests
+from keystone.tests import unit
-class TestDependencyInjection(tests.BaseTestCase):
+class TestDependencyInjection(unit.BaseTestCase):
def setUp(self):
super(TestDependencyInjection, self).setUp()
dependency.reset()
diff --git a/keystone-moon/keystone/tests/unit/common/test_json_home.py b/keystone-moon/keystone/tests/unit/common/test_json_home.py
index fb7f8448..94e2d138 100644
--- a/keystone-moon/keystone/tests/unit/common/test_json_home.py
+++ b/keystone-moon/keystone/tests/unit/common/test_json_home.py
@@ -18,10 +18,10 @@ import copy
from testtools import matchers
from keystone.common import json_home
-from keystone.tests import unit as tests
+from keystone.tests import unit
-class JsonHomeTest(tests.BaseTestCase):
+class JsonHomeTest(unit.BaseTestCase):
def test_build_v3_resource_relation(self):
resource_name = self.getUniqueString()
relation = json_home.build_v3_resource_relation(resource_name)
diff --git a/keystone-moon/keystone/tests/unit/common/test_ldap.py b/keystone-moon/keystone/tests/unit/common/test_ldap.py
index d3ce8cd2..e6e2c732 100644
--- a/keystone-moon/keystone/tests/unit/common/test_ldap.py
+++ b/keystone-moon/keystone/tests/unit/common/test_ldap.py
@@ -24,7 +24,7 @@ from testtools import matchers
from keystone.common import driver_hints
from keystone.common import ldap as ks_ldap
from keystone.common.ldap import core as common_ldap_core
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import default_fixtures
from keystone.tests.unit import fakeldap
@@ -32,7 +32,7 @@ from keystone.tests.unit import fakeldap
CONF = cfg.CONF
-class DnCompareTest(tests.BaseTestCase):
+class DnCompareTest(unit.BaseTestCase):
"""Tests for the DN comparison functions in keystone.common.ldap.core."""
def test_prep(self):
@@ -200,7 +200,7 @@ class DnCompareTest(tests.BaseTestCase):
self.assertTrue(ks_ldap.dn_startswith(child, parent))
-class LDAPDeleteTreeTest(tests.TestCase):
+class LDAPDeleteTreeTest(unit.TestCase):
def setUp(self):
super(LDAPDeleteTreeTest, self).setUp()
@@ -223,7 +223,7 @@ class LDAPDeleteTreeTest(tests.TestCase):
def config_files(self):
config_files = super(LDAPDeleteTreeTest, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_ldap.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_ldap.conf'))
return config_files
def test_deleteTree(self):
@@ -283,7 +283,7 @@ class LDAPDeleteTreeTest(tests.TestCase):
conn.search_s, grandchild_dn, ldap.SCOPE_BASE)
-class SslTlsTest(tests.TestCase):
+class SslTlsTest(unit.TestCase):
"""Tests for the SSL/TLS functionality in keystone.common.ldap.core."""
@mock.patch.object(ks_ldap.core.KeystoneLDAPHandler, 'simple_bind_s')
@@ -350,7 +350,7 @@ class SslTlsTest(tests.TestCase):
self.assertEqual(certdir, ldap.get_option(ldap.OPT_X_TLS_CACERTDIR))
-class LDAPPagedResultsTest(tests.TestCase):
+class LDAPPagedResultsTest(unit.TestCase):
"""Tests the paged results functionality in keystone.common.ldap.core."""
def setUp(self):
@@ -373,7 +373,7 @@ class LDAPPagedResultsTest(tests.TestCase):
def config_files(self):
config_files = super(LDAPPagedResultsTest, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_ldap.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_ldap.conf'))
return config_files
@mock.patch.object(fakeldap.FakeLdap, 'search_ext')
@@ -390,7 +390,7 @@ class LDAPPagedResultsTest(tests.TestCase):
'objectclass=*')
-class CommonLdapTestCase(tests.BaseTestCase):
+class CommonLdapTestCase(unit.BaseTestCase):
"""These test cases call functions in keystone.common.ldap."""
def test_binary_attribute_values(self):
@@ -497,7 +497,7 @@ class CommonLdapTestCase(tests.BaseTestCase):
self.assertEqual(user_name, py_result[0][1]['user_name'][0])
-class LDAPFilterQueryCompositionTest(tests.TestCase):
+class LDAPFilterQueryCompositionTest(unit.TestCase):
"""These test cases test LDAP filter generation."""
def setUp(self):
diff --git a/keystone-moon/keystone/tests/unit/common/test_manager.py b/keystone-moon/keystone/tests/unit/common/test_manager.py
new file mode 100644
index 00000000..1bc19763
--- /dev/null
+++ b/keystone-moon/keystone/tests/unit/common/test_manager.py
@@ -0,0 +1,39 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import mock
+
+from keystone import catalog
+from keystone.common import manager
+from keystone.tests import unit
+
+
+class TestCreateLegacyDriver(unit.BaseTestCase):
+
+ @mock.patch('oslo_log.versionutils.report_deprecated_feature')
+ def test_class_is_properly_deprecated(self, mock_reporter):
+ Driver = manager.create_legacy_driver(catalog.CatalogDriverV8)
+
+ # NOTE(dstanek): I want to subvert the requirement for this
+ # class to implement all of the abstractmethods.
+ Driver.__abstractmethods__ = set()
+ impl = Driver()
+
+ details = {
+ 'as_of': 'Liberty',
+ 'what': 'keystone.catalog.core.Driver',
+ 'in_favor_of': 'keystone.catalog.core.CatalogDriverV8',
+ 'remove_in': 'N',
+ }
+ mock_reporter.assert_called_with(mock.ANY, mock.ANY, details)
+
+ self.assertIsInstance(impl, catalog.CatalogDriverV8)
diff --git a/keystone-moon/keystone/tests/unit/common/test_notifications.py b/keystone-moon/keystone/tests/unit/common/test_notifications.py
index 2d872733..ec087c41 100644
--- a/keystone-moon/keystone/tests/unit/common/test_notifications.py
+++ b/keystone-moon/keystone/tests/unit/common/test_notifications.py
@@ -1007,7 +1007,7 @@ class TestCallbackRegistration(unit.BaseTestCase):
with mock.patch('keystone.notifications.LOG', self.mock_log):
notifications.register_event_callback(
- CREATED_OPERATION, 'thing', C.callback)
+ CREATED_OPERATION, 'thing', C().callback)
callback = 'keystone.tests.unit.common.test_notifications.C.callback'
expected_log_data = {
@@ -1026,7 +1026,7 @@ class TestCallbackRegistration(unit.BaseTestCase):
with mock.patch('keystone.notifications.LOG', self.mock_log):
notifications.register_event_callback(
- CREATED_OPERATION, 'thing', [callback, C.callback])
+ CREATED_OPERATION, 'thing', [callback, C().callback])
callback_1 = 'keystone.tests.unit.common.test_notifications.callback'
callback_2 = 'keystone.tests.unit.common.test_notifications.C.callback'
diff --git a/keystone-moon/keystone/tests/unit/common/test_sql_core.py b/keystone-moon/keystone/tests/unit/common/test_sql_core.py
index 1f33cfc3..b110ed08 100644
--- a/keystone-moon/keystone/tests/unit/common/test_sql_core.py
+++ b/keystone-moon/keystone/tests/unit/common/test_sql_core.py
@@ -14,7 +14,7 @@
from sqlalchemy.ext import declarative
from keystone.common import sql
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import utils
@@ -27,7 +27,7 @@ class TestModel(ModelBase, sql.ModelDictMixin):
text = sql.Column(sql.String(64), nullable=False)
-class TestModelDictMixin(tests.BaseTestCase):
+class TestModelDictMixin(unit.BaseTestCase):
def test_creating_a_model_instance_from_a_dict(self):
d = {'id': utils.new_uuid(), 'text': utils.new_uuid()}
diff --git a/keystone-moon/keystone/tests/unit/common/test_utils.py b/keystone-moon/keystone/tests/unit/common/test_utils.py
index e8bac3c0..d52eb729 100644
--- a/keystone-moon/keystone/tests/unit/common/test_utils.py
+++ b/keystone-moon/keystone/tests/unit/common/test_utils.py
@@ -20,7 +20,7 @@ from oslo_serialization import jsonutils
from keystone.common import utils as common_utils
from keystone import exception
from keystone import service
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import utils
@@ -29,7 +29,7 @@ CONF = cfg.CONF
TZ = utils.TZ
-class UtilsTestCase(tests.BaseTestCase):
+class UtilsTestCase(unit.BaseTestCase):
OPTIONAL = object()
def setUp(self):
@@ -154,11 +154,11 @@ class UtilsTestCase(tests.BaseTestCase):
self.assertEqual(expected_json, json)
-class ServiceHelperTests(tests.BaseTestCase):
+class ServiceHelperTests(unit.BaseTestCase):
@service.fail_gracefully
def _do_test(self):
raise Exception("Test Exc")
def test_fail_gracefully(self):
- self.assertRaises(tests.UnexpectedExit, self._do_test)
+ self.assertRaises(unit.UnexpectedExit, self._do_test)
diff --git a/keystone-moon/keystone/tests/unit/contrib/federation/test_utils.py b/keystone-moon/keystone/tests/unit/contrib/federation/test_utils.py
index a8b4ae76..5804f1c0 100644
--- a/keystone-moon/keystone/tests/unit/contrib/federation/test_utils.py
+++ b/keystone-moon/keystone/tests/unit/contrib/federation/test_utils.py
@@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import uuid
from keystone.auth.plugins import mapped
from keystone.contrib.federation import utils as mapping_utils
@@ -609,3 +610,25 @@ class MappingRuleEngineTests(unit.BaseTestCase):
self.assertEqual(exp_user_name, mapped_properties['user']['name'])
self.assertEqual('abc123%40example.com',
mapped_properties['user']['id'])
+
+ def test_whitelist_pass_through(self):
+ mapping = mapping_fixtures.MAPPING_GROUPS_WHITELIST_PASS_THROUGH
+ rp = mapping_utils.RuleProcessor(mapping['rules'])
+ assertion = mapping_fixtures.DEVELOPER_ASSERTION
+ mapped_properties = rp.process(assertion)
+ self.assertValidMappedUserObject(mapped_properties)
+
+ self.assertEqual('developacct', mapped_properties['user']['name'])
+ self.assertEqual('Developer',
+ mapped_properties['group_names'][0]['name'])
+
+ def test_type_not_in_assertion(self):
+ """Test that if the remote "type" is not in the assertion it fails."""
+ mapping = mapping_fixtures.MAPPING_GROUPS_WHITELIST_PASS_THROUGH
+ rp = mapping_utils.RuleProcessor(mapping['rules'])
+ assertion = {uuid.uuid4().hex: uuid.uuid4().hex}
+ mapped_properties = rp.process(assertion)
+ self.assertValidMappedUserObject(mapped_properties)
+
+ self.assertNotIn('id', mapped_properties['user'])
+ self.assertNotIn('name', mapped_properties['user'])
diff --git a/keystone-moon/keystone/tests/unit/core.py b/keystone-moon/keystone/tests/unit/core.py
index e999b641..eb8b9f65 100644
--- a/keystone-moon/keystone/tests/unit/core.py
+++ b/keystone-moon/keystone/tests/unit/core.py
@@ -14,6 +14,7 @@
from __future__ import absolute_import
import atexit
+import datetime
import functools
import logging
import os
@@ -21,18 +22,21 @@ import re
import shutil
import socket
import sys
+import uuid
import warnings
import fixtures
from oslo_config import cfg
from oslo_config import fixture as config_fixture
+from oslo_log import fixture as log_fixture
from oslo_log import log
+from oslo_utils import timeutils
import oslotest.base as oslotest
from oslotest import mockpatch
+from paste.deploy import loadwsgi
import six
from sqlalchemy import exc
from testtools import testcase
-import webob
# NOTE(ayoung)
# environment.use_eventlet must run before any of the code that will
@@ -82,6 +86,8 @@ rules.init()
IN_MEM_DB_CONN_STRING = 'sqlite://'
+TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ'
+
exception._FATAL_EXCEPTION_FORMAT_ERRORS = True
os.makedirs(TMPDIR)
atexit.register(shutil.rmtree, TMPDIR)
@@ -113,6 +119,26 @@ class dirs(object):
DEFAULT_TEST_DB_FILE = dirs.tmp('test.db')
+class EggLoader(loadwsgi.EggLoader):
+ _basket = {}
+
+ def find_egg_entry_point(self, object_type, name=None):
+ egg_key = '%s:%s' % (object_type, name)
+ egg_ep = self._basket.get(egg_key)
+ if not egg_ep:
+ egg_ep = super(EggLoader, self).find_egg_entry_point(
+ object_type, name=name)
+ self._basket[egg_key] = egg_ep
+ return egg_ep
+
+
+# NOTE(dstanek): class paths were remove from the keystone-paste.ini in
+# favor of using entry points. This caused tests to slow to a crawl
+# since we reload the application object for each RESTful test. This
+# monkey-patching adds caching to paste deploy's egg lookup.
+loadwsgi.EggLoader = EggLoader
+
+
@atexit.register
def remove_test_databases():
db = dirs.tmp('test.db')
@@ -197,39 +223,135 @@ class UnexpectedExit(Exception):
pass
-class BadLog(Exception):
- """Raised on invalid call to logging (parameter mismatch)."""
- pass
-
-
-class TestClient(object):
- def __init__(self, app=None, token=None):
- self.app = app
- self.token = token
-
- def request(self, method, path, headers=None, body=None):
- if headers is None:
- headers = {}
-
- if self.token:
- headers.setdefault('X-Auth-Token', self.token)
-
- req = webob.Request.blank(path)
- req.method = method
- for k, v in headers.items():
- req.headers[k] = v
- if body:
- req.body = body
- return req.get_response(self.app)
-
- def get(self, path, headers=None):
- return self.request('GET', path=path, headers=headers)
-
- def post(self, path, headers=None, body=None):
- return self.request('POST', path=path, headers=headers, body=body)
-
- def put(self, path, headers=None, body=None):
- return self.request('PUT', path=path, headers=headers, body=body)
+def new_ref():
+ """Populates a ref with attributes common to some API entities."""
+ return {
+ 'id': uuid.uuid4().hex,
+ 'name': uuid.uuid4().hex,
+ 'description': uuid.uuid4().hex,
+ 'enabled': True}
+
+
+def new_region_ref():
+ ref = new_ref()
+ # Region doesn't have name or enabled.
+ del ref['name']
+ del ref['enabled']
+ ref['parent_region_id'] = None
+ return ref
+
+
+def new_service_ref():
+ ref = new_ref()
+ ref['type'] = uuid.uuid4().hex
+ return ref
+
+
+def new_endpoint_ref(service_id, interface='public', default_region_id=None,
+ **kwargs):
+ ref = new_ref()
+ del ref['enabled'] # enabled is optional
+ ref['interface'] = interface
+ ref['service_id'] = service_id
+ ref['url'] = 'https://' + uuid.uuid4().hex + '.com'
+ ref['region_id'] = default_region_id
+ ref.update(kwargs)
+ return ref
+
+
+def new_domain_ref():
+ ref = new_ref()
+ return ref
+
+
+def new_project_ref(domain_id=None, parent_id=None, is_domain=False):
+ ref = new_ref()
+ ref['domain_id'] = domain_id
+ ref['parent_id'] = parent_id
+ ref['is_domain'] = is_domain
+ return ref
+
+
+def new_user_ref(domain_id, project_id=None):
+ ref = new_ref()
+ ref['domain_id'] = domain_id
+ ref['email'] = uuid.uuid4().hex
+ ref['password'] = uuid.uuid4().hex
+ if project_id:
+ ref['default_project_id'] = project_id
+ return ref
+
+
+def new_group_ref(domain_id):
+ ref = new_ref()
+ ref['domain_id'] = domain_id
+ return ref
+
+
+def new_credential_ref(user_id, project_id=None, cred_type=None):
+ ref = dict()
+ ref['id'] = uuid.uuid4().hex
+ ref['user_id'] = user_id
+ if cred_type == 'ec2':
+ ref['type'] = 'ec2'
+ ref['blob'] = uuid.uuid4().hex
+ else:
+ ref['type'] = 'cert'
+ ref['blob'] = uuid.uuid4().hex
+ if project_id:
+ ref['project_id'] = project_id
+ return ref
+
+
+def new_role_ref():
+ ref = new_ref()
+ # Roles don't have a description or the enabled flag
+ del ref['description']
+ del ref['enabled']
+ return ref
+
+
+def new_policy_ref():
+ ref = new_ref()
+ ref['blob'] = uuid.uuid4().hex
+ ref['type'] = uuid.uuid4().hex
+ return ref
+
+
+def new_trust_ref(trustor_user_id, trustee_user_id, project_id=None,
+ impersonation=None, expires=None, role_ids=None,
+ role_names=None, remaining_uses=None,
+ allow_redelegation=False):
+ ref = dict()
+ ref['id'] = uuid.uuid4().hex
+ ref['trustor_user_id'] = trustor_user_id
+ ref['trustee_user_id'] = trustee_user_id
+ ref['impersonation'] = impersonation or False
+ ref['project_id'] = project_id
+ ref['remaining_uses'] = remaining_uses
+ ref['allow_redelegation'] = allow_redelegation
+
+ if isinstance(expires, six.string_types):
+ ref['expires_at'] = expires
+ elif isinstance(expires, dict):
+ ref['expires_at'] = (
+ timeutils.utcnow() + datetime.timedelta(**expires)
+ ).strftime(TIME_FORMAT)
+ elif expires is None:
+ pass
+ else:
+ raise NotImplementedError('Unexpected value for "expires"')
+
+ role_ids = role_ids or []
+ role_names = role_names or []
+ if role_ids or role_names:
+ ref['roles'] = []
+ for role_id in role_ids:
+ ref['roles'].append({'id': role_id})
+ for role_name in role_names:
+ ref['roles'].append({'name': role_name})
+
+ return ref
class BaseTestCase(oslotest.BaseTestCase):
@@ -245,8 +367,7 @@ class BaseTestCase(oslotest.BaseTestCase):
super(BaseTestCase, self).setUp()
self.useFixture(mockpatch.PatchObject(sys, 'exit',
side_effect=UnexpectedExit))
- self.useFixture(mockpatch.PatchObject(logging.Handler, 'handleError',
- side_effect=BadLog))
+ self.useFixture(log_fixture.get_logging_handle_error_fixture())
warnings.filterwarnings('error', category=DeprecationWarning,
module='^keystone\\.')
diff --git a/keystone-moon/keystone/tests/unit/identity/test_core.py b/keystone-moon/keystone/tests/unit/identity/test_core.py
index fa95ec50..e9845401 100644
--- a/keystone-moon/keystone/tests/unit/identity/test_core.py
+++ b/keystone-moon/keystone/tests/unit/identity/test_core.py
@@ -22,20 +22,20 @@ from oslo_config import fixture as config_fixture
from keystone import exception
from keystone import identity
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit.ksfixtures import database
CONF = cfg.CONF
-class TestDomainConfigs(tests.BaseTestCase):
+class TestDomainConfigs(unit.BaseTestCase):
def setUp(self):
super(TestDomainConfigs, self).setUp()
self.addCleanup(CONF.reset)
- self.tmp_dir = tests.dirs.tmp()
+ self.tmp_dir = unit.dirs.tmp()
self.config_fixture = self.useFixture(config_fixture.Config(CONF))
self.config_fixture.config(domain_config_dir=self.tmp_dir,
@@ -125,7 +125,7 @@ class TestDomainConfigs(tests.BaseTestCase):
self.assertEqual(3, load_driver_mock.call_count)
-class TestDatabaseDomainConfigs(tests.TestCase):
+class TestDatabaseDomainConfigs(unit.TestCase):
def setUp(self):
super(TestDatabaseDomainConfigs, self).setUp()
diff --git a/keystone-moon/keystone/tests/unit/ksfixtures/database.py b/keystone-moon/keystone/tests/unit/ksfixtures/database.py
index 0012df74..6f23a99d 100644
--- a/keystone-moon/keystone/tests/unit/ksfixtures/database.py
+++ b/keystone-moon/keystone/tests/unit/ksfixtures/database.py
@@ -19,7 +19,7 @@ from oslo_config import cfg
from oslo_db import options as db_options
from keystone.common import sql
-from keystone.tests import unit as tests
+from keystone.tests import unit
CONF = cfg.CONF
@@ -47,7 +47,7 @@ def initialize_sql_session():
# test cases.
db_options.set_defaults(
CONF,
- connection=tests.IN_MEM_DB_CONN_STRING)
+ connection=unit.IN_MEM_DB_CONN_STRING)
@run_once
diff --git a/keystone-moon/keystone/tests/unit/mapping_fixtures.py b/keystone-moon/keystone/tests/unit/mapping_fixtures.py
index f86d9245..94b07133 100644
--- a/keystone-moon/keystone/tests/unit/mapping_fixtures.py
+++ b/keystone-moon/keystone/tests/unit/mapping_fixtures.py
@@ -901,6 +901,290 @@ MAPPING_GROUPS_WHITELIST_AND_BLACKLIST = {
]
}
+# Mapping used by tokenless test cases, it maps the user_name
+# and domain_name.
+MAPPING_WITH_USERNAME_AND_DOMAINNAME = {
+ 'rules': [
+ {
+ 'local': [
+ {
+ 'user': {
+ 'name': '{0}',
+ 'domain': {
+ 'name': '{1}'
+ },
+ 'type': 'local'
+ }
+ }
+ ],
+ 'remote': [
+ {
+ 'type': 'SSL_CLIENT_USER_NAME'
+ },
+ {
+ 'type': 'SSL_CLIENT_DOMAIN_NAME'
+ }
+ ]
+ }
+ ]
+}
+
+# Mapping used by tokenless test cases, it maps the user_id
+# and domain_name.
+MAPPING_WITH_USERID_AND_DOMAINNAME = {
+ 'rules': [
+ {
+ 'local': [
+ {
+ 'user': {
+ 'id': '{0}',
+ 'domain': {
+ 'name': '{1}'
+ },
+ 'type': 'local'
+ }
+ }
+ ],
+ 'remote': [
+ {
+ 'type': 'SSL_CLIENT_USER_ID'
+ },
+ {
+ 'type': 'SSL_CLIENT_DOMAIN_NAME'
+ }
+ ]
+ }
+ ]
+}
+
+# Mapping used by tokenless test cases, it maps the user_name
+# and domain_id.
+MAPPING_WITH_USERNAME_AND_DOMAINID = {
+ 'rules': [
+ {
+ 'local': [
+ {
+ 'user': {
+ 'name': '{0}',
+ 'domain': {
+ 'id': '{1}'
+ },
+ 'type': 'local'
+ }
+ }
+ ],
+ 'remote': [
+ {
+ 'type': 'SSL_CLIENT_USER_NAME'
+ },
+ {
+ 'type': 'SSL_CLIENT_DOMAIN_ID'
+ }
+ ]
+ }
+ ]
+}
+
+# Mapping used by tokenless test cases, it maps the user_id
+# and domain_id.
+MAPPING_WITH_USERID_AND_DOMAINID = {
+ 'rules': [
+ {
+ 'local': [
+ {
+ 'user': {
+ 'id': '{0}',
+ 'domain': {
+ 'id': '{1}'
+ },
+ 'type': 'local'
+ }
+ }
+ ],
+ 'remote': [
+ {
+ 'type': 'SSL_CLIENT_USER_ID'
+ },
+ {
+ 'type': 'SSL_CLIENT_DOMAIN_ID'
+ }
+ ]
+ }
+ ]
+}
+
+# Mapping used by tokenless test cases, it maps the domain_id only.
+MAPPING_WITH_DOMAINID_ONLY = {
+ 'rules': [
+ {
+ 'local': [
+ {
+ 'user': {
+ 'domain': {
+ 'id': '{0}'
+ },
+ 'type': 'local'
+ }
+ }
+ ],
+ 'remote': [
+ {
+ 'type': 'SSL_CLIENT_DOMAIN_ID'
+ }
+ ]
+ }
+ ]
+}
+
+# Mapping used by tokenless test cases, it maps the domain_name only.
+MAPPING_WITH_DOMAINNAME_ONLY = {
+ 'rules': [
+ {
+ 'local': [
+ {
+ 'user': {
+ 'domain': {
+ 'name': '{0}'
+ },
+ 'type': 'local'
+ }
+ }
+ ],
+ 'remote': [
+ {
+ 'type': 'SSL_CLIENT_DOMAIN_NAME'
+ }
+ ]
+ }
+ ]
+}
+
+# Mapping used by tokenless test cases, it maps the user_name only.
+MAPPING_WITH_USERNAME_ONLY = {
+ 'rules': [
+ {
+ 'local': [
+ {
+ 'user': {
+ 'name': '{0}',
+ 'type': 'local'
+ }
+ }
+ ],
+ 'remote': [
+ {
+ 'type': 'SSL_CLIENT_USER_NAME'
+ }
+ ]
+ }
+ ]
+}
+
+# Mapping used by tokenless test cases, it maps the user_id only.
+MAPPING_WITH_USERID_ONLY = {
+ 'rules': [
+ {
+ 'local': [
+ {
+ 'user': {
+ 'id': '{0}',
+ 'type': 'local'
+ }
+ }
+ ],
+ 'remote': [
+ {
+ 'type': 'SSL_CLIENT_USER_ID'
+ }
+ ]
+ }
+ ]
+}
+
+MAPPING_FOR_EPHEMERAL_USER = {
+ 'rules': [
+ {
+ 'local': [
+ {
+ 'user': {
+ 'name': '{0}',
+ 'type': 'ephemeral'
+ },
+ 'group': {
+ 'id': 'dummy'
+ }
+ }
+ ],
+ 'remote': [
+ {
+ 'type': 'SSL_CLIENT_USER_NAME'
+ }
+ ]
+ }
+ ]
+}
+
+MAPPING_FOR_DEFAULT_EPHEMERAL_USER = {
+ 'rules': [
+ {
+ 'local': [
+ {
+ 'user': {
+ 'name': '{0}'
+ },
+ 'group': {
+ 'id': 'dummy'
+ }
+ }
+ ],
+ 'remote': [
+ {
+ 'type': 'SSL_CLIENT_USER_NAME'
+ }
+ ]
+ }
+ ]
+}
+
+MAPPING_GROUPS_WHITELIST_PASS_THROUGH = {
+ "rules": [
+ {
+ "remote": [
+ {
+ "type": "UserName"
+ }
+ ],
+ "local": [
+ {
+ "user": {
+ "name": "{0}",
+ "domain": {
+ "id": DEVELOPER_GROUP_DOMAIN_ID
+ }
+ }
+ }
+ ]
+ },
+ {
+ "remote": [
+ {
+ "type": "orgPersonType",
+ "whitelist": ['Developer']
+ }
+ ],
+ "local": [
+ {
+ "groups": "{0}",
+ "domain": {
+ "id": DEVELOPER_GROUP_DOMAIN_ID
+ }
+ }
+ ]
+ }
+ ]
+}
+
+
EMPLOYEE_ASSERTION = {
'Email': 'tim@example.com',
'UserName': 'tbo',
diff --git a/keystone-moon/keystone/tests/unit/rest.py b/keystone-moon/keystone/tests/unit/rest.py
index bfa52354..da24019f 100644
--- a/keystone-moon/keystone/tests/unit/rest.py
+++ b/keystone-moon/keystone/tests/unit/rest.py
@@ -13,15 +13,16 @@
# under the License.
from oslo_serialization import jsonutils
+from six.moves import http_client
import webtest
from keystone.auth import controllers as auth_controllers
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import default_fixtures
from keystone.tests.unit.ksfixtures import database
-class RestfulTestCase(tests.TestCase):
+class RestfulTestCase(unit.TestCase):
"""Performs restful tests against the WSGI app over HTTP.
This class launches public & admin WSGI servers for every test, which can
@@ -113,7 +114,7 @@ class RestfulTestCase(tests.TestCase):
example::
- self.assertResponseStatus(response, 204)
+ self.assertResponseStatus(response, http_client.NO_CONTENT)
"""
self.assertEqual(
response.status_code,
@@ -125,7 +126,8 @@ class RestfulTestCase(tests.TestCase):
"""Ensures that response headers appear as expected."""
self.assertIn('X-Auth-Token', response.headers.get('Vary'))
- def assertValidErrorResponse(self, response, expected_status=400):
+ def assertValidErrorResponse(self, response,
+ expected_status=http_client.BAD_REQUEST):
"""Verify that the error response is valid.
Subclasses can override this function based on the expected response.
@@ -184,7 +186,8 @@ class RestfulTestCase(tests.TestCase):
self._from_content_type(response, content_type=response_content_type)
# we can save some code & improve coverage by always doing this
- if method != 'HEAD' and response.status_code >= 400:
+ if (method != 'HEAD' and
+ response.status_code >= http_client.BAD_REQUEST):
self.assertValidErrorResponse(response)
# Contains the decoded response.body
diff --git a/keystone-moon/keystone/tests/unit/test_associate_project_endpoint_extension.py b/keystone-moon/keystone/tests/unit/test_associate_project_endpoint_extension.py
index 9cde704e..4c574549 100644
--- a/keystone-moon/keystone/tests/unit/test_associate_project_endpoint_extension.py
+++ b/keystone-moon/keystone/tests/unit/test_associate_project_endpoint_extension.py
@@ -15,6 +15,7 @@
import copy
import uuid
+from six.moves import http_client
from testtools import matchers
from keystone.tests.unit import test_v3
@@ -47,8 +48,7 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
Valid endpoint and project id test case.
"""
- self.put(self.default_request_url,
- expected_status=204)
+ self.put(self.default_request_url)
def test_create_endpoint_project_association_with_invalid_project(self):
"""PUT OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id}
@@ -60,7 +60,7 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
'/endpoints/%(endpoint_id)s' % {
'project_id': uuid.uuid4().hex,
'endpoint_id': self.endpoint_id},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_create_endpoint_project_association_with_invalid_endpoint(self):
"""PUT /OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id}
@@ -72,7 +72,7 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
'/endpoints/%(endpoint_id)s' % {
'project_id': self.default_domain_project_id,
'endpoint_id': uuid.uuid4().hex},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_create_endpoint_project_association_with_unexpected_body(self):
"""PUT /OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id}
@@ -81,8 +81,7 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
"""
self.put(self.default_request_url,
- body={'project_id': self.default_domain_project_id},
- expected_status=204)
+ body={'project_id': self.default_domain_project_id})
def test_check_endpoint_project_association(self):
"""HEAD /OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id}
@@ -90,13 +89,11 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
Valid project and endpoint id test case.
"""
- self.put(self.default_request_url,
- expected_status=204)
+ self.put(self.default_request_url)
self.head('/OS-EP-FILTER/projects/%(project_id)s'
'/endpoints/%(endpoint_id)s' % {
'project_id': self.default_domain_project_id,
- 'endpoint_id': self.endpoint_id},
- expected_status=204)
+ 'endpoint_id': self.endpoint_id})
def test_check_endpoint_project_association_with_invalid_project(self):
"""HEAD /OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id}
@@ -109,7 +106,7 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
'/endpoints/%(endpoint_id)s' % {
'project_id': uuid.uuid4().hex,
'endpoint_id': self.endpoint_id},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_check_endpoint_project_association_with_invalid_endpoint(self):
"""HEAD /OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id}
@@ -122,7 +119,7 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
'/endpoints/%(endpoint_id)s' % {
'project_id': self.default_domain_project_id,
'endpoint_id': uuid.uuid4().hex},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_list_endpoints_associated_with_valid_project(self):
"""GET /OS-EP-FILTER/projects/{project_id}/endpoints
@@ -146,7 +143,7 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
self.put(self.default_request_url)
self.get('/OS-EP-FILTER/projects/%(project_id)s/endpoints' % {
'project_id': uuid.uuid4().hex},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_list_projects_associated_with_endpoint(self):
"""GET /OS-EP-FILTER/endpoints/{endpoint_id}/projects
@@ -168,8 +165,7 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
"""
r = self.get('/OS-EP-FILTER/endpoints/%(endpoint_id)s/projects' %
- {'endpoint_id': self.endpoint_id},
- expected_status=200)
+ {'endpoint_id': self.endpoint_id})
self.assertValidProjectListResponse(r, expected_length=0)
def test_list_projects_associated_with_invalid_endpoint(self):
@@ -180,7 +176,7 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
"""
self.get('/OS-EP-FILTER/endpoints/%(endpoint_id)s/projects' %
{'endpoint_id': uuid.uuid4().hex},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_remove_endpoint_project_association(self):
"""DELETE /OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id}
@@ -192,8 +188,7 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
self.delete('/OS-EP-FILTER/projects/%(project_id)s'
'/endpoints/%(endpoint_id)s' % {
'project_id': self.default_domain_project_id,
- 'endpoint_id': self.endpoint_id},
- expected_status=204)
+ 'endpoint_id': self.endpoint_id})
def test_remove_endpoint_project_association_with_invalid_project(self):
"""DELETE /OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id}
@@ -206,7 +201,7 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
'/endpoints/%(endpoint_id)s' % {
'project_id': uuid.uuid4().hex,
'endpoint_id': self.endpoint_id},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_remove_endpoint_project_association_with_invalid_endpoint(self):
"""DELETE /OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id}
@@ -219,32 +214,32 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
'/endpoints/%(endpoint_id)s' % {
'project_id': self.default_domain_project_id,
'endpoint_id': uuid.uuid4().hex},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_endpoint_project_association_cleanup_when_project_deleted(self):
self.put(self.default_request_url)
association_url = ('/OS-EP-FILTER/endpoints/%(endpoint_id)s/projects' %
{'endpoint_id': self.endpoint_id})
- r = self.get(association_url, expected_status=200)
+ r = self.get(association_url)
self.assertValidProjectListResponse(r, expected_length=1)
self.delete('/projects/%(project_id)s' % {
'project_id': self.default_domain_project_id})
- r = self.get(association_url, expected_status=200)
+ r = self.get(association_url)
self.assertValidProjectListResponse(r, expected_length=0)
def test_endpoint_project_association_cleanup_when_endpoint_deleted(self):
self.put(self.default_request_url)
association_url = '/OS-EP-FILTER/projects/%(project_id)s/endpoints' % {
'project_id': self.default_domain_project_id}
- r = self.get(association_url, expected_status=200)
+ r = self.get(association_url)
self.assertValidEndpointListResponse(r, expected_length=1)
self.delete('/endpoints/%(endpoint_id)s' % {
'endpoint_id': self.endpoint_id})
- r = self.get(association_url, expected_status=200)
+ r = self.get(association_url)
self.assertValidEndpointListResponse(r, expected_length=0)
@@ -275,8 +270,7 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
self.put('/OS-EP-FILTER/projects/%(project_id)s'
'/endpoints/%(endpoint_id)s' % {
'project_id': project['id'],
- 'endpoint_id': self.endpoint_id},
- expected_status=204)
+ 'endpoint_id': self.endpoint_id})
# attempt to authenticate without requesting a project
auth_data = self.build_authentication_request(
@@ -296,8 +290,7 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
self.put('/OS-EP-FILTER/projects/%(project_id)s'
'/endpoints/%(endpoint_id)s' % {
'project_id': self.project['id'],
- 'endpoint_id': self.endpoint_id},
- expected_status=204)
+ 'endpoint_id': self.endpoint_id})
auth_data = self.build_authentication_request(
user_id=self.user['id'],
@@ -317,8 +310,7 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
self.put('/OS-EP-FILTER/projects/%(project_id)s'
'/endpoints/%(endpoint_id)s' % {
'project_id': self.project['id'],
- 'endpoint_id': self.endpoint_id},
- expected_status=204)
+ 'endpoint_id': self.endpoint_id})
auth_data = self.build_authentication_request(
user_id=self.user['id'],
@@ -337,8 +329,7 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
self.put('/OS-EP-FILTER/projects/%(project_id)s'
'/endpoints/%(endpoint_id)s' % {
'project_id': self.project['id'],
- 'endpoint_id': self.endpoint_id},
- expected_status=204)
+ 'endpoint_id': self.endpoint_id})
# create a second temporary endpoint
self.endpoint_id2 = uuid.uuid4().hex
@@ -352,8 +343,7 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
self.put('/OS-EP-FILTER/projects/%(project_id)s'
'/endpoints/%(endpoint_id)s' % {
'project_id': self.project['id'],
- 'endpoint_id': self.endpoint_id2},
- expected_status=204)
+ 'endpoint_id': self.endpoint_id2})
# remove the temporary reference
# this will create inconsistency in the endpoint filter table
@@ -379,8 +369,7 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
self.put('/OS-EP-FILTER/projects/%(project_id)s'
'/endpoints/%(endpoint_id)s' % {
'project_id': self.project['id'],
- 'endpoint_id': self.endpoint_id},
- expected_status=204)
+ 'endpoint_id': self.endpoint_id})
# Add a disabled endpoint to the default project.
@@ -398,8 +387,7 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
self.put('/OS-EP-FILTER/projects/%(project_id)s'
'/endpoints/%(endpoint_id)s' % {
'project_id': self.project['id'],
- 'endpoint_id': disabled_endpoint_id},
- expected_status=204)
+ 'endpoint_id': disabled_endpoint_id})
# Authenticate to get token with catalog
auth_data = self.build_authentication_request(
@@ -428,13 +416,11 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
self.put('/OS-EP-FILTER/projects/%(project_id)s'
'/endpoints/%(endpoint_id)s' % {
'project_id': self.project['id'],
- 'endpoint_id': endpoint_id1},
- expected_status=204)
+ 'endpoint_id': endpoint_id1})
self.put('/OS-EP-FILTER/projects/%(project_id)s'
'/endpoints/%(endpoint_id)s' % {
'project_id': self.project['id'],
- 'endpoint_id': endpoint_id2},
- expected_status=204)
+ 'endpoint_id': endpoint_id2})
# there should be only two endpoints in token catalog
auth_data = self.build_authentication_request(
@@ -453,8 +439,7 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
self.put('/OS-EP-FILTER/projects/%(project_id)s'
'/endpoints/%(endpoint_id)s' % {
'project_id': self.project['id'],
- 'endpoint_id': self.endpoint_id},
- expected_status=204)
+ 'endpoint_id': self.endpoint_id})
auth_data = self.build_authentication_request(
user_id=self.user['id'],
@@ -589,7 +574,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
invalid_body['endpoint_group']['filters'] = {'foobar': 'admin'}
self.post(self.DEFAULT_ENDPOINT_GROUP_URL,
body=invalid_body,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_get_endpoint_group(self):
"""GET /OS-EP-FILTER/endpoint_groups/{endpoint_group}
@@ -624,7 +609,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
endpoint_group_id = 'foobar'
url = '/OS-EP-FILTER/endpoint_groups/%(endpoint_group_id)s' % {
'endpoint_group_id': endpoint_group_id}
- self.get(url, expected_status=404)
+ self.get(url, expected_status=http_client.NOT_FOUND)
def test_check_endpoint_group(self):
"""HEAD /OS-EP-FILTER/endpoint_groups/{endpoint_group_id}
@@ -637,7 +622,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
self.DEFAULT_ENDPOINT_GROUP_URL, self.DEFAULT_ENDPOINT_GROUP_BODY)
url = '/OS-EP-FILTER/endpoint_groups/%(endpoint_group_id)s' % {
'endpoint_group_id': endpoint_group_id}
- self.head(url, expected_status=200)
+ self.head(url, expected_status=http_client.OK)
def test_check_invalid_endpoint_group(self):
"""HEAD /OS-EP-FILTER/endpoint_groups/{endpoint_group_id}
@@ -648,7 +633,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
endpoint_group_id = 'foobar'
url = '/OS-EP-FILTER/endpoint_groups/%(endpoint_group_id)s' % {
'endpoint_group_id': endpoint_group_id}
- self.head(url, expected_status=404)
+ self.head(url, expected_status=http_client.NOT_FOUND)
def test_patch_endpoint_group(self):
"""PATCH /OS-EP-FILTER/endpoint_groups/{endpoint_group}
@@ -685,7 +670,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
}
url = '/OS-EP-FILTER/endpoint_groups/%(endpoint_group_id)s' % {
'endpoint_group_id': 'ABC'}
- self.patch(url, body=body, expected_status=404)
+ self.patch(url, body=body, expected_status=http_client.NOT_FOUND)
def test_patch_invalid_endpoint_group(self):
"""PATCH /OS-EP-FILTER/endpoint_groups/{endpoint_group}
@@ -707,7 +692,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
self.DEFAULT_ENDPOINT_GROUP_URL, self.DEFAULT_ENDPOINT_GROUP_BODY)
url = '/OS-EP-FILTER/endpoint_groups/%(endpoint_group_id)s' % {
'endpoint_group_id': endpoint_group_id}
- self.patch(url, body=body, expected_status=400)
+ self.patch(url, body=body, expected_status=http_client.BAD_REQUEST)
# Perform a GET call to ensure that the content remains
# the same (as DEFAULT_ENDPOINT_GROUP_BODY) after attempting to update
@@ -731,7 +716,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
url = '/OS-EP-FILTER/endpoint_groups/%(endpoint_group_id)s' % {
'endpoint_group_id': endpoint_group_id}
self.delete(url)
- self.get(url, expected_status=404)
+ self.get(url, expected_status=http_client.NOT_FOUND)
def test_delete_invalid_endpoint_group(self):
"""GET /OS-EP-FILTER/endpoint_groups/{endpoint_group}
@@ -742,7 +727,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
endpoint_group_id = 'foobar'
url = '/OS-EP-FILTER/endpoint_groups/%(endpoint_group_id)s' % {
'endpoint_group_id': endpoint_group_id}
- self.delete(url, expected_status=404)
+ self.delete(url, expected_status=http_client.NOT_FOUND)
def test_add_endpoint_group_to_project(self):
"""Create a valid endpoint group and project association."""
@@ -761,7 +746,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
project_id = uuid.uuid4().hex
url = self._get_project_endpoint_group_url(
endpoint_group_id, project_id)
- self.put(url, expected_status=404)
+ self.put(url, expected_status=http_client.NOT_FOUND)
def test_get_endpoint_group_in_project(self):
"""Test retrieving project endpoint group association."""
@@ -787,7 +772,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
project_id = uuid.uuid4().hex
url = self._get_project_endpoint_group_url(
endpoint_group_id, project_id)
- self.get(url, expected_status=404)
+ self.get(url, expected_status=http_client.NOT_FOUND)
def test_list_endpoint_groups_in_project(self):
"""GET /OS-EP-FILTER/projects/{project_id}/endpoint_groups."""
@@ -813,7 +798,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
project_id = uuid.uuid4().hex
url = ('/OS-EP-FILTER/projects/%(project_id)s/endpoint_groups' %
{'project_id': project_id})
- self.get(url, expected_status=404)
+ self.get(url, expected_status=http_client.NOT_FOUND)
def test_empty_endpoint_groups_in_project(self):
"""Test when no endpoint groups associated with the project."""
@@ -831,7 +816,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
self.project_id)
url = self._get_project_endpoint_group_url(
endpoint_group_id, self.project_id)
- self.head(url, expected_status=200)
+ self.head(url, expected_status=http_client.OK)
def test_check_endpoint_group_to_project_with_invalid_project_id(self):
"""Test HEAD with an invalid endpoint group and project association."""
@@ -848,7 +833,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
project_id = uuid.uuid4().hex
url = self._get_project_endpoint_group_url(
endpoint_group_id, project_id)
- self.head(url, expected_status=404)
+ self.head(url, expected_status=http_client.NOT_FOUND)
def test_list_endpoint_groups(self):
"""GET /OS-EP-FILTER/endpoint_groups."""
@@ -992,7 +977,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
# endpoint group association again
self.delete('/projects/%(project_id)s' % {
'project_id': project['id']})
- self.get(url, expected_status=404)
+ self.get(url, expected_status=http_client.NOT_FOUND)
def test_endpoint_group_project_cleanup_with_endpoint_group(self):
# create endpoint group
@@ -1012,7 +997,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
# now remove the project endpoint group association
self.delete(url)
- self.get(url, expected_status=404)
+ self.get(url, expected_status=http_client.NOT_FOUND)
def test_removing_an_endpoint_group_project(self):
# create an endpoint group
@@ -1026,7 +1011,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
# remove the endpoint group project
self.delete(url)
- self.get(url, expected_status=404)
+ self.get(url, expected_status=http_client.NOT_FOUND)
def test_remove_endpoint_group_with_project_association(self):
# create an endpoint group
@@ -1044,8 +1029,9 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
'%(endpoint_group_id)s'
% {'endpoint_group_id': endpoint_group_id})
self.delete(endpoint_group_url)
- self.get(endpoint_group_url, expected_status=404)
- self.get(project_endpoint_group_url, expected_status=404)
+ self.get(endpoint_group_url, expected_status=http_client.NOT_FOUND)
+ self.get(project_endpoint_group_url,
+ expected_status=http_client.NOT_FOUND)
def _create_valid_endpoint_group(self, url, body):
r = self.post(url, body=body)
diff --git a/keystone-moon/keystone/tests/unit/test_auth.py b/keystone-moon/keystone/tests/unit/test_auth.py
index f253b02d..6dd52c8a 100644
--- a/keystone-moon/keystone/tests/unit/test_auth.py
+++ b/keystone-moon/keystone/tests/unit/test_auth.py
@@ -29,7 +29,7 @@ from keystone.common import authorization
from keystone import config
from keystone import exception
from keystone.models import token_model
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import default_fixtures
from keystone.tests.unit.ksfixtures import database
from keystone import token
@@ -72,7 +72,7 @@ def _build_user_auth(token=None, user_id=None, username=None,
return auth_json
-class AuthTest(tests.TestCase):
+class AuthTest(unit.TestCase):
def setUp(self):
self.useFixture(database.Database())
super(AuthTest, self).setUp()
@@ -460,6 +460,37 @@ class AuthWithToken(AuthTest):
dict(is_admin=True, query_string={}),
token_id=token_id)
+ def test_deleting_role_assignment_does_not_revoke_unscoped_token(self):
+ no_context = {}
+ admin_context = dict(is_admin=True, query_string={})
+
+ project = {
+ 'id': uuid.uuid4().hex,
+ 'name': uuid.uuid4().hex,
+ 'domain_id': DEFAULT_DOMAIN_ID}
+ self.resource_api.create_project(project['id'], project)
+ role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex}
+ self.role_api.create_role(role['id'], role)
+ self.assignment_api.add_role_to_user_and_project(
+ self.user_foo['id'], project['id'], role['id'])
+
+ # Get an unscoped token.
+ token = self.controller.authenticate(no_context, _build_user_auth(
+ username=self.user_foo['name'],
+ password=self.user_foo['password']))
+ token_id = token['access']['token']['id']
+
+ # Ensure it is valid
+ self.controller.validate_token(admin_context, token_id=token_id)
+
+ # Delete the role assignment, which should not invalidate the token,
+ # because we're not consuming it with just an unscoped token.
+ self.assignment_api.remove_role_from_user_and_project(
+ self.user_foo['id'], project['id'], role['id'])
+
+ # Ensure it is still valid
+ self.controller.validate_token(admin_context, token_id=token_id)
+
def test_only_original_audit_id_is_kept(self):
context = {}
@@ -1285,14 +1316,14 @@ class TokenExpirationTest(AuthTest):
self._maintain_token_expiration()
-class AuthCatalog(tests.SQLDriverOverrides, AuthTest):
+class AuthCatalog(unit.SQLDriverOverrides, AuthTest):
"""Tests for the catalog provided in the auth response."""
def config_files(self):
config_files = super(AuthCatalog, self).config_files()
# We need to use a backend that supports disabled endpoints, like the
# SQL backend.
- config_files.append(tests.dirs.tests_conf('backend_sql.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_sql.conf'))
return config_files
def _create_endpoints(self):
@@ -1402,7 +1433,7 @@ class AuthCatalog(tests.SQLDriverOverrides, AuthTest):
self.assertEqual(exp_endpoint, endpoint)
-class NonDefaultAuthTest(tests.TestCase):
+class NonDefaultAuthTest(unit.TestCase):
def test_add_non_default_auth_method(self):
self.config_fixture.config(group='auth',
diff --git a/keystone-moon/keystone/tests/unit/test_auth_plugin.py b/keystone-moon/keystone/tests/unit/test_auth_plugin.py
index a259cc2a..8dd22aa8 100644
--- a/keystone-moon/keystone/tests/unit/test_auth_plugin.py
+++ b/keystone-moon/keystone/tests/unit/test_auth_plugin.py
@@ -18,7 +18,7 @@ import mock
from keystone import auth
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
# for testing purposes only
@@ -37,7 +37,7 @@ class SimpleChallengeResponse(auth.AuthMethodHandler):
return {"challenge": "What's the name of your high school?"}
-class TestAuthPlugin(tests.SQLDriverOverrides, tests.TestCase):
+class TestAuthPlugin(unit.SQLDriverOverrides, unit.TestCase):
def setUp(self):
super(TestAuthPlugin, self).setUp()
self.load_backends()
@@ -121,11 +121,11 @@ class TestAuthPluginDynamicOptions(TestAuthPlugin):
def config_files(self):
config_files = super(TestAuthPluginDynamicOptions, self).config_files()
- config_files.append(tests.dirs.tests_conf('test_auth_plugin.conf'))
+ config_files.append(unit.dirs.tests_conf('test_auth_plugin.conf'))
return config_files
-class TestMapped(tests.TestCase):
+class TestMapped(unit.TestCase):
def setUp(self):
super(TestMapped, self).setUp()
self.load_backends()
@@ -134,7 +134,7 @@ class TestMapped(tests.TestCase):
def config_files(self):
config_files = super(TestMapped, self).config_files()
- config_files.append(tests.dirs.tests_conf('test_auth_plugin.conf'))
+ config_files.append(unit.dirs.tests_conf('test_auth_plugin.conf'))
return config_files
def auth_plugin_config_override(self, methods=None, **method_classes):
diff --git a/keystone-moon/keystone/tests/unit/test_backend.py b/keystone-moon/keystone/tests/unit/test_backend.py
index 45b8e0b0..d3b51edd 100644
--- a/keystone-moon/keystone/tests/unit/test_backend.py
+++ b/keystone-moon/keystone/tests/unit/test_backend.py
@@ -28,7 +28,7 @@ from testtools import matchers
from keystone.catalog import core
from keystone.common import driver_hints
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import default_fixtures
from keystone.tests.unit import filtering
from keystone.tests.unit import utils as test_utils
@@ -40,7 +40,379 @@ DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id
NULL_OBJECT = object()
-class IdentityTests(object):
+class AssignmentTestHelperMixin(object):
+ """Mixin class to aid testing of assignments.
+
+ This class supports data driven test plans that enable:
+
+ - Creation of initial entities, such as domains, users, groups, projects
+ and roles
+ - Creation of assignments referencing the above entities
+ - A set of input parameters and expected outputs to list_role_assignments
+ based on the above test data
+
+ A test plan is a dict of the form:
+
+ test_plan = {
+ entities: details and number of entities,
+ group_memberships: group-user entity memberships,
+ assignments: list of assignments to create,
+ tests: list of pairs of input params and expected outputs}
+
+ An example test plan:
+
+ test_plan = {
+ # First, create the entities required. Entities are specified by
+ # a dict with the key being the entity type and the value an
+ # entity specification which can be one of:
+ #
+ # - a simple number, e.g. {'users': 3} creates 3 users
+ # - a dict where more information regarding the contents of the entity
+ # is required, e.g. {'domains' : {'users : 3}} creates a domain
+ # with three users
+ # - a list of entity specifications if multiple are required
+ #
+ # The following creates a domain that contains a single user, group and
+ # project, as well as creating three roles.
+
+ 'entities': {'domains': {'users': 1, 'groups': 1, 'projects': 1},
+ 'roles': 3},
+
+ # If it is required that an existing domain be used for the new
+ # entities, then the id of that domain can be included in the
+ # domain dict. For example, if alternatively we wanted to add 3 users
+ # to the default domain, add a second domain containing 3 projects as
+ # well as 5 additional empty domains, the entities would be defined as:
+ #
+ # 'entities': {'domains': [{'id': DEFAULT_DOMAIN, 'users': 3},
+ # {'projects': 3}, 5]},
+ #
+ # A project hierarchy can be specified within the 'projects' section by
+ # nesting the 'project' key, for example to create a project with three
+ # sub-projects you would use:
+
+ 'projects': {'project': 3}
+
+ # A more complex hierarchy can also be defined, for example the
+ # following would define three projects each containing a
+ # sub-project, each of which contain a further three sub-projects.
+
+ 'projects': [{'project': {'project': 3}},
+ {'project': {'project': 3}},
+ {'project': {'project': 3}}]
+
+ # A list of groups and their members. In this case make users with
+ # index 0 and 1 members of group with index 0. Users and Groups are
+ # indexed in the order they appear in the 'entities' key above.
+
+ 'group_memberships': [{'group': 0, 'users': [0, 1]}]
+
+ # Next, create assignments between the entities, referencing the
+ # entities by index, i.e. 'user': 0 refers to user[0]. Entities are
+ # indexed in the order they appear in the 'entities' key above within
+ # their entity type.
+
+ 'assignments': [{'user': 0, 'role': 0, 'domain': 0},
+ {'user': 0, 'role': 1, 'project': 0},
+ {'group': 0, 'role': 2, 'domain': 0},
+ {'user': 0, 'role': 2, 'project': 0}],
+
+ # Finally, define an array of tests where list_role_assignment() is
+ # called with the given input parameters and the results are then
+ # confirmed to be as given in 'results'. Again, all entities are
+ # referenced by index.
+
+ 'tests': [
+ {'params': {},
+ 'results': [{'user': 0, 'role': 0, 'domain': 0},
+ {'user': 0, 'role': 1, 'project': 0},
+ {'group': 0, 'role': 2, 'domain': 0},
+ {'user': 0, 'role': 2, 'project': 0}]},
+ {'params': {'role': 2},
+ 'results': [{'group': 0, 'role': 2, 'domain': 0},
+ {'user': 0, 'role': 2, 'project': 0}]}]
+
+ # The 'params' key also supports the 'effective' and
+ # 'inherited_to_projects' options to list_role_assignments.}
+
+ """
+ def _handle_project_spec(self, test_data, domain_id, project_spec,
+ parent_id=None):
+ """Handle the creation of a project or hierarchy of projects.
+
+ project_spec may either be a count of the number of projects to
+ create, or it may be a list of the form:
+
+ [{'project': project_spec}, {'project': project_spec}, ...]
+
+ This method is called recursively to handle the creation of a
+ hierarchy of projects.
+
+ """
+ def _create_project(domain_id, parent_id):
+ new_project = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex,
+ 'domain_id': domain_id, 'parent_id': parent_id}
+ new_project = self.resource_api.create_project(new_project['id'],
+ new_project)
+ return new_project
+
+ if isinstance(project_spec, list):
+ for this_spec in project_spec:
+ self._handle_project_spec(
+ test_data, domain_id, this_spec, parent_id=parent_id)
+ elif isinstance(project_spec, dict):
+ new_proj = _create_project(domain_id, parent_id)
+ test_data['projects'].append(new_proj)
+ self._handle_project_spec(
+ test_data, domain_id, project_spec['project'],
+ parent_id=new_proj['id'])
+ else:
+ for _ in range(project_spec):
+ test_data['projects'].append(
+ _create_project(domain_id, parent_id))
+
+ def _handle_domain_spec(self, test_data, domain_spec):
+ """Handle the creation of domains and their contents.
+
+ domain_spec may either be a count of the number of empty domains to
+ create, a dict describing the domain contents, or a list of
+ domain_specs.
+
+ In the case when a list is provided, this method calls itself
+ recursively to handle the list elements.
+
+ This method will insert any entities created into test_data
+
+ """
+ def _create_domain(domain_id=None):
+ if domain_id is None:
+ new_domain = {'id': uuid.uuid4().hex,
+ 'name': uuid.uuid4().hex}
+ self.resource_api.create_domain(new_domain['id'],
+ new_domain)
+ return new_domain
+ else:
+ # The test plan specified an existing domain to use
+ return self.resource_api.get_domain(domain_id)
+
+ def _create_entity_in_domain(entity_type, domain_id):
+ """Create a user or group entity in the domain."""
+
+ new_entity = {'name': uuid.uuid4().hex, 'domain_id': domain_id}
+ if entity_type == 'users':
+ new_entity = self.identity_api.create_user(new_entity)
+ elif entity_type == 'groups':
+ new_entity = self.identity_api.create_group(new_entity)
+ else:
+ # Must be a bad test plan
+ raise exception.NotImplemented()
+ return new_entity
+
+ if isinstance(domain_spec, list):
+ for x in domain_spec:
+ self._handle_domain_spec(test_data, x)
+ elif isinstance(domain_spec, dict):
+ # If there is a domain ID specified, then use it
+ the_domain = _create_domain(domain_spec.get('id'))
+ test_data['domains'].append(the_domain)
+ for entity_type, value in domain_spec.items():
+ if entity_type == 'id':
+ # We already used this above to determine whether to
+ # use and existing domain
+ continue
+ if entity_type == 'projects':
+ # If it's projects, we need to handle the potential
+ # specification of a project hierarchy
+ self._handle_project_spec(
+ test_data, the_domain['id'], value)
+ else:
+ # It's a count of number of entities
+ for _ in range(value):
+ test_data[entity_type].append(
+ _create_entity_in_domain(
+ entity_type, the_domain['id']))
+ else:
+ for _ in range(domain_spec):
+ test_data['domains'].append(_create_domain())
+
+ def create_entities(self, entity_pattern):
+ """Create the entities specified in the test plan.
+
+ Process the 'entities' key in the test plan, creating the requested
+ entities. Each created entity will be added to the array of entities
+ stored in the returned test_data object, e.g.:
+
+ test_data['users'] = [user[0], user[1]....]
+
+ """
+ def _create_role():
+ new_role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex}
+ return self.role_api.create_role(new_role['id'], new_role)
+
+ test_data = {}
+ for entity in ['users', 'groups', 'domains', 'projects', 'roles']:
+ test_data[entity] = []
+
+ # Create any domains requested and, if specified, any entities within
+ # those domains
+ if 'domains' in entity_pattern:
+ self._handle_domain_spec(test_data, entity_pattern['domains'])
+
+ # Create any roles requested
+ if 'roles' in entity_pattern:
+ for _ in range(entity_pattern['roles']):
+ test_data['roles'].append(_create_role())
+
+ return test_data
+
+ def _convert_entity_shorthand(self, key, shorthand_data, reference_data):
+ """Convert a shorthand entity description into a full ID reference.
+
+ In test plan definitions, we allow a shorthand for referencing to an
+ entity of the form:
+
+ 'user': 0
+
+ which is actually shorthand for:
+
+ 'user_id': reference_data['users'][0]['id']
+
+ This method converts the shorthand version into the full reference.
+
+ """
+ expanded_key = '%s_id' % key
+ reference_index = '%ss' % key
+ index_value = (
+ reference_data[reference_index][shorthand_data[key]]['id'])
+ return expanded_key, index_value
+
+ def create_group_memberships(self, group_pattern, test_data):
+ """Create the group memberships specified in the test plan."""
+
+ for group_spec in group_pattern:
+ # Each membership specification is a dict of the form:
+ #
+ # {'group': 0, 'users': [list of user indexes]}
+ #
+ # Add all users in the list to the specified group, first
+ # converting from index to full entity ID.
+ group_value = test_data['groups'][group_spec['group']]['id']
+ for user_index in group_spec['users']:
+ user_value = test_data['users'][user_index]['id']
+ self.identity_api.add_user_to_group(user_value, group_value)
+ return test_data
+
+ def create_assignments(self, assignment_pattern, test_data):
+ """Create the assignments specified in the test plan."""
+
+ # First store how many assignments are already in the system,
+ # so during the tests we can check the number of new assignments
+ # created.
+ test_data['initial_assignment_count'] = (
+ len(self.assignment_api.list_role_assignments()))
+
+ # Now create the new assignments in the test plan
+ for assignment in assignment_pattern:
+ # Each assignment is a dict of the form:
+ #
+ # { 'user': 0, 'project':1, 'role': 6}
+ #
+ # where the value of each item is the index into the array of
+ # entities created earlier.
+ #
+ # We process the assignment dict to create the args required to
+ # make the create_grant() call.
+ args = {}
+ for param in assignment:
+ if param == 'inherited_to_projects':
+ args[param] = assignment[param]
+ else:
+ # Turn 'entity : 0' into 'entity_id = ac6736ba873d'
+ # where entity in user, group, project or domain
+ key, value = self._convert_entity_shorthand(
+ param, assignment, test_data)
+ args[key] = value
+ self.assignment_api.create_grant(**args)
+ return test_data
+
+ def execute_assignment_tests(self, test_plan, test_data):
+ """Execute the test plan, based on the created test_data."""
+
+ def check_results(expected, actual, param_arg_count):
+ if param_arg_count == 0:
+ # It was an unfiltered call, so default fixture assignments
+ # might be polluting our answer - so we take into account
+ # how many assignments there were before the test.
+ self.assertEqual(
+ len(expected) + test_data['initial_assignment_count'],
+ len(actual))
+ else:
+ self.assertThat(actual, matchers.HasLength(len(expected)))
+
+ for each_expected in expected:
+ expected_assignment = {}
+ for param in each_expected:
+ if param == 'inherited_to_projects':
+ expected_assignment[param] = each_expected[param]
+ elif param == 'indirect':
+ # We're expecting the result to contain an indirect
+ # dict with the details how the role came to be placed
+ # on this entity - so convert the key/value pairs of
+ # that dict into real entity references.
+ indirect_term = {}
+ for indirect_param in each_expected[param]:
+ key, value = self._convert_entity_shorthand(
+ indirect_param, each_expected[param],
+ test_data)
+ indirect_term[key] = value
+ expected_assignment[param] = indirect_term
+ else:
+ # Convert a simple shorthand entry into a full
+ # entity reference
+ key, value = self._convert_entity_shorthand(
+ param, each_expected, test_data)
+ expected_assignment[key] = value
+ self.assertIn(expected_assignment, actual)
+
+ # Go through each test in the array, processing the input params, which
+ # we build into an args dict, and then call list_role_assignments. Then
+ # check the results against those specified in the test plan.
+ for test in test_plan.get('tests', []):
+ args = {}
+ for param in test['params']:
+ if param in ['effective', 'inherited']:
+ # Just pass the value into the args
+ args[param] = test['params'][param]
+ else:
+ # Turn 'entity : 0' into 'entity_id = ac6736ba873d'
+ # where entity in user, group, project or domain
+ key, value = self._convert_entity_shorthand(
+ param, test['params'], test_data)
+ args[key] = value
+ results = self.assignment_api.list_role_assignments(**args)
+ check_results(test['results'], results, len(args))
+
+ def execute_assignment_test_plan(self, test_plan):
+ """Create entities, assignments and execute the test plan.
+
+ The standard method to call to create entities and assignments and
+ execute the tests as specified in the test_plan. The test_data
+ dict is returned so that, if required, the caller can execute
+ additional manual tests with the entities and assignments created.
+
+ """
+ test_data = self.create_entities(test_plan['entities'])
+ if 'group_memberships' in test_plan:
+ self.create_group_memberships(test_plan['group_memberships'],
+ test_data)
+ if 'assignments' in test_plan:
+ test_data = self.create_assignments(test_plan['assignments'],
+ test_data)
+ self.execute_assignment_tests(test_plan, test_data)
+ return test_data
+
+
+class IdentityTests(AssignmentTestHelperMixin):
def _get_domain_fixture(self):
domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex}
self.resource_api.create_domain(domain['id'], domain)
@@ -227,7 +599,7 @@ class IdentityTests(object):
self.user_foo.pop('password')
self.assertDictEqual(user_ref, self.user_foo)
- @tests.skip_if_cache_disabled('identity')
+ @unit.skip_if_cache_disabled('identity')
def test_cache_layer_get_user(self):
user = {
'name': uuid.uuid4().hex.lower(),
@@ -279,7 +651,7 @@ class IdentityTests(object):
self.user_foo.pop('password')
self.assertDictEqual(user_ref, self.user_foo)
- @tests.skip_if_cache_disabled('identity')
+ @unit.skip_if_cache_disabled('identity')
def test_cache_layer_get_user_by_name(self):
user = {
'name': uuid.uuid4().hex.lower(),
@@ -506,168 +878,83 @@ class IdentityTests(object):
'fake2')
def test_list_role_assignments_unfiltered(self):
- """Test unfiltered listing of role assignments.
-
- Test Plan:
-
- - Create a domain, with a user, group & project
- - Find how many role assignments already exist (from default
- fixtures)
- - Create a grant of each type (user/group on project/domain)
- - Check the number of assignments has gone up by 4 and that
- the entries we added are in the list returned
- - Check that if we list assignments by role_id, then we get back
- assignments that only contain that role.
-
- """
- new_domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex}
- self.resource_api.create_domain(new_domain['id'], new_domain)
- new_user = {'name': uuid.uuid4().hex, 'password': uuid.uuid4().hex,
- 'enabled': True, 'domain_id': new_domain['id']}
- new_user = self.identity_api.create_user(new_user)
- new_group = {'domain_id': new_domain['id'], 'name': uuid.uuid4().hex}
- new_group = self.identity_api.create_group(new_group)
- new_project = {'id': uuid.uuid4().hex,
- 'name': uuid.uuid4().hex,
- 'domain_id': new_domain['id']}
- self.resource_api.create_project(new_project['id'], new_project)
-
- # First check how many role grants already exist
- existing_assignments = len(self.assignment_api.list_role_assignments())
-
- # Now create the grants (roles are defined in default_fixtures)
- self.assignment_api.create_grant(user_id=new_user['id'],
- domain_id=new_domain['id'],
- role_id='member')
- self.assignment_api.create_grant(user_id=new_user['id'],
- project_id=new_project['id'],
- role_id='other')
- self.assignment_api.create_grant(group_id=new_group['id'],
- domain_id=new_domain['id'],
- role_id='admin')
- self.assignment_api.create_grant(group_id=new_group['id'],
- project_id=new_project['id'],
- role_id='admin')
-
- # Read back the full list of assignments - check it is gone up by 4
- assignment_list = self.assignment_api.list_role_assignments()
- self.assertEqual(existing_assignments + 4, len(assignment_list))
-
- # Now check that each of our four new entries are in the list
- self.assertIn(
- {'user_id': new_user['id'], 'domain_id': new_domain['id'],
- 'role_id': 'member'},
- assignment_list)
- self.assertIn(
- {'user_id': new_user['id'], 'project_id': new_project['id'],
- 'role_id': 'other'},
- assignment_list)
- self.assertIn(
- {'group_id': new_group['id'], 'domain_id': new_domain['id'],
- 'role_id': 'admin'},
- assignment_list)
- self.assertIn(
- {'group_id': new_group['id'], 'project_id': new_project['id'],
- 'role_id': 'admin'},
- assignment_list)
+ """Test unfiltered listing of role assignments."""
+
+ test_plan = {
+ # Create a domain, with a user, group & project
+ 'entities': {'domains': {'users': 1, 'groups': 1, 'projects': 1},
+ 'roles': 3},
+ # Create a grant of each type (user/group on project/domain)
+ 'assignments': [{'user': 0, 'role': 0, 'domain': 0},
+ {'user': 0, 'role': 1, 'project': 0},
+ {'group': 0, 'role': 2, 'domain': 0},
+ {'group': 0, 'role': 2, 'project': 0}],
+ 'tests': [
+ # Check that we get back the 4 assignments
+ {'params': {},
+ 'results': [{'user': 0, 'role': 0, 'domain': 0},
+ {'user': 0, 'role': 1, 'project': 0},
+ {'group': 0, 'role': 2, 'domain': 0},
+ {'group': 0, 'role': 2, 'project': 0}]}
+ ]
+ }
+ self.execute_assignment_test_plan(test_plan)
def test_list_role_assignments_filtered_by_role(self):
- """Test listing of role assignments filtered by role ID.
-
- Test Plan:
-
- - Create a user, group & project
- - Find how many role assignments already exist (from default
- fixtures)
- - Create a grant of each type (user/group on project/domain)
- - Check that if we list assignments by role_id, then we get back
- assignments that only contain that role.
-
- """
- new_user = {'name': uuid.uuid4().hex, 'password': uuid.uuid4().hex,
- 'enabled': True, 'domain_id': DEFAULT_DOMAIN_ID}
- new_user = self.identity_api.create_user(new_user)
- new_group = {'domain_id': DEFAULT_DOMAIN_ID, 'name': uuid.uuid4().hex}
- new_group = self.identity_api.create_group(new_group)
- new_project = {'id': uuid.uuid4().hex,
- 'name': uuid.uuid4().hex,
- 'domain_id': DEFAULT_DOMAIN_ID}
- self.resource_api.create_project(new_project['id'], new_project)
-
- # First check how many role grants already exist
- existing_assignments_for_role = len(
- self.assignment_api.list_role_assignments_for_role(
- role_id='admin'))
-
- # Now create the grants (roles are defined in default_fixtures)
- self.assignment_api.create_grant(user_id=new_user['id'],
- domain_id=DEFAULT_DOMAIN_ID,
- role_id='member')
- self.assignment_api.create_grant(user_id=new_user['id'],
- project_id=new_project['id'],
- role_id='other')
- self.assignment_api.create_grant(group_id=new_group['id'],
- domain_id=DEFAULT_DOMAIN_ID,
- role_id='admin')
- self.assignment_api.create_grant(group_id=new_group['id'],
- project_id=new_project['id'],
- role_id='admin')
+ """Test listing of role assignments filtered by role ID."""
+
+ test_plan = {
+ # Create a user, group & project in the default domain
+ 'entities': {'domains': {'id': DEFAULT_DOMAIN_ID,
+ 'users': 1, 'groups': 1, 'projects': 1},
+ 'roles': 3},
+ # Create a grant of each type (user/group on project/domain)
+ 'assignments': [{'user': 0, 'role': 0, 'domain': 0},
+ {'user': 0, 'role': 1, 'project': 0},
+ {'group': 0, 'role': 2, 'domain': 0},
+ {'group': 0, 'role': 2, 'project': 0}],
+ 'tests': [
+ # Check that when filtering by role, we only get back those
+ # that match
+ {'params': {'role': 2},
+ 'results': [{'group': 0, 'role': 2, 'domain': 0},
+ {'group': 0, 'role': 2, 'project': 0}]}
+ ]
+ }
+ test_data = self.execute_assignment_test_plan(test_plan)
- # Read back the list of assignments for just the admin role, checking
- # this only goes up by two.
+ # Also test that list_role_assignments_for_role() gives the same answer
assignment_list = self.assignment_api.list_role_assignments_for_role(
- role_id='admin')
- self.assertEqual(existing_assignments_for_role + 2,
- len(assignment_list))
+ role_id=test_data['roles'][2]['id'])
+ self.assertThat(assignment_list, matchers.HasLength(2))
# Now check that each of our two new entries are in the list
self.assertIn(
- {'group_id': new_group['id'], 'domain_id': DEFAULT_DOMAIN_ID,
- 'role_id': 'admin'},
+ {'group_id': test_data['groups'][0]['id'],
+ 'domain_id': DEFAULT_DOMAIN_ID,
+ 'role_id': test_data['roles'][2]['id']},
assignment_list)
self.assertIn(
- {'group_id': new_group['id'], 'project_id': new_project['id'],
- 'role_id': 'admin'},
+ {'group_id': test_data['groups'][0]['id'],
+ 'project_id': test_data['projects'][0]['id'],
+ 'role_id': test_data['roles'][2]['id']},
assignment_list)
def test_list_group_role_assignment(self):
# When a group role assignment is created and the role assignments are
# listed then the group role assignment is included in the list.
- MEMBER_ROLE_ID = 'member'
-
- def get_member_assignments():
- assignments = self.assignment_api.list_role_assignments()
- return [x for x in assignments if x['role_id'] == MEMBER_ROLE_ID]
-
- orig_member_assignments = get_member_assignments()
-
- # Create a group.
- new_group = {
- 'domain_id': DEFAULT_DOMAIN_ID,
- 'name': self.getUniqueString(prefix='tlgra')}
- new_group = self.identity_api.create_group(new_group)
-
- # Create a project.
- new_project = {
- 'id': uuid.uuid4().hex,
- 'name': self.getUniqueString(prefix='tlgra'),
- 'domain_id': DEFAULT_DOMAIN_ID}
- self.resource_api.create_project(new_project['id'], new_project)
-
- # Assign a role to the group.
- self.assignment_api.create_grant(
- group_id=new_group['id'], project_id=new_project['id'],
- role_id=MEMBER_ROLE_ID)
-
- # List role assignments
- new_member_assignments = get_member_assignments()
-
- expected_member_assignments = orig_member_assignments + [{
- 'group_id': new_group['id'], 'project_id': new_project['id'],
- 'role_id': MEMBER_ROLE_ID}]
- self.assertItemsEqual(expected_member_assignments,
- new_member_assignments)
+ test_plan = {
+ 'entities': {'domains': {'id': DEFAULT_DOMAIN_ID,
+ 'groups': 1, 'projects': 1},
+ 'roles': 1},
+ 'assignments': [{'group': 0, 'role': 0, 'project': 0}],
+ 'tests': [
+ {'params': {},
+ 'results': [{'group': 0, 'role': 0, 'project': 0}]}
+ ]
+ }
+ self.execute_assignment_test_plan(test_plan)
def test_list_role_assignments_bad_role(self):
assignment_list = self.assignment_api.list_role_assignments_for_role(
@@ -1695,6 +1982,82 @@ class IdentityTests(object):
self.identity_api.delete_group(group1['id'])
self.identity_api.get_user(user1['id'])
+ def test_list_role_assignment_by_domain(self):
+ """Test listing of role assignment filtered by domain."""
+
+ test_plan = {
+ # A domain with 3 users, 1 group, a spoiler domain and 2 roles.
+ 'entities': {'domains': [{'users': 3, 'groups': 1}, 1],
+ 'roles': 2},
+ # Users 1 & 2 are in the group
+ 'group_memberships': [{'group': 0, 'users': [1, 2]}],
+ # Assign a role for user 0 and the group
+ 'assignments': [{'user': 0, 'role': 0, 'domain': 0},
+ {'group': 0, 'role': 1, 'domain': 0}],
+ 'tests': [
+ # List all effective assignments for domain[0].
+ # Should get one direct user role and user roles for each of
+ # the users in the group.
+ {'params': {'domain': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 0, 'domain': 0},
+ {'user': 1, 'role': 1, 'domain': 0,
+ 'indirect': {'group': 0}},
+ {'user': 2, 'role': 1, 'domain': 0,
+ 'indirect': {'group': 0}}
+ ]},
+ # Using domain[1] should return nothing
+ {'params': {'domain': 1, 'effective': True},
+ 'results': []},
+ ]
+ }
+ self.execute_assignment_test_plan(test_plan)
+
+ def test_list_role_assignment_by_user_with_domain_group_roles(self):
+ """Test listing assignments by user, with group roles on a domain."""
+
+ test_plan = {
+ # A domain with 3 users, 3 groups, a spoiler domain
+ # plus 3 roles.
+ 'entities': {'domains': [{'users': 3, 'groups': 3}, 1],
+ 'roles': 3},
+ # Users 1 & 2 are in the group 0, User 1 also in group 1
+ 'group_memberships': [{'group': 0, 'users': [0, 1]},
+ {'group': 1, 'users': [0]}],
+ 'assignments': [{'user': 0, 'role': 0, 'domain': 0},
+ {'group': 0, 'role': 1, 'domain': 0},
+ {'group': 1, 'role': 2, 'domain': 0},
+ # ...and two spoiler assignments
+ {'user': 1, 'role': 1, 'domain': 0},
+ {'group': 2, 'role': 2, 'domain': 0}],
+ 'tests': [
+ # List all effective assignments for user[0].
+ # Should get one direct user role and a user roles for each of
+ # groups 0 and 1
+ {'params': {'user': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 0, 'domain': 0},
+ {'user': 0, 'role': 1, 'domain': 0,
+ 'indirect': {'group': 0}},
+ {'user': 0, 'role': 2, 'domain': 0,
+ 'indirect': {'group': 1}}
+ ]},
+ # Adding domain[0] as a filter should return the same data
+ {'params': {'user': 0, 'domain': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 0, 'domain': 0},
+ {'user': 0, 'role': 1, 'domain': 0,
+ 'indirect': {'group': 0}},
+ {'user': 0, 'role': 2, 'domain': 0,
+ 'indirect': {'group': 1}}
+ ]},
+ # Using domain[1] should return nothing
+ {'params': {'user': 0, 'domain': 1, 'effective': True},
+ 'results': []},
+ # Using user[2] should return nothing
+ {'params': {'user': 2, 'domain': 0, 'effective': True},
+ 'results': []},
+ ]
+ }
+ self.execute_assignment_test_plan(test_plan)
+
def test_delete_domain_with_user_group_project_links(self):
# TODO(chungg):add test case once expected behaviour defined
pass
@@ -2162,7 +2525,7 @@ class IdentityTests(object):
self.assertIn(self.tenant_mtu['id'], project_ids)
self.assertIn(self.tenant_service['id'], project_ids)
- @tests.skip_if_no_multiple_domains_support
+ @unit.skip_if_no_multiple_domains_support
def test_list_projects_for_alternate_domain(self):
domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex}
self.resource_api.create_domain(domain1['id'], domain1)
@@ -2219,7 +2582,7 @@ class IdentityTests(object):
return projects
- @tests.skip_if_no_multiple_domains_support
+ @unit.skip_if_no_multiple_domains_support
def test_create_domain_with_project_api(self):
project_id = uuid.uuid4().hex
project = {'id': project_id,
@@ -2233,7 +2596,7 @@ class IdentityTests(object):
self.assertTrue(ref['is_domain'])
self.assertEqual(DEFAULT_DOMAIN_ID, ref['domain_id'])
- @tests.skip_if_no_multiple_domains_support
+ @unit.skip_if_no_multiple_domains_support
@test_utils.wip('waiting for projects acting as domains implementation')
def test_is_domain_sub_project_has_parent_domain_id(self):
project = {'id': uuid.uuid4().hex,
@@ -2258,7 +2621,7 @@ class IdentityTests(object):
self.assertEqual(project['id'], ref['parent_id'])
self.assertEqual(project['id'], ref['domain_id'])
- @tests.skip_if_no_multiple_domains_support
+ @unit.skip_if_no_multiple_domains_support
@test_utils.wip('waiting for projects acting as domains implementation')
def test_delete_domain_with_project_api(self):
project_id = uuid.uuid4().hex
@@ -2283,7 +2646,7 @@ class IdentityTests(object):
# Successfuly delete the project
self.resource_api.delete_project(project['id'])
- @tests.skip_if_no_multiple_domains_support
+ @unit.skip_if_no_multiple_domains_support
@test_utils.wip('waiting for projects acting as domains implementation')
def test_create_domain_under_regular_project_hierarchy_fails(self):
# Creating a regular project hierarchy. Projects acting as domains
@@ -2303,7 +2666,7 @@ class IdentityTests(object):
self.resource_api.create_project,
project['id'], project)
- @tests.skip_if_no_multiple_domains_support
+ @unit.skip_if_no_multiple_domains_support
@test_utils.wip('waiting for projects acting as domains implementation')
def test_create_project_under_domain_hierarchy(self):
projects_hierarchy = self._create_projects_hierarchy(is_domain=True)
@@ -2917,7 +3280,7 @@ class IdentityTests(object):
uuid.uuid4().hex,
DEFAULT_DOMAIN_ID)
- @tests.skip_if_cache_disabled('identity')
+ @unit.skip_if_cache_disabled('identity')
def test_cache_layer_group_crud(self):
group = {'domain_id': DEFAULT_DOMAIN_ID, 'name': uuid.uuid4().hex}
group = self.identity_api.create_group(group)
@@ -2992,7 +3355,7 @@ class IdentityTests(object):
group1['id'],
group1)
- @tests.skip_if_no_multiple_domains_support
+ @unit.skip_if_no_multiple_domains_support
def test_project_crud(self):
domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex,
'enabled': True}
@@ -3093,7 +3456,7 @@ class IdentityTests(object):
project['id'],
project)
- @tests.skip_if_no_multiple_domains_support
+ @unit.skip_if_no_multiple_domains_support
def test_create_leaf_project_with_different_domain(self):
root_project = {'id': uuid.uuid4().hex,
'name': uuid.uuid4().hex,
@@ -3308,7 +3671,7 @@ class IdentityTests(object):
self.resource_api.get_domain,
domain['id'])
- @tests.skip_if_no_multiple_domains_support
+ @unit.skip_if_no_multiple_domains_support
def test_create_domain_case_sensitivity(self):
# create a ref with a lowercase name
ref = {
@@ -3443,8 +3806,8 @@ class IdentityTests(object):
user_projects = self.assignment_api.list_projects_for_user(user1['id'])
self.assertEqual(3, len(user_projects))
- @tests.skip_if_cache_disabled('resource')
- @tests.skip_if_no_multiple_domains_support
+ @unit.skip_if_cache_disabled('resource')
+ @unit.skip_if_no_multiple_domains_support
def test_domain_rename_invalidates_get_domain_by_name_cache(self):
domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex,
'enabled': True}
@@ -3458,7 +3821,7 @@ class IdentityTests(object):
self.resource_api.get_domain_by_name,
domain_name)
- @tests.skip_if_cache_disabled('resource')
+ @unit.skip_if_cache_disabled('resource')
def test_cache_layer_domain_crud(self):
domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex,
'enabled': True}
@@ -3513,8 +3876,8 @@ class IdentityTests(object):
self.resource_api.get_domain,
domain_id)
- @tests.skip_if_cache_disabled('resource')
- @tests.skip_if_no_multiple_domains_support
+ @unit.skip_if_cache_disabled('resource')
+ @unit.skip_if_no_multiple_domains_support
def test_project_rename_invalidates_get_project_by_name_cache(self):
domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex,
'enabled': True}
@@ -3533,8 +3896,8 @@ class IdentityTests(object):
project_name,
domain['id'])
- @tests.skip_if_cache_disabled('resource')
- @tests.skip_if_no_multiple_domains_support
+ @unit.skip_if_cache_disabled('resource')
+ @unit.skip_if_no_multiple_domains_support
def test_cache_layer_project_crud(self):
domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex,
'enabled': True}
@@ -3646,7 +4009,7 @@ class IdentityTests(object):
group_id=uuid.uuid4().hex,
project_id=self.tenant_bar['id'])
- @tests.skip_if_no_multiple_domains_support
+ @unit.skip_if_no_multiple_domains_support
def test_get_default_domain_by_name(self):
domain_name = 'default'
@@ -4308,7 +4671,7 @@ class TokenTests(object):
def test_list_revoked_tokens_for_multiple_tokens(self):
self.check_list_revoked_tokens([self.delete_token()
- for x in six.moves.range(2)])
+ for x in range(2)])
def test_flush_expired_token(self):
token_id = uuid.uuid4().hex
@@ -4339,7 +4702,7 @@ class TokenTests(object):
self.assertEqual(1, len(tokens))
self.assertIn(token_id, tokens)
- @tests.skip_if_cache_disabled('token')
+ @unit.skip_if_cache_disabled('token')
def test_revocation_list_cache(self):
expire_time = timeutils.utcnow() + datetime.timedelta(minutes=10)
token_id = uuid.uuid4().hex
@@ -4769,7 +5132,7 @@ class CatalogTests(object):
for region in regions:
self.assertEqual(parent_id, region['parent_region_id'])
- @tests.skip_if_cache_disabled('catalog')
+ @unit.skip_if_cache_disabled('catalog')
def test_cache_layer_region_crud(self):
region_id = uuid.uuid4().hex
new_region = {
@@ -4797,7 +5160,7 @@ class CatalogTests(object):
self.assertRaises(exception.RegionNotFound,
self.catalog_api.get_region, region_id)
- @tests.skip_if_cache_disabled('catalog')
+ @unit.skip_if_cache_disabled('catalog')
def test_invalidate_cache_when_updating_region(self):
region_id = uuid.uuid4().hex
new_region = {
@@ -4875,7 +5238,7 @@ class CatalogTests(object):
region_two['id'],
{'parent_region_id': region_four['id']})
- @mock.patch.object(core.Driver,
+ @mock.patch.object(core.CatalogDriverV8,
"_ensure_no_circle_in_hierarchical_regions")
def test_circular_regions_can_be_deleted(self, mock_ensure_on_circle):
# turn off the enforcement so that cycles can be created for the test
@@ -5003,7 +5366,7 @@ class CatalogTests(object):
self.catalog_api.delete_service(unrelated_service1['id'])
self.catalog_api.delete_service(unrelated_service2['id'])
- @tests.skip_if_cache_disabled('catalog')
+ @unit.skip_if_cache_disabled('catalog')
def test_cache_layer_service_crud(self):
service_id = uuid.uuid4().hex
new_service = {
@@ -5040,7 +5403,7 @@ class CatalogTests(object):
self.catalog_api.get_service,
service_id)
- @tests.skip_if_cache_disabled('catalog')
+ @unit.skip_if_cache_disabled('catalog')
def test_invalidate_cache_when_updating_service(self):
service_id = uuid.uuid4().hex
new_service = {
@@ -5351,7 +5714,7 @@ class CatalogTests(object):
endpoint_ids = [x['id'] for x in catalog[0]['endpoints']]
self.assertEqual([enabled_endpoint_ref['id']], endpoint_ids)
- @tests.skip_if_cache_disabled('catalog')
+ @unit.skip_if_cache_disabled('catalog')
def test_invalidate_cache_when_updating_endpoint(self):
service = {
'id': uuid.uuid4().hex,
@@ -5468,7 +5831,71 @@ class PolicyTests(object):
uuid.uuid4().hex)
-class InheritanceTests(object):
+class InheritanceTests(AssignmentTestHelperMixin):
+
+ def test_role_assignments_user_domain_to_project_inheritance(self):
+ test_plan = {
+ 'entities': {'domains': {'users': 2, 'projects': 1},
+ 'roles': 3},
+ 'assignments': [{'user': 0, 'role': 0, 'domain': 0},
+ {'user': 0, 'role': 1, 'project': 0},
+ {'user': 0, 'role': 2, 'domain': 0,
+ 'inherited_to_projects': True},
+ {'user': 1, 'role': 1, 'project': 0}],
+ 'tests': [
+ # List all direct assignments for user[0]
+ {'params': {'user': 0},
+ 'results': [{'user': 0, 'role': 0, 'domain': 0},
+ {'user': 0, 'role': 1, 'project': 0},
+ {'user': 0, 'role': 2, 'domain': 0,
+ 'inherited_to_projects': 'projects'}]},
+ # Now the effective ones - so the domain role should turn into
+ # a project role
+ {'params': {'user': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 0, 'domain': 0},
+ {'user': 0, 'role': 1, 'project': 0},
+ {'user': 0, 'role': 2, 'project': 0,
+ 'indirect': {'domain': 0}}]},
+ # Narrow down to effective roles for user[0] and project[0]
+ {'params': {'user': 0, 'project': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 1, 'project': 0},
+ {'user': 0, 'role': 2, 'project': 0,
+ 'indirect': {'domain': 0}}]}
+ ]
+ }
+ self.config_fixture.config(group='os_inherit', enabled=True)
+ self.execute_assignment_test_plan(test_plan)
+
+ def test_inherited_role_assignments_excluded_if_os_inherit_false(self):
+ test_plan = {
+ 'entities': {'domains': {'users': 2, 'groups': 1, 'projects': 1},
+ 'roles': 4},
+ 'group_memberships': [{'group': 0, 'users': [0]}],
+ 'assignments': [{'user': 0, 'role': 0, 'domain': 0},
+ {'user': 0, 'role': 1, 'project': 0},
+ {'user': 0, 'role': 2, 'domain': 0,
+ 'inherited_to_projects': True},
+ {'user': 1, 'role': 1, 'project': 0},
+ {'group': 0, 'role': 3, 'project': 0}],
+ 'tests': [
+ # List all direct assignments for user[0], since os-inherit is
+ # disabled, we should not see the inherited role
+ {'params': {'user': 0},
+ 'results': [{'user': 0, 'role': 0, 'domain': 0},
+ {'user': 0, 'role': 1, 'project': 0}]},
+ # Same in effective mode - inherited roles should not be
+ # included or expanded...but the group role should now
+ # turn up as a user role, since group expansion is not
+ # part of os-inherit.
+ {'params': {'user': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 0, 'domain': 0},
+ {'user': 0, 'role': 1, 'project': 0},
+ {'user': 0, 'role': 3, 'project': 0,
+ 'indirect': {'group': 0}}]},
+ ]
+ }
+ self.config_fixture.config(group='os_inherit', enabled=False)
+ self.execute_assignment_test_plan(test_plan)
def _test_crud_inherited_and_direct_assignment(self, **kwargs):
"""Tests inherited and direct assignments for the actor and target
@@ -5616,6 +6043,42 @@ class InheritanceTests(object):
self.assertEqual(1, len(combined_role_list))
self.assertIn(role_list[1]['id'], combined_role_list)
+ # TODO(henry-nash): The test above uses get_roles_for_user_and_project
+ # and get_roles_for_user_and_domain, which will, in a subsequent patch,
+ # be re-implemeted to simply call list_role_assignments (see blueprint
+ # remove-role-metadata).
+ #
+ # The test plan below therefore mirrors this test, to ensure that
+ # list_role_assignments works the same. Once get_roles_for_user_and
+ # project/domain have been re-implemented then the manual tests above
+ # can be refactored to simply ensure it gives the same answers.
+ test_plan = {
+ # A domain with a user & project, plus 3 roles.
+ 'entities': {'domains': {'users': 1, 'projects': 1},
+ 'roles': 3},
+ 'assignments': [{'user': 0, 'role': 0, 'project': 0},
+ {'user': 0, 'role': 1, 'domain': 0},
+ {'user': 0, 'role': 2, 'domain': 0,
+ 'inherited_to_projects': True}],
+ 'tests': [
+ # List all effective assignments for user[0] on project[0].
+ # Should get one direct role and one inherited role.
+ {'params': {'user': 0, 'project': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 0, 'project': 0},
+ {'user': 0, 'role': 2, 'project': 0,
+ 'indirect': {'domain': 0}}]},
+ # Ensure effective mode on the domain does not list the
+ # inherited role on that domain
+ {'params': {'user': 0, 'domain': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 1, 'domain': 0}]},
+ # Ensure non-inherited mode also only returns the non-inherited
+ # role on the domain
+ {'params': {'user': 0, 'domain': 0, 'inherited': False},
+ 'results': [{'user': 0, 'role': 1, 'domain': 0}]},
+ ]
+ }
+ self.execute_assignment_test_plan(test_plan)
+
def test_inherited_role_grants_for_group(self):
"""Test inherited group roles.
@@ -5699,6 +6162,42 @@ class InheritanceTests(object):
self.assertIn(role_list[2]['id'], combined_list)
self.assertIn(role_list[3]['id'], combined_list)
+ # TODO(henry-nash): The test above uses get_roles_for_user_and_project
+ # which will, in a subsequent patch, be re-implemeted to simply call
+ # list_role_assignments (see blueprint remove-role-metadata).
+ #
+ # The test plan below therefore mirrors this test, to ensure that
+ # list_role_assignments works the same. Once
+ # get_roles_for_user_and_project has been re-implemented then the
+ # manual tests above can be refactored to simply ensure it gives
+ # the same answers.
+ test_plan = {
+ # A domain with a user and project, 2 groups, plus 4 roles.
+ 'entities': {'domains': {'users': 1, 'projects': 1, 'groups': 2},
+ 'roles': 4},
+ 'group_memberships': [{'group': 0, 'users': [0]},
+ {'group': 1, 'users': [0]}],
+ 'assignments': [{'user': 0, 'role': 0, 'project': 0},
+ {'group': 0, 'role': 1, 'domain': 0},
+ {'group': 1, 'role': 2, 'domain': 0,
+ 'inherited_to_projects': True},
+ {'group': 1, 'role': 3, 'domain': 0,
+ 'inherited_to_projects': True}],
+ 'tests': [
+ # List all effective assignments for user[0] on project[0].
+ # Should get one direct role and both inherited roles, but
+ # not the direct one on domain[0], even though user[0] is
+ # in group[0].
+ {'params': {'user': 0, 'project': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 0, 'project': 0},
+ {'user': 0, 'role': 2, 'project': 0,
+ 'indirect': {'domain': 0, 'group': 1}},
+ {'user': 0, 'role': 3, 'project': 0,
+ 'indirect': {'domain': 0, 'group': 1}}]}
+ ]
+ }
+ self.execute_assignment_test_plan(test_plan)
+
def test_list_projects_for_user_with_inherited_grants(self):
"""Test inherited user roles.
@@ -5738,6 +6237,37 @@ class InheritanceTests(object):
user_projects = self.assignment_api.list_projects_for_user(user1['id'])
self.assertEqual(3, len(user_projects))
+ # TODO(henry-nash): The test above uses list_projects_for_user
+ # which may, in a subsequent patch, be re-implemeted to call
+ # list_role_assignments and then report only the distinct projects.
+ #
+ # The test plan below therefore mirrors this test, to ensure that
+ # list_role_assignments works the same. Once list_projects_for_user
+ # has been re-implemented then the manual tests above can be
+ # refactored.
+ test_plan = {
+ # A domain with 1 project, plus a second domain with 2 projects,
+ # as well as a user. Also, create 2 roles.
+ 'entities': {'domains': [{'projects': 1},
+ {'users': 1, 'projects': 2}],
+ 'roles': 2},
+ 'assignments': [{'user': 0, 'role': 0, 'project': 0},
+ {'user': 0, 'role': 1, 'domain': 1,
+ 'inherited_to_projects': True}],
+ 'tests': [
+ # List all effective assignments for user[0]
+ # Should get one direct role plus one inherited role for each
+ # project in domain
+ {'params': {'user': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 0, 'project': 0},
+ {'user': 0, 'role': 1, 'project': 1,
+ 'indirect': {'domain': 1}},
+ {'user': 0, 'role': 1, 'project': 2,
+ 'indirect': {'domain': 1}}]}
+ ]
+ }
+ self.execute_assignment_test_plan(test_plan)
+
def test_list_projects_for_user_with_inherited_user_project_grants(self):
"""Test inherited role assignments for users on nested projects.
@@ -5798,6 +6328,50 @@ class InheritanceTests(object):
self.assertEqual(1, len(user_projects))
self.assertIn(root_project, user_projects)
+ # TODO(henry-nash): The test above uses list_projects_for_user
+ # which may, in a subsequent patch, be re-implemeted to call
+ # list_role_assignments and then report only the distinct projects.
+ #
+ # The test plan below therefore mirrors this test, to ensure that
+ # list_role_assignments works the same. Once list_projects_for_user
+ # has been re-implemented then the manual tests above can be
+ # refactored.
+ test_plan = {
+ # A domain with a project and sub-project, plus a user.
+ # Also, create 2 roles.
+ 'entities': {
+ 'domains': {'id': DEFAULT_DOMAIN_ID, 'users': 1,
+ 'projects': {'project': 1}},
+ 'roles': 2},
+ # A direct role and an inherited role on the parent
+ 'assignments': [{'user': 0, 'role': 0, 'project': 0},
+ {'user': 0, 'role': 1, 'project': 0,
+ 'inherited_to_projects': True}],
+ 'tests': [
+ # List all effective assignments for user[0] - should get back
+ # one direct role plus one inherited role.
+ {'params': {'user': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 0, 'project': 0},
+ {'user': 0, 'role': 1, 'project': 1,
+ 'indirect': {'project': 0}}]}
+ ]
+ }
+
+ test_plan_with_os_inherit_disabled = {
+ 'tests': [
+ # List all effective assignments for user[0] - should only get
+ # back the one direct role.
+ {'params': {'user': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 0, 'project': 0}]}
+ ]
+ }
+ self.config_fixture.config(group='os_inherit', enabled=True)
+ test_data = self.execute_assignment_test_plan(test_plan)
+ self.config_fixture.config(group='os_inherit', enabled=False)
+ # Pass the existing test data in to allow execution of 2nd test plan
+ self.execute_assignment_tests(
+ test_plan_with_os_inherit_disabled, test_data)
+
def test_list_projects_for_user_with_inherited_group_grants(self):
"""Test inherited group roles.
@@ -5862,6 +6436,48 @@ class InheritanceTests(object):
user_projects = self.assignment_api.list_projects_for_user(user1['id'])
self.assertEqual(5, len(user_projects))
+ # TODO(henry-nash): The test above uses list_projects_for_user
+ # which may, in a subsequent patch, be re-implemeted to call
+ # list_role_assignments and then report only the distinct projects.
+ #
+ # The test plan below therefore mirrors this test, to ensure that
+ # list_role_assignments works the same. Once list_projects_for_user
+ # has been re-implemented then the manual tests above can be
+ # refactored.
+ test_plan = {
+ # A domain with a 1 project, plus a second domain with 2 projects,
+ # as well as a user & group and a 3rd domain with 2 projects.
+ # Also, created 2 roles.
+ 'entities': {'domains': [{'projects': 1},
+ {'users': 1, 'groups': 1, 'projects': 2},
+ {'projects': 2}],
+ 'roles': 2},
+ 'group_memberships': [{'group': 0, 'users': [0]}],
+ 'assignments': [{'user': 0, 'role': 0, 'project': 0},
+ {'user': 0, 'role': 0, 'project': 3},
+ {'user': 0, 'role': 1, 'domain': 1,
+ 'inherited_to_projects': True},
+ {'user': 0, 'role': 1, 'domain': 2,
+ 'inherited_to_projects': True}],
+ 'tests': [
+ # List all effective assignments for user[0]
+ # Should get back both direct roles plus roles on both projects
+ # from each domain. Duplicates should not be fitered out.
+ {'params': {'user': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 0, 'project': 3},
+ {'user': 0, 'role': 0, 'project': 0},
+ {'user': 0, 'role': 1, 'project': 1,
+ 'indirect': {'domain': 1}},
+ {'user': 0, 'role': 1, 'project': 2,
+ 'indirect': {'domain': 1}},
+ {'user': 0, 'role': 1, 'project': 3,
+ 'indirect': {'domain': 2}},
+ {'user': 0, 'role': 1, 'project': 4,
+ 'indirect': {'domain': 2}}]}
+ ]
+ }
+ self.execute_assignment_test_plan(test_plan)
+
def test_list_projects_for_user_with_inherited_group_project_grants(self):
"""Test inherited role assignments for groups on nested projects.
@@ -5925,6 +6541,53 @@ class InheritanceTests(object):
self.assertEqual(1, len(user_projects))
self.assertIn(root_project, user_projects)
+ # TODO(henry-nash): The test above uses list_projects_for_user
+ # which may, in a subsequent patch, be re-implemeted to call
+ # list_role_assignments and then report only the distinct projects.
+ #
+ # The test plan below therefore mirrors this test, to ensure that
+ # list_role_assignments works the same. Once list_projects_for_user
+ # has been re-implemented then the manual tests above can be
+ # refactored.
+ test_plan = {
+ # A domain with a project ans sub-project, plus a user.
+ # Also, create 2 roles.
+ 'entities': {
+ 'domains': {'id': DEFAULT_DOMAIN_ID, 'users': 1, 'groups': 1,
+ 'projects': {'project': 1}},
+ 'roles': 2},
+ 'group_memberships': [{'group': 0, 'users': [0]}],
+ # A direct role and an inherited role on the parent
+ 'assignments': [{'group': 0, 'role': 0, 'project': 0},
+ {'group': 0, 'role': 1, 'project': 0,
+ 'inherited_to_projects': True}],
+ 'tests': [
+ # List all effective assignments for user[0] - should get back
+ # one direct role plus one inherited role.
+ {'params': {'user': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 0, 'project': 0,
+ 'indirect': {'group': 0}},
+ {'user': 0, 'role': 1, 'project': 1,
+ 'indirect': {'group': 0, 'project': 0}}]}
+ ]
+ }
+
+ test_plan_with_os_inherit_disabled = {
+ 'tests': [
+ # List all effective assignments for user[0] - should only get
+ # back the one direct role.
+ {'params': {'user': 0, 'effective': True},
+ 'results': [{'user': 0, 'role': 0, 'project': 0,
+ 'indirect': {'group': 0}}]}
+ ]
+ }
+ self.config_fixture.config(group='os_inherit', enabled=True)
+ test_data = self.execute_assignment_test_plan(test_plan)
+ self.config_fixture.config(group='os_inherit', enabled=False)
+ # Pass the existing test data in to allow execution of 2nd test plan
+ self.execute_assignment_tests(
+ test_plan_with_os_inherit_disabled, test_data)
+
class FilterTests(filtering.FilterTests):
def test_list_entities_filtered(self):
diff --git a/keystone-moon/keystone/tests/unit/test_backend_kvs.py b/keystone-moon/keystone/tests/unit/test_backend_kvs.py
index a22faa59..7406192a 100644
--- a/keystone-moon/keystone/tests/unit/test_backend_kvs.py
+++ b/keystone-moon/keystone/tests/unit/test_backend_kvs.py
@@ -20,14 +20,14 @@ import six
from keystone.common import utils
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import test_backend
CONF = cfg.CONF
-class KvsToken(tests.TestCase, test_backend.TokenTests):
+class KvsToken(unit.TestCase, test_backend.TokenTests):
def setUp(self):
super(KvsToken, self).setUp()
self.load_backends()
@@ -103,7 +103,7 @@ class KvsToken(tests.TestCase, test_backend.TokenTests):
self.assertEqual(expected_user_token_list, user_token_list)
-class KvsCatalog(tests.TestCase, test_backend.CatalogTests):
+class KvsCatalog(unit.TestCase, test_backend.CatalogTests):
def setUp(self):
super(KvsCatalog, self).setUp()
self.load_backends()
@@ -157,7 +157,7 @@ class KvsCatalog(tests.TestCase, test_backend.CatalogTests):
self.skipTest("kvs backend doesn't support filtering")
-class KvsTokenCacheInvalidation(tests.TestCase,
+class KvsTokenCacheInvalidation(unit.TestCase,
test_backend.TokenCacheInvalidation):
def setUp(self):
super(KvsTokenCacheInvalidation, self).setUp()
diff --git a/keystone-moon/keystone/tests/unit/test_backend_ldap.py b/keystone-moon/keystone/tests/unit/test_backend_ldap.py
index 94fb82e7..808922a7 100644
--- a/keystone-moon/keystone/tests/unit/test_backend_ldap.py
+++ b/keystone-moon/keystone/tests/unit/test_backend_ldap.py
@@ -21,6 +21,7 @@ import ldap
import mock
from oslo_config import cfg
import pkg_resources
+from six.moves import http_client
from six.moves import range
from testtools import matchers
@@ -31,7 +32,7 @@ from keystone import exception
from keystone import identity
from keystone.identity.mapping_backends import mapping as map
from keystone import resource
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import default_fixtures
from keystone.tests.unit import identity_mapping as mapping_sql
from keystone.tests.unit.ksfixtures import database
@@ -138,7 +139,7 @@ class BaseLDAPIdentity(test_backend.IdentityTests):
def config_files(self):
config_files = super(BaseLDAPIdentity, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_ldap.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_ldap.conf'))
return config_files
def get_user_enabled_vals(self, user):
@@ -712,7 +713,7 @@ class BaseLDAPIdentity(test_backend.IdentityTests):
self.identity_api.get_group,
group['id'])
- @tests.skip_if_cache_disabled('identity')
+ @unit.skip_if_cache_disabled('identity')
def test_cache_layer_group_crud(self):
group = {
'domain_id': CONF.identity.default_domain_id,
@@ -979,8 +980,21 @@ class BaseLDAPIdentity(test_backend.IdentityTests):
# returned as part of the ref.
self.assertIs(True, project_info['enabled'])
+ def test_list_role_assignment_by_domain(self):
+ """Multiple domain assignments are not supported."""
+ self.assertRaises(
+ (exception.Forbidden, exception.DomainNotFound),
+ super(BaseLDAPIdentity, self).test_list_role_assignment_by_domain)
+
+ def test_list_role_assignment_by_user_with_domain_group_roles(self):
+ """Multiple domain assignments are not supported."""
+ self.assertRaises(
+ (exception.Forbidden, exception.DomainNotFound),
+ super(BaseLDAPIdentity, self).
+ test_list_role_assignment_by_user_with_domain_group_roles)
+
-class LDAPIdentity(BaseLDAPIdentity, tests.TestCase):
+class LDAPIdentity(BaseLDAPIdentity, unit.TestCase):
def setUp(self):
# NOTE(dstanek): The database must be setup prior to calling the
@@ -1578,7 +1592,7 @@ class LDAPIdentity(BaseLDAPIdentity, tests.TestCase):
self.resource_api.get_domain,
domain['id'])
- @tests.skip_if_no_multiple_domains_support
+ @unit.skip_if_no_multiple_domains_support
def test_create_domain_case_sensitivity(self):
# domains are read-only, so case sensitivity isn't an issue
ref = {
@@ -1633,7 +1647,7 @@ class LDAPIdentity(BaseLDAPIdentity, tests.TestCase):
self.resource_api.get_project,
project['id'])
- @tests.skip_if_cache_disabled('assignment')
+ @unit.skip_if_cache_disabled('assignment')
def test_cache_layer_project_crud(self):
# NOTE(morganfainberg): LDAP implementation does not currently support
# updating project names. This method override provides a different
@@ -2091,7 +2105,7 @@ class LDAPIdentityEnabledEmulation(LDAPIdentity):
def config_files(self):
config_files = super(LDAPIdentityEnabledEmulation, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_ldap.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_ldap.conf'))
return config_files
def config_overrides(self):
@@ -2250,12 +2264,12 @@ class LDAPIdentityEnabledEmulation(LDAPIdentity):
self.assertIs(False, user_ref['enabled'])
-class LdapIdentitySqlAssignment(BaseLDAPIdentity, tests.SQLDriverOverrides,
- tests.TestCase):
+class LdapIdentitySqlAssignment(BaseLDAPIdentity, unit.SQLDriverOverrides,
+ unit.TestCase):
def config_files(self):
config_files = super(LdapIdentitySqlAssignment, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_ldap_sql.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_ldap_sql.conf'))
return config_files
def setUp(self):
@@ -2473,7 +2487,7 @@ class BaseMultiLDAPandSQLIdentity(object):
self.identity_api._get_domain_driver_and_entity_id(
user['id']))
- if expected_status == 200:
+ if expected_status == http_client.OK:
ref = driver.get_user(entity_id)
ref = self.identity_api._set_domain_id_and_mapping(
ref, domain_id, driver, map.EntityType.USER)
@@ -2518,8 +2532,8 @@ class BaseMultiLDAPandSQLIdentity(object):
password=self.users[user]['password'])
-class MultiLDAPandSQLIdentity(BaseLDAPIdentity, tests.SQLDriverOverrides,
- tests.TestCase, BaseMultiLDAPandSQLIdentity):
+class MultiLDAPandSQLIdentity(BaseLDAPIdentity, unit.SQLDriverOverrides,
+ unit.TestCase, BaseMultiLDAPandSQLIdentity):
"""Class to test common SQL plus individual LDAP backends.
We define a set of domains and domain-specific backends:
@@ -2598,7 +2612,7 @@ class MultiLDAPandSQLIdentity(BaseLDAPIdentity, tests.SQLDriverOverrides,
"""
self.config_fixture.config(
group='identity', domain_specific_drivers_enabled=True,
- domain_config_dir=tests.TESTCONF + '/domain_configs_multi_ldap')
+ domain_config_dir=unit.TESTCONF + '/domain_configs_multi_ldap')
self.config_fixture.config(group='identity_mapping',
backward_compatible_ids=False)
@@ -2647,21 +2661,23 @@ class MultiLDAPandSQLIdentity(BaseLDAPIdentity, tests.SQLDriverOverrides,
check_user = self.check_user
check_user(self.users['user0'],
- self.domains['domain_default']['id'], 200)
+ self.domains['domain_default']['id'], http_client.OK)
for domain in [self.domains['domain1']['id'],
self.domains['domain2']['id'],
self.domains['domain3']['id'],
self.domains['domain4']['id']]:
check_user(self.users['user0'], domain, exception.UserNotFound)
- check_user(self.users['user1'], self.domains['domain1']['id'], 200)
+ check_user(self.users['user1'], self.domains['domain1']['id'],
+ http_client.OK)
for domain in [self.domains['domain_default']['id'],
self.domains['domain2']['id'],
self.domains['domain3']['id'],
self.domains['domain4']['id']]:
check_user(self.users['user1'], domain, exception.UserNotFound)
- check_user(self.users['user2'], self.domains['domain2']['id'], 200)
+ check_user(self.users['user2'], self.domains['domain2']['id'],
+ http_client.OK)
for domain in [self.domains['domain_default']['id'],
self.domains['domain1']['id'],
self.domains['domain3']['id'],
@@ -2671,10 +2687,14 @@ class MultiLDAPandSQLIdentity(BaseLDAPIdentity, tests.SQLDriverOverrides,
# domain3 and domain4 share the same backend, so you should be
# able to see user3 and user4 from either.
- check_user(self.users['user3'], self.domains['domain3']['id'], 200)
- check_user(self.users['user3'], self.domains['domain4']['id'], 200)
- check_user(self.users['user4'], self.domains['domain3']['id'], 200)
- check_user(self.users['user4'], self.domains['domain4']['id'], 200)
+ check_user(self.users['user3'], self.domains['domain3']['id'],
+ http_client.OK)
+ check_user(self.users['user3'], self.domains['domain4']['id'],
+ http_client.OK)
+ check_user(self.users['user4'], self.domains['domain3']['id'],
+ http_client.OK)
+ check_user(self.users['user4'], self.domains['domain4']['id'],
+ http_client.OK)
for domain in [self.domains['domain_default']['id'],
self.domains['domain1']['id'],
@@ -2803,6 +2823,17 @@ class MultiLDAPandSQLIdentity(BaseLDAPIdentity, tests.SQLDriverOverrides,
base = super(BaseLDAPIdentity, self)
base.test_list_role_assignments_filtered_by_role()
+ def test_list_role_assignment_by_domain(self):
+ # With multi LDAP this method should work, so override the override
+ # from BaseLDAPIdentity
+ super(BaseLDAPIdentity, self).test_list_role_assignment_by_domain
+
+ def test_list_role_assignment_by_user_with_domain_group_roles(self):
+ # With multi LDAP this method should work, so override the override
+ # from BaseLDAPIdentity
+ super(BaseLDAPIdentity, self).\
+ test_list_role_assignment_by_user_with_domain_group_roles
+
class MultiLDAPandSQLIdentityDomainConfigsInSQL(MultiLDAPandSQLIdentity):
"""Class to test the use of domain configs stored in the database.
@@ -2919,19 +2950,104 @@ class MultiLDAPandSQLIdentityDomainConfigsInSQL(MultiLDAPandSQLIdentity):
domain_cfgs.get_domain_conf(CONF.identity.default_domain_id))
self.assertEqual(CONF.ldap.url, default_config.ldap.url)
- def test_setting_sql_driver_raises_exception(self):
- """Ensure setting of domain specific sql driver is prevented."""
+ def test_setting_multiple_sql_driver_raises_exception(self):
+ """Ensure setting multiple domain specific sql drivers is prevented."""
new_config = {'identity': {'driver': 'sql'}}
self.domain_config_api.create_config(
CONF.identity.default_domain_id, new_config)
- self.assertRaises(exception.InvalidDomainConfig,
+ self.identity_api.domain_configs.get_domain_conf(
+ CONF.identity.default_domain_id)
+ self.domain_config_api.create_config(self.domains['domain1']['id'],
+ new_config)
+ self.assertRaises(exception.MultipleSQLDriversInConfig,
self.identity_api.domain_configs.get_domain_conf,
- CONF.identity.default_domain_id)
+ self.domains['domain1']['id'])
+
+ def test_same_domain_gets_sql_driver(self):
+ """Ensure we can set an SQL driver if we have had it before."""
+
+ new_config = {'identity': {'driver': 'sql'}}
+ self.domain_config_api.create_config(
+ CONF.identity.default_domain_id, new_config)
+ self.identity_api.domain_configs.get_domain_conf(
+ CONF.identity.default_domain_id)
+
+ # By using a slightly different config, we cause the driver to be
+ # reloaded...and hence check if we can reuse the sql driver
+ new_config = {'identity': {'driver': 'sql'},
+ 'ldap': {'url': 'fake://memory1'}}
+ self.domain_config_api.create_config(
+ CONF.identity.default_domain_id, new_config)
+ self.identity_api.domain_configs.get_domain_conf(
+ CONF.identity.default_domain_id)
+
+ def test_delete_domain_clears_sql_registration(self):
+ """Ensure registration is deleted when a domain is deleted."""
+
+ domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex}
+ domain = self.resource_api.create_domain(domain['id'], domain)
+ new_config = {'identity': {'driver': 'sql'}}
+ self.domain_config_api.create_config(domain['id'], new_config)
+ self.identity_api.domain_configs.get_domain_conf(domain['id'])
+
+ # First show that trying to set SQL for another driver fails
+ self.domain_config_api.create_config(self.domains['domain1']['id'],
+ new_config)
+ self.assertRaises(exception.MultipleSQLDriversInConfig,
+ self.identity_api.domain_configs.get_domain_conf,
+ self.domains['domain1']['id'])
+ self.domain_config_api.delete_config(self.domains['domain1']['id'])
+
+ # Now we delete the domain
+ domain['enabled'] = False
+ self.resource_api.update_domain(domain['id'], domain)
+ self.resource_api.delete_domain(domain['id'])
+
+ # The registration should now be available
+ self.domain_config_api.create_config(self.domains['domain1']['id'],
+ new_config)
+ self.identity_api.domain_configs.get_domain_conf(
+ self.domains['domain1']['id'])
+
+ def test_orphaned_registration_does_not_prevent_getting_sql_driver(self):
+ """Ensure we self heal an orphaned sql registration."""
+
+ domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex}
+ domain = self.resource_api.create_domain(domain['id'], domain)
+ new_config = {'identity': {'driver': 'sql'}}
+ self.domain_config_api.create_config(domain['id'], new_config)
+ self.identity_api.domain_configs.get_domain_conf(domain['id'])
+
+ # First show that trying to set SQL for another driver fails
+ self.domain_config_api.create_config(self.domains['domain1']['id'],
+ new_config)
+ self.assertRaises(exception.MultipleSQLDriversInConfig,
+ self.identity_api.domain_configs.get_domain_conf,
+ self.domains['domain1']['id'])
+
+ # Now we delete the domain by using the backend driver directly,
+ # which causes the domain to be deleted without any of the cleanup
+ # that is in the manager (this is simulating a server process crashing
+ # in the middle of a delete domain operation, and somehow leaving the
+ # domain config settings in place, but the domain is deleted). We
+ # should still be able to set another domain to SQL, since we should
+ # self heal this issue.
+
+ self.resource_api.driver.delete_domain(domain['id'])
+ # Invalidate cache (so we will see the domain has gone)
+ self.resource_api.get_domain.invalidate(
+ self.resource_api, domain['id'])
+
+ # The registration should now be available
+ self.domain_config_api.create_config(self.domains['domain1']['id'],
+ new_config)
+ self.identity_api.domain_configs.get_domain_conf(
+ self.domains['domain1']['id'])
class DomainSpecificLDAPandSQLIdentity(
- BaseLDAPIdentity, tests.SQLDriverOverrides, tests.TestCase,
+ BaseLDAPIdentity, unit.SQLDriverOverrides, unit.TestCase,
BaseMultiLDAPandSQLIdentity):
"""Class to test when all domains use specific configs, including SQL.
@@ -2954,7 +3070,7 @@ class DomainSpecificLDAPandSQLIdentity(
self.config_fixture.config(
group='identity', domain_specific_drivers_enabled=True,
domain_config_dir=(
- tests.TESTCONF + '/domain_configs_one_sql_one_ldap'))
+ unit.TESTCONF + '/domain_configs_one_sql_one_ldap'))
self.config_fixture.config(group='identity_mapping',
backward_compatible_ids=False)
@@ -3035,12 +3151,12 @@ class DomainSpecificLDAPandSQLIdentity(
# driver, but won't find it via any other domain driver
self.check_user(self.users['user0'],
- self.domains['domain_default']['id'], 200)
+ self.domains['domain_default']['id'], http_client.OK)
self.check_user(self.users['user0'],
self.domains['domain1']['id'], exception.UserNotFound)
self.check_user(self.users['user1'],
- self.domains['domain1']['id'], 200)
+ self.domains['domain1']['id'], http_client.OK)
self.check_user(self.users['user1'],
self.domains['domain_default']['id'],
exception.UserNotFound)
@@ -3113,7 +3229,7 @@ class DomainSpecificSQLIdentity(DomainSpecificLDAPandSQLIdentity):
self.config_fixture.config(
group='identity', domain_specific_drivers_enabled=True,
domain_config_dir=(
- tests.TESTCONF + '/domain_configs_default_ldap_one_sql'))
+ unit.TESTCONF + '/domain_configs_default_ldap_one_sql'))
# Part of the testing counts how many new mappings get created as
# we create users, so ensure we are NOT using mapping for the default
# LDAP domain so this doesn't confuse the calculation.
@@ -3189,12 +3305,12 @@ class DomainSpecificSQLIdentity(DomainSpecificLDAPandSQLIdentity):
exception.MultipleSQLDriversInConfig,
self.identity_api.domain_configs._load_config_from_file,
self.resource_api,
- [tests.TESTCONF + '/domain_configs_one_extra_sql/' +
+ [unit.TESTCONF + '/domain_configs_one_extra_sql/' +
'keystone.domain2.conf'],
'domain2')
-class LdapFilterTests(test_backend.FilterTests, tests.TestCase):
+class LdapFilterTests(test_backend.FilterTests, unit.TestCase):
def setUp(self):
super(LdapFilterTests, self).setUp()
@@ -3212,7 +3328,7 @@ class LdapFilterTests(test_backend.FilterTests, tests.TestCase):
def config_files(self):
config_files = super(LdapFilterTests, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_ldap.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_ldap.conf'))
return config_files
def test_list_users_in_group_filtered(self):
diff --git a/keystone-moon/keystone/tests/unit/test_backend_ldap_pool.py b/keystone-moon/keystone/tests/unit/test_backend_ldap_pool.py
index 66827d7e..2b714b57 100644
--- a/keystone-moon/keystone/tests/unit/test_backend_ldap_pool.py
+++ b/keystone-moon/keystone/tests/unit/test_backend_ldap_pool.py
@@ -21,7 +21,7 @@ from oslotest import mockpatch
from keystone.common.ldap import core as ldap_core
from keystone.identity.backends import ldap
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import fakeldap
from keystone.tests.unit import test_backend_ldap
@@ -209,7 +209,7 @@ class LdapPoolCommonTestMixin(object):
class LdapIdentitySqlAssignment(LdapPoolCommonTestMixin,
test_backend_ldap.LdapIdentitySqlAssignment,
- tests.TestCase):
+ unit.TestCase):
"""Executes tests in existing base class with pooled LDAP handler."""
def setUp(self):
self.useFixture(mockpatch.PatchObject(
@@ -226,7 +226,7 @@ class LdapIdentitySqlAssignment(LdapPoolCommonTestMixin,
def config_files(self):
config_files = super(LdapIdentitySqlAssignment, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_ldap_pool.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_ldap_pool.conf'))
return config_files
@mock.patch.object(ldap_core, 'utf8_encode')
diff --git a/keystone-moon/keystone/tests/unit/test_backend_rules.py b/keystone-moon/keystone/tests/unit/test_backend_rules.py
index bc0dc13d..9a11fddc 100644
--- a/keystone-moon/keystone/tests/unit/test_backend_rules.py
+++ b/keystone-moon/keystone/tests/unit/test_backend_rules.py
@@ -14,11 +14,11 @@
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import test_backend
-class RulesPolicy(tests.TestCase, test_backend.PolicyTests):
+class RulesPolicy(unit.TestCase, test_backend.PolicyTests):
def setUp(self):
super(RulesPolicy, self).setUp()
self.load_backends()
diff --git a/keystone-moon/keystone/tests/unit/test_backend_sql.py b/keystone-moon/keystone/tests/unit/test_backend_sql.py
index bf50ac21..69fac63a 100644
--- a/keystone-moon/keystone/tests/unit/test_backend_sql.py
+++ b/keystone-moon/keystone/tests/unit/test_backend_sql.py
@@ -29,7 +29,7 @@ from keystone.common import driver_hints
from keystone.common import sql
from keystone import exception
from keystone.identity.backends import sql as identity_sql
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import default_fixtures
from keystone.tests.unit.ksfixtures import database
from keystone.tests.unit import test_backend
@@ -40,7 +40,7 @@ CONF = cfg.CONF
DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id
-class SqlTests(tests.SQLDriverOverrides, tests.TestCase):
+class SqlTests(unit.SQLDriverOverrides, unit.TestCase):
def setUp(self):
super(SqlTests, self).setUp()
@@ -54,7 +54,7 @@ class SqlTests(tests.SQLDriverOverrides, tests.TestCase):
def config_files(self):
config_files = super(SqlTests, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_sql.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_sql.conf'))
return config_files
@@ -840,7 +840,7 @@ class FakeTable(sql.ModelBase):
raise KeyError
-class SqlDecorators(tests.TestCase):
+class SqlDecorators(unit.TestCase):
def test_initialization_fail(self):
self.assertRaises(exception.StringLengthExceeded,
@@ -863,7 +863,7 @@ class SqlDecorators(tests.TestCase):
self.assertRaises(KeyError, FakeTable().lookup)
-class SqlModuleInitialization(tests.TestCase):
+class SqlModuleInitialization(unit.TestCase):
@mock.patch.object(sql.core, 'CONF')
@mock.patch.object(options, 'set_defaults')
diff --git a/keystone-moon/keystone/tests/unit/test_backend_templated.py b/keystone-moon/keystone/tests/unit/test_backend_templated.py
index 82a8bed8..4a7bf9e5 100644
--- a/keystone-moon/keystone/tests/unit/test_backend_templated.py
+++ b/keystone-moon/keystone/tests/unit/test_backend_templated.py
@@ -18,7 +18,7 @@ import mock
from six.moves import zip
from keystone import catalog
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import default_fixtures
from keystone.tests.unit.ksfixtures import database
from keystone.tests.unit import test_backend
@@ -28,7 +28,7 @@ BROKEN_WRITE_FUNCTIONALITY_MSG = ("Templated backend doesn't correctly "
"implement write operations")
-class TestTemplatedCatalog(tests.TestCase, test_backend.CatalogTests):
+class TestTemplatedCatalog(unit.TestCase, test_backend.CatalogTests):
DEFAULT_FIXTURE = {
'RegionOne': {
@@ -60,7 +60,7 @@ class TestTemplatedCatalog(tests.TestCase, test_backend.CatalogTests):
self.config_fixture.config(
group='catalog',
driver='templated',
- template_file=tests.dirs.tests('default_catalog.templates'))
+ template_file=unit.dirs.tests('default_catalog.templates'))
def test_get_catalog(self):
catalog_ref = self.catalog_api.get_catalog('foo', 'bar')
@@ -161,11 +161,11 @@ class TestTemplatedCatalog(tests.TestCase, test_backend.CatalogTests):
def test_region_crud(self):
self.skipTest(BROKEN_WRITE_FUNCTIONALITY_MSG)
- @tests.skip_if_cache_disabled('catalog')
+ @unit.skip_if_cache_disabled('catalog')
def test_cache_layer_region_crud(self):
self.skipTest(BROKEN_WRITE_FUNCTIONALITY_MSG)
- @tests.skip_if_cache_disabled('catalog')
+ @unit.skip_if_cache_disabled('catalog')
def test_invalidate_cache_when_updating_region(self):
self.skipTest(BROKEN_WRITE_FUNCTIONALITY_MSG)
@@ -189,11 +189,11 @@ class TestTemplatedCatalog(tests.TestCase, test_backend.CatalogTests):
def test_service_crud(self):
self.skipTest(BROKEN_WRITE_FUNCTIONALITY_MSG)
- @tests.skip_if_cache_disabled('catalog')
+ @unit.skip_if_cache_disabled('catalog')
def test_cache_layer_service_crud(self):
self.skipTest(BROKEN_WRITE_FUNCTIONALITY_MSG)
- @tests.skip_if_cache_disabled('catalog')
+ @unit.skip_if_cache_disabled('catalog')
def test_invalidate_cache_when_updating_service(self):
self.skipTest(BROKEN_WRITE_FUNCTIONALITY_MSG)
@@ -234,6 +234,6 @@ class TestTemplatedCatalog(tests.TestCase, test_backend.CatalogTests):
endpoints = self.catalog_api.list_endpoints()
self.assertEqual(expected_ids, set(e['id'] for e in endpoints))
- @tests.skip_if_cache_disabled('catalog')
+ @unit.skip_if_cache_disabled('catalog')
def test_invalidate_cache_when_updating_endpoint(self):
self.skipTest(BROKEN_WRITE_FUNCTIONALITY_MSG)
diff --git a/keystone-moon/keystone/tests/unit/test_cache.py b/keystone-moon/keystone/tests/unit/test_cache.py
index c60df877..3c2afe66 100644
--- a/keystone-moon/keystone/tests/unit/test_cache.py
+++ b/keystone-moon/keystone/tests/unit/test_cache.py
@@ -23,7 +23,7 @@ from oslo_config import cfg
from keystone.common import cache
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
CONF = cfg.CONF
@@ -76,7 +76,7 @@ class TestProxyValue(object):
self.cached = False
-class CacheRegionTest(tests.TestCase):
+class CacheRegionTest(unit.TestCase):
def setUp(self):
super(CacheRegionTest, self).setUp()
@@ -293,7 +293,7 @@ class CacheRegionTest(tests.TestCase):
"bogus")
-class CacheNoopBackendTest(tests.TestCase):
+class CacheNoopBackendTest(unit.TestCase):
def setUp(self):
super(CacheNoopBackendTest, self).setUp()
diff --git a/keystone-moon/keystone/tests/unit/test_cache_backend_mongo.py b/keystone-moon/keystone/tests/unit/test_cache_backend_mongo.py
index 369570d6..66f80c21 100644
--- a/keystone-moon/keystone/tests/unit/test_cache_backend_mongo.py
+++ b/keystone-moon/keystone/tests/unit/test_cache_backend_mongo.py
@@ -24,7 +24,7 @@ from six.moves import range
from keystone.common.cache.backends import mongo
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
# Mock database structure sample where 'ks_cache' is database and
@@ -278,7 +278,7 @@ class MyTransformer(mongo.BaseTransform):
return super(MyTransformer, self).transform_outgoing(son, collection)
-class MongoCache(tests.BaseTestCase):
+class MongoCache(unit.BaseTestCase):
def setUp(self):
super(MongoCache, self).setUp()
global COLLECTIONS
diff --git a/keystone-moon/keystone/tests/unit/test_catalog.py b/keystone-moon/keystone/tests/unit/test_catalog.py
index 4e7f4037..85acfedf 100644
--- a/keystone-moon/keystone/tests/unit/test_catalog.py
+++ b/keystone-moon/keystone/tests/unit/test_catalog.py
@@ -14,8 +14,10 @@
import uuid
+from six.moves import http_client
+
from keystone import catalog
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit.ksfixtures import database
from keystone.tests.unit import rest
@@ -30,7 +32,7 @@ class V2CatalogTestCase(rest.RestfulTestCase):
self.useFixture(database.Database())
self.service_id = uuid.uuid4().hex
- self.service = self.new_service_ref()
+ self.service = unit.new_service_ref()
self.service['id'] = self.service_id
self.catalog_api.create_service(
self.service_id,
@@ -47,24 +49,12 @@ class V2CatalogTestCase(rest.RestfulTestCase):
super(V2CatalogTestCase, self).config_overrides()
self.config_fixture.config(group='catalog', driver='sql')
- def new_ref(self):
- """Populates a ref with attributes common to all API entities."""
- return {
- 'id': uuid.uuid4().hex,
- 'name': uuid.uuid4().hex,
- 'description': uuid.uuid4().hex,
- 'enabled': True}
-
- def new_service_ref(self):
- ref = self.new_ref()
- ref['type'] = uuid.uuid4().hex
- return ref
-
def _get_token_id(self, r):
"""Applicable only to JSON."""
return r.result['access']['token']['id']
- def _endpoint_create(self, expected_status=200, service_id=SERVICE_FIXTURE,
+ def _endpoint_create(self, expected_status=http_client.OK,
+ service_id=SERVICE_FIXTURE,
publicurl='http://localhost:8080',
internalurl='http://localhost:8080',
adminurl='http://localhost:8080'):
@@ -115,16 +105,20 @@ class V2CatalogTestCase(rest.RestfulTestCase):
self.assertNotIn("internalurl", response.result['endpoint'])
def test_endpoint_create_with_null_publicurl(self):
- self._endpoint_create(expected_status=400, publicurl=None)
+ self._endpoint_create(expected_status=http_client.BAD_REQUEST,
+ publicurl=None)
def test_endpoint_create_with_empty_publicurl(self):
- self._endpoint_create(expected_status=400, publicurl='')
+ self._endpoint_create(expected_status=http_client.BAD_REQUEST,
+ publicurl='')
def test_endpoint_create_with_null_service_id(self):
- self._endpoint_create(expected_status=400, service_id=None)
+ self._endpoint_create(expected_status=http_client.BAD_REQUEST,
+ service_id=None)
def test_endpoint_create_with_empty_service_id(self):
- self._endpoint_create(expected_status=400, service_id='')
+ self._endpoint_create(expected_status=http_client.BAD_REQUEST,
+ service_id='')
def test_endpoint_create_with_valid_url(self):
"""Create endpoint with valid URL should be tested, too."""
@@ -132,7 +126,7 @@ class V2CatalogTestCase(rest.RestfulTestCase):
valid_url = 'http://127.0.0.1:8774/v1.1/$(tenant_id)s'
# baseline tests that all valid URLs works
- self._endpoint_create(expected_status=200,
+ self._endpoint_create(expected_status=http_client.OK,
publicurl=valid_url,
internalurl=valid_url,
adminurl=valid_url)
@@ -159,7 +153,7 @@ class V2CatalogTestCase(rest.RestfulTestCase):
# Case one: publicurl, internalurl and adminurl are
# all invalid
for invalid_url in invalid_urls:
- self._endpoint_create(expected_status=400,
+ self._endpoint_create(expected_status=http_client.BAD_REQUEST,
publicurl=invalid_url,
internalurl=invalid_url,
adminurl=invalid_url)
@@ -167,7 +161,7 @@ class V2CatalogTestCase(rest.RestfulTestCase):
# Case two: publicurl, internalurl are invalid
# and adminurl is valid
for invalid_url in invalid_urls:
- self._endpoint_create(expected_status=400,
+ self._endpoint_create(expected_status=http_client.BAD_REQUEST,
publicurl=invalid_url,
internalurl=invalid_url,
adminurl=valid_url)
@@ -175,7 +169,7 @@ class V2CatalogTestCase(rest.RestfulTestCase):
# Case three: publicurl, adminurl are invalid
# and internalurl is valid
for invalid_url in invalid_urls:
- self._endpoint_create(expected_status=400,
+ self._endpoint_create(expected_status=http_client.BAD_REQUEST,
publicurl=invalid_url,
internalurl=valid_url,
adminurl=invalid_url)
@@ -183,7 +177,7 @@ class V2CatalogTestCase(rest.RestfulTestCase):
# Case four: internalurl, adminurl are invalid
# and publicurl is valid
for invalid_url in invalid_urls:
- self._endpoint_create(expected_status=400,
+ self._endpoint_create(expected_status=http_client.BAD_REQUEST,
publicurl=valid_url,
internalurl=invalid_url,
adminurl=invalid_url)
@@ -191,7 +185,7 @@ class V2CatalogTestCase(rest.RestfulTestCase):
# Case five: publicurl is invalid, internalurl
# and adminurl are valid
for invalid_url in invalid_urls:
- self._endpoint_create(expected_status=400,
+ self._endpoint_create(expected_status=http_client.BAD_REQUEST,
publicurl=invalid_url,
internalurl=valid_url,
adminurl=valid_url)
@@ -199,7 +193,7 @@ class V2CatalogTestCase(rest.RestfulTestCase):
# Case six: internalurl is invalid, publicurl
# and adminurl are valid
for invalid_url in invalid_urls:
- self._endpoint_create(expected_status=400,
+ self._endpoint_create(expected_status=http_client.BAD_REQUEST,
publicurl=valid_url,
internalurl=invalid_url,
adminurl=valid_url)
@@ -207,13 +201,13 @@ class V2CatalogTestCase(rest.RestfulTestCase):
# Case seven: adminurl is invalid, publicurl
# and internalurl are valid
for invalid_url in invalid_urls:
- self._endpoint_create(expected_status=400,
+ self._endpoint_create(expected_status=http_client.BAD_REQUEST,
publicurl=valid_url,
internalurl=valid_url,
adminurl=invalid_url)
-class TestV2CatalogAPISQL(tests.TestCase):
+class TestV2CatalogAPISQL(unit.TestCase):
def setUp(self):
super(TestV2CatalogAPISQL, self).setUp()
diff --git a/keystone-moon/keystone/tests/unit/test_cert_setup.py b/keystone-moon/keystone/tests/unit/test_cert_setup.py
index 3d300810..47a99810 100644
--- a/keystone-moon/keystone/tests/unit/test_cert_setup.py
+++ b/keystone-moon/keystone/tests/unit/test_cert_setup.py
@@ -17,18 +17,19 @@ import os
import shutil
import mock
+from six.moves import http_client
from testtools import matchers
from keystone.common import environment
from keystone.common import openssl
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import rest
from keystone import token
-SSLDIR = tests.dirs.tmp('ssl')
-CONF = tests.CONF
+SSLDIR = unit.dirs.tmp('ssl')
+CONF = unit.CONF
DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id
@@ -113,11 +114,13 @@ class CertSetupTestCase(rest.RestfulTestCase):
# requests don't have some of the normal information
signing_resp = self.request(self.public_app,
'/v2.0/certificates/signing',
- method='GET', expected_status=200)
+ method='GET',
+ expected_status=http_client.OK)
cacert_resp = self.request(self.public_app,
'/v2.0/certificates/ca',
- method='GET', expected_status=200)
+ method='GET',
+ expected_status=http_client.OK)
with open(CONF.signing.certfile) as f:
self.assertEqual(f.read(), signing_resp.text)
@@ -133,7 +136,7 @@ class CertSetupTestCase(rest.RestfulTestCase):
for accept in [None, 'text/html', 'application/json', 'text/xml']:
headers = {'Accept': accept} if accept else {}
resp = self.request(self.public_app, path, method='GET',
- expected_status=200,
+ expected_status=http_client.OK,
headers=headers)
self.assertEqual('text/html', resp.content_type)
@@ -146,7 +149,7 @@ class CertSetupTestCase(rest.RestfulTestCase):
def test_failure(self):
for path in ['/v2.0/certificates/signing', '/v2.0/certificates/ca']:
self.request(self.public_app, path, method='GET',
- expected_status=500)
+ expected_status=http_client.INTERNAL_SERVER_ERROR)
def test_pki_certs_rebuild(self):
self.test_create_pki_certs()
@@ -219,7 +222,7 @@ class CertSetupTestCase(rest.RestfulTestCase):
self.assertEqual(cert_file1, cert_file2)
-class TestExecCommand(tests.TestCase):
+class TestExecCommand(unit.TestCase):
@mock.patch.object(environment.subprocess.Popen, 'poll')
def test_running_a_successful_command(self, mock_poll):
diff --git a/keystone-moon/keystone/tests/unit/test_cli.py b/keystone-moon/keystone/tests/unit/test_cli.py
index 3f37612e..d967eb53 100644
--- a/keystone-moon/keystone/tests/unit/test_cli.py
+++ b/keystone-moon/keystone/tests/unit/test_cli.py
@@ -23,17 +23,17 @@ from keystone.cmd import cli
from keystone.common import dependency
from keystone.i18n import _
from keystone import resource
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit.ksfixtures import database
CONF = cfg.CONF
-class CliTestCase(tests.SQLDriverOverrides, tests.TestCase):
+class CliTestCase(unit.SQLDriverOverrides, unit.TestCase):
def config_files(self):
config_files = super(CliTestCase, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_sql.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_sql.conf'))
return config_files
def test_token_flush(self):
@@ -42,7 +42,7 @@ class CliTestCase(tests.SQLDriverOverrides, tests.TestCase):
cli.TokenFlush.main()
-class CliDomainConfigAllTestCase(tests.SQLDriverOverrides, tests.TestCase):
+class CliDomainConfigAllTestCase(unit.SQLDriverOverrides, unit.TestCase):
def setUp(self):
self.useFixture(database.Database())
@@ -50,7 +50,7 @@ class CliDomainConfigAllTestCase(tests.SQLDriverOverrides, tests.TestCase):
self.load_backends()
self.config_fixture.config(
group='identity',
- domain_config_dir=tests.TESTCONF + '/domain_configs_multi_ldap')
+ domain_config_dir=unit.TESTCONF + '/domain_configs_multi_ldap')
self.domain_count = 3
self.setup_initial_domains()
@@ -58,7 +58,7 @@ class CliDomainConfigAllTestCase(tests.SQLDriverOverrides, tests.TestCase):
self.config_fixture.register_cli_opt(cli.command_opt)
self.addCleanup(self.cleanup)
config_files = super(CliDomainConfigAllTestCase, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_sql.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_sql.conf'))
return config_files
def cleanup(self):
diff --git a/keystone-moon/keystone/tests/unit/test_config.py b/keystone-moon/keystone/tests/unit/test_config.py
index 431f9965..7984646d 100644
--- a/keystone-moon/keystone/tests/unit/test_config.py
+++ b/keystone-moon/keystone/tests/unit/test_config.py
@@ -18,31 +18,31 @@ from oslo_config import cfg
from keystone import config
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
CONF = cfg.CONF
-class ConfigTestCase(tests.TestCase):
+class ConfigTestCase(unit.TestCase):
def config_files(self):
config_files = super(ConfigTestCase, self).config_files()
# Insert the keystone sample as the first config file to be loaded
# since it is used in one of the code paths to determine the paste-ini
# location.
- config_files.insert(0, tests.dirs.etc('keystone.conf.sample'))
+ config_files.insert(0, unit.dirs.etc('keystone.conf.sample'))
return config_files
def test_paste_config(self):
- self.assertEqual(tests.dirs.etc('keystone-paste.ini'),
+ self.assertEqual(unit.dirs.etc('keystone-paste.ini'),
config.find_paste_config())
self.config_fixture.config(group='paste_deploy',
config_file=uuid.uuid4().hex)
self.assertRaises(exception.ConfigFileNotFound,
config.find_paste_config)
self.config_fixture.config(group='paste_deploy', config_file='')
- self.assertEqual(tests.dirs.etc('keystone.conf.sample'),
+ self.assertEqual(unit.dirs.etc('keystone.conf.sample'),
config.find_paste_config())
def test_config_default(self):
@@ -50,12 +50,12 @@ class ConfigTestCase(tests.TestCase):
self.assertIs(None, CONF.auth.token)
-class DeprecatedTestCase(tests.TestCase):
+class DeprecatedTestCase(unit.TestCase):
"""Test using the original (deprecated) name for renamed options."""
def config_files(self):
config_files = super(DeprecatedTestCase, self).config_files()
- config_files.append(tests.dirs.tests_conf('deprecated.conf'))
+ config_files.append(unit.dirs.tests_conf('deprecated.conf'))
return config_files
def test_sql(self):
@@ -66,12 +66,12 @@ class DeprecatedTestCase(tests.TestCase):
self.assertEqual(54321, CONF.database.idle_timeout)
-class DeprecatedOverrideTestCase(tests.TestCase):
+class DeprecatedOverrideTestCase(unit.TestCase):
"""Test using the deprecated AND new name for renamed options."""
def config_files(self):
config_files = super(DeprecatedOverrideTestCase, self).config_files()
- config_files.append(tests.dirs.tests_conf('deprecated_override.conf'))
+ config_files.append(unit.dirs.tests_conf('deprecated_override.conf'))
return config_files
def test_sql(self):
diff --git a/keystone-moon/keystone/tests/unit/test_contrib_ec2.py b/keystone-moon/keystone/tests/unit/test_contrib_ec2.py
index c6717dc5..2810a47a 100644
--- a/keystone-moon/keystone/tests/unit/test_contrib_ec2.py
+++ b/keystone-moon/keystone/tests/unit/test_contrib_ec2.py
@@ -18,12 +18,12 @@ from keystoneclient.contrib.ec2 import utils as ec2_utils
from keystone.contrib.ec2 import controllers
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import default_fixtures
from keystone.tests.unit.ksfixtures import database
-class TestCredentialEc2(tests.TestCase):
+class TestCredentialEc2(unit.TestCase):
# TODO(davechen): more testcases for ec2 credential are expected here and
# the file name would be renamed to "test_credential" to correspond with
# "test_v3_credential.py".
diff --git a/keystone-moon/keystone/tests/unit/test_contrib_s3_core.py b/keystone-moon/keystone/tests/unit/test_contrib_s3_core.py
index 43ea1ac5..18c76dad 100644
--- a/keystone-moon/keystone/tests/unit/test_contrib_s3_core.py
+++ b/keystone-moon/keystone/tests/unit/test_contrib_s3_core.py
@@ -16,10 +16,10 @@ import uuid
from keystone.contrib import s3
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
-class S3ContribCore(tests.TestCase):
+class S3ContribCore(unit.TestCase):
def setUp(self):
super(S3ContribCore, self).setUp()
diff --git a/keystone-moon/keystone/tests/unit/test_contrib_simple_cert.py b/keystone-moon/keystone/tests/unit/test_contrib_simple_cert.py
index 8664e2c3..b241b41b 100644
--- a/keystone-moon/keystone/tests/unit/test_contrib_simple_cert.py
+++ b/keystone-moon/keystone/tests/unit/test_contrib_simple_cert.py
@@ -12,6 +12,8 @@
import uuid
+from six.moves import http_client
+
from keystone.tests.unit import test_v3
@@ -31,7 +33,7 @@ class TestSimpleCert(BaseTestCase):
method='GET',
path=path,
headers={'Accept': content_type},
- expected_status=200)
+ expected_status=http_client.OK)
self.assertEqual(content_type, response.content_type.lower())
self.assertIn('---BEGIN', response.body)
@@ -54,4 +56,4 @@ class TestSimpleCert(BaseTestCase):
self.request(app=self.public_app,
method='GET',
path=path,
- expected_status=500)
+ expected_status=http_client.INTERNAL_SERVER_ERROR)
diff --git a/keystone-moon/keystone/tests/unit/test_exception.py b/keystone-moon/keystone/tests/unit/test_exception.py
index bf541dfd..4d602ccc 100644
--- a/keystone-moon/keystone/tests/unit/test_exception.py
+++ b/keystone-moon/keystone/tests/unit/test_exception.py
@@ -21,10 +21,10 @@ import six
from keystone.common import wsgi
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
-class ExceptionTestCase(tests.BaseTestCase):
+class ExceptionTestCase(unit.BaseTestCase):
def assertValidJsonRendering(self, e):
resp = wsgi.render_exception(e)
self.assertEqual(e.code, resp.status_int)
diff --git a/keystone-moon/keystone/tests/unit/test_ipv6.py b/keystone-moon/keystone/tests/unit/test_ipv6.py
index e3d467fb..df59429e 100644
--- a/keystone-moon/keystone/tests/unit/test_ipv6.py
+++ b/keystone-moon/keystone/tests/unit/test_ipv6.py
@@ -16,14 +16,14 @@
from oslo_config import cfg
from keystone.common import environment
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit.ksfixtures import appserver
CONF = cfg.CONF
-class IPv6TestCase(tests.TestCase):
+class IPv6TestCase(unit.TestCase):
def setUp(self):
self.skip_if_no_ipv6()
diff --git a/keystone-moon/keystone/tests/unit/test_kvs.py b/keystone-moon/keystone/tests/unit/test_kvs.py
index 77e05e6d..18931f5d 100644
--- a/keystone-moon/keystone/tests/unit/test_kvs.py
+++ b/keystone-moon/keystone/tests/unit/test_kvs.py
@@ -26,7 +26,7 @@ from keystone.common.kvs.backends import inmemdb
from keystone.common.kvs.backends import memcached
from keystone.common.kvs import core
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
NO_VALUE = api.NO_VALUE
@@ -147,7 +147,7 @@ class TestMemcacheDriver(api.CacheBackend):
self.client.set_multi(mapping, **self.set_arguments)
-class KVSTest(tests.TestCase):
+class KVSTest(unit.TestCase):
def setUp(self):
super(KVSTest, self).setUp()
self.key_foo = 'foo_' + uuid.uuid4().hex
@@ -569,7 +569,7 @@ class KVSTest(tests.TestCase):
key=test_key)
-class TestMemcachedBackend(tests.TestCase):
+class TestMemcachedBackend(unit.TestCase):
@mock.patch('keystone.common.kvs.backends.memcached._', six.text_type)
def test_invalid_backend_fails_initialization(self):
diff --git a/keystone-moon/keystone/tests/unit/test_ldap_livetest.py b/keystone-moon/keystone/tests/unit/test_ldap_livetest.py
index b9f56e8d..e2abd56d 100644
--- a/keystone-moon/keystone/tests/unit/test_ldap_livetest.py
+++ b/keystone-moon/keystone/tests/unit/test_ldap_livetest.py
@@ -21,7 +21,7 @@ from six.moves import range
from keystone import exception
from keystone.identity.backends import ldap as identity_ldap
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import test_backend_ldap
@@ -78,7 +78,7 @@ class LiveLDAPIdentity(test_backend_ldap.LDAPIdentity):
def config_files(self):
config_files = super(LiveLDAPIdentity, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_liveldap.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_liveldap.conf'))
return config_files
def test_build_tree(self):
diff --git a/keystone-moon/keystone/tests/unit/test_ldap_pool_livetest.py b/keystone-moon/keystone/tests/unit/test_ldap_pool_livetest.py
index a8776e5b..81e91ce5 100644
--- a/keystone-moon/keystone/tests/unit/test_ldap_pool_livetest.py
+++ b/keystone-moon/keystone/tests/unit/test_ldap_pool_livetest.py
@@ -19,7 +19,7 @@ from oslo_config import cfg
from keystone.common.ldap import core as ldap_core
from keystone.identity.backends import ldap
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import fakeldap
from keystone.tests.unit import test_backend_ldap_pool
from keystone.tests.unit import test_ldap_livetest
@@ -44,8 +44,7 @@ class LiveLDAPPoolIdentity(test_backend_ldap_pool.LdapPoolCommonTestMixin,
def config_files(self):
config_files = super(LiveLDAPPoolIdentity, self).config_files()
- config_files.append(tests.dirs.
- tests_conf('backend_pool_liveldap.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_pool_liveldap.conf'))
return config_files
def test_assert_connector_used_not_fake_ldap_pool(self):
diff --git a/keystone-moon/keystone/tests/unit/test_ldap_tls_livetest.py b/keystone-moon/keystone/tests/unit/test_ldap_tls_livetest.py
index e77bbc98..6b47bfd9 100644
--- a/keystone-moon/keystone/tests/unit/test_ldap_tls_livetest.py
+++ b/keystone-moon/keystone/tests/unit/test_ldap_tls_livetest.py
@@ -18,7 +18,7 @@ from oslo_config import cfg
from keystone import exception
from keystone import identity
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import test_ldap_livetest
@@ -40,7 +40,7 @@ class LiveTLSLDAPIdentity(test_ldap_livetest.LiveLDAPIdentity):
def config_files(self):
config_files = super(LiveTLSLDAPIdentity, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_tls_liveldap.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_tls_liveldap.conf'))
return config_files
def test_tls_certfile_demand_option(self):
diff --git a/keystone-moon/keystone/tests/unit/test_middleware.py b/keystone-moon/keystone/tests/unit/test_middleware.py
index 3a26dd24..0eedb9c6 100644
--- a/keystone-moon/keystone/tests/unit/test_middleware.py
+++ b/keystone-moon/keystone/tests/unit/test_middleware.py
@@ -12,11 +12,21 @@
# License for the specific language governing permissions and limitations
# under the License.
+import hashlib
+import uuid
+
from oslo_config import cfg
+from six.moves import http_client
import webob
+from keystone.common import authorization
+from keystone.common import tokenless_auth
+from keystone.contrib.federation import constants as federation_constants
+from keystone import exception
from keystone import middleware
-from keystone.tests import unit as tests
+from keystone.tests import unit
+from keystone.tests.unit import mapping_fixtures
+from keystone.tests.unit import test_backend_sql
CONF = cfg.CONF
@@ -40,7 +50,7 @@ def make_response(**kwargs):
return webob.Response(body)
-class TokenAuthMiddlewareTest(tests.TestCase):
+class TokenAuthMiddlewareTest(unit.TestCase):
def test_request(self):
req = make_request()
req.headers[middleware.AUTH_TOKEN_HEADER] = 'MAGIC'
@@ -49,7 +59,7 @@ class TokenAuthMiddlewareTest(tests.TestCase):
self.assertEqual('MAGIC', context['token_id'])
-class AdminTokenAuthMiddlewareTest(tests.TestCase):
+class AdminTokenAuthMiddlewareTest(unit.TestCase):
def test_request_admin(self):
req = make_request()
req.headers[middleware.AUTH_TOKEN_HEADER] = CONF.admin_token
@@ -65,7 +75,7 @@ class AdminTokenAuthMiddlewareTest(tests.TestCase):
self.assertFalse(context['is_admin'])
-class PostParamsMiddlewareTest(tests.TestCase):
+class PostParamsMiddlewareTest(unit.TestCase):
def test_request_with_params(self):
req = make_request(body="arg1=one", method='POST')
middleware.PostParamsMiddleware(None).process_request(req)
@@ -73,7 +83,7 @@ class PostParamsMiddlewareTest(tests.TestCase):
self.assertEqual({"arg1": "one"}, params)
-class JsonBodyMiddlewareTest(tests.TestCase):
+class JsonBodyMiddlewareTest(unit.TestCase):
def test_request_with_params(self):
req = make_request(body='{"arg1": "one", "arg2": ["a"]}',
content_type='application/json',
@@ -87,14 +97,14 @@ class JsonBodyMiddlewareTest(tests.TestCase):
content_type='application/json',
method='POST')
resp = middleware.JsonBodyMiddleware(None).process_request(req)
- self.assertEqual(400, resp.status_int)
+ self.assertEqual(http_client.BAD_REQUEST, resp.status_int)
def test_not_dict_body(self):
req = make_request(body='42',
content_type='application/json',
method='POST')
resp = middleware.JsonBodyMiddleware(None).process_request(req)
- self.assertEqual(400, resp.status_int)
+ self.assertEqual(http_client.BAD_REQUEST, resp.status_int)
self.assertTrue('valid JSON object' in resp.json['error']['message'])
def test_no_content_type(self):
@@ -109,7 +119,7 @@ class JsonBodyMiddlewareTest(tests.TestCase):
content_type='text/plain',
method='POST')
resp = middleware.JsonBodyMiddleware(None).process_request(req)
- self.assertEqual(400, resp.status_int)
+ self.assertEqual(http_client.BAD_REQUEST, resp.status_int)
def test_unrecognized_content_type_without_body(self):
req = make_request(content_type='text/plain',
@@ -117,3 +127,624 @@ class JsonBodyMiddlewareTest(tests.TestCase):
middleware.JsonBodyMiddleware(None).process_request(req)
params = req.environ.get(middleware.PARAMS_ENV, {})
self.assertEqual({}, params)
+
+
+class AuthContextMiddlewareTest(test_backend_sql.SqlTests):
+
+ def setUp(self):
+ super(AuthContextMiddlewareTest, self).setUp()
+ self.client_issuer = uuid.uuid4().hex
+ self.untrusted_client_issuer = uuid.uuid4().hex
+ self.trusted_issuer = self.client_issuer
+ self.config_fixture.config(group='tokenless_auth',
+ trusted_issuer=[self.trusted_issuer])
+
+ # This idp_id is calculated based on
+ # sha256(self.client_issuer)
+ hashed_idp = hashlib.sha256(self.client_issuer)
+ self.idp_id = hashed_idp.hexdigest()
+ self._load_sample_data()
+
+ def _load_sample_data(self):
+ self.domain_id = uuid.uuid4().hex
+ self.domain_name = uuid.uuid4().hex
+ self.project_id = uuid.uuid4().hex
+ self.project_name = uuid.uuid4().hex
+ self.user_name = uuid.uuid4().hex
+ self.user_password = uuid.uuid4().hex
+ self.user_email = uuid.uuid4().hex
+ self.protocol_id = 'x509'
+ self.role_id = uuid.uuid4().hex
+ self.role_name = uuid.uuid4().hex
+ # for ephemeral user
+ self.group_name = uuid.uuid4().hex
+
+ # 1) Create a domain for the user.
+ self.domain = {
+ 'description': uuid.uuid4().hex,
+ 'enabled': True,
+ 'id': self.domain_id,
+ 'name': self.domain_name,
+ }
+
+ self.resource_api.create_domain(self.domain_id, self.domain)
+
+ # 2) Create a project for the user.
+ self.project = {
+ 'description': uuid.uuid4().hex,
+ 'domain_id': self.domain_id,
+ 'enabled': True,
+ 'id': self.project_id,
+ 'name': self.project_name,
+ }
+
+ self.resource_api.create_project(self.project_id, self.project)
+
+ # 3) Create a user in new domain.
+ self.user = {
+ 'name': self.user_name,
+ 'domain_id': self.domain_id,
+ 'project_id': self.project_id,
+ 'password': self.user_password,
+ 'email': self.user_email,
+ }
+
+ self.user = self.identity_api.create_user(self.user)
+
+ # Add IDP
+ self.idp = self._idp_ref(id=self.idp_id)
+ self.federation_api.create_idp(self.idp['id'],
+ self.idp)
+
+ # Add a role
+ self.role = {
+ 'id': self.role_id,
+ 'name': self.role_name,
+ }
+ self.role_api.create_role(self.role_id, self.role)
+
+ # Add a group
+ self.group = {
+ 'name': self.group_name,
+ 'domain_id': self.domain_id,
+ }
+ self.group = self.identity_api.create_group(self.group)
+
+ # Assign a role to the user on a project
+ self.assignment_api.add_role_to_user_and_project(
+ user_id=self.user['id'],
+ tenant_id=self.project_id,
+ role_id=self.role_id)
+
+ # Assign a role to the group on a project
+ self.assignment_api.create_grant(
+ role_id=self.role_id,
+ group_id=self.group['id'],
+ project_id=self.project_id)
+
+ def _load_mapping_rules(self, rules):
+ # Add a mapping
+ self.mapping = self._mapping_ref(rules=rules)
+ self.federation_api.create_mapping(self.mapping['id'],
+ self.mapping)
+ # Add protocols
+ self.proto_x509 = self._proto_ref(mapping_id=self.mapping['id'])
+ self.proto_x509['id'] = self.protocol_id
+ self.federation_api.create_protocol(self.idp['id'],
+ self.proto_x509['id'],
+ self.proto_x509)
+
+ def _idp_ref(self, id=None):
+ idp = {
+ 'id': id or uuid.uuid4().hex,
+ 'enabled': True,
+ 'description': uuid.uuid4().hex
+ }
+ return idp
+
+ def _proto_ref(self, mapping_id=None):
+ proto = {
+ 'id': uuid.uuid4().hex,
+ 'mapping_id': mapping_id or uuid.uuid4().hex
+ }
+ return proto
+
+ def _mapping_ref(self, rules=None):
+ if rules is None:
+ mapped_rules = {}
+ else:
+ mapped_rules = rules.get('rules', {})
+ return {
+ 'id': uuid.uuid4().hex,
+ 'rules': mapped_rules
+ }
+
+ def _assert_tokenless_auth_context(self, context, ephemeral_user=False):
+ self.assertIsNotNone(context)
+ self.assertEqual(self.project_id, context['project_id'])
+ self.assertIn(self.role_name, context['roles'])
+ if ephemeral_user:
+ self.assertEqual(self.group['id'], context['group_ids'][0])
+ self.assertEqual('ephemeral',
+ context[federation_constants.PROTOCOL])
+ self.assertEqual(self.idp_id,
+ context[federation_constants.IDENTITY_PROVIDER])
+ else:
+ self.assertEqual(self.user['id'], context['user_id'])
+
+ def _create_context(self, request, mapping_ref=None,
+ exception_expected=False):
+ """Builds the auth context from the given arguments.
+
+ auth context will be returned from the AuthContextMiddleware based on
+ what is being passed in the given request and what mapping is being
+ setup in the backend DB.
+
+ :param request: HTTP request
+ :param mapping_ref: A mapping in JSON structure will be setup in the
+ backend DB for mapping an user or a group.
+ :param exception_expected: Sets to True when an exception is expected
+ to raised based on the given arguments.
+ :returns: context an auth context contains user and role information
+ :rtype: dict
+ """
+ if mapping_ref:
+ self._load_mapping_rules(mapping_ref)
+
+ if not exception_expected:
+ (middleware.AuthContextMiddleware('Tokenless_auth_test').
+ process_request(request))
+ context = request.environ.get(authorization.AUTH_CONTEXT_ENV)
+ else:
+ context = middleware.AuthContextMiddleware('Tokenless_auth_test')
+ return context
+
+ def test_context_already_exists(self):
+ req = make_request()
+ token_id = uuid.uuid4().hex
+ req.environ[authorization.AUTH_CONTEXT_ENV] = {'token_id': token_id}
+ context = self._create_context(request=req)
+ self.assertEqual(token_id, context['token_id'])
+
+ def test_not_applicable_to_token_request(self):
+ env = {}
+ env['PATH_INFO'] = '/auth/tokens'
+ env['REQUEST_METHOD'] = 'POST'
+ req = make_request(environ=env)
+ context = self._create_context(request=req)
+ self.assertIsNone(context)
+
+ def test_no_tokenless_attributes_request(self):
+ req = make_request()
+ context = self._create_context(request=req)
+ self.assertIsNone(context)
+
+ def test_no_issuer_attribute_request(self):
+ env = {}
+ env['HTTP_X_PROJECT_ID'] = uuid.uuid4().hex
+ req = make_request(environ=env)
+ context = self._create_context(request=req)
+ self.assertIsNone(context)
+
+ def test_has_only_issuer_and_project_name_request(self):
+ env = {}
+ # SSL_CLIENT_I_DN is the attribute name that wsgi env
+ # references to issuer of the client certificate.
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = uuid.uuid4().hex
+ req = make_request(environ=env)
+ context = self._create_context(request=req,
+ exception_expected=True)
+ self.assertRaises(exception.ValidationError,
+ context.process_request,
+ req)
+
+ def test_has_only_issuer_and_project_domain_name_request(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_DOMAIN_NAME'] = uuid.uuid4().hex
+ req = make_request(environ=env)
+ context = self._create_context(request=req,
+ exception_expected=True)
+ self.assertRaises(exception.ValidationError,
+ context.process_request,
+ req)
+
+ def test_has_only_issuer_and_project_domain_id_request(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_DOMAIN_ID'] = uuid.uuid4().hex
+ req = make_request(environ=env)
+ context = self._create_context(request=req,
+ exception_expected=True)
+ self.assertRaises(exception.ValidationError,
+ context.process_request,
+ req)
+
+ def test_missing_both_domain_and_project_request(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ req = make_request(environ=env)
+ context = self._create_context(request=req,
+ exception_expected=True)
+ self.assertRaises(exception.ValidationError,
+ context.process_request,
+ req)
+
+ def test_empty_trusted_issuer_list(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_ID'] = uuid.uuid4().hex
+ req = make_request(environ=env)
+ self.config_fixture.config(group='tokenless_auth',
+ trusted_issuer=[])
+ context = self._create_context(request=req)
+ self.assertIsNone(context)
+
+ def test_client_issuer_not_trusted(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.untrusted_client_issuer
+ env['HTTP_X_PROJECT_ID'] = uuid.uuid4().hex
+ req = make_request(environ=env)
+ context = self._create_context(request=req)
+ self.assertIsNone(context)
+
+ def test_proj_scope_with_proj_id_and_proj_dom_id_success(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_ID'] = self.project_id
+ env['HTTP_X_PROJECT_DOMAIN_ID'] = self.domain_id
+ # SSL_CLIENT_USER_NAME and SSL_CLIENT_DOMAIN_NAME are the types
+ # defined in the mapping that will map to the user name and
+ # domain name
+ env['SSL_CLIENT_USER_NAME'] = self.user_name
+ env['SSL_CLIENT_DOMAIN_NAME'] = self.domain_name
+ req = make_request(environ=env)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_USERNAME_AND_DOMAINNAME)
+ self._assert_tokenless_auth_context(context)
+
+ def test_proj_scope_with_proj_id_only_success(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_ID'] = self.project_id
+ env['SSL_CLIENT_USER_NAME'] = self.user_name
+ env['SSL_CLIENT_DOMAIN_NAME'] = self.domain_name
+ req = make_request(environ=env)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_USERNAME_AND_DOMAINNAME)
+ self._assert_tokenless_auth_context(context)
+
+ def test_proj_scope_with_proj_name_and_proj_dom_id_success(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = self.project_name
+ env['HTTP_X_PROJECT_DOMAIN_ID'] = self.domain_id
+ env['SSL_CLIENT_USER_NAME'] = self.user_name
+ env['SSL_CLIENT_DOMAIN_NAME'] = self.domain_name
+ req = make_request(environ=env)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_USERNAME_AND_DOMAINNAME)
+ self._assert_tokenless_auth_context(context)
+
+ def test_proj_scope_with_proj_name_and_proj_dom_name_success(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = self.project_name
+ env['HTTP_X_PROJECT_DOMAIN_NAME'] = self.domain_name
+ env['SSL_CLIENT_USER_NAME'] = self.user_name
+ env['SSL_CLIENT_DOMAIN_NAME'] = self.domain_name
+ req = make_request(environ=env)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_USERNAME_AND_DOMAINNAME)
+ self._assert_tokenless_auth_context(context)
+
+ def test_proj_scope_with_proj_name_only_fail(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = self.project_id
+ env['SSL_CLIENT_USER_NAME'] = self.user_name
+ env['SSL_CLIENT_DOMAIN_NAME'] = self.domain_name
+ req = make_request(environ=env)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_USERNAME_AND_DOMAINNAME,
+ exception_expected=True)
+ self.assertRaises(exception.ValidationError,
+ context.process_request,
+ req)
+
+ def test_mapping_with_userid_and_domainid_success(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = self.project_name
+ env['HTTP_X_PROJECT_DOMAIN_NAME'] = self.domain_name
+ env['SSL_CLIENT_USER_ID'] = self.user['id']
+ env['SSL_CLIENT_DOMAIN_ID'] = self.domain_id
+ req = make_request(environ=env)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_USERID_AND_DOMAINID)
+ self._assert_tokenless_auth_context(context)
+
+ def test_mapping_with_userid_and_domainname_success(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = self.project_name
+ env['HTTP_X_PROJECT_DOMAIN_NAME'] = self.domain_name
+ env['SSL_CLIENT_USER_ID'] = self.user['id']
+ env['SSL_CLIENT_DOMAIN_NAME'] = self.domain_name
+ req = make_request(environ=env)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_USERID_AND_DOMAINNAME)
+ self._assert_tokenless_auth_context(context)
+
+ def test_mapping_with_username_and_domainid_success(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = self.project_name
+ env['HTTP_X_PROJECT_DOMAIN_NAME'] = self.domain_name
+ env['SSL_CLIENT_USER_NAME'] = self.user_name
+ env['SSL_CLIENT_DOMAIN_ID'] = self.domain_id
+ req = make_request(environ=env)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_USERNAME_AND_DOMAINID)
+ self._assert_tokenless_auth_context(context)
+
+ def test_only_domain_name_fail(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_ID'] = self.project_id
+ env['HTTP_X_PROJECT_DOMAIN_ID'] = self.domain_id
+ env['SSL_CLIENT_DOMAIN_NAME'] = self.domain_name
+ req = make_request(environ=env)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_DOMAINNAME_ONLY,
+ exception_expected=True)
+ self.assertRaises(exception.ValidationError,
+ context.process_request,
+ req)
+
+ def test_only_domain_id_fail(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_ID'] = self.project_id
+ env['HTTP_X_PROJECT_DOMAIN_ID'] = self.domain_id
+ env['SSL_CLIENT_DOMAIN_ID'] = self.domain_id
+ req = make_request(environ=env)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_DOMAINID_ONLY,
+ exception_expected=True)
+ self.assertRaises(exception.ValidationError,
+ context.process_request,
+ req)
+
+ def test_missing_domain_data_fail(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_ID'] = self.project_id
+ env['HTTP_X_PROJECT_DOMAIN_ID'] = self.domain_id
+ env['SSL_CLIENT_USER_NAME'] = self.user_name
+ req = make_request(environ=env)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_USERNAME_ONLY,
+ exception_expected=True)
+ self.assertRaises(exception.ValidationError,
+ context.process_request,
+ req)
+
+ def test_userid_success(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_ID'] = self.project_id
+ env['HTTP_X_PROJECT_DOMAIN_ID'] = self.domain_id
+ env['SSL_CLIENT_USER_ID'] = self.user['id']
+ req = make_request(environ=env)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_USERID_ONLY)
+ self._assert_tokenless_auth_context(context)
+
+ def test_domain_disable_fail(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = self.project_name
+ env['HTTP_X_PROJECT_DOMAIN_NAME'] = self.domain_name
+ env['SSL_CLIENT_USER_NAME'] = self.user_name
+ env['SSL_CLIENT_DOMAIN_ID'] = self.domain_id
+ req = make_request(environ=env)
+ self.domain['enabled'] = False
+ self.domain = self.resource_api.update_domain(
+ self.domain['id'], self.domain)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_USERNAME_AND_DOMAINID,
+ exception_expected=True)
+ self.assertRaises(exception.Unauthorized,
+ context.process_request,
+ req)
+
+ def test_user_disable_fail(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = self.project_name
+ env['HTTP_X_PROJECT_DOMAIN_NAME'] = self.domain_name
+ env['SSL_CLIENT_USER_NAME'] = self.user_name
+ env['SSL_CLIENT_DOMAIN_ID'] = self.domain_id
+ req = make_request(environ=env)
+ self.user['enabled'] = False
+ self.user = self.identity_api.update_user(self.user['id'], self.user)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_USERNAME_AND_DOMAINID,
+ exception_expected=True)
+ self.assertRaises(AssertionError,
+ context.process_request,
+ req)
+
+ def test_invalid_user_fail(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_ID'] = self.project_id
+ env['HTTP_X_PROJECT_DOMAIN_ID'] = self.domain_id
+ env['SSL_CLIENT_USER_NAME'] = uuid.uuid4().hex
+ env['SSL_CLIENT_DOMAIN_NAME'] = self.domain_name
+ req = make_request(environ=env)
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping_fixtures.MAPPING_WITH_USERNAME_AND_DOMAINNAME,
+ exception_expected=True)
+ self.assertRaises(exception.UserNotFound,
+ context.process_request,
+ req)
+
+ def test_ephemeral_success(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = self.project_name
+ env['HTTP_X_PROJECT_DOMAIN_NAME'] = self.domain_name
+ env['SSL_CLIENT_USER_NAME'] = self.user_name
+ req = make_request(environ=env)
+ self.config_fixture.config(group='tokenless_auth',
+ protocol='ephemeral')
+ self.protocol_id = 'ephemeral'
+ mapping = mapping_fixtures.MAPPING_FOR_EPHEMERAL_USER.copy()
+ mapping['rules'][0]['local'][0]['group']['id'] = self.group['id']
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping)
+ self._assert_tokenless_auth_context(context, ephemeral_user=True)
+
+ def test_ephemeral_with_default_user_type_success(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = self.project_name
+ env['HTTP_X_PROJECT_DOMAIN_NAME'] = self.domain_name
+ env['SSL_CLIENT_USER_NAME'] = self.user_name
+ req = make_request(environ=env)
+ self.config_fixture.config(group='tokenless_auth',
+ protocol='ephemeral')
+ self.protocol_id = 'ephemeral'
+ # this mapping does not have the user type defined
+ # and it should defaults to 'ephemeral' which is
+ # the expected type for the test case.
+ mapping = mapping_fixtures.MAPPING_FOR_DEFAULT_EPHEMERAL_USER.copy()
+ mapping['rules'][0]['local'][0]['group']['id'] = self.group['id']
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping)
+ self._assert_tokenless_auth_context(context, ephemeral_user=True)
+
+ def test_ephemeral_any_user_success(self):
+ """Ephemeral user does not need a specified user
+ Keystone is not looking to match the user, but a corresponding group.
+ """
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = self.project_name
+ env['HTTP_X_PROJECT_DOMAIN_NAME'] = self.domain_name
+ env['SSL_CLIENT_USER_NAME'] = uuid.uuid4().hex
+ req = make_request(environ=env)
+ self.config_fixture.config(group='tokenless_auth',
+ protocol='ephemeral')
+ self.protocol_id = 'ephemeral'
+ mapping = mapping_fixtures.MAPPING_FOR_EPHEMERAL_USER.copy()
+ mapping['rules'][0]['local'][0]['group']['id'] = self.group['id']
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping)
+ self._assert_tokenless_auth_context(context, ephemeral_user=True)
+
+ def test_ephemeral_invalid_scope_fail(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = uuid.uuid4().hex
+ env['HTTP_X_PROJECT_DOMAIN_NAME'] = uuid.uuid4().hex
+ env['SSL_CLIENT_USER_NAME'] = self.user_name
+ req = make_request(environ=env)
+ self.config_fixture.config(group='tokenless_auth',
+ protocol='ephemeral')
+ self.protocol_id = 'ephemeral'
+ mapping = mapping_fixtures.MAPPING_FOR_EPHEMERAL_USER.copy()
+ mapping['rules'][0]['local'][0]['group']['id'] = self.group['id']
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping,
+ exception_expected=True)
+ self.assertRaises(exception.Unauthorized,
+ context.process_request,
+ req)
+
+ def test_ephemeral_no_group_found_fail(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = self.project_name
+ env['HTTP_X_PROJECT_DOMAIN_NAME'] = self.domain_name
+ env['SSL_CLIENT_USER_NAME'] = self.user_name
+ req = make_request(environ=env)
+ self.config_fixture.config(group='tokenless_auth',
+ protocol='ephemeral')
+ self.protocol_id = 'ephemeral'
+ mapping = mapping_fixtures.MAPPING_FOR_EPHEMERAL_USER.copy()
+ mapping['rules'][0]['local'][0]['group']['id'] = uuid.uuid4().hex
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping,
+ exception_expected=True)
+ self.assertRaises(exception.MappedGroupNotFound,
+ context.process_request,
+ req)
+
+ def test_ephemeral_incorrect_mapping_fail(self):
+ """Ephemeral user picks up the non-ephemeral user mapping.
+ Looking up the mapping with protocol Id 'x509' will load up
+ the non-ephemeral user mapping, results unauthenticated.
+ """
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ env['HTTP_X_PROJECT_NAME'] = self.project_name
+ env['HTTP_X_PROJECT_DOMAIN_NAME'] = self.domain_name
+ env['SSL_CLIENT_USER_NAME'] = self.user_name
+ req = make_request(environ=env)
+ # This will pick up the incorrect mapping
+ self.config_fixture.config(group='tokenless_auth',
+ protocol='x509')
+ self.protocol_id = 'x509'
+ mapping = mapping_fixtures.MAPPING_FOR_EPHEMERAL_USER.copy()
+ mapping['rules'][0]['local'][0]['group']['id'] = uuid.uuid4().hex
+ context = self._create_context(
+ request=req,
+ mapping_ref=mapping,
+ exception_expected=True)
+ self.assertRaises(exception.MappedGroupNotFound,
+ context.process_request,
+ req)
+
+ def test_create_idp_id_success(self):
+ env = {}
+ env['SSL_CLIENT_I_DN'] = self.client_issuer
+ auth = tokenless_auth.TokenlessAuthHelper(env)
+ idp_id = auth._build_idp_id()
+ self.assertEqual(self.idp_id, idp_id)
+
+ def test_create_idp_id_attri_not_found_fail(self):
+ env = {}
+ env[uuid.uuid4().hex] = self.client_issuer
+ auth = tokenless_auth.TokenlessAuthHelper(env)
+ expected_msg = ('Could not determine Identity Provider ID. The '
+ 'configuration option %s was not found in the '
+ 'request environment.' %
+ CONF.tokenless_auth.issuer_attribute)
+ # Check the content of the exception message as well
+ self.assertRaisesRegexp(exception.TokenlessAuthConfigError,
+ expected_msg,
+ auth._build_idp_id)
diff --git a/keystone-moon/keystone/tests/unit/test_no_admin_token_auth.py b/keystone-moon/keystone/tests/unit/test_no_admin_token_auth.py
index 9f67fbd7..bf60cff0 100644
--- a/keystone-moon/keystone/tests/unit/test_no_admin_token_auth.py
+++ b/keystone-moon/keystone/tests/unit/test_no_admin_token_auth.py
@@ -14,12 +14,13 @@
import os
+from six.moves import http_client
import webtest
-from keystone.tests import unit as tests
+from keystone.tests import unit
-class TestNoAdminTokenAuth(tests.TestCase):
+class TestNoAdminTokenAuth(unit.TestCase):
def setUp(self):
super(TestNoAdminTokenAuth, self).setUp()
self.load_backends()
@@ -27,7 +28,7 @@ class TestNoAdminTokenAuth(tests.TestCase):
self._generate_paste_config()
self.admin_app = webtest.TestApp(
- self.loadapp(tests.dirs.tmp('no_admin_token_auth'), name='admin'),
+ self.loadapp(unit.dirs.tmp('no_admin_token_auth'), name='admin'),
extra_environ=dict(REMOTE_ADDR='127.0.0.1'))
self.addCleanup(setattr, self, 'admin_app', None)
@@ -35,12 +36,12 @@ class TestNoAdminTokenAuth(tests.TestCase):
# Generate a file, based on keystone-paste.ini, that doesn't include
# admin_token_auth in the pipeline
- with open(tests.dirs.etc('keystone-paste.ini'), 'r') as f:
+ with open(unit.dirs.etc('keystone-paste.ini'), 'r') as f:
contents = f.read()
new_contents = contents.replace(' admin_token_auth ', ' ')
- filename = tests.dirs.tmp('no_admin_token_auth-paste.ini')
+ filename = unit.dirs.tmp('no_admin_token_auth-paste.ini')
with open(filename, 'w') as f:
f.write(new_contents)
self.addCleanup(os.remove, filename)
@@ -56,4 +57,4 @@ class TestNoAdminTokenAuth(tests.TestCase):
# If the following does not raise, then the test is successful.
self.admin_app.get(REQ_PATH, headers={'X-Auth-Token': 'NotAdminToken'},
- status=401)
+ status=http_client.UNAUTHORIZED)
diff --git a/keystone-moon/keystone/tests/unit/test_policy.py b/keystone-moon/keystone/tests/unit/test_policy.py
index 30df0b2b..b2f0e525 100644
--- a/keystone-moon/keystone/tests/unit/test_policy.py
+++ b/keystone-moon/keystone/tests/unit/test_policy.py
@@ -24,11 +24,11 @@ from testtools import matchers
from keystone import exception
from keystone.policy.backends import rules
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit.ksfixtures import temporaryfile
-class BasePolicyTestCase(tests.TestCase):
+class BasePolicyTestCase(unit.TestCase):
def setUp(self):
super(BasePolicyTestCase, self).setUp()
rules.reset()
@@ -214,15 +214,15 @@ class DefaultPolicyTestCase(BasePolicyTestCase):
self.credentials, "example:noexist", {})
-class PolicyJsonTestCase(tests.TestCase):
+class PolicyJsonTestCase(unit.TestCase):
def _load_entries(self, filename):
return set(json.load(open(filename)))
def test_json_examples_have_matching_entries(self):
- policy_keys = self._load_entries(tests.dirs.etc('policy.json'))
+ policy_keys = self._load_entries(unit.dirs.etc('policy.json'))
cloud_policy_keys = self._load_entries(
- tests.dirs.etc('policy.v3cloudsample.json'))
+ unit.dirs.etc('policy.v3cloudsample.json'))
policy_extra_keys = ['admin_or_token_subject',
'service_admin_or_token_subject',
@@ -236,7 +236,7 @@ class PolicyJsonTestCase(tests.TestCase):
# All the targets in the sample policy file must be documented in
# doc/source/policy_mapping.rst.
- policy_keys = self._load_entries(tests.dirs.etc('policy.json'))
+ policy_keys = self._load_entries(unit.dirs.etc('policy.json'))
# These keys are in the policy.json but aren't targets.
policy_rule_keys = [
@@ -249,7 +249,7 @@ class PolicyJsonTestCase(tests.TestCase):
# targets.
doc_path = os.path.join(
- tests.ROOTDIR, 'doc', 'source', 'policy_mapping.rst')
+ unit.ROOTDIR, 'doc', 'source', 'policy_mapping.rst')
with open(doc_path) as doc_file:
for line in doc_file:
if line.startswith('Target'):
diff --git a/keystone-moon/keystone/tests/unit/test_revoke.py b/keystone-moon/keystone/tests/unit/test_revoke.py
index 5394688c..9062981f 100644
--- a/keystone-moon/keystone/tests/unit/test_revoke.py
+++ b/keystone-moon/keystone/tests/unit/test_revoke.py
@@ -22,7 +22,7 @@ from testtools import matchers
from keystone.common import utils
from keystone.contrib.revoke import model
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import test_backend_sql
from keystone.token import provider
@@ -191,7 +191,7 @@ class SqlRevokeTests(test_backend_sql.SqlTests, RevokeTests):
revoke_by_id=False)
-class KvsRevokeTests(tests.TestCase, RevokeTests):
+class KvsRevokeTests(unit.TestCase, RevokeTests):
def config_overrides(self):
super(KvsRevokeTests, self).config_overrides()
self.config_fixture.config(group='revoke', driver='kvs')
@@ -205,7 +205,7 @@ class KvsRevokeTests(tests.TestCase, RevokeTests):
self.load_backends()
-class RevokeTreeTests(tests.TestCase):
+class RevokeTreeTests(unit.TestCase):
def setUp(self):
super(RevokeTreeTests, self).setUp()
self.events = []
diff --git a/keystone-moon/keystone/tests/unit/test_sql_livetest.py b/keystone-moon/keystone/tests/unit/test_sql_livetest.py
index 96ee6c70..e2186907 100644
--- a/keystone-moon/keystone/tests/unit/test_sql_livetest.py
+++ b/keystone-moon/keystone/tests/unit/test_sql_livetest.py
@@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import test_sql_migrate_extensions
from keystone.tests.unit import test_sql_upgrade
@@ -24,7 +24,7 @@ class PostgresqlMigrateTests(test_sql_upgrade.SqlUpgradeTests):
def config_files(self):
files = super(PostgresqlMigrateTests, self).config_files()
- files.append(tests.dirs.tests_conf("backend_postgresql.conf"))
+ files.append(unit.dirs.tests_conf("backend_postgresql.conf"))
return files
@@ -35,7 +35,7 @@ class MysqlMigrateTests(test_sql_upgrade.SqlUpgradeTests):
def config_files(self):
files = super(MysqlMigrateTests, self).config_files()
- files.append(tests.dirs.tests_conf("backend_mysql.conf"))
+ files.append(unit.dirs.tests_conf("backend_mysql.conf"))
return files
@@ -47,7 +47,7 @@ class PostgresqlRevokeExtensionsTests(
def config_files(self):
files = super(PostgresqlRevokeExtensionsTests, self).config_files()
- files.append(tests.dirs.tests_conf("backend_postgresql.conf"))
+ files.append(unit.dirs.tests_conf("backend_postgresql.conf"))
return files
@@ -58,7 +58,7 @@ class MysqlRevokeExtensionsTests(test_sql_migrate_extensions.RevokeExtension):
def config_files(self):
files = super(MysqlRevokeExtensionsTests, self).config_files()
- files.append(tests.dirs.tests_conf("backend_mysql.conf"))
+ files.append(unit.dirs.tests_conf("backend_mysql.conf"))
return files
@@ -69,5 +69,5 @@ class Db2MigrateTests(test_sql_upgrade.SqlUpgradeTests):
def config_files(self):
files = super(Db2MigrateTests, self).config_files()
- files.append(tests.dirs.tests_conf("backend_db2.conf"))
+ files.append(unit.dirs.tests_conf("backend_db2.conf"))
return files
diff --git a/keystone-moon/keystone/tests/unit/test_sql_upgrade.py b/keystone-moon/keystone/tests/unit/test_sql_upgrade.py
index 96dfa9e8..d617d445 100644
--- a/keystone-moon/keystone/tests/unit/test_sql_upgrade.py
+++ b/keystone-moon/keystone/tests/unit/test_sql_upgrade.py
@@ -48,7 +48,7 @@ from keystone.common.sql import migration_helpers
from keystone.contrib import federation
from keystone.contrib import revoke
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import default_fixtures
from keystone.tests.unit.ksfixtures import database
@@ -124,14 +124,14 @@ EXTENSIONS = {'federation': federation,
'revoke': revoke}
-class SqlMigrateBase(tests.SQLDriverOverrides, tests.TestCase):
+class SqlMigrateBase(unit.SQLDriverOverrides, unit.TestCase):
def initialize_sql(self):
self.metadata = sqlalchemy.MetaData()
self.metadata.bind = self.engine
def config_files(self):
config_files = super(SqlMigrateBase, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_sql.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_sql.conf'))
return config_files
def repo_package(self):
@@ -141,15 +141,15 @@ class SqlMigrateBase(tests.SQLDriverOverrides, tests.TestCase):
super(SqlMigrateBase, self).setUp()
database.initialize_sql_session()
conn_str = CONF.database.connection
- if (conn_str != tests.IN_MEM_DB_CONN_STRING and
+ if (conn_str != unit.IN_MEM_DB_CONN_STRING and
conn_str.startswith('sqlite') and
- conn_str[10:] == tests.DEFAULT_TEST_DB_FILE):
+ conn_str[10:] == unit.DEFAULT_TEST_DB_FILE):
# Override the default with a DB that is specific to the migration
# tests only if the DB Connection string is the same as the global
# default. This is required so that no conflicts occur due to the
# global default DB already being under migrate control. This is
# only needed if the DB is not-in-memory
- db_file = tests.dirs.tmp('keystone_migrate_test.db')
+ db_file = unit.dirs.tmp('keystone_migrate_test.db')
self.config_fixture.config(
group='database',
connection='sqlite:///%s' % db_file)
@@ -636,6 +636,13 @@ class SqlUpgradeTests(SqlMigrateBase):
'enabled', 'domain_id', 'parent_id',
'is_domain'])
+ def test_add_config_registration(self):
+ config_registration = 'config_register'
+ self.upgrade(74)
+ self.assertTableDoesNotExist(config_registration)
+ self.upgrade(75)
+ self.assertTableColumns(config_registration, ['type', 'domain_id'])
+
def populate_user_table(self, with_pass_enab=False,
with_pass_enab_domain=False):
# Populate the appropriate fields in the user
diff --git a/keystone-moon/keystone/tests/unit/test_ssl.py b/keystone-moon/keystone/tests/unit/test_ssl.py
index 3b86bb2d..6a6d9ffb 100644
--- a/keystone-moon/keystone/tests/unit/test_ssl.py
+++ b/keystone-moon/keystone/tests/unit/test_ssl.py
@@ -19,21 +19,21 @@ import ssl
from oslo_config import cfg
from keystone.common import environment
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit.ksfixtures import appserver
CONF = cfg.CONF
-CERTDIR = tests.dirs.root('examples', 'pki', 'certs')
-KEYDIR = tests.dirs.root('examples', 'pki', 'private')
+CERTDIR = unit.dirs.root('examples', 'pki', 'certs')
+KEYDIR = unit.dirs.root('examples', 'pki', 'private')
CERT = os.path.join(CERTDIR, 'ssl_cert.pem')
KEY = os.path.join(KEYDIR, 'ssl_key.pem')
CA = os.path.join(CERTDIR, 'cacert.pem')
CLIENT = os.path.join(CERTDIR, 'middleware.pem')
-class SSLTestCase(tests.TestCase):
+class SSLTestCase(unit.TestCase):
def setUp(self):
super(SSLTestCase, self).setUp()
raise self.skipTest('SSL Version and Ciphers cannot be configured '
diff --git a/keystone-moon/keystone/tests/unit/test_token_bind.py b/keystone-moon/keystone/tests/unit/test_token_bind.py
index 7dc7ccca..ee4d011a 100644
--- a/keystone-moon/keystone/tests/unit/test_token_bind.py
+++ b/keystone-moon/keystone/tests/unit/test_token_bind.py
@@ -18,7 +18,7 @@ import uuid
from keystone.common import wsgi
from keystone import exception
from keystone.models import token_model
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import test_token_provider
@@ -26,7 +26,7 @@ KERBEROS_BIND = 'USER@REALM'
ANY = 'any'
-class BindTest(tests.TestCase):
+class BindTest(unit.TestCase):
"""Test binding tokens to a Principal.
Even though everything in this file references kerberos the same concepts
diff --git a/keystone-moon/keystone/tests/unit/test_token_provider.py b/keystone-moon/keystone/tests/unit/test_token_provider.py
index 3ebb0187..f60f7d53 100644
--- a/keystone-moon/keystone/tests/unit/test_token_provider.py
+++ b/keystone-moon/keystone/tests/unit/test_token_provider.py
@@ -20,7 +20,7 @@ from oslo_utils import timeutils
from keystone.common import dependency
from keystone.common import utils
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit.ksfixtures import database
from keystone import token
from keystone.token.providers import fernet
@@ -712,7 +712,7 @@ SAMPLE_MALFORMED_TOKEN = {
}
-class TestTokenProvider(tests.TestCase):
+class TestTokenProvider(unit.TestCase):
def setUp(self):
super(TestTokenProvider, self).setUp()
self.useFixture(database.Database())
@@ -817,7 +817,7 @@ class PKIProviderTests(object):
token_data)
-class TestPKIProviderWithEventlet(PKIProviderTests, tests.TestCase):
+class TestPKIProviderWithEventlet(PKIProviderTests, unit.TestCase):
def setUp(self):
# force keystoneclient.common.cms to use eventlet's subprocess
@@ -827,7 +827,7 @@ class TestPKIProviderWithEventlet(PKIProviderTests, tests.TestCase):
super(TestPKIProviderWithEventlet, self).setUp()
-class TestPKIProviderWithStdlib(PKIProviderTests, tests.TestCase):
+class TestPKIProviderWithStdlib(PKIProviderTests, unit.TestCase):
def setUp(self):
# force keystoneclient.common.cms to use the stdlib subprocess
diff --git a/keystone-moon/keystone/tests/unit/test_url_middleware.py b/keystone-moon/keystone/tests/unit/test_url_middleware.py
index 1b3872b5..217b302d 100644
--- a/keystone-moon/keystone/tests/unit/test_url_middleware.py
+++ b/keystone-moon/keystone/tests/unit/test_url_middleware.py
@@ -15,7 +15,7 @@
import webob
from keystone import middleware
-from keystone.tests import unit as tests
+from keystone.tests import unit
class FakeApp(object):
@@ -26,7 +26,7 @@ class FakeApp(object):
return resp(env, start_response)
-class UrlMiddlewareTest(tests.TestCase):
+class UrlMiddlewareTest(unit.TestCase):
def setUp(self):
self.middleware = middleware.NormalizingFilter(FakeApp())
self.response_status = None
diff --git a/keystone-moon/keystone/tests/unit/test_v2.py b/keystone-moon/keystone/tests/unit/test_v2.py
index 415150cf..99b5a897 100644
--- a/keystone-moon/keystone/tests/unit/test_v2.py
+++ b/keystone-moon/keystone/tests/unit/test_v2.py
@@ -19,6 +19,7 @@ import uuid
from keystoneclient.common import cms
from oslo_config import cfg
import six
+from six.moves import http_client
from testtools import matchers
from keystone.common import extension as keystone_extension
@@ -70,13 +71,13 @@ class CoreApiTests(object):
def test_public_not_found(self):
r = self.public_request(
path='/%s' % uuid.uuid4().hex,
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
self.assertValidErrorResponse(r)
def test_admin_not_found(self):
r = self.admin_request(
path='/%s' % uuid.uuid4().hex,
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
self.assertValidErrorResponse(r)
def test_public_multiple_choice(self):
@@ -107,11 +108,11 @@ class CoreApiTests(object):
def test_admin_extensions_404(self):
self.admin_request(path='/v2.0/extensions/invalid-extension',
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_public_osksadm_extension_404(self):
self.public_request(path='/v2.0/extensions/OS-KSADM',
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_admin_osksadm_extension(self):
r = self.admin_request(path='/v2.0/extensions/OS-KSADM')
@@ -131,7 +132,7 @@ class CoreApiTests(object):
'tenantId': self.tenant_bar['id'],
},
},
- expected_status=200)
+ expected_status=http_client.OK)
self.assertValidAuthenticationResponse(r, require_service_catalog=True)
def test_authenticate_unscoped(self):
@@ -146,7 +147,7 @@ class CoreApiTests(object):
},
},
},
- expected_status=200)
+ expected_status=http_client.OK)
self.assertValidAuthenticationResponse(r)
def test_get_tenants_for_token(self):
@@ -170,7 +171,7 @@ class CoreApiTests(object):
'token_id': 'invalid',
},
token=token,
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_validate_token_service_role(self):
self.md_foobar = self.assignment_api.add_role_to_user_and_project(
@@ -204,7 +205,7 @@ class CoreApiTests(object):
r = self.admin_request(
path='/v2.0/tokens/%s' % token,
token=token,
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_validate_token_belongs_to(self):
token = self.get_scoped_token()
@@ -233,7 +234,7 @@ class CoreApiTests(object):
'token_id': token,
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
def test_endpoints(self):
token = self.get_scoped_token()
@@ -306,7 +307,7 @@ class CoreApiTests(object):
},
},
token=token,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
self.assertValidErrorResponse(r)
r = self.admin_request(
@@ -321,7 +322,7 @@ class CoreApiTests(object):
},
},
token=token,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
self.assertValidErrorResponse(r)
# Test UPDATE request
@@ -338,7 +339,7 @@ class CoreApiTests(object):
},
},
token=token,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
self.assertValidErrorResponse(r)
r = self.admin_request(
@@ -351,7 +352,7 @@ class CoreApiTests(object):
},
},
token=token,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
self.assertValidErrorResponse(r)
def test_create_update_user_valid_enabled_type(self):
@@ -369,11 +370,12 @@ class CoreApiTests(object):
},
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
def test_error_response(self):
"""This triggers assertValidErrorResponse by convention."""
- self.public_request(path='/v2.0/tenants', expected_status=401)
+ self.public_request(path='/v2.0/tenants',
+ expected_status=http_client.UNAUTHORIZED)
def test_invalid_parameter_error_response(self):
token = self.get_scoped_token()
@@ -387,13 +389,13 @@ class CoreApiTests(object):
path='/v2.0/OS-KSADM/services',
body=bad_body,
token=token,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
self.assertValidErrorResponse(res)
res = self.admin_request(method='POST',
path='/v2.0/users',
body=bad_body,
token=token,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
self.assertValidErrorResponse(res)
def _get_user_id(self, r):
@@ -457,7 +459,7 @@ class CoreApiTests(object):
},
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
user_id = self._get_user_id(r.result)
@@ -468,7 +470,7 @@ class CoreApiTests(object):
'user_id': user_id
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
self.assertEqual(CONF.member_role_name, self._get_role_name(r.result))
# Create a new tenant
@@ -483,7 +485,7 @@ class CoreApiTests(object):
},
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
project_id = self._get_project_id(r.result)
@@ -499,7 +501,7 @@ class CoreApiTests(object):
},
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
# 'member_role' should be in new_tenant
r = self.admin_request(
@@ -508,7 +510,7 @@ class CoreApiTests(object):
'user_id': user_id
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
self.assertEqual('_member_', self._get_role_name(r.result))
# 'member_role' should not be in tenant_bar any more
@@ -518,7 +520,7 @@ class CoreApiTests(object):
'user_id': user_id
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
self.assertNoRoles(r.result)
def test_update_user_with_invalid_tenant(self):
@@ -537,7 +539,7 @@ class CoreApiTests(object):
},
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
user_id = self._get_user_id(r.result)
# Update user with an invalid tenant
@@ -552,7 +554,7 @@ class CoreApiTests(object):
},
},
token=token,
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_update_user_with_invalid_tenant_no_prev_tenant(self):
token = self.get_scoped_token()
@@ -569,7 +571,7 @@ class CoreApiTests(object):
},
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
user_id = self._get_user_id(r.result)
# Update user with an invalid tenant
@@ -584,7 +586,7 @@ class CoreApiTests(object):
},
},
token=token,
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_update_user_with_old_tenant(self):
token = self.get_scoped_token()
@@ -602,7 +604,7 @@ class CoreApiTests(object):
},
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
user_id = self._get_user_id(r.result)
@@ -613,7 +615,7 @@ class CoreApiTests(object):
'user_id': user_id
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
self.assertEqual(CONF.member_role_name, self._get_role_name(r.result))
# Update user's tenant with old tenant id
@@ -628,7 +630,7 @@ class CoreApiTests(object):
},
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
# 'member_role' should still be in tenant_bar
r = self.admin_request(
@@ -637,7 +639,7 @@ class CoreApiTests(object):
'user_id': user_id
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
self.assertEqual('_member_', self._get_role_name(r.result))
def test_authenticating_a_user_with_no_password(self):
@@ -669,13 +671,13 @@ class CoreApiTests(object):
},
},
},
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
self.assertValidErrorResponse(r)
def test_www_authenticate_header(self):
r = self.public_request(
path='/v2.0/tenants',
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
self.assertEqual('Keystone uri="http://localhost"',
r.headers.get('WWW-Authenticate'))
@@ -684,7 +686,7 @@ class CoreApiTests(object):
self.config_fixture.config(public_endpoint=test_url)
r = self.public_request(
path='/v2.0/tenants',
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
self.assertEqual('Keystone uri="%s"' % test_url,
r.headers.get('WWW-Authenticate'))
@@ -719,7 +721,7 @@ class LegacyV2UsernameTests(object):
path='/v2.0/users',
token=token,
body=body,
- expected_status=200)
+ expected_status=http_client.OK)
def test_create_with_extra_username(self):
"""The response for creating a user will contain the extra fields."""
@@ -770,7 +772,7 @@ class LegacyV2UsernameTests(object):
'enabled': enabled,
},
},
- expected_status=200)
+ expected_status=http_client.OK)
self.assertValidUserResponse(r)
@@ -800,7 +802,7 @@ class LegacyV2UsernameTests(object):
'enabled': enabled,
},
},
- expected_status=200)
+ expected_status=http_client.OK)
self.assertValidUserResponse(r)
@@ -879,7 +881,7 @@ class LegacyV2UsernameTests(object):
'enabled': enabled,
},
},
- expected_status=200)
+ expected_status=http_client.OK)
self.assertValidUserResponse(r)
@@ -909,7 +911,7 @@ class LegacyV2UsernameTests(object):
'enabled': enabled,
},
},
- expected_status=200)
+ expected_status=http_client.OK)
self.assertValidUserResponse(r)
@@ -929,7 +931,7 @@ class LegacyV2UsernameTests(object):
'enabled': True,
},
},
- expected_status=200)
+ expected_status=http_client.OK)
self.assertValidUserResponse(r)
@@ -954,7 +956,7 @@ class LegacyV2UsernameTests(object):
'enabled': enabled,
},
},
- expected_status=200)
+ expected_status=http_client.OK)
self.assertValidUserResponse(r)
@@ -1141,8 +1143,9 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
return r.result['user'][attribute_name]
def test_service_crud_requires_auth(self):
- """Service CRUD should 401 without an X-Auth-Token (bug 1006822)."""
- # values here don't matter because we should 401 before they're checked
+ """Service CRUD should return unauthorized without an X-Auth-Token."""
+ # values here don't matter because it will be unauthorized before
+ # they're checked (bug 1006822).
service_path = '/v2.0/OS-KSADM/services/%s' % uuid.uuid4().hex
service_body = {
'OS-KSADM:service': {
@@ -1153,41 +1156,43 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
r = self.admin_request(method='GET',
path='/v2.0/OS-KSADM/services',
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
self.assertValidErrorResponse(r)
r = self.admin_request(method='POST',
path='/v2.0/OS-KSADM/services',
body=service_body,
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
self.assertValidErrorResponse(r)
r = self.admin_request(method='GET',
path=service_path,
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
self.assertValidErrorResponse(r)
r = self.admin_request(method='DELETE',
path=service_path,
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
self.assertValidErrorResponse(r)
def test_user_role_list_requires_auth(self):
- """User role list should 401 without an X-Auth-Token (bug 1006815)."""
- # values here don't matter because we should 401 before they're checked
+ """User role list return unauthorized without an X-Auth-Token."""
+ # values here don't matter because it will be unauthorized before
+ # they're checked (bug 1006815).
path = '/v2.0/tenants/%(tenant_id)s/users/%(user_id)s/roles' % {
'tenant_id': uuid.uuid4().hex,
'user_id': uuid.uuid4().hex,
}
- r = self.admin_request(path=path, expected_status=401)
+ r = self.admin_request(path=path,
+ expected_status=http_client.UNAUTHORIZED)
self.assertValidErrorResponse(r)
def test_fetch_revocation_list_nonadmin_fails(self):
self.admin_request(
method='GET',
path='/v2.0/tokens/revoked',
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_fetch_revocation_list_admin_200(self):
token = self.get_scoped_token()
@@ -1195,7 +1200,7 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
method='GET',
path='/v2.0/tokens/revoked',
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
self.assertValidRevocationListResponse(r)
def assertValidRevocationListResponse(self, response):
@@ -1226,7 +1231,7 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
method='GET',
path='/v2.0/tokens/revoked',
token=token1,
- expected_status=200)
+ expected_status=http_client.OK)
signed_text = r.result['signed']
data_json = cms.cms_verify(signed_text, CONF.signing.certfile,
@@ -1278,7 +1283,7 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
},
},
token=token,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
self.assertValidErrorResponse(r)
# Test UPDATE request
@@ -1294,7 +1299,7 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
},
},
token=token,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
self.assertValidErrorResponse(r)
def test_authenticating_a_user_with_an_OSKSADM_password(self):
@@ -1328,7 +1333,7 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
},
},
},
- expected_status=200)
+ expected_status=http_client.OK)
# ensure password doesn't leak
user_id = r.result['user']['id']
@@ -1336,7 +1341,7 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
method='GET',
path='/v2.0/users/%s' % user_id,
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
self.assertNotIn('OS-KSADM:password', r.result['user'])
def test_updating_a_user_with_an_OSKSADM_password(self):
@@ -1355,7 +1360,7 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
},
},
token=token,
- expected_status=200)
+ expected_status=http_client.OK)
# successfully authenticate
self.public_request(
@@ -1369,7 +1374,7 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
},
},
},
- expected_status=200)
+ expected_status=http_client.OK)
class RevokeApiTestCase(V2TestCase):
@@ -1431,7 +1436,7 @@ class TestFernetTokenProviderV2(RestfulTestCase):
method='GET',
path=path,
token=admin_token,
- expected_status=200)
+ expected_status=http_client.OK)
def test_authenticate_scoped_token(self):
project_ref = self.new_project_ref()
@@ -1461,7 +1466,7 @@ class TestFernetTokenProviderV2(RestfulTestCase):
method='GET',
path=path,
token=admin_token,
- expected_status=200)
+ expected_status=http_client.OK)
def test_token_authentication_and_validation(self):
"""Test token authentication for Fernet token provider.
@@ -1486,7 +1491,7 @@ class TestFernetTokenProviderV2(RestfulTestCase):
}
}
},
- expected_status=200)
+ expected_status=http_client.OK)
token_id = self._get_token_id(r)
path = ('/v2.0/tokens/%s?belongsTo=%s' % (token_id, project_ref['id']))
@@ -1495,7 +1500,7 @@ class TestFernetTokenProviderV2(RestfulTestCase):
method='GET',
path=path,
token=CONF.admin_token,
- expected_status=200)
+ expected_status=http_client.OK)
def test_rescoped_tokens_maintain_original_expiration(self):
project_ref = self.new_project_ref()
@@ -1517,7 +1522,7 @@ class TestFernetTokenProviderV2(RestfulTestCase):
},
# NOTE(lbragstad): This test may need to be refactored if Keystone
# decides to disallow rescoping using a scoped token.
- expected_status=200)
+ expected_status=http_client.OK)
original_token = resp.result['access']['token']['id']
original_expiration = resp.result['access']['token']['expires']
@@ -1532,7 +1537,7 @@ class TestFernetTokenProviderV2(RestfulTestCase):
}
}
},
- expected_status=200)
+ expected_status=http_client.OK)
rescoped_token = resp.result['access']['token']['id']
rescoped_expiration = resp.result['access']['token']['expires']
self.assertNotEqual(original_token, rescoped_token)
diff --git a/keystone-moon/keystone/tests/unit/test_v2_controller.py b/keystone-moon/keystone/tests/unit/test_v2_controller.py
index 0d4b3cdc..581e6b9c 100644
--- a/keystone-moon/keystone/tests/unit/test_v2_controller.py
+++ b/keystone-moon/keystone/tests/unit/test_v2_controller.py
@@ -18,7 +18,7 @@ import uuid
from keystone.assignment import controllers as assignment_controllers
from keystone import exception
from keystone.resource import controllers as resource_controllers
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import default_fixtures
from keystone.tests.unit.ksfixtures import database
@@ -26,7 +26,7 @@ from keystone.tests.unit.ksfixtures import database
_ADMIN_CONTEXT = {'is_admin': True, 'query_string': {}}
-class TenantTestCase(tests.TestCase):
+class TenantTestCase(unit.TestCase):
"""Tests for the V2 Tenant controller.
These tests exercise :class:`keystone.assignment.controllers.Tenant`.
diff --git a/keystone-moon/keystone/tests/unit/test_v2_keystoneclient.py b/keystone-moon/keystone/tests/unit/test_v2_keystoneclient.py
index e0843605..8d6d9eb7 100644
--- a/keystone-moon/keystone/tests/unit/test_v2_keystoneclient.py
+++ b/keystone-moon/keystone/tests/unit/test_v2_keystoneclient.py
@@ -22,10 +22,11 @@ import mock
from oslo_config import cfg
from oslo_serialization import jsonutils
from oslo_utils import timeutils
+from six.moves import http_client
from six.moves import range
import webob
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import default_fixtures
from keystone.tests.unit.ksfixtures import appserver
from keystone.tests.unit.ksfixtures import database
@@ -35,11 +36,11 @@ CONF = cfg.CONF
DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id
-class ClientDrivenTestCase(tests.TestCase):
+class ClientDrivenTestCase(unit.TestCase):
def config_files(self):
config_files = super(ClientDrivenTestCase, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_sql.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_sql.conf'))
return config_files
def setUp(self):
@@ -1032,7 +1033,8 @@ class ClientDrivenTestCase(tests.TestCase):
(new_password, self.user_two['password']))
self.public_server.application(req.environ,
responseobject.start_fake_response)
- self.assertEqual(403, responseobject.response_status)
+ self.assertEqual(http_client.FORBIDDEN,
+ responseobject.response_status)
self.user_two['password'] = new_password
self.assertRaises(client_exceptions.Unauthorized,
@@ -1110,10 +1112,10 @@ class ClientDrivenTestCase(tests.TestCase):
if not client:
client = self.default_client
url = '%s/ec2tokens' % self.default_client.auth_url
- (resp, token) = client.request(
+ resp = client.session.request(
url=url, method='POST',
- body={'credentials': credentials})
- return resp, token
+ json={'credentials': credentials})
+ return resp, resp.json()
def _generate_default_user_ec2_credentials(self):
cred = self. default_client.ec2.create(
@@ -1135,7 +1137,7 @@ class ClientDrivenTestCase(tests.TestCase):
credentials, signature = self._generate_default_user_ec2_credentials()
credentials['signature'] = signature
resp, token = self._send_ec2_auth_request(credentials)
- self.assertEqual(200, resp.status_code)
+ self.assertEqual(http_client.OK, resp.status_code)
self.assertIn('access', token)
def test_ec2_auth_success_trust(self):
@@ -1167,7 +1169,7 @@ class ClientDrivenTestCase(tests.TestCase):
cred.access, cred.secret)
credentials['signature'] = signature
resp, token = self._send_ec2_auth_request(credentials)
- self.assertEqual(200, resp.status_code)
+ self.assertEqual(http_client.OK, resp.status_code)
self.assertEqual(trust_id, token['access']['trust']['id'])
# TODO(shardy) we really want to check the roles and trustee
# but because of where the stubbing happens we don't seem to
diff --git a/keystone-moon/keystone/tests/unit/test_v3.py b/keystone-moon/keystone/tests/unit/test_v3.py
index 9bbfa103..7afe6ad8 100644
--- a/keystone-moon/keystone/tests/unit/test_v3.py
+++ b/keystone-moon/keystone/tests/unit/test_v3.py
@@ -18,7 +18,7 @@ import uuid
from oslo_config import cfg
from oslo_serialization import jsonutils
from oslo_utils import timeutils
-import six
+from six.moves import http_client
from testtools import matchers
from keystone import auth
@@ -27,14 +27,14 @@ from keystone.common import cache
from keystone import exception
from keystone import middleware
from keystone.policy.backends import rules
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import rest
CONF = cfg.CONF
DEFAULT_DOMAIN_ID = 'default'
-TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ'
+TIME_FORMAT = unit.TIME_FORMAT
class AuthTestMixin(object):
@@ -116,11 +116,11 @@ class AuthTestMixin(object):
return {'auth': auth_data}
-class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase,
+class RestfulTestCase(unit.SQLDriverOverrides, rest.RestfulTestCase,
AuthTestMixin):
def config_files(self):
config_files = super(RestfulTestCase, self).config_files()
- config_files.append(tests.dirs.tests_conf('backend_sql.conf'))
+ config_files.append(unit.dirs.tests_conf('backend_sql.conf'))
return config_files
def get_extensions(self):
@@ -132,7 +132,7 @@ class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase,
def generate_paste_config(self):
new_paste_file = None
try:
- new_paste_file = tests.generate_paste_config(self.EXTENSION_TO_ADD)
+ new_paste_file = unit.generate_paste_config(self.EXTENSION_TO_ADD)
except AttributeError:
# no need to report this error here, as most tests will not have
# EXTENSION_TO_ADD defined.
@@ -142,7 +142,7 @@ class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase,
def remove_generated_paste_config(self):
try:
- tests.remove_generated_paste_config(self.EXTENSION_TO_ADD)
+ unit.remove_generated_paste_config(self.EXTENSION_TO_ADD)
except AttributeError:
pass
@@ -176,7 +176,7 @@ class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase,
self.load_sample_data()
def _populate_default_domain(self):
- if CONF.database.connection == tests.IN_MEM_DB_CONN_STRING:
+ if CONF.database.connection == unit.IN_MEM_DB_CONN_STRING:
# NOTE(morganfainberg): If an in-memory db is being used, be sure
# to populate the default domain, this is typically done by
# a migration, but the in-mem db uses model definitions to create
@@ -265,122 +265,52 @@ class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase,
self.endpoint['enabled'] = True
def new_ref(self):
- """Populates a ref with attributes common to all API entities."""
- return {
- 'id': uuid.uuid4().hex,
- 'name': uuid.uuid4().hex,
- 'description': uuid.uuid4().hex,
- 'enabled': True}
+ """Populates a ref with attributes common to some API entities."""
+ return unit.new_ref()
def new_region_ref(self):
- ref = self.new_ref()
- # Region doesn't have name or enabled.
- del ref['name']
- del ref['enabled']
- ref['parent_region_id'] = None
- return ref
+ return unit.new_region_ref()
def new_service_ref(self):
- ref = self.new_ref()
- ref['type'] = uuid.uuid4().hex
- return ref
+ return unit.new_service_ref()
def new_endpoint_ref(self, service_id, interface='public', **kwargs):
- ref = self.new_ref()
- del ref['enabled'] # enabled is optional
- ref['interface'] = interface
- ref['service_id'] = service_id
- ref['url'] = 'https://' + uuid.uuid4().hex + '.com'
- ref['region_id'] = self.region_id
- ref.update(kwargs)
- return ref
+ return unit.new_endpoint_ref(
+ service_id, interface=interface, default_region_id=self.region_id,
+ **kwargs)
def new_domain_ref(self):
- ref = self.new_ref()
- return ref
+ return unit.new_domain_ref()
def new_project_ref(self, domain_id=None, parent_id=None, is_domain=False):
- ref = self.new_ref()
- ref['domain_id'] = domain_id
- ref['parent_id'] = parent_id
- ref['is_domain'] = is_domain
- return ref
+ return unit.new_project_ref(domain_id=domain_id, parent_id=parent_id,
+ is_domain=is_domain)
def new_user_ref(self, domain_id, project_id=None):
- ref = self.new_ref()
- ref['domain_id'] = domain_id
- ref['email'] = uuid.uuid4().hex
- ref['password'] = uuid.uuid4().hex
- if project_id:
- ref['default_project_id'] = project_id
- return ref
+ return unit.new_user_ref(domain_id, project_id=project_id)
def new_group_ref(self, domain_id):
- ref = self.new_ref()
- ref['domain_id'] = domain_id
- return ref
+ return unit.new_group_ref(domain_id)
def new_credential_ref(self, user_id, project_id=None, cred_type=None):
- ref = dict()
- ref['id'] = uuid.uuid4().hex
- ref['user_id'] = user_id
- if cred_type == 'ec2':
- ref['type'] = 'ec2'
- ref['blob'] = {'blah': 'test'}
- else:
- ref['type'] = 'cert'
- ref['blob'] = uuid.uuid4().hex
- if project_id:
- ref['project_id'] = project_id
- return ref
+ return unit.new_credential_ref(user_id, project_id=project_id,
+ cred_type=cred_type)
def new_role_ref(self):
- ref = self.new_ref()
- # Roles don't have a description or the enabled flag
- del ref['description']
- del ref['enabled']
- return ref
+ return unit.new_role_ref()
def new_policy_ref(self):
- ref = self.new_ref()
- ref['blob'] = uuid.uuid4().hex
- ref['type'] = uuid.uuid4().hex
- return ref
+ return unit.new_policy_ref()
def new_trust_ref(self, trustor_user_id, trustee_user_id, project_id=None,
impersonation=None, expires=None, role_ids=None,
role_names=None, remaining_uses=None,
allow_redelegation=False):
- ref = dict()
- ref['id'] = uuid.uuid4().hex
- ref['trustor_user_id'] = trustor_user_id
- ref['trustee_user_id'] = trustee_user_id
- ref['impersonation'] = impersonation or False
- ref['project_id'] = project_id
- ref['remaining_uses'] = remaining_uses
- ref['allow_redelegation'] = allow_redelegation
-
- if isinstance(expires, six.string_types):
- ref['expires_at'] = expires
- elif isinstance(expires, dict):
- ref['expires_at'] = (
- timeutils.utcnow() + datetime.timedelta(**expires)
- ).strftime(TIME_FORMAT)
- elif expires is None:
- pass
- else:
- raise NotImplementedError('Unexpected value for "expires"')
-
- role_ids = role_ids or []
- role_names = role_names or []
- if role_ids or role_names:
- ref['roles'] = []
- for role_id in role_ids:
- ref['roles'].append({'id': role_id})
- for role_name in role_names:
- ref['roles'].append({'name': role_name})
-
- return ref
+ return unit.new_trust_ref(
+ trustor_user_id, trustee_user_id, project_id=project_id,
+ impersonation=impersonation, expires=expires, role_ids=role_ids,
+ role_names=role_names, remaining_uses=remaining_uses,
+ allow_redelegation=allow_redelegation)
def create_new_default_project_for_user(self, user_id, domain_id,
enable_project=True):
@@ -482,7 +412,7 @@ class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase,
r = self.v3_authenticate_token(auth)
return r.headers.get('X-Subject-Token')
- def v3_authenticate_token(self, auth, expected_status=201):
+ def v3_authenticate_token(self, auth, expected_status=http_client.CREATED):
return self.admin_request(method='POST',
path='/v3/auth/tokens',
body=auth,
@@ -511,42 +441,31 @@ class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase,
return self.admin_request(path=path, token=token, **kwargs)
- def get(self, path, **kwargs):
- r = self.v3_request(method='GET', path=path, **kwargs)
- if 'expected_status' not in kwargs:
- self.assertResponseStatus(r, 200)
- return r
+ def get(self, path, expected_status=http_client.OK, **kwargs):
+ return self.v3_request(path, method='GET',
+ expected_status=expected_status, **kwargs)
- def head(self, path, **kwargs):
- r = self.v3_request(method='HEAD', path=path, **kwargs)
- if 'expected_status' not in kwargs:
- self.assertResponseStatus(r, 204)
+ def head(self, path, expected_status=http_client.NO_CONTENT, **kwargs):
+ r = self.v3_request(path, method='HEAD',
+ expected_status=expected_status, **kwargs)
self.assertEqual('', r.body)
return r
- def post(self, path, **kwargs):
- r = self.v3_request(method='POST', path=path, **kwargs)
- if 'expected_status' not in kwargs:
- self.assertResponseStatus(r, 201)
- return r
+ def post(self, path, expected_status=http_client.CREATED, **kwargs):
+ return self.v3_request(path, method='POST',
+ expected_status=expected_status, **kwargs)
- def put(self, path, **kwargs):
- r = self.v3_request(method='PUT', path=path, **kwargs)
- if 'expected_status' not in kwargs:
- self.assertResponseStatus(r, 204)
- return r
+ def put(self, path, expected_status=http_client.NO_CONTENT, **kwargs):
+ return self.v3_request(path, method='PUT',
+ expected_status=expected_status, **kwargs)
- def patch(self, path, **kwargs):
- r = self.v3_request(method='PATCH', path=path, **kwargs)
- if 'expected_status' not in kwargs:
- self.assertResponseStatus(r, 200)
- return r
+ def patch(self, path, expected_status=http_client.OK, **kwargs):
+ return self.v3_request(path, method='PATCH',
+ expected_status=expected_status, **kwargs)
- def delete(self, path, **kwargs):
- r = self.v3_request(method='DELETE', path=path, **kwargs)
- if 'expected_status' not in kwargs:
- self.assertResponseStatus(r, 204)
- return r
+ def delete(self, path, expected_status=http_client.NO_CONTENT, **kwargs):
+ return self.v3_request(path, method='DELETE',
+ expected_status=expected_status, **kwargs)
def assertValidErrorResponse(self, r):
resp = r.result
diff --git a/keystone-moon/keystone/tests/unit/test_v3_assignment.py b/keystone-moon/keystone/tests/unit/test_v3_assignment.py
index 03e5d30b..f22e9f2b 100644
--- a/keystone-moon/keystone/tests/unit/test_v3_assignment.py
+++ b/keystone-moon/keystone/tests/unit/test_v3_assignment.py
@@ -14,11 +14,12 @@ import random
import uuid
from oslo_config import cfg
+from six.moves import http_client
from six.moves import range
from keystone.common import controller
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import test_v3
from keystone.tests.unit import utils
@@ -75,9 +76,10 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
body={'domain': ref})
self.assertValidDomainResponse(r, ref)
- def test_create_domain_400(self):
+ def test_create_domain_bad_request(self):
"""Call ``POST /domains``."""
- self.post('/domains', body={'domain': {}}, expected_status=400)
+ self.post('/domains', body={'domain': {}},
+ expected_status=http_client.BAD_REQUEST)
def test_list_domains(self):
"""Call ``GET /domains``."""
@@ -133,7 +135,8 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
}
}
self.admin_request(
- path='/v2.0/tokens', method='POST', body=body, expected_status=401)
+ path='/v2.0/tokens', method='POST', body=body,
+ expected_status=http_client.UNAUTHORIZED)
auth_data = self.build_authentication_request(
user_id=self.user2['id'],
@@ -160,21 +163,24 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
}
}
self.admin_request(
- path='/v2.0/tokens', method='POST', body=body, expected_status=401)
+ path='/v2.0/tokens', method='POST', body=body,
+ expected_status=http_client.UNAUTHORIZED)
# Try looking up in v3 by name and id
auth_data = self.build_authentication_request(
user_id=self.user2['id'],
password=self.user2['password'],
project_id=self.project2['id'])
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
auth_data = self.build_authentication_request(
username=self.user2['name'],
user_domain_id=self.domain2['id'],
password=self.user2['password'],
project_id=self.project2['id'])
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_delete_enabled_domain_fails(self):
"""Call ``DELETE /domains/{domain_id}`` (when domain enabled)."""
@@ -357,20 +363,19 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
# validates the returned token and it should be valid.
self.head('/auth/tokens',
headers={'x-subject-token': subject_token},
- expected_status=200)
+ expected_status=http_client.OK)
# now disable the domain
self.domain['enabled'] = False
url = "/domains/%(domain_id)s" % {'domain_id': self.domain['id']}
self.patch(url,
- body={'domain': {'enabled': False}},
- expected_status=200)
+ body={'domain': {'enabled': False}})
# validates the same token again and it should be 'not found'
# as the domain has already been disabled.
self.head('/auth/tokens',
headers={'x-subject-token': subject_token},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_delete_domain_hierarchy(self):
"""Call ``DELETE /domains/{domain_id}``."""
@@ -485,14 +490,16 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
body={'project': ref})
self.assertValidProjectResponse(r, ref)
- def test_create_project_400(self):
+ def test_create_project_bad_request(self):
"""Call ``POST /projects``."""
- self.post('/projects', body={'project': {}}, expected_status=400)
+ self.post('/projects', body={'project': {}},
+ expected_status=http_client.BAD_REQUEST)
def test_create_project_invalid_domain_id(self):
"""Call ``POST /projects``."""
ref = self.new_project_ref(domain_id=uuid.uuid4().hex)
- self.post('/projects', body={'project': ref}, expected_status=400)
+ self.post('/projects', body={'project': ref},
+ expected_status=http_client.BAD_REQUEST)
def test_create_project_is_domain_not_allowed(self):
"""Call ``POST /projects``.
@@ -504,7 +511,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
ref = self.new_project_ref(domain_id=self.domain_id, is_domain=True)
self.post('/projects',
body={'project': ref},
- expected_status=501)
+ expected_status=http_client.NOT_IMPLEMENTED)
@utils.wip('waiting for projects acting as domains implementation')
def test_create_project_without_parent_id_and_without_domain_id(self):
@@ -644,18 +651,20 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
def test_get_project_with_parents_as_list_with_invalid_id(self):
"""Call ``GET /projects/{project_id}?parents_as_list``."""
self.get('/projects/%(project_id)s?parents_as_list' % {
- 'project_id': None}, expected_status=404)
+ 'project_id': None}, expected_status=http_client.NOT_FOUND)
self.get('/projects/%(project_id)s?parents_as_list' % {
- 'project_id': uuid.uuid4().hex}, expected_status=404)
+ 'project_id': uuid.uuid4().hex},
+ expected_status=http_client.NOT_FOUND)
def test_get_project_with_subtree_as_list_with_invalid_id(self):
"""Call ``GET /projects/{project_id}?subtree_as_list``."""
self.get('/projects/%(project_id)s?subtree_as_list' % {
- 'project_id': None}, expected_status=404)
+ 'project_id': None}, expected_status=http_client.NOT_FOUND)
self.get('/projects/%(project_id)s?subtree_as_list' % {
- 'project_id': uuid.uuid4().hex}, expected_status=404)
+ 'project_id': uuid.uuid4().hex},
+ expected_status=http_client.NOT_FOUND)
def test_get_project_with_parents_as_ids(self):
"""Call ``GET /projects/{project_id}?parents_as_ids``."""
@@ -766,7 +775,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
self.get(
'/projects/%(project_id)s?parents_as_list&parents_as_ids' % {
'project_id': projects[1]['project']['id']},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_get_project_with_subtree_as_ids(self):
"""Call ``GET /projects/{project_id}?subtree_as_ids``.
@@ -928,7 +937,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
self.get(
'/projects/%(project_id)s?subtree_as_list&subtree_as_ids' % {
'project_id': projects[1]['project']['id']},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_update_project(self):
"""Call ``PATCH /projects/{project_id}``."""
@@ -965,7 +974,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
'/projects/%(project_id)s' % {
'project_id': leaf_project['id']},
body={'project': leaf_project},
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_update_project_is_domain_not_allowed(self):
"""Call ``PATCH /projects/{project_id}`` with is_domain.
@@ -981,7 +990,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
self.patch('/projects/%(project_id)s' % {
'project_id': resp.result['project']['id']},
body={'project': project},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_disable_leaf_project(self):
"""Call ``PATCH /projects/{project_id}``."""
@@ -1004,7 +1013,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
'/projects/%(project_id)s' % {
'project_id': root_project['id']},
body={'project': root_project},
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_delete_project(self):
"""Call ``DELETE /projects/{project_id}``
@@ -1048,7 +1057,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
self.delete(
'/projects/%(project_id)s' % {
'project_id': projects[0]['project']['id']},
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
# Role CRUD tests
@@ -1060,9 +1069,10 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
body={'role': ref})
return self.assertValidRoleResponse(r, ref)
- def test_create_role_400(self):
+ def test_create_role_bad_request(self):
"""Call ``POST /roles``."""
- self.post('/roles', body={'role': {}}, expected_status=400)
+ self.post('/roles', body={'role': {}},
+ expected_status=http_client.BAD_REQUEST)
def test_list_roles(self):
"""Call ``GET /roles``."""
@@ -1132,7 +1142,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
"""Grant role on a project to a user that doesn't exist, 404 result.
When grant a role on a project to a user that doesn't exist, the server
- returns 404 Not Found for the user.
+ returns Not Found for the user.
"""
@@ -1145,7 +1155,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
'collection_url': collection_url,
'role_id': self.role_id}
- self.put(member_url, expected_status=404)
+ self.put(member_url, expected_status=http_client.NOT_FOUND)
def test_crud_user_domain_role_grants(self):
collection_url = (
@@ -1184,7 +1194,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
'collection_url': collection_url,
'role_id': self.role_id}
- self.put(member_url, expected_status=404)
+ self.put(member_url, expected_status=http_client.NOT_FOUND)
def test_crud_group_project_role_grants(self):
collection_url = (
@@ -1224,7 +1234,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
'collection_url': collection_url,
'role_id': self.role_id}
- self.put(member_url, expected_status=404)
+ self.put(member_url, expected_status=http_client.NOT_FOUND)
def test_crud_group_domain_role_grants(self):
collection_url = (
@@ -1264,7 +1274,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
'collection_url': collection_url,
'role_id': self.role_id}
- self.put(member_url, expected_status=404)
+ self.put(member_url, expected_status=http_client.NOT_FOUND)
def _create_new_user_and_assign_role_on_project(self):
"""Create a new user and assign user a role on a project."""
@@ -1279,9 +1289,9 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
member_url = ('%(collection_url)s/%(role_id)s' % {
'collection_url': collection_url,
'role_id': self.role_id})
- self.put(member_url, expected_status=204)
+ self.put(member_url)
# Check the user has the role assigned
- self.head(member_url, expected_status=204)
+ self.head(member_url)
return member_url, user_ref
def test_delete_user_before_removing_role_assignment_succeeds(self):
@@ -1290,9 +1300,9 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
# Delete the user from identity backend
self.identity_api.driver.delete_user(user['id'])
# Clean up the role assignment
- self.delete(member_url, expected_status=204)
+ self.delete(member_url)
# Make sure the role is gone
- self.head(member_url, expected_status=404)
+ self.head(member_url, expected_status=http_client.NOT_FOUND)
def test_delete_user_and_check_role_assignment_fails(self):
"""Call ``DELETE`` on the user and check the role assignment."""
@@ -1301,7 +1311,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
self.identity_api.delete_user(user['id'])
# We should get a 404 when looking for the user in the identity
# backend because we're not performing a delete operation on the role.
- self.head(member_url, expected_status=404)
+ self.head(member_url, expected_status=http_client.NOT_FOUND)
def test_token_revoked_once_group_role_grant_revoked(self):
"""Test token is revoked when group role grant is revoked
@@ -1333,7 +1343,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
# validates the returned token; it should be valid.
self.head('/auth/tokens',
headers={'x-subject-token': token},
- expected_status=200)
+ expected_status=http_client.OK)
# revokes the grant from group on project.
self.assignment_api.delete_grant(role_id=self.role['id'],
@@ -1343,7 +1353,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
# validates the same token again; it should not longer be valid.
self.head('/auth/tokens',
headers={'x-subject-token': token},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
# Role Assignments tests
@@ -1858,7 +1868,7 @@ class RoleAssignmentBaseTestCase(test_v3.RestfulTestCase,
self.default_user_id = self.user_ids[0]
self.default_group_id = self.group_ids[0]
- def get_role_assignments(self, expected_status=200, **filters):
+ def get_role_assignments(self, expected_status=http_client.OK, **filters):
"""Returns the result from querying role assignment API + queried URL.
Calls GET /v3/role_assignments?<params> and returns its result, where
@@ -1903,24 +1913,24 @@ class RoleAssignmentFailureTestCase(RoleAssignmentBaseTestCase):
def test_get_role_assignments_by_domain_and_project(self):
self.get_role_assignments(domain_id=self.domain_id,
project_id=self.project_id,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_get_role_assignments_by_user_and_group(self):
self.get_role_assignments(user_id=self.default_user_id,
group_id=self.default_group_id,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_get_role_assignments_by_effective_and_inherited(self):
self.config_fixture.config(group='os_inherit', enabled=True)
self.get_role_assignments(domain_id=self.domain_id, effective=True,
inherited_to_projects=True,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_get_role_assignments_by_effective_and_group(self):
self.get_role_assignments(effective=True,
group_id=self.default_group_id,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
class RoleAssignmentDirectTestCase(RoleAssignmentBaseTestCase):
@@ -2193,8 +2203,10 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
project_id=self.project_id)
# Check the user cannot get a domain nor a project token
- self.v3_authenticate_token(domain_auth_data, expected_status=401)
- self.v3_authenticate_token(project_auth_data, expected_status=401)
+ self.v3_authenticate_token(domain_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
+ self.v3_authenticate_token(project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
# Grant non-inherited role for user on domain
non_inher_ud_link = self.build_role_assignment_link(
@@ -2203,7 +2215,8 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
# Check the user can get only a domain token
self.v3_authenticate_token(domain_auth_data)
- self.v3_authenticate_token(project_auth_data, expected_status=401)
+ self.v3_authenticate_token(project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
# Create inherited role
inherited_role = {'id': uuid.uuid4().hex, 'name': 'inherited'}
@@ -2224,13 +2237,15 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
# Check the user can only get a domain token
self.v3_authenticate_token(domain_auth_data)
- self.v3_authenticate_token(project_auth_data, expected_status=401)
+ self.v3_authenticate_token(project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
# Delete non-inherited grant
self.delete(non_inher_ud_link)
# Check the user cannot get a domain token anymore
- self.v3_authenticate_token(domain_auth_data, expected_status=401)
+ self.v3_authenticate_token(domain_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_get_token_from_inherited_group_domain_role_grants(self):
# Create a new group and put a new user in it to
@@ -2255,8 +2270,10 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
project_id=self.project_id)
# Check the user cannot get a domain nor a project token
- self.v3_authenticate_token(domain_auth_data, expected_status=401)
- self.v3_authenticate_token(project_auth_data, expected_status=401)
+ self.v3_authenticate_token(domain_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
+ self.v3_authenticate_token(project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
# Grant non-inherited role for user on domain
non_inher_gd_link = self.build_role_assignment_link(
@@ -2265,7 +2282,8 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
# Check the user can get only a domain token
self.v3_authenticate_token(domain_auth_data)
- self.v3_authenticate_token(project_auth_data, expected_status=401)
+ self.v3_authenticate_token(project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
# Create inherited role
inherited_role = {'id': uuid.uuid4().hex, 'name': 'inherited'}
@@ -2286,13 +2304,15 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
# Check the user can only get a domain token
self.v3_authenticate_token(domain_auth_data)
- self.v3_authenticate_token(project_auth_data, expected_status=401)
+ self.v3_authenticate_token(project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
# Delete non-inherited grant
self.delete(non_inher_gd_link)
# Check the user cannot get a domain token anymore
- self.v3_authenticate_token(domain_auth_data, expected_status=401)
+ self.v3_authenticate_token(domain_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def _test_crud_inherited_and_direct_assignment_on_target(self, target_url):
# Create a new role to avoid assignments loaded from sample data
@@ -2308,7 +2328,7 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
self.put(direct_url)
# Check the direct assignment exists, but the inherited one does not
self.head(direct_url)
- self.head(inherited_url, expected_status=404)
+ self.head(inherited_url, expected_status=http_client.NOT_FOUND)
# Now add the inherited assignment
self.put(inherited_url)
@@ -2320,13 +2340,13 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
self.delete(inherited_url)
# Check the direct assignment exists, but the inherited one does not
self.head(direct_url)
- self.head(inherited_url, expected_status=404)
+ self.head(inherited_url, expected_status=http_client.NOT_FOUND)
# Now delete the inherited assignment
self.delete(direct_url)
# Check that none of them exist
- self.head(direct_url, expected_status=404)
- self.head(inherited_url, expected_status=404)
+ self.head(direct_url, expected_status=http_client.NOT_FOUND)
+ self.head(inherited_url, expected_status=http_client.NOT_FOUND)
def test_crud_inherited_and_direct_assignment_on_domains(self):
self._test_crud_inherited_and_direct_assignment_on_target(
@@ -2801,8 +2821,10 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
project_id=leaf_id)
# Check the user cannot get a token on root nor leaf project
- self.v3_authenticate_token(root_project_auth_data, expected_status=401)
- self.v3_authenticate_token(leaf_project_auth_data, expected_status=401)
+ self.v3_authenticate_token(root_project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
+ self.v3_authenticate_token(leaf_project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
# Grant non-inherited role for user on leaf project
non_inher_up_link = self.build_role_assignment_link(
@@ -2811,7 +2833,8 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
self.put(non_inher_up_link)
# Check the user can only get a token on leaf project
- self.v3_authenticate_token(root_project_auth_data, expected_status=401)
+ self.v3_authenticate_token(root_project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
self.v3_authenticate_token(leaf_project_auth_data)
# Grant inherited role for user on root project
@@ -2821,21 +2844,24 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
self.put(inher_up_link)
# Check the user still can get a token only on leaf project
- self.v3_authenticate_token(root_project_auth_data, expected_status=401)
+ self.v3_authenticate_token(root_project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
self.v3_authenticate_token(leaf_project_auth_data)
# Delete non-inherited grant
self.delete(non_inher_up_link)
# Check the inherited role still applies for leaf project
- self.v3_authenticate_token(root_project_auth_data, expected_status=401)
+ self.v3_authenticate_token(root_project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
self.v3_authenticate_token(leaf_project_auth_data)
# Delete inherited grant
self.delete(inher_up_link)
# Check the user cannot get a token on leaf project anymore
- self.v3_authenticate_token(leaf_project_auth_data, expected_status=401)
+ self.v3_authenticate_token(leaf_project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_get_token_from_inherited_group_project_role_grants(self):
# Create default scenario
@@ -2858,8 +2884,10 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
project_id=leaf_id)
# Check the user cannot get a token on root nor leaf project
- self.v3_authenticate_token(root_project_auth_data, expected_status=401)
- self.v3_authenticate_token(leaf_project_auth_data, expected_status=401)
+ self.v3_authenticate_token(root_project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
+ self.v3_authenticate_token(leaf_project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
# Grant non-inherited role for group on leaf project
non_inher_gp_link = self.build_role_assignment_link(
@@ -2868,7 +2896,8 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
self.put(non_inher_gp_link)
# Check the user can only get a token on leaf project
- self.v3_authenticate_token(root_project_auth_data, expected_status=401)
+ self.v3_authenticate_token(root_project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
self.v3_authenticate_token(leaf_project_auth_data)
# Grant inherited role for group on root project
@@ -2878,7 +2907,8 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
self.put(inher_gp_link)
# Check the user still can get a token only on leaf project
- self.v3_authenticate_token(root_project_auth_data, expected_status=401)
+ self.v3_authenticate_token(root_project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
self.v3_authenticate_token(leaf_project_auth_data)
# Delete no-inherited grant
@@ -2891,7 +2921,8 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
self.delete(inher_gp_link)
# Check the user cannot get a token on leaf project anymore
- self.v3_authenticate_token(leaf_project_auth_data, expected_status=401)
+ self.v3_authenticate_token(leaf_project_auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_get_role_assignments_for_project_hierarchy(self):
"""Call ``GET /role_assignments``.
@@ -3069,13 +3100,13 @@ class AssignmentInheritanceDisabledTestCase(test_v3.RestfulTestCase):
'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)
+ self.put(member_url, expected_status=http_client.NOT_FOUND)
+ self.head(member_url, expected_status=http_client.NOT_FOUND)
+ self.get(collection_url, expected_status=http_client.NOT_FOUND)
+ self.delete(member_url, expected_status=http_client.NOT_FOUND)
-class AssignmentV3toV2MethodsTestCase(tests.TestCase):
+class AssignmentV3toV2MethodsTestCase(unit.TestCase):
"""Test domain V3 to V2 conversion methods."""
def _setup_initial_projects(self):
self.project_id = uuid.uuid4().hex
diff --git a/keystone-moon/keystone/tests/unit/test_v3_auth.py b/keystone-moon/keystone/tests/unit/test_v3_auth.py
index 96f0ff1f..496a75c0 100644
--- a/keystone-moon/keystone/tests/unit/test_v3_auth.py
+++ b/keystone-moon/keystone/tests/unit/test_v3_auth.py
@@ -22,6 +22,7 @@ from keystoneclient.common import cms
import mock
from oslo_config import cfg
from oslo_utils import timeutils
+from six.moves import http_client
from six.moves import range
from testtools import matchers
from testtools import testcase
@@ -30,7 +31,7 @@ from keystone import auth
from keystone.common import utils
from keystone import exception
from keystone.policy.backends import rules
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import ksfixtures
from keystone.tests.unit import test_v3
@@ -141,7 +142,7 @@ class TokenAPITests(object):
path='/v2.0/tokens/%s' % v3_token,
token=CONF.admin_token,
method='GET',
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_v3_v2_intermix_new_default_domain(self):
# If the default_domain_id config option is changed, then should be
@@ -199,7 +200,7 @@ class TokenAPITests(object):
method='GET',
path='/v2.0/tokens/%s' % v3_token,
token=CONF.admin_token,
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_v3_v2_intermix_non_default_project_failed(self):
# self.project is in a non-default domain
@@ -213,7 +214,7 @@ class TokenAPITests(object):
method='GET',
path='/v2.0/tokens/%s' % v3_token,
token=CONF.admin_token,
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_v3_v2_intermix_non_default_user_failed(self):
self.assignment_api.create_grant(
@@ -232,7 +233,7 @@ class TokenAPITests(object):
method='GET',
path='/v2.0/tokens/%s' % v3_token,
token=CONF.admin_token,
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_v3_v2_intermix_domain_scope_failed(self):
self.assignment_api.create_grant(
@@ -250,7 +251,7 @@ class TokenAPITests(object):
path='/v2.0/tokens/%s' % v3_token,
token=CONF.admin_token,
method='GET',
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_v3_v2_unscoped_token_intermix(self):
r = self.v3_authenticate_token(self.build_authentication_request(
@@ -383,14 +384,13 @@ class TokenAPITests(object):
v2_token = r.result['access']['token']['id']
# Delete the v2 token using v3.
- resp = self.delete(
+ self.delete(
'/auth/tokens', headers={'X-Subject-Token': v2_token})
- self.assertEqual(resp.status_code, 204)
# Attempting to use the deleted token on v2 should fail.
self.admin_request(
path='/v2.0/tenants', method='GET', token=v2_token,
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_rescoping_token(self):
expires = self.v3_token_data['token']['expires_at']
@@ -405,7 +405,8 @@ class TokenAPITests(object):
self.assertEqual(expires, r.result['token']['expires_at'])
def test_check_token(self):
- self.head('/auth/tokens', headers=self.headers, expected_status=200)
+ self.head('/auth/tokens', headers=self.headers,
+ expected_status=http_client.OK)
def test_validate_token(self):
r = self.get('/auth/tokens', headers=self.headers)
@@ -434,7 +435,7 @@ class AllowRescopeScopedTokenDisabledTests(test_v3.RestfulTestCase):
self.build_authentication_request(
token=self.get_scoped_token(),
project_id=self.project_id),
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def _v2_token(self):
body = {
@@ -460,7 +461,7 @@ class AllowRescopeScopedTokenDisabledTests(test_v3.RestfulTestCase):
self.admin_request(path='/v2.0/tokens',
method='POST',
body=body,
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_rescoping_v2_to_v3_disabled(self):
token = self._v2_token()
@@ -468,7 +469,7 @@ class AllowRescopeScopedTokenDisabledTests(test_v3.RestfulTestCase):
self.build_authentication_request(
token=token['access']['token']['id'],
project_id=self.project_id),
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_rescoping_v3_to_v2_disabled(self):
token = {'id': self.get_scoped_token()}
@@ -498,7 +499,7 @@ class AllowRescopeScopedTokenDisabledTests(test_v3.RestfulTestCase):
self.build_authentication_request(
token=domain_scoped_token,
project_id=self.project_id),
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
class TestPKITokenAPIs(test_v3.RestfulTestCase, TokenAPITests):
@@ -637,7 +638,7 @@ class TestTokenRevokeSelfAndAdmin(test_v3.RestfulTestCase):
super(TestTokenRevokeSelfAndAdmin, self).config_overrides()
self.config_fixture.config(
group='oslo_policy',
- policy_file=tests.dirs.etc('policy.v3cloudsample.json'))
+ policy_file=unit.dirs.etc('policy.v3cloudsample.json'))
def test_user_revokes_own_token(self):
user_token = self.get_requested_token(
@@ -654,23 +655,29 @@ class TestTokenRevokeSelfAndAdmin(test_v3.RestfulTestCase):
password=self.userAdminA['password'],
domain_name=self.domainA['name']))
- self.head('/auth/tokens', headers=headers, expected_status=200,
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.OK,
token=adminA_token)
- self.head('/auth/tokens', headers=headers, expected_status=200,
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.OK,
token=user_token)
- self.delete('/auth/tokens', headers=headers, expected_status=204,
+ self.delete('/auth/tokens', headers=headers,
token=user_token)
- # invalid X-Auth-Token and invalid X-Subject-Token (401)
- self.head('/auth/tokens', headers=headers, expected_status=401,
+ # invalid X-Auth-Token and invalid X-Subject-Token
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.UNAUTHORIZED,
token=user_token)
- # invalid X-Auth-Token and invalid X-Subject-Token (401)
- self.delete('/auth/tokens', headers=headers, expected_status=401,
+ # invalid X-Auth-Token and invalid X-Subject-Token
+ self.delete('/auth/tokens', headers=headers,
+ expected_status=http_client.UNAUTHORIZED,
token=user_token)
- # valid X-Auth-Token and invalid X-Subject-Token (404)
- self.delete('/auth/tokens', headers=headers, expected_status=404,
+ # valid X-Auth-Token and invalid X-Subject-Token
+ self.delete('/auth/tokens', headers=headers,
+ expected_status=http_client.NOT_FOUND,
token=adminA_token)
- # valid X-Auth-Token and invalid X-Subject-Token (404)
- self.head('/auth/tokens', headers=headers, expected_status=404,
+ # valid X-Auth-Token and invalid X-Subject-Token
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.NOT_FOUND,
token=adminA_token)
def test_adminA_revokes_userA_token(self):
@@ -688,20 +695,25 @@ class TestTokenRevokeSelfAndAdmin(test_v3.RestfulTestCase):
password=self.userAdminA['password'],
domain_name=self.domainA['name']))
- self.head('/auth/tokens', headers=headers, expected_status=200,
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.OK,
token=adminA_token)
- self.head('/auth/tokens', headers=headers, expected_status=200,
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.OK,
token=user_token)
- self.delete('/auth/tokens', headers=headers, expected_status=204,
+ self.delete('/auth/tokens', headers=headers,
token=adminA_token)
- # invalid X-Auth-Token and invalid X-Subject-Token (401)
- self.head('/auth/tokens', headers=headers, expected_status=401,
+ # invalid X-Auth-Token and invalid X-Subject-Token
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.UNAUTHORIZED,
token=user_token)
- # valid X-Auth-Token and invalid X-Subject-Token (404)
- self.delete('/auth/tokens', headers=headers, expected_status=404,
+ # valid X-Auth-Token and invalid X-Subject-Token
+ self.delete('/auth/tokens', headers=headers,
+ expected_status=http_client.NOT_FOUND,
token=adminA_token)
- # valid X-Auth-Token and invalid X-Subject-Token (404)
- self.head('/auth/tokens', headers=headers, expected_status=404,
+ # valid X-Auth-Token and invalid X-Subject-Token
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.NOT_FOUND,
token=adminA_token)
def test_adminB_fails_revoking_userA_token(self):
@@ -729,9 +741,11 @@ class TestTokenRevokeSelfAndAdmin(test_v3.RestfulTestCase):
password=self.userAdminB['password'],
domain_name=self.domainB['name']))
- self.head('/auth/tokens', headers=headers, expected_status=403,
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.FORBIDDEN,
token=adminB_token)
- self.delete('/auth/tokens', headers=headers, expected_status=403,
+ self.delete('/auth/tokens', headers=headers,
+ expected_status=http_client.FORBIDDEN,
token=adminB_token)
@@ -854,10 +868,10 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# confirm both tokens are valid
self.head('/auth/tokens',
headers={'X-Subject-Token': unscoped_token},
- expected_status=200)
+ expected_status=http_client.OK)
self.head('/auth/tokens',
headers={'X-Subject-Token': scoped_token},
- expected_status=200)
+ expected_status=http_client.OK)
# create a new role
role = self.new_role_ref()
@@ -873,10 +887,10 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# both tokens should remain valid
self.head('/auth/tokens',
headers={'X-Subject-Token': unscoped_token},
- expected_status=200)
+ expected_status=http_client.OK)
self.head('/auth/tokens',
headers={'X-Subject-Token': scoped_token},
- expected_status=200)
+ expected_status=http_client.OK)
def test_deleting_user_grant_revokes_token(self):
"""Test deleting a user grant revokes token.
@@ -896,7 +910,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# Confirm token is valid
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
- expected_status=200)
+ expected_status=http_client.OK)
# Delete the grant, which should invalidate the token
grant_url = (
'/projects/%(project_id)s/users/%(user_id)s/'
@@ -907,7 +921,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
self.delete(grant_url)
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def role_data_fixtures(self):
self.projectC = self.new_project_ref(domain_id=self.domainA['id'])
@@ -998,19 +1012,19 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# Confirm tokens are valid
self.head('/auth/tokens',
headers={'X-Subject-Token': tokenA},
- expected_status=200)
+ expected_status=http_client.OK)
self.head('/auth/tokens',
headers={'X-Subject-Token': tokenB},
- expected_status=200)
+ expected_status=http_client.OK)
self.head('/auth/tokens',
headers={'X-Subject-Token': tokenC},
- expected_status=200)
+ expected_status=http_client.OK)
self.head('/auth/tokens',
headers={'X-Subject-Token': tokenD},
- expected_status=200)
+ expected_status=http_client.OK)
self.head('/auth/tokens',
headers={'X-Subject-Token': tokenE},
- expected_status=200)
+ expected_status=http_client.OK)
# Delete the role, which should invalidate the tokens
role_url = '/roles/%s' % self.role1['id']
@@ -1019,21 +1033,21 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# Check the tokens that used role1 is invalid
self.head('/auth/tokens',
headers={'X-Subject-Token': tokenA},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
self.head('/auth/tokens',
headers={'X-Subject-Token': tokenB},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
self.head('/auth/tokens',
headers={'X-Subject-Token': tokenD},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
self.head('/auth/tokens',
headers={'X-Subject-Token': tokenE},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
# ...but the one using role2 is still valid
self.head('/auth/tokens',
headers={'X-Subject-Token': tokenC},
- expected_status=200)
+ expected_status=http_client.OK)
def test_domain_user_role_assignment_maintains_token(self):
"""Test user-domain role assignment maintains existing token.
@@ -1053,7 +1067,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# Confirm token is valid
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
- expected_status=200)
+ expected_status=http_client.OK)
# Assign a role, which should not affect the token
grant_url = (
'/domains/%(domain_id)s/users/%(user_id)s/'
@@ -1064,7 +1078,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
self.put(grant_url)
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
- expected_status=200)
+ expected_status=http_client.OK)
def test_disabling_project_revokes_token(self):
token = self.get_requested_token(
@@ -1076,7 +1090,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# confirm token is valid
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
- expected_status=200)
+ expected_status=http_client.OK)
# disable the project, which should invalidate the token
self.patch(
@@ -1086,13 +1100,13 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# user should no longer have access to the project
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
self.v3_authenticate_token(
self.build_authentication_request(
user_id=self.user3['id'],
password=self.user3['password'],
project_id=self.projectA['id']),
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_deleting_project_revokes_token(self):
token = self.get_requested_token(
@@ -1104,7 +1118,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# confirm token is valid
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
- expected_status=200)
+ expected_status=http_client.OK)
# delete the project, which should invalidate the token
self.delete(
@@ -1113,13 +1127,13 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# user should no longer have access to the project
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
self.v3_authenticate_token(
self.build_authentication_request(
user_id=self.user3['id'],
password=self.user3['password'],
project_id=self.projectA['id']),
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_deleting_group_grant_revokes_tokens(self):
"""Test deleting a group grant revokes tokens.
@@ -1153,13 +1167,13 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# Confirm tokens are valid
self.head('/auth/tokens',
headers={'X-Subject-Token': token1},
- expected_status=200)
+ expected_status=http_client.OK)
self.head('/auth/tokens',
headers={'X-Subject-Token': token2},
- expected_status=200)
+ expected_status=http_client.OK)
self.head('/auth/tokens',
headers={'X-Subject-Token': token3},
- expected_status=200)
+ expected_status=http_client.OK)
# Delete the group grant, which should invalidate the
# tokens for user1 and user2
grant_url = (
@@ -1171,15 +1185,15 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
self.delete(grant_url)
self.head('/auth/tokens',
headers={'X-Subject-Token': token1},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
self.head('/auth/tokens',
headers={'X-Subject-Token': token2},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
# But user3's token should be invalid too as revocation is done for
# scope role & project
self.head('/auth/tokens',
headers={'X-Subject-Token': token3},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_domain_group_role_assignment_maintains_token(self):
"""Test domain-group role assignment maintains existing token.
@@ -1199,7 +1213,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# Confirm token is valid
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
- expected_status=200)
+ expected_status=http_client.OK)
# Delete the grant, which should invalidate the token
grant_url = (
'/domains/%(domain_id)s/groups/%(group_id)s/'
@@ -1210,7 +1224,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
self.put(grant_url)
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
- expected_status=200)
+ expected_status=http_client.OK)
def test_group_membership_changes_revokes_token(self):
"""Test add/removal to/from group revokes token.
@@ -1240,10 +1254,10 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# Confirm tokens are valid
self.head('/auth/tokens',
headers={'X-Subject-Token': token1},
- expected_status=200)
+ expected_status=http_client.OK)
self.head('/auth/tokens',
headers={'X-Subject-Token': token2},
- expected_status=200)
+ expected_status=http_client.OK)
# Remove user1 from group1, which should invalidate
# the token
self.delete('/groups/%(group_id)s/users/%(user_id)s' % {
@@ -1251,18 +1265,18 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
'user_id': self.user1['id']})
self.head('/auth/tokens',
headers={'X-Subject-Token': token1},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
# But user2's token should still be valid
self.head('/auth/tokens',
headers={'X-Subject-Token': token2},
- expected_status=200)
+ expected_status=http_client.OK)
# Adding user2 to a group should not invalidate token
self.put('/groups/%(group_id)s/users/%(user_id)s' % {
'group_id': self.group2['id'],
'user_id': self.user2['id']})
self.head('/auth/tokens',
headers={'X-Subject-Token': token2},
- expected_status=200)
+ expected_status=http_client.OK)
def test_removing_role_assignment_does_not_affect_other_users(self):
"""Revoking a role from one user should not affect other users."""
@@ -1295,18 +1309,18 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# authorization for the first user should now fail
self.head('/auth/tokens',
headers={'X-Subject-Token': user1_token},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
self.v3_authenticate_token(
self.build_authentication_request(
user_id=self.user1['id'],
password=self.user1['password'],
project_id=self.projectA['id']),
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
# authorization for the second user should still succeed
self.head('/auth/tokens',
headers={'X-Subject-Token': user3_token},
- expected_status=200)
+ expected_status=http_client.OK)
self.v3_authenticate_token(
self.build_authentication_request(
user_id=self.user3['id'],
@@ -1329,7 +1343,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
'/projects/%(project_id)s' % {'project_id': self.projectA['id']})
# Make sure that we get a NotFound(404) when heading that role.
- self.head(role_path, expected_status=404)
+ self.head(role_path, expected_status=http_client.NOT_FOUND)
def get_v2_token(self, token=None, project_id=None):
body = {'auth': {}, }
@@ -1356,12 +1370,11 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
token = self.get_v2_token()
self.delete('/auth/tokens',
- headers={'X-Subject-Token': token},
- expected_status=204)
+ headers={'X-Subject-Token': token})
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_revoke_token_from_token(self):
# Test that a scoped token can be requested from an unscoped token,
@@ -1387,38 +1400,36 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# revoke the project-scoped token.
self.delete('/auth/tokens',
- headers={'X-Subject-Token': project_scoped_token},
- expected_status=204)
+ headers={'X-Subject-Token': project_scoped_token})
# The project-scoped token is invalidated.
self.head('/auth/tokens',
headers={'X-Subject-Token': project_scoped_token},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
# The unscoped token should still be valid.
self.head('/auth/tokens',
headers={'X-Subject-Token': unscoped_token},
- expected_status=200)
+ expected_status=http_client.OK)
# The domain-scoped token should still be valid.
self.head('/auth/tokens',
headers={'X-Subject-Token': domain_scoped_token},
- expected_status=200)
+ expected_status=http_client.OK)
# revoke the domain-scoped token.
self.delete('/auth/tokens',
- headers={'X-Subject-Token': domain_scoped_token},
- expected_status=204)
+ headers={'X-Subject-Token': domain_scoped_token})
# The domain-scoped token is invalid.
self.head('/auth/tokens',
headers={'X-Subject-Token': domain_scoped_token},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
# The unscoped token should still be valid.
self.head('/auth/tokens',
headers={'X-Subject-Token': unscoped_token},
- expected_status=200)
+ expected_status=http_client.OK)
def test_revoke_token_from_token_v2(self):
# Test that a scoped token can be requested from an unscoped token,
@@ -1436,18 +1447,17 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
# revoke the project-scoped token.
self.delete('/auth/tokens',
- headers={'X-Subject-Token': project_scoped_token},
- expected_status=204)
+ headers={'X-Subject-Token': project_scoped_token})
# The project-scoped token is invalidated.
self.head('/auth/tokens',
headers={'X-Subject-Token': project_scoped_token},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
# The unscoped token should still be valid.
self.head('/auth/tokens',
headers={'X-Subject-Token': unscoped_token},
- expected_status=200)
+ expected_status=http_client.OK)
class TestTokenRevokeByAssignment(TestTokenRevokeById):
@@ -1491,11 +1501,11 @@ class TestTokenRevokeByAssignment(TestTokenRevokeById):
# authorization for the projectA should still succeed
self.head('/auth/tokens',
headers={'X-Subject-Token': other_project_token},
- expected_status=200)
+ expected_status=http_client.OK)
# while token for the projectB should not
self.head('/auth/tokens',
headers={'X-Subject-Token': project_token},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
revoked_tokens = [
t['id'] for t in self.token_provider_api.list_revoked_tokens()]
# token is in token revocation list
@@ -1553,57 +1563,53 @@ class TestTokenRevokeApi(TestTokenRevokeById):
def test_revoke_token(self):
scoped_token = self.get_scoped_token()
headers = {'X-Subject-Token': scoped_token}
- response = self.get('/auth/tokens', headers=headers,
- expected_status=200).json_body['token']
+ response = self.get('/auth/tokens', headers=headers).json_body['token']
- self.delete('/auth/tokens', headers=headers, expected_status=204)
- self.head('/auth/tokens', headers=headers, expected_status=404)
- events_response = self.get('/OS-REVOKE/events',
- expected_status=200).json_body
+ self.delete('/auth/tokens', headers=headers)
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.NOT_FOUND)
+ events_response = self.get('/OS-REVOKE/events').json_body
self.assertValidRevokedTokenResponse(events_response,
audit_id=response['audit_ids'][0])
def test_revoke_v2_token(self):
token = self.get_v2_token()
headers = {'X-Subject-Token': token}
- response = self.get('/auth/tokens', headers=headers,
- expected_status=200).json_body['token']
- self.delete('/auth/tokens', headers=headers, expected_status=204)
- self.head('/auth/tokens', headers=headers, expected_status=404)
- events_response = self.get('/OS-REVOKE/events',
- expected_status=200).json_body
+ response = self.get('/auth/tokens',
+ headers=headers).json_body['token']
+ self.delete('/auth/tokens', headers=headers)
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.NOT_FOUND)
+ events_response = self.get('/OS-REVOKE/events').json_body
self.assertValidRevokedTokenResponse(
events_response,
audit_id=response['audit_ids'][0])
def test_revoke_by_id_false_410(self):
- self.get('/auth/tokens/OS-PKI/revoked', expected_status=410)
+ self.get('/auth/tokens/OS-PKI/revoked',
+ expected_status=http_client.GONE)
def test_list_delete_project_shows_in_event_list(self):
self.role_data_fixtures()
- events = self.get('/OS-REVOKE/events',
- expected_status=200).json_body['events']
+ events = self.get('/OS-REVOKE/events').json_body['events']
self.assertEqual([], events)
self.delete(
'/projects/%(project_id)s' % {'project_id': self.projectA['id']})
- events_response = self.get('/OS-REVOKE/events',
- expected_status=200).json_body
+ events_response = self.get('/OS-REVOKE/events').json_body
self.assertValidDeletedProjectResponse(events_response,
self.projectA['id'])
def test_disable_domain_shows_in_event_list(self):
- events = self.get('/OS-REVOKE/events',
- expected_status=200).json_body['events']
+ events = self.get('/OS-REVOKE/events').json_body['events']
self.assertEqual([], events)
disable_body = {'domain': {'enabled': False}}
self.patch(
'/domains/%(project_id)s' % {'project_id': self.domainA['id']},
body=disable_body)
- events = self.get('/OS-REVOKE/events',
- expected_status=200).json_body
+ events = self.get('/OS-REVOKE/events').json_body
self.assertDomainInList(events, self.domainA['id'])
@@ -1633,8 +1639,7 @@ class TestTokenRevokeApi(TestTokenRevokeById):
def test_list_delete_token_shows_in_event_list(self):
self.role_data_fixtures()
- events = self.get('/OS-REVOKE/events',
- expected_status=200).json_body['events']
+ events = self.get('/OS-REVOKE/events').json_body['events']
self.assertEqual([], events)
scoped_token = self.get_scoped_token()
@@ -1648,47 +1653,50 @@ class TestTokenRevokeApi(TestTokenRevokeById):
response.json_body['token']
headers3 = {'X-Subject-Token': response.headers['X-Subject-Token']}
- self.head('/auth/tokens', headers=headers, expected_status=200)
- self.head('/auth/tokens', headers=headers2, expected_status=200)
- self.head('/auth/tokens', headers=headers3, expected_status=200)
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.OK)
+ self.head('/auth/tokens', headers=headers2,
+ expected_status=http_client.OK)
+ self.head('/auth/tokens', headers=headers3,
+ expected_status=http_client.OK)
- self.delete('/auth/tokens', headers=headers, expected_status=204)
+ self.delete('/auth/tokens', headers=headers)
# NOTE(ayoung): not deleting token3, as it should be deleted
# by previous
- events_response = self.get('/OS-REVOKE/events',
- expected_status=200).json_body
+ events_response = self.get('/OS-REVOKE/events').json_body
events = events_response['events']
self.assertEqual(1, len(events))
self.assertEventDataInList(
events,
audit_id=token2['audit_ids'][1])
- self.head('/auth/tokens', headers=headers, expected_status=404)
- self.head('/auth/tokens', headers=headers2, expected_status=200)
- self.head('/auth/tokens', headers=headers3, expected_status=200)
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.NOT_FOUND)
+ self.head('/auth/tokens', headers=headers2,
+ expected_status=http_client.OK)
+ self.head('/auth/tokens', headers=headers3,
+ expected_status=http_client.OK)
def test_list_with_filter(self):
self.role_data_fixtures()
- events = self.get('/OS-REVOKE/events',
- expected_status=200).json_body['events']
+ events = self.get('/OS-REVOKE/events').json_body['events']
self.assertEqual(0, len(events))
scoped_token = self.get_scoped_token()
headers = {'X-Subject-Token': scoped_token}
auth = self.build_authentication_request(token=scoped_token)
headers2 = {'X-Subject-Token': self.get_requested_token(auth)}
- self.delete('/auth/tokens', headers=headers, expected_status=204)
- self.delete('/auth/tokens', headers=headers2, expected_status=204)
+ self.delete('/auth/tokens', headers=headers)
+ self.delete('/auth/tokens', headers=headers2)
- events = self.get('/OS-REVOKE/events',
- expected_status=200).json_body['events']
+ events = self.get('/OS-REVOKE/events').json_body['events']
self.assertEqual(2, len(events))
future = utils.isotime(timeutils.utcnow() +
datetime.timedelta(seconds=1000))
- events = self.get('/OS-REVOKE/events?since=%s' % (future),
- expected_status=200).json_body['events']
+ events = self.get('/OS-REVOKE/events?since=%s' % (future)
+ ).json_body['events']
self.assertEqual(0, len(events))
@@ -2002,7 +2010,7 @@ class TestAuth(test_v3.RestfulTestCase):
self._check_disabled_endpoint_result(r.result['token']['catalog'],
disabled_endpoint_id)
- def test_project_id_scoped_token_with_user_id_401(self):
+ def test_project_id_scoped_token_with_user_id_unauthorized(self):
project = self.new_project_ref(domain_id=self.domain_id)
self.resource_api.create_project(project['id'], project)
@@ -2010,7 +2018,8 @@ class TestAuth(test_v3.RestfulTestCase):
user_id=self.user['id'],
password=self.user['password'],
project_id=project['id'])
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_user_and_group_roles_scoped_token(self):
"""Test correct roles are returned in scoped token.
@@ -2346,7 +2355,8 @@ class TestAuth(test_v3.RestfulTestCase):
user_id=self.user['id'],
password=self.user['password'],
domain_id=self.domain['id'])
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_auth_with_id(self):
auth_data = self.build_authentication_request(
@@ -2395,34 +2405,39 @@ class TestAuth(test_v3.RestfulTestCase):
auth_data = self.build_authentication_request(
user_id=uuid.uuid4().hex,
password=self.user['password'])
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_invalid_user_name(self):
auth_data = self.build_authentication_request(
username=uuid.uuid4().hex,
user_domain_id=self.domain['id'],
password=self.user['password'])
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_invalid_domain_id(self):
auth_data = self.build_authentication_request(
username=self.user['name'],
user_domain_id=uuid.uuid4().hex,
password=self.user['password'])
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_invalid_domain_name(self):
auth_data = self.build_authentication_request(
username=self.user['name'],
user_domain_name=uuid.uuid4().hex,
password=self.user['password'])
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_invalid_password(self):
auth_data = self.build_authentication_request(
user_id=self.user['id'],
password=uuid.uuid4().hex)
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_remote_user_no_realm(self):
api = auth.controllers.Auth()
@@ -2588,7 +2603,8 @@ class TestAuth(test_v3.RestfulTestCase):
user_id=user['id'],
password='password')
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_disabled_default_project_result_in_unscoped_token(self):
# create a disabled project to work with
@@ -2666,7 +2682,8 @@ class TestAuth(test_v3.RestfulTestCase):
user_id=self.user['id'],
password=self.user['password'],
project_id=project['id'])
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
# user should not be able to auth with project_name & domain
auth_data = self.build_authentication_request(
@@ -2674,7 +2691,8 @@ class TestAuth(test_v3.RestfulTestCase):
password=self.user['password'],
project_name=project['name'],
project_domain_id=domain['id'])
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_auth_methods_with_different_identities_fails(self):
# get the token for a user. This is self.user which is different from
@@ -2686,7 +2704,8 @@ class TestAuth(test_v3.RestfulTestCase):
token=token,
user_id=self.default_domain_user['id'],
password=self.default_domain_user['password'])
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
class TestAuthJSONExternal(test_v3.RestfulTestCase):
@@ -2712,15 +2731,18 @@ class TestTrustOptional(test_v3.RestfulTestCase):
self.config_fixture.config(group='trust', enabled=False)
def test_trusts_404(self):
- self.get('/OS-TRUST/trusts', body={'trust': {}}, expected_status=404)
- self.post('/OS-TRUST/trusts', body={'trust': {}}, expected_status=404)
+ self.get('/OS-TRUST/trusts', body={'trust': {}},
+ expected_status=http_client.NOT_FOUND)
+ self.post('/OS-TRUST/trusts', body={'trust': {}},
+ expected_status=http_client.NOT_FOUND)
- def test_auth_with_scope_in_trust_403(self):
+ def test_auth_with_scope_in_trust_forbidden(self):
auth_data = self.build_authentication_request(
user_id=self.user['id'],
password=self.user['password'],
trust_id=uuid.uuid4().hex)
- self.v3_authenticate_token(auth_data, expected_status=403)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.FORBIDDEN)
class TestTrustRedelegation(test_v3.RestfulTestCase):
@@ -2804,7 +2826,7 @@ class TestTrustRedelegation(test_v3.RestfulTestCase):
self.post('/OS-TRUST/trusts',
body={'trust': self.chained_trust_ref},
token=trust_token,
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_modified_redelegation_count_error(self):
r = self.post('/OS-TRUST/trusts',
@@ -2820,14 +2842,14 @@ class TestTrustRedelegation(test_v3.RestfulTestCase):
self.post('/OS-TRUST/trusts',
body={'trust': self.chained_trust_ref},
token=trust_token,
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_max_redelegation_count_constraint(self):
incorrect = CONF.trust.max_redelegation_count + 1
self.redelegated_trust_ref['redelegation_count'] = incorrect
self.post('/OS-TRUST/trusts',
body={'trust': self.redelegated_trust_ref},
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_redelegation_expiry(self):
r = self.post('/OS-TRUST/trusts',
@@ -2847,7 +2869,7 @@ class TestTrustRedelegation(test_v3.RestfulTestCase):
self.post('/OS-TRUST/trusts',
body={'trust': too_long_live_chained_trust_ref},
token=trust_token,
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_redelegation_remaining_uses(self):
r = self.post('/OS-TRUST/trusts',
@@ -2862,7 +2884,7 @@ class TestTrustRedelegation(test_v3.RestfulTestCase):
self.post('/OS-TRUST/trusts',
body={'trust': self.chained_trust_ref},
token=trust_token,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_roles_subset(self):
# Build second role
@@ -2949,7 +2971,7 @@ class TestTrustRedelegation(test_v3.RestfulTestCase):
self.post('/OS-TRUST/trusts',
body={'trust': self.chained_trust_ref},
token=trust_token,
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_redelegation_terminator(self):
r = self.post('/OS-TRUST/trusts',
@@ -2977,7 +2999,7 @@ class TestTrustRedelegation(test_v3.RestfulTestCase):
self.post('/OS-TRUST/trusts',
body={'trust': ref},
token=trust_token,
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
class TestTrustChain(test_v3.RestfulTestCase):
@@ -3084,22 +3106,20 @@ class TestTrustChain(test_v3.RestfulTestCase):
def test_delete_trust_cascade(self):
self.assert_user_authenticate(self.user_chain[0])
self.delete('/OS-TRUST/trusts/%(trust_id)s' % {
- 'trust_id': self.trust_chain[0]['id']},
- expected_status=204)
+ 'trust_id': self.trust_chain[0]['id']})
headers = {'X-Subject-Token': self.last_token}
- self.head('/auth/tokens', headers=headers, expected_status=404)
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.NOT_FOUND)
self.assert_trust_tokens_revoked(self.trust_chain[0]['id'])
def test_delete_broken_chain(self):
self.assert_user_authenticate(self.user_chain[0])
self.delete('/OS-TRUST/trusts/%(trust_id)s' % {
- 'trust_id': self.trust_chain[1]['id']},
- expected_status=204)
+ 'trust_id': self.trust_chain[1]['id']})
self.delete('/OS-TRUST/trusts/%(trust_id)s' % {
- 'trust_id': self.trust_chain[0]['id']},
- expected_status=204)
+ 'trust_id': self.trust_chain[0]['id']})
def test_trustor_roles_revoked(self):
self.assert_user_authenticate(self.user_chain[0])
@@ -3111,7 +3131,8 @@ class TestTrustChain(test_v3.RestfulTestCase):
auth_data = self.build_authentication_request(
token=self.last_token,
trust_id=self.trust_chain[-1]['id'])
- self.v3_authenticate_token(auth_data, expected_status=404)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.NOT_FOUND)
def test_intermediate_user_disabled(self):
self.assert_user_authenticate(self.user_chain[0])
@@ -3123,7 +3144,8 @@ class TestTrustChain(test_v3.RestfulTestCase):
# Bypass policy enforcement
with mock.patch.object(rules, 'enforce', return_value=True):
headers = {'X-Subject-Token': self.last_token}
- self.head('/auth/tokens', headers=headers, expected_status=403)
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.FORBIDDEN)
def test_intermediate_user_deleted(self):
self.assert_user_authenticate(self.user_chain[0])
@@ -3133,7 +3155,8 @@ class TestTrustChain(test_v3.RestfulTestCase):
# Bypass policy enforcement
with mock.patch.object(rules, 'enforce', return_value=True):
headers = {'X-Subject-Token': self.last_token}
- self.head('/auth/tokens', headers=headers, expected_status=403)
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.FORBIDDEN)
class TestTrustAuth(test_v3.RestfulTestCase):
@@ -3159,9 +3182,10 @@ class TestTrustAuth(test_v3.RestfulTestCase):
self.trustee_user['password'] = password
self.trustee_user_id = self.trustee_user['id']
- def test_create_trust_400(self):
+ def test_create_trust_bad_request(self):
# The server returns a 403 Forbidden rather than a 400, see bug 1133435
- self.post('/OS-TRUST/trusts', body={'trust': {}}, expected_status=403)
+ self.post('/OS-TRUST/trusts', body={'trust': {}},
+ expected_status=http_client.FORBIDDEN)
def test_create_unscoped_trust(self):
ref = self.new_trust_ref(
@@ -3175,7 +3199,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
trustor_user_id=self.user_id,
trustee_user_id=self.trustee_user_id,
project_id=self.project_id)
- self.post('/OS-TRUST/trusts', body={'trust': ref}, expected_status=403)
+ self.post('/OS-TRUST/trusts', body={'trust': ref},
+ expected_status=http_client.FORBIDDEN)
def _initialize_test_consume_trust(self, count):
# Make sure remaining_uses is decremented as we consume the trust
@@ -3189,8 +3214,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
# make sure the trust exists
trust = self.assertValidTrustResponse(r, ref)
r = self.get(
- '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
- expected_status=200)
+ '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']})
# get a token for the trustee
auth_data = self.build_authentication_request(
user_id=self.trustee_user['id'],
@@ -3208,8 +3232,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
trust = self._initialize_test_consume_trust(2)
# check decremented value
r = self.get(
- '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
- expected_status=200)
+ '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']})
trust = r.result.get('trust')
self.assertIsNotNone(trust)
self.assertEqual(1, trust['remaining_uses'])
@@ -3219,13 +3242,14 @@ class TestTrustAuth(test_v3.RestfulTestCase):
# No more uses, the trust is made unavailable
self.get(
'/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
# this time we can't get a trust token
auth_data = self.build_authentication_request(
user_id=self.trustee_user['id'],
password=self.trustee_user['password'],
trust_id=trust['id'])
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_create_trust_with_bad_values_for_remaining_uses(self):
# negative values for the remaining_uses parameter are forbidden
@@ -3245,7 +3269,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
role_ids=[self.role_id])
self.post('/OS-TRUST/trusts',
body={'trust': ref},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_invalid_trust_request_without_impersonation(self):
ref = self.new_trust_ref(
@@ -3258,7 +3282,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
self.post('/OS-TRUST/trusts',
body={'trust': ref},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_invalid_trust_request_without_trustee(self):
ref = self.new_trust_ref(
@@ -3271,7 +3295,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
self.post('/OS-TRUST/trusts',
body={'trust': ref},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_create_unlimited_use_trust(self):
# by default trusts are unlimited in terms of tokens that can be
@@ -3286,8 +3310,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
trust = self.assertValidTrustResponse(r, ref)
r = self.get(
- '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
- expected_status=200)
+ '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']})
auth_data = self.build_authentication_request(
user_id=self.trustee_user['id'],
password=self.trustee_user['password'])
@@ -3298,8 +3321,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
trust_id=trust['id'])
r = self.v3_authenticate_token(auth_data)
r = self.get(
- '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
- expected_status=200)
+ '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']})
trust = r.result.get('trust')
self.assertIsNone(trust['remaining_uses'])
@@ -3313,45 +3335,41 @@ class TestTrustAuth(test_v3.RestfulTestCase):
trust = self.assertValidTrustResponse(r, ref)
r = self.get(
- '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
- expected_status=200)
+ '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']})
self.assertValidTrustResponse(r, ref)
# validate roles on the trust
r = self.get(
'/OS-TRUST/trusts/%(trust_id)s/roles' % {
- 'trust_id': trust['id']},
- expected_status=200)
+ 'trust_id': trust['id']})
roles = self.assertValidRoleListResponse(r, self.role)
self.assertIn(self.role['id'], [x['id'] for x in roles])
self.head(
'/OS-TRUST/trusts/%(trust_id)s/roles/%(role_id)s' % {
'trust_id': trust['id'],
'role_id': self.role['id']},
- expected_status=200)
+ expected_status=http_client.OK)
r = self.get(
'/OS-TRUST/trusts/%(trust_id)s/roles/%(role_id)s' % {
'trust_id': trust['id'],
- 'role_id': self.role['id']},
- expected_status=200)
+ 'role_id': self.role['id']})
self.assertValidRoleResponse(r, self.role)
- r = self.get('/OS-TRUST/trusts', expected_status=200)
+ r = self.get('/OS-TRUST/trusts')
self.assertValidTrustListResponse(r, trust)
# trusts are immutable
self.patch(
'/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
body={'trust': ref},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
self.delete(
- '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
- expected_status=204)
+ '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']})
self.get(
'/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_create_trust_trustee_404(self):
ref = self.new_trust_ref(
@@ -3359,7 +3377,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
trustee_user_id=uuid.uuid4().hex,
project_id=self.project_id,
role_ids=[self.role_id])
- self.post('/OS-TRUST/trusts', body={'trust': ref}, expected_status=404)
+ self.post('/OS-TRUST/trusts', body={'trust': ref},
+ expected_status=http_client.NOT_FOUND)
def test_create_trust_trustor_trustee_backwards(self):
ref = self.new_trust_ref(
@@ -3367,7 +3386,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
trustee_user_id=self.user_id,
project_id=self.project_id,
role_ids=[self.role_id])
- self.post('/OS-TRUST/trusts', body={'trust': ref}, expected_status=403)
+ self.post('/OS-TRUST/trusts', body={'trust': ref},
+ expected_status=http_client.FORBIDDEN)
def test_create_trust_project_404(self):
ref = self.new_trust_ref(
@@ -3375,7 +3395,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
trustee_user_id=self.trustee_user_id,
project_id=uuid.uuid4().hex,
role_ids=[self.role_id])
- self.post('/OS-TRUST/trusts', body={'trust': ref}, expected_status=404)
+ self.post('/OS-TRUST/trusts', body={'trust': ref},
+ expected_status=http_client.NOT_FOUND)
def test_create_trust_role_id_404(self):
ref = self.new_trust_ref(
@@ -3383,7 +3404,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
trustee_user_id=self.trustee_user_id,
project_id=self.project_id,
role_ids=[uuid.uuid4().hex])
- self.post('/OS-TRUST/trusts', body={'trust': ref}, expected_status=404)
+ self.post('/OS-TRUST/trusts', body={'trust': ref},
+ expected_status=http_client.NOT_FOUND)
def test_create_trust_role_name_404(self):
ref = self.new_trust_ref(
@@ -3391,7 +3413,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
trustee_user_id=self.trustee_user_id,
project_id=self.project_id,
role_names=[uuid.uuid4().hex])
- self.post('/OS-TRUST/trusts', body={'trust': ref}, expected_status=404)
+ self.post('/OS-TRUST/trusts', body={'trust': ref},
+ expected_status=http_client.NOT_FOUND)
def test_v3_v2_intermix_trustor_not_in_default_domain_failed(self):
ref = self.new_trust_ref(
@@ -3419,7 +3442,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
path = '/v2.0/tokens/%s' % (token)
self.admin_request(
path=path, token=CONF.admin_token,
- method='GET', expected_status=401)
+ method='GET', expected_status=http_client.UNAUTHORIZED)
def test_v3_v2_intermix_trustor_not_in_default_domaini_failed(self):
ref = self.new_trust_ref(
@@ -3452,7 +3475,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
path = '/v2.0/tokens/%s' % (token)
self.admin_request(
path=path, token=CONF.admin_token,
- method='GET', expected_status=401)
+ method='GET', expected_status=http_client.UNAUTHORIZED)
def test_v3_v2_intermix_project_not_in_default_domaini_failed(self):
# create a trustee in default domain to delegate stuff to
@@ -3492,7 +3515,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
path = '/v2.0/tokens/%s' % (token)
self.admin_request(
path=path, token=CONF.admin_token,
- method='GET', expected_status=401)
+ method='GET', expected_status=http_client.UNAUTHORIZED)
def test_v3_v2_intermix(self):
# create a trustee in default domain to delegate stuff to
@@ -3531,7 +3554,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
path = '/v2.0/tokens/%s' % (token)
self.admin_request(
path=path, token=CONF.admin_token,
- method='GET', expected_status=200)
+ method='GET', expected_status=http_client.OK)
def test_exercise_trust_scoped_token_without_impersonation(self):
ref = self.new_trust_ref(
@@ -3624,7 +3647,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
self.post('/OS-TRUST/trusts',
body={'trust': ref},
token=trust_token,
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_trust_deleted_grant(self):
# create a new role
@@ -3662,7 +3685,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
user_id=self.trustee_user['id'],
password=self.trustee_user['password'],
trust_id=trust['id'])
- r = self.v3_authenticate_token(auth_data, expected_status=403)
+ r = self.v3_authenticate_token(auth_data,
+ expected_status=http_client.FORBIDDEN)
def test_trust_chained(self):
"""Test that a trust token can't be used to execute another trust.
@@ -3730,11 +3754,11 @@ class TestTrustAuth(test_v3.RestfulTestCase):
auth_data = self.build_authentication_request(
token=trust_token,
trust_id=trust1['id'])
- r = self.v3_authenticate_token(auth_data, expected_status=403)
+ r = self.v3_authenticate_token(auth_data,
+ expected_status=http_client.FORBIDDEN)
def assertTrustTokensRevoked(self, trust_id):
- revocation_response = self.get('/OS-REVOKE/events',
- expected_status=200)
+ revocation_response = self.get('/OS-REVOKE/events')
revocation_events = revocation_response.json_body['events']
found = False
for event in revocation_events:
@@ -3763,10 +3787,10 @@ class TestTrustAuth(test_v3.RestfulTestCase):
r, self.trustee_user)
trust_token = r.headers['X-Subject-Token']
self.delete('/OS-TRUST/trusts/%(trust_id)s' % {
- 'trust_id': trust_id},
- expected_status=204)
+ 'trust_id': trust_id})
headers = {'X-Subject-Token': trust_token}
- self.head('/auth/tokens', headers=headers, expected_status=404)
+ self.head('/auth/tokens', headers=headers,
+ expected_status=http_client.NOT_FOUND)
self.assertTrustTokensRevoked(trust_id)
def disable_user(self, user):
@@ -3790,7 +3814,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
user_id=self.trustee_user['id'],
password=self.trustee_user['password'],
trust_id=trust['id'])
- self.v3_authenticate_token(auth_data, expected_status=201)
+ self.v3_authenticate_token(auth_data)
self.disable_user(self.user)
@@ -3798,7 +3822,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
user_id=self.trustee_user['id'],
password=self.trustee_user['password'],
trust_id=trust['id'])
- self.v3_authenticate_token(auth_data, expected_status=403)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.FORBIDDEN)
def test_trust_get_token_fails_if_trustee_disabled(self):
ref = self.new_trust_ref(
@@ -3817,7 +3842,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
user_id=self.trustee_user['id'],
password=self.trustee_user['password'],
trust_id=trust['id'])
- self.v3_authenticate_token(auth_data, expected_status=201)
+ self.v3_authenticate_token(auth_data)
self.disable_user(self.trustee_user)
@@ -3825,7 +3850,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
user_id=self.trustee_user['id'],
password=self.trustee_user['password'],
trust_id=trust['id'])
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_delete_trust(self):
ref = self.new_trust_ref(
@@ -3841,22 +3867,22 @@ class TestTrustAuth(test_v3.RestfulTestCase):
trust = self.assertValidTrustResponse(r, ref)
self.delete('/OS-TRUST/trusts/%(trust_id)s' % {
- 'trust_id': trust['id']},
- expected_status=204)
+ 'trust_id': trust['id']})
self.get('/OS-TRUST/trusts/%(trust_id)s' % {
'trust_id': trust['id']},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
self.get('/OS-TRUST/trusts/%(trust_id)s' % {
'trust_id': trust['id']},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
auth_data = self.build_authentication_request(
user_id=self.trustee_user['id'],
password=self.trustee_user['password'],
trust_id=trust['id'])
- self.v3_authenticate_token(auth_data, expected_status=401)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.UNAUTHORIZED)
def test_list_trusts(self):
ref = self.new_trust_ref(
@@ -3871,19 +3897,19 @@ class TestTrustAuth(test_v3.RestfulTestCase):
r = self.post('/OS-TRUST/trusts', body={'trust': ref})
self.assertValidTrustResponse(r, ref)
- r = self.get('/OS-TRUST/trusts', expected_status=200)
+ r = self.get('/OS-TRUST/trusts')
trusts = r.result['trusts']
self.assertEqual(3, len(trusts))
self.assertValidTrustListResponse(r)
r = self.get('/OS-TRUST/trusts?trustor_user_id=%s' %
- self.user_id, expected_status=200)
+ self.user_id)
trusts = r.result['trusts']
self.assertEqual(3, len(trusts))
self.assertValidTrustListResponse(r)
r = self.get('/OS-TRUST/trusts?trustee_user_id=%s' %
- self.user_id, expected_status=200)
+ self.user_id)
trusts = r.result['trusts']
self.assertEqual(0, len(trusts))
@@ -3909,16 +3935,14 @@ class TestTrustAuth(test_v3.RestfulTestCase):
trust_token = r.headers.get('X-Subject-Token')
self.get('/OS-TRUST/trusts?trustor_user_id=%s' %
- self.user_id, expected_status=200,
- token=trust_token)
+ self.user_id, token=trust_token)
self.assertValidUserResponse(
self.patch('/users/%s' % self.trustee_user['id'],
- body={'user': {'password': uuid.uuid4().hex}},
- expected_status=200))
+ body={'user': {'password': uuid.uuid4().hex}}))
self.get('/OS-TRUST/trusts?trustor_user_id=%s' %
- self.user_id, expected_status=401,
+ self.user_id, expected_status=http_client.UNAUTHORIZED,
token=trust_token)
def test_trustee_can_do_role_ops(self):
@@ -3947,14 +3971,13 @@ class TestTrustAuth(test_v3.RestfulTestCase):
'trust_id': trust['id'],
'role_id': self.role['id']},
auth=auth_data,
- expected_status=200)
+ expected_status=http_client.OK)
r = self.get(
'/OS-TRUST/trusts/%(trust_id)s/roles/%(role_id)s' % {
'trust_id': trust['id'],
'role_id': self.role['id']},
- auth=auth_data,
- expected_status=200)
+ auth=auth_data)
self.assertValidRoleResponse(r, self.role)
def test_do_not_consume_remaining_uses_when_get_token_fails(self):
@@ -3977,7 +4000,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
user_id=self.default_domain_user['id'],
password=self.default_domain_user['password'],
trust_id=trust_id)
- self.v3_authenticate_token(auth_data, expected_status=403)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.FORBIDDEN)
r = self.get('/OS-TRUST/trusts/%s' % trust_id)
self.assertEqual(3, r.result.get('trust').get('remaining_uses'))
@@ -3998,10 +4022,10 @@ class TestAPIProtectionWithoutAuthContextMiddleware(test_v3.RestfulTestCase):
'query_string': {},
'environment': {}}
r = auth_controller.validate_token(context)
- self.assertEqual(200, r.status_code)
+ self.assertEqual(http_client.OK, r.status_code)
-class TestAuthContext(tests.TestCase):
+class TestAuthContext(unit.TestCase):
def setUp(self):
super(TestAuthContext, self).setUp()
self.auth_context = auth.controllers.AuthContext()
@@ -4058,9 +4082,7 @@ class TestAuthSpecificData(test_v3.RestfulTestCase):
def test_get_catalog_project_scoped_token(self):
"""Call ``GET /auth/catalog`` with a project-scoped token."""
- r = self.get(
- '/auth/catalog',
- expected_status=200)
+ r = self.get('/auth/catalog')
self.assertValidCatalogResponse(r)
def test_get_catalog_domain_scoped_token(self):
@@ -4075,7 +4097,7 @@ class TestAuthSpecificData(test_v3.RestfulTestCase):
user_id=self.user['id'],
password=self.user['password'],
domain_id=self.domain['id']),
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_get_catalog_unscoped_token(self):
"""Call ``GET /auth/catalog`` with an unscoped token."""
@@ -4084,17 +4106,17 @@ class TestAuthSpecificData(test_v3.RestfulTestCase):
auth=self.build_authentication_request(
user_id=self.default_domain_user['id'],
password=self.default_domain_user['password']),
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_get_catalog_no_token(self):
"""Call ``GET /auth/catalog`` without a token."""
self.get(
'/auth/catalog',
noauth=True,
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_get_projects_project_scoped_token(self):
- r = self.get('/auth/projects', expected_status=200)
+ r = self.get('/auth/projects')
self.assertThat(r.json['projects'], matchers.HasLength(1))
self.assertValidProjectListResponse(r)
@@ -4102,7 +4124,7 @@ class TestAuthSpecificData(test_v3.RestfulTestCase):
self.put(path='/domains/%s/users/%s/roles/%s' % (
self.domain['id'], self.user['id'], self.role['id']))
- r = self.get('/auth/domains', expected_status=200)
+ r = self.get('/auth/domains')
self.assertThat(r.json['domains'], matchers.HasLength(1))
self.assertValidDomainListResponse(r)
@@ -4113,7 +4135,7 @@ class TestFernetTokenProvider(test_v3.RestfulTestCase):
self.useFixture(ksfixtures.KeyRepository(self.config_fixture))
def _make_auth_request(self, auth_data):
- resp = self.post('/auth/tokens', body=auth_data, expected_status=201)
+ resp = self.post('/auth/tokens', body=auth_data)
token = resp.headers.get('X-Subject-Token')
self.assertLess(len(token), 255)
return token
@@ -4145,13 +4167,13 @@ class TestFernetTokenProvider(test_v3.RestfulTestCase):
trust_id=trust['id'])
return self._make_auth_request(auth_data)
- def _validate_token(self, token, expected_status=200):
+ def _validate_token(self, token, expected_status=http_client.OK):
return self.get(
'/auth/tokens',
headers={'X-Subject-Token': token},
expected_status=expected_status)
- def _revoke_token(self, token, expected_status=204):
+ def _revoke_token(self, token, expected_status=http_client.NO_CONTENT):
return self.delete(
'/auth/tokens',
headers={'X-Subject-Token': token},
@@ -4190,13 +4212,15 @@ class TestFernetTokenProvider(test_v3.RestfulTestCase):
unscoped_token = self._get_unscoped_token()
tampered_token = (unscoped_token[:50] + uuid.uuid4().hex +
unscoped_token[50 + 32:])
- self._validate_token(tampered_token, expected_status=404)
+ self._validate_token(tampered_token,
+ expected_status=http_client.NOT_FOUND)
def test_revoke_unscoped_token(self):
unscoped_token = self._get_unscoped_token()
self._validate_token(unscoped_token)
self._revoke_token(unscoped_token)
- self._validate_token(unscoped_token, expected_status=404)
+ self._validate_token(unscoped_token,
+ expected_status=http_client.NOT_FOUND)
def test_unscoped_token_is_invalid_after_disabling_user(self):
unscoped_token = self._get_unscoped_token()
@@ -4270,13 +4294,15 @@ class TestFernetTokenProvider(test_v3.RestfulTestCase):
project_scoped_token = self._get_project_scoped_token()
tampered_token = (project_scoped_token[:50] + uuid.uuid4().hex +
project_scoped_token[50 + 32:])
- self._validate_token(tampered_token, expected_status=404)
+ self._validate_token(tampered_token,
+ expected_status=http_client.NOT_FOUND)
def test_revoke_project_scoped_token(self):
project_scoped_token = self._get_project_scoped_token()
self._validate_token(project_scoped_token)
self._revoke_token(project_scoped_token)
- self._validate_token(project_scoped_token, expected_status=404)
+ self._validate_token(project_scoped_token,
+ expected_status=http_client.NOT_FOUND)
def test_project_scoped_token_is_invalid_after_disabling_user(self):
project_scoped_token = self._get_project_scoped_token()
@@ -4378,7 +4404,8 @@ class TestFernetTokenProvider(test_v3.RestfulTestCase):
# Get a trust scoped token
tampered_token = (trust_scoped_token[:50] + uuid.uuid4().hex +
trust_scoped_token[50 + 32:])
- self._validate_token(tampered_token, expected_status=404)
+ self._validate_token(tampered_token,
+ expected_status=http_client.NOT_FOUND)
def test_revoke_trust_scoped_token(self):
trustee_user, trust = self._create_trust()
@@ -4386,7 +4413,8 @@ class TestFernetTokenProvider(test_v3.RestfulTestCase):
# Validate a trust scoped token
self._validate_token(trust_scoped_token)
self._revoke_token(trust_scoped_token)
- self._validate_token(trust_scoped_token, expected_status=404)
+ self._validate_token(trust_scoped_token,
+ expected_status=http_client.NOT_FOUND)
def test_trust_scoped_token_is_invalid_after_disabling_trustee(self):
trustee_user, trust = self._create_trust()
@@ -4460,7 +4488,7 @@ class TestFernetTokenProvider(test_v3.RestfulTestCase):
self.token_provider_api.validate_token,
trust_scoped_token)
- def test_v2_validate_unscoped_token_returns_401(self):
+ def test_v2_validate_unscoped_token_returns_unauthorized(self):
"""Test raised exception when validating unscoped token.
Test that validating an unscoped token in v2.0 of a v3 user of a
@@ -4471,7 +4499,7 @@ class TestFernetTokenProvider(test_v3.RestfulTestCase):
self.token_provider_api.validate_v2_token,
unscoped_token)
- def test_v2_validate_domain_scoped_token_returns_401(self):
+ def test_v2_validate_domain_scoped_token_returns_unauthorized(self):
"""Test raised exception when validating a domain scoped token.
Test that validating an domain scoped token in v2.0
@@ -4519,7 +4547,8 @@ class TestAuthFernetTokenProvider(TestAuth):
self.admin_app.extra_environ.update({'REMOTE_USER': remote_user,
'AUTH_TYPE': 'Negotiate'})
# Bind not current supported by Fernet, see bug 1433311.
- self.v3_authenticate_token(auth_data, expected_status=501)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.NOT_IMPLEMENTED)
def test_v2_v3_bind_token_intermix(self):
self.config_fixture.config(group='token', bind='kerberos')
@@ -4534,7 +4563,7 @@ class TestAuthFernetTokenProvider(TestAuth):
self.admin_request(path='/v2.0/tokens',
method='POST',
body=body,
- expected_status=501)
+ expected_status=http_client.NOT_IMPLEMENTED)
def test_auth_with_bind_token(self):
self.config_fixture.config(group='token', bind=['kerberos'])
@@ -4544,4 +4573,5 @@ class TestAuthFernetTokenProvider(TestAuth):
self.admin_app.extra_environ.update({'REMOTE_USER': remote_user,
'AUTH_TYPE': 'Negotiate'})
# Bind not current supported by Fernet, see bug 1433311.
- self.v3_authenticate_token(auth_data, expected_status=501)
+ self.v3_authenticate_token(auth_data,
+ expected_status=http_client.NOT_IMPLEMENTED)
diff --git a/keystone-moon/keystone/tests/unit/test_v3_catalog.py b/keystone-moon/keystone/tests/unit/test_v3_catalog.py
index f96b2a12..0d82390d 100644
--- a/keystone-moon/keystone/tests/unit/test_v3_catalog.py
+++ b/keystone-moon/keystone/tests/unit/test_v3_catalog.py
@@ -15,10 +15,11 @@
import copy
import uuid
+from six.moves import http_client
from testtools import matchers
from keystone import catalog
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit.ksfixtures import database
from keystone.tests.unit import test_v3
@@ -35,7 +36,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
r = self.put(
'/regions/%s' % region_id,
body={'region': ref},
- expected_status=201)
+ expected_status=http_client.CREATED)
self.assertValidRegionResponse(r, ref)
# Double-check that the region ID was kept as-is and not
# populated with a UUID, as is the case with POST /v3/regions
@@ -48,7 +49,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
r = self.put(
'/regions/%s' % region_id,
body={'region': ref},
- expected_status=201)
+ expected_status=http_client.CREATED)
self.assertValidRegionResponse(r, ref)
# Double-check that the region ID was kept as-is and not
# populated with a UUID, as is the case with POST /v3/regions
@@ -59,7 +60,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
ref = dict(description="my region")
self.put(
'/regions/myregion',
- body={'region': ref}, expected_status=201)
+ body={'region': ref}, expected_status=http_client.CREATED)
# Create region again with duplicate id
self.put(
'/regions/myregion',
@@ -85,9 +86,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
ref = self.new_region_ref()
ref['id'] = ''
- r = self.post(
- '/regions',
- body={'region': ref}, expected_status=201)
+ r = self.post('/regions', body={'region': ref})
self.assertValidRegionResponse(r, ref)
self.assertNotEmpty(r.result['region'].get('id'))
@@ -99,10 +98,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
del ref['id']
# let the service define the ID
- r = self.post(
- '/regions',
- body={'region': ref},
- expected_status=201)
+ r = self.post('/regions', body={'region': ref})
self.assertValidRegionResponse(r, ref)
def test_create_region_without_description(self):
@@ -111,10 +107,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
del ref['description']
- r = self.post(
- '/regions',
- body={'region': ref},
- expected_status=201)
+ r = self.post('/regions', body={'region': ref})
# Create the description in the reference to compare to since the
# response should now have a description, even though we didn't send
# it with the original reference.
@@ -134,16 +127,10 @@ class CatalogTestCase(test_v3.RestfulTestCase):
ref1['description'] = region_desc
ref2['description'] = region_desc
- resp1 = self.post(
- '/regions',
- body={'region': ref1},
- expected_status=201)
+ resp1 = self.post('/regions', body={'region': ref1})
self.assertValidRegionResponse(resp1, ref1)
- resp2 = self.post(
- '/regions',
- body={'region': ref2},
- expected_status=201)
+ resp2 = self.post('/regions', body={'region': ref2})
self.assertValidRegionResponse(resp2, ref2)
def test_create_regions_without_descriptions(self):
@@ -158,15 +145,9 @@ class CatalogTestCase(test_v3.RestfulTestCase):
del ref1['description']
ref2['description'] = None
- resp1 = self.post(
- '/regions',
- body={'region': ref1},
- expected_status=201)
+ resp1 = self.post('/regions', body={'region': ref1})
- resp2 = self.post(
- '/regions',
- body={'region': ref2},
- expected_status=201)
+ resp2 = self.post('/regions', body={'region': ref2})
# Create the descriptions in the references to compare to since the
# responses should now have descriptions, even though we didn't send
# a description with the original references.
@@ -184,7 +165,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
self.put(
'/regions/%s' % uuid.uuid4().hex,
body={'region': ref},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_list_regions(self):
"""Call ``GET /regions``."""
@@ -230,16 +211,14 @@ class CatalogTestCase(test_v3.RestfulTestCase):
"""Call ``PATCH /regions/{region_id}``."""
region_ref = self.new_region_ref()
- resp = self.post('/regions', body={'region': region_ref},
- expected_status=201)
+ resp = self.post('/regions', body={'region': region_ref})
region_updates = {
# update with something that's not the description
'parent_region_id': self.region_id,
}
resp = self.patch('/regions/%s' % region_ref['id'],
- body={'region': region_updates},
- expected_status=200)
+ body={'region': region_updates})
# NOTE(dstanek): Keystone should keep the original description.
self.assertEqual(region_ref['description'],
@@ -326,19 +305,22 @@ class CatalogTestCase(test_v3.RestfulTestCase):
"""Call ``POST /services``."""
ref = self.new_service_ref()
ref['enabled'] = 'True'
- self.post('/services', body={'service': ref}, expected_status=400)
+ self.post('/services', body={'service': ref},
+ expected_status=http_client.BAD_REQUEST)
def test_create_service_enabled_str_false(self):
"""Call ``POST /services``."""
ref = self.new_service_ref()
ref['enabled'] = 'False'
- self.post('/services', body={'service': ref}, expected_status=400)
+ self.post('/services', body={'service': ref},
+ expected_status=http_client.BAD_REQUEST)
def test_create_service_enabled_str_random(self):
"""Call ``POST /services``."""
ref = self.new_service_ref()
ref['enabled'] = 'puppies'
- self.post('/services', body={'service': ref}, expected_status=400)
+ self.post('/services', body={'service': ref},
+ expected_status=http_client.BAD_REQUEST)
def test_list_services(self):
"""Call ``GET /services``."""
@@ -575,7 +557,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
self.post(
'/endpoints',
body={'endpoint': ref},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_create_endpoint_enabled_str_false(self):
"""Call ``POST /endpoints`` with enabled: 'False'."""
@@ -584,7 +566,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
self.post(
'/endpoints',
body={'endpoint': ref},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_create_endpoint_enabled_str_random(self):
"""Call ``POST /endpoints`` with enabled: 'puppies'."""
@@ -593,13 +575,14 @@ class CatalogTestCase(test_v3.RestfulTestCase):
self.post(
'/endpoints',
body={'endpoint': ref},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_create_endpoint_with_invalid_region_id(self):
"""Call ``POST /endpoints``."""
ref = self.new_endpoint_ref(service_id=self.service_id)
ref["region_id"] = uuid.uuid4().hex
- self.post('/endpoints', body={'endpoint': ref}, expected_status=400)
+ self.post('/endpoints', body={'endpoint': ref},
+ expected_status=http_client.BAD_REQUEST)
def test_create_endpoint_with_region(self):
"""EndpointV3 creates the region before creating the endpoint, if
@@ -608,7 +591,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
ref = self.new_endpoint_ref(service_id=self.service_id)
ref["region"] = uuid.uuid4().hex
ref.pop('region_id')
- self.post('/endpoints', body={'endpoint': ref}, expected_status=201)
+ self.post('/endpoints', body={'endpoint': ref})
# Make sure the region is created
self.get('/regions/%(region_id)s' % {
'region_id': ref["region"]})
@@ -617,13 +600,14 @@ class CatalogTestCase(test_v3.RestfulTestCase):
"""EndpointV3 allows to creates the endpoint without region."""
ref = self.new_endpoint_ref(service_id=self.service_id)
ref.pop('region_id')
- self.post('/endpoints', body={'endpoint': ref}, expected_status=201)
+ self.post('/endpoints', body={'endpoint': ref})
def test_create_endpoint_with_empty_url(self):
"""Call ``POST /endpoints``."""
ref = self.new_endpoint_ref(service_id=self.service_id)
ref["url"] = ''
- self.post('/endpoints', body={'endpoint': ref}, expected_status=400)
+ self.post('/endpoints', body={'endpoint': ref},
+ expected_status=http_client.BAD_REQUEST)
def test_get_endpoint(self):
"""Call ``GET /endpoints/{endpoint_id}``."""
@@ -667,7 +651,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
'/endpoints/%(endpoint_id)s' % {
'endpoint_id': self.endpoint_id},
body={'endpoint': {'enabled': 'True'}},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_update_endpoint_enabled_str_false(self):
"""Call ``PATCH /endpoints/{endpoint_id}`` with enabled: 'False'."""
@@ -675,7 +659,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
'/endpoints/%(endpoint_id)s' % {
'endpoint_id': self.endpoint_id},
body={'endpoint': {'enabled': 'False'}},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_update_endpoint_enabled_str_random(self):
"""Call ``PATCH /endpoints/{endpoint_id}`` with enabled: 'kitties'."""
@@ -683,7 +667,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
'/endpoints/%(endpoint_id)s' % {
'endpoint_id': self.endpoint_id},
body={'endpoint': {'enabled': 'kitties'}},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_delete_endpoint(self):
"""Call ``DELETE /endpoints/{endpoint_id}``."""
@@ -762,7 +746,8 @@ class CatalogTestCase(test_v3.RestfulTestCase):
self.delete('/endpoints/%s' % ref['id'])
# make sure it's deleted (GET should return 404)
- self.get('/endpoints/%s' % ref['id'], expected_status=404)
+ self.get('/endpoints/%s' % ref['id'],
+ expected_status=http_client.NOT_FOUND)
def test_endpoint_create_with_valid_url(self):
"""Create endpoint with valid url should be tested,too."""
@@ -771,9 +756,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
ref = self.new_endpoint_ref(self.service_id)
ref['url'] = valid_url
- self.post('/endpoints',
- body={'endpoint': ref},
- expected_status=201)
+ self.post('/endpoints', body={'endpoint': ref})
def test_endpoint_create_with_invalid_url(self):
"""Test the invalid cases: substitutions is not exactly right.
@@ -798,10 +781,10 @@ class CatalogTestCase(test_v3.RestfulTestCase):
ref['url'] = invalid_url
self.post('/endpoints',
body={'endpoint': ref},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
-class TestCatalogAPISQL(tests.TestCase):
+class TestCatalogAPISQL(unit.TestCase):
"""Tests for the catalog Manager against the SQL backend.
"""
@@ -909,7 +892,7 @@ class TestCatalogAPISQL(tests.TestCase):
# TODO(dstanek): this needs refactoring with the test above, but we are in a
# crunch so that will happen in a future patch.
-class TestCatalogAPISQLRegions(tests.TestCase):
+class TestCatalogAPISQLRegions(unit.TestCase):
"""Tests for the catalog Manager against the SQL backend.
"""
diff --git a/keystone-moon/keystone/tests/unit/test_v3_controller.py b/keystone-moon/keystone/tests/unit/test_v3_controller.py
index eef64a82..563e656e 100644
--- a/keystone-moon/keystone/tests/unit/test_v3_controller.py
+++ b/keystone-moon/keystone/tests/unit/test_v3_controller.py
@@ -20,10 +20,10 @@ from testtools import matchers
from keystone.common import controller
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
-class V3ControllerTestCase(tests.TestCase):
+class V3ControllerTestCase(unit.TestCase):
"""Tests for the V3Controller class."""
def setUp(self):
super(V3ControllerTestCase, self).setUp()
diff --git a/keystone-moon/keystone/tests/unit/test_v3_credential.py b/keystone-moon/keystone/tests/unit/test_v3_credential.py
index f8f6d35b..cf504b00 100644
--- a/keystone-moon/keystone/tests/unit/test_v3_credential.py
+++ b/keystone-moon/keystone/tests/unit/test_v3_credential.py
@@ -18,6 +18,7 @@ import uuid
from keystoneclient.contrib.ec2 import utils as ec2_utils
from oslo_config import cfg
+from six.moves import http_client
from testtools import matchers
from keystone import exception
@@ -98,6 +99,60 @@ class CredentialTestCase(CredentialBaseTestCase):
for cred in r.result['credentials']:
self.assertEqual(self.user['id'], cred['user_id'])
+ def test_list_credentials_filtered_by_type(self):
+ """Call ``GET /credentials?type={type}``."""
+ # The type ec2 was chosen, instead of a random string,
+ # because the type must be in the list of supported types
+ ec2_credential = self.new_credential_ref(user_id=uuid.uuid4().hex,
+ project_id=self.project_id,
+ cred_type='ec2')
+
+ ec2_resp = self.credential_api.create_credential(
+ ec2_credential['id'], ec2_credential)
+
+ # The type cert was chosen for the same reason as ec2
+ r = self.get('/credentials?type=cert')
+
+ # Testing the filter for two different types
+ self.assertValidCredentialListResponse(r, ref=self.credential)
+ for cred in r.result['credentials']:
+ self.assertEqual('cert', cred['type'])
+
+ r_ec2 = self.get('/credentials?type=ec2')
+ self.assertThat(r_ec2.result['credentials'], matchers.HasLength(1))
+ cred_ec2 = r_ec2.result['credentials'][0]
+
+ self.assertValidCredentialListResponse(r_ec2, ref=ec2_resp)
+ self.assertEqual('ec2', cred_ec2['type'])
+ self.assertEqual(cred_ec2['id'], ec2_credential['id'])
+
+ def test_list_credentials_filtered_by_type_and_user_id(self):
+ """Call ``GET /credentials?user_id={user_id}&type={type}``."""
+ user1_id = uuid.uuid4().hex
+ user2_id = uuid.uuid4().hex
+
+ # Creating credentials for two different users
+ credential_user1_ec2 = self.new_credential_ref(
+ user_id=user1_id, cred_type='ec2')
+ credential_user1_cert = self.new_credential_ref(
+ user_id=user1_id)
+ credential_user2_cert = self.new_credential_ref(
+ user_id=user2_id)
+
+ self.credential_api.create_credential(
+ credential_user1_ec2['id'], credential_user1_ec2)
+ self.credential_api.create_credential(
+ credential_user1_cert['id'], credential_user1_cert)
+ self.credential_api.create_credential(
+ credential_user2_cert['id'], credential_user2_cert)
+
+ r = self.get('/credentials?user_id=%s&type=ec2' % user1_id)
+ self.assertValidCredentialListResponse(r, ref=credential_user1_ec2)
+ self.assertThat(r.result['credentials'], matchers.HasLength(1))
+ cred = r.result['credentials'][0]
+ self.assertEqual('ec2', cred['type'])
+ self.assertEqual(user1_id, cred['user_id'])
+
def test_create_credential(self):
"""Call ``POST /credentials``."""
ref = self.new_credential_ref(user_id=self.user['id'])
@@ -198,10 +253,10 @@ class CredentialTestCase(CredentialBaseTestCase):
"secret": uuid.uuid4().hex}
ref['blob'] = json.dumps(blob)
ref['type'] = 'ec2'
- # Assert 400 status for bad request with missing project_id
+ # Assert bad request status when missing project_id
self.post(
'/credentials',
- body={'credential': ref}, expected_status=400)
+ body={'credential': ref}, expected_status=http_client.BAD_REQUEST)
def test_create_ec2_credential_with_invalid_blob(self):
"""Call ``POST /credentials`` for creating ec2
@@ -211,11 +266,10 @@ class CredentialTestCase(CredentialBaseTestCase):
project_id=self.project_id)
ref['blob'] = '{"abc":"def"d}'
ref['type'] = 'ec2'
- # Assert 400 status for bad request containing invalid
- # blob
+ # Assert bad request status when request contains invalid blob
response = self.post(
'/credentials',
- body={'credential': ref}, expected_status=400)
+ body={'credential': ref}, expected_status=http_client.BAD_REQUEST)
self.assertValidErrorResponse(response)
def test_create_credential_with_admin_token(self):
@@ -328,7 +382,7 @@ class TestCredentialEc2(CredentialBaseTestCase):
r = self.post(
'/ec2tokens',
body={'ec2Credentials': sig_ref},
- expected_status=200)
+ expected_status=http_client.OK)
self.assertValidTokenResponse(r)
def test_ec2_credential_signature_validate(self):
diff --git a/keystone-moon/keystone/tests/unit/test_v3_domain_config.py b/keystone-moon/keystone/tests/unit/test_v3_domain_config.py
index 6f96f0e7..3f7af87d 100644
--- a/keystone-moon/keystone/tests/unit/test_v3_domain_config.py
+++ b/keystone-moon/keystone/tests/unit/test_v3_domain_config.py
@@ -14,6 +14,7 @@ import copy
import uuid
from oslo_config import cfg
+from six.moves import http_client
from keystone import exception
from keystone.tests.unit import test_v3
@@ -39,7 +40,7 @@ class DomainConfigTestCase(test_v3.RestfulTestCase):
url = '/domains/%(domain_id)s/config' % {
'domain_id': self.domain['id']}
r = self.put(url, body={'config': self.config},
- expected_status=201)
+ expected_status=http_client.CREATED)
res = self.domain_config_api.get_config(self.domain['id'])
self.assertEqual(self.config, r.result['config'])
self.assertEqual(self.config, res)
@@ -49,11 +50,11 @@ class DomainConfigTestCase(test_v3.RestfulTestCase):
self.put('/domains/%(domain_id)s/config' % {
'domain_id': self.domain['id']},
body={'config': self.config},
- expected_status=201)
+ expected_status=http_client.CREATED)
self.put('/domains/%(domain_id)s/config' % {
'domain_id': self.domain['id']},
body={'config': self.config},
- expected_status=200)
+ expected_status=http_client.OK)
def test_delete_config(self):
"""Call ``DELETE /domains{domain_id}/config``."""
@@ -79,7 +80,7 @@ class DomainConfigTestCase(test_v3.RestfulTestCase):
'domain_id': self.domain['id']}
r = self.get(url)
self.assertEqual(self.config, r.result['config'])
- self.head(url, expected_status=200)
+ self.head(url, expected_status=http_client.OK)
def test_get_config_by_group(self):
"""Call ``GET & HEAD /domains{domain_id}/config/{group}``."""
@@ -88,7 +89,7 @@ class DomainConfigTestCase(test_v3.RestfulTestCase):
'domain_id': self.domain['id']}
r = self.get(url)
self.assertEqual({'ldap': self.config['ldap']}, r.result['config'])
- self.head(url, expected_status=200)
+ self.head(url, expected_status=http_client.OK)
def test_get_config_by_option(self):
"""Call ``GET & HEAD /domains{domain_id}/config/{group}/{option}``."""
@@ -98,26 +99,29 @@ class DomainConfigTestCase(test_v3.RestfulTestCase):
r = self.get(url)
self.assertEqual({'url': self.config['ldap']['url']},
r.result['config'])
- self.head(url, expected_status=200)
+ self.head(url, expected_status=http_client.OK)
def test_get_non_existant_config(self):
"""Call ``GET /domains{domain_id}/config when no config defined``."""
self.get('/domains/%(domain_id)s/config' % {
- 'domain_id': self.domain['id']}, expected_status=404)
+ 'domain_id': self.domain['id']},
+ expected_status=http_client.NOT_FOUND)
def test_get_non_existant_config_group(self):
"""Call ``GET /domains{domain_id}/config/{group_not_exist}``."""
config = {'ldap': {'url': uuid.uuid4().hex}}
self.domain_config_api.create_config(self.domain['id'], config)
self.get('/domains/%(domain_id)s/config/identity' % {
- 'domain_id': self.domain['id']}, expected_status=404)
+ 'domain_id': self.domain['id']},
+ expected_status=http_client.NOT_FOUND)
def test_get_non_existant_config_option(self):
"""Call ``GET /domains{domain_id}/config/group/{option_not_exist}``."""
config = {'ldap': {'url': uuid.uuid4().hex}}
self.domain_config_api.create_config(self.domain['id'], config)
self.get('/domains/%(domain_id)s/config/ldap/user_tree_dn' % {
- 'domain_id': self.domain['id']}, expected_status=404)
+ 'domain_id': self.domain['id']},
+ expected_status=http_client.NOT_FOUND)
def test_update_config(self):
"""Call ``PATCH /domains/{domain_id}/config``."""
@@ -163,7 +167,7 @@ class DomainConfigTestCase(test_v3.RestfulTestCase):
self.patch('/domains/%(domain_id)s/config/%(invalid_group)s' % {
'domain_id': self.domain['id'], 'invalid_group': invalid_group},
body={'config': new_config},
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
# Trying to update a valid group, but one that is not in the current
# config should result in NotFound
config = {'ldap': {'suffix': uuid.uuid4().hex}}
@@ -172,7 +176,7 @@ class DomainConfigTestCase(test_v3.RestfulTestCase):
self.patch('/domains/%(domain_id)s/config/identity' % {
'domain_id': self.domain['id']},
body={'config': new_config},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_update_config_option(self):
"""Call ``PATCH /domains/{domain_id}/config/{group}/{option}``."""
@@ -199,7 +203,7 @@ class DomainConfigTestCase(test_v3.RestfulTestCase):
'domain_id': self.domain['id'],
'invalid_option': invalid_option},
body={'config': new_config},
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
# Trying to update a valid option, but one that is not in the current
# config should result in NotFound
new_config = {'suffix': uuid.uuid4().hex}
@@ -207,4 +211,4 @@ class DomainConfigTestCase(test_v3.RestfulTestCase):
'/domains/%(domain_id)s/config/ldap/suffix' % {
'domain_id': self.domain['id']},
body={'config': new_config},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
diff --git a/keystone-moon/keystone/tests/unit/test_v3_endpoint_policy.py b/keystone-moon/keystone/tests/unit/test_v3_endpoint_policy.py
index 4daeff4d..b0c8256e 100644
--- a/keystone-moon/keystone/tests/unit/test_v3_endpoint_policy.py
+++ b/keystone-moon/keystone/tests/unit/test_v3_endpoint_policy.py
@@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+from six.moves import http_client
from testtools import matchers
from keystone.tests.unit import test_v3
@@ -48,17 +49,23 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
# Test when the resource does not exist also ensures
# that there is not a false negative after creation.
- self.assert_head_and_get_return_same_response(url, expected_status=404)
+ self.assert_head_and_get_return_same_response(
+ url,
+ expected_status=http_client.NOT_FOUND)
- self.put(url, expected_status=204)
+ self.put(url)
# test that the new resource is accessible.
- self.assert_head_and_get_return_same_response(url, expected_status=204)
+ self.assert_head_and_get_return_same_response(
+ url,
+ expected_status=http_client.NO_CONTENT)
- self.delete(url, expected_status=204)
+ self.delete(url)
# test that the deleted resource is no longer accessible
- self.assert_head_and_get_return_same_response(url, expected_status=404)
+ self.assert_head_and_get_return_same_response(
+ url,
+ expected_status=http_client.NOT_FOUND)
def test_crud_for_policy_for_explicit_endpoint(self):
"""PUT, HEAD and DELETE for explicit endpoint policy."""
@@ -94,18 +101,16 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
self.put('/policies/%(policy_id)s/OS-ENDPOINT-POLICY'
'/endpoints/%(endpoint_id)s' % {
'policy_id': self.policy['id'],
- 'endpoint_id': self.endpoint['id']},
- expected_status=204)
+ 'endpoint_id': self.endpoint['id']})
self.head('/endpoints/%(endpoint_id)s/OS-ENDPOINT-POLICY'
'/policy' % {
'endpoint_id': self.endpoint['id']},
- expected_status=200)
+ expected_status=http_client.OK)
r = self.get('/endpoints/%(endpoint_id)s/OS-ENDPOINT-POLICY'
'/policy' % {
- 'endpoint_id': self.endpoint['id']},
- expected_status=200)
+ 'endpoint_id': self.endpoint['id']})
self.assertValidPolicyResponse(r, ref=self.policy)
def test_list_endpoints_for_policy(self):
@@ -114,13 +119,11 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
self.put('/policies/%(policy_id)s/OS-ENDPOINT-POLICY'
'/endpoints/%(endpoint_id)s' % {
'policy_id': self.policy['id'],
- 'endpoint_id': self.endpoint['id']},
- expected_status=204)
+ 'endpoint_id': self.endpoint['id']})
r = self.get('/policies/%(policy_id)s/OS-ENDPOINT-POLICY'
'/endpoints' % {
- 'policy_id': self.policy['id']},
- expected_status=200)
+ 'policy_id': self.policy['id']})
self.assertValidEndpointListResponse(r, ref=self.endpoint)
self.assertThat(r.result.get('endpoints'), matchers.HasLength(1))
@@ -130,13 +133,13 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
'policy_id': self.policy['id'],
'endpoint_id': self.endpoint['id']}
- self.put(url, expected_status=204)
- self.head(url, expected_status=204)
+ self.put(url)
+ self.head(url)
self.delete('/endpoints/%(endpoint_id)s' % {
'endpoint_id': self.endpoint['id']})
- self.head(url, expected_status=404)
+ self.head(url, expected_status=http_client.NOT_FOUND)
def test_region_service_association_cleanup_when_region_deleted(self):
url = ('/policies/%(policy_id)s/OS-ENDPOINT-POLICY'
@@ -145,13 +148,13 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
'service_id': self.service['id'],
'region_id': self.region['id']}
- self.put(url, expected_status=204)
- self.head(url, expected_status=204)
+ self.put(url)
+ self.head(url)
self.delete('/regions/%(region_id)s' % {
'region_id': self.region['id']})
- self.head(url, expected_status=404)
+ self.head(url, expected_status=http_client.NOT_FOUND)
def test_region_service_association_cleanup_when_service_deleted(self):
url = ('/policies/%(policy_id)s/OS-ENDPOINT-POLICY'
@@ -160,13 +163,13 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
'service_id': self.service['id'],
'region_id': self.region['id']}
- self.put(url, expected_status=204)
- self.head(url, expected_status=204)
+ self.put(url)
+ self.head(url)
self.delete('/services/%(service_id)s' % {
'service_id': self.service['id']})
- self.head(url, expected_status=404)
+ self.head(url, expected_status=http_client.NOT_FOUND)
def test_service_association_cleanup_when_service_deleted(self):
url = ('/policies/%(policy_id)s/OS-ENDPOINT-POLICY'
@@ -174,13 +177,13 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
'policy_id': self.policy['id'],
'service_id': self.service['id']}
- self.put(url, expected_status=204)
- self.get(url, expected_status=204)
+ self.put(url)
+ self.get(url, expected_status=http_client.NO_CONTENT)
self.delete('/policies/%(policy_id)s' % {
'policy_id': self.policy['id']})
- self.head(url, expected_status=404)
+ self.head(url, expected_status=http_client.NOT_FOUND)
def test_service_association_cleanup_when_policy_deleted(self):
url = ('/policies/%(policy_id)s/OS-ENDPOINT-POLICY'
@@ -188,13 +191,13 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
'policy_id': self.policy['id'],
'service_id': self.service['id']}
- self.put(url, expected_status=204)
- self.get(url, expected_status=204)
+ self.put(url)
+ self.get(url, expected_status=http_client.NO_CONTENT)
self.delete('/services/%(service_id)s' % {
'service_id': self.service['id']})
- self.head(url, expected_status=404)
+ self.head(url, expected_status=http_client.NOT_FOUND)
class JsonHomeTests(test_v3.JsonHomeTestMixin):
diff --git a/keystone-moon/keystone/tests/unit/test_v3_federation.py b/keystone-moon/keystone/tests/unit/test_v3_federation.py
index e646bc0a..5717e67b 100644
--- a/keystone-moon/keystone/tests/unit/test_v3_federation.py
+++ b/keystone-moon/keystone/tests/unit/test_v3_federation.py
@@ -12,7 +12,6 @@
import os
import random
-import subprocess
from testtools import matchers
import uuid
@@ -26,12 +25,14 @@ from oslotest import mockpatch
import saml2
from saml2 import saml
from saml2 import sigver
+from six.moves import http_client
from six.moves import range, urllib, zip
xmldsig = importutils.try_import("saml2.xmldsig")
if not xmldsig:
xmldsig = importutils.try_import("xmldsig")
from keystone.auth import controllers as auth_controllers
+from keystone.common import environment
from keystone.contrib.federation import controllers as federation_controllers
from keystone.contrib.federation import idp as keystone_idp
from keystone import exception
@@ -44,6 +45,8 @@ from keystone.tests.unit import test_v3
from keystone.token.providers import common as token_common
+subprocess = environment.subprocess
+
CONF = cfg.CONF
LOG = log.getLogger(__name__)
ROOTDIR = os.path.dirname(os.path.abspath(__file__))
@@ -109,25 +112,43 @@ class FederatedSetupMixin(object):
self.assertEqual(token_projects, projects_ref)
def _check_scoped_token_attributes(self, token):
- def xor_project_domain(token_keys):
- return sum(('project' in token_keys, 'domain' in token_keys)) % 2
for obj in ('user', 'catalog', 'expires_at', 'issued_at',
'methods', 'roles'):
self.assertIn(obj, token)
- # Check for either project or domain
- if not xor_project_domain(list(token.keys())):
- raise AssertionError("You must specify either"
- "project or domain.")
- self.assertIn('OS-FEDERATION', token['user'])
os_federation = token['user']['OS-FEDERATION']
+
+ self.assertIn('groups', os_federation)
+ self.assertIn('identity_provider', os_federation)
+ self.assertIn('protocol', os_federation)
+ self.assertThat(os_federation, matchers.HasLength(3))
+
self.assertEqual(self.IDP, os_federation['identity_provider']['id'])
self.assertEqual(self.PROTOCOL, os_federation['protocol']['id'])
- self.assertListEqual(sorted(['groups',
- 'identity_provider',
- 'protocol']),
- sorted(os_federation.keys()))
+
+ def _check_project_scoped_token_attributes(self, token, project_id):
+ self.assertEqual(project_id, token['project']['id'])
+ self._check_scoped_token_attributes(token)
+
+ def _check_domain_scoped_token_attributes(self, token, domain_id):
+ self.assertEqual(domain_id, token['domain']['id'])
+ self._check_scoped_token_attributes(token)
+
+ def assertValidMappedUser(self, token):
+ """Check if user object meets all the criteria."""
+
+ user = token['user']
+ self.assertIn('id', user)
+ self.assertIn('name', user)
+ self.assertIn('domain', user)
+
+ self.assertIn('groups', user['OS-FEDERATION'])
+ self.assertIn('identity_provider', user['OS-FEDERATION'])
+ self.assertIn('protocol', user['OS-FEDERATION'])
+
+ # Make sure user_id is url safe
+ self.assertEqual(urllib.parse.quote(user['name']), user['id'])
def _issue_unscoped_token(self,
idp=None,
@@ -794,7 +815,7 @@ class FederatedIdentityProviderTests(FederationTests):
if body is None:
body = self._http_idp_input()
resp = self.put(url, body={'identity_provider': body},
- expected_status=201)
+ expected_status=http_client.CREATED)
return resp
def _http_idp_input(self, **kwargs):
@@ -881,7 +902,7 @@ class FederatedIdentityProviderTests(FederationTests):
body['remote_ids'] = [uuid.uuid4().hex,
repeated_remote_id]
self.put(url, body={'identity_provider': body},
- expected_status=409)
+ expected_status=http_client.CONFLICT)
def test_create_idp_remote_empty(self):
"""Creates an IdP with empty remote_ids."""
@@ -1006,9 +1027,9 @@ class FederatedIdentityProviderTests(FederationTests):
url = self.base_url(suffix=uuid.uuid4().hex)
body = self._http_idp_input()
self.put(url, body={'identity_provider': body},
- expected_status=201)
+ expected_status=http_client.CREATED)
self.put(url, body={'identity_provider': body},
- expected_status=409)
+ expected_status=http_client.CONFLICT)
def test_get_idp(self):
"""Create and later fetch IdP."""
@@ -1033,7 +1054,7 @@ class FederatedIdentityProviderTests(FederationTests):
self.assertIsNotNone(idp_id)
url = self.base_url(suffix=idp_id)
- self.get(url, expected_status=404)
+ self.get(url, expected_status=http_client.NOT_FOUND)
def test_delete_existing_idp(self):
"""Create and later delete IdP.
@@ -1047,7 +1068,7 @@ class FederatedIdentityProviderTests(FederationTests):
self.assertIsNotNone(idp_id)
url = self.base_url(suffix=idp_id)
self.delete(url)
- self.get(url, expected_status=404)
+ self.get(url, expected_status=http_client.NOT_FOUND)
def test_delete_idp_also_deletes_assigned_protocols(self):
"""Deleting an IdP will delete its assigned protocol."""
@@ -1063,7 +1084,7 @@ class FederatedIdentityProviderTests(FederationTests):
idp_url = self.base_url(suffix=idp_id)
# assign protocol to IdP
- kwargs = {'expected_status': 201}
+ kwargs = {'expected_status': http_client.CREATED}
resp, idp_id, proto = self._assign_protocol_to_idp(
url=url,
idp_id=idp_id,
@@ -1073,7 +1094,7 @@ class FederatedIdentityProviderTests(FederationTests):
# removing IdP will remove the assigned protocol as well
self.assertEqual(1, len(self.federation_api.list_protocols(idp_id)))
self.delete(idp_url)
- self.get(idp_url, expected_status=404)
+ self.get(idp_url, expected_status=http_client.NOT_FOUND)
self.assertEqual(0, len(self.federation_api.list_protocols(idp_id)))
def test_delete_nonexisting_idp(self):
@@ -1083,7 +1104,7 @@ class FederatedIdentityProviderTests(FederationTests):
"""
idp_id = uuid.uuid4().hex
url = self.base_url(suffix=idp_id)
- self.delete(url, expected_status=404)
+ self.delete(url, expected_status=http_client.NOT_FOUND)
def test_update_idp_mutable_attributes(self):
"""Update IdP's mutable parameters."""
@@ -1124,7 +1145,7 @@ class FederatedIdentityProviderTests(FederationTests):
def test_update_idp_immutable_attributes(self):
"""Update IdP's immutable parameters.
- Expect HTTP 403 code.
+ Expect HTTP FORBIDDEN.
"""
default_resp = self._create_default_idp()
@@ -1138,7 +1159,8 @@ class FederatedIdentityProviderTests(FederationTests):
body['protocols'] = [uuid.uuid4().hex, uuid.uuid4().hex]
url = self.base_url(suffix=idp_id)
- self.patch(url, body={'identity_provider': body}, expected_status=403)
+ self.patch(url, body={'identity_provider': body},
+ expected_status=http_client.FORBIDDEN)
def test_update_nonexistent_idp(self):
"""Update nonexistent IdP
@@ -1152,12 +1174,12 @@ class FederatedIdentityProviderTests(FederationTests):
body['enabled'] = False
body = {'identity_provider': body}
- self.patch(url, body=body, expected_status=404)
+ self.patch(url, body=body, expected_status=http_client.NOT_FOUND)
def test_assign_protocol_to_idp(self):
"""Assign a protocol to existing IdP."""
- self._assign_protocol_to_idp(expected_status=201)
+ self._assign_protocol_to_idp(expected_status=http_client.CREATED)
def test_protocol_composite_pk(self):
"""Test whether Keystone let's add two entities with identical
@@ -1171,7 +1193,7 @@ class FederatedIdentityProviderTests(FederationTests):
"""
url = self.base_url(suffix='%(idp_id)s/protocols/%(protocol_id)s')
- kwargs = {'expected_status': 201}
+ kwargs = {'expected_status': http_client.CREATED}
self._assign_protocol_to_idp(proto='saml2',
url=url, **kwargs)
@@ -1187,10 +1209,10 @@ class FederatedIdentityProviderTests(FederationTests):
"""
url = self.base_url(suffix='%(idp_id)s/protocols/%(protocol_id)s')
- kwargs = {'expected_status': 201}
+ kwargs = {'expected_status': http_client.CREATED}
resp, idp_id, proto = self._assign_protocol_to_idp(proto='saml2',
url=url, **kwargs)
- kwargs = {'expected_status': 409}
+ kwargs = {'expected_status': http_client.CONFLICT}
resp, idp_id, proto = self._assign_protocol_to_idp(idp_id=idp_id,
proto='saml2',
validate=False,
@@ -1204,7 +1226,7 @@ class FederatedIdentityProviderTests(FederationTests):
"""
idp_id = uuid.uuid4().hex
- kwargs = {'expected_status': 404}
+ kwargs = {'expected_status': http_client.NOT_FOUND}
self._assign_protocol_to_idp(proto='saml2',
idp_id=idp_id,
validate=False,
@@ -1213,7 +1235,8 @@ class FederatedIdentityProviderTests(FederationTests):
def test_get_protocol(self):
"""Create and later fetch protocol tied to IdP."""
- resp, idp_id, proto = self._assign_protocol_to_idp(expected_status=201)
+ resp, idp_id, proto = self._assign_protocol_to_idp(
+ expected_status=http_client.CREATED)
proto_id = self._fetch_attribute_from_response(resp, 'protocol')['id']
url = "%s/protocols/%s" % (idp_id, proto_id)
url = self.base_url(suffix=url)
@@ -1232,12 +1255,14 @@ class FederatedIdentityProviderTests(FederationTests):
Compare input and output id sets.
"""
- resp, idp_id, proto = self._assign_protocol_to_idp(expected_status=201)
+ resp, idp_id, proto = self._assign_protocol_to_idp(
+ expected_status=http_client.CREATED)
iterations = random.randint(0, 16)
protocol_ids = []
for _ in range(iterations):
- resp, _, proto = self._assign_protocol_to_idp(idp_id=idp_id,
- expected_status=201)
+ resp, _, proto = self._assign_protocol_to_idp(
+ idp_id=idp_id,
+ expected_status=http_client.CREATED)
proto_id = self._fetch_attribute_from_response(resp, 'protocol')
proto_id = proto_id['id']
protocol_ids.append(proto_id)
@@ -1256,7 +1281,8 @@ class FederatedIdentityProviderTests(FederationTests):
def test_update_protocols_attribute(self):
"""Update protocol's attribute."""
- resp, idp_id, proto = self._assign_protocol_to_idp(expected_status=201)
+ resp, idp_id, proto = self._assign_protocol_to_idp(
+ expected_status=http_client.CREATED)
new_mapping_id = uuid.uuid4().hex
url = "%s/protocols/%s" % (idp_id, proto)
@@ -1277,11 +1303,12 @@ class FederatedIdentityProviderTests(FederationTests):
"""
url = self.base_url(suffix='/%(idp_id)s/'
'protocols/%(protocol_id)s')
- resp, idp_id, proto = self._assign_protocol_to_idp(expected_status=201)
+ resp, idp_id, proto = self._assign_protocol_to_idp(
+ expected_status=http_client.CREATED)
url = url % {'idp_id': idp_id,
'protocol_id': proto}
self.delete(url)
- self.get(url, expected_status=404)
+ self.get(url, expected_status=http_client.NOT_FOUND)
class MappingCRUDTests(FederationTests):
@@ -1318,7 +1345,7 @@ class MappingCRUDTests(FederationTests):
url = self.MAPPING_URL + uuid.uuid4().hex
resp = self.put(url,
body={'mapping': mapping_fixtures.MAPPING_LARGE},
- expected_status=201)
+ expected_status=http_client.CREATED)
return resp
def _get_id_from_response(self, resp):
@@ -1335,7 +1362,7 @@ class MappingCRUDTests(FederationTests):
resp = self.get(url)
entities = resp.result.get('mappings')
self.assertIsNotNone(entities)
- self.assertResponseStatus(resp, 200)
+ self.assertResponseStatus(resp, http_client.OK)
self.assertValidListLinks(resp.result.get('links'))
self.assertEqual(1, len(entities))
@@ -1345,8 +1372,8 @@ class MappingCRUDTests(FederationTests):
mapping_id = self._get_id_from_response(resp)
url = url % {'mapping_id': str(mapping_id)}
resp = self.delete(url)
- self.assertResponseStatus(resp, 204)
- self.get(url, expected_status=404)
+ self.assertResponseStatus(resp, http_client.NO_CONTENT)
+ self.get(url, expected_status=http_client.NOT_FOUND)
def test_mapping_get(self):
url = self.MAPPING_URL + '%(mapping_id)s'
@@ -1369,70 +1396,73 @@ class MappingCRUDTests(FederationTests):
def test_delete_mapping_dne(self):
url = self.MAPPING_URL + uuid.uuid4().hex
- self.delete(url, expected_status=404)
+ self.delete(url, expected_status=http_client.NOT_FOUND)
def test_get_mapping_dne(self):
url = self.MAPPING_URL + uuid.uuid4().hex
- self.get(url, expected_status=404)
+ self.get(url, expected_status=http_client.NOT_FOUND)
def test_create_mapping_bad_requirements(self):
url = self.MAPPING_URL + uuid.uuid4().hex
- self.put(url, expected_status=400,
+ self.put(url, expected_status=http_client.BAD_REQUEST,
body={'mapping': mapping_fixtures.MAPPING_BAD_REQ})
def test_create_mapping_no_rules(self):
url = self.MAPPING_URL + uuid.uuid4().hex
- self.put(url, expected_status=400,
+ self.put(url, expected_status=http_client.BAD_REQUEST,
body={'mapping': mapping_fixtures.MAPPING_NO_RULES})
def test_create_mapping_no_remote_objects(self):
url = self.MAPPING_URL + uuid.uuid4().hex
- self.put(url, expected_status=400,
+ self.put(url, expected_status=http_client.BAD_REQUEST,
body={'mapping': mapping_fixtures.MAPPING_NO_REMOTE})
def test_create_mapping_bad_value(self):
url = self.MAPPING_URL + uuid.uuid4().hex
- self.put(url, expected_status=400,
+ self.put(url, expected_status=http_client.BAD_REQUEST,
body={'mapping': mapping_fixtures.MAPPING_BAD_VALUE})
def test_create_mapping_missing_local(self):
url = self.MAPPING_URL + uuid.uuid4().hex
- self.put(url, expected_status=400,
+ self.put(url, expected_status=http_client.BAD_REQUEST,
body={'mapping': mapping_fixtures.MAPPING_MISSING_LOCAL})
def test_create_mapping_missing_type(self):
url = self.MAPPING_URL + uuid.uuid4().hex
- self.put(url, expected_status=400,
+ self.put(url, expected_status=http_client.BAD_REQUEST,
body={'mapping': mapping_fixtures.MAPPING_MISSING_TYPE})
def test_create_mapping_wrong_type(self):
url = self.MAPPING_URL + uuid.uuid4().hex
- self.put(url, expected_status=400,
+ self.put(url, expected_status=http_client.BAD_REQUEST,
body={'mapping': mapping_fixtures.MAPPING_WRONG_TYPE})
def test_create_mapping_extra_remote_properties_not_any_of(self):
url = self.MAPPING_URL + uuid.uuid4().hex
mapping = mapping_fixtures.MAPPING_EXTRA_REMOTE_PROPS_NOT_ANY_OF
- self.put(url, expected_status=400, body={'mapping': mapping})
+ self.put(url, expected_status=http_client.BAD_REQUEST,
+ body={'mapping': mapping})
def test_create_mapping_extra_remote_properties_any_one_of(self):
url = self.MAPPING_URL + uuid.uuid4().hex
mapping = mapping_fixtures.MAPPING_EXTRA_REMOTE_PROPS_ANY_ONE_OF
- self.put(url, expected_status=400, body={'mapping': mapping})
+ self.put(url, expected_status=http_client.BAD_REQUEST,
+ body={'mapping': mapping})
def test_create_mapping_extra_remote_properties_just_type(self):
url = self.MAPPING_URL + uuid.uuid4().hex
mapping = mapping_fixtures.MAPPING_EXTRA_REMOTE_PROPS_JUST_TYPE
- self.put(url, expected_status=400, body={'mapping': mapping})
+ self.put(url, expected_status=http_client.BAD_REQUEST,
+ body={'mapping': mapping})
def test_create_mapping_empty_map(self):
url = self.MAPPING_URL + uuid.uuid4().hex
- self.put(url, expected_status=400,
+ self.put(url, expected_status=http_client.BAD_REQUEST,
body={'mapping': {}})
def test_create_mapping_extra_rules_properties(self):
url = self.MAPPING_URL + uuid.uuid4().hex
- self.put(url, expected_status=400,
+ self.put(url, expected_status=http_client.BAD_REQUEST,
body={'mapping': mapping_fixtures.MAPPING_EXTRA_RULES_PROPS})
def test_create_mapping_with_blacklist_and_whitelist(self):
@@ -1444,7 +1474,8 @@ class MappingCRUDTests(FederationTests):
"""
url = self.MAPPING_URL + uuid.uuid4().hex
mapping = mapping_fixtures.MAPPING_GROUPS_WHITELIST_AND_BLACKLIST
- self.put(url, expected_status=400, body={'mapping': mapping})
+ self.put(url, expected_status=http_client.BAD_REQUEST,
+ body={'mapping': mapping})
class FederatedTokenTests(FederationTests, FederatedSetupMixin):
@@ -1494,6 +1525,7 @@ class FederatedTokenTests(FederationTests, FederatedSetupMixin):
def test_issue_unscoped_token(self):
r = self._issue_unscoped_token()
self.assertIsNotNone(r.headers.get('X-Subject-Token'))
+ self.assertValidMappedUser(r.json['token'])
def test_issue_unscoped_token_disabled_idp(self):
"""Checks if authentication works with disabled identity providers.
@@ -1632,11 +1664,12 @@ class FederatedTokenTests(FederationTests, FederatedSetupMixin):
self.TOKEN_SCOPE_PROJECT_EMPLOYEE_FROM_EMPLOYEE)
token_resp = r.result['token']
project_id = token_resp['project']['id']
- self.assertEqual(project_id, self.proj_employees['id'])
- self._check_scoped_token_attributes(token_resp)
+ self._check_project_scoped_token_attributes(token_resp, project_id)
roles_ref = [self.role_employee]
+
projects_ref = self.proj_employees
self._check_projects_and_roles(token_resp, roles_ref, projects_ref)
+ self.assertValidMappedUser(token_resp)
def test_scope_token_with_idp_disabled(self):
"""Scope token issued by disabled IdP.
@@ -1659,14 +1692,14 @@ class FederatedTokenTests(FederationTests, FederatedSetupMixin):
self.federation_api.update_idp(self.IDP, enabled_false)
self.v3_authenticate_token(
self.TOKEN_SCOPE_PROJECT_EMPLOYEE_FROM_CUSTOMER,
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_scope_to_bad_project(self):
"""Scope unscoped token with a project we don't have access to."""
self.v3_authenticate_token(
self.TOKEN_SCOPE_PROJECT_EMPLOYEE_FROM_CUSTOMER,
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_scope_to_project_multiple_times(self):
"""Try to scope the unscoped token multiple times.
@@ -1685,9 +1718,8 @@ class FederatedTokenTests(FederationTests, FederatedSetupMixin):
for body, project_id_ref in zip(bodies, project_ids):
r = self.v3_authenticate_token(body)
token_resp = r.result['token']
- project_id = token_resp['project']['id']
- self.assertEqual(project_id, project_id_ref)
- self._check_scoped_token_attributes(token_resp)
+ self._check_project_scoped_token_attributes(token_resp,
+ project_id_ref)
def test_scope_to_project_with_only_inherited_roles(self):
"""Try to scope token whose only roles are inherited."""
@@ -1695,18 +1727,18 @@ class FederatedTokenTests(FederationTests, FederatedSetupMixin):
r = self.v3_authenticate_token(
self.TOKEN_SCOPE_PROJECT_INHERITED_FROM_CUSTOMER)
token_resp = r.result['token']
- project_id = token_resp['project']['id']
- self.assertEqual(project_id, self.project_inherited['id'])
- self._check_scoped_token_attributes(token_resp)
+ self._check_project_scoped_token_attributes(
+ token_resp, self.project_inherited['id'])
roles_ref = [self.role_customer]
projects_ref = self.project_inherited
self._check_projects_and_roles(token_resp, roles_ref, projects_ref)
+ self.assertValidMappedUser(token_resp)
def test_scope_token_from_nonexistent_unscoped_token(self):
"""Try to scope token from non-existent unscoped token."""
self.v3_authenticate_token(
self.TOKEN_SCOPE_PROJECT_FROM_NONEXISTENT_TOKEN,
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_issue_token_from_rules_without_user(self):
api = auth_controllers.Auth()
@@ -1730,9 +1762,8 @@ class FederatedTokenTests(FederationTests, FederatedSetupMixin):
def test_scope_to_domain_once(self):
r = self.v3_authenticate_token(self.TOKEN_SCOPE_DOMAIN_A_FROM_CUSTOMER)
token_resp = r.result['token']
- domain_id = token_resp['domain']['id']
- self.assertEqual(self.domainA['id'], domain_id)
- self._check_scoped_token_attributes(token_resp)
+ self._check_domain_scoped_token_attributes(token_resp,
+ self.domainA['id'])
def test_scope_to_domain_multiple_tokens(self):
"""Issue multiple tokens scoping to different domains.
@@ -1754,15 +1785,14 @@ class FederatedTokenTests(FederationTests, FederatedSetupMixin):
for body, domain_id_ref in zip(bodies, domain_ids):
r = self.v3_authenticate_token(body)
token_resp = r.result['token']
- domain_id = token_resp['domain']['id']
- self.assertEqual(domain_id_ref, domain_id)
- self._check_scoped_token_attributes(token_resp)
+ self._check_domain_scoped_token_attributes(token_resp,
+ domain_id_ref)
def test_scope_to_domain_with_only_inherited_roles_fails(self):
"""Try to scope to a domain that has no direct roles."""
self.v3_authenticate_token(
self.TOKEN_SCOPE_DOMAIN_D_FROM_CUSTOMER,
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_list_projects(self):
urls = ('/OS-FEDERATION/projects', '/auth/projects')
@@ -1863,9 +1893,10 @@ class FederatedTokenTests(FederationTests, FederatedSetupMixin):
"""
r = self._issue_unscoped_token()
+ token_resp = r.json_body['token']
+ self.assertValidMappedUser(token_resp)
employee_unscoped_token_id = r.headers.get('X-Subject-Token')
- r = self.get('/OS-FEDERATION/projects',
- token=employee_unscoped_token_id)
+ r = self.get('/auth/projects', token=employee_unscoped_token_id)
projects = r.result['projects']
random_project = random.randint(0, len(projects)) - 1
project = projects[random_project]
@@ -1875,9 +1906,7 @@ class FederatedTokenTests(FederationTests, FederatedSetupMixin):
r = self.v3_authenticate_token(v3_scope_request)
token_resp = r.result['token']
- project_id = token_resp['project']['id']
- self.assertEqual(project['id'], project_id)
- self._check_scoped_token_attributes(token_resp)
+ self._check_project_scoped_token_attributes(token_resp, project['id'])
def test_workflow_with_groups_deletion(self):
"""Test full workflow with groups deletion before token scoping.
@@ -1947,7 +1976,8 @@ class FederatedTokenTests(FederationTests, FederatedSetupMixin):
token_id, 'project',
self.project_all['id'])
- self.v3_authenticate_token(scoped_token, expected_status=500)
+ self.v3_authenticate_token(
+ scoped_token, expected_status=http_client.INTERNAL_SERVER_ERROR)
def test_lists_with_missing_group_in_backend(self):
"""Test a mapping that points to a group that does not exist
@@ -2379,11 +2409,13 @@ class FernetFederatedTokenTests(FederationTests, FederatedSetupMixin):
def test_federated_unscoped_token(self):
resp = self._issue_unscoped_token()
self.assertEqual(204, len(resp.headers['X-Subject-Token']))
+ self.assertValidMappedUser(resp.json_body['token'])
def test_federated_unscoped_token_with_multiple_groups(self):
assertion = 'ANOTHER_CUSTOMER_ASSERTION'
resp = self._issue_unscoped_token(assertion=assertion)
- self.assertEqual(232, len(resp.headers['X-Subject-Token']))
+ self.assertEqual(226, len(resp.headers['X-Subject-Token']))
+ self.assertValidMappedUser(resp.json_body['token'])
def test_validate_federated_unscoped_token(self):
resp = self._issue_unscoped_token()
@@ -2400,9 +2432,9 @@ class FernetFederatedTokenTests(FederationTests, FederatedSetupMixin):
"""
resp = self._issue_unscoped_token()
+ self.assertValidMappedUser(resp.json_body['token'])
unscoped_token = resp.headers.get('X-Subject-Token')
- resp = self.get('/OS-FEDERATION/projects',
- token=unscoped_token)
+ resp = self.get('/auth/projects', token=unscoped_token)
projects = resp.result['projects']
random_project = random.randint(0, len(projects)) - 1
project = projects[random_project]
@@ -2412,9 +2444,7 @@ class FernetFederatedTokenTests(FederationTests, FederatedSetupMixin):
resp = self.v3_authenticate_token(v3_scope_request)
token_resp = resp.result['token']
- project_id = token_resp['project']['id']
- self.assertEqual(project['id'], project_id)
- self._check_scoped_token_attributes(token_resp)
+ self._check_project_scoped_token_attributes(token_resp, project['id'])
class FederatedTokenTestsMethodToken(FederatedTokenTests):
@@ -2499,7 +2529,7 @@ class SAMLGenerationTests(FederationTests):
self.sp = self.sp_ref()
url = '/OS-FEDERATION/service_providers/' + self.SERVICE_PROVDIER_ID
self.put(url, body={'service_provider': self.sp},
- expected_status=201)
+ expected_status=http_client.CREATED)
def test_samlize_token_values(self):
"""Test the SAML generator produces a SAML object.
@@ -2615,8 +2645,8 @@ class SAMLGenerationTests(FederationTests):
# the assertion as is without signing it
return assertion_content
- with mock.patch('subprocess.check_output',
- side_effect=mocked_subprocess_check_output):
+ with mock.patch.object(subprocess, 'check_output',
+ side_effect=mocked_subprocess_check_output):
generator = keystone_idp.SAMLGenerator()
response = generator.samlize_token(self.ISSUER, self.RECIPIENT,
self.SUBJECT,
@@ -2711,7 +2741,7 @@ class SAMLGenerationTests(FederationTests):
with mock.patch.object(keystone_idp, '_sign_assertion',
return_value=self.signed_assertion):
self.post(self.SAML_GENERATION_ROUTE, body=body,
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_generate_saml_route(self):
"""Test that the SAML generation endpoint produces XML.
@@ -2733,7 +2763,7 @@ class SAMLGenerationTests(FederationTests):
return_value=self.signed_assertion):
http_response = self.post(self.SAML_GENERATION_ROUTE, body=body,
response_content_type='text/xml',
- expected_status=200)
+ expected_status=http_client.OK)
response = etree.fromstring(http_response.result)
issuer = response[0]
@@ -2774,7 +2804,8 @@ class SAMLGenerationTests(FederationTests):
self.SERVICE_PROVDIER_ID)
del body['auth']['scope']
- self.post(self.SAML_GENERATION_ROUTE, body=body, expected_status=400)
+ self.post(self.SAML_GENERATION_ROUTE, body=body,
+ expected_status=http_client.BAD_REQUEST)
def test_invalid_token_body(self):
"""Test that missing the token in request body raises an exception.
@@ -2788,7 +2819,8 @@ class SAMLGenerationTests(FederationTests):
self.SERVICE_PROVDIER_ID)
del body['auth']['identity']['token']
- self.post(self.SAML_GENERATION_ROUTE, body=body, expected_status=400)
+ self.post(self.SAML_GENERATION_ROUTE, body=body,
+ expected_status=http_client.BAD_REQUEST)
def test_sp_not_found(self):
"""Test SAML generation with an invalid service provider ID.
@@ -2799,7 +2831,8 @@ class SAMLGenerationTests(FederationTests):
sp_id = uuid.uuid4().hex
token_id = self._fetch_valid_token()
body = self._create_generate_saml_request(token_id, sp_id)
- self.post(self.SAML_GENERATION_ROUTE, body=body, expected_status=404)
+ self.post(self.SAML_GENERATION_ROUTE, body=body,
+ expected_status=http_client.NOT_FOUND)
def test_sp_disabled(self):
"""Try generating assertion for disabled Service Provider."""
@@ -2811,7 +2844,8 @@ class SAMLGenerationTests(FederationTests):
token_id = self._fetch_valid_token()
body = self._create_generate_saml_request(token_id,
self.SERVICE_PROVDIER_ID)
- self.post(self.SAML_GENERATION_ROUTE, body=body, expected_status=403)
+ self.post(self.SAML_GENERATION_ROUTE, body=body,
+ expected_status=http_client.FORBIDDEN)
def test_token_not_found(self):
"""Test that an invalid token in the request body raises an exception.
@@ -2823,7 +2857,8 @@ class SAMLGenerationTests(FederationTests):
token_id = uuid.uuid4().hex
body = self._create_generate_saml_request(token_id,
self.SERVICE_PROVDIER_ID)
- self.post(self.SAML_GENERATION_ROUTE, body=body, expected_status=404)
+ self.post(self.SAML_GENERATION_ROUTE, body=body,
+ expected_status=http_client.NOT_FOUND)
def test_generate_ecp_route(self):
"""Test that the ECP generation endpoint produces XML.
@@ -2844,7 +2879,7 @@ class SAMLGenerationTests(FederationTests):
return_value=self.signed_assertion):
http_response = self.post(self.ECP_GENERATION_ROUTE, body=body,
response_content_type='text/xml',
- expected_status=200)
+ expected_status=http_client.OK)
env_response = etree.fromstring(http_response.result)
header = env_response[0]
@@ -2879,7 +2914,7 @@ class SAMLGenerationTests(FederationTests):
@mock.patch('saml2.create_class_from_xml_string')
@mock.patch('oslo_utils.fileutils.write_to_tempfile')
- @mock.patch('subprocess.check_output')
+ @mock.patch.object(subprocess, 'check_output')
def test__sign_assertion(self, check_output_mock,
write_to_tempfile_mock, create_class_mock):
write_to_tempfile_mock.return_value = 'tmp_path'
@@ -2890,7 +2925,7 @@ class SAMLGenerationTests(FederationTests):
create_class_mock.assert_called_with(saml.Assertion, 'fakeoutput')
@mock.patch('oslo_utils.fileutils.write_to_tempfile')
- @mock.patch('subprocess.check_output')
+ @mock.patch.object(subprocess, 'check_output')
def test__sign_assertion_exc(self, check_output_mock,
write_to_tempfile_mock):
# If the command fails the command output is logged.
@@ -2903,12 +2938,15 @@ class SAMLGenerationTests(FederationTests):
returncode=sample_returncode, cmd=CONF.saml.xmlsec1_binary,
output=sample_output)
- # FIXME(blk-u): This should raise exception.SAMLSigningError instead,
- # but fails with TypeError due to concatenating string to Message, see
- # bug 1484735.
- self.assertRaises(TypeError,
+ logger_fixture = self.useFixture(fixtures.LoggerFixture())
+ self.assertRaises(exception.SAMLSigningError,
keystone_idp._sign_assertion,
self.signed_assertion)
+ expected_log = (
+ "Error when signing assertion, reason: Command '%s' returned "
+ "non-zero exit status %s %s\n" %
+ (CONF.saml.xmlsec1_binary, sample_returncode, sample_output))
+ self.assertEqual(expected_log, logger_fixture.output)
@mock.patch('oslo_utils.fileutils.write_to_tempfile')
def test__sign_assertion_fileutils_exc(self, write_to_tempfile_mock):
@@ -3041,13 +3079,13 @@ class IdPMetadataGenerationTests(FederationTests):
self.generator.generate_metadata)
def test_get_metadata_with_no_metadata_file_configured(self):
- self.get(self.METADATA_URL, expected_status=500)
+ self.get(self.METADATA_URL,
+ expected_status=http_client.INTERNAL_SERVER_ERROR)
def test_get_metadata(self):
self.config_fixture.config(
group='saml', idp_metadata_path=XMLDIR + '/idp_saml2_metadata.xml')
- r = self.get(self.METADATA_URL, response_content_type='text/xml',
- expected_status=200)
+ r = self.get(self.METADATA_URL, response_content_type='text/xml')
self.assertEqual('text/xml', r.headers.get('Content-Type'))
reference_file = _load_xml('idp_saml2_metadata.xml')
@@ -3070,7 +3108,7 @@ class ServiceProviderTests(FederationTests):
self.SP_REF = self.sp_ref()
self.SERVICE_PROVIDER = self.put(
url, body={'service_provider': self.SP_REF},
- expected_status=201).result
+ expected_status=http_client.CREATED).result
def sp_ref(self):
ref = {
@@ -3089,19 +3127,19 @@ class ServiceProviderTests(FederationTests):
def test_get_service_provider(self):
url = self.base_url(suffix=self.SERVICE_PROVIDER_ID)
- resp = self.get(url, expected_status=200)
+ resp = self.get(url)
self.assertValidEntity(resp.result['service_provider'],
keys_to_check=self.SP_KEYS)
def test_get_service_provider_fail(self):
url = self.base_url(suffix=uuid.uuid4().hex)
- self.get(url, expected_status=404)
+ self.get(url, expected_status=http_client.NOT_FOUND)
def test_create_service_provider(self):
url = self.base_url(suffix=uuid.uuid4().hex)
sp = self.sp_ref()
resp = self.put(url, body={'service_provider': sp},
- expected_status=201)
+ expected_status=http_client.CREATED)
self.assertValidEntity(resp.result['service_provider'],
keys_to_check=self.SP_KEYS)
@@ -3111,7 +3149,7 @@ class ServiceProviderTests(FederationTests):
sp = self.sp_ref()
del sp['relay_state_prefix']
resp = self.put(url, body={'service_provider': sp},
- expected_status=201)
+ expected_status=http_client.CREATED)
sp_result = resp.result['service_provider']
self.assertEqual(CONF.saml.relay_state_prefix,
sp_result['relay_state_prefix'])
@@ -3123,7 +3161,7 @@ class ServiceProviderTests(FederationTests):
non_default_prefix = uuid.uuid4().hex
sp['relay_state_prefix'] = non_default_prefix
resp = self.put(url, body={'service_provider': sp},
- expected_status=201)
+ expected_status=http_client.CREATED)
sp_result = resp.result['service_provider']
self.assertEqual(non_default_prefix,
sp_result['relay_state_prefix'])
@@ -3134,7 +3172,7 @@ class ServiceProviderTests(FederationTests):
sp = self.sp_ref()
sp[uuid.uuid4().hex] = uuid.uuid4().hex
self.put(url, body={'service_provider': sp},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_list_service_providers(self):
"""Test listing of service provider objects.
@@ -3150,7 +3188,8 @@ class ServiceProviderTests(FederationTests):
}
for id, sp in ref_service_providers.items():
url = self.base_url(suffix=id)
- self.put(url, body={'service_provider': sp}, expected_status=201)
+ self.put(url, body={'service_provider': sp},
+ expected_status=http_client.CREATED)
# Insert ids into service provider object, we will compare it with
# responses from server and those include 'id' attribute.
@@ -3177,15 +3216,14 @@ class ServiceProviderTests(FederationTests):
"""
new_sp_ref = self.sp_ref()
url = self.base_url(suffix=self.SERVICE_PROVIDER_ID)
- resp = self.patch(url, body={'service_provider': new_sp_ref},
- expected_status=200)
+ resp = self.patch(url, body={'service_provider': new_sp_ref})
patch_result = resp.result
new_sp_ref['id'] = self.SERVICE_PROVIDER_ID
self.assertValidEntity(patch_result['service_provider'],
ref=new_sp_ref,
keys_to_check=self.SP_KEYS)
- resp = self.get(url, expected_status=200)
+ resp = self.get(url)
get_result = resp.result
self.assertDictEqual(patch_result['service_provider'],
@@ -3201,21 +3239,21 @@ class ServiceProviderTests(FederationTests):
new_sp_ref = {'id': uuid.uuid4().hex}
url = self.base_url(suffix=self.SERVICE_PROVIDER_ID)
self.patch(url, body={'service_provider': new_sp_ref},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_update_service_provider_unknown_parameter(self):
new_sp_ref = self.sp_ref()
new_sp_ref[uuid.uuid4().hex] = uuid.uuid4().hex
url = self.base_url(suffix=self.SERVICE_PROVIDER_ID)
self.patch(url, body={'service_provider': new_sp_ref},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_update_service_provider_404(self):
new_sp_ref = self.sp_ref()
new_sp_ref['description'] = uuid.uuid4().hex
url = self.base_url(suffix=uuid.uuid4().hex)
self.patch(url, body={'service_provider': new_sp_ref},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_update_sp_relay_state(self):
"""Update an SP with custome relay state."""
@@ -3223,19 +3261,18 @@ class ServiceProviderTests(FederationTests):
non_default_prefix = uuid.uuid4().hex
new_sp_ref['relay_state_prefix'] = non_default_prefix
url = self.base_url(suffix=self.SERVICE_PROVIDER_ID)
- resp = self.patch(url, body={'service_provider': new_sp_ref},
- expected_status=200)
+ resp = self.patch(url, body={'service_provider': new_sp_ref})
sp_result = resp.result['service_provider']
self.assertEqual(non_default_prefix,
sp_result['relay_state_prefix'])
def test_delete_service_provider(self):
url = self.base_url(suffix=self.SERVICE_PROVIDER_ID)
- self.delete(url, expected_status=204)
+ self.delete(url)
def test_delete_service_provider_404(self):
url = self.base_url(suffix=uuid.uuid4().hex)
- self.delete(url, expected_status=404)
+ self.delete(url, expected_status=http_client.NOT_FOUND)
class WebSSOTests(FederatedTokenTests):
@@ -3337,6 +3374,16 @@ class WebSSOTests(FederatedTokenTests):
self.api.federated_sso_auth,
context, self.PROTOCOL)
+ def test_identity_provider_specific_federated_authentication(self):
+ environment = {self.REMOTE_ID_ATTR: self.REMOTE_IDS[0]}
+ context = {'environment': environment}
+ query_string = {'origin': self.ORIGIN}
+ self._inject_assertion(context, 'EMPLOYEE_ASSERTION', query_string)
+ resp = self.api.federated_idp_specific_sso_auth(context,
+ self.idp['id'],
+ self.PROTOCOL)
+ self.assertIn(self.TRUSTED_DASHBOARD, resp.body)
+
class K2KServiceCatalogTests(FederationTests):
SP1 = 'SP1'
diff --git a/keystone-moon/keystone/tests/unit/test_v3_identity.py b/keystone-moon/keystone/tests/unit/test_v3_identity.py
index e0090829..3d424cea 100644
--- a/keystone-moon/keystone/tests/unit/test_v3_identity.py
+++ b/keystone-moon/keystone/tests/unit/test_v3_identity.py
@@ -16,12 +16,14 @@ import logging
import uuid
import fixtures
+import mock
from oslo_config import cfg
+from six.moves import http_client
from testtools import matchers
from keystone.common import controller
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import test_v3
@@ -96,17 +98,24 @@ class IdentityTestCase(test_v3.RestfulTestCase):
user_id=self.user['id'],
password=self.user['password'],
project_id=self.project['id'])
- r = self.post('/users', body={'user': ref_nd}, auth=auth)
+
# TODO(henry-nash): Due to bug #1283539 we currently automatically
# use the default domain_id if a domain scoped token is not being
- # used. Change the code below to expect a failure once this bug is
+ # used. For now we just check that a deprecation warning has been
+ # issued. Change the code below to expect a failure once this bug is
# fixed.
+ with mock.patch(
+ 'oslo_log.versionutils.report_deprecated_feature') as mock_dep:
+ r = self.post('/users', body={'user': ref_nd}, auth=auth)
+ self.assertTrue(mock_dep.called)
+
ref['domain_id'] = CONF.identity.default_domain_id
return self.assertValidUserResponse(r, ref)
- def test_create_user_400(self):
+ def test_create_user_bad_request(self):
"""Call ``POST /users``."""
- self.post('/users', body={'user': {}}, expected_status=400)
+ self.post('/users', body={'user': {}},
+ expected_status=http_client.BAD_REQUEST)
def test_list_users(self):
"""Call ``GET /users``."""
@@ -286,30 +295,31 @@ class IdentityTestCase(test_v3.RestfulTestCase):
old_password_auth = self.build_authentication_request(
user_id=user_ref['id'],
password=password)
- r = self.v3_authenticate_token(old_password_auth, expected_status=201)
+ r = self.v3_authenticate_token(old_password_auth)
old_token = r.headers.get('X-Subject-Token')
# auth as user with a token should work before a password change
old_token_auth = self.build_authentication_request(token=old_token)
- self.v3_authenticate_token(old_token_auth, expected_status=201)
+ self.v3_authenticate_token(old_token_auth)
# administrative password reset
new_password = uuid.uuid4().hex
self.patch('/users/%s' % user_ref['id'],
- body={'user': {'password': new_password}},
- expected_status=200)
+ body={'user': {'password': new_password}})
# auth as user with original password should not work after change
- self.v3_authenticate_token(old_password_auth, expected_status=401)
+ self.v3_authenticate_token(old_password_auth,
+ expected_status=http_client.UNAUTHORIZED)
# auth as user with an old token should not work after change
- self.v3_authenticate_token(old_token_auth, expected_status=404)
+ self.v3_authenticate_token(old_token_auth,
+ expected_status=http_client.NOT_FOUND)
# new password should work
new_password_auth = self.build_authentication_request(
user_id=user_ref['id'],
password=new_password)
- self.v3_authenticate_token(new_password_auth, expected_status=201)
+ self.v3_authenticate_token(new_password_auth)
def test_update_user_domain_id(self):
"""Call ``PATCH /users/{user_id}`` with domain_id."""
@@ -360,7 +370,7 @@ class IdentityTestCase(test_v3.RestfulTestCase):
# Confirm token is valid for now
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
- expected_status=200)
+ expected_status=http_client.OK)
# Now delete the user
self.delete('/users/%(user_id)s' % {
@@ -389,9 +399,10 @@ class IdentityTestCase(test_v3.RestfulTestCase):
body={'group': ref})
return self.assertValidGroupResponse(r, ref)
- def test_create_group_400(self):
+ def test_create_group_bad_request(self):
"""Call ``POST /groups``."""
- self.post('/groups', body={'group': {}}, expected_status=400)
+ self.post('/groups', body={'group': {}},
+ expected_status=http_client.BAD_REQUEST)
def test_list_groups(self):
"""Call ``GET /groups``."""
@@ -462,14 +473,13 @@ class IdentityTestCase(test_v3.RestfulTestCase):
# administrative password reset
new_password = uuid.uuid4().hex
self.patch('/users/%s' % user_ref['id'],
- body={'user': {'password': new_password}},
- expected_status=200)
+ body={'user': {'password': new_password}})
self.assertNotIn(password, log_fix.output)
self.assertNotIn(new_password, log_fix.output)
-class IdentityV3toV2MethodsTestCase(tests.TestCase):
+class IdentityV3toV2MethodsTestCase(unit.TestCase):
"""Test users V3 to V2 conversion methods."""
def setUp(self):
@@ -549,7 +559,8 @@ class UserSelfServiceChangingPasswordsTestCase(test_v3.RestfulTestCase):
password = self.user_ref['password']
self.user_ref = self.identity_api.create_user(self.user_ref)
self.user_ref['password'] = password
- self.token = self.get_request_token(self.user_ref['password'], 201)
+ self.token = self.get_request_token(self.user_ref['password'],
+ http_client.CREATED)
def get_request_token(self, password, expected_status):
auth_data = self.build_authentication_request(
@@ -569,42 +580,45 @@ class UserSelfServiceChangingPasswordsTestCase(test_v3.RestfulTestCase):
def test_changing_password(self):
# original password works
token_id = self.get_request_token(self.user_ref['password'],
- expected_status=201)
+ expected_status=http_client.CREATED)
# original token works
old_token_auth = self.build_authentication_request(token=token_id)
- self.v3_authenticate_token(old_token_auth, expected_status=201)
+ self.v3_authenticate_token(old_token_auth)
# change password
new_password = uuid.uuid4().hex
self.change_password(password=new_password,
original_password=self.user_ref['password'],
- expected_status=204)
+ expected_status=http_client.NO_CONTENT)
# old password fails
- self.get_request_token(self.user_ref['password'], expected_status=401)
+ self.get_request_token(self.user_ref['password'],
+ expected_status=http_client.UNAUTHORIZED)
# old token fails
- self.v3_authenticate_token(old_token_auth, expected_status=404)
+ self.v3_authenticate_token(old_token_auth,
+ expected_status=http_client.NOT_FOUND)
# new password works
- self.get_request_token(new_password, expected_status=201)
+ self.get_request_token(new_password,
+ expected_status=http_client.CREATED)
def test_changing_password_with_missing_original_password_fails(self):
r = self.change_password(password=uuid.uuid4().hex,
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
self.assertThat(r.result['error']['message'],
matchers.Contains('original_password'))
def test_changing_password_with_missing_password_fails(self):
r = self.change_password(original_password=self.user_ref['password'],
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
self.assertThat(r.result['error']['message'],
matchers.Contains('password'))
def test_changing_password_with_incorrect_password_fails(self):
self.change_password(password=uuid.uuid4().hex,
original_password=uuid.uuid4().hex,
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_changing_password_with_disabled_user_fails(self):
# disable the user account
@@ -614,7 +628,7 @@ class UserSelfServiceChangingPasswordsTestCase(test_v3.RestfulTestCase):
self.change_password(password=uuid.uuid4().hex,
original_password=self.user_ref['password'],
- expected_status=401)
+ expected_status=http_client.UNAUTHORIZED)
def test_changing_password_not_logged(self):
# When a user changes their password, the password isn't logged at any
@@ -626,7 +640,7 @@ class UserSelfServiceChangingPasswordsTestCase(test_v3.RestfulTestCase):
new_password = uuid.uuid4().hex
self.change_password(password=new_password,
original_password=self.user_ref['password'],
- expected_status=204)
+ expected_status=http_client.NO_CONTENT)
self.assertNotIn(self.user_ref['password'], log_fix.output)
self.assertNotIn(new_password, log_fix.output)
diff --git a/keystone-moon/keystone/tests/unit/test_v3_oauth1.py b/keystone-moon/keystone/tests/unit/test_v3_oauth1.py
index 6c063c5e..3a0d481c 100644
--- a/keystone-moon/keystone/tests/unit/test_v3_oauth1.py
+++ b/keystone-moon/keystone/tests/unit/test_v3_oauth1.py
@@ -18,6 +18,7 @@ import uuid
from oslo_config import cfg
from oslo_serialization import jsonutils
from pycadf import cadftaxonomy
+from six.moves import http_client
from six.moves import urllib
from keystone.contrib import oauth1
@@ -139,7 +140,7 @@ class ConsumerCRUDTests(OAuth1Tests):
consumer = self._create_single_consumer()
consumer_id = consumer['id']
resp = self.delete(self.CONSUMER_URL + '/%s' % consumer_id)
- self.assertResponseStatus(resp, 204)
+ self.assertResponseStatus(resp, http_client.NO_CONTENT)
def test_consumer_get(self):
consumer = self._create_single_consumer()
@@ -182,7 +183,7 @@ class ConsumerCRUDTests(OAuth1Tests):
update_ref['secret'] = uuid.uuid4().hex
self.patch(self.CONSUMER_URL + '/%s' % original_id,
body={'consumer': update_ref},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_consumer_update_bad_id(self):
consumer = self._create_single_consumer()
@@ -195,7 +196,7 @@ class ConsumerCRUDTests(OAuth1Tests):
update_ref['id'] = update_description
self.patch(self.CONSUMER_URL + '/%s' % original_id,
body={'consumer': update_ref},
- expected_status=400)
+ expected_status=http_client.BAD_REQUEST)
def test_consumer_update_normalize_field(self):
# If update a consumer with a field with : or - in the name,
@@ -236,7 +237,7 @@ class ConsumerCRUDTests(OAuth1Tests):
def test_consumer_get_bad_id(self):
self.get(self.CONSUMER_URL + '/%(consumer_id)s'
% {'consumer_id': uuid.uuid4().hex},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
class OAuthFlowTests(OAuth1Tests):
@@ -261,7 +262,7 @@ class OAuthFlowTests(OAuth1Tests):
url = self._authorize_request_token(request_key)
body = {'roles': [{'id': self.role_id}]}
- resp = self.put(url, body=body, expected_status=200)
+ resp = self.put(url, body=body, expected_status=http_client.OK)
self.verifier = resp.result['token']['oauth_verifier']
self.assertTrue(all(i in core.VERIFIER_CHARS for i in self.verifier))
self.assertEqual(8, len(self.verifier))
@@ -291,7 +292,7 @@ class AccessTokenCRUDTests(OAuthFlowTests):
self.delete('/users/%(user)s/OS-OAUTH1/access_tokens/%(auth)s'
% {'user': self.user_id,
'auth': uuid.uuid4().hex},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_list_no_access_tokens(self):
resp = self.get('/users/%(user_id)s/OS-OAUTH1/access_tokens'
@@ -316,7 +317,7 @@ class AccessTokenCRUDTests(OAuthFlowTests):
self.get('/users/%(user_id)s/OS-OAUTH1/access_tokens/%(key)s'
% {'user_id': self.user_id,
'key': uuid.uuid4().hex},
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_list_all_roles_in_access_token(self):
self.test_oauth_flow()
@@ -341,7 +342,7 @@ class AccessTokenCRUDTests(OAuthFlowTests):
url = ('/users/%(id)s/OS-OAUTH1/access_tokens/%(key)s/roles/%(role)s'
% {'id': self.user_id, 'key': self.access_token.key,
'role': uuid.uuid4().hex})
- self.get(url, expected_status=404)
+ self.get(url, expected_status=http_client.NOT_FOUND)
def test_list_and_delete_access_tokens(self):
self.test_oauth_flow()
@@ -356,7 +357,7 @@ class AccessTokenCRUDTests(OAuthFlowTests):
resp = self.delete('/users/%(user)s/OS-OAUTH1/access_tokens/%(auth)s'
% {'user': self.user_id,
'auth': self.access_token.key})
- self.assertResponseStatus(resp, 204)
+ self.assertResponseStatus(resp, http_client.NO_CONTENT)
# List access_token should be 0
resp = self.get('/users/%(user_id)s/OS-OAUTH1/access_tokens'
@@ -399,13 +400,13 @@ class AuthTokenTests(OAuthFlowTests):
resp = self.delete('/users/%(user)s/OS-OAUTH1/access_tokens/%(auth)s'
% {'user': self.user_id,
'auth': self.access_token.key})
- self.assertResponseStatus(resp, 204)
+ self.assertResponseStatus(resp, http_client.NO_CONTENT)
# Check Keystone Token no longer exists
headers = {'X-Subject-Token': self.keystone_token_id,
'X-Auth-Token': self.keystone_token_id}
self.get('/auth/tokens', headers=headers,
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_deleting_consumer_also_deletes_tokens(self):
self.test_oauth_flow()
@@ -414,7 +415,7 @@ class AuthTokenTests(OAuthFlowTests):
consumer_id = self.consumer['key']
resp = self.delete('/OS-OAUTH1/consumers/%(consumer_id)s'
% {'consumer_id': consumer_id})
- self.assertResponseStatus(resp, 204)
+ self.assertResponseStatus(resp, http_client.NO_CONTENT)
# List access_token should be 0
resp = self.get('/users/%(user_id)s/OS-OAUTH1/access_tokens'
@@ -426,7 +427,7 @@ class AuthTokenTests(OAuthFlowTests):
headers = {'X-Subject-Token': self.keystone_token_id,
'X-Auth-Token': self.keystone_token_id}
self.head('/auth/tokens', headers=headers,
- expected_status=404)
+ expected_status=http_client.NOT_FOUND)
def test_change_user_password_also_deletes_tokens(self):
self.test_oauth_flow()
@@ -445,7 +446,7 @@ class AuthTokenTests(OAuthFlowTests):
headers = {'X-Subject-Token': self.keystone_token_id,
'X-Auth-Token': self.keystone_token_id}
self.admin_request(path='/auth/tokens', headers=headers,
- method='GET', expected_status=404)
+ method='GET', expected_status=http_client.NOT_FOUND)
def test_deleting_project_also_invalidates_tokens(self):
self.test_oauth_flow()
@@ -462,7 +463,7 @@ class AuthTokenTests(OAuthFlowTests):
headers = {'X-Subject-Token': self.keystone_token_id,
'X-Auth-Token': self.keystone_token_id}
self.admin_request(path='/auth/tokens', headers=headers,
- method='GET', expected_status=404)
+ method='GET', expected_status=http_client.NOT_FOUND)
def test_token_chaining_is_not_allowed(self):
self.test_oauth_flow()
@@ -477,7 +478,7 @@ class AuthTokenTests(OAuthFlowTests):
body=auth_data,
token=self.keystone_token_id,
method='POST',
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_delete_keystone_tokens_by_consumer_id(self):
self.test_oauth_flow()
@@ -545,14 +546,14 @@ class AuthTokenTests(OAuthFlowTests):
self.post('/OS-TRUST/trusts',
body={'trust': ref},
token=self.keystone_token_id,
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_oauth_token_cannot_authorize_request_token(self):
self.test_oauth_flow()
url = self._approve_request_token_url()
body = {'roles': [{'id': self.role_id}]}
self.put(url, body=body, token=self.keystone_token_id,
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_oauth_token_cannot_list_request_tokens(self):
self._set_policy({"identity:list_access_tokens": [],
@@ -561,7 +562,7 @@ class AuthTokenTests(OAuthFlowTests):
self.test_oauth_flow()
url = '/users/%s/OS-OAUTH1/access_tokens' % self.user_id
self.get(url, token=self.keystone_token_id,
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def _set_policy(self, new_policy):
self.tempfile = self.useFixture(temporaryfile.SecureTempFile())
@@ -575,14 +576,16 @@ class AuthTokenTests(OAuthFlowTests):
trust_token = self._create_trust_get_token()
url = self._approve_request_token_url()
body = {'roles': [{'id': self.role_id}]}
- self.put(url, body=body, token=trust_token, expected_status=403)
+ self.put(url, body=body, token=trust_token,
+ expected_status=http_client.FORBIDDEN)
def test_trust_token_cannot_list_request_tokens(self):
self._set_policy({"identity:list_access_tokens": [],
"identity:create_trust": []})
trust_token = self._create_trust_get_token()
url = '/users/%s/OS-OAUTH1/access_tokens' % self.user_id
- self.get(url, token=trust_token, expected_status=403)
+ self.get(url, token=trust_token,
+ expected_status=http_client.FORBIDDEN)
class MaliciousOAuth1Tests(OAuth1Tests):
@@ -592,7 +595,8 @@ class MaliciousOAuth1Tests(OAuth1Tests):
consumer_id = consumer['id']
consumer = {'key': consumer_id, 'secret': uuid.uuid4().hex}
url, headers = self._create_request_token(consumer, self.project_id)
- self.post(url, headers=headers, expected_status=401)
+ self.post(url, headers=headers,
+ expected_status=http_client.UNAUTHORIZED)
def test_bad_request_token_key(self):
consumer = self._create_single_consumer()
@@ -605,7 +609,7 @@ class MaliciousOAuth1Tests(OAuth1Tests):
response_content_type='application/x-www-urlformencoded')
url = self._authorize_request_token(uuid.uuid4().hex)
body = {'roles': [{'id': self.role_id}]}
- self.put(url, body=body, expected_status=404)
+ self.put(url, body=body, expected_status=http_client.NOT_FOUND)
def test_bad_consumer_id(self):
consumer = self._create_single_consumer()
@@ -613,7 +617,7 @@ class MaliciousOAuth1Tests(OAuth1Tests):
consumer_secret = consumer['secret']
consumer = {'key': consumer_id, 'secret': consumer_secret}
url, headers = self._create_request_token(consumer, self.project_id)
- self.post(url, headers=headers, expected_status=404)
+ self.post(url, headers=headers, expected_status=http_client.NOT_FOUND)
def test_bad_requested_project_id(self):
consumer = self._create_single_consumer()
@@ -622,7 +626,7 @@ class MaliciousOAuth1Tests(OAuth1Tests):
consumer = {'key': consumer_id, 'secret': consumer_secret}
project_id = uuid.uuid4().hex
url, headers = self._create_request_token(consumer, project_id)
- self.post(url, headers=headers, expected_status=404)
+ self.post(url, headers=headers, expected_status=http_client.NOT_FOUND)
def test_bad_verifier(self):
consumer = self._create_single_consumer()
@@ -641,13 +645,14 @@ class MaliciousOAuth1Tests(OAuth1Tests):
url = self._authorize_request_token(request_key)
body = {'roles': [{'id': self.role_id}]}
- resp = self.put(url, body=body, expected_status=200)
+ resp = self.put(url, body=body, expected_status=http_client.OK)
verifier = resp.result['token']['oauth_verifier']
self.assertIsNotNone(verifier)
request_token.set_verifier(uuid.uuid4().hex)
url, headers = self._create_access_token(consumer, request_token)
- self.post(url, headers=headers, expected_status=401)
+ self.post(url, headers=headers,
+ expected_status=http_client.UNAUTHORIZED)
def test_bad_authorizing_roles(self):
consumer = self._create_single_consumer()
@@ -667,7 +672,7 @@ class MaliciousOAuth1Tests(OAuth1Tests):
url = self._authorize_request_token(request_key)
body = {'roles': [{'id': self.role_id}]}
self.admin_request(path=url, method='PUT',
- body=body, expected_status=404)
+ body=body, expected_status=http_client.NOT_FOUND)
def test_expired_authorizing_request_token(self):
self.config_fixture.config(group='oauth1', request_token_duration=-1)
@@ -691,7 +696,7 @@ class MaliciousOAuth1Tests(OAuth1Tests):
url = self._authorize_request_token(request_key)
body = {'roles': [{'id': self.role_id}]}
- self.put(url, body=body, expected_status=401)
+ self.put(url, body=body, expected_status=http_client.UNAUTHORIZED)
def test_expired_creating_keystone_token(self):
self.config_fixture.config(group='oauth1', access_token_duration=-1)
@@ -714,7 +719,7 @@ class MaliciousOAuth1Tests(OAuth1Tests):
url = self._authorize_request_token(request_key)
body = {'roles': [{'id': self.role_id}]}
- resp = self.put(url, body=body, expected_status=200)
+ resp = self.put(url, body=body, expected_status=http_client.OK)
self.verifier = resp.result['token']['oauth_verifier']
self.request_token.set_verifier(self.verifier)
@@ -731,7 +736,8 @@ class MaliciousOAuth1Tests(OAuth1Tests):
url, headers, body = self._get_oauth_token(self.consumer,
self.access_token)
- self.post(url, headers=headers, body=body, expected_status=401)
+ self.post(url, headers=headers, body=body,
+ expected_status=http_client.UNAUTHORIZED)
def test_missing_oauth_headers(self):
endpoint = '/OS-OAUTH1/request_token'
@@ -747,7 +753,8 @@ class MaliciousOAuth1Tests(OAuth1Tests):
# NOTE(stevemar): To simulate this error, we remove the Authorization
# header from the post request.
del headers['Authorization']
- self.post(endpoint, headers=headers, expected_status=500)
+ self.post(endpoint, headers=headers,
+ expected_status=http_client.INTERNAL_SERVER_ERROR)
class OAuthNotificationTests(OAuth1Tests,
@@ -823,7 +830,7 @@ class OAuthNotificationTests(OAuth1Tests,
url = self._authorize_request_token(request_key)
body = {'roles': [{'id': self.role_id}]}
- resp = self.put(url, body=body, expected_status=200)
+ resp = self.put(url, body=body, expected_status=http_client.OK)
self.verifier = resp.result['token']['oauth_verifier']
self.assertTrue(all(i in core.VERIFIER_CHARS for i in self.verifier))
self.assertEqual(8, len(self.verifier))
@@ -852,7 +859,7 @@ class OAuthNotificationTests(OAuth1Tests,
resp = self.delete('/users/%(user)s/OS-OAUTH1/access_tokens/%(auth)s'
% {'user': self.user_id,
'auth': self.access_token.key})
- self.assertResponseStatus(resp, 204)
+ self.assertResponseStatus(resp, http_client.NO_CONTENT)
# Test to ensure the delete access token notification is sent
self._assert_notify_sent(access_key,
diff --git a/keystone-moon/keystone/tests/unit/test_v3_os_revoke.py b/keystone-moon/keystone/tests/unit/test_v3_os_revoke.py
index 48226cd4..86ced724 100644
--- a/keystone-moon/keystone/tests/unit/test_v3_os_revoke.py
+++ b/keystone-moon/keystone/tests/unit/test_v3_os_revoke.py
@@ -15,6 +15,7 @@ import uuid
from oslo_utils import timeutils
import six
+from six.moves import http_client
from testtools import matchers
from keystone.common import utils
@@ -112,7 +113,8 @@ class OSRevokeTests(test_v3.RestfulTestCase, test_v3.JsonHomeTestMixin):
self.assertReportedEventMatchesRecorded(events[0], sample, before_time)
def test_list_since_invalid(self):
- self.get('/OS-REVOKE/events?since=blah', expected_status=400)
+ self.get('/OS-REVOKE/events?since=blah',
+ expected_status=http_client.BAD_REQUEST)
def test_list_since_valid(self):
resp = self.get('/OS-REVOKE/events?since=2013-02-27T18:30:59.999999Z')
diff --git a/keystone-moon/keystone/tests/unit/test_v3_protection.py b/keystone-moon/keystone/tests/unit/test_v3_protection.py
index 458c61de..296e1d4b 100644
--- a/keystone-moon/keystone/tests/unit/test_v3_protection.py
+++ b/keystone-moon/keystone/tests/unit/test_v3_protection.py
@@ -17,10 +17,11 @@ import uuid
from oslo_config import cfg
from oslo_serialization import jsonutils
+from six.moves import http_client
from keystone import exception
from keystone.policy.backends import rules
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit.ksfixtures import temporaryfile
from keystone.tests.unit import test_v3
@@ -428,7 +429,8 @@ class IdentityTestPolicySample(test_v3.RestfulTestCase):
user2_token = self.get_requested_token(user2_auth)
self.get('/auth/tokens', token=user1_token,
- headers={'X-Subject-Token': user2_token}, expected_status=403)
+ headers={'X-Subject-Token': user2_token},
+ expected_status=http_client.FORBIDDEN)
def test_admin_validate_user_token(self):
# An admin can validate a user's token.
@@ -459,7 +461,8 @@ class IdentityTestPolicySample(test_v3.RestfulTestCase):
token = self.get_requested_token(auth)
self.head('/auth/tokens', token=token,
- headers={'X-Subject-Token': token}, expected_status=200)
+ headers={'X-Subject-Token': token},
+ expected_status=http_client.OK)
def test_user_check_user_token(self):
# A user can check one of their own tokens.
@@ -472,7 +475,8 @@ class IdentityTestPolicySample(test_v3.RestfulTestCase):
token2 = self.get_requested_token(auth)
self.head('/auth/tokens', token=token1,
- headers={'X-Subject-Token': token2}, expected_status=200)
+ headers={'X-Subject-Token': token2},
+ expected_status=http_client.OK)
def test_user_check_other_user_token_rejected(self):
# A user cannot check another user's token.
@@ -490,7 +494,7 @@ class IdentityTestPolicySample(test_v3.RestfulTestCase):
self.head('/auth/tokens', token=user1_token,
headers={'X-Subject-Token': user2_token},
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_admin_check_user_token(self):
# An admin can check a user's token.
@@ -508,7 +512,8 @@ class IdentityTestPolicySample(test_v3.RestfulTestCase):
user_token = self.get_requested_token(user_auth)
self.head('/auth/tokens', token=admin_token,
- headers={'X-Subject-Token': user_token}, expected_status=200)
+ headers={'X-Subject-Token': user_token},
+ expected_status=http_client.OK)
def test_user_revoke_same_token(self):
# Given a non-admin user token, the token can be used to revoke
@@ -552,7 +557,7 @@ class IdentityTestPolicySample(test_v3.RestfulTestCase):
self.delete('/auth/tokens', token=user1_token,
headers={'X-Subject-Token': user2_token},
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_admin_revoke_user_token(self):
# An admin can revoke a user's token.
@@ -607,7 +612,7 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
rules.reset()
self.config_fixture.config(
group='oslo_policy',
- policy_file=tests.dirs.etc('policy.v3cloudsample.json'))
+ policy_file=unit.dirs.etc('policy.v3cloudsample.json'))
def load_sample_data(self):
# Start by creating a couple of domains
@@ -681,7 +686,8 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
# Return the expected return codes for APIs with and without data
# with any specified status overriding the normal values
if expected_status is None:
- return (200, 201, 204)
+ return (http_client.OK, http_client.CREATED,
+ http_client.NO_CONTENT)
else:
return (expected_status, expected_status, expected_status)
@@ -948,7 +954,8 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
collection_url = self.build_role_assignment_query_url(
domain_id=self.domainB['id'])
- self.get(collection_url, auth=self.auth, expected_status=403)
+ self.get(collection_url, auth=self.auth,
+ expected_status=http_client.FORBIDDEN)
def test_domain_user_list_assignments_of_domain_failed(self):
self.auth = self.build_authentication_request(
@@ -958,7 +965,8 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
collection_url = self.build_role_assignment_query_url(
domain_id=self.domainA['id'])
- self.get(collection_url, auth=self.auth, expected_status=403)
+ self.get(collection_url, auth=self.auth,
+ expected_status=http_client.FORBIDDEN)
def test_cloud_admin_list_assignments_of_project(self):
self.auth = self.build_authentication_request(
@@ -986,7 +994,7 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
self.assertRoleAssignmentInListResponse(r, project_admin_entity)
self.assertRoleAssignmentInListResponse(r, project_user_entity)
- @tests.utils.wip('waiting on bug #1437407')
+ @unit.utils.wip('waiting on bug #1437407')
def test_domain_admin_list_assignments_of_project(self):
self.auth = self.build_authentication_request(
user_id=self.domain_admin_user['id'],
@@ -1021,7 +1029,8 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
collection_url = self.build_role_assignment_query_url(
project_id=self.project['id'])
- self.get(collection_url, auth=self.auth, expected_status=403)
+ self.get(collection_url, auth=self.auth,
+ expected_status=http_client.FORBIDDEN)
def test_cloud_admin(self):
self.auth = self.build_authentication_request(
@@ -1045,7 +1054,7 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
password=self.domain_admin_user['password'],
domain_id=self.domainA['id'])
entity_url = '/domains/%s' % self.domainA['id']
- self.get(entity_url, auth=self.auth, expected_status=200)
+ self.get(entity_url, auth=self.auth)
def test_list_user_credentials(self):
self.credential_user = self.new_credential_ref(self.just_a_user['id'])
@@ -1145,7 +1154,8 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
user2_token = self.get_requested_token(user2_auth)
self.get('/auth/tokens', token=user1_token,
- headers={'X-Subject-Token': user2_token}, expected_status=403)
+ headers={'X-Subject-Token': user2_token},
+ expected_status=http_client.FORBIDDEN)
def test_admin_validate_user_token(self):
# An admin can validate a user's token.
@@ -1176,7 +1186,8 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
token = self.get_requested_token(auth)
self.head('/auth/tokens', token=token,
- headers={'X-Subject-Token': token}, expected_status=200)
+ headers={'X-Subject-Token': token},
+ expected_status=http_client.OK)
def test_user_check_user_token(self):
# A user can check one of their own tokens.
@@ -1189,7 +1200,8 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
token2 = self.get_requested_token(auth)
self.head('/auth/tokens', token=token1,
- headers={'X-Subject-Token': token2}, expected_status=200)
+ headers={'X-Subject-Token': token2},
+ expected_status=http_client.OK)
def test_user_check_other_user_token_rejected(self):
# A user cannot check another user's token.
@@ -1207,7 +1219,7 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
self.head('/auth/tokens', token=user1_token,
headers={'X-Subject-Token': user2_token},
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_admin_check_user_token(self):
# An admin can check a user's token.
@@ -1225,7 +1237,8 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
user_token = self.get_requested_token(user_auth)
self.head('/auth/tokens', token=admin_token,
- headers={'X-Subject-Token': user_token}, expected_status=200)
+ headers={'X-Subject-Token': user_token},
+ expected_status=http_client.OK)
def test_user_revoke_same_token(self):
# Given a non-admin user token, the token can be used to revoke
@@ -1269,7 +1282,7 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
self.delete('/auth/tokens', token=user1_token,
headers={'X-Subject-Token': user2_token},
- expected_status=403)
+ expected_status=http_client.FORBIDDEN)
def test_admin_revoke_user_token(self):
# An admin can revoke a user's token.
diff --git a/keystone-moon/keystone/tests/unit/test_versions.py b/keystone-moon/keystone/tests/unit/test_versions.py
index 7f722f94..fc8051b2 100644
--- a/keystone-moon/keystone/tests/unit/test_versions.py
+++ b/keystone-moon/keystone/tests/unit/test_versions.py
@@ -20,11 +20,13 @@ import random
import mock
from oslo_config import cfg
from oslo_serialization import jsonutils
+from six.moves import http_client
from testtools import matchers as tt_matchers
+import webob
from keystone.common import json_home
from keystone import controllers
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import utils
@@ -170,6 +172,8 @@ BASE_ACCESS_TOKEN = (
# TODO(stevemar): Use BASE_IDP_PROTOCOL when bug 1420125 is resolved.
FEDERATED_AUTH_URL = ('/OS-FEDERATION/identity_providers/{identity_provider}'
'/protocols/{protocol}/auth')
+FEDERATED_IDP_SPECIFIC_WEBSSO = ('/auth/OS-FEDERATION/identity_providers/'
+ '{idp_id}/protocols/{protocol_id}/websso')
V3_JSON_HOME_RESOURCES_INHERIT_DISABLED = {
json_home.build_v3_resource_relation('auth_tokens'): {
@@ -345,13 +349,13 @@ V3_JSON_HOME_RESOURCES_INHERIT_DISABLED = {
'href-vars': {'user_id': json_home.Parameters.USER_ID, }},
json_home.build_v3_resource_relation('users'): {'href': '/users'},
_build_federation_rel(resource_name='domains'): {
- 'href': '/OS-FEDERATION/domains'},
+ 'href': '/auth/domains'},
_build_federation_rel(resource_name='websso'): {
'href-template': '/auth/OS-FEDERATION/websso/{protocol_id}',
'href-vars': {
'protocol_id': PROTOCOL_ID_PARAM_RELATION, }},
_build_federation_rel(resource_name='projects'): {
- 'href': '/OS-FEDERATION/projects'},
+ 'href': '/auth/projects'},
_build_federation_rel(resource_name='saml2'): {
'href': '/auth/OS-FEDERATION/saml2'},
_build_federation_rel(resource_name='ecp'): {
@@ -368,6 +372,11 @@ V3_JSON_HOME_RESOURCES_INHERIT_DISABLED = {
{
'href-template': '/OS-FEDERATION/identity_providers/{idp_id}',
'href-vars': {'idp_id': IDP_ID_PARAMETER_RELATION, }},
+ _build_federation_rel(resource_name='identity_providers'): {
+ 'href-template': FEDERATED_IDP_SPECIFIC_WEBSSO,
+ 'href-vars': {
+ 'idp_id': IDP_ID_PARAMETER_RELATION,
+ 'protocol_id': PROTOCOL_ID_PARAM_RELATION, }},
_build_federation_rel(resource_name='service_provider'):
{
'href-template': '/OS-FEDERATION/service_providers/{sp_id}',
@@ -614,6 +623,36 @@ V3_JSON_HOME_RESOURCES_INHERIT_ENABLED.update(
)
+class TestClient(object):
+ def __init__(self, app=None, token=None):
+ self.app = app
+ self.token = token
+
+ def request(self, method, path, headers=None, body=None):
+ if headers is None:
+ headers = {}
+
+ if self.token:
+ headers.setdefault('X-Auth-Token', self.token)
+
+ req = webob.Request.blank(path)
+ req.method = method
+ for k, v in headers.items():
+ req.headers[k] = v
+ if body:
+ req.body = body
+ return req.get_response(self.app)
+
+ def get(self, path, headers=None):
+ return self.request('GET', path=path, headers=headers)
+
+ def post(self, path, headers=None, body=None):
+ return self.request('POST', path=path, headers=headers, body=body)
+
+ def put(self, path, headers=None, body=None):
+ return self.request('PUT', path=path, headers=headers, body=body)
+
+
class _VersionsEqual(tt_matchers.MatchesListwise):
def __init__(self, expected):
super(_VersionsEqual, self).__init__([
@@ -632,7 +671,7 @@ class _VersionsEqual(tt_matchers.MatchesListwise):
])
-class VersionTestCase(tests.TestCase):
+class VersionTestCase(unit.TestCase):
def setUp(self):
super(VersionTestCase, self).setUp()
self.load_backends()
@@ -657,7 +696,7 @@ class VersionTestCase(tests.TestCase):
link['href'] = port
def test_public_versions(self):
- client = tests.TestClient(self.public_app)
+ client = TestClient(self.public_app)
resp = client.get('/')
self.assertEqual(300, resp.status_int)
data = jsonutils.loads(resp.body)
@@ -674,7 +713,7 @@ class VersionTestCase(tests.TestCase):
self.assertThat(data, _VersionsEqual(expected))
def test_admin_versions(self):
- client = tests.TestClient(self.admin_app)
+ client = TestClient(self.admin_app)
resp = client.get('/')
self.assertEqual(300, resp.status_int)
data = jsonutils.loads(resp.body)
@@ -694,7 +733,7 @@ class VersionTestCase(tests.TestCase):
self.config_fixture.config(public_endpoint=None, admin_endpoint=None)
for app in (self.public_app, self.admin_app):
- client = tests.TestClient(app)
+ client = TestClient(app)
resp = client.get('/')
self.assertEqual(300, resp.status_int)
data = jsonutils.loads(resp.body)
@@ -710,9 +749,9 @@ class VersionTestCase(tests.TestCase):
self.assertThat(data, _VersionsEqual(expected))
def test_public_version_v2(self):
- client = tests.TestClient(self.public_app)
+ client = TestClient(self.public_app)
resp = client.get('/v2.0/')
- self.assertEqual(200, resp.status_int)
+ self.assertEqual(http_client.OK, resp.status_int)
data = jsonutils.loads(resp.body)
expected = v2_VERSION_RESPONSE
self._paste_in_port(expected['version'],
@@ -721,9 +760,9 @@ class VersionTestCase(tests.TestCase):
self.assertEqual(expected, data)
def test_admin_version_v2(self):
- client = tests.TestClient(self.admin_app)
+ client = TestClient(self.admin_app)
resp = client.get('/v2.0/')
- self.assertEqual(200, resp.status_int)
+ self.assertEqual(http_client.OK, resp.status_int)
data = jsonutils.loads(resp.body)
expected = v2_VERSION_RESPONSE
self._paste_in_port(expected['version'],
@@ -734,18 +773,18 @@ class VersionTestCase(tests.TestCase):
def test_use_site_url_if_endpoint_unset_v2(self):
self.config_fixture.config(public_endpoint=None, admin_endpoint=None)
for app in (self.public_app, self.admin_app):
- client = tests.TestClient(app)
+ client = TestClient(app)
resp = client.get('/v2.0/')
- self.assertEqual(200, resp.status_int)
+ self.assertEqual(http_client.OK, resp.status_int)
data = jsonutils.loads(resp.body)
expected = v2_VERSION_RESPONSE
self._paste_in_port(expected['version'], 'http://localhost/v2.0/')
self.assertEqual(data, expected)
def test_public_version_v3(self):
- client = tests.TestClient(self.public_app)
+ client = TestClient(self.public_app)
resp = client.get('/v3/')
- self.assertEqual(200, resp.status_int)
+ self.assertEqual(http_client.OK, resp.status_int)
data = jsonutils.loads(resp.body)
expected = v3_VERSION_RESPONSE
self._paste_in_port(expected['version'],
@@ -755,9 +794,9 @@ class VersionTestCase(tests.TestCase):
@utils.wip('waiting on bug #1381961')
def test_admin_version_v3(self):
- client = tests.TestClient(self.admin_app)
+ client = TestClient(self.admin_app)
resp = client.get('/v3/')
- self.assertEqual(200, resp.status_int)
+ self.assertEqual(http_client.OK, resp.status_int)
data = jsonutils.loads(resp.body)
expected = v3_VERSION_RESPONSE
self._paste_in_port(expected['version'],
@@ -768,9 +807,9 @@ class VersionTestCase(tests.TestCase):
def test_use_site_url_if_endpoint_unset_v3(self):
self.config_fixture.config(public_endpoint=None, admin_endpoint=None)
for app in (self.public_app, self.admin_app):
- client = tests.TestClient(app)
+ client = TestClient(app)
resp = client.get('/v3/')
- self.assertEqual(200, resp.status_int)
+ self.assertEqual(http_client.OK, resp.status_int)
data = jsonutils.loads(resp.body)
expected = v3_VERSION_RESPONSE
self._paste_in_port(expected['version'], 'http://localhost/v3/')
@@ -778,14 +817,14 @@ class VersionTestCase(tests.TestCase):
@mock.patch.object(controllers, '_VERSIONS', ['v3'])
def test_v2_disabled(self):
- client = tests.TestClient(self.public_app)
+ client = TestClient(self.public_app)
# request to /v2.0 should fail
resp = client.get('/v2.0/')
- self.assertEqual(404, resp.status_int)
+ self.assertEqual(http_client.NOT_FOUND, resp.status_int)
# request to /v3 should pass
resp = client.get('/v3/')
- self.assertEqual(200, resp.status_int)
+ self.assertEqual(http_client.OK, resp.status_int)
data = jsonutils.loads(resp.body)
expected = v3_VERSION_RESPONSE
self._paste_in_port(expected['version'],
@@ -811,14 +850,14 @@ class VersionTestCase(tests.TestCase):
@mock.patch.object(controllers, '_VERSIONS', ['v2.0'])
def test_v3_disabled(self):
- client = tests.TestClient(self.public_app)
+ client = TestClient(self.public_app)
# request to /v3 should fail
resp = client.get('/v3/')
- self.assertEqual(404, resp.status_int)
+ self.assertEqual(http_client.NOT_FOUND, resp.status_int)
# request to /v2.0 should pass
resp = client.get('/v2.0/')
- self.assertEqual(200, resp.status_int)
+ self.assertEqual(http_client.OK, resp.status_int)
data = jsonutils.loads(resp.body)
expected = v2_VERSION_RESPONSE
self._paste_in_port(expected['version'],
@@ -843,7 +882,7 @@ class VersionTestCase(tests.TestCase):
self.assertEqual(v2_only_response, data)
def _test_json_home(self, path, exp_json_home_data):
- client = tests.TestClient(self.public_app)
+ client = TestClient(self.public_app)
resp = client.get(path, headers={'Accept': 'application/json-home'})
self.assertThat(resp.status, tt_matchers.Equals('200 OK'))
@@ -876,7 +915,7 @@ class VersionTestCase(tests.TestCase):
# Accept headers with multiple types and qvalues are handled.
def make_request(accept_types=None):
- client = tests.TestClient(self.public_app)
+ client = TestClient(self.public_app)
headers = None
if accept_types:
headers = {'Accept': accept_types}
@@ -926,7 +965,7 @@ class VersionTestCase(tests.TestCase):
self.assertIsNone(extensions_property)
-class VersionSingleAppTestCase(tests.TestCase):
+class VersionSingleAppTestCase(unit.TestCase):
"""Tests running with a single application loaded.
These are important because when Keystone is running in Apache httpd
@@ -962,7 +1001,7 @@ class VersionSingleAppTestCase(tests.TestCase):
else:
return CONF.eventlet_server.public_port
app = self.loadapp('keystone', app_name)
- client = tests.TestClient(app)
+ client = TestClient(app)
resp = client.get('/')
self.assertEqual(300, resp.status_int)
data = jsonutils.loads(resp.body)
@@ -983,7 +1022,7 @@ class VersionSingleAppTestCase(tests.TestCase):
self._test_version('admin')
-class VersionInheritEnabledTestCase(tests.TestCase):
+class VersionInheritEnabledTestCase(unit.TestCase):
def setUp(self):
super(VersionInheritEnabledTestCase, self).setUp()
self.load_backends()
@@ -1008,7 +1047,7 @@ class VersionInheritEnabledTestCase(tests.TestCase):
# If the request is /v3 and the Accept header is application/json-home
# then the server responds with a JSON Home document.
- client = tests.TestClient(self.public_app)
+ client = TestClient(self.public_app)
resp = client.get('/v3/', headers={'Accept': 'application/json-home'})
self.assertThat(resp.status, tt_matchers.Equals('200 OK'))
@@ -1022,7 +1061,7 @@ class VersionInheritEnabledTestCase(tests.TestCase):
tt_matchers.Equals(exp_json_home_data))
-class VersionBehindSslTestCase(tests.TestCase):
+class VersionBehindSslTestCase(unit.TestCase):
def setUp(self):
super(VersionBehindSslTestCase, self).setUp()
self.load_backends()
@@ -1048,7 +1087,7 @@ class VersionBehindSslTestCase(tests.TestCase):
return expected
def test_versions_without_headers(self):
- client = tests.TestClient(self.public_app)
+ client = TestClient(self.public_app)
host_name = 'host-%d' % random.randint(10, 30)
host_port = random.randint(10000, 30000)
host = 'http://%s:%s/' % (host_name, host_port)
@@ -1059,7 +1098,7 @@ class VersionBehindSslTestCase(tests.TestCase):
self.assertThat(data, _VersionsEqual(expected))
def test_versions_with_header(self):
- client = tests.TestClient(self.public_app)
+ client = TestClient(self.public_app)
host_name = 'host-%d' % random.randint(10, 30)
host_port = random.randint(10000, 30000)
resp = client.get('http://%s:%s/' % (host_name, host_port),
diff --git a/keystone-moon/keystone/tests/unit/test_wsgi.py b/keystone-moon/keystone/tests/unit/test_wsgi.py
index 62156bd5..2a5cb386 100644
--- a/keystone-moon/keystone/tests/unit/test_wsgi.py
+++ b/keystone-moon/keystone/tests/unit/test_wsgi.py
@@ -23,13 +23,14 @@ import mock
import oslo_i18n
from oslo_serialization import jsonutils
import six
+from six.moves import http_client
from testtools import matchers
import webob
from keystone.common import environment
from keystone.common import wsgi
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
class FakeApp(wsgi.Application):
@@ -52,7 +53,7 @@ class FakeAttributeCheckerApp(wsgi.Application):
self._require_attributes(ref, attr)
-class RouterTest(tests.TestCase):
+class RouterTest(unit.TestCase):
def setUp(self):
self.router = wsgi.RoutersBase()
super(RouterTest, self).setUp()
@@ -68,7 +69,7 @@ class RouterTest(tests.TestCase):
status=uuid.uuid4().hex)
-class BaseWSGITest(tests.TestCase):
+class BaseWSGITest(unit.TestCase):
def setUp(self):
self.app = FakeApp()
super(BaseWSGITest, self).setUp()
@@ -111,15 +112,16 @@ class ApplicationTest(BaseWSGITest):
resp = wsgi.render_response(body=data)
self.assertEqual('200 OK', resp.status)
- self.assertEqual(200, resp.status_int)
+ self.assertEqual(http_client.OK, resp.status_int)
self.assertEqual(body, resp.body)
self.assertEqual('X-Auth-Token', resp.headers.get('Vary'))
self.assertEqual(str(len(body)), resp.headers.get('Content-Length'))
def test_render_response_custom_status(self):
- resp = wsgi.render_response(status=(501, 'Not Implemented'))
+ resp = wsgi.render_response(
+ status=(http_client.NOT_IMPLEMENTED, 'Not Implemented'))
self.assertEqual('501 Not Implemented', resp.status)
- self.assertEqual(501, resp.status_int)
+ self.assertEqual(http_client.NOT_IMPLEMENTED, resp.status_int)
def test_successful_require_attribute(self):
app = FakeAttributeCheckerApp()
@@ -171,14 +173,14 @@ class ApplicationTest(BaseWSGITest):
def test_render_response_no_body(self):
resp = wsgi.render_response()
self.assertEqual('204 No Content', resp.status)
- self.assertEqual(204, resp.status_int)
+ self.assertEqual(http_client.NO_CONTENT, resp.status_int)
self.assertEqual(b'', resp.body)
self.assertEqual('0', resp.headers.get('Content-Length'))
self.assertIsNone(resp.headers.get('Content-Type'))
def test_render_response_head_with_body(self):
resp = wsgi.render_response({'id': uuid.uuid4().hex}, method='HEAD')
- self.assertEqual(200, resp.status_int)
+ self.assertEqual(http_client.OK, resp.status_int)
self.assertEqual(b'', resp.body)
self.assertNotEqual(resp.headers.get('Content-Length'), '0')
self.assertEqual('application/json', resp.headers.get('Content-Type'))
@@ -195,14 +197,14 @@ class ApplicationTest(BaseWSGITest):
def test_render_exception(self):
e = exception.Unauthorized(message=u'\u7f51\u7edc')
resp = wsgi.render_exception(e)
- self.assertEqual(401, resp.status_int)
+ self.assertEqual(http_client.UNAUTHORIZED, resp.status_int)
def test_render_exception_host(self):
e = exception.Unauthorized(message=u'\u7f51\u7edc')
context = {'host_url': 'http://%s:5000' % uuid.uuid4().hex}
resp = wsgi.render_exception(e, context=context)
- self.assertEqual(401, resp.status_int)
+ self.assertEqual(http_client.UNAUTHORIZED, resp.status_int)
def test_improperly_encoded_params(self):
class FakeApp(wsgi.Application):
@@ -311,7 +313,7 @@ class MiddlewareTest(BaseWSGITest):
self.assertEqual("test", app.kwargs["testkey"])
-class LocalizedResponseTest(tests.TestCase):
+class LocalizedResponseTest(unit.TestCase):
def test_request_match_default(self):
# The default language if no Accept-Language is provided is None
req = webob.Request.blank('/')
@@ -409,7 +411,7 @@ class LocalizedResponseTest(tests.TestCase):
self.assertThat(xlation_mock.called, matchers.Equals(True))
-class ServerTest(tests.TestCase):
+class ServerTest(unit.TestCase):
def setUp(self):
super(ServerTest, self).setUp()
diff --git a/keystone-moon/keystone/tests/unit/tests/test_core.py b/keystone-moon/keystone/tests/unit/tests/test_core.py
index 2de51c52..50f1309e 100644
--- a/keystone-moon/keystone/tests/unit/tests/test_core.py
+++ b/keystone-moon/keystone/tests/unit/tests/test_core.py
@@ -19,28 +19,28 @@ from oslo_log import log
from sqlalchemy import exc
from testtools import matchers
-from keystone.tests import unit as tests
+from keystone.tests import unit
LOG = log.getLogger(__name__)
-class BaseTestTestCase(tests.BaseTestCase):
+class BaseTestTestCase(unit.BaseTestCase):
def test_unexpected_exit(self):
# if a test calls sys.exit it raises rather than exiting.
self.assertThat(lambda: sys.exit(),
- matchers.raises(tests.UnexpectedExit))
+ matchers.raises(unit.UnexpectedExit))
-class TestTestCase(tests.TestCase):
+class TestTestCase(unit.TestCase):
def test_bad_log(self):
# If the arguments are invalid for the string in a log it raises an
# exception during testing.
self.assertThat(
lambda: LOG.warn('String %(p1)s %(p2)s', {'p1': 'something'}),
- matchers.raises(tests.BadLog))
+ matchers.raises(KeyError))
def test_sa_warning(self):
self.assertThat(
diff --git a/keystone-moon/keystone/tests/unit/token/test_fernet_provider.py b/keystone-moon/keystone/tests/unit/token/test_fernet_provider.py
index 4101369c..5f74b430 100644
--- a/keystone-moon/keystone/tests/unit/token/test_fernet_provider.py
+++ b/keystone-moon/keystone/tests/unit/token/test_fernet_provider.py
@@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import base64
import datetime
import hashlib
import os
@@ -20,7 +21,7 @@ from oslo_utils import timeutils
from keystone.common import config
from keystone.common import utils
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.tests.unit import ksfixtures
from keystone.token import provider
from keystone.token.providers import fernet
@@ -31,7 +32,7 @@ from keystone.token.providers.fernet import utils as fernet_utils
CONF = config.CONF
-class TestFernetTokenProvider(tests.TestCase):
+class TestFernetTokenProvider(unit.TestCase):
def setUp(self):
super(TestFernetTokenProvider, self).setUp()
self.useFixture(ksfixtures.KeyRepository(self.config_fixture))
@@ -56,7 +57,24 @@ class TestFernetTokenProvider(tests.TestCase):
uuid.uuid4().hex)
-class TestPayloads(tests.TestCase):
+class TestTokenFormatter(unit.TestCase):
+ def test_restore_padding(self):
+ # 'a' will result in '==' padding, 'aa' will result in '=' padding, and
+ # 'aaa' will result in no padding.
+ strings_to_test = ['a', 'aa', 'aaa']
+
+ for string in strings_to_test:
+ encoded_string = base64.urlsafe_b64encode(string)
+ encoded_str_without_padding = encoded_string.rstrip('=')
+ self.assertFalse(encoded_str_without_padding.endswith('='))
+ encoded_str_with_padding_restored = (
+ token_formatters.TokenFormatter.restore_padding(
+ encoded_str_without_padding)
+ )
+ self.assertEqual(encoded_string, encoded_str_with_padding_restored)
+
+
+class TestPayloads(unit.TestCase):
def test_uuid_hex_to_byte_conversions(self):
payload_cls = token_formatters.BasePayload
@@ -387,7 +405,7 @@ class TestPayloads(tests.TestCase):
self.assertDictEqual(exp_federated_info, federated_info)
-class TestFernetKeyRotation(tests.TestCase):
+class TestFernetKeyRotation(unit.TestCase):
def setUp(self):
super(TestFernetKeyRotation, self).setUp()
@@ -512,7 +530,7 @@ class TestFernetKeyRotation(tests.TestCase):
self.assertEqual(3, keys)
-class TestLoadKeys(tests.TestCase):
+class TestLoadKeys(unit.TestCase):
def test_non_numeric_files(self):
self.useFixture(ksfixtures.KeyRepository(self.config_fixture))
evil_file = os.path.join(CONF.fernet_tokens.key_repository, '~1')
diff --git a/keystone-moon/keystone/tests/unit/token/test_pki_provider.py b/keystone-moon/keystone/tests/unit/token/test_pki_provider.py
index dad31266..b3ad4c2b 100644
--- a/keystone-moon/keystone/tests/unit/token/test_pki_provider.py
+++ b/keystone-moon/keystone/tests/unit/token/test_pki_provider.py
@@ -10,11 +10,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.token.providers import pki
-class TestPkiTokenProvider(tests.TestCase):
+class TestPkiTokenProvider(unit.TestCase):
def setUp(self):
super(TestPkiTokenProvider, self).setUp()
self.provider = pki.Provider()
diff --git a/keystone-moon/keystone/tests/unit/token/test_pkiz_provider.py b/keystone-moon/keystone/tests/unit/token/test_pkiz_provider.py
index 4a492bc1..1ffe7cfc 100644
--- a/keystone-moon/keystone/tests/unit/token/test_pkiz_provider.py
+++ b/keystone-moon/keystone/tests/unit/token/test_pkiz_provider.py
@@ -10,11 +10,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.token.providers import pkiz
-class TestPkizTokenProvider(tests.TestCase):
+class TestPkizTokenProvider(unit.TestCase):
def setUp(self):
super(TestPkizTokenProvider, self).setUp()
self.provider = pkiz.Provider()
diff --git a/keystone-moon/keystone/tests/unit/token/test_token_data_helper.py b/keystone-moon/keystone/tests/unit/token/test_token_data_helper.py
index a12a22d4..6114b723 100644
--- a/keystone-moon/keystone/tests/unit/token/test_token_data_helper.py
+++ b/keystone-moon/keystone/tests/unit/token/test_token_data_helper.py
@@ -16,11 +16,11 @@ import uuid
from testtools import matchers
from keystone import exception
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.token.providers import common
-class TestTokenDataHelper(tests.TestCase):
+class TestTokenDataHelper(unit.TestCase):
def setUp(self):
super(TestTokenDataHelper, self).setUp()
self.load_backends()
diff --git a/keystone-moon/keystone/tests/unit/token/test_token_model.py b/keystone-moon/keystone/tests/unit/token/test_token_model.py
index 3959d901..f1398491 100644
--- a/keystone-moon/keystone/tests/unit/token/test_token_model.py
+++ b/keystone-moon/keystone/tests/unit/token/test_token_model.py
@@ -30,7 +30,6 @@ CONF = cfg.CONF
class TestKeystoneTokenModel(core.TestCase):
def setUp(self):
super(TestKeystoneTokenModel, self).setUp()
- self.load_backends()
self.v2_sample_token = copy.deepcopy(
test_token_provider.SAMPLE_V2_TOKEN)
self.v3_sample_token = copy.deepcopy(
diff --git a/keystone-moon/keystone/tests/unit/token/test_uuid_provider.py b/keystone-moon/keystone/tests/unit/token/test_uuid_provider.py
index b49427f0..5c364490 100644
--- a/keystone-moon/keystone/tests/unit/token/test_uuid_provider.py
+++ b/keystone-moon/keystone/tests/unit/token/test_uuid_provider.py
@@ -10,11 +10,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-from keystone.tests import unit as tests
+from keystone.tests import unit
from keystone.token.providers import uuid
-class TestUuidTokenProvider(tests.TestCase):
+class TestUuidTokenProvider(unit.TestCase):
def setUp(self):
super(TestUuidTokenProvider, self).setUp()
self.provider = uuid.Provider()