From: Ondrej Lichtner <olichtne(a)redhat.com>
This patch makes it so that we change into the directory containing the
python task before running it. This ensures that the developer can use
file paths relative to the location of the python taks.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Controller/NetTestController.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lnst/Controller/NetTestController.py b/lnst/Controller/NetTestController.py
index eeb6426..5c2695d 100644
--- a/lnst/Controller/NetTestController.py
+++ b/lnst/Controller/NetTestController.py
@@ -682,10 +682,13 @@ class NetTestController:
# Initialize the API handle
Task.ctl = Task.ControllerAPI(self, self._machines)
+ cwd = os.getcwd()
task_path = task["python"]
name = os.path.basename(task_path.abs_path()).split(".")[0]
sys.path.append(os.path.dirname(task_path.resolve()))
+ os.chdir(os.path.dirname(task_path.resolve()))
module = imp.load_source(name, task_path.resolve())
+ os.chdir(cwd)
sys.path.remove(os.path.dirname(task_path.resolve()))
#restore resource table
--
2.1.0
Show replies by date
From: Ondrej Lichtner <olichtne(a)redhat.com>
Exception tracebacks of commands should be logged to make problem
solving and debugging easier.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Common/NetTestCommand.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lnst/Common/NetTestCommand.py b/lnst/Common/NetTestCommand.py
index cfa2b3b..f872a12 100644
--- a/lnst/Common/NetTestCommand.py
+++ b/lnst/Common/NetTestCommand.py
@@ -21,6 +21,7 @@ import re
from time import time
from lnst.Common.ExecCmd import exec_cmd, ExecCmdFail
from lnst.Common.ConnectionHandler import recv_data, send_data
+from lnst.Common.Logs import log_exc_traceback
DEFAULT_TIMEOUT = 60
@@ -157,6 +158,7 @@ class NetTestCommand:
except (KeyboardInterrupt, SystemExit):
pass
except:
+ log_exc_traceback()
type, value, tb = sys.exc_info()
data = {"Exception": "%s" % value}
self._cmd_cls.set_fail(data)
--
2.1.0
From: Ondrej Lichtner <olichtne(a)redhat.com>
This function returns the standard deviation of a list of numbers. This
will be used in the NetPerf module.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Common/Utils.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/lnst/Common/Utils.py b/lnst/Common/Utils.py
index 6884dfa..39c851f 100644
--- a/lnst/Common/Utils.py
+++ b/lnst/Common/Utils.py
@@ -19,6 +19,7 @@ import subprocess
import errno
import ast
import collections
+import math
from _ast import Call, Attribute
from lnst.Common.ExecCmd import exec_cmd
@@ -244,3 +245,11 @@ def dict_to_dot(original_dict, prefix=""):
else:
return_list.append((prefix+key, str(value)))
return return_list
+
+def std_deviation(values):
+ s1 = 0.0
+ s2 = 0.0
+ for val in values:
+ s1 += val
+ s2 += val**2
+ return (math.sqrt(len(values)*s2 - s1**2))/len(values)
--
2.1.0
From: Ondrej Lichtner <olichtne(a)redhat.com>
Options are stored as tuples which caused problems when serializing them
for PerfRepo. This needs to be properly fixed by replacing tuples with
dictionaries but that might cause different problems elsewhere so for
now I'm submitting this temporary fix.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Common/Utils.py | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/lnst/Common/Utils.py b/lnst/Common/Utils.py
index 39c851f..fd86a8e 100644
--- a/lnst/Common/Utils.py
+++ b/lnst/Common/Utils.py
@@ -229,6 +229,10 @@ def list_to_dot(original_list, prefix="",
key=""):
return_list.extend(sub_list)
elif isinstance(value, list):
raise Exception("Nested lists not allowed")
+ elif isinstance(value, tuple):
+ #TODO temporary fix, tuples shouldn't be here
+ if len(value) == 2:
+ return_list.append((iter_key+'.'+value[0], value[1]))
else:
return_list.append((iter_key, value))
return return_list
@@ -242,6 +246,10 @@ def dict_to_dot(original_dict, prefix=""):
elif isinstance(value, list):
sub_list = list_to_dot(value, prefix, key)
return_list.extend(sub_list)
+ elif isinstance(value, tuple):
+ #TODO temporary fix, tuples shouldn't be here
+ if len(value) == 2:
+ return_list.append((iter_key+'.'+value[0], value[1]))
else:
return_list.append((prefix+key, str(value)))
return return_list
--
2.1.0
From: Ondrej Lichtner <olichtne(a)redhat.com>
This commit fixes a copy paste mistake when calling get_option to
retrieve url, username and password to access a PerfRepo instance.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Controller/Task.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lnst/Controller/Task.py b/lnst/Controller/Task.py
index 529d134..e350679 100644
--- a/lnst/Controller/Task.py
+++ b/lnst/Controller/Task.py
@@ -108,9 +108,9 @@ class ControllerAPI(object):
if url is None:
url = lnst_config.get_option("perfrepo", "url")
if username is None:
- url = lnst_config.get_option("perfrepo", "username")
+ username = lnst_config.get_option("perfrepo",
"username")
if password is None:
- url = lnst_config.get_option("perfrepo", "password")
+ password = lnst_config.get_option("perfrepo",
"password")
self._perf_repo_api.connect(url, username, password)
return self._perf_repo_api
--
2.1.0
From: Ondrej Lichtner <olichtne(a)redhat.com>
This gives us the ability to reuse the same ModuleAPI object multiple
times but with different options.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Controller/Task.py | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/lnst/Controller/Task.py b/lnst/Controller/Task.py
index e350679..e69c348 100644
--- a/lnst/Controller/Task.py
+++ b/lnst/Controller/Task.py
@@ -14,6 +14,7 @@ from lnst.Controller.PerfRepo import PerfRepoRESTAPI
from lnst.Controller.PerfRepo import PerfRepoTestExecution
from lnst.Controller.PerfRepo import PerfRepoValue
from lnst.Common.Utils import dot_to_dict, dict_to_dot, list_to_dot
+from lnst.Common.Utils import recursive_dict_update
from lnst.Common.Config import lnst_config
# The handle to be imported from each task
@@ -391,6 +392,15 @@ class ModuleAPI(object):
else:
self._opts[opt].append({"value": str(val)})
+ def update_options(self, options):
+ for opt, val in options.iteritems():
+ self._opts[opt] = []
+ if type(val) == list:
+ for v in val:
+ self._opts[opt].append({"value": str(v)})
+ else:
+ self._opts[opt].append({"value": str(val)})
+
class ProcessAPI(object):
""" An API class representing either a running or finished process.
"""
--
2.1.0
From: Ondrej Lichtner <olichtne(a)redhat.com>
These will be used from the Python Task PerfRepo API.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Controller/PerfRepo.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lnst/Controller/PerfRepo.py b/lnst/Controller/PerfRepo.py
index 21d1eaa..ffc29d5 100644
--- a/lnst/Controller/PerfRepo.py
+++ b/lnst/Controller/PerfRepo.py
@@ -207,9 +207,15 @@ class PerfRepoTestExecution(PerfRepoObject):
def add_tag(self, tag):
self._tags.append(tag)
+ def get_tags(self):
+ return self._tags
+
def add_parameter(self, name, value):
self._parameters.append((name, value))
+ def get_parameters(self):
+ return self._parameters
+
def to_xml(self):
root = Element('testExecution')
self._set_element_atrib(root, 'id', self._id)
--
2.1.0
From: Ondrej Lichtner <olichtne(a)redhat.com>
This method computes a sha1 hash of the PerfRepoTestExecution object.
this hash can be used as an id for mapping to report ids while we don't
have a better solution. The hash is computed from the objects parameters
and tags that are ordered to ensure determinism between runs.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Controller/Task.py | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/lnst/Controller/Task.py b/lnst/Controller/Task.py
index e69c348..ccbd299 100644
--- a/lnst/Controller/Task.py
+++ b/lnst/Controller/Task.py
@@ -10,6 +10,7 @@ __author__ = """
rpazdera(a)redhat.com (Radek Pazdera)
"""
+import hashlib
from lnst.Controller.PerfRepo import PerfRepoRESTAPI
from lnst.Controller.PerfRepo import PerfRepoTestExecution
from lnst.Controller.PerfRepo import PerfRepoValue
@@ -575,3 +576,15 @@ class PerfRepoResult(object):
def get_testExecution(self):
return self._testExecution
+
+ def generate_hash(self):
+ tags = self._testExecution.get_tags()
+ params = self._testExecution.get_parameters()
+
+ sha1 = hashlib.sha1()
+ for i in sorted(tags):
+ sha1.update(i)
+ for i in sorted(params, key=lambda x: x[0]):
+ sha1.update(i[0])
+ sha1.update(i[1])
+ return sha1.hexdigest()
--
2.1.0