# License for the specific language governing permissions and limitations
# under the License.
-# yardstick comment: this is a modified copy of rally/rally/common/utils.py
-
-from __future__ import absolute_import
-from __future__ import print_function
-
+import collections
+from contextlib import closing
import datetime
import errno
+import importlib
+import ipaddress
import logging
import os
+import random
+import socket
import subprocess
import sys
-import collections
-import socket
-import random
-import ipaddress
-from contextlib import closing
import six
from flask import jsonify
from six.moves import configparser
-from oslo_utils import importutils
from oslo_serialization import jsonutils
import yardstick
-from yardstick.common.yaml_loader import yaml_load
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
yield sub
-def try_append_module(name, modules):
- if name not in modules:
- modules[name] = importutils.import_module(name)
-
-
def import_modules_from_package(package):
- """Import modules from package and append into sys.modules
+ """Import modules given a package name
:param: package - Full package name. For example: rally.deploy.engines
"""
- path = [os.path.dirname(yardstick.__file__), ".."] + package.split(".")
- path = os.path.join(*path)
- for root, dirs, files in os.walk(path):
- for filename in files:
- if filename.startswith("__") or not filename.endswith(".py"):
- continue
- new_package = ".".join(root.split(os.sep)).split("....")[1]
- module_name = "%s.%s" % (new_package, filename[:-3])
+ yardstick_root = os.path.dirname(os.path.dirname(yardstick.__file__))
+ path = os.path.join(yardstick_root, *package.split('.'))
+ for root, _, files in os.walk(path):
+ matches = (filename for filename in files if filename.endswith('.py')
+ and not filename.startswith('__'))
+ new_package = os.path.relpath(root, yardstick_root).replace(os.sep,
+ '.')
+ module_names = set(
+ '{}.{}'.format(new_package, filename.rsplit('.py', 1)[0])
+ for filename in matches)
+ # Find modules which haven't already been imported
+ missing_modules = module_names.difference(sys.modules)
+ logger.debug('Importing modules: %s', missing_modules)
+ for module_name in missing_modules:
try:
- try_append_module(module_name, sys.modules)
- except ImportError:
- logger.exception("unable to import %s", module_name)
-
-
-def parse_yaml(file_path):
- try:
- with open(file_path) as f:
- value = yaml_load(f)
- except IOError:
- return {}
- except OSError as e:
- if e.errno != errno.EEXIST:
- raise
- else:
- return value
+ importlib.import_module(module_name)
+ except (ImportError, SyntaxError):
+ logger.exception('Unable to import module %s', module_name)
def makedirs(d):
def get_free_port(ip):
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
- while True:
+ port = random.randint(5000, 10000)
+ while s.connect_ex((ip, port)) == 0:
port = random.randint(5000, 10000)
- if s.connect_ex((ip, port)) != 0:
- return port
+ return port
def mac_address_to_hex_list(mac):
def validate_non_string_sequence(value, default=None, raise_exc=None):
- if isinstance(value, collections.Sequence) and not isinstance(value, str):
+ # NOTE(ralonsoh): refactor this function to check if raise_exc is an
+ # Exception. Remove duplicate code, this function is duplicated in this
+ # repository.
+ if isinstance(value, collections.Sequence) and not isinstance(value, six.string_types):
return value
if raise_exc:
- raise raise_exc
+ raise raise_exc # pylint: disable=raising-bad-type
return default
return str(separator).join(str(non_string) for non_string in non_strings)
+def safe_decode_utf8(s):
+ """Safe decode a str from UTF"""
+ if six.PY3 and isinstance(s, bytes):
+ return s.decode('utf-8', 'surrogateescape')
+ return s
+
+
class ErrorClass(object):
def __init__(self, *args, **kwargs):