Merge "test_spec: Clarify LTD.Throughput.RFC2544.SystemRecoveryTime"
[vswitchperf.git] / conf / __init__.py
1 # Copyright 2015 Intel Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #   http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 """Settings and configuration handlers.
16
17 Settings will be loaded from several .conf files
18 and any user provided settings file.
19 """
20
21 # pylint: disable=invalid-name
22
23 import os
24 import re
25 import pprint
26
27 class Settings(object):
28     """Holding class for settings.
29     """
30     def __init__(self):
31         pass
32
33     def getValue(self, attr):
34         """Return a settings item value
35         """
36         if attr in self.__dict__:
37             return getattr(self, attr)
38         else:
39             raise AttributeError("%r object has no attribute %r" %
40                                  (self.__class__, attr))
41
42     def __setattr__(self, name, value):
43         """Set a value
44         """
45         # skip non-settings. this should exclude built-ins amongst others
46         if not name.isupper():
47             return
48
49         # we can assume all uppercase keys are valid settings
50         super(Settings, self).__setattr__(name, value)
51
52     def load_from_file(self, path):
53         """Update ``settings`` with values found in module at ``path``.
54         """
55         import imp
56
57         custom_settings = imp.load_source('custom_settings', path)
58
59         for key in dir(custom_settings):
60             if getattr(custom_settings, key) is not None:
61                 setattr(self, key, getattr(custom_settings, key))
62
63     def load_from_dir(self, dir_path):
64         """Update ``settings`` with contents of the .conf files at ``path``.
65
66         Each file must be named Nfilename.conf, where N is a single or
67         multi-digit decimal number.  The files are loaded in ascending order of
68         N - so if a configuration item exists in more that one file the setting
69         in the file with the largest value of N takes precedence.
70
71         :param dir_path: The full path to the dir from which to load the .conf
72             files.
73
74         :returns: None
75         """
76         regex = re.compile("^(?P<digit_part>[0-9]+).*.conf$")
77
78         def get_prefix(filename):
79             """
80             Provide a suitable function for sort's key arg
81             """
82             match_object = regex.search(os.path.basename(filename))
83             return int(match_object.group('digit_part'))
84
85         # get full file path to all files & dirs in dir_path
86         file_paths = os.listdir(dir_path)
87         file_paths = [os.path.join(dir_path, x) for x in file_paths]
88
89         # filter to get only those that are a files, with a leading
90         # digit and end in '.conf'
91         file_paths = [x for x in file_paths if os.path.isfile(x) and
92                       regex.search(os.path.basename(x))]
93
94         # sort ascending on the leading digits
95         file_paths.sort(key=get_prefix)
96
97         # load settings from each file in turn
98         for filepath in file_paths:
99             self.load_from_file(filepath)
100
101     def load_from_dict(self, conf):
102         """
103         Update ``settings`` with values found in ``conf``.
104
105         Unlike the other loaders, this is case insensitive.
106         """
107         for key in conf:
108             if conf[key] is not None:
109                 setattr(self, key.upper(), conf[key])
110
111     def load_from_env(self):
112         """
113         Update ``settings`` with values found in the environment.
114         """
115         for key in os.environ:
116             setattr(self, key, os.environ[key])
117
118     def __str__(self):
119         """Provide settings as a human-readable string.
120
121         This can be useful for debug.
122
123         Returns:
124             A human-readable string.
125         """
126         return pprint.pformat(self.__dict__)
127
128
129 settings = Settings()
130
131
132 def get_test_param(key, default=None):
133     """Retrieve value for test param ``key`` if available.
134
135     :param key: Key to retrieve from test params.
136     :param default: Default to return if key not found.
137
138     :returns: Value for ``key`` if found, else ``default``.
139     """
140     test_params = settings.getValue('TEST_PARAMS')
141     return test_params.get(key, default) if test_params else default