Merge "Remove multisite support"
[functest.git] / functest / api / common / api_utils.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2017 Huawei Technologies Co.,Ltd and others.
4 #
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9
10 """
11 Utils for functest restapi
12
13 """
14
15 import collections
16 import logging
17 import os
18 import sys
19 from oslo_utils import importutils
20
21 import six
22
23 import functest
24
25 LOGGER = logging.getLogger(__name__)
26
27
28 def change_to_str_in_dict(obj):
29     """
30     Return a dict with key and value both in string if they are in Unicode
31     """
32     if isinstance(obj, collections.Mapping):
33         return {str(k): change_to_str_in_dict(v) for k, v in obj.items()}
34     elif isinstance(obj, list):
35         return [change_to_str_in_dict(ele) for ele in obj]
36     elif isinstance(obj, six.text_type):
37         return str(obj)
38     return obj
39
40
41 def itersubclasses(cls, _seen=None):
42     """ Generator over all subclasses of a given class in depth first order """
43
44     if not isinstance(cls, type):
45         raise TypeError("itersubclasses must be called with "
46                         "new-style classes, not %.100r" % cls)
47     _seen = _seen or set()
48     try:
49         subs = cls.__subclasses__()
50     except TypeError:   # fails only when cls is type
51         subs = cls.__subclasses__(cls)
52     for sub in subs:
53         if sub not in _seen:
54             _seen.add(sub)
55             yield sub
56             for itersub in itersubclasses(sub, _seen):
57                 yield itersub
58
59
60 def import_modules_from_package(package):
61     """
62     Import modules from package and append into sys.modules
63     :param: package - Full package name. For example: functest.api.resources
64     """
65     path = [os.path.dirname(functest.__file__), ".."] + package.split(".")
66     path = os.path.join(*path)
67     for root, _, files in os.walk(path):
68         for filename in files:
69             if filename.startswith("__") or not filename.endswith(".py"):
70                 continue
71             new_package = ".".join(root.split(os.sep)).split("....")[1]
72             module_name = "%s.%s" % (new_package, filename[:-3])
73             try:
74                 try_append_module(module_name, sys.modules)
75             except ImportError:
76                 LOGGER.exception("unable to import %s", module_name)
77
78
79 def try_append_module(name, modules):
80     """ Append the module into specified module system """
81
82     if name not in modules:
83         modules[name] = importutils.import_module(name)
84
85
86 def change_obj_to_dict(obj):
87     """  Transfer the object into dict """
88     dic = {}
89     for key, value in vars(obj).items():
90         dic.update({key: value})
91     return dic