paths: Modify algorithm for PATHS verification
[vswitchperf.git] / conf / __init__.py
index 2a2586f..808cfc9 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2015-2016 Intel Corporation.
+# Copyright 2015-2017 Intel Corporation.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -49,6 +49,40 @@ class Settings(object):
     def __init__(self):
         pass
 
+    def _eval_param(self, param):
+        # pylint: disable=invalid-name
+        """ Helper function for expansion of references to vsperf parameters
+        """
+        if isinstance(param, str):
+            # evaluate every #PARAM reference inside parameter itself
+            macros = re.findall(r'#PARAM\((([\w\-]+)(\[[\w\[\]\-\'\"]+\])*)\)', param)
+            if macros:
+                for macro in macros:
+                    # pylint: disable=eval-used
+                    try:
+                        tmp_val = str(eval("self.getValue('{}'){}".format(macro[1], macro[2])))
+                        param = param.replace('#PARAM({})'.format(macro[0]), tmp_val)
+                    # silently ignore that option required by PARAM macro can't be evaluated;
+                    # It is possible, that referred parameter will be constructed during runtime
+                    # and re-read later.
+                    except IndexError:
+                        pass
+                    except AttributeError:
+                        pass
+            return param
+        elif isinstance(param, list) or isinstance(param, tuple):
+            tmp_list = []
+            for item in param:
+                tmp_list.append(self._eval_param(item))
+            return tmp_list
+        elif isinstance(param, dict):
+            tmp_dict = {}
+            for (key, value) in param.items():
+                tmp_dict[key] = self._eval_param(value)
+            return tmp_dict
+        else:
+            return param
+
     def getValue(self, attr):
         """Return a settings item value
         """
@@ -59,17 +93,17 @@ class Settings(object):
                 master_value = getattr(self, attr)
                 # Check if parameter value was modified by CLI option
                 cli_value = get_test_param(attr, None)
-                if cli_value:
+                if cli_value is not None:
                     # TRAFFIC dictionary is not overridden by CLI option
                     # but only updated by specified values
                     if attr == 'TRAFFIC':
                         tmp_value = copy.deepcopy(master_value)
                         tmp_value = merge_spec(tmp_value, cli_value)
-                        return tmp_value
+                        return self._eval_param(tmp_value)
                     else:
-                        return cli_value
+                        return self._eval_param(cli_value)
                 else:
-                    return master_value
+                    return self._eval_param(master_value)
         else:
             raise AttributeError("%r object has no attribute %r" %
                                  (self.__class__, attr))
@@ -114,14 +148,15 @@ class Settings(object):
 
         :returns: None
         """
-        regex = re.compile("^(?P<digit_part>[0-9]+).*.conf$")
+        regex = re.compile("^(?P<digit_part>[0-9]+)(?P<alfa_part>[a-z]?)_.*.conf$")
 
         def get_prefix(filename):
             """
             Provide a suitable function for sort's key arg
             """
             match_object = regex.search(os.path.basename(filename))
-            return int(match_object.group('digit_part'))
+            return [int(match_object.group('digit_part')),
+                    match_object.group('alfa_part')]
 
         # get full file path to all files & dirs in dir_path
         file_paths = os.listdir(dir_path)
@@ -132,7 +167,7 @@ class Settings(object):
         file_paths = [x for x in file_paths if os.path.isfile(x) and
                       regex.search(os.path.basename(x))]
 
-        # sort ascending on the leading digits
+        # sort ascending on the leading digits and afla (e.g. 03_, 05a_)
         file_paths.sort(key=get_prefix)
 
         # load settings from each file in turn
@@ -189,7 +224,7 @@ class Settings(object):
         for key in self.__dict__:
             if key.startswith('GUEST_'):
                 value = self.getValue(key)
-                if isinstance(value, str) and value.find('#') >= 0:
+                if isinstance(value, str) and str(value).find('#') >= 0:
                     self._expand_vm_settings(key, 1)
 
                 if isinstance(value, list):
@@ -266,7 +301,9 @@ class Settings(object):
     def validate_getValue(self, result, attr):
         """Verifies, that correct value was returned
         """
-        assert result == self.__dict__[attr]
+        # getValue must be called to expand macros and apply
+        # values from TEST_PARAM option
+        assert result == self.getValue(attr)
         return True
 
     def validate_setValue(self, dummy_result, name, value):