Merge "Test glance distributed import"
diff --git a/releasenotes/notes/add-alt-project-dynamic-creds-1a3bc543e65d9433.yaml b/releasenotes/notes/add-alt-project-dynamic-creds-1a3bc543e65d9433.yaml
new file mode 100644
index 0000000..de81b2b
--- /dev/null
+++ b/releasenotes/notes/add-alt-project-dynamic-creds-1a3bc543e65d9433.yaml
@@ -0,0 +1,4 @@
+---
+features:
+ - |
+ Add project alternate admin, member and reader role for dynamic credentials.
diff --git a/releasenotes/notes/intermediate-wallaby-release-55a0b31b1dee7b23.yaml b/releasenotes/notes/intermediate-wallaby-release-55a0b31b1dee7b23.yaml
new file mode 100644
index 0000000..cda3b89
--- /dev/null
+++ b/releasenotes/notes/intermediate-wallaby-release-55a0b31b1dee7b23.yaml
@@ -0,0 +1,4 @@
+---
+prelude: >
+ This is an intermediate release during the Wallaby development cycle to
+ make new functionality available to plugins and other consumers.
diff --git a/releasenotes/notes/support-scope-in-get-roles-dynamic-creds-90bfab163c1c289a.yaml b/releasenotes/notes/support-scope-in-get-roles-dynamic-creds-90bfab163c1c289a.yaml
new file mode 100644
index 0000000..26282f0
--- /dev/null
+++ b/releasenotes/notes/support-scope-in-get-roles-dynamic-creds-90bfab163c1c289a.yaml
@@ -0,0 +1,36 @@
+---
+features:
+ - |
+ Dynamic credentials now support the scope type for specific roles
+ too along with ``admin``, ``member``, ``reader`` role.
+ Test can specify the scope in the prefix of ``cls.credentials`` name.
+ If ``system`` is prefix in ``cls.credentials`` name then creds will
+ be created with scope as ``system``. If ``domain`` is prefix in
+ ``cls.credentials`` name then creds will be created with scope as
+ ``domain`` otherwise default ``project`` scope will be used.
+ For Example::
+
+ credentials = [['my_role', 'role1'], # this will be old style and project scoped
+ ['project_my_role', 'role1'], # this will be project scoped
+ ['domain_my_role', 'role1'], # this will be domain scoped
+ ['system_my_role', 'role1']] # this will be system scoped
+
+ And below is how test can access the credential manager of respective
+ credentials type::
+
+ cls.os_my_role.any_client
+ cls.os_project_my_role.any_client
+ cls.os_domain_my_role.any_client
+ cls.os_system_my_role.any_client
+
+
+ For backward compatibility, we set the credentials manager class attribute
+ in old style form too which is prefix with ``os_roles_*``, example
+ ``cls.os_roles_my_role`` but we recommend to use the new style attribute
+ as shown above.
+issues:
+ - |
+ Scope support for specific role is not yet added for pre-provisioned credentials.
+fixes:
+ - |
+ Fixes the `bug# 1917168 <https://bugs.launchpad.net/tempest/+bug/1917168>`_
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index 941315e..52ccea7 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -169,8 +169,13 @@
block_migrate_cinder_iscsi,
'Block Live migration not configured for iSCSI')
@utils.services('volume')
- def test_iscsi_volume(self):
- """Test live migrating a server with volume attached"""
+ def test_live_block_migration_with_attached_volume(self):
+ """Test the live-migration of an instance with an attached volume.
+
+ This tests the live-migration of an instance with both a local disk and
+ attach volume. This differs from test_volume_backed_live_migration
+ above that tests live-migration with only an attached volume.
+ """
server = self.create_test_server(wait_until="ACTIVE")
server_id = server['id']
if not CONF.compute_feature_enabled.can_migrate_between_any_hosts:
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 102792e..ac18442 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -16,7 +16,6 @@
import time
from oslo_log import log
-import six
from tempest.api.compute import base
from tempest.common import compute
@@ -241,7 +240,7 @@
except lib_exc.BadRequest as e:
msg = ('Multiple possible networks found, use a Network ID to be '
'more specific.')
- if not CONF.compute.fixed_network_name and six.text_type(e) == msg:
+ if not CONF.compute.fixed_network_name and str(e) == msg:
raise
else:
ifs.append(iface)
@@ -450,7 +449,7 @@
except lib_exc.BadRequest as e:
msg = ('Multiple possible networks found, use a Network ID to be '
'more specific.')
- if not CONF.compute.fixed_network_name and six.text_type(e) == msg:
+ if not CONF.compute.fixed_network_name and str(e) == msg:
raise
else:
# just to check the response schema
diff --git a/tempest/api/compute/servers/test_novnc.py b/tempest/api/compute/servers/test_novnc.py
index 34b3146..a9c0e56 100644
--- a/tempest/api/compute/servers/test_novnc.py
+++ b/tempest/api/compute/servers/test_novnc.py
@@ -69,7 +69,7 @@
resp = urllib3.PoolManager().request('GET', vnc_url)
# Make sure that the GET request was accepted by the novncproxy
self.assertEqual(resp.status, 200, 'Got a Bad HTTP Response on the '
- 'initial call: ' + six.text_type(resp.status))
+ 'initial call: ' + str(resp.status))
# Do some basic validation to make sure it is an expected HTML document
resp_data = resp.data.decode()
# This is needed in the case of example: <html lang="en">
@@ -165,11 +165,11 @@
self._websocket.response.startswith(b'HTTP/1.1 101 Switching '
b'Protocols'),
'Incorrect HTTP return status code: {}'.format(
- six.text_type(self._websocket.response)
+ str(self._websocket.response)
)
)
_required_header = 'upgrade: websocket'
- _response = six.text_type(self._websocket.response).lower()
+ _response = str(self._websocket.response).lower()
self.assertIn(
_required_header,
_response,
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index f3a7471..5bbd65c 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import six
-
from tempest.api.identity import base
from tempest import config
from tempest.lib.common.utils import data_utils
@@ -70,8 +68,8 @@
orig_expires_at = token_auth['token']['expires_at']
orig_user = token_auth['token']['user']
- self.assertIsInstance(token_auth['token']['expires_at'], six.text_type)
- self.assertIsInstance(token_auth['token']['issued_at'], six.text_type)
+ self.assertIsInstance(token_auth['token']['expires_at'], str)
+ self.assertIsInstance(token_auth['token']['issued_at'], str)
self.assertEqual(['password'], token_auth['token']['methods'])
self.assertEqual(user['id'], token_auth['token']['user']['id'])
self.assertEqual(user['name'], token_auth['token']['user']['name'])
@@ -91,7 +89,7 @@
self.assertEqual(orig_expires_at, token_auth['token']['expires_at'],
'Expiration time should match original token')
- self.assertIsInstance(token_auth['token']['issued_at'], six.text_type)
+ self.assertIsInstance(token_auth['token']['issued_at'], str)
self.assertEqual(set(['password', 'token']),
set(token_auth['token']['methods']))
self.assertEqual(orig_user, token_auth['token']['user'],
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 479578d..63078cd 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -16,7 +16,6 @@
import ipaddress
import netaddr
-import six
import testtools
from tempest.api.network import base_security_groups as sec_base
@@ -234,15 +233,15 @@
# Get two IP addresses
ip_address_1 = None
ip_address_2 = None
- ip_network = ipaddress.ip_network(six.text_type(subnet['cidr']))
+ ip_network = ipaddress.ip_network(str(subnet['cidr']))
for ip in ip_network:
if ip == ip_network.network_address:
continue
if ip_address_1 is None:
- ip_address_1 = six.text_type(ip)
+ ip_address_1 = str(ip)
else:
ip_address_2 = ip_address_1
- ip_address_1 = six.text_type(ip)
+ ip_address_1 = str(ip)
# Make sure these two IP addresses have different substring
if ip_address_1[:-1] != ip_address_2[:-1]:
break
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index e8f3f8b..478a834 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -13,12 +13,9 @@
# License for the specific language governing permissions and limitations
# under the License.
-import time
-
from tempest.common import custom_matchers
from tempest import config
from tempest.lib.common.utils import data_utils
-from tempest.lib.common.utils import test_utils
from tempest.lib import exceptions as lib_exc
import tempest.test
@@ -50,12 +47,11 @@
_, objlist = container_client.list_container_objects(cont, params)
# delete every object in the container
for obj in objlist:
- test_utils.call_and_ignore_notfound_exc(
- object_client.delete_object, cont, obj['name'])
- # sleep 2 seconds to sync the deletion of the objects
- # in HA deployment
- time.sleep(2)
+ object_client.delete_object(cont, obj['name'])
+ object_client.wait_for_resource_deletion(obj['name'], cont)
+ # Verify resource deletion
container_client.delete_container(cont)
+ container_client.wait_for_resource_deletion(cont)
except lib_exc.NotFound:
pass
diff --git a/tempest/api/object_storage/test_account_services.py b/tempest/api/object_storage/test_account_services.py
index da8ad66..ffea6f6 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -62,7 +62,7 @@
self.assertIsNotNone(container_list)
for container_name in self.containers:
- self.assertIn(six.text_type(container_name).encode('utf-8'),
+ self.assertIn(str(container_name).encode('utf-8'),
container_list)
@decorators.idempotent_id('884ec421-fbad-4fcc-916b-0580f2699565')
diff --git a/tempest/cmd/subunit_describe_calls.py b/tempest/cmd/subunit_describe_calls.py
index 172fbaa..6c36d82 100644
--- a/tempest/cmd/subunit_describe_calls.py
+++ b/tempest/cmd/subunit_describe_calls.py
@@ -40,12 +40,14 @@
subunit-describe-calls will take in either stdin subunit v1 or v2 stream or a
file path which contains either a subunit v1 or v2 stream passed via the
---subunit parameter. This is then parsed checking for details contained in the
-file_bytes of the --non-subunit-name parameter (the default is pythonlogging
-which is what Tempest uses to store logs). By default the OpenStack Kilo
-release port defaults (http://bit.ly/22jpF5P) are used unless a file is
-provided via the --ports option. The resulting output is dumped in JSON output
-to the path provided in the --output-file option.
+``--subunit`` parameter. This is then parsed checking for details contained in
+the file_bytes of the ``--non-subunit-name`` parameter (the default is
+pythonlogging which is what Tempest uses to store logs). By default `the
+OpenStack default ports
+<https://docs.openstack.org/install-guide/firewalls-default-ports.html>`_
+are used unless a file is provided via the ``--ports`` option. The resulting
+output is dumped in JSON output to the path provided in the ``--output-file``
+option.
Ports file JSON structure
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -110,9 +112,8 @@
response_re = re.compile(r'.* Response - Headers: (?P<headers>.*)')
body_re = re.compile(r'.*Body: (?P<body>.*)')
- # Based on newton defaults:
- # http://docs.openstack.org/newton/config-reference/
- # firewalls-default-ports.html
+ # Based on OpenStack default ports:
+ # https://docs.openstack.org/install-guide/firewalls-default-ports.html
services = {
"8776": "Block Storage",
"8774": "Nova",
@@ -131,7 +132,10 @@
"3260": "iSCSI",
"3306": "MySQL",
"5672": "AMQP",
- "8082": "murano"}
+ "8082": "murano",
+ "8778": "Clustering",
+ "8999": "Vitrage",
+ "8989": "Mistral"}
def __init__(self, services=None):
super(UrlParser, self).__init__()
diff --git a/tempest/lib/common/cred_provider.py b/tempest/lib/common/cred_provider.py
index 35bca1d..069172a 100644
--- a/tempest/lib/common/cred_provider.py
+++ b/tempest/lib/common/cred_provider.py
@@ -86,14 +86,26 @@
return
@abc.abstractmethod
+ def get_project_alt_admin_creds(self):
+ return
+
+ @abc.abstractmethod
def get_project_member_creds(self):
return
@abc.abstractmethod
+ def get_project_alt_member_creds(self):
+ return
+
+ @abc.abstractmethod
def get_project_reader_creds(self):
return
@abc.abstractmethod
+ def get_project_alt_reader_creds(self):
+ return
+
+ @abc.abstractmethod
def clear_creds(self):
return
@@ -106,7 +118,7 @@
return
@abc.abstractmethod
- def get_creds_by_roles(self, roles, force_new=False):
+ def get_creds_by_roles(self, roles, force_new=False, scope=None):
return
@abc.abstractmethod
diff --git a/tempest/lib/common/dynamic_creds.py b/tempest/lib/common/dynamic_creds.py
index 0244128..f334c36 100644
--- a/tempest/lib/common/dynamic_creds.py
+++ b/tempest/lib/common/dynamic_creds.py
@@ -228,8 +228,9 @@
roles_to_assign = [r for r in roles]
if admin:
roles_to_assign.append(self.admin_role)
- self.creds_client.assign_user_role(
- user, project, self.identity_admin_role)
+ if scope == 'project':
+ self.creds_client.assign_user_role(
+ user, project, self.identity_admin_role)
if (self.identity_version == 'v3' and
self.identity_admin_domain_scope):
self.creds_client.assign_user_role_on_domain(
@@ -341,7 +342,7 @@
tenant_id=tenant_id,
enable_dhcp=self.network_resources['dhcp'],
ip_version=(ipaddress.ip_network(
- six.text_type(subnet_cidr)).version))
+ str(subnet_cidr)).version))
else:
resp_body = self.subnets_admin_client.\
create_subnet(network_id=network_id,
@@ -349,7 +350,7 @@
name=subnet_name,
tenant_id=tenant_id,
ip_version=(ipaddress.ip_network(
- six.text_type(subnet_cidr)).version))
+ str(subnet_cidr)).version))
break
except lib_exc.BadRequest as e:
if 'overlaps with another subnet' not in str(e):
@@ -375,13 +376,22 @@
def get_credentials(self, credential_type, scope=None):
if not scope and self._creds.get(str(credential_type)):
credentials = self._creds[str(credential_type)]
- elif scope and self._creds.get("%s_%s" % (scope, credential_type[0])):
- credentials = self._creds["%s_%s" % (scope, credential_type[0])]
+ elif scope and (
+ self._creds.get("%s_%s" % (scope, str(credential_type)))):
+ credentials = self._creds["%s_%s" % (scope, str(credential_type))]
else:
+ LOG.debug("Creating new dynamic creds for scope: %s and "
+ "credential_type: %s", scope, credential_type)
if scope:
- if credential_type == 'admin':
+ if credential_type in [['admin'], ['alt_admin']]:
credentials = self._create_creds(
admin=True, scope=scope)
+ elif credential_type in [['alt_member'], ['alt_reader']]:
+ cred_type = credential_type[0][4:]
+ if isinstance(cred_type, str):
+ cred_type = [cred_type]
+ credentials = self._create_creds(
+ roles=cred_type, scope=scope)
else:
credentials = self._create_creds(
roles=credential_type, scope=scope)
@@ -392,7 +402,7 @@
credentials = self._create_creds(roles=credential_type)
if scope:
self._creds["%s_%s" %
- (scope, credential_type[0])] = credentials
+ (scope, str(credential_type))] = credentials
else:
self._creds[str(credential_type)] = credentials
# Maintained until tests are ported
@@ -443,25 +453,37 @@
def get_project_admin_creds(self):
return self.get_credentials(['admin'], scope='project')
+ def get_project_alt_admin_creds(self):
+ return self.get_credentials(['alt_admin'], scope='project')
+
def get_project_member_creds(self):
return self.get_credentials(['member'], scope='project')
+ def get_project_alt_member_creds(self):
+ return self.get_credentials(['alt_member'], scope='project')
+
def get_project_reader_creds(self):
return self.get_credentials(['reader'], scope='project')
- def get_creds_by_roles(self, roles, force_new=False):
+ def get_project_alt_reader_creds(self):
+ return self.get_credentials(['alt_reader'], scope='project')
+
+ def get_creds_by_roles(self, roles, force_new=False, scope=None):
roles = list(set(roles))
# The roles list as a str will become the index as the dict key for
# the created credentials set in the dynamic_creds dict.
- exist_creds = self._creds.get(str(roles))
+ creds_name = str(roles)
+ if scope:
+ creds_name = "%s_%s" % (scope, str(roles))
+ exist_creds = self._creds.get(creds_name)
# If force_new flag is True 2 cred sets with the same roles are needed
# handle this by creating a separate index for old one to store it
# separately for cleanup
if exist_creds and force_new:
- new_index = str(roles) + '-' + str(len(self._creds))
+ new_index = creds_name + '-' + str(len(self._creds))
self._creds[new_index] = exist_creds
- del self._creds[str(roles)]
- return self.get_credentials(roles)
+ del self._creds[creds_name]
+ return self.get_credentials(roles, scope=scope)
def _clear_isolated_router(self, router_id, router_name):
client = self.routers_admin_client
diff --git a/tempest/lib/common/jsonschema_validator.py b/tempest/lib/common/jsonschema_validator.py
index bbf5e89..0ac757d 100644
--- a/tempest/lib/common/jsonschema_validator.py
+++ b/tempest/lib/common/jsonschema_validator.py
@@ -15,7 +15,6 @@
import jsonschema
from oslo_serialization import base64
from oslo_utils import timeutils
-import six
# JSON Schema validator and format checker used for JSON Schema validation
JSONSCHEMA_VALIDATOR = jsonschema.Draft4Validator
@@ -43,7 +42,7 @@
@jsonschema.FormatChecker.cls_checks('base64')
def _validate_base64_format(instance):
try:
- if isinstance(instance, six.text_type):
+ if isinstance(instance, str):
instance = instance.encode('utf-8')
base64.decode_as_bytes(instance)
except TypeError:
diff --git a/tempest/lib/common/preprov_creds.py b/tempest/lib/common/preprov_creds.py
index 9784a1f..df0f4d6 100644
--- a/tempest/lib/common/preprov_creds.py
+++ b/tempest/lib/common/preprov_creds.py
@@ -17,7 +17,6 @@
from oslo_concurrency import lockutils
from oslo_log import log as logging
-import six
import yaml
from tempest.lib import auth
@@ -138,7 +137,7 @@
temp_hash = hashlib.md5()
account_for_hash = dict((k, v) for (k, v) in account.items()
if k in cls.HASH_CRED_FIELDS)
- temp_hash.update(six.text_type(account_for_hash).encode('utf-8'))
+ temp_hash.update(str(account_for_hash).encode('utf-8'))
temp_hash_key = temp_hash.hexdigest()
hash_dict['creds'][temp_hash_key] = account
for role in roles:
@@ -375,6 +374,10 @@
self._creds['project_admin'] = project_admin
return project_admin
+ def get_project_alt_admin_creds(self):
+ # TODO(gmann): Implement alt admin hash.
+ return
+
def get_project_member_creds(self):
if self._creds.get('project_member'):
return self._creds.get('project_member')
@@ -382,6 +385,10 @@
self._creds['project_member'] = project_member
return project_member
+ def get_project_alt_member_creds(self):
+ # TODO(gmann): Implement alt member hash.
+ return
+
def get_project_reader_creds(self):
if self._creds.get('project_reader'):
return self._creds.get('project_reader')
@@ -389,9 +396,13 @@
self._creds['project_reader'] = project_reader
return project_reader
- def get_creds_by_roles(self, roles, force_new=False):
+ def get_project_alt_reader_creds(self):
+ # TODO(gmann): Implement alt reader hash.
+ return
+
+ def get_creds_by_roles(self, roles, force_new=False, scope=None):
roles = list(set(roles))
- exist_creds = self._creds.get(six.text_type(roles).encode(
+ exist_creds = self._creds.get(str(roles).encode(
'utf-8'), None)
# The force kwarg is used to allocate an additional set of creds with
# the same role list. The index used for the previously allocation
@@ -401,11 +412,11 @@
elif exist_creds and force_new:
# NOTE(andreaf) In py3.x encode returns bytes, and b'' is bytes
# In py2.7 encode returns strings, and b'' is still string
- new_index = six.text_type(roles).encode('utf-8') + b'-' + \
- six.text_type(len(self._creds)).encode('utf-8')
+ new_index = str(roles).encode('utf-8') + b'-' + \
+ str(len(self._creds)).encode('utf-8')
self._creds[new_index] = exist_creds
net_creds = self._get_creds(roles=roles)
- self._creds[six.text_type(roles).encode('utf-8')] = net_creds
+ self._creds[str(roles).encode('utf-8')] = net_creds
return net_creds
def clear_creds(self):
diff --git a/tempest/lib/common/rest_client.py b/tempest/lib/common/rest_client.py
index c950f63..00f2aeb 100644
--- a/tempest/lib/common/rest_client.py
+++ b/tempest/lib/common/rest_client.py
@@ -418,7 +418,7 @@
def _safe_body(self, body, maxlen=4096):
# convert a structure into a string safely
try:
- text = six.text_type(body)
+ text = str(body)
except UnicodeDecodeError:
# if this isn't actually text, return marker that
return "<BinaryData: removed>"
@@ -890,7 +890,7 @@
return True
return 'exceed' in resp_body.get('message', 'blabla')
- def wait_for_resource_deletion(self, id):
+ def wait_for_resource_deletion(self, id, *args, **kwargs):
"""Waits for a resource to be deleted
This method will loop over is_resource_deleted until either
@@ -903,7 +903,7 @@
"""
start_time = int(time.time())
while True:
- if self.is_resource_deleted(id):
+ if self.is_resource_deleted(id, *args, **kwargs):
return
if int(time.time()) - start_time >= self.build_timeout:
message = ('Failed to delete %(resource_type)s %(id)s within '
diff --git a/tempest/lib/services/identity/v3/oauth_token_client.py b/tempest/lib/services/identity/v3/oauth_token_client.py
index 3336094..236b224 100644
--- a/tempest/lib/services/identity/v3/oauth_token_client.py
+++ b/tempest/lib/services/identity/v3/oauth_token_client.py
@@ -33,7 +33,7 @@
def _escape(self, s):
"""Escape a unicode string in an OAuth-compatible fashion."""
safe = b'~'
- s = s.encode('utf-8') if isinstance(s, six.text_type) else s
+ s = s.encode('utf-8') if isinstance(s, str) else s
s = urlparse.quote(s, safe)
if isinstance(s, six.binary_type):
s = s.decode('utf-8')
@@ -47,8 +47,8 @@
verifier=None,
http_method='GET'):
"""Generate OAUTH params along with signature."""
- timestamp = six.text_type(int(time.time()))
- nonce = six.text_type(random.getrandbits(64)) + timestamp
+ timestamp = str(int(time.time()))
+ nonce = str(random.getrandbits(64)) + timestamp
oauth_params = [
('oauth_nonce', nonce),
('oauth_timestamp', timestamp),
diff --git a/tempest/lib/services/object_storage/container_client.py b/tempest/lib/services/object_storage/container_client.py
index 8472a97..6d07ec1 100644
--- a/tempest/lib/services/object_storage/container_client.py
+++ b/tempest/lib/services/object_storage/container_client.py
@@ -20,10 +20,18 @@
from oslo_serialization import jsonutils as json
from tempest.lib.common import rest_client
+from tempest.lib import exceptions
class ContainerClient(rest_client.RestClient):
+ def is_resource_deleted(self, container):
+ try:
+ self.list_container_metadata(container)
+ except exceptions.NotFound:
+ return True
+ return False
+
def update_container(self, container_name, **headers):
"""Creates or Updates a container
diff --git a/tempest/lib/services/object_storage/object_client.py b/tempest/lib/services/object_storage/object_client.py
index 8845d79..bb82975 100644
--- a/tempest/lib/services/object_storage/object_client.py
+++ b/tempest/lib/services/object_storage/object_client.py
@@ -23,6 +23,13 @@
class ObjectClient(rest_client.RestClient):
+ def is_resource_deleted(self, object_name, container):
+ try:
+ self.get_object(container, object_name)
+ except exceptions.NotFound:
+ return True
+ return False
+
def create_object(self, container, object_name, data,
params=None, metadata=None, headers=None,
chunked=False):
diff --git a/tempest/lib/services/placement/resource_providers_client.py b/tempest/lib/services/placement/resource_providers_client.py
index fcd220f..e6fbcb2 100644
--- a/tempest/lib/services/placement/resource_providers_client.py
+++ b/tempest/lib/services/placement/resource_providers_client.py
@@ -81,3 +81,29 @@
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
+
+ def update_resource_providers_inventories(self, rp_uuid, **kwargs):
+ """Update resource providers inventories.
+
+ For full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/placement/#update-resource-provider-inventories
+ """
+ url = '/resource_providers/{}/inventories'.format(rp_uuid)
+ data = json.dumps(kwargs)
+ resp, body = self.put(url, data)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def delete_resource_providers_inventories(self, rp_uuid):
+ """Delete resource providers inventories.
+
+ For full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/placement/#delete-resource-provider-inventories
+ """
+ url = '/resource_providers/{}/inventories'.format(rp_uuid)
+ resp, body = self.delete(url)
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 99a3f32..22d0fd2 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -18,6 +18,7 @@
import subprocess
import netaddr
+
from oslo_log import log
from oslo_serialization import jsonutils as json
from oslo_utils import netutils
@@ -589,7 +590,7 @@
rules.append(sg_rule)
return rules
- def _create_security_group(self, **kwargs):
+ def create_security_group(self, **kwargs):
"""Create security group and add rules to security group"""
if not kwargs.get('name'):
kwargs['name'] = data_utils.rand_name(self.__class__.__name__)
@@ -1060,10 +1061,10 @@
if not CONF.service_available.neutron:
raise cls.skipException('Neutron not available')
- def _create_network(self, networks_client=None,
- project_id=None,
- namestart='network-smoke-',
- port_security_enabled=True, **net_dict):
+ def create_network(self, networks_client=None,
+ project_id=None,
+ namestart='network-smoke-',
+ port_security_enabled=True, **net_dict):
if not networks_client:
networks_client = self.networks_client
if not project_id:
@@ -1098,6 +1099,8 @@
:Keyword Arguments:
* *ip_version = ip version of the given network,
+ use_default_subnetpool = default subnetpool to
+ manage IPv6 addresses range.
"""
if not subnets_client:
@@ -1120,51 +1123,73 @@
network_id=ext_net['id'], cidr=cidr)['subnets'])
return len(tenant_subnets + external_subnets) != 0
- ip_version = kwargs.pop('ip_version', 4)
-
- if ip_version == 6:
- tenant_cidr = netaddr.IPNetwork(
- CONF.network.project_network_v6_cidr)
- num_bits = CONF.network.project_network_v6_mask_bits
- else:
- tenant_cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
- num_bits = CONF.network.project_network_mask_bits
-
- result = None
- str_cidr = None
- # Repeatedly attempt subnet creation with sequential cidr
- # blocks until an unallocated block is found.
- for subnet_cidr in tenant_cidr.subnet(num_bits):
- str_cidr = str(subnet_cidr)
- if cidr_in_use(str_cidr, project_id=network['project_id']):
- continue
+ def _make_create_subnet_request(namestart, network,
+ ip_version, subnets_client, **kwargs):
subnet = dict(
name=data_utils.rand_name(namestart),
network_id=network['id'],
project_id=network['project_id'],
- cidr=str_cidr,
ip_version=ip_version,
**kwargs
)
+
+ if ip_version == 6:
+ subnet['ipv6_address_mode'] = 'slaac'
+ subnet['ipv6_ra_mode'] = 'slaac'
+
try:
- result = subnets_client.create_subnet(**subnet)
- break
+ return subnets_client.create_subnet(**subnet)
except lib_exc.Conflict as e:
- is_overlapping_cidr = 'overlaps with another subnet' in str(e)
- if not is_overlapping_cidr:
+ if 'overlaps with another subnet' not in str(e):
raise
+
+ result = None
+ str_cidr = None
+
+ use_default_subnetpool = kwargs.get('use_default_subnetpool', False)
+ ip_version = kwargs.pop('ip_version', 4)
+
+ if not use_default_subnetpool:
+
+ if ip_version == 6:
+ tenant_cidr = netaddr.IPNetwork(
+ CONF.network.project_network_v6_cidr)
+ num_bits = CONF.network.project_network_v6_mask_bits
+ else:
+ tenant_cidr = netaddr.IPNetwork(
+ CONF.network.project_network_cidr)
+ num_bits = CONF.network.project_network_mask_bits
+
+ # Repeatedly attempt subnet creation with sequential cidr
+ # blocks until an unallocated block is found.
+ for subnet_cidr in tenant_cidr.subnet(num_bits):
+ str_cidr = str(subnet_cidr)
+ if cidr_in_use(str_cidr, project_id=network['project_id']):
+ continue
+ result = _make_create_subnet_request(
+ namestart, network, ip_version, subnets_client,
+ cidr=str_cidr, **kwargs)
+
+ if result is not None:
+ break
+
+ else:
+ result = _make_create_subnet_request(
+ namestart, network, ip_version, subnets_client,
+ **kwargs)
self.assertIsNotNone(result, 'Unable to allocate tenant network')
subnet = result['subnet']
- self.assertEqual(subnet['cidr'], str_cidr)
+ if str_cidr is not None:
+ self.assertEqual(subnet['cidr'], str_cidr)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
subnets_client.delete_subnet, subnet['id'])
return subnet
- def _get_server_port_id_and_ip4(self, server, ip_addr=None, **kwargs):
+ def get_server_port_id_and_ip4(self, server, ip_addr=None, **kwargs):
if ip_addr and not kwargs.get('fixed_ips'):
kwargs['fixed_ips'] = 'ip_address=%s' % ip_addr
@@ -1201,7 +1226,7 @@
% port_map)
return port_map[0]
- def _get_network_by_name(self, network_name):
+ def get_network_by_name(self, network_name):
net = self.os_admin.networks_client.list_networks(
name=network_name)['networks']
self.assertNotEmpty(net,
@@ -1217,7 +1242,7 @@
if not client:
client = self.floating_ips_client
if not port_id:
- port_id, ip4 = self._get_server_port_id_and_ip4(server)
+ port_id, ip4 = self.get_server_port_id_and_ip4(server)
else:
ip4 = None
@@ -1245,7 +1270,7 @@
This wrapper utility attaches the floating_ip for
the respective port_id of server
"""
- port_id, _ = self._get_server_port_id_and_ip4(server)
+ port_id, _ = self.get_server_port_id_and_ip4(server)
kwargs = dict(port_id=port_id)
floating_ip = self.floating_ips_client.update_floatingip(
floating_ip['id'], **kwargs)['floatingip']
@@ -1361,17 +1386,17 @@
self.log_console_output()
self.fail(msg)
- def _create_security_group(self, security_group_rules_client=None,
- project_id=None,
- namestart='secgroup-smoke',
- security_groups_client=None):
+ def create_security_group(self, security_group_rules_client=None,
+ project_id=None,
+ namestart='secgroup-smoke',
+ security_groups_client=None):
if security_group_rules_client is None:
security_group_rules_client = self.security_group_rules_client
if security_groups_client is None:
security_groups_client = self.security_groups_client
if project_id is None:
project_id = security_groups_client.project_id
- secgroup = self._create_empty_security_group(
+ secgroup = self.create_empty_security_group(
namestart=namestart, client=security_groups_client,
project_id=project_id)
@@ -1385,8 +1410,8 @@
self.assertEqual(secgroup['id'], rule['security_group_id'])
return secgroup
- def _create_empty_security_group(self, client=None, project_id=None,
- namestart='secgroup-smoke'):
+ def create_empty_security_group(self, client=None, project_id=None,
+ namestart='secgroup-smoke'):
"""Create a security group without rules.
Default rules will be created:
@@ -1520,7 +1545,7 @@
return rules
- def _get_router(self, client=None, project_id=None, **kwargs):
+ def get_router(self, client=None, project_id=None, **kwargs):
"""Retrieve a router for the given tenant id.
If a public router has been configured, it will be returned.
@@ -1589,18 +1614,18 @@
if not CONF.compute.fixed_network_name:
m = 'fixed_network_name must be specified in config'
raise lib_exc.InvalidConfiguration(m)
- network = self._get_network_by_name(
+ network = self.get_network_by_name(
CONF.compute.fixed_network_name)
router = None
subnet = None
else:
- network = self._create_network(
+ network = self.create_network(
networks_client=networks_client,
project_id=project_id,
port_security_enabled=port_security_enabled,
**net_dict)
- router = self._get_router(client=routers_client,
- project_id=project_id)
+ router = self.get_router(client=routers_client,
+ project_id=project_id)
subnet_kwargs = dict(network=network,
subnets_client=subnets_client)
# use explicit check because empty list is a valid option
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index fe42583..5201315 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -78,7 +78,7 @@
self.assertEqual(1, disks.count(CONF.compute.volume_device_name))
def create_and_add_security_group_to_server(self, server):
- secgroup = self._create_security_group()
+ secgroup = self.create_security_group()
self.servers_client.add_security_group(server['id'],
name=secgroup['name'])
self.addCleanup(self.servers_client.remove_security_group,
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index dbab212..20d2e80 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -60,7 +60,7 @@
def _setup_server(self, keypair):
security_groups = []
if utils.is_extension_enabled('security-group', 'network'):
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
security_groups = [{'name': security_group['name']}]
network, _, _ = self.create_networks()
server = self.create_server(
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 6c1b3fa..e359c71 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -159,7 +159,7 @@
keypair = self.create_keypair()
self.keypairs[keypair['name']] = keypair
security_groups = [
- {'name': self._create_security_group()['name']}
+ {'name': self.create_security_group()['name']}
]
network = {'uuid': network['id']}
if port_id is not None:
@@ -223,14 +223,14 @@
floating_ip, server = self.floating_ip_tuple
# create a new server for the floating ip
server = self._create_server(self.network)
- port_id, _ = self._get_server_port_id_and_ip4(server)
+ port_id, _ = self.get_server_port_id_and_ip4(server)
floating_ip = self.floating_ips_client.update_floatingip(
floating_ip['id'], port_id=port_id)['floatingip']
self.assertEqual(port_id, floating_ip['port_id'])
self.floating_ip_tuple = Floating_IP_tuple(floating_ip, server)
def _create_new_network(self, create_gateway=False):
- self.new_net = self._create_network()
+ self.new_net = self.create_network()
if create_gateway:
self.new_subnet = self.create_subnet(
network=self.new_net)
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index 9be28c4..4f5118b 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -66,7 +66,7 @@
def setUp(self):
super(TestGettingAddress, self).setUp()
self.keypair = self.create_keypair()
- self.sec_grp = self._create_security_group()
+ self.sec_grp = self.create_security_group()
def prepare_network(self, address6_mode, n_subnets6=1, dualnet=False):
"""Prepare network
@@ -77,15 +77,15 @@
if dualnet - create IPv6 subnets on a different network
:return: list of created networks
"""
- network = self._create_network()
+ network = self.create_network()
if dualnet:
- network_v6 = self._create_network()
+ network_v6 = self.create_network()
sub4 = self.create_subnet(network=network,
namestart='sub4',
ip_version=4)
- router = self._get_router()
+ router = self.get_router()
self.routers_client.add_router_interface(router['id'],
subnet_id=sub4['id'])
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 496a371..e078f23 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -197,14 +197,14 @@
tenant.keypair = keypair
def _create_tenant_security_groups(self, tenant):
- access_sg = self._create_empty_security_group(
+ access_sg = self.create_empty_security_group(
namestart='secgroup_access-',
project_id=tenant.creds.project_id,
client=tenant.manager.security_groups_client
)
# don't use default secgroup since it allows in-project traffic
- def_sg = self._create_empty_security_group(
+ def_sg = self.create_empty_security_group(
namestart='secgroup_general-',
project_id=tenant.creds.project_id,
client=tenant.manager.security_groups_client
@@ -534,7 +534,7 @@
new_tenant = self.primary_tenant
# Create empty security group and add icmp rule in it
- new_sg = self._create_empty_security_group(
+ new_sg = self.create_empty_security_group(
namestart='secgroup_new-',
project_id=new_tenant.creds.project_id,
client=new_tenant.manager.security_groups_client)
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 60242d5..4c82d84 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -128,7 +128,7 @@
@utils.services('compute', 'network')
def test_server_basic_ops(self):
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
self.md = {'meta1': 'data1', 'meta2': 'data2', 'metaN': 'dataN'}
self.instance = self.create_server(
key_name=keypair['name'],
diff --git a/tempest/scenario/test_shelve_instance.py b/tempest/scenario/test_shelve_instance.py
index ed06898..29612ec 100644
--- a/tempest/scenario/test_shelve_instance.py
+++ b/tempest/scenario/test_shelve_instance.py
@@ -76,7 +76,7 @@
cold_migrate=False):
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
security_groups = [{'name': security_group['name']}]
server = self.create_server(
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index a062d40..d04cb9a 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -50,7 +50,7 @@
def test_snapshot_pattern(self):
# prepare for booting an instance
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
# boot an instance and create a timestamp file in it
server = self.create_server(
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index a8e4c30..4b81b9e 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -81,7 +81,7 @@
def test_stamp_pattern(self):
# prepare for booting an instance
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
# boot an instance and create a timestamp file in it
volume = self.create_volume()
diff --git a/tempest/scenario/test_volume_backup_restore.py b/tempest/scenario/test_volume_backup_restore.py
index 8a8c54e..71e6b53 100644
--- a/tempest/scenario/test_volume_backup_restore.py
+++ b/tempest/scenario/test_volume_backup_restore.py
@@ -70,7 +70,7 @@
# Create keypair and security group
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
# Boot a server from the restored backup
bd_map_v2 = [{
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 3b4bbda..5a5cc27 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -64,7 +64,7 @@
LOG.info("Creating keypair and security group")
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
# create an instance from volume
LOG.info("Booting instance 1 from volume")
diff --git a/tempest/scenario/test_volume_migrate_attached.py b/tempest/scenario/test_volume_migrate_attached.py
index 106500e..57d2a1a 100644
--- a/tempest/scenario/test_volume_migrate_attached.py
+++ b/tempest/scenario/test_volume_migrate_attached.py
@@ -100,7 +100,7 @@
def test_volume_retype_attached(self):
LOG.info("Creating keypair and security group")
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
# create volume types
LOG.info("Creating Volume types")
@@ -156,7 +156,7 @@
def test_volume_migrate_attached(self):
LOG.info("Creating keypair and security group")
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
LOG.info("Creating volume")
# Create a unique volume type to avoid using the backend default
diff --git a/tempest/test.py b/tempest/test.py
index 68602d6..655b9a4 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -296,6 +296,7 @@
identity_version = cls.get_identity_version()
# setting force_tenant_isolation to True also needs admin credentials.
if ('admin' in cls.credentials or
+ 'alt_admin' in cls.credentials or
getattr(cls, 'force_tenant_isolation', False)):
if not credentials.is_admin_available(
identity_version=identity_version):
@@ -414,8 +415,18 @@
'alt_manager', 'os_alt', version='Pike',
removal_version='Queens')
elif isinstance(credentials_type, list):
+ scope = 'project'
+ if credentials_type[0].startswith('system'):
+ scope = 'system'
+ elif credentials_type[0].startswith('domain'):
+ scope = 'domain'
manager = cls.get_client_manager(roles=credentials_type[1:],
- force_new=True)
+ force_new=True,
+ scope=scope)
+ setattr(cls, 'os_%s' % credentials_type[0], manager)
+ # TODO(gmann): Setting the old style attribute too for
+ # backward compatibility but at some point we should
+ # remove this.
setattr(cls, 'os_roles_%s' % credentials_type[0], manager)
@classmethod
@@ -657,7 +668,7 @@
@classmethod
def get_client_manager(cls, credential_type=None, roles=None,
- force_new=None):
+ force_new=None, scope=None):
"""Returns an OpenStack client manager
Returns an OpenStack client manager based on either credential_type
@@ -665,6 +676,7 @@
credential_type 'primary'
:param credential_type: string - primary, alt or admin
:param roles: list of roles
+ :param scope: scope for the test user
:returns: the created client manager
:raises skipException: if the requested credentials are not available
@@ -683,7 +695,7 @@
" is not able to provide credentials with the %s role "
"assigned." % (cls.__name__, role))
raise cls.skipException(skip_msg)
- params = dict(roles=roles)
+ params = dict(roles=roles, scope=scope)
if force_new is not None:
params.update(force_new=force_new)
creds = cred_provider.get_creds_by_roles(**params)
@@ -850,7 +862,13 @@
if isinstance(credentials_type, six.string_types):
manager = cls.get_client_manager(credential_type=credentials_type)
elif isinstance(credentials_type, list):
- manager = cls.get_client_manager(roles=credentials_type[1:])
+ scope = 'project'
+ if credentials_type[0].startswith('system'):
+ scope = 'system'
+ elif credentials_type[0].startswith('domain'):
+ scope = 'domain'
+ manager = cls.get_client_manager(roles=credentials_type[1:],
+ scope=scope)
else:
manager = cls.get_client_manager()
diff --git a/tempest/tests/api/compute/test_base.py b/tempest/tests/api/compute/test_base.py
index 74d2625..8a1873b 100644
--- a/tempest/tests/api/compute/test_base.py
+++ b/tempest/tests/api/compute/test_base.py
@@ -15,7 +15,6 @@
from unittest import mock
from oslo_utils import uuidutils
-import six
from tempest.api.compute import base as compute_base
from tempest.common import waiters
@@ -128,9 +127,9 @@
mock.sentinel.server_id, wait_until='active')
# make our assertions
if fault:
- self.assertIn(fault, six.text_type(ex))
+ self.assertIn(fault, str(ex))
else:
- self.assertNotIn(fault, six.text_type(ex))
+ self.assertNotIn(fault, str(ex))
if compute_base.BaseV2ComputeTest.is_requested_microversion_compatible(
'2.35'):
status = 'ACTIVE'
diff --git a/tempest/tests/cmd/test_run.py b/tempest/tests/cmd/test_run.py
index ec7b760..3b5e901 100644
--- a/tempest/tests/cmd/test_run.py
+++ b/tempest/tests/cmd/test_run.py
@@ -21,7 +21,6 @@
from unittest import mock
import fixtures
-import six
from tempest.cmd import run
from tempest.cmd import workspace
@@ -153,12 +152,12 @@
subprocess.call(['stestr', 'init'])
out, err = self.assertRunExit(['tempest', 'run', '-l'], 0)
tests = out.split()
- tests = sorted([six.text_type(x.rstrip()) for x in tests if x])
+ tests = sorted([str(x.rstrip()) for x in tests if x])
result = [
- six.text_type('tests.test_failing.FakeTestClass.test_pass'),
- six.text_type('tests.test_failing.FakeTestClass.test_pass_list'),
- six.text_type('tests.test_passing.FakeTestClass.test_pass'),
- six.text_type('tests.test_passing.FakeTestClass.test_pass_list'),
+ str('tests.test_failing.FakeTestClass.test_pass'),
+ str('tests.test_failing.FakeTestClass.test_pass_list'),
+ str('tests.test_passing.FakeTestClass.test_pass'),
+ str('tests.test_passing.FakeTestClass.test_pass_list'),
]
# NOTE(mtreinish): on python 3 the subprocess prints b'' around
# stdout.
diff --git a/tempest/tests/lib/common/test_api_version_utils.py b/tempest/tests/lib/common/test_api_version_utils.py
index b99e8d4..8d5de09 100644
--- a/tempest/tests/lib/common/test_api_version_utils.py
+++ b/tempest/tests/lib/common/test_api_version_utils.py
@@ -12,7 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import six
import testtools
from tempest.lib.common import api_version_utils
@@ -31,7 +30,7 @@
cfg_max_version)
except testtools.TestCase.skipException as e:
if not expected_skip:
- raise testtools.TestCase.failureException(six.text_type(e))
+ raise testtools.TestCase.failureException(str(e))
def test_version_min_in_range(self):
self._test_version('2.2', '2.10', '2.1', '2.7')
diff --git a/tempest/tests/lib/common/test_dynamic_creds.py b/tempest/tests/lib/common/test_dynamic_creds.py
index e9073cc..b4b1b91 100644
--- a/tempest/tests/lib/common/test_dynamic_creds.py
+++ b/tempest/tests/lib/common/test_dynamic_creds.py
@@ -214,6 +214,56 @@
self.assertEqual(admin_creds.user_id, '1234')
@mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_project_alt_admin_creds(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_roles('1234', 'admin')
+ self._mock_user_create('1234', 'fake_alt_admin_user')
+ self._mock_tenant_create('1234', 'fake_alt_admin')
+
+ user_mock = mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project')
+ user_mock.start()
+ self.addCleanup(user_mock.stop)
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project') as user_mock:
+ alt_admin_creds = creds.get_project_alt_admin_creds()
+ user_mock.assert_has_calls([
+ mock.call('1234', '1234', '1234')])
+ self.assertEqual(alt_admin_creds.username, 'fake_alt_admin_user')
+ self.assertEqual(alt_admin_creds.project_name, 'fake_alt_admin')
+ # Verify IDs
+ self.assertEqual(alt_admin_creds.project_id, '1234')
+ self.assertEqual(alt_admin_creds.user_id, '1234')
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_project_alt_member_creds(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_assign_user_role()
+ self._mock_list_role()
+ self._mock_tenant_create('1234', 'fake_alt_member')
+ self._mock_user_create('1234', 'fake_alt_user')
+ alt_member_creds = creds.get_project_alt_member_creds()
+ self.assertEqual(alt_member_creds.username, 'fake_alt_user')
+ self.assertEqual(alt_member_creds.project_name, 'fake_alt_member')
+ # Verify IDs
+ self.assertEqual(alt_member_creds.project_id, '1234')
+ self.assertEqual(alt_member_creds.user_id, '1234')
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_project_alt_reader_creds(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_assign_user_role()
+ self._mock_list_roles('1234', 'reader')
+ self._mock_tenant_create('1234', 'fake_alt_reader')
+ self._mock_user_create('1234', 'fake_alt_user')
+ alt_reader_creds = creds.get_project_alt_reader_creds()
+ self.assertEqual(alt_reader_creds.username, 'fake_alt_user')
+ self.assertEqual(alt_reader_creds.project_name, 'fake_alt_reader')
+ # Verify IDs
+ self.assertEqual(alt_reader_creds.project_id, '1234')
+ self.assertEqual(alt_reader_creds.user_id, '1234')
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
def test_role_creds(self, MockRestClient):
creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
self._mock_list_2_roles()
@@ -242,6 +292,100 @@
self.assertEqual(role_creds.user_id, '1234')
@mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_role_creds_with_project_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+ self._mock_tenant_create('1234', 'fake_role_project')
+
+ user_mock = mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project')
+ user_mock.start()
+ self.addCleanup(user_mock.stop)
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='project')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ args = map(lambda x: x[1], calls)
+ args = list(args)
+ self.assertIn(('1234', '1234', '1234'), args)
+ self.assertIn(('1234', '1234', '12345'), args)
+ self.assertEqual(role_creds.username, 'fake_role_user')
+ self.assertEqual(role_creds.project_name, 'fake_role_project')
+ # Verify IDs
+ self.assertEqual(role_creds.project_id, '1234')
+ self.assertEqual(role_creds.user_id, '1234')
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def _test_get_same_role_creds_with_project_scope(self, MockRestClient,
+ scope=None):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+ self._mock_tenant_create('1234', 'fake_role_project')
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope=scope)
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+
+ # Fetch the same creds again
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project') as user_mock1:
+ role_creds_new = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope=scope)
+ calls = user_mock1.mock_calls
+ # Assert that previously created creds are return and no call to
+ # role creation.
+ self.assertEqual(len(calls), 0)
+ # Check if previously created creds are returned.
+ self.assertEqual(role_creds, role_creds_new)
+
+ def test_get_same_role_creds_with_project_scope(self):
+ self._test_get_same_role_creds_with_project_scope(scope='project')
+
+ def test_get_same_role_creds_with_default_scope(self):
+ self._test_get_same_role_creds_with_project_scope()
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def _test_get_different_role_creds_with_project_scope(
+ self, MockRestClient, scope=None):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+ self._mock_tenant_create('1234', 'fake_role_project')
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope=scope)
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ # Fetch the creds with one role different
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project') as user_mock1:
+ role_creds_new = creds.get_creds_by_roles(
+ roles=['role1'], scope=scope)
+ calls = user_mock1.mock_calls
+ # Because one role is different, assert that the role creation
+ # is called with the 1 specified roles
+ self.assertEqual(len(calls), 1)
+ # Check new creds is created for new roles.
+ self.assertNotEqual(role_creds, role_creds_new)
+
+ def test_get_different_role_creds_with_project_scope(self):
+ self._test_get_different_role_creds_with_project_scope(
+ scope='project')
+
+ def test_get_different_role_creds_with_default_scope(self):
+ self._test_get_different_role_creds_with_project_scope()
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
def test_all_cred_cleanup(self, MockRestClient):
creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
self._mock_assign_user_role()
@@ -658,6 +802,232 @@
return project_fix
@mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_role_creds_with_system_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_system') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='system')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ args = map(lambda x: x[1], calls)
+ args = list(args)
+ self.assertIn(('1234', '1234'), args)
+ self.assertIn(('1234', '12345'), args)
+ self.assertEqual(role_creds.username, 'fake_role_user')
+ self.assertEqual(role_creds.user_id, '1234')
+ # Verify system scope
+ self.assertEqual(role_creds.system, 'all')
+ # Verify domain is default
+ self.assertEqual(role_creds.domain_id, 'default')
+ self.assertEqual(role_creds.domain_name, 'Default')
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_get_same_role_creds_with_system_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_system') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='system')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+
+ # Fetch the same creds again
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_system') as user_mock1:
+ role_creds_new = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='system')
+ calls = user_mock1.mock_calls
+ # Assert that previously created creds are return and no call to
+ # role creation.
+ self.assertEqual(len(calls), 0)
+ # Verify system scope
+ self.assertEqual(role_creds_new.system, 'all')
+ # Check if previously created creds are returned.
+ self.assertEqual(role_creds, role_creds_new)
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_get_different_role_creds_with_system_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_system') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='system')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ # Verify system scope
+ self.assertEqual(role_creds.system, 'all')
+ # Fetch the creds with one role different
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_system') as user_mock1:
+ role_creds_new = creds.get_creds_by_roles(
+ roles=['role1'], scope='system')
+ calls = user_mock1.mock_calls
+ # Because one role is different, assert that the role creation
+ # is called with the 1 specified roles
+ self.assertEqual(len(calls), 1)
+ # Verify Scope
+ self.assertEqual(role_creds_new.system, 'all')
+ # Check new creds is created for new roles.
+ self.assertNotEqual(role_creds, role_creds_new)
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_role_creds_with_domain_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+
+ domain = {
+ "id": '12',
+ "enabled": True,
+ "name": "TestDomain"
+ }
+
+ self.useFixture(fixtures.MockPatch(
+ 'tempest.lib.common.cred_client.V3CredsClient.create_domain',
+ return_value=domain))
+
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_domain') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='domain')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ args = map(lambda x: x[1], calls)
+ args = list(args)
+ self.assertIn((domain['id'], '1234', '1234'), args)
+ self.assertIn((domain['id'], '1234', '12345'), args)
+ self.assertEqual(role_creds.username, 'fake_role_user')
+ self.assertEqual(role_creds.user_id, '1234')
+ # Verify creds are under new created domain
+ self.assertEqual(role_creds.domain_id, domain['id'])
+ self.assertEqual(role_creds.domain_name, domain['name'])
+ # Verify that Scope is None
+ self.assertIsNone(role_creds.system)
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_get_same_role_creds_with_domain_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+
+ domain = {
+ "id": '12',
+ "enabled": True,
+ "name": "TestDomain"
+ }
+
+ self.useFixture(fixtures.MockPatch(
+ 'tempest.lib.common.cred_client.V3CredsClient.create_domain',
+ return_value=domain))
+
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_domain') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='domain')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ self.assertEqual(role_creds.user_id, '1234')
+ # Verify Scope
+ self.assertIsNone(role_creds.system)
+ # Fetch the same creds again
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_domain') as user_mock1:
+ role_creds_new = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='domain')
+ calls = user_mock1.mock_calls
+ # Assert that previously created creds are return and no call to
+ # role creation.
+ self.assertEqual(len(calls), 0)
+ # Verify Scope
+ self.assertIsNone(role_creds_new.system)
+ # Check if previously created creds are returned.
+ self.assertEqual(role_creds, role_creds_new)
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_get_different_role_creds_with_domain_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+
+ domain = {
+ "id": '12',
+ "enabled": True,
+ "name": "TestDomain"
+ }
+
+ self.useFixture(fixtures.MockPatch(
+ 'tempest.lib.common.cred_client.V3CredsClient.create_domain',
+ return_value=domain))
+
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_domain') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='domain')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ self.assertEqual(role_creds.user_id, '1234')
+ # Verify Scope
+ self.assertIsNone(role_creds.system)
+ # Fetch the same creds again
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_domain') as user_mock1:
+ role_creds_new = creds.get_creds_by_roles(
+ roles=['role1'], scope='domain')
+ calls = user_mock1.mock_calls
+ # Because one role is different, assert that the role creation
+ # is called with the 1 specified roles
+ self.assertEqual(len(calls), 1)
+ # Verify Scope
+ self.assertIsNone(role_creds_new.system)
+ # Check new creds is created for new roles.
+ self.assertNotEqual(role_creds, role_creds_new)
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_get_role_creds_with_different_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+ self._mock_tenant_create('1234', 'fake_role_project')
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_system') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='system')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ # Verify Scope
+ self.assertEqual(role_creds.system, 'all')
+
+ # Fetch the same role creds but with different scope
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project') as user_mock1:
+ role_creds_new = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='project')
+ calls = user_mock1.mock_calls
+ # Because scope is different, assert that the role creation
+ # is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ # Verify Scope
+ self.assertIsNone(role_creds_new.system)
+ # Check that created creds are different
+ self.assertNotEqual(role_creds, role_creds_new)
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
def test_member_role_creation_with_duplicate(self, rest_client_mock):
creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
creds.creds_client = mock.MagicMock()
diff --git a/tempest/tests/lib/common/test_preprov_creds.py b/tempest/tests/lib/common/test_preprov_creds.py
index 579363e..499b6fe 100644
--- a/tempest/tests/lib/common/test_preprov_creds.py
+++ b/tempest/tests/lib/common/test_preprov_creds.py
@@ -17,7 +17,6 @@
import shutil
from unittest import mock
-import six
import testtools
import fixtures
@@ -109,7 +108,7 @@
hash = hashlib.md5()
account_for_hash = dict((k, v) for (k, v) in account.items()
if k in hash_fields)
- hash.update(six.text_type(account_for_hash).encode('utf-8'))
+ hash.update(str(account_for_hash).encode('utf-8'))
temp_hash = hash.hexdigest()
hash_list.append(temp_hash)
return hash_list
diff --git a/tempest/tests/lib/services/placement/test_resource_providers_client.py b/tempest/tests/lib/services/placement/test_resource_providers_client.py
index 11aeaf2..485f584 100644
--- a/tempest/tests/lib/services/placement/test_resource_providers_client.py
+++ b/tempest/tests/lib/services/placement/test_resource_providers_client.py
@@ -48,6 +48,43 @@
FAKE_RESOURCE_PROVIDER_AGGREGATES = {
'aggregates': [FAKE_AGGREGATE_UUID]
}
+ FAKE_RESOURCE_UPDATE_INVENTORIES_RESPONSE = {
+ "inventories": {
+ "MEMORY_MB": {
+ "allocation_ratio": 2.0,
+ "max_unit": 16,
+ "min_unit": 1,
+ "reserved": 0,
+ "step_size": 4,
+ "total": 128
+ },
+ "VCPU": {
+ "allocation_ratio": 10.0,
+ "max_unit": 2147483647,
+ "min_unit": 1,
+ "reserved": 2,
+ "step_size": 1,
+ "total": 64
+ }
+ },
+ "resource_provider_generation": 2
+ }
+ FAKE_RESOURCE_UPDATE_INVENTORIES_REQUEST = {
+ "inventories": {
+ "MEMORY_MB": {
+ "allocation_ratio": 2.0,
+ "max_unit": 16,
+ "step_size": 4,
+ "total": 128
+ },
+ "VCPU": {
+ "allocation_ratio": 10.0,
+ "reserved": 2,
+ "total": 64
+ }
+ },
+ "resource_provider_generation": 1
+ }
def setUp(self):
super(TestResourceProvidersClient, self).setUp()
@@ -102,6 +139,32 @@
def test_list_resource_provider_inventories_with_bytes_body(self):
self._test_list_resource_provider_inventories(bytes_body=True)
+ def _test_update_resource_providers_inventories(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.update_resource_providers_inventories,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ self.FAKE_RESOURCE_UPDATE_INVENTORIES_RESPONSE,
+ to_utf=bytes_body,
+ status=200,
+ rp_uuid=self.FAKE_RESOURCE_PROVIDER_UUID,
+ **self.FAKE_RESOURCE_UPDATE_INVENTORIES_REQUEST
+ )
+
+ def test_update_resource_providers_inventories_with_str_body(self):
+ self._test_update_resource_providers_inventories()
+
+ def test_update_resource_providers_inventories_with_bytes_body(self):
+ self._test_update_resource_providers_inventories(bytes_body=True)
+
+ def test_delete_resource_providers_inventories(self):
+ self.check_service_client_function(
+ self.client.delete_resource_providers_inventories,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ status=204,
+ rp_uuid=self.FAKE_RESOURCE_PROVIDER_UUID,
+ )
+
def _test_list_resource_provider_aggregates(self, bytes_body=False):
self.check_service_client_function(
self.client.list_resource_provider_aggregates,
diff --git a/tempest/tests/lib/test_ssh.py b/tempest/tests/lib/test_ssh.py
index 0ec9262..035bdb0 100644
--- a/tempest/tests/lib/test_ssh.py
+++ b/tempest/tests/lib/test_ssh.py
@@ -274,7 +274,7 @@
client = ssh.Client('localhost', 'root', timeout=2)
exc = self.assertRaises(exceptions.SSHExecCommandFailed,
client.exec_command, "test")
- self.assertIn('R' + self._utf8_string, six.text_type(exc))
+ self.assertIn('R' + self._utf8_string, str(exc))
def test_exec_command_no_select(self):
gsc_mock = self.patch('tempest.lib.common.ssh.Client.'
diff --git a/tempest/tests/test_base_test.py b/tempest/tests/test_base_test.py
index b154cd5..88c28bf 100644
--- a/tempest/tests/test_base_test.py
+++ b/tempest/tests/test_base_test.py
@@ -109,7 +109,7 @@
test.BaseTestCase.get_tenant_network(credentials_type=creds)
- mock_gcm.assert_called_once_with(roles=['role1'])
+ mock_gcm.assert_called_once_with(roles=['role1'], scope='project')
mock_gprov.assert_called_once_with()
mock_gtn.assert_called_once_with(mock_prov, net_client,
self.fixed_network_name)
diff --git a/tempest/tests/test_list_tests.py b/tempest/tests/test_list_tests.py
index 1cc9c9a..fe44ef6 100644
--- a/tempest/tests/test_list_tests.py
+++ b/tempest/tests/test_list_tests.py
@@ -16,8 +16,6 @@
import re
import subprocess
-import six
-
from tempest.tests import base
@@ -32,7 +30,7 @@
self.assertEqual(0, p.returncode,
"test discovery failed, one or more files cause an "
"error on import %s" % ids)
- ids = six.text_type(ids).split('\n')
+ ids = str(ids).split('\n')
for test_id in ids:
if re.match(r'(\w+\.){3}\w+', test_id):
if not test_id.startswith('tempest.'):
diff --git a/tempest/tests/test_microversions.py b/tempest/tests/test_microversions.py
index ee6db71..835f51c 100644
--- a/tempest/tests/test_microversions.py
+++ b/tempest/tests/test_microversions.py
@@ -13,7 +13,6 @@
# under the License.
from oslo_config import cfg
-import six
import testtools
from tempest.api.compute import base as compute_base
@@ -75,7 +74,7 @@
self.assertRaises(testtools.TestCase.skipException,
test_class.skip_checks)
except testtools.TestCase.skipException as e:
- raise testtools.TestCase.failureException(six.text_type(e))
+ raise testtools.TestCase.failureException(str(e))
def test_config_version_none_none(self):
expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2]
diff --git a/tempest/tests/test_test.py b/tempest/tests/test_test.py
index 72e8b6d..9aeedb3 100644
--- a/tempest/tests/test_test.py
+++ b/tempest/tests/test_test.py
@@ -453,6 +453,130 @@
expected_creds[1][1:],
mock_get_client_manager.mock_calls[1][2]['roles'])
+ def test_setup_credentials_with_role_and_system_scope(self):
+ expected_creds = [['system_my_role', 'role1', 'role2']]
+
+ class SystemRoleCredentials(self.parent_test):
+ credentials = expected_creds
+
+ expected_clients = 'clients'
+ with mock.patch.object(
+ SystemRoleCredentials,
+ 'get_client_manager') as mock_get_client_manager:
+ mock_get_client_manager.return_value = expected_clients
+ sys_creds = SystemRoleCredentials()
+ sys_creds.setup_credentials()
+ self.assertTrue(hasattr(sys_creds, 'os_system_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_system_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role)
+ self.assertEqual(1, mock_get_client_manager.call_count)
+ self.assertEqual(
+ expected_creds[0][1:],
+ mock_get_client_manager.mock_calls[0][2]['roles'])
+ self.assertEqual(
+ 'system',
+ mock_get_client_manager.mock_calls[0][2]['scope'])
+
+ def test_setup_credentials_with_multiple_role_and_system_scope(self):
+ expected_creds = [['system_my_role', 'role1', 'role2'],
+ ['system_my_role2', 'role1', 'role2'],
+ ['system_my_role3', 'role3']]
+
+ class SystemRoleCredentials(self.parent_test):
+ credentials = expected_creds
+
+ expected_clients = 'clients'
+ with mock.patch.object(
+ SystemRoleCredentials,
+ 'get_client_manager') as mock_get_client_manager:
+ mock_get_client_manager.return_value = expected_clients
+ sys_creds = SystemRoleCredentials()
+ sys_creds.setup_credentials()
+ self.assertTrue(hasattr(sys_creds, 'os_system_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_system_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_system_my_role2'))
+ self.assertEqual(expected_clients, sys_creds.os_system_my_role2)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role2'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role2)
+ self.assertTrue(hasattr(sys_creds, 'os_system_my_role3'))
+ self.assertEqual(expected_clients, sys_creds.os_system_my_role3)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role3'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role3)
+ self.assertEqual(3, mock_get_client_manager.call_count)
+ self.assertEqual(
+ expected_creds[0][1:],
+ mock_get_client_manager.mock_calls[0][2]['roles'])
+ self.assertEqual(
+ 'system', mock_get_client_manager.mock_calls[0][2]['scope'])
+ self.assertEqual(
+ expected_creds[1][1:],
+ mock_get_client_manager.mock_calls[1][2]['roles'])
+ self.assertEqual(
+ 'system', mock_get_client_manager.mock_calls[1][2]['scope'])
+ self.assertEqual(
+ expected_creds[2][1:],
+ mock_get_client_manager.mock_calls[2][2]['roles'])
+ self.assertEqual(
+ 'system', mock_get_client_manager.mock_calls[2][2]['scope'])
+
+ def test_setup_credentials_with_role_and_multiple_scope(self):
+ expected_creds = [['my_role', 'role1', 'role2'],
+ ['project_my_role', 'role1', 'role2'],
+ ['domain_my_role', 'role1', 'role2'],
+ ['system_my_role', 'role1', 'role2']]
+
+ class SystemRoleCredentials(self.parent_test):
+ credentials = expected_creds
+
+ expected_clients = 'clients'
+ with mock.patch.object(
+ SystemRoleCredentials,
+ 'get_client_manager') as mock_get_client_manager:
+ mock_get_client_manager.return_value = expected_clients
+ sys_creds = SystemRoleCredentials()
+ sys_creds.setup_credentials()
+ self.assertTrue(hasattr(sys_creds, 'os_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_project_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_project_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_project_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_project_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_domain_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_domain_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_domain_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_domain_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_system_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_system_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role)
+
+ self.assertEqual(4, mock_get_client_manager.call_count)
+ self.assertEqual(
+ expected_creds[0][1:],
+ mock_get_client_manager.mock_calls[0][2]['roles'])
+ self.assertEqual(
+ 'project', mock_get_client_manager.mock_calls[0][2]['scope'])
+ self.assertEqual(
+ expected_creds[1][1:],
+ mock_get_client_manager.mock_calls[1][2]['roles'])
+ self.assertEqual(
+ 'project', mock_get_client_manager.mock_calls[1][2]['scope'])
+ self.assertEqual(
+ expected_creds[2][1:],
+ mock_get_client_manager.mock_calls[2][2]['roles'])
+ self.assertEqual(
+ 'domain', mock_get_client_manager.mock_calls[2][2]['scope'])
+ self.assertEqual(
+ expected_creds[3][1:],
+ mock_get_client_manager.mock_calls[3][2]['roles'])
+ self.assertEqual(
+ 'system', mock_get_client_manager.mock_calls[3][2]['scope'])
+
def test_setup_class_overwritten(self):
class OverridesSetup(self.parent_test):
diff --git a/zuul.d/integrated-gate.yaml b/zuul.d/integrated-gate.yaml
index 0a9fb71..4e62d67 100644
--- a/zuul.d/integrated-gate.yaml
+++ b/zuul.d/integrated-gate.yaml
@@ -306,6 +306,12 @@
subnode:
devstack_localrc:
USE_PYTHON3: true
+ devstack_local_conf:
+ post-config:
+ "/$NEUTRON_CORE_PLUGIN_CONF":
+ ovs:
+ bridge_mappings: public:br-ex
+ resource_provider_bandwidths: br-ex:1000000:1000000
- job:
name: tempest-slow