Merge "ci in huawei-pod1 do not run test case after tc074"
[yardstick.git] / yardstick / common / utils.py
1 # Copyright 2013: Mirantis Inc.
2 # All Rights Reserved.
3 #
4 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
5 #    not use this file except in compliance with the License. You may obtain
6 #    a copy of the License at
7 #
8 #         http://www.apache.org/licenses/LICENSE-2.0
9 #
10 #    Unless required by applicable law or agreed to in writing, software
11 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 #    License for the specific language governing permissions and limitations
14 #    under the License.
15
16 # yardstick comment: this is a modified copy of rally/rally/common/utils.py
17
18 from __future__ import absolute_import
19 from __future__ import print_function
20
21 import errno
22 import logging
23 import os
24 import subprocess
25 import sys
26 from functools import reduce
27
28 import yaml
29 from oslo_utils import importutils
30 from oslo_serialization import jsonutils
31
32 import yardstick
33
34 logger = logging.getLogger(__name__)
35 logger.setLevel(logging.DEBUG)
36
37
38 # Decorator for cli-args
39 def cliargs(*args, **kwargs):
40     def _decorator(func):
41         func.__dict__.setdefault('arguments', []).insert(0, (args, kwargs))
42         return func
43     return _decorator
44
45
46 def itersubclasses(cls, _seen=None):
47     """Generator over all subclasses of a given class in depth first order."""
48
49     if not isinstance(cls, type):
50         raise TypeError("itersubclasses must be called with "
51                         "new-style classes, not %.100r" % cls)
52     _seen = _seen or set()
53     try:
54         subs = cls.__subclasses__()
55     except TypeError:   # fails only when cls is type
56         subs = cls.__subclasses__(cls)
57     for sub in subs:
58         if sub not in _seen:
59             _seen.add(sub)
60             yield sub
61             for sub in itersubclasses(sub, _seen):
62                 yield sub
63
64
65 def try_append_module(name, modules):
66     if name not in modules:
67         modules[name] = importutils.import_module(name)
68
69
70 def import_modules_from_package(package):
71     """Import modules from package and append into sys.modules
72
73     :param: package - Full package name. For example: rally.deploy.engines
74     """
75     path = [os.path.dirname(yardstick.__file__), ".."] + package.split(".")
76     path = os.path.join(*path)
77     for root, dirs, files in os.walk(path):
78         for filename in files:
79             if filename.startswith("__") or not filename.endswith(".py"):
80                 continue
81             new_package = ".".join(root.split(os.sep)).split("....")[1]
82             module_name = "%s.%s" % (new_package, filename[:-3])
83             try_append_module(module_name, sys.modules)
84
85
86 def get_para_from_yaml(file_path, args):
87
88     def func(a, b):
89         if a is None:
90             return None
91         return a.get(b)
92
93     if os.path.exists(file_path):
94         with open(file_path) as f:
95             value = yaml.safe_load(f)
96             value = reduce(func, args.split('.'), value)
97
98             if value is None:
99                 print('parameter not found')
100                 return None
101
102             return value
103     else:
104         print('file not exist')
105         return None
106
107
108 def makedirs(d):
109     try:
110         os.makedirs(d)
111     except OSError as e:
112         if e.errno != errno.EEXIST:
113             raise
114
115
116 def execute_command(cmd):
117     exec_msg = "Executing command: '%s'" % cmd
118     logger.debug(exec_msg)
119
120     output = subprocess.check_output(cmd.split()).split(os.linesep)
121
122     return output
123
124
125 def source_env(env_file):
126     p = subprocess.Popen(". %s; env" % env_file, stdout=subprocess.PIPE,
127                          shell=True)
128     output = p.communicate()[0]
129     env = dict((line.split('=', 1) for line in output.splitlines()))
130     os.environ.update(env)
131     return env
132
133
134 def read_json_from_file(path):
135     with open(path, 'r') as f:
136         return jsonutils.load(f)
137
138
139 def write_json_to_file(path, data, mode='w'):
140     with open(path, mode) as f:
141         jsonutils.dump(data, f)
142
143
144 def write_file(path, data, mode='w'):
145     with open(path, mode) as f:
146         f.write(data)