Merge "Keep py3.X compatibility for urllib"
diff --git a/tempest/common/cred_client.py b/tempest/common/cred_client.py
index 37c9727..b23bc6f 100644
--- a/tempest/common/cred_client.py
+++ b/tempest/common/cred_client.py
@@ -170,6 +170,29 @@
user['id'],
role['id'])
+ def assign_user_role_on_domain(self, user, role_name, domain=None):
+ """Assign the specified role on a domain
+
+ :param user: a user dict
+ :param role_name: name of the role to be assigned
+ :param domain: (optional) The domain to assign the role on. If not
+ specified the default domain of cred_client
+ """
+ # NOTE(andreaf) This method is very specific to the v3 case, and
+ # because of that it's not defined in the parent class.
+ if domain is None:
+ domain = self.creds_domain
+ role = self._check_role_exists(role_name)
+ if not role:
+ msg = 'No "%s" role found' % role_name
+ raise lib_exc.NotFound(msg)
+ try:
+ self.roles_client.assign_user_role_on_domain(
+ domain['id'], user['id'], role['id'])
+ except lib_exc.Conflict:
+ LOG.debug("Role %s already assigned on domain %s for user %s",
+ role['id'], domain['id'], user['id'])
+
def get_creds_client(identity_client,
projects_client,
diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py
index a63af38..e5d65f5 100644
--- a/tempest/common/dynamic_creds.py
+++ b/tempest/common/dynamic_creds.py
@@ -134,6 +134,9 @@
self.creds_client.assign_user_role(user, project,
self.admin_role)
role_assigned = True
+ if self.identity_version == 'v3':
+ self.creds_client.assign_user_role_on_domain(
+ user, CONF.identity.admin_role)
# Add roles specified in config file
for conf_role in CONF.auth.tempest_roles:
self.creds_client.assign_user_role(user, project, conf_role)
diff --git a/tempest/lib/common/rest_client.py b/tempest/lib/common/rest_client.py
index 179db17..627143d 100644
--- a/tempest/lib/common/rest_client.py
+++ b/tempest/lib/common/rest_client.py
@@ -221,6 +221,10 @@
:raises exceptions.InvalidHttpSuccessCode: if the read code isn't an
expected http success code
"""
+ if not isinstance(read_code, int):
+ raise TypeError("'read_code' must be an int instead of (%s)"
+ % type(read_code))
+
assert_msg = ("This function only allowed to use for HTTP status"
"codes which explicitly defined in the RFC 7231 & 4918."
"{0} is not a defined Success Code!"
diff --git a/tempest/lib/decorators.py b/tempest/lib/decorators.py
index e78e624..6ed99b4 100644
--- a/tempest/lib/decorators.py
+++ b/tempest/lib/decorators.py
@@ -69,12 +69,11 @@
"or False") % attr
def __call__(self, func):
+ @functools.wraps(func)
def _skipper(*args, **kw):
"""Wrapped skipper function."""
testobj = args[0]
if not getattr(testobj, self.attr, False):
raise testtools.TestCase.skipException(self.message)
func(*args, **kw)
- _skipper.__name__ = func.__name__
- _skipper.__doc__ = func.__doc__
return _skipper
diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
index 8d4f33b..f025418 100644
--- a/tempest/tests/common/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -21,15 +21,19 @@
from tempest import config
from tempest import exceptions
from tempest.lib.common import rest_client
-from tempest.lib.services.identity.v2 import token_client as json_token_client
-from tempest.services.identity.v2.json import identity_client as \
- json_iden_client
-from tempest.services.identity.v2.json import roles_client as \
- json_roles_client
+from tempest.lib.services.identity.v2 import token_client as v2_token_client
+from tempest.lib.services.identity.v3 import token_client as v3_token_client
+from tempest.services.identity.v2.json import identity_client as v2_iden_client
+from tempest.services.identity.v2.json import roles_client as v2_roles_client
from tempest.services.identity.v2.json import tenants_client as \
- json_tenants_client
-from tempest.services.identity.v2.json import users_client as \
- json_users_client
+ v2_tenants_client
+from tempest.services.identity.v2.json import users_client as v2_users_client
+from tempest.services.identity.v3.json import domains_client
+from tempest.services.identity.v3.json import identity_client as v3_iden_client
+from tempest.services.identity.v3.json import projects_client as \
+ v3_projects_client
+from tempest.services.identity.v3.json import roles_client as v3_roles_client
+from tempest.services.identity.v3.json import users_clients as v3_users_client
from tempest.services.network.json import routers_client
from tempest.tests import base
from tempest.tests import fake_config
@@ -43,13 +47,24 @@
'identity_version': 'v2',
'admin_role': 'admin'}
+ token_client = v2_token_client
+ iden_client = v2_iden_client
+ roles_client = v2_roles_client
+ tenants_client = v2_tenants_client
+ users_client = v2_users_client
+ token_client_class = token_client.TokenClient
+ fake_response = fake_identity._fake_v2_response
+ assign_role_on_project = 'assign_user_role'
+ tenants_client_class = tenants_client.TenantsClient
+ delete_tenant = 'delete_tenant'
+
def setUp(self):
super(TestDynamicCredentialProvider, self).setUp()
self.useFixture(fake_config.ConfigFixture())
self.patchobject(config, 'TempestConfigPrivate',
fake_config.FakePrivate)
- self.patchobject(json_token_client.TokenClient, 'raw_request',
- fake_identity._fake_v2_response)
+ self.patchobject(self.token_client_class, 'raw_request',
+ self.fake_response)
cfg.CONF.set_default('operator_role', 'FakeRole',
group='object-storage')
self._mock_list_ec2_credentials('fake_user_id', 'fake_tenant_id')
@@ -59,7 +74,7 @@
def test_tempest_client(self):
creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
self.assertIsInstance(creds.identity_admin_client,
- json_iden_client.IdentityClient)
+ self.iden_client.IdentityClient)
def _get_fake_admin_creds(self):
return credentials.get_credentials(
@@ -70,7 +85,7 @@
def _mock_user_create(self, id, name):
user_fix = self.useFixture(mockpatch.PatchObject(
- json_users_client.UsersClient,
+ self.users_client.UsersClient,
'create_user',
return_value=(rest_client.ResponseBody
(200, {'user': {'id': id, 'name': name}}))))
@@ -78,7 +93,7 @@
def _mock_tenant_create(self, id, name):
tenant_fix = self.useFixture(mockpatch.PatchObject(
- json_tenants_client.TenantsClient,
+ self.tenants_client.TenantsClient,
'create_tenant',
return_value=(rest_client.ResponseBody
(200, {'tenant': {'id': id, 'name': name}}))))
@@ -86,7 +101,7 @@
def _mock_list_roles(self, id, name):
roles_fix = self.useFixture(mockpatch.PatchObject(
- json_roles_client.RolesClient,
+ self.roles_client.RolesClient,
'list_roles',
return_value=(rest_client.ResponseBody
(200,
@@ -97,7 +112,7 @@
def _mock_list_2_roles(self):
roles_fix = self.useFixture(mockpatch.PatchObject(
- json_roles_client.RolesClient,
+ self.roles_client.RolesClient,
'list_roles',
return_value=(rest_client.ResponseBody
(200,
@@ -108,24 +123,25 @@
def _mock_assign_user_role(self):
tenant_fix = self.useFixture(mockpatch.PatchObject(
- json_roles_client.RolesClient,
- 'assign_user_role',
+ self.roles_client.RolesClient,
+ self.assign_role_on_project,
return_value=(rest_client.ResponseBody
(200, {}))))
return tenant_fix
def _mock_list_role(self):
roles_fix = self.useFixture(mockpatch.PatchObject(
- json_roles_client.RolesClient,
+ self.roles_client.RolesClient,
'list_roles',
return_value=(rest_client.ResponseBody
- (200, {'roles': [{'id': '1',
- 'name': 'FakeRole'}]}))))
+ (200, {'roles': [
+ {'id': '1', 'name': 'FakeRole'},
+ {'id': '2', 'name': 'Member'}]}))))
return roles_fix
def _mock_list_ec2_credentials(self, user_id, tenant_id):
ec2_creds_fix = self.useFixture(mockpatch.PatchObject(
- json_users_client.UsersClient,
+ self.users_client.UsersClient,
'list_user_ec2_credentials',
return_value=(rest_client.ResponseBody
(200, {'credentials': [{
@@ -180,12 +196,12 @@
self._mock_user_create('1234', 'fake_admin_user')
self._mock_tenant_create('1234', 'fake_admin_tenant')
- user_mock = mock.patch.object(json_roles_client.RolesClient,
- 'assign_user_role')
+ user_mock = mock.patch.object(self.roles_client.RolesClient,
+ self.assign_role_on_project)
user_mock.start()
self.addCleanup(user_mock.stop)
- with mock.patch.object(json_roles_client.RolesClient,
- 'assign_user_role') as user_mock:
+ with mock.patch.object(self.roles_client.RolesClient,
+ self.assign_role_on_project) as user_mock:
admin_creds = creds.get_admin_creds()
user_mock.assert_has_calls([
mock.call('1234', '1234', '1234')])
@@ -203,12 +219,12 @@
self._mock_user_create('1234', 'fake_role_user')
self._mock_tenant_create('1234', 'fake_role_tenant')
- user_mock = mock.patch.object(json_roles_client.RolesClient,
- 'assign_user_role')
+ user_mock = mock.patch.object(self.roles_client.RolesClient,
+ self.assign_role_on_project)
user_mock.start()
self.addCleanup(user_mock.stop)
- with mock.patch.object(json_roles_client.RolesClient,
- 'assign_user_role') as user_mock:
+ with mock.patch.object(self.roles_client.RolesClient,
+ self.assign_role_on_project) as user_mock:
role_creds = creds.get_creds_by_roles(
roles=['role1', 'role2'])
calls = user_mock.mock_calls
@@ -240,12 +256,10 @@
self._mock_user_create('123456', 'fake_admin_user')
self._mock_list_roles('123456', 'admin')
creds.get_admin_creds()
- user_mock = self.patch(
- 'tempest.services.identity.v2.json.users_client.'
- 'UsersClient.delete_user')
- tenant_mock = self.patch(
- 'tempest.services.identity.v2.json.tenants_client.'
- 'TenantsClient.delete_tenant')
+ user_mock = self.patchobject(self.users_client.UsersClient,
+ 'delete_user')
+ tenant_mock = self.patchobject(self.tenants_client_class,
+ self.delete_tenant)
creds.clear_creds()
# Verify user delete calls
calls = user_mock.mock_calls
@@ -374,18 +388,13 @@
self._mock_router_create('123456', 'fake_admin_router')
self._mock_list_roles('123456', 'admin')
creds.get_admin_creds()
- self.patch('tempest.services.identity.v2.json.users_client.'
- 'UsersClient.delete_user')
- self.patch('tempest.services.identity.v2.json.tenants_client.'
- 'TenantsClient.delete_tenant')
- net = mock.patch.object(creds.networks_admin_client,
- 'delete_network')
+ self.patchobject(self.users_client.UsersClient, 'delete_user')
+ self.patchobject(self.tenants_client_class, self.delete_tenant)
+ net = mock.patch.object(creds.networks_admin_client, 'delete_network')
net_mock = net.start()
- subnet = mock.patch.object(creds.subnets_admin_client,
- 'delete_subnet')
+ subnet = mock.patch.object(creds.subnets_admin_client, 'delete_subnet')
subnet_mock = subnet.start()
- router = mock.patch.object(creds.routers_admin_client,
- 'delete_router')
+ router = mock.patch.object(creds.routers_admin_client, 'delete_router')
router_mock = router.start()
remove_router_interface_mock = self.patch(
'tempest.services.network.json.routers_client.RoutersClient.'
@@ -587,3 +596,42 @@
self._mock_tenant_create('1234', 'fake_prim_tenant')
self.assertRaises(exceptions.InvalidConfiguration,
creds.get_primary_creds)
+
+
+class TestDynamicCredentialProviderV3(TestDynamicCredentialProvider):
+
+ fixed_params = {'name': 'test class',
+ 'identity_version': 'v3',
+ 'admin_role': 'admin'}
+
+ token_client = v3_token_client
+ iden_client = v3_iden_client
+ roles_client = v3_roles_client
+ tenants_client = v3_projects_client
+ users_client = v3_users_client
+ token_client_class = token_client.V3TokenClient
+ fake_response = fake_identity._fake_v3_response
+ assign_role_on_project = 'assign_user_role_on_project'
+ tenants_client_class = tenants_client.ProjectsClient
+ delete_tenant = 'delete_project'
+
+ def setUp(self):
+ super(TestDynamicCredentialProviderV3, self).setUp()
+ self.useFixture(fake_config.ConfigFixture())
+ self.useFixture(mockpatch.PatchObject(
+ domains_client.DomainsClient, 'list_domains',
+ return_value=dict(domains=[dict(id='default',
+ name='Default')])))
+ self.patchobject(self.roles_client.RolesClient,
+ 'assign_user_role_on_domain')
+
+ def _mock_list_ec2_credentials(self, user_id, tenant_id):
+ pass
+
+ def _mock_tenant_create(self, id, name):
+ project_fix = self.useFixture(mockpatch.PatchObject(
+ self.tenants_client.ProjectsClient,
+ 'create_project',
+ return_value=(rest_client.ResponseBody
+ (200, {'project': {'id': id, 'name': name}}))))
+ return project_fix
diff --git a/tempest/tests/lib/test_rest_client.py b/tempest/tests/lib/test_rest_client.py
index 2a6fad5..106a1e5 100644
--- a/tempest/tests/lib/test_rest_client.py
+++ b/tempest/tests/lib/test_rest_client.py
@@ -693,6 +693,24 @@
self.assertRaises(AssertionError, self.rest_client.expected_success,
expected_code, read_code)
+ def test_non_success_read_code_as_string(self):
+ expected_code = 202
+ read_code = '202'
+ self.assertRaises(TypeError, self.rest_client.expected_success,
+ expected_code, read_code)
+
+ def test_non_success_read_code_as_list(self):
+ expected_code = 202
+ read_code = [202]
+ self.assertRaises(TypeError, self.rest_client.expected_success,
+ expected_code, read_code)
+
+ def test_non_success_expected_code_as_non_int(self):
+ expected_code = ['201', 202]
+ read_code = 202
+ self.assertRaises(AssertionError, self.rest_client.expected_success,
+ expected_code, read_code)
+
class TestResponseBody(base.TestCase):