summaryrefslogtreecommitdiffstats
path: root/conf/__init__.py
diff options
context:
space:
mode:
authorMartin Klozik <martinx.klozik@intel.com>2016-12-14 14:02:43 +0000
committerMartin Klozik <martinx.klozik@intel.com>2017-01-16 08:50:02 +0000
commit4481df385ac03ece015ccb429201f96189dc5ae2 (patch)
treea959a804e7b1efd663dbb24a447609421e339211 /conf/__init__.py
parentcafcb9f24b422a4b3a0b19ba00c83fe2819dcbaa (diff)
traffic: Configurable traffic details
Traffic generated by traffic generator is based on default values and their modifications specific to particular testing scenario. Traffic default values were defined inside VSPERF code and it was not possible to change them. This patch introduces new TRAFFIC dictionary inside 03_traffic.conf. Thus user can modify any of TRAFFIC values either in configuration file or by CLI or by 'Parameters' section of testcase definition. Following CLI options were obsoleted by this patch: 'bidirectional', 'traffic_type', 'iload', 'multistream', 'stream_type' and 'pre-installed_flows' Following CLI option was renamed to be consistent with other options: 'tunnel_type' => 'TUNNEL_TYPE' Following sections of testcase definition were obsoleted: "Traffic Type", "biDirectional", "MultiStream", "Stream Type", "Pre-installed Flows", "Flow Type" and "iLoad" New TRAFFIC dictionary should be used instead of old CLI options and old testcase definition sections. Testcase definitons, yardstick sample testcases and documentation were updated to reflect configuration changes. JIRA: VSPERF-433 Change-Id: I03a388c766491d5688e715f6d7b51e8e0377ec27 Signed-off-by: Martin Klozik <martinx.klozik@intel.com> Reviewed-by: Al Morton <acmorton@att.com> Reviewed-by: Christian Trautman <ctrautma@redhat.com> Reviewed-by: Bill Michalowski <bmichalo@redhat.com> Reviewed-by: Antonio Fischetti <antonio.fischetti@intel.com> Reviewed-by: <sridhar.rao@spirent.com>
Diffstat (limited to 'conf/__init__.py')
-rw-r--r--conf/__init__.py67
1 files changed, 49 insertions, 18 deletions
diff --git a/conf/__init__.py b/conf/__init__.py
index 2448d390..2a2586ff 100644
--- a/conf/__init__.py
+++ b/conf/__init__.py
@@ -20,6 +20,7 @@ and any user provided settings file.
# pylint: disable=invalid-name
+import copy
import os
import re
import logging
@@ -30,8 +31,7 @@ import netaddr
_LOGGER = logging.getLogger(__name__)
# Special test parameters which are not part of standard VSPERF configuration
-_EXTRA_TEST_PARAMS = ['bidirectional', 'traffic_type', 'iload', 'tunnel_type',
- 'multistream', 'stream_type', 'pre-installed_flows']
+_EXTRA_TEST_PARAMS = ['TUNNEL_TYPE']
# regex to parse configuration macros from 04_vnf.conf
# it will select all patterns starting with # sign
@@ -57,9 +57,19 @@ class Settings(object):
return getattr(self, attr)
else:
master_value = getattr(self, attr)
- # Check if parameter value was overridden by CLI option
+ # Check if parameter value was modified by CLI option
cli_value = get_test_param(attr, None)
- return cli_value if cli_value else master_value
+ if cli_value:
+ # 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
+ else:
+ return cli_value
+ else:
+ return master_value
else:
raise AttributeError("%r object has no attribute %r" %
(self.__class__, attr))
@@ -137,7 +147,12 @@ class Settings(object):
"""
for key in conf:
if conf[key] is not None:
- setattr(self, key.upper(), conf[key])
+ if isinstance(conf[key], dict):
+ # recursively update dict items, e.g. TEST_PARAMS
+ setattr(self, key.upper(),
+ merge_spec(getattr(self, key.upper()), conf[key]))
+ else:
+ setattr(self, key.upper(), conf[key])
def load_from_env(self):
"""
@@ -271,17 +286,33 @@ def get_test_param(key, default=None):
:returns: Value for ``key`` if found, else ``default``.
"""
test_params = settings.getValue('TEST_PARAMS')
- if key in test_params:
- if not isinstance(test_params.get(key), str):
- return test_params.get(key)
+ return test_params.get(key, default) if test_params else default
+
+def merge_spec(orig, new):
+ """Merges ``new`` dict with ``orig`` dict, and returns orig.
+
+ This takes into account nested dictionaries. Example:
+
+ >>> old = {'foo': 1, 'bar': {'foo': 2, 'bar': 3}}
+ >>> new = {'foo': 6, 'bar': {'foo': 7}}
+ >>> merge_spec(old, new)
+ {'foo': 6, 'bar': {'foo': 7, 'bar': 3}}
+
+ You'll notice that ``bar.bar`` is not removed. This is the desired result.
+ """
+ for key in orig:
+ if key not in new:
+ continue
+
+ # Not allowing derived dictionary types for now
+ # pylint: disable=unidiomatic-typecheck
+ if type(orig[key]) == dict:
+ orig[key] = merge_spec(orig[key], new[key])
else:
- # values are passed inside string from CLI, so we must retype them accordingly
- try:
- return ast.literal_eval(test_params.get(key))
- except ValueError:
- # for backward compatibility, we have to accept strings without quotes
- _LOGGER.warning("Adding missing quotes around string value: %s = %s",
- key, str(test_params.get(key)))
- return str(test_params.get(key))
- else:
- return default
+ orig[key] = new[key]
+
+ for key in new:
+ if key not in orig:
+ orig[key] = new[key]
+
+ return orig