1 # Copyright 2015 Intel Corporation.
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
15 """Settings and configuration handlers.
17 Settings will be loaded from several .conf files
18 and any user provided settings file.
21 # pylint: disable=invalid-name
27 class Settings(object):
28 """Holding class for settings.
33 def getValue(self, attr):
34 """Return a settings item value
36 if attr in self.__dict__:
37 return getattr(self, attr)
39 raise AttributeError("%r object has no attribute %r" %
40 (self.__class__, attr))
42 def __setattr__(self, name, value):
45 # skip non-settings. this should exclude built-ins amongst others
46 if not name.isupper():
49 # we can assume all uppercase keys are valid settings
50 super(Settings, self).__setattr__(name, value)
52 def setValue(self, name, value):
55 if name is not None and value is not None:
56 super(Settings, self).__setattr__(name, value)
58 def load_from_file(self, path):
59 """Update ``settings`` with values found in module at ``path``.
63 custom_settings = imp.load_source('custom_settings', path)
65 for key in dir(custom_settings):
66 if getattr(custom_settings, key) is not None:
67 setattr(self, key, getattr(custom_settings, key))
69 def load_from_dir(self, dir_path):
70 """Update ``settings`` with contents of the .conf files at ``path``.
72 Each file must be named Nfilename.conf, where N is a single or
73 multi-digit decimal number. The files are loaded in ascending order of
74 N - so if a configuration item exists in more that one file the setting
75 in the file with the largest value of N takes precedence.
77 :param dir_path: The full path to the dir from which to load the .conf
82 regex = re.compile("^(?P<digit_part>[0-9]+).*.conf$")
84 def get_prefix(filename):
86 Provide a suitable function for sort's key arg
88 match_object = regex.search(os.path.basename(filename))
89 return int(match_object.group('digit_part'))
91 # get full file path to all files & dirs in dir_path
92 file_paths = os.listdir(dir_path)
93 file_paths = [os.path.join(dir_path, x) for x in file_paths]
95 # filter to get only those that are a files, with a leading
96 # digit and end in '.conf'
97 file_paths = [x for x in file_paths if os.path.isfile(x) and
98 regex.search(os.path.basename(x))]
100 # sort ascending on the leading digits
101 file_paths.sort(key=get_prefix)
103 # load settings from each file in turn
104 for filepath in file_paths:
105 self.load_from_file(filepath)
107 def load_from_dict(self, conf):
109 Update ``settings`` with values found in ``conf``.
111 Unlike the other loaders, this is case insensitive.
114 if conf[key] is not None:
115 setattr(self, key.upper(), conf[key])
117 def load_from_env(self):
119 Update ``settings`` with values found in the environment.
121 for key in os.environ:
122 setattr(self, key, os.environ[key])
125 """Provide settings as a human-readable string.
127 This can be useful for debug.
130 A human-readable string.
132 return pprint.pformat(self.__dict__)
135 settings = Settings()
138 def get_test_param(key, default=None):
139 """Retrieve value for test param ``key`` if available.
141 :param key: Key to retrieve from test params.
142 :param default: Default to return if key not found.
144 :returns: Value for ``key`` if found, else ``default``.
146 test_params = settings.getValue('TEST_PARAMS')
147 return test_params.get(key, default) if test_params else default