aboutsummaryrefslogtreecommitdiffstats
path: root/functest/utils/functest_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'functest/utils/functest_utils.py')
-rw-r--r--functest/utils/functest_utils.py105
1 files changed, 80 insertions, 25 deletions
diff --git a/functest/utils/functest_utils.py b/functest/utils/functest_utils.py
index 42c1edc9b..eec544489 100644
--- a/functest/utils/functest_utils.py
+++ b/functest/utils/functest_utils.py
@@ -11,10 +11,12 @@
from __future__ import print_function
import logging
+import os
import subprocess
import sys
import yaml
+from shade import _utils
import six
LOGGER = logging.getLogger(__name__)
@@ -30,28 +32,26 @@ def execute_command_raise(cmd, info=False, error_msg="",
def execute_command(cmd, info=False, error_msg="",
verbose=True, output_file=None):
if not error_msg:
- error_msg = ("The command '%s' failed." % cmd)
- msg_exec = ("Executing command: '%s'" % cmd)
+ error_msg = f"The command '{cmd}' failed."
+ msg_exec = f"Executing command: '{cmd}'"
if verbose:
if info:
LOGGER.info(msg_exec)
else:
LOGGER.debug(msg_exec)
- popen = subprocess.Popen(
- cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- if output_file:
- ofd = open(output_file, "w")
- for line in iter(popen.stdout.readline, b''):
+ with subprocess.Popen(
+ cmd, shell=True, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT) as popen:
if output_file:
- ofd.write(line.decode("utf-8"))
- else:
- line = line.decode("utf-8").replace('\n', '')
- print(line)
- sys.stdout.flush()
- if output_file:
- ofd.close()
- popen.stdout.close()
- returncode = popen.wait()
+ with open(output_file, "w", encoding='utf-8') as ofd:
+ for line in iter(popen.stdout.readline, b''):
+ if output_file:
+ ofd.write(line.decode("utf-8"))
+ else:
+ line = line.decode("utf-8").replace('\n', '')
+ print(line)
+ sys.stdout.flush()
+ returncode = popen.wait()
if returncode != 0:
if verbose:
LOGGER.error(error_msg)
@@ -65,14 +65,14 @@ def get_parameter_from_yaml(parameter, yfile):
parameter must be given in string format with dots
Example: general.openstack.image_name
"""
- with open(yfile) as yfd:
+ with open(yfile, encoding='utf-8') as yfd:
file_yaml = yaml.safe_load(yfd)
value = file_yaml
for element in parameter.split("."):
value = value.get(element)
if value is None:
- raise ValueError("The parameter %s is not defined in"
- " %s" % (parameter, yfile))
+ raise ValueError(f"The parameter {parameter} is not defined in"
+ f" {yfile}")
return value
@@ -108,11 +108,22 @@ def get_openstack_version(cloud):
- OpenStack release
- Unknown on operation error
"""
+ # pylint: disable=too-many-branches
version = get_nova_version(cloud)
try:
assert version
- if version > (2, 72):
+ if version > (2, 93):
osversion = "Master"
+ elif version > (2, 90):
+ osversion = "Zed"
+ elif version > (2, 88):
+ osversion = "Xena"
+ elif version > (2, 87):
+ osversion = "Wallaby"
+ elif version > (2, 79):
+ osversion = "Ussuri"
+ elif version > (2, 72):
+ osversion = "Train"
elif version > (2, 65):
osversion = "Stein"
elif version > (2, 60):
@@ -140,24 +151,68 @@ def get_openstack_version(cloud):
return "Unknown"
+def list_services(cloud):
+ # pylint: disable=protected-access
+ """Search Keystone services via $OS_INTERFACE.
+
+ It mainly conforms with `Shade
+ <https://docs.openstack.org/shade/latest>`_ but allows testing vs
+ public endpoints. It's worth mentioning that it doesn't support keystone
+ v2.
+
+ :returns: a list of ``munch.Munch`` containing the services description
+
+ :raises: ``OpenStackCloudException`` if something goes wrong during the
+ openstack API call.
+ """
+ url, key = '/services', 'services'
+ data = cloud._identity_client.get(
+ url, endpoint_filter={
+ 'interface': os.environ.get('OS_INTERFACE', 'public')},
+ error_message="Failed to list services")
+ services = cloud._get_and_munchify(key, data)
+ return _utils.normalize_keystone_services(services)
+
+
+def search_services(cloud, name_or_id=None, filters=None):
+ # pylint: disable=protected-access
+ """Search Keystone services ia $OS_INTERFACE.
+
+ It mainly conforms with `Shade
+ <https://docs.openstack.org/shade/latest>`_ but allows testing vs
+ public endpoints. It's worth mentioning that it doesn't support keystone
+ v2.
+
+ :param name_or_id: Name or id of the desired service.
+ :param filters: a dict containing additional filters to use. e.g.
+ {'type': 'network'}.
+
+ :returns: a list of ``munch.Munch`` containing the services description
+
+ :raises: ``OpenStackCloudException`` if something goes wrong during the
+ openstack API call.
+ """
+ services = list_services(cloud)
+ return _utils._filter_list(services, name_or_id, filters)
+
+
def convert_dict_to_ini(value):
"Convert dict to oslo.conf input"
assert isinstance(value, dict)
- return ",".join("{}:{}".format(
- key, val) for (key, val) in six.iteritems(value))
+ return ",".join(f"{key}:{val}" for (key, val) in six.iteritems(value))
def convert_list_to_ini(value):
"Convert list to oslo.conf input"
assert isinstance(value, list)
- return ",".join("{}".format(val) for val in value)
+ return ",".join(val for val in value)
def convert_ini_to_dict(value):
"Convert oslo.conf input to dict"
assert isinstance(value, str)
try:
- return {k: v for k, v in (x.rsplit(':', 1) for x in value.split(','))}
+ return dict((x.rsplit(':', 1) for x in value.split(',')))
except ValueError:
return {}
@@ -167,4 +222,4 @@ def convert_ini_to_list(value):
assert isinstance(value, str)
if not value:
return []
- return [x for x in value.split(',')]
+ return list(value.split(','))