commit 19ab0b521068c222cdd5afea76efd4ead06a85f7 Author: CentOS Sources Date: Thu Aug 1 11:13:17 2019 -0400 import rteval-2.14-25.el8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d6c5df1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/rteval-2.14.tar.bz2 diff --git a/.rteval.metadata b/.rteval.metadata new file mode 100644 index 0000000..4f9340b --- /dev/null +++ b/.rteval.metadata @@ -0,0 +1 @@ +d59b224576a8c1106d4cde856158814a6bfe9fb2 SOURCES/rteval-2.14.tar.bz2 diff --git a/SOURCES/python-setup.py-Comment-out-os.unlink.patch b/SOURCES/python-setup.py-Comment-out-os.unlink.patch new file mode 100644 index 0000000..87335f2 --- /dev/null +++ b/SOURCES/python-setup.py-Comment-out-os.unlink.patch @@ -0,0 +1,30 @@ +From 7768ab5bc6b1c428de1dd1b3d9a4340bd020a2cd Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Wed, 30 May 2018 13:17:36 +0100 +Subject: [PATCH] python: setup.py: Comment out os.unlink + +Comment out os.unlink('dist/__init__.pyc') +as a temporary fix + +Signed-off-by: John Kacur +--- + setup.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/setup.py b/setup.py +index 95efa905f4d1..9a76ffbf89be 100644 +--- a/setup.py ++++ b/setup.py +@@ -79,7 +79,8 @@ mean, variance and standard deviation) and a report is generated. + os.unlink('dist/rteval') + os.unlink('dist/rteval.8.gz') + os.unlink('dist/__init__.py') +-os.unlink('dist/__init__.pyc') ++# TODO FIX THIS, or at least find out why it was there ++#os.unlink('dist/__init__.pyc') + + if distcreated: + try: +-- +2.14.3 + diff --git a/SOURCES/rteval-2to3-transformations.patch b/SOURCES/rteval-2to3-transformations.patch new file mode 100644 index 0000000..e57f118 --- /dev/null +++ b/SOURCES/rteval-2to3-transformations.patch @@ -0,0 +1,1617 @@ +From fd3b732f714da07d5b5326489b6e4aec1bc4fb00 Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Tue, 8 May 2018 23:29:25 +0100 +Subject: [PATCH 18/18] rteval: 2to3 transformations + +Applied a series of fixes from the 2to3 tool, as well as a few of my own +tweaks + +Signed-off-by: John Kacur +--- + rteval-cmd | 14 +++--- + rteval/Log.py | 12 ++--- + rteval/__init__.py | 52 ++++++++++----------- + rteval/misc.py | 8 ++-- + rteval/modules/__init__.py | 20 ++++---- + rteval/modules/loads/hackbench.py | 6 +-- + rteval/modules/loads/kcompile.py | 8 ++-- + rteval/modules/measurement/__init__.py | 2 +- + rteval/modules/measurement/cyclictest.py | 16 +++---- + rteval/modules/measurement/sysstat.py | 4 +- + rteval/rtevalConfig.py | 50 ++++++++++---------- + rteval/rtevalMailer.py | 6 +-- + rteval/rtevalReport.py | 8 ++-- + rteval/rtevalXMLRPC.py | 18 ++++---- + rteval/rtevalclient.py | 12 ++--- + rteval/sysinfo/__init__.py | 48 ++++++++++---------- + rteval/sysinfo/cputopology.py | 12 ++--- + rteval/sysinfo/dmi.py | 12 ++--- + rteval/sysinfo/kernel.py | 10 ++-- + rteval/sysinfo/memory.py | 12 ++--- + rteval/sysinfo/network.py | 4 +- + rteval/sysinfo/osinfo.py | 20 ++++---- + rteval/sysinfo/services.py | 6 +-- + rteval/sysinfo/tools.py | 4 +- + rteval/systopology.py | 28 ++++++------ + rteval/xmlout.py | 76 +++++++++++++++---------------- + setup.py | 4 +- + 34 files changed, 329 insertions(+), 329 deletions(-) + +diff --git a/rteval-cmd b/rteval-cmd +index 3ae29dbd9fe3..739a929316a3 100755 +--- a/rteval-cmd ++++ b/rteval-cmd +@@ -52,7 +52,7 @@ def summarize(repfile, xslt): + try: + t = tarfile.open(repfile) + except: +- print "Don't know how to summarize %s (tarfile open failed)" % repfile ++ print("Don't know how to summarize %s (tarfile open failed)" % repfile) + return + element = None + for f in t.getnames(): +@@ -60,7 +60,7 @@ def summarize(repfile, xslt): + element = f + break + if element == None: +- print "No summary.xml found in tar archive %s" % repfile ++ print("No summary.xml found in tar archive %s" % repfile) + return + tmp = tempfile.gettempdir() + t.extract(element, path=tmp) +@@ -83,7 +83,7 @@ def summarize(repfile, xslt): + + # Parse and print the report through the XSLT template - preserve proper encoding + resdoc = xsltprs(xmldoc) +- print unicode(resdoc).encode('UTF-8') ++ print(str(resdoc).encode('UTF-8')) + + # Clean up + del resdoc +@@ -162,7 +162,7 @@ def parse_options(cfg, parser, cmdargs): + + (cmd_opts, cmd_args) = parser.parse_args(args = cmdargs) + if cmd_opts.rteval___version: +- print("rteval version %s" % RTEVAL_VERSION) ++ print(("rteval version %s" % RTEVAL_VERSION)) + sys.exit(0); + + if cmd_opts.rteval___duration: +@@ -266,7 +266,7 @@ if __name__ == '__main__': + # if --summarize was specified then just parse the XML, print it and exit + if rtevcfg.summarize or rtevcfg.rawhistogram: + if len(cmd_args) < 1: +- raise RuntimeError, "Must specify at least one XML file with --summarize!" ++ raise RuntimeError("Must specify at least one XML file with --summarize!") + + for x in cmd_args: + if rtevcfg.summarize: +@@ -277,7 +277,7 @@ if __name__ == '__main__': + sys.exit(0) + + if os.getuid() != 0: +- print "Must be root to run rteval!" ++ print("Must be root to run rteval!") + sys.exit(-1) + + logger.log(Log.DEBUG, '''rteval options: +@@ -295,7 +295,7 @@ if __name__ == '__main__': + rtevcfg.duration, rtevcfg.sysreport)) + + if not os.path.isdir(rtevcfg.workdir): +- raise RuntimeError, "work directory %s does not exist" % rtevcfg.workdir ++ raise RuntimeError("work directory %s does not exist" % rtevcfg.workdir) + + + rteval = RtEval(config, loadmods, measuremods, logger) +diff --git a/rteval/Log.py b/rteval/Log.py +index a41ef319be0f..66aa77a59431 100644 +--- a/rteval/Log.py ++++ b/rteval/Log.py +@@ -80,26 +80,26 @@ def unit_test(rootdir): + def run_log_test(l): + for lt in range(min(logtypes), max(logtypes)*2): + test = ", ".join([logtypes_s[logtypes.index(i)] for i in [p for p in takewhile(lambda x: x <= lt, (2**i for i in count())) if p & lt]]) +- print "Testing verbosity flags set to: (%i) %s" % (lt, test) ++ print("Testing verbosity flags set to: (%i) %s" % (lt, test)) + msg = "Log entry when verbosity is set to %i [%s]" % (lt, test) + l.SetLogVerbosity(lt) + test_log(l, msg) +- print "-"*20 ++ print("-"*20) + + try: +- print "** Testing stdout" ++ print("** Testing stdout") + l = Log() + run_log_test(l) + +- print "** Testing file logging - using test.log" ++ print("** Testing file logging - using test.log") + l = Log("test.log") + run_log_test(l) + + return 0 +- except Exception, e: ++ except Exception as e: + import traceback + traceback.print_exc(file=sys.stdout) +- print "** EXCEPTION %s", str(e) ++ print("** EXCEPTION %s", str(e)) + return 1 + + +diff --git a/rteval/__init__.py b/rteval/__init__.py +index a7e44d9c41f1..176715f74ebd 100644 +--- a/rteval/__init__.py ++++ b/rteval/__init__.py +@@ -34,13 +34,13 @@ __license__ = "GPLv2 License" + import os, signal, sys, threading, time + from datetime import datetime + from distutils import sysconfig +-from modules.loads import LoadModules +-from modules.measurement import MeasurementModules, MeasurementProfile +-from rtevalReport import rtevalReport +-from rtevalXMLRPC import rtevalXMLRPC +-from Log import Log +-import rtevalConfig, rtevalMailer +-import version ++from .modules.loads import LoadModules ++from .modules.measurement import MeasurementModules, MeasurementProfile ++from .rtevalReport import rtevalReport ++from .rtevalXMLRPC import rtevalXMLRPC ++from .Log import Log ++from . import rtevalConfig, rtevalMailer ++from . import version + + RTEVAL_VERSION = version.RTEVAL_VERSION + +@@ -52,7 +52,7 @@ def sig_handler(signum, frame): + if signum == signal.SIGINT or signum == signal.SIGTERM: + global stopsig_received + stopsig_received = True +- print "*** stop signal received - stopping rteval run ***" ++ print("*** stop signal received - stopping rteval run ***") + else: + raise RuntimeError("SIGNAL received! (%d)" % signum) + +@@ -81,7 +81,7 @@ class RtEval(rtevalReport): + self.__reportdir = None + + # Import SystemInfo here, to avoid DMI warnings if RtEval() is not used +- from sysinfo import SystemInfo ++ from .sysinfo import SystemInfo + self._sysinfo = SystemInfo(self.__rtevcfg, logger=self.__logger) + + # prepare a mailer, if that's configured +@@ -105,11 +105,11 @@ class RtEval(rtevalReport): + self.__xmlrpc = rtevalXMLRPC(self.__rtevcfg.xmlrpc, self.__logger, self.__mailer) + if not self.__xmlrpc.Ping(): + if not self.__rtevcfg.xmlrpc_noabort: +- print "ERROR: Could not reach XML-RPC server '%s'. Aborting." % \ +- self.__rtevcfg.xmlrpc ++ print("ERROR: Could not reach XML-RPC server '%s'. Aborting." % \ ++ self.__rtevcfg.xmlrpc) + sys.exit(2) + else: +- print "WARNING: Could not ping the XML-RPC server. Will continue anyway." ++ print("WARNING: Could not ping the XML-RPC server. Will continue anyway.") + else: + self.__xmlrpc = None + +@@ -122,7 +122,7 @@ class RtEval(rtevalReport): + if hours: r = r - (hours * 3600) + minutes = r / 60 + if minutes: r = r - (minutes * 60) +- print "rteval time remaining: %d days, %d hours, %d minutes, %d seconds" % (days, hours, minutes, r) ++ print("rteval time remaining: %d days, %d hours, %d minutes, %d seconds" % (days, hours, minutes, r)) + + + def Prepare(self, onlyload = False): +@@ -135,7 +135,7 @@ class RtEval(rtevalReport): + # or the loads logging is enabled + if not onlyload or self.__rtevcfg.logging: + self.__reportdir = self._make_report_dir(self.__rtevcfg.workdir, "summary.xml") +- except Exception, e: ++ except Exception as e: + raise RuntimeError("Cannot create report directory (NFS with rootsquash on?) [%s]", str(e)) + + self.__logger.log(Log.INFO, "Preparing load modules") +@@ -173,23 +173,23 @@ class RtEval(rtevalReport): + if with_loads: + self._loadmods.Start() + +- print "rteval run on %s started at %s" % (os.uname()[2], time.asctime()) ++ print("rteval run on %s started at %s" % (os.uname()[2], time.asctime())) + onlinecpus = self._sysinfo.cpu_getCores(True) + cpulist = self._loadmods._cfg.GetSection("loads").cpulist + if cpulist: +- print "started %d loads on cores %s" % (self._loadmods.ModulesLoaded(), cpulist), ++ print("started %d loads on cores %s" % (self._loadmods.ModulesLoaded(), cpulist), end=' ') + else: +- print "started %d loads on %d cores" % (self._loadmods.ModulesLoaded(), onlinecpus), ++ print("started %d loads on %d cores" % (self._loadmods.ModulesLoaded(), onlinecpus), end=' ') + if self._sysinfo.mem_get_numa_nodes() > 1: +- print " with %d numa nodes" % self._sysinfo.mem_get_numa_nodes() ++ print(" with %d numa nodes" % self._sysinfo.mem_get_numa_nodes()) + else: +- print "" ++ print("") + cpulist = self._measuremods._MeasurementModules__cfg.GetSection("measurement").cpulist + if cpulist: +- print "started measurement threads on cores %s" % cpulist ++ print("started measurement threads on cores %s" % cpulist) + else: +- print "started measurement threads on %d cores" % onlinecpus +- print "Run duration: %s seconds" % str(self.__rtevcfg.duration) ++ print("started measurement threads on %d cores" % onlinecpus) ++ print("Run duration: %s seconds" % str(self.__rtevcfg.duration)) + + # start the cyclictest thread + measure_profile.Start() +@@ -220,7 +220,7 @@ class RtEval(rtevalReport): + + if with_loads: + if len(threading.enumerate()) < nthreads: +- raise RuntimeError, "load thread died!" ++ raise RuntimeError("load thread died!") + + if not load_avg_checked: + self._loadmods.SaveLoadAvg() +@@ -232,14 +232,14 @@ class RtEval(rtevalReport): + left_to_run = stoptime - currtime + self.__show_remaining_time(left_to_run) + rpttime = currtime + report_interval +- print "load average: %.2f" % self._loadmods.GetLoadAvg() ++ print("load average: %.2f" % self._loadmods.GetLoadAvg()) + currtime = time.time() + + self.__logger.log(Log.DEBUG, "out of measurement loop") + signal.signal(signal.SIGINT, signal.SIG_DFL) + signal.signal(signal.SIGTERM, signal.SIG_DFL) + +- except RuntimeError, e: ++ except RuntimeError as e: + raise RuntimeError("appeared during measurement: %s" % e) + + finally: +@@ -250,7 +250,7 @@ class RtEval(rtevalReport): + if with_loads: + self._loadmods.Stop() + +- print "stopping run at %s" % time.asctime() ++ print("stopping run at %s" % time.asctime()) + + # wait for measurement modules to finish calculating stats + measure_profile.WaitForCompletion() +diff --git a/rteval/misc.py b/rteval/misc.py +index 0cfc69dfbd62..b9ff246e0f01 100644 +--- a/rteval/misc.py ++++ b/rteval/misc.py +@@ -29,7 +29,7 @@ def expand_cpulist(cpulist): + if '-' in part: + a, b = part.split('-') + a, b = int(a), int(b) +- result.extend(range(a, b + 1)) ++ result.extend(list(range(a, b + 1))) + else: + a = int(part) + result.append(a) +@@ -61,9 +61,9 @@ def cpuinfo(): + if __name__ == "__main__": + + info = cpuinfo() +- idx = info.keys() ++ idx = list(info.keys()) + idx.sort() + for i in idx: +- print "%s: %s" % (i, info[i]) ++ print("%s: %s" % (i, info[i])) + +- print "0: %s" % (info['0']['model name']) ++ print("0: %s" % (info['0']['model name'])) +diff --git a/rteval/modules/__init__.py b/rteval/modules/__init__.py +index b41653e62d09..0feb8a916179 100644 +--- a/rteval/modules/__init__.py ++++ b/rteval/modules/__init__.py +@@ -211,7 +211,7 @@ class rtevalModulePrototype(threading.Thread): + "Return libxml2.xmlNode object with the gathered timestamps" + + ts_n = libxml2.newNode("timestamps") +- for k in self.__timestamps.keys(): ++ for k in list(self.__timestamps.keys()): + ts_n.newChild(None, k, str(self.__timestamps[k])) + + return ts_n +@@ -277,7 +277,7 @@ the information provided by the module""" + metavar='LIST') + parser.add_option_group(grparser) + +- for (modname, mod) in self.__modsloaded.items(): ++ for (modname, mod) in list(self.__modsloaded.items()): + opts = mod.ModuleParameters() + if len(opts) == 0: + continue +@@ -290,9 +290,9 @@ the information provided by the module""" + cfg = None + + grparser = optparse.OptionGroup(parser, "Options for the %s module" % shortmod) +- for (o, s) in opts.items(): +- descr = s.has_key('descr') and s['descr'] or "" +- metavar = s.has_key('metavar') and s['metavar'] or None ++ for (o, s) in list(opts.items()): ++ descr = 'descr' in s and s['descr'] or "" ++ metavar = 'metavar' in s and s['metavar'] or None + + try: + default = cfg and getattr(cfg, o) or None +@@ -301,7 +301,7 @@ the information provided by the module""" + default = None + + if default is None: +- default = s.has_key('default') and s['default'] or None ++ default = 'default' in s and s['default'] or None + + + grparser.add_option('--%s-%s' % (shortmod, o), +@@ -353,7 +353,7 @@ returned when a ModuleContainer object is iterated over""" + + def GetModulesList(self): + "Returns a list of module names" +- return self.__modobjects.keys() ++ return list(self.__modobjects.keys()) + + + def GetNamedModuleObject(self, modname): +@@ -364,11 +364,11 @@ returned when a ModuleContainer object is iterated over""" + def __iter__(self): + "Initiates the iterating process" + +- self.__iter_list = self.__modobjects.keys() ++ self.__iter_list = list(self.__modobjects.keys()) + return self + + +- def next(self): ++ def __next__(self): + """Internal Python iterating method, returns the next + module name and object to be processed""" + +@@ -511,7 +511,7 @@ start their workloads yet""" + self._logger.log(Log.DEBUG, "\t - Stopping %s" % modname) + if mod.is_alive(): + mod.join(2.0) +- except RuntimeError, e: ++ except RuntimeError as e: + self._logger.log(Log.ERR, "\t\tFailed stopping %s: %s" % (modname, str(e))) + self.__timestamps['stop'] = datetime.now() + +diff --git a/rteval/modules/loads/hackbench.py b/rteval/modules/loads/hackbench.py +index 9d3f6c834356..4b0fc59c3518 100644 +--- a/rteval/modules/loads/hackbench.py ++++ b/rteval/modules/loads/hackbench.py +@@ -128,7 +128,7 @@ class Hackbench(CommandLineLoad): + stderr=self.__err) + if not p: + self._log(Log.DEBUG, "hackbench failed to start on node %s" % node) +- raise RuntimeError, "hackbench failed to start on node %s" % node ++ raise RuntimeError("hackbench failed to start on node %s" % node) + return p + + def _WorkloadTask(self): +@@ -147,7 +147,7 @@ class Hackbench(CommandLineLoad): + if self.tasks[n].poll() is not None: + self.tasks[n].wait() + self.tasks[n] = self.__starton(n) +- except OSError, e: ++ except OSError as e: + if e.errno != errno.ENOMEM: + raise e + # Exit gracefully without a traceback for out-of-memory errors +@@ -166,7 +166,7 @@ class Hackbench(CommandLineLoad): + return + + for node in self.nodes: +- if self.tasks.has_key(node) and self.tasks[node].poll() is None: ++ if node in self.tasks and self.tasks[node].poll() is None: + self._log(Log.INFO, "cleaning up hackbench on node %s" % node) + self.tasks[node].send_signal(SIGKILL) + if self.tasks[node].poll() == None: +diff --git a/rteval/modules/loads/kcompile.py b/rteval/modules/loads/kcompile.py +index ef636c235fb8..ca4932172b87 100644 +--- a/rteval/modules/loads/kcompile.py ++++ b/rteval/modules/loads/kcompile.py +@@ -110,7 +110,7 @@ class Kcompile(CommandLineLoad): + + def _WorkloadSetup(self): + # find our source tarball +- if self._cfg.has_key('tarball'): ++ if 'tarball' in self._cfg: + tarfile = os.path.join(self.srcdir, self._cfg.tarfile) + if not os.path.exists(tarfile): + raise rtevalRuntimeError(self, " tarfile %s does not exist!" % tarfile) +@@ -176,7 +176,7 @@ class Kcompile(CommandLineLoad): + stdin=null, stdout=out, stderr=err) + if ret: + raise rtevalRuntimeError(self, "kcompile setup failed: %d" % ret) +- except KeyboardInterrupt, m: ++ except KeyboardInterrupt as m: + self._log(Log.DEBUG, "keyboard interrupt, aborting") + return + self._log(Log.DEBUG, "ready to run") +@@ -197,7 +197,7 @@ class Kcompile(CommandLineLoad): + else: + self.__outfd = self.__errfd = self.__nullfd + +- if self._cfg.has_key('cpulist') and self._cfg.cpulist: ++ if 'cpulist' in self._cfg and self._cfg.cpulist: + cpulist = self._cfg.cpulist + self.num_cpus = len(expand_cpulist(cpulist)) + else: +@@ -206,7 +206,7 @@ class Kcompile(CommandLineLoad): + def _WorkloadTask(self): + for n in self.topology: + if not self.buildjobs[n]: +- raise RuntimeError, "Build job not set up for node %d" % int(n) ++ raise RuntimeError("Build job not set up for node %d" % int(n)) + if self.buildjobs[n].jobid is None or self.buildjobs[n].jobid.poll() is not None: + self._log(Log.INFO, "Starting load on node %d" % n) + self.buildjobs[n].run(self.__nullfd, self.__outfd, self.__errfd) +diff --git a/rteval/modules/measurement/__init__.py b/rteval/modules/measurement/__init__.py +index b382971052cf..5a179949ad36 100644 +--- a/rteval/modules/measurement/__init__.py ++++ b/rteval/modules/measurement/__init__.py +@@ -204,7 +204,7 @@ measurement profiles, based on their characteristics""" + return self + + +- def next(self): ++ def __next__(self): + """Internal Python iterating method, returns the next + MeasurementProfile object to be processed""" + +diff --git a/rteval/modules/measurement/cyclictest.py b/rteval/modules/measurement/cyclictest.py +index 04f78d1c9612..c992c0c9e4eb 100644 +--- a/rteval/modules/measurement/cyclictest.py ++++ b/rteval/modules/measurement/cyclictest.py +@@ -87,7 +87,7 @@ class RunData(object): + + self._log(Log.INFO, "reducing %s" % self.__id) + total = 0 +- keys = self.__samples.keys() ++ keys = list(self.__samples.keys()) + keys.sort() + sorted = [] + +@@ -167,7 +167,7 @@ class RunData(object): + + hist_n = rep_n.newChild(None, 'histogram', None) + hist_n.newProp('nbuckets', str(len(self.__samples))) +- keys = self.__samples.keys() ++ keys = list(self.__samples.keys()) + keys.sort() + for k in keys: + if self.__samples[k] == 0: +@@ -255,7 +255,7 @@ class Cyclictest(rtevalModulePrototype): + + + def _WorkloadPrepare(self): +- self.__interval = self.__cfg.has_key('interval') and '-i%d' % int(self.__cfg.interval) or "" ++ self.__interval = 'interval' in self.__cfg and '-i%d' % int(self.__cfg.interval) or "" + + self.__cmd = ['cyclictest', + self.__interval, +@@ -269,10 +269,10 @@ class Cyclictest(rtevalModulePrototype): + else: + self.__cmd.append(self.__getmode()) + +- if self.__cfg.has_key('threads') and self.__cfg.threads: ++ if 'threads' in self.__cfg and self.__cfg.threads: + self.__cmd.append("-t%d" % int(self.__cfg.threads)) + +- if self.__cfg.has_key('breaktrace') and self.__cfg.breaktrace: ++ if 'breaktrace' in self.__cfg and self.__cfg.breaktrace: + self.__cmd.append("-b%d" % int(self.__cfg.breaktrace)) + self.__cmd.append("--tracemark") + self.__cmd.append("--notrace") +@@ -290,7 +290,7 @@ class Cyclictest(rtevalModulePrototype): + self.__nullfp = os.open('/dev/null', os.O_RDWR) + + debugdir = self.__get_debugfs_mount() +- if self.__cfg.has_key('breaktrace') and self.__cfg.breaktrace and debugdir: ++ if 'breaktrace' in self.__cfg and self.__cfg.breaktrace and debugdir: + # Ensure that the trace log is clean + trace = os.path.join(debugdir, 'tracing', 'trace') + fp = open(os.path.join(trace), "w") +@@ -353,7 +353,7 @@ class Cyclictest(rtevalModulePrototype): + self.__cyclicdata['system'].bucket(index, int(vals[i+1])) + + # generate statistics for each RunData object +- for n in self.__cyclicdata.keys(): ++ for n in list(self.__cyclicdata.keys()): + #print "reducing self.__cyclicdata[%s]" % n + self.__cyclicdata[n].reduce() + #print self.__cyclicdata[n] +@@ -429,7 +429,7 @@ if __name__ == '__main__': + cfg = rtevalConfig({}, logger=l) + prms = {} + modprms = ModuleParameters() +- for c, p in modprms.items(): ++ for c, p in list(modprms.items()): + prms[c] = p['default'] + cfg.AppendConfig('cyclictest', prms) + +diff --git a/rteval/modules/measurement/sysstat.py b/rteval/modules/measurement/sysstat.py +index 033e8825fa30..cbad928326dc 100644 +--- a/rteval/modules/measurement/sysstat.py ++++ b/rteval/modules/measurement/sysstat.py +@@ -131,7 +131,7 @@ if __name__ == '__main__': + cfg = rtevalConfig({}, logger=l) + prms = {} + modprms = ModuleParameters() +- for c, p in modprms.items(): ++ for c, p in list(modprms.items()): + prms[c] = p['default'] + cfg.AppendConfig('MeasurementModuleTemplate', prms) + +@@ -144,7 +144,7 @@ if __name__ == '__main__': + c._WorkloadSetup() + c._WorkloadPrepare() + c._WorkloadTask() +- print "Running for approx %i seconds" % runtime ++ print("Running for approx %i seconds" % runtime) + while runtime > 0: + c.WorkloadAlive() + time.sleep(1) +diff --git a/rteval/rtevalConfig.py b/rteval/rtevalConfig.py +index 16ac2d0199c4..36f1354b6a4f 100644 +--- a/rteval/rtevalConfig.py ++++ b/rteval/rtevalConfig.py +@@ -31,9 +31,9 @@ + # are deemed to be part of the source code. + # + import os, sys +-import ConfigParser +-from Log import Log +-from systopology import SysTopology ++import configparser ++from .Log import Log ++from .systopology import SysTopology + + def get_user_name(): + name = os.getenv('SUDO_USER') +@@ -111,7 +111,7 @@ class rtevalCfgSection(object): + "Simple method for dumping config when object is used as a string" + if len(self.__cfgdata) == 0: + return "# empty" +- return "\n".join(["%s: %s" % (k,v) for k,v in self.__cfgdata.items()]) + "\n" ++ return "\n".join(["%s: %s" % (k,v) for k,v in list(self.__cfgdata.items())]) + "\n" + + + def __setattr__(self, key, val): +@@ -119,22 +119,22 @@ class rtevalCfgSection(object): + + + def __getattr__(self, key): +- if key in self.__cfgdata.keys(): ++ if key in list(self.__cfgdata.keys()): + return self.__cfgdata[key] + return None + + + def items(self): +- return self.__cfgdata.items() ++ return list(self.__cfgdata.items()) + + + def __iter__(self): + "Initialises the iterator loop" +- self.__dict__['_rtevalCfgSection__iter_list'] = self.__cfgdata.keys() ++ self.__dict__['_rtevalCfgSection__iter_list'] = list(self.__cfgdata.keys()) + return self + + +- def next(self): ++ def __next__(self): + "Function used by the iterator" + + if not self.__dict__['_rtevalCfgSection__iter_list'] \ +@@ -153,16 +153,16 @@ class rtevalCfgSection(object): + + def has_key(self, key): + "has_key() wrapper for the configuration data" +- return self.__cfgdata.has_key(key) ++ return key in self.__cfgdata + + + def keys(self): + "keys() wrapper for configuration data" +- return self.__cfgdata.keys() ++ return list(self.__cfgdata.keys()) + + + def setdefault(self, key, defvalue): +- if not self.__cfgdata.has_key(key): ++ if key not in self.__cfgdata: + self.__cfgdata[key] = defvalue + return self.__cfgdata[key] + +@@ -171,7 +171,7 @@ class rtevalCfgSection(object): + if type(newdict) is not dict: + raise TypeError('update() method expects a dict as argument') + +- for key, val in newdict.iteritems(): ++ for key, val in newdict.items(): + self.__cfgdata[key] = val + + +@@ -190,10 +190,10 @@ class rtevalConfig(object): + + # get our system topology info + self.__systopology = SysTopology() +- print("got system topology: %s" % self.__systopology) ++ print(("got system topology: %s" % self.__systopology)) + + # Import the default config first +- for sect, vals in default_config.items(): ++ for sect, vals in list(default_config.items()): + self.__update_section(sect, vals) + + # Set the runtime provided init variables +@@ -201,7 +201,7 @@ class rtevalConfig(object): + if type(initvars) is not dict: + raise TypeError('initvars argument is not a dict variable') + +- for sect, vals in initvars.items(): ++ for sect, vals in list(initvars.items()): + self.__update_section(sect, vals) + + +@@ -209,7 +209,7 @@ class rtevalConfig(object): + if not section or not newvars: + return + +- if not self.__config_data.has_key(section): ++ if section not in self.__config_data: + self.__config_data[section] = rtevalCfgSection(newvars) + else: + self.__config_data[section].update(newvars) +@@ -218,7 +218,7 @@ class rtevalConfig(object): + def __str__(self): + "Simple method for dumping config when object is used as a string" + ret = "" +- for sect in self.__config_data.keys(): ++ for sect in list(self.__config_data.keys()): + ret += "[%s]\n%s\n" % (sect, str(self.__config_data[sect])) + return ret + +@@ -236,7 +236,7 @@ class rtevalConfig(object): + if os.path.exists(p): + self.__info("found config file %s" % p) + return p +- raise RuntimeError, "Unable to find configfile" ++ raise RuntimeError("Unable to find configfile") + + + def Load(self, fname = None, append = False): +@@ -253,13 +253,13 @@ class rtevalConfig(object): + return + + self.__info("reading config file %s" % cfgfile) +- ini = ConfigParser.ConfigParser() ++ ini = configparser.ConfigParser() + ini.optionxform = str + ini.read(cfgfile) + + # wipe any previously read config info + if not append: +- for s in self.__config_data.keys(): ++ for s in list(self.__config_data.keys()): + self.__config_data[s].wipe() + + # copy the section data into the __config_data dictionary +@@ -308,14 +308,14 @@ class rtevalConfig(object): + + + def HasSection(self, section): +- return self.__config_data.has_key(section) ++ return section in self.__config_data + + + def GetSection(self, section): + try: + # Return a new object with config settings of a given section + return self.__config_data[section] +- except KeyError, err: ++ except KeyError as err: + raise KeyError("The section '%s' does not exist in the config file" % section) + + +@@ -325,10 +325,10 @@ def unit_test(rootdir): + l.SetLogVerbosity(Log.INFO) + cfg = rtevalConfig(logger=l) + cfg.Load(os.path.join(rootdir, 'rteval.conf')) +- print cfg ++ print(cfg) + return 0 +- except Exception, e: +- print "** EXCEPTION %s", str(e) ++ except Exception as e: ++ print("** EXCEPTION %s", str(e)) + return 1 + + +diff --git a/rteval/rtevalMailer.py b/rteval/rtevalMailer.py +index 4588f149aaf6..f8f84d1916d0 100644 +--- a/rteval/rtevalMailer.py ++++ b/rteval/rtevalMailer.py +@@ -38,11 +38,11 @@ class rtevalMailer(object): + # * to_address + # + errmsg = "" +- if not cfg.has_key('smtp_server'): ++ if 'smtp_server' not in cfg: + errmsg = "\n** Missing smtp_server in config" +- if not cfg.has_key('from_address'): ++ if 'from_address' not in cfg: + errmsg += "\n** Missing from_address in config" +- if not cfg.has_key('to_address'): ++ if 'to_address' not in cfg: + errmsg += "\n** Missing to_address in config" + + if not errmsg == "": +diff --git a/rteval/rtevalReport.py b/rteval/rtevalReport.py +index b22fa39b1831..55594ae8f0bc 100644 +--- a/rteval/rtevalReport.py ++++ b/rteval/rtevalReport.py +@@ -26,7 +26,7 @@ + + import os, tarfile + from datetime import datetime +-import xmlout ++from . import xmlout + + + class rtevalReport(object): +@@ -95,11 +95,11 @@ class rtevalReport(object): + + def _show_report(self, xmlfile, xsltfile): + '''summarize a previously generated xml file''' +- print "Loading %s for summarizing" % xmlfile ++ print("Loading %s for summarizing" % xmlfile) + + xsltfullpath = os.path.join(self.__installdir, xsltfile) + if not os.path.exists(xsltfullpath): +- raise RuntimeError, "can't find XSL template (%s)!" % xsltfullpath ++ raise RuntimeError("can't find XSL template (%s)!" % xsltfullpath) + + xmlreport = xmlout.XMLOut('rteval', self.__version) + xmlreport.LoadReport(xmlfile) +@@ -126,7 +126,7 @@ class rtevalReport(object): + + def _tar_results(self): + if not os.path.isdir(self.__reportdir): +- raise RuntimeError, "no such directory: %s" % reportdir ++ raise RuntimeError("no such directory: %s" % reportdir) + + dirname = os.path.dirname(self.__reportdir) + rptdir = os.path.basename(self.__reportdir) +diff --git a/rteval/rtevalXMLRPC.py b/rteval/rtevalXMLRPC.py +index ed080cb13b91..7b2d207e0088 100644 +--- a/rteval/rtevalXMLRPC.py ++++ b/rteval/rtevalXMLRPC.py +@@ -25,8 +25,8 @@ + # + + import socket, time +-import rtevalclient, xmlrpclib +-from Log import Log ++import rtevalclient, xmlrpc.client ++from .Log import Log + + class rtevalXMLRPC(object): + def __init__(self, host, logger, mailer = None): +@@ -48,12 +48,12 @@ class rtevalXMLRPC(object): + res = self.__client.Hello() + attempt = 10 + ping_success = True +- except xmlrpclib.ProtocolError: ++ except xmlrpc.client.ProtocolError: + # Server do not support Hello(), but is reachable + self.__logger.log(Log.INFO, "Got XML-RPC connection with %s but it did not support Hello()" + % self.__host) + res = None +- except socket.error, err: ++ except socket.error as err: + self.__logger.log(Log.INFO, "Could not establish XML-RPC contact with %s\n%s" + % (self.__host, str(err))) + +@@ -67,7 +67,7 @@ class rtevalXMLRPC(object): + "Server %s did not respond." % self.__host) + warning_sent = True + +- print "Failed pinging XML-RPC server. Doing another attempt(%i) " % attempt ++ print("Failed pinging XML-RPC server. Doing another attempt(%i) " % attempt) + time.sleep(attempt) #*15) # Incremental sleep - sleep attempts*15 seconds + ping_success = False + +@@ -87,9 +87,9 @@ class rtevalXMLRPC(object): + warning_sent = False + while attempt < 6: + try: +- print "Submitting report to %s" % self.__url ++ print("Submitting report to %s" % self.__url) + rterid = self.__client.SendReport(xmlreport) +- print "Report registered with submission id %i" % rterid ++ print("Report registered with submission id %i" % rterid) + attempt = 10 + exitcode = 0 # Success + except socket.error: +@@ -103,10 +103,10 @@ class rtevalXMLRPC(object): + % self.__host) + warning_sent = True + +- print "Failed sending report. Doing another attempt(%i) " % attempt ++ print("Failed sending report. Doing another attempt(%i) " % attempt) + time.sleep(attempt) #*5*60) # Incremental sleep - sleep attempts*5 minutes + +- except Exception, err: ++ except Exception as err: + raise err + + +diff --git a/rteval/rtevalclient.py b/rteval/rtevalclient.py +index 7ccf3231ca37..26c953005326 100644 +--- a/rteval/rtevalclient.py ++++ b/rteval/rtevalclient.py +@@ -25,9 +25,9 @@ + # are deemed to be part of the source code. + # + +-import xmlrpclib ++import xmlrpc.client + import libxml2 +-import StringIO ++import io + import bz2 + import base64 + import platform +@@ -37,7 +37,7 @@ class rtevalclient: + rtevalclient is a library for sending rteval reports to an rteval server via XML-RPC. + """ + def __init__(self, url="http://rtserver.farm.hsv.redhat.com/rteval/API1/", hostn = None): +- self.srv = xmlrpclib.ServerProxy(url) ++ self.srv = xmlrpc.client.ServerProxy(url) + if hostn is None: + self.hostname = platform.node() + else: +@@ -51,9 +51,9 @@ class rtevalclient: + + def SendReport(self, xmldoc): + if xmldoc.type != 'document_xml': +- raise Exception, "Input is not XML document" ++ raise Exception("Input is not XML document") + +- fbuf = StringIO.StringIO() ++ fbuf = io.StringIO() + xmlbuf = libxml2.createOutputBuffer(fbuf, 'UTF-8') + doclen = xmldoc.saveFileTo(xmlbuf, 'UTF-8') + +@@ -61,7 +61,7 @@ class rtevalclient: + cmpr = compr.compress(fbuf.getvalue()) + data = base64.b64encode(cmpr + compr.flush()) + ret = self.srv.SendReport(self.hostname, data) +- print "rtevalclient::SendReport() - Sent %i bytes (XML document length: %i bytes, compression ratio: %.02f%%)" % (len(data), doclen, (1-(float(len(data)) / float(doclen)))*100 ) ++ print("rtevalclient::SendReport() - Sent %i bytes (XML document length: %i bytes, compression ratio: %.02f%%)" % (len(data), doclen, (1-(float(len(data)) / float(doclen)))*100 )) + return ret + + def SendDataAsFile(self, fname, data, decompr = False): +diff --git a/rteval/sysinfo/__init__.py b/rteval/sysinfo/__init__.py +index f7bf823aa36d..69b225bbbe47 100644 +--- a/rteval/sysinfo/__init__.py ++++ b/rteval/sysinfo/__init__.py +@@ -26,14 +26,14 @@ + import sys, libxml2 + from rteval.Log import Log + from glob import glob +-from kernel import KernelInfo +-from services import SystemServices +-from cputopology import CPUtopology +-from memory import MemoryInfo +-from osinfo import OSInfo +-from network import NetworkInfo +-from cmdline import cmdlineInfo +-import dmi ++from .kernel import KernelInfo ++from .services import SystemServices ++from .cputopology import CPUtopology ++from .memory import MemoryInfo ++from .osinfo import OSInfo ++from .network import NetworkInfo ++from .cmdline import cmdlineInfo ++from . import dmi + + class SystemInfo(KernelInfo, SystemServices, dmi.DMIinfo, CPUtopology, MemoryInfo, OSInfo, NetworkInfo, cmdlineInfo): + def __init__(self, config, logger=None): +@@ -78,29 +78,29 @@ if __name__ == "__main__": + cfg.installdir = "." + si = SystemInfo(cfg, logger=l) + +- print "\tRunning on %s" % si.get_base_os() +- print "\tNUMA nodes: %d" % si.mem_get_numa_nodes() +- print "\tMemory available: %03.2f %s\n" % si.mem_get_size() ++ print("\tRunning on %s" % si.get_base_os()) ++ print("\tNUMA nodes: %d" % si.mem_get_numa_nodes()) ++ print("\tMemory available: %03.2f %s\n" % si.mem_get_size()) + +- print "\tServices: " +- for (s, r) in si.services_get().items(): +- print "\t\t%s: %s" % (s, r) ++ print("\tServices: ") ++ for (s, r) in list(si.services_get().items()): ++ print("\t\t%s: %s" % (s, r)) + (curr, avail) = si.kernel_get_clocksources() + +- print "\tCurrent clocksource: %s" % curr +- print "\tAvailable clocksources: %s" % avail +- print "\tModules:" ++ print("\tCurrent clocksource: %s" % curr) ++ print("\tAvailable clocksources: %s" % avail) ++ print("\tModules:") + for m in si.kernel_get_modules(): +- print "\t\t%s: %s" % (m['modname'], m['modstate']) +- print "\tKernel threads:" +- for (p, i) in si.kernel_get_kthreads().items(): +- print "\t\t%-30.30s pid: %-5.5s policy: %-7.7s prio: %-3.3s" % ( ++ print("\t\t%s: %s" % (m['modname'], m['modstate'])) ++ print("\tKernel threads:") ++ for (p, i) in list(si.kernel_get_kthreads().items()): ++ print("\t\t%-30.30s pid: %-5.5s policy: %-7.7s prio: %-3.3s" % ( + i["name"]+":", p, i["policy"], i["priority"] +- ) ++ )) + +- print "\n\tCPU topology info - cores: %i online: %i sockets: %i" % ( ++ print("\n\tCPU topology info - cores: %i online: %i sockets: %i" % ( + si.cpu_getCores(False), si.cpu_getCores(True), si.cpu_getSockets() +- ) ++ )) + + xml = si.MakeReport() + xml_d = libxml2.newDoc("1.0") +diff --git a/rteval/sysinfo/cputopology.py b/rteval/sysinfo/cputopology.py +index 73ea3254cbc5..773af64f48de 100644 +--- a/rteval/sysinfo/cputopology.py ++++ b/rteval/sysinfo/cputopology.py +@@ -117,20 +117,20 @@ def unit_test(rootdir): + cputop = CPUtopology() + n = cputop._parse() + +- print " ---- XML Result ---- " ++ print(" ---- XML Result ---- ") + x = libxml2.newDoc('1.0') + x.setRootElement(n) + x.saveFormatFileEnc('-','UTF-8',1) + +- print " ---- getCPUcores() / getCPUscokets() ---- " +- print "CPU cores: %i (online: %i) - CPU sockets: %i" % (cputop.cpu_getCores(False), ++ print(" ---- getCPUcores() / getCPUscokets() ---- ") ++ print("CPU cores: %i (online: %i) - CPU sockets: %i" % (cputop.cpu_getCores(False), + cputop.cpu_getCores(True), +- cputop.cpu_getSockets()) ++ cputop.cpu_getSockets())) + return 0 +- except Exception, e: ++ except Exception as e: + # import traceback + # traceback.print_exc(file=sys.stdout) +- print "** EXCEPTION %s", str(e) ++ print("** EXCEPTION %s", str(e)) + return 1 + + if __name__ == '__main__': +diff --git a/rteval/sysinfo/dmi.py b/rteval/sysinfo/dmi.py +index f8e25005b9c1..8f05a6820332 100644 +--- a/rteval/sysinfo/dmi.py ++++ b/rteval/sysinfo/dmi.py +@@ -56,7 +56,7 @@ def ProcessWarnings(): + + # All other warnings will be printed + if len(warnline) > 0: +- print "** DMI WARNING ** %s" % warnline ++ print("** DMI WARNING ** %s" % warnline) + + dmidecode.clear_warnings() + +@@ -91,7 +91,7 @@ class DMIinfo(object): + xsltfile.close() + return ret + +- raise RuntimeError, 'Could not locate XSLT template for DMI data (%s)' % (self.sharedir + '/' + fname) ++ raise RuntimeError('Could not locate XSLT template for DMI data (%s)' % (self.sharedir + '/' + fname)) + + + def MakeReport(self): +@@ -119,13 +119,13 @@ def unit_test(rootdir): + self.__update_vars() + + def __update_vars(self): +- for k in self.config.keys(): ++ for k in list(self.config.keys()): + self.__dict__[k] = self.config[k] + + try: + ProcessWarnings() + if os.getuid() != 0: +- print "** ERROR ** Must be root to run this unit_test()" ++ print("** ERROR ** Must be root to run this unit_test()") + return 1 + + log = Log() +@@ -137,8 +137,8 @@ def unit_test(rootdir): + x.setRootElement(dx) + x.saveFormatFileEnc("-", "UTF-8", 1) + return 0 +- except Exception, e: +- print "** EXCEPTION: %s" % str(e) ++ except Exception as e: ++ print("** EXCEPTION: %s" % str(e)) + return 1 + + if __name__ == '__main__': +diff --git a/rteval/sysinfo/kernel.py b/rteval/sysinfo/kernel.py +index 209afd7bac4e..fd261fe2ab77 100644 +--- a/rteval/sysinfo/kernel.py ++++ b/rteval/sysinfo/kernel.py +@@ -73,7 +73,7 @@ class KernelInfo(object): + "modstate": mod[4]}) + line = fp.readline() + fp.close() +- except Exception, err: ++ except Exception as err: + raise err + return modlist + +@@ -82,7 +82,7 @@ class KernelInfo(object): + '''get the available and curent clocksources for this kernel''' + path = '/sys/devices/system/clocksource/clocksource0' + if not os.path.exists(path): +- raise RuntimeError, "Can't find clocksource path in /sys" ++ raise RuntimeError("Can't find clocksource path in /sys") + f = open (os.path.join (path, "current_clocksource")) + current_clocksource = f.readline().strip() + f = open (os.path.join (path, "available_clocksource")) +@@ -131,7 +131,7 @@ class KernelInfo(object): + rep_n.addChild(kthreads_n) + + kthreads = self.kernel_get_kthreads() +- keys = kthreads.keys() ++ keys = list(kthreads.keys()) + if len(keys): + keys.sort() + for pid in keys: +@@ -161,10 +161,10 @@ def unit_test(rootdir): + xml_d.setRootElement(ki_xml) + xml_d.saveFormatFileEnc("-", "UTF-8", 1) + +- except Exception, e: ++ except Exception as e: + import traceback + traceback.print_exc(file=sys.stdout) +- print "** EXCEPTION %s", str(e) ++ print("** EXCEPTION %s", str(e)) + return 1 + + if __name__ == '__main__': +diff --git a/rteval/sysinfo/memory.py b/rteval/sysinfo/memory.py +index 2c31d6593952..4df198be47f7 100644 +--- a/rteval/sysinfo/memory.py ++++ b/rteval/sysinfo/memory.py +@@ -48,12 +48,12 @@ class MemoryInfo(object): + if l.startswith('MemTotal:'): + parts = l.split() + if parts[2].lower() != 'kb': +- raise RuntimeError, "Units changed from kB! (%s)" % parts[2] ++ raise RuntimeError("Units changed from kB! (%s)" % parts[2]) + rawsize = int(parts[1]) + f.close() + break + if rawsize == 0: +- raise RuntimeError, "can't find memtotal in /proc/meminfo!" ++ raise RuntimeError("can't find memtotal in /proc/meminfo!") + + # Get a more readable result + # Note that this depends on /proc/meminfo starting in Kb +@@ -87,12 +87,12 @@ def unit_test(rootdir): + import sys + try: + mi = MemoryInfo() +- print "Numa nodes: %i" % mi.mem_get_numa_nodes() +- print "Memory: %i %s" % mi.mem_get_size() +- except Exception, e: ++ print("Numa nodes: %i" % mi.mem_get_numa_nodes()) ++ print("Memory: %i %s" % mi.mem_get_size()) ++ except Exception as e: + import traceback + traceback.print_exc(file=sys.stdout) +- print "** EXCEPTION %s", str(e) ++ print("** EXCEPTION %s", str(e)) + return 1 + + if __name__ == '__main__': +diff --git a/rteval/sysinfo/network.py b/rteval/sysinfo/network.py +index fa29db2bba55..9b933c13464b 100644 +--- a/rteval/sysinfo/network.py ++++ b/rteval/sysinfo/network.py +@@ -106,10 +106,10 @@ def unit_test(rootdir): + doc.setRootElement(cfg) + doc.saveFormatFileEnc('-', 'UTF-8', 1) + +- except Exception, e: ++ except Exception as e: + import traceback + traceback.print_exc(file=sys.stdout) +- print "** EXCEPTION %s", str(e) ++ print("** EXCEPTION %s", str(e)) + return 1 + + if __name__ == '__main__': +diff --git a/rteval/sysinfo/osinfo.py b/rteval/sysinfo/osinfo.py +index e262c06d968d..333f82beb558 100644 +--- a/rteval/sysinfo/osinfo.py ++++ b/rteval/sysinfo/osinfo.py +@@ -54,7 +54,7 @@ class OSInfo(object): + if os.path.exists('/usr/bin/dmesg'): + subprocess.call('/usr/bin/dmesg > %s' % os.path.join(repdir, "dmesg"), shell=True) + return +- print "dmesg file not found at %s and no dmesg exe found!" % dpath ++ print("dmesg file not found at %s and no dmesg exe found!" % dpath) + + + +@@ -64,7 +64,7 @@ class OSInfo(object): + elif os.path.exists('/usr/sbin/sysreport'): + exe = '/usr/sbin/sysreport' + else: +- raise RuntimeError, "Can't find sosreport/sysreport" ++ raise RuntimeError("Can't find sosreport/sysreport") + + self.__logger.log(Log.DEBUG, "report tool: %s" % exe) + options = ['-k', 'rpm.rpmva=off', +@@ -115,22 +115,22 @@ def unit_test(rootdir): + log = Log() + log.SetLogVerbosity(Log.DEBUG|Log.INFO) + osi = OSInfo(logger=log) +- print "Base OS: %s" % osi.get_base_os() ++ print("Base OS: %s" % osi.get_base_os()) + +- print "Testing OSInfo::copy_dmesg('/tmp'): ", ++ print("Testing OSInfo::copy_dmesg('/tmp'): ", end=' ') + osi.copy_dmesg('/tmp') + if os.path.isfile("/tmp/dmesg"): + md5orig = subprocess.check_output(("md5sum","/var/log/dmesg")) + md5copy = subprocess.check_output(("md5sum","/tmp/dmesg")) + if md5orig.split(" ")[0] == md5copy.split(" ")[0]: +- print "PASS" ++ print("PASS") + else: +- print "FAIL (md5sum)" ++ print("FAIL (md5sum)") + os.unlink("/tmp/dmesg") + else: +- print "FAIL (copy failed)" ++ print("FAIL (copy failed)") + +- print "Running sysreport/sosreport with output to current dir" ++ print("Running sysreport/sosreport with output to current dir") + osi.run_sysreport(".") + + osinfo_xml = osi.MakeReport() +@@ -138,10 +138,10 @@ def unit_test(rootdir): + xml_d.setRootElement(osinfo_xml) + xml_d.saveFormatFileEnc("-", "UTF-8", 1) + +- except Exception, e: ++ except Exception as e: + import traceback + traceback.print_exc(file=sys.stdout) +- print "** EXCEPTION %s", str(e) ++ print("** EXCEPTION %s", str(e)) + return 1 + + if __name__ == '__main__': +diff --git a/rteval/sysinfo/services.py b/rteval/sysinfo/services.py +index 6465d35e1b73..1bab2de4eb59 100644 +--- a/rteval/sysinfo/services.py ++++ b/rteval/sysinfo/services.py +@@ -49,7 +49,7 @@ class SystemServices(object): + servicesdir = sdir + break + if not servicesdir: +- raise RuntimeError, "No services dir (init.d) found on your system" ++ raise RuntimeError("No services dir (init.d) found on your system") + self.__log(Log.DEBUG, "Services located in %s, going through each service file to check status" % servicesdir) + ret_services = {} + for service in glob.glob(os.path.join(servicesdir, '*')): +@@ -127,8 +127,8 @@ def unit_test(rootdir): + xml_d.saveFormatFileEnc("-", "UTF-8", 1) + + return 0 +- except Exception, e: +- print "** EXCEPTION: %s" % str(e) ++ except Exception as e: ++ print("** EXCEPTION: %s" % str(e)) + return 1 + + +diff --git a/rteval/sysinfo/tools.py b/rteval/sysinfo/tools.py +index a61aa48160d3..ea14922b519a 100644 +--- a/rteval/sysinfo/tools.py ++++ b/rteval/sysinfo/tools.py +@@ -32,13 +32,13 @@ def getcmdpath(which): + getcmdpath is a method which allows finding an executable in the PATH + directories to call it from full path + """ +- if not pathSave.has_key(which): ++ if which not in pathSave: + for path in os.environ['PATH'].split(':'): + cmdfile = os.path.join(path, which) + if os.path.isfile(cmdfile) and os.access(cmdfile, os.X_OK): + pathSave[which] = cmdfile + break + if not pathSave[which]: +- raise RuntimeError, "Command '%s' is unknown on this system" % which ++ raise RuntimeError("Command '%s' is unknown on this system" % which) + return pathSave[which] + +diff --git a/rteval/systopology.py b/rteval/systopology.py +index fc3876c20bc9..97a6037e83aa 100644 +--- a/rteval/systopology.py ++++ b/rteval/systopology.py +@@ -99,7 +99,7 @@ class CpuList(object): + if '-' in part: + a, b = part.split('-') + a, b = int(a), int(b) +- result.extend(range(a, b + 1)) ++ result.extend(list(range(a, b + 1))) + else: + a = int(part) + result.append(a) +@@ -112,7 +112,7 @@ class CpuList(object): + # check whether cpu n is online + def isonline(self, n): + if n not in self.cpulist: +- raise RuntimeError, "invalid cpu number %d" % n ++ raise RuntimeError("invalid cpu number %d" % n) + if n == 0: + return True + path = os.path.join(CpuList.cpupath,'cpu%d' % n) +@@ -183,11 +183,11 @@ class SysTopology(object): + self.getinfo() + + def __len__(self): +- return len(self.nodes.keys()) ++ return len(list(self.nodes.keys())) + + def __str__(self): +- s = "%d node system" % len(self.nodes.keys()) +- s += " (%d cores per node)" % (len(self.nodes[self.nodes.keys()[0]])) ++ s = "%d node system" % len(list(self.nodes.keys())) ++ s += " (%d cores per node)" % (len(self.nodes[list(self.nodes.keys())[0]])) + return s + + # inplement the 'in' function +@@ -207,7 +207,7 @@ class SysTopology(object): + return self + + # iterator function +- def next(self): ++ def __next__(self): + if self.current >= len(self.nodes): + raise StopIteration + n = self.nodes[self.current] +@@ -217,14 +217,14 @@ class SysTopology(object): + def getinfo(self): + nodes = glob.glob(os.path.join(SysTopology.nodepath, 'node[0-9]*')) + if not nodes: +- raise RuntimeError, "No valid nodes found in %s!" % SysTopology.nodepath ++ raise RuntimeError("No valid nodes found in %s!" % SysTopology.nodepath) + nodes.sort() + for n in nodes: + node = int(os.path.basename(n)[4:]) + self.nodes[node] = NumaNode(n) + + def getnodes(self): +- return self.nodes.keys() ++ return list(self.nodes.keys()) + + def getcpus(self, node): + return self.nodes[node] +@@ -235,12 +235,12 @@ if __name__ == "__main__": + + def unit_test(): + s = SysTopology() +- print s +- print "number of nodes: %d" % len(s) ++ print(s) ++ print("number of nodes: %d" % len(s)) + for n in s: +- print "node[%d]: %s" % (n.nodeid, n) +- print "system has numa node 0: %s" % (0 in s) +- print "system has numa node 2: %s" % (2 in s) +- print "system has numa node 24: %s" % (24 in s) ++ print("node[%d]: %s" % (n.nodeid, n)) ++ print("system has numa node 0: %s" % (0 in s)) ++ print("system has numa node 2: %s" % (2 in s)) ++ print("system has numa node 24: %s" % (24 in s)) + + unit_test() +diff --git a/rteval/xmlout.py b/rteval/xmlout.py +index ddc29643e9ca..64642588b8b9 100644 +--- a/rteval/xmlout.py ++++ b/rteval/xmlout.py +@@ -29,7 +29,7 @@ import libxml2 + import lxml.etree + import codecs + import re +-from string import maketrans ++#from string import maketrans + + + def convert_libxml2_to_lxml_doc(inxml): +@@ -69,7 +69,7 @@ class XMLOut(object): + + def __del__(self): + if self.level > 0: +- raise RuntimeError, "XMLOut: open blocks at __del__ (last opened '%s')" % self.currtag.name ++ raise RuntimeError("XMLOut: open blocks at __del__ (last opened '%s')" % self.currtag.name) + if self.xmldoc is not None: + self.xmldoc.freeDoc() + +@@ -88,12 +88,12 @@ class XMLOut(object): + return tagname.translate(self.tag_trans) + + def __encode(self, value, tagmode = False): +- if type(value) is unicode: ++ if type(value) is str: + val = value + elif type(value) is str: +- val = unicode(value) ++ val = str(value) + else: +- val = unicode(str(value)) ++ val = str(str(value)) + + if tagmode is True: + rx = re.compile(" ") +@@ -106,7 +106,7 @@ class XMLOut(object): + + def __add_attributes(self, node, attr): + if attr is not None: +- for k, v in attr.iteritems(): ++ for k, v in attr.items(): + node.newProp(k, self.__encode(v)) + + +@@ -116,7 +116,7 @@ class XMLOut(object): + # unknown types. + + t = type(data) +- if t is unicode or t is str or t is int or t is float: ++ if t is str or t is str or t is int or t is float: + n = libxml2.newText(self.__encode(data)) + node.addChild(n) + elif t is bool: +@@ -124,7 +124,7 @@ class XMLOut(object): + n = libxml2.newText(self.__encode(v)) + node.addChild(n) + elif t is dict: +- for (key, val) in data.iteritems(): ++ for (key, val) in data.items(): + node2 = libxml2.newNode(self.__encode(self.parsedata_prefix + key, True)) + self.__parseToXML(node2, val) + node.addChild(node2) +@@ -137,15 +137,15 @@ class XMLOut(object): + self.__parseToXML(n, v) + node.addChild(n) + else: +- raise TypeError, "unhandled type (%s) for value '%s'" % (type(data), unicode(data)) ++ raise TypeError("unhandled type (%s) for value '%s'" % (type(data), str(data))) + + def close(self): + if self.status == 0: +- raise RuntimeError, "XMLOut: No XML document is created nor loaded" ++ raise RuntimeError("XMLOut: No XML document is created nor loaded") + if self.status == 3: +- raise RuntimeError, "XMLOut: XML document already closed" ++ raise RuntimeError("XMLOut: XML document already closed") + if self.level > 0: +- raise RuntimeError, "XMLOut: open blocks at close() (last opened '%s')" % self.currtag.name ++ raise RuntimeError("XMLOut: open blocks at close() (last opened '%s')" % self.currtag.name) + + if self.status == 1: # Only set the root node in the doc on created reports (NewReport called) + self.xmldoc.setRootElement(self.xmlroot) +@@ -154,7 +154,7 @@ class XMLOut(object): + + def NewReport(self): + if self.status != 0 and self.status != 3: +- raise RuntimeError, "XMLOut: Cannot start a new report without closing the currently opened one" ++ raise RuntimeError("XMLOut: Cannot start a new report without closing the currently opened one") + + if self.status == 3: + self.xmldoc.freeDoc() # Free the report from memory if we have one already +@@ -175,30 +175,30 @@ class XMLOut(object): + self.xmldoc = libxml2.parseFile(filename) + if self.xmldoc.name != filename: + self.status = 3 +- raise RuntimeError, "XMLOut: Loading report failed" ++ raise RuntimeError("XMLOut: Loading report failed") + + root = self.xmldoc.children + if root.name != self.roottag: + self.status = 3 +- raise RuntimeError, "XMLOut: Loaded report is not a valid %s XML file" % self.roottag ++ raise RuntimeError("XMLOut: Loaded report is not a valid %s XML file" % self.roottag) + + if validate_version is True: + ver = root.hasProp('version') + + if ver is None: + self.status = 3 +- raise RuntimeError, "XMLOut: Loaded report is missing version attribute in root node" ++ raise RuntimeError("XMLOut: Loaded report is missing version attribute in root node") + + if ver.getContent() != self.version: + self.status = 3 +- raise RuntimeError, "XMLOut: Loaded report is not of version %s" % self.version ++ raise RuntimeError("XMLOut: Loaded report is not of version %s" % self.version) + + self.status = 2 # Confirm that we have loaded a report from file + + + def Write(self, filename, xslt = None): + if self.status != 2 and self.status != 3: +- raise RuntimeError, "XMLOut: XML document is not closed" ++ raise RuntimeError("XMLOut: XML document is not closed") + + if xslt == None: + # If no XSLT template is give, write raw XML +@@ -223,7 +223,7 @@ class XMLOut(object): + resdoc = parser(xmldoc) + + # Write the file with the requested output encoding +- dstfile.write(unicode(resdoc).encode(self.encoding)) ++ dstfile.write(str(resdoc).encode(self.encoding)) + + if dstfile != sys.stdout: + dstfile.close() +@@ -238,12 +238,12 @@ class XMLOut(object): + + def GetXMLdocument(self): + if self.status != 2 and self.status != 3: +- raise RuntimeError, "XMLOut: XML document is not closed" ++ raise RuntimeError("XMLOut: XML document is not closed") + return self.xmldoc + + def openblock(self, tagname, attributes=None): + if self.status != 1: +- raise RuntimeError, "XMLOut: openblock() cannot be called before NewReport() is called" ++ raise RuntimeError("XMLOut: openblock() cannot be called before NewReport() is called") + ntag = libxml2.newNode(self.__fixtag(tagname)); + self.__add_attributes(ntag, attributes) + self.currtag.addChild(ntag) +@@ -253,16 +253,16 @@ class XMLOut(object): + + def closeblock(self): + if self.status != 1: +- raise RuntimeError, "XMLOut: closeblock() cannot be called before NewReport() is called" ++ raise RuntimeError("XMLOut: closeblock() cannot be called before NewReport() is called") + if self.level == 0: +- raise RuntimeError, "XMLOut: no open tags to close" ++ raise RuntimeError("XMLOut: no open tags to close") + self.currtag = self.currtag.get_parent() + self.level -= 1 + return self.currtag + + def taggedvalue(self, tag, value, attributes=None): + if self.status != 1: +- raise RuntimeError, "XMLOut: taggedvalue() cannot be called before NewReport() is called" ++ raise RuntimeError("XMLOut: taggedvalue() cannot be called before NewReport() is called") + ntag = self.currtag.newTextChild(None, self.__fixtag(tag), self.__encode(value)) + self.__add_attributes(ntag, attributes) + return ntag +@@ -270,7 +270,7 @@ class XMLOut(object): + + def ParseData(self, tagname, data, attributes=None, tuple_tagname="tuples", prefix = ""): + if self.status != 1: +- raise RuntimeError, "XMLOut: taggedvalue() cannot be called before NewReport() is called" ++ raise RuntimeError("XMLOut: taggedvalue() cannot be called before NewReport() is called") + + self.tuple_tagname = self.__fixtag(tuple_tagname) + self.parsedata_prefix = prefix +@@ -283,7 +283,7 @@ class XMLOut(object): + + def AppendXMLnodes(self, nodes): + if not isinstance(nodes, libxml2.xmlNode): +- raise ValueError, "Input value is not a libxml2.xmlNode" ++ raise ValueError("Input value is not a libxml2.xmlNode") + + return self.currtag.addChild(nodes) + +@@ -297,7 +297,7 @@ def unit_test(rootdir): + x.taggedvalue('date', '2000-11-22') + x.closeblock() + x.openblock('uname') +- x.taggedvalue('node', u'testing - \xe6\xf8') ++ x.taggedvalue('node', 'testing - \xe6\xf8') + x.taggedvalue('kernel', 'my_test_kernel', {'is_RT': 0}) + x.taggedvalue('arch', 'mips') + x.closeblock() +@@ -311,25 +311,25 @@ def unit_test(rootdir): + x.taggedvalue('command_line','dd if=/dev/zero of=/dev/null', {'name': 'lightloader'}) + x.closeblock() + x.close() +- print "------------- XML OUTPUT ----------------------------" ++ print("------------- XML OUTPUT ----------------------------") + x.Write("-") +- print "------------- XSLT PARSED OUTPUT --------------------" ++ print("------------- XSLT PARSED OUTPUT --------------------") + x.Write("-", "rteval_text.xsl") +- print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ++ print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") + x.Write("/tmp/xmlout-test.xml") + del x + +- print "------------- LOAD XML FROM FILE -----------------------------" ++ print("------------- LOAD XML FROM FILE -----------------------------") + x = XMLOut('rteval','UNIT-TEST', None, 'UTF-8') + x.LoadReport("/tmp/xmlout-test.xml", True) +- print "------------- LOADED XML DATA --------------------------------" ++ print("------------- LOADED XML DATA --------------------------------") + x.Write("-") +- print "------------- XSLT PARSED OUTPUT FROM LOADED XML--------------" ++ print("------------- XSLT PARSED OUTPUT FROM LOADED XML--------------") + x.Write("-", "rteval_text.xsl") + x.close() + + ## Test new data parser ... it eats most data types +- print "------------- TESTING XMLOut::ParseData() --------------" ++ print("------------- TESTING XMLOut::ParseData() --------------") + x.NewReport() + x.ParseData("ParseTest", "test string", {"type": "simple_string"}) + x.ParseData("ParseTest", 1234, {"type": "integer"}) +@@ -348,14 +348,14 @@ def unit_test(rootdir): + "varA4": {'another_level': True, + 'another_value': "blabla"} + }, +- "utf8 data": u'ƦĆøĆ„', +- u"lĆøpe": True} ++ "utf8 data": 'ƦĆøĆ„', ++ "lĆøpe": True} + x.ParseData("ParseTest", test, {"type": "dict"}, prefix="test ") + x.close() + x.Write("-") + return 0 +- except Exception, e: +- print "** EXCEPTION %s", str(e) ++ except Exception as e: ++ print("** EXCEPTION %s", str(e)) + return 1 + + if __name__ == '__main__': +diff --git a/setup.py b/setup.py +index 39bc8247b704..fc78a93c8793 100644 +--- a/setup.py ++++ b/setup.py +@@ -10,9 +10,9 @@ PYTHONLIB = join(get_python_lib(standard_lib=1, prefix=''), 'site-packages') + + # Tiny hack to make rteval-cmd become a rteval when building/installing the package + try: +- os.mkdir('dist', 0755) ++ os.mkdir('dist', 0o755) + distcreated = True +-except OSError, e: ++except OSError as e: + if e.errno == 17: + # If it already exists, ignore this error + distcreated = False diff --git a/SOURCES/rteval-Changes-for-python3-and-rt-tests-with-automat.patch b/SOURCES/rteval-Changes-for-python3-and-rt-tests-with-automat.patch new file mode 100644 index 0000000..a2a719f --- /dev/null +++ b/SOURCES/rteval-Changes-for-python3-and-rt-tests-with-automat.patch @@ -0,0 +1,156 @@ +From 1897019ec6fd7bfd465dd687e58ed355e6e0bead Mon Sep 17 00:00:00 2001 +From: root +Date: Sat, 23 Jun 2018 12:34:36 -0400 +Subject: [PATCH] rteval: Changes for python3 and rt-tests with automated numa + detection + +cyclictest no-longer requires --numa, but uses it automatically if detected. +rteval was changed to accomodate this. + +In addtion a number of changes were made for python3 compatibility. +Mostly these ahd to do with string and bytes. + +Signed-off-by: John Kacur +--- + rteval/modules/measurement/cyclictest.py | 5 +++-- + rteval/sysinfo/kernel.py | 8 +++++--- + rteval/sysinfo/network.py | 2 +- + rteval/xmlout.py | 21 +++++++++------------ + 4 files changed, 18 insertions(+), 18 deletions(-) + +diff --git a/rteval/modules/measurement/cyclictest.py b/rteval/modules/measurement/cyclictest.py +index c992c0c..21d313c 100644 +--- a/rteval/modules/measurement/cyclictest.py ++++ b/rteval/modules/measurement/cyclictest.py +@@ -228,7 +228,7 @@ class Cyclictest(rtevalModulePrototype): + def __getmode(self): + if self.__numanodes > 1: + self._log(Log.DEBUG, "running in NUMA mode (%d nodes)" % self.__numanodes) +- return '--numa' ++ return '' + self._log(Log.DEBUG, "running in SMP mode") + return '--smp' + +@@ -278,7 +278,7 @@ class Cyclictest(rtevalModulePrototype): + self.__cmd.append("--notrace") + + # Buffer for cyclictest data written to stdout +- self.__cyclicoutput = tempfile.SpooledTemporaryFile(mode='rw+b') ++ self.__cyclicoutput = tempfile.SpooledTemporaryFile(mode='w+b') + + + def _WorkloadTask(self): +@@ -327,6 +327,7 @@ class Cyclictest(rtevalModulePrototype): + # now parse the histogram output + self.__cyclicoutput.seek(0) + for line in self.__cyclicoutput: ++ line = bytes.decode(line) + if line.startswith('#'): + # Catch if cyclictest stopped due to a breaktrace + if line.startswith('# Break value: '): +diff --git a/rteval/sysinfo/kernel.py b/rteval/sysinfo/kernel.py +index fd261fe..308846b 100644 +--- a/rteval/sysinfo/kernel.py ++++ b/rteval/sysinfo/kernel.py +@@ -50,9 +50,11 @@ class KernelInfo(object): + for p in c.stdout: + v = p.strip().split() + kcmd = v.pop(0) ++ kcmd = bytes.decode(kcmd) + try: + if int(v[0]) > 0 and kcmd.startswith('[') and kcmd.endswith(']'): +- ret_kthreads[v[0]] = {'policy' : policies[v[1]], ++ ++ ret_kthreads[v[0]] = {'policy' : policies[bytes.decode(v[1])], + 'priority' : v[2], 'name' : v[3] } + except ValueError: + pass # Ignore lines which don't have a number in the first row +@@ -137,9 +139,9 @@ class KernelInfo(object): + for pid in keys: + kthri_n = libxml2.newNode("thread") + kthreads_n.addChild(kthri_n) +- kthri_n.addContent(kthreads[pid]["name"]) ++ kthri_n.addContent(bytes.decode(kthreads[pid]["name"])) + kthri_n.newProp("policy", kthreads[pid]["policy"]) +- kthri_n.newProp("priority", kthreads[pid]["priority"]) ++ kthri_n.newProp("priority", bytes.decode(kthreads[pid]["priority"])) + + return rep_n + +diff --git a/rteval/sysinfo/network.py b/rteval/sysinfo/network.py +index 9b933c1..ce9989a 100644 +--- a/rteval/sysinfo/network.py ++++ b/rteval/sysinfo/network.py +@@ -53,7 +53,7 @@ class NetworkInfo(object): + if hasattr(ethtool, 'get_interfaces_info'): + # Using the newer python-ethtool API (version >= 0.4) + for dev in ethtool.get_interfaces_info(ethtool.get_devices()): +- if cmp(dev.device,'lo') == 0: ++ if dev.device == 'lo': + continue + + intf_n = libxml2.newNode('interface') +diff --git a/rteval/xmlout.py b/rteval/xmlout.py +index 6464258..15391a6 100644 +--- a/rteval/xmlout.py ++++ b/rteval/xmlout.py +@@ -29,7 +29,6 @@ import libxml2 + import lxml.etree + import codecs + import re +-#from string import maketrans + + + def convert_libxml2_to_lxml_doc(inxml): +@@ -51,7 +50,7 @@ def convert_lxml_to_libxml2_nodes(inlxml): + if not isinstance(inlxml,lxml.etree._Element) and not isinstance(inlxml, lxml.etree._XSLTResultTree): + raise TypeError('Function requires an lxml.etree object as input') + +- return libxml2.parseDoc(lxml.etree.tostring(inlxml)).getRootElement() ++ return libxml2.parseDoc(bytes.decode(lxml.etree.tostring(inlxml))).getRootElement() + + + +@@ -74,13 +73,13 @@ class XMLOut(object): + self.xmldoc.freeDoc() + + def __setup_tag_trans(self): +- t = maketrans('', '') +- t = t.replace(' ', '_') +- t = t.replace('\t', '_') +- t = t.replace('(', '_') +- t = t.replace(')', '_') +- t = t.replace(':', '-') ++ t = str.maketrans('', '') + return t ++# t = t.replace(' ', '_') ++# t = t.replace('\t', '_') ++# t = t.replace('(', '_') ++# t = t.replace(')', '_') ++# t = t.replace(':', '-') + + def __fixtag(self, tagname): + if not isinstance(tagname, str): +@@ -99,9 +98,7 @@ class XMLOut(object): + rx = re.compile(" ") + val = rx.sub("_", val) + +- # libxml2 uses UTF-8 internally and must have +- # all input as UTF-8. +- return val.encode('utf-8') ++ return val + + + def __add_attributes(self, node, attr): +@@ -223,7 +220,7 @@ class XMLOut(object): + resdoc = parser(xmldoc) + + # Write the file with the requested output encoding +- dstfile.write(str(resdoc).encode(self.encoding)) ++ dstfile.write(bytes.decode(str(resdoc).encode(self.encoding))) + + if dstfile != sys.stdout: + dstfile.close() +-- +2.17.0 + diff --git a/SOURCES/rteval-Disable-options-for-remote-xmlrpc-server.patch b/SOURCES/rteval-Disable-options-for-remote-xmlrpc-server.patch new file mode 100644 index 0000000..744684d --- /dev/null +++ b/SOURCES/rteval-Disable-options-for-remote-xmlrpc-server.patch @@ -0,0 +1,41 @@ +From 2d547eb6a7598f608a5fce44988223186cb65760 Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Tue, 16 Oct 2018 19:23:25 +0200 +Subject: [PATCH] rteval: Disable options for remote xmlrpc server + +Disable options for remote xmlrpc server + +The simplest way to keep the code in place but disable this is to +comment out the options where the commandline is parsed. + +Signed-off-by: John Kacur +--- + rteval-cmd | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/rteval-cmd b/rteval-cmd +index 404d4ca0eb37..dff972f663cf 100755 +--- a/rteval-cmd ++++ b/rteval-cmd +@@ -129,12 +129,12 @@ def parse_options(cfg, parser, cmdargs): + parser.add_option("-D", '--debug', dest='rteval___debugging', + action='store_true', default=rtevcfg.debugging, + help='turn on debug prints (default: %default)') +- parser.add_option("-X", '--xmlrpc-submit', dest='rteval___xmlrpc', +- action='store', default=rtevcfg.xmlrpc, metavar='HOST', +- help='Hostname to XML-RPC server to submit reports') +- parser.add_option("-P", "--xmlrpc-no-abort", dest="rteval___xmlrpc_noabort", +- action='store_true', default=False, +- help="Do not abort if XML-RPC server do not respond to ping request"); ++ #parser.add_option("-X", '--xmlrpc-submit', dest='rteval___xmlrpc', ++ # action='store', default=rtevcfg.xmlrpc, metavar='HOST', ++ # help='Hostname to XML-RPC server to submit reports') ++ #parser.add_option("-P", "--xmlrpc-no-abort", dest="rteval___xmlrpc_noabort", ++ # action='store_true', default=False, ++ # help="Do not abort if XML-RPC server do not respond to ping request"); + parser.add_option("-Z", '--summarize', dest='rteval___summarize', + action='store_true', default=False, + help='summarize an already existing XML report') +-- +2.14.4 + diff --git a/SOURCES/rteval-Explicitly-use-python3.patch b/SOURCES/rteval-Explicitly-use-python3.patch new file mode 100644 index 0000000..f8c8481 --- /dev/null +++ b/SOURCES/rteval-Explicitly-use-python3.patch @@ -0,0 +1,47 @@ +From 0c6bc0249618ba3833d062f13ff987fd29a11ab8 Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Tue, 8 May 2018 19:18:54 +0100 +Subject: [PATCH 17/18] rteval: Explicitly use python3 + +Make the use of python3 explicit + +Signed-off-by: John Kacur +--- + rteval-cmd | 2 +- + rteval/misc.py | 2 +- + setup.py | 2 +- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/rteval-cmd b/rteval-cmd +index ed61d98de1a2..3ae29dbd9fe3 100755 +--- a/rteval-cmd ++++ b/rteval-cmd +@@ -1,4 +1,4 @@ +-#!/usr/bin/python -tt ++#!/usr/bin/python3 -tt + # -*- coding: utf-8 -*- + # + # rteval - script for evaluating platform suitability for RT Linux +diff --git a/rteval/misc.py b/rteval/misc.py +index 7b55b3490e61..0cfc69dfbd62 100644 +--- a/rteval/misc.py ++++ b/rteval/misc.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python -tt ++#!/usr/bin/python3 -tt + # + # Copyright (C) 2015 Clark Williams + # Copyright (C) 2015 Red Hat, Inc. +diff --git a/setup.py b/setup.py +index f5dc14610ae4..39bc8247b704 100644 +--- a/setup.py ++++ b/setup.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/python3 + from distutils.sysconfig import get_python_lib + from distutils.core import setup + from os.path import isfile, join +-- +2.14.3 + diff --git a/SOURCES/rteval-Fix-typo-in-debug-output.patch b/SOURCES/rteval-Fix-typo-in-debug-output.patch new file mode 100644 index 0000000..4581656 --- /dev/null +++ b/SOURCES/rteval-Fix-typo-in-debug-output.patch @@ -0,0 +1,28 @@ +From 098651a756aaad2d638dec12b9f387e416339892 Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Mon, 17 Dec 2018 17:40:49 +0100 +Subject: [PATCH] rteval: Fix typo in debug output + +Fix typo in debug output. Should say cmdline + +Signed-off-by: John Kacur +--- + rteval/sysinfo/cmdline.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/rteval/sysinfo/cmdline.py b/rteval/sysinfo/cmdline.py +index 12b3a5d9b7bd..7e7566aa2d8e 100644 +--- a/rteval/sysinfo/cmdline.py ++++ b/rteval/sysinfo/cmdline.py +@@ -13,7 +13,7 @@ class cmdlineInfo: + cmdlineList = [] + fp = open('/proc/cmdline', 'r') + line = fp.readline() +- self.__log(Log.DEBUG, "/proc/mcdline\n") ++ self.__log(Log.DEBUG, "/proc/cmdline\n") + fp.close() + return line + +-- +2.19.2 + diff --git a/SOURCES/rteval-Improve-error-handling-if-cyclictest-fails-to.patch b/SOURCES/rteval-Improve-error-handling-if-cyclictest-fails-to.patch new file mode 100644 index 0000000..4ad4bf0 --- /dev/null +++ b/SOURCES/rteval-Improve-error-handling-if-cyclictest-fails-to.patch @@ -0,0 +1,50 @@ +From afbb4f884cd4221f557f8de98670c106448d2529 Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Tue, 16 May 2017 20:55:36 -0400 +Subject: [PATCH 04/18] rteval: Improve error handling if cyclictest fails to + run + +Improve error handling if cyclictest fails to run. +An example of this could be if cyclictest is not installed, or rteval +cannot find the installation + +Signed-off-by: John Kacur +--- + rteval/modules/measurement/cyclictest.py | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/rteval/modules/measurement/cyclictest.py b/rteval/modules/measurement/cyclictest.py +index c5b30557da0b..d920e4be6548 100644 +--- a/rteval/modules/measurement/cyclictest.py ++++ b/rteval/modules/measurement/cyclictest.py +@@ -299,11 +299,14 @@ class Cyclictest(rtevalModulePrototype): + fp.close() + + self.__cyclicoutput.seek(0) +- self.__cyclicprocess = subprocess.Popen(self.__cmd, ++ try: ++ self.__cyclicprocess = subprocess.Popen(self.__cmd, + stdout=self.__cyclicoutput, + stderr=self.__nullfp, + stdin=self.__nullfp) +- self.__started = True ++ self.__started = True ++ except OSError: ++ self.__started = False + + + def WorkloadAlive(self): +@@ -314,7 +317,9 @@ class Cyclictest(rtevalModulePrototype): + + + def _WorkloadCleanup(self): +- while self.__cyclicprocess.poll() == None: ++ if not self.__started: ++ return ++ while self.__cyclicprocess.poll() is None: + self._log(Log.DEBUG, "Sending SIGINT") + os.kill(self.__cyclicprocess.pid, signal.SIGINT) + time.sleep(2) +-- +2.14.3 + diff --git a/SOURCES/rteval-Remove-rteval-sysinfo-systopology.py.patch b/SOURCES/rteval-Remove-rteval-sysinfo-systopology.py.patch new file mode 100644 index 0000000..95784c6 --- /dev/null +++ b/SOURCES/rteval-Remove-rteval-sysinfo-systopology.py.patch @@ -0,0 +1,262 @@ +From 59d3912d71832092c4daadf31fb3184f50aaa8b0 Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Thu, 18 May 2017 14:49:03 +0200 +Subject: [PATCH 09/18] rteval: Remove rteval/sysinfo/systopology.py + +Remove rteval/sysinfo/systopology.py as it is replaced by +rteval/systopology.py + +As was intended by 6e4d54b8c6d3697efba0e3d + +Signed-off-by: John Kacur +--- + rteval/sysinfo/systopology.py | 237 ------------------------------------------ + 1 file changed, 237 deletions(-) + delete mode 100644 rteval/sysinfo/systopology.py + +diff --git a/rteval/sysinfo/systopology.py b/rteval/sysinfo/systopology.py +deleted file mode 100644 +index a6e5c1a8b409..000000000000 +--- a/rteval/sysinfo/systopology.py ++++ /dev/null +@@ -1,237 +0,0 @@ +-# -*- coding: utf-8 -*- +-# +-# Copyright 2016 - Clark Williams +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +-# +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License along +-# with this program; if not, write to the Free Software Foundation, Inc., +-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +-# +-# For the avoidance of doubt the "preferred form" of this code is one which +-# is in an open unpatent encumbered format. Where cryptographic key signing +-# forms part of the process of creating an executable the information +-# including keys needed to generate an equivalently functional executable +-# are deemed to be part of the source code. +-# +- +-import os, sys +-import os.path +-import glob +- +-def _sysread(path, obj): +- fp = open(os.path.join(path,obj), "r") +- return fp.readline().strip() +- +-# +-# class to provide access to a list of cpus +-# +- +-class CpuList(object): +- "Object that represents a group of system cpus" +- +- cpupath = '/sys/devices/system/cpu' +- +- def __init__(self, cpulist): +- if type(cpulist) is list: +- self.cpulist = cpulist +- elif type(cpulist) is str: +- self.cpulist = self.__expand_cpulist(cpulist) +- self.cpulist.sort() +- +- def __str__(self): +- return self.__collapse_cpulist(self.cpulist) +- +- def __contains__(self, cpu): +- return cpu in self.cpulist +- +- def __len__(self): +- return len(self.cpulist) +- +- +- # return the index of the last element of a sequence +- # that steps by one +- def __longest_sequence(self, cpulist): +- lim = len(cpulist) +- for idx,val in enumerate(cpulist): +- if idx+1 == lim: +- break +- if int(cpulist[idx+1]) != (int(cpulist[idx])+1): +- return idx +- return lim - 1 +- +- +- # +- # collapse a list of cpu numbers into a string range +- # of cpus (e.g. 0-5, 7, 9) +- # +- def __collapse_cpulist(self, cpulist): +- if len(cpulist) == 0: +- return "" +- idx = self.__longest_sequence(cpulist) +- if idx == 0: +- seq = str(cpulist[0]) +- else: +- if idx == 1: +- seq = "%d,%d" % (cpulist[0], cpulist[idx]) +- else: +- seq = "%d-%d" % (cpulist[0], cpulist[idx]) +- +- rest = self.__collapse_cpulist(cpulist[idx+1:]) +- if rest == "": +- return seq +- return ",".join((seq, rest)) +- +- # expand a string range into a list +- # don't error check against online cpus +- def __expand_cpulist(self, cpulist): +- '''expand a range string into an array of cpu numbers''' +- result = [] +- for part in cpulist.split(','): +- if '-' in part: +- a, b = part.split('-') +- a, b = int(a), int(b) +- result.extend(range(a, b + 1)) +- else: +- a = int(part) +- result.append(a) +- return [ int(i) for i in list(set(result)) ] +- +- # returns the list of cpus tracked +- def getcpulist(self): +- return self.cpulist +- +- # check whether cpu n is online +- def isonline(self, n): +- if n not in self.cpulist: +- raise RuntimeError, "invalid cpu number %d" % n +- if n == 0: +- return True +- path = os.path.join(CpuList.cpupath,'cpu%d' % n) +- if os.path.exists(path): +- return _sysread(path, "online") == 1 +- return False +- +-# +-# class to abstract access to NUMA nodes in /sys filesystem +-# +- +-class NumaNode(object): +- "class representing a system NUMA node" +- +- # constructor argument is the full path to the /sys node file +- # e.g. /sys/devices/system/node/node0 +- def __init__(self, path): +- self.path = path +- self.nodeid = int(os.path.basename(path)[4:].strip()) +- self.cpus = CpuList(_sysread(self.path, "cpulist")) +- self.getmeminfo() +- +- # function for the 'in' operator +- def __contains__(self, cpu): +- return cpu in self.cpus +- +- # allow the 'len' builtin +- def __len__(self): +- return len(self.cpus) +- +- # string representation of the cpus for this node +- def __str__(self): +- return self.getcpustr() +- +- # read info about memory attached to this node +- def getmeminfo(self): +- self.meminfo = {} +- for l in open(os.path.join(self.path, "meminfo"), "r"): +- elements = l.split() +- key=elements[2][0:-1] +- val=int(elements[3]) +- if len(elements) == 5 and elements[4] == "kB": +- val *= 1024 +- self.meminfo[key] = val +- +- # return list of cpus for this node as a string +- def getcpustr(self): +- return str(self.cpus) +- +- # return list of cpus for this node +- def getcpulist(self): +- return self.cpus.getcpulist() +- +-# +-# Class to abstract the system topology of numa nodes and cpus +-# +-class SysTopology(object): +- "Object that represents the system's NUMA-node/cpu topology" +- +- cpupath = '/sys/devices/system/cpu' +- nodepath = '/sys/devices/system/node' +- +- def __init__(self): +- self.nodes = {} +- self.getinfo() +- +- def __len__(self): +- return len(self.nodes.keys()) +- +- # inplement the 'in' function +- def __contains__(self, node): +- for n in self.nodes: +- if self.nodes[n].nodeid == node: +- return True +- return False +- +- # allow indexing for the nodes +- def __getitem__(self, key): +- return self.nodes[key] +- +- # allow iteration over the cpus for the node +- def __iter__(self): +- self.current = 0 +- return self +- +- # iterator function +- def next(self): +- if self.current >= len(self.nodes): +- raise StopIteration +- n = self.nodes[self.current] +- self.current += 1 +- return n +- +- def getinfo(self): +- nodes = glob.glob(os.path.join(SysTopology.nodepath, 'node[0-9]*')) +- if not nodes: +- raise RuntimeError, "No valid nodes found in %s!" % SysTopology.nodepath +- nodes.sort() +- for n in nodes: +- node = int(os.path.basename(n)[4:]) +- self.nodes[node] = NumaNode(n) +- +- def getnodes(self): +- return self.nodes.keys() +- +- def getcpus(self, node): +- return self.nodes[node] +- +- +- +-if __name__ == "__main__": +- +- def unit_test(): +- s = SysTopology() +- print "number of nodes: %d" % len(s) +- for n in s: +- print "node[%d]: %s" % (n.nodeid, n) +- print "system has numa node 0: %s" % (0 in s) +- print "system has numa node 2: %s" % (2 in s) +- print "system has numa node 24: %s" % (24 in s) +- +- unit_test() +-- +2.14.3 + diff --git a/SOURCES/rteval-add-the-proc-cmdline-to-rteval-report.patch b/SOURCES/rteval-add-the-proc-cmdline-to-rteval-report.patch new file mode 100644 index 0000000..483640e --- /dev/null +++ b/SOURCES/rteval-add-the-proc-cmdline-to-rteval-report.patch @@ -0,0 +1,115 @@ +From 5a54d982b05caa48a51fb7db1c5c1d10a76dcc68 Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Fri, 20 Oct 2017 12:17:47 +0100 +Subject: [PATCH 12/18] rteval: add the /proc/cmdline to rteval report + +Bugzilla: bz1452788 + +Creates a new class cmdlineInfo which is added to the report + +example of the output: + + Cmdline: BOOT_IMAGE=/vmlinuz-3.10.0-663.el7.x86_64 +root=/dev/mapper/rhel_dell--pem710--02-root ro crashkernel=auto +rd.lvm.lv=rhel_dell-pem710-02/root rd.lvm.lv=rhel_dell-pem710-02/swap +console=ttyS0,115200n81 isolcpus=3 + +Signed-off-by: John Kacur + +cmdline + +Signed-off-by: John Kacur +(cherry picked from commit 3e883c598c5588ebec3e9a6e1f8bd396e5d3ab94) +Signed-off-by: John Kacur +--- + rteval/rteval_text.xsl | 5 +++++ + rteval/sysinfo/__init__.py | 5 ++++- + rteval/sysinfo/cmdline.py | 28 ++++++++++++++++++++++++++++ + 3 files changed, 37 insertions(+), 1 deletion(-) + create mode 100644 rteval/sysinfo/cmdline.py + +diff --git a/rteval/rteval_text.xsl b/rteval/rteval_text.xsl +index e99c0162c75a..c40063e3dd19 100644 +--- a/rteval/rteval_text.xsl ++++ b/rteval/rteval_text.xsl +@@ -136,6 +136,11 @@ + + + ++ ++ Cmdline: ++ ++ ++ + + + =================================================================== +diff --git a/rteval/sysinfo/__init__.py b/rteval/sysinfo/__init__.py +index 0de985bf86f1..f7bf823aa36d 100644 +--- a/rteval/sysinfo/__init__.py ++++ b/rteval/sysinfo/__init__.py +@@ -32,9 +32,10 @@ from cputopology import CPUtopology + from memory import MemoryInfo + from osinfo import OSInfo + from network import NetworkInfo ++from cmdline import cmdlineInfo + import dmi + +-class SystemInfo(KernelInfo, SystemServices, dmi.DMIinfo, CPUtopology, MemoryInfo, OSInfo, NetworkInfo): ++class SystemInfo(KernelInfo, SystemServices, dmi.DMIinfo, CPUtopology, MemoryInfo, OSInfo, NetworkInfo, cmdlineInfo): + def __init__(self, config, logger=None): + self.__logger = logger + KernelInfo.__init__(self, logger=logger) +@@ -42,6 +43,7 @@ class SystemInfo(KernelInfo, SystemServices, dmi.DMIinfo, CPUtopology, MemoryInf + dmi.DMIinfo.__init__(self, config, logger=logger) + CPUtopology.__init__(self) + OSInfo.__init__(self, logger=logger) ++ cmdlineInfo.__init__(self, logger=logger) + + # Parse initial DMI decoding errors + dmi.ProcessWarnings() +@@ -62,6 +64,7 @@ class SystemInfo(KernelInfo, SystemServices, dmi.DMIinfo, CPUtopology, MemoryInf + report_n.addChild(CPUtopology.MakeReport(self)) + report_n.addChild(MemoryInfo.MakeReport(self)) + report_n.addChild(dmi.DMIinfo.MakeReport(self)) ++ report_n.addChild(cmdlineInfo.MakeReport(self)) + + return report_n + +diff --git a/rteval/sysinfo/cmdline.py b/rteval/sysinfo/cmdline.py +new file mode 100644 +index 000000000000..12b3a5d9b7bd +--- /dev/null ++++ b/rteval/sysinfo/cmdline.py +@@ -0,0 +1,28 @@ ++import sys, os, readline, libxml2 ++from rteval.Log import Log ++ ++class cmdlineInfo: ++ def __init__(self, logger = None): ++ self.__logger = logger ++ ++ def __log(self, logtype, msg): ++ if self.__logger: ++ self.__logger.log(logtype, msg) ++ ++ def read_cmdline(self): ++ cmdlineList = [] ++ fp = open('/proc/cmdline', 'r') ++ line = fp.readline() ++ self.__log(Log.DEBUG, "/proc/mcdline\n") ++ fp.close() ++ return line ++ ++ def MakeReport(self): ++ rep_n = libxml2.newNode("cmdlineInfo") ++ cmdline_n = libxml2.newNode("cmdline") ++ cmdlineStr = self.read_cmdline() ++ cmdline_n.addContent(cmdlineStr) ++ self.__log(Log.DEBUG, cmdlineStr) ++ rep_n.addChild(cmdline_n) ++ ++ return rep_n +-- +2.14.3 + diff --git a/SOURCES/rteval-cyclictest.py-Fix-spacing-problems.patch b/SOURCES/rteval-cyclictest.py-Fix-spacing-problems.patch new file mode 100644 index 0000000..c3d17ac --- /dev/null +++ b/SOURCES/rteval-cyclictest.py-Fix-spacing-problems.patch @@ -0,0 +1,38 @@ +From 3ec25aea4b437db0d0910b4cb7110c8850d3b64b Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Tue, 8 May 2018 15:44:50 +0100 +Subject: [PATCH 15/18] rteval: cyclictest.py: Fix spacing problems + +Some spacing problems got introduced with the last fix, possibly +as a result of examining them with certain text editors + +Fix these + +Signed-off-by: John Kacur +--- + rteval/modules/measurement/cyclictest.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/rteval/modules/measurement/cyclictest.py b/rteval/modules/measurement/cyclictest.py +index d920e4be6548..f6c6d1353fac 100644 +--- a/rteval/modules/measurement/cyclictest.py ++++ b/rteval/modules/measurement/cyclictest.py +@@ -299,13 +299,13 @@ class Cyclictest(rtevalModulePrototype): + fp.close() + + self.__cyclicoutput.seek(0) +- try: ++ try: + self.__cyclicprocess = subprocess.Popen(self.__cmd, + stdout=self.__cyclicoutput, + stderr=self.__nullfp, + stdin=self.__nullfp) + self.__started = True +- except OSError: ++ except OSError: + self.__started = False + + +-- +2.14.3 + diff --git a/SOURCES/rteval-cyclictest.py-Remove-n-for-cyclictest-options.patch b/SOURCES/rteval-cyclictest.py-Remove-n-for-cyclictest-options.patch new file mode 100644 index 0000000..cfd3621 --- /dev/null +++ b/SOURCES/rteval-cyclictest.py-Remove-n-for-cyclictest-options.patch @@ -0,0 +1,30 @@ +From 6c89a0dcb9133792fc755d2b7370b81b5471753e Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Tue, 8 May 2018 16:35:59 +0100 +Subject: [PATCH 16/18] rteval: cyclictest.py: Remove -n for cyclictest options + +Upstream cyclictest made clock_nanosleep the default and removed +the -n option. Passing it as an option now creates an error, so remove +that here too. + +Signed-off-by: John Kacur +--- + rteval/modules/measurement/cyclictest.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/rteval/modules/measurement/cyclictest.py b/rteval/modules/measurement/cyclictest.py +index f6c6d1353fac..04f78d1c9612 100644 +--- a/rteval/modules/measurement/cyclictest.py ++++ b/rteval/modules/measurement/cyclictest.py +@@ -259,7 +259,7 @@ class Cyclictest(rtevalModulePrototype): + + self.__cmd = ['cyclictest', + self.__interval, +- '-qmun', ++ '-qmu', + '-h %d' % self.__buckets, + "-p%d" % int(self.__priority), + ] +-- +2.14.3 + diff --git a/SOURCES/rteval-fix-rtevalclient-import.patch b/SOURCES/rteval-fix-rtevalclient-import.patch new file mode 100644 index 0000000..44f04c3 --- /dev/null +++ b/SOURCES/rteval-fix-rtevalclient-import.patch @@ -0,0 +1,29 @@ +From 989eb650c0171a3d79e33986627ed4d5fb970b46 Mon Sep 17 00:00:00 2001 +From: Jiri Kastner +Date: Thu, 2 Aug 2018 16:37:15 +0200 +Subject: [PATCH] rteval: fix rtevalclient import + +Signed-off-by: Jiri Kastner +Signed-off-by: John Kacur +--- + rteval/rtevalXMLRPC.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/rteval/rtevalXMLRPC.py b/rteval/rtevalXMLRPC.py +index 7b2d207e0088..54bc114099d9 100644 +--- a/rteval/rtevalXMLRPC.py ++++ b/rteval/rtevalXMLRPC.py +@@ -24,8 +24,8 @@ + # are deemed to be part of the source code. + # + +-import socket, time +-import rtevalclient, xmlrpc.client ++import socket, time, xmlrpc.client ++from .rtevalclient import rtevalclient + from .Log import Log + + class rtevalXMLRPC(object): +-- +2.14.4 + diff --git a/SOURCES/rteval-hackbench.py-Do-not-sleep-if-hackbench-fails-.patch b/SOURCES/rteval-hackbench.py-Do-not-sleep-if-hackbench-fails-.patch new file mode 100644 index 0000000..da6a465 --- /dev/null +++ b/SOURCES/rteval-hackbench.py-Do-not-sleep-if-hackbench-fails-.patch @@ -0,0 +1,41 @@ +From 5ed68ae77ec05786aab99fbed35d0347a5d25997 Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Fri, 20 Oct 2017 12:17:49 +0100 +Subject: [PATCH 14/18] rteval: hackbench.py: Do not sleep if hackbench fails + from memory errors + +Do not sleep if hackbench fails to launch due to out-of-memory errors. +This can cause rteval to execute correctly without applying a full +stress load. Instead, exit gracefully + +Signed-off-by: John Kacur +--- + rteval/modules/loads/hackbench.py | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/rteval/modules/loads/hackbench.py b/rteval/modules/loads/hackbench.py +index 8456a24f4bba..9d3f6c834356 100644 +--- a/rteval/modules/loads/hackbench.py ++++ b/rteval/modules/loads/hackbench.py +@@ -150,14 +150,10 @@ class Hackbench(CommandLineLoad): + except OSError, e: + if e.errno != errno.ENOMEM: + raise e +- # Catch out-of-memory errors and wait a bit to (hopefully) +- # ease memory pressure +- self._log(Log.DEBUG, "ERROR: %s, sleeping for %f seconds" % (e.strerror, self.__err_sleep)) +- time.sleep(self.__err_sleep) +- if self.__err_sleep < 60.0: +- self.__err_sleep *= 2.0 +- if self.__err_sleep > 60.0: +- self.__err_sleep = 60.0 ++ # Exit gracefully without a traceback for out-of-memory errors ++ self._log(Log.DEBUG, "ERROR, ENOMEM while trying to launch hackbench") ++ print("out-of-memory trying to launch hackbench, exiting") ++ sys.exit(-1) + + + def WorkloadAlive(self): +-- +2.14.3 + diff --git a/SOURCES/rteval-remaining-time-fix.patch b/SOURCES/rteval-remaining-time-fix.patch new file mode 100644 index 0000000..1397791 --- /dev/null +++ b/SOURCES/rteval-remaining-time-fix.patch @@ -0,0 +1,36 @@ +From 69a848c0030d39a9546253b27b060634852bf8e9 Mon Sep 17 00:00:00 2001 +From: Jiri Kastner +Date: Fri, 3 Aug 2018 13:09:56 +0200 +Subject: [PATCH] rteval: remaining time fix + +in python3 division of integer/integer results in float. +casting division to int gives us needed numbers. + +Signed-off-by: Jiri Kastner +Signed-off-by: John Kacur +--- + rteval/__init__.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/rteval/__init__.py b/rteval/__init__.py +index 176715f74ebd..88145b7eba1c 100644 +--- a/rteval/__init__.py ++++ b/rteval/__init__.py +@@ -116,11 +116,11 @@ class RtEval(rtevalReport): + + def __show_remaining_time(self, remaining): + r = int(remaining) +- days = r / 86400 ++ days = int(r / 86400) + if days: r = r - (days * 86400) +- hours = r / 3600 ++ hours = int(r / 3600) + if hours: r = r - (hours * 3600) +- minutes = r / 60 ++ minutes = int(r / 60) + if minutes: r = r - (minutes * 60) + print("rteval time remaining: %d days, %d hours, %d minutes, %d seconds" % (days, hours, minutes, r)) + +-- +2.14.4 + diff --git a/SOURCES/rteval-remove-unnecssary-encode.patch b/SOURCES/rteval-remove-unnecssary-encode.patch new file mode 100644 index 0000000..dcd5a8f --- /dev/null +++ b/SOURCES/rteval-remove-unnecssary-encode.patch @@ -0,0 +1,33 @@ +From 4c64b6b5ef7eba57c0892407816223c3f226b9ae Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Fri, 10 Aug 2018 17:44:35 +0200 +Subject: [PATCH] rteval: remove unnecssary encode + +When running $ rteval --summarize + +the newlines are missing and the output comes out as one big line. + +The addition of the encoding for python3 compatibility has made the +encoding here unnessary and in fact it causes problems, so remove it + +Signed-off-by: John Kacur +--- + rteval-cmd | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/rteval-cmd b/rteval-cmd +index 739a929316a3..404d4ca0eb37 100755 +--- a/rteval-cmd ++++ b/rteval-cmd +@@ -83,7 +83,7 @@ def summarize(repfile, xslt): + + # Parse and print the report through the XSLT template - preserve proper encoding + resdoc = xsltprs(xmldoc) +- print(str(resdoc).encode('UTF-8')) ++ print(str(resdoc)) + + # Clean up + del resdoc +-- +2.14.4 + diff --git a/SOURCES/rteval-setup.py-Open-byte-like-object.patch b/SOURCES/rteval-setup.py-Open-byte-like-object.patch new file mode 100644 index 0000000..46e15e6 --- /dev/null +++ b/SOURCES/rteval-setup.py-Open-byte-like-object.patch @@ -0,0 +1,28 @@ +From b64537b1530b7918618f925ea7ccc3b119a8b471 Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Wed, 30 May 2018 13:12:21 +0100 +Subject: [PATCH] rteval: setup.py: Open byte like object + +python3 differentiates between text and binary data + +Signed-off-by: John Kacur +--- + setup.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/setup.py b/setup.py +index fc78a93c8793..95efa905f4d1 100644 +--- a/setup.py ++++ b/setup.py +@@ -28,7 +28,7 @@ from dist import RTEVAL_VERSION + + # Compress the man page, so distutil will only care for the compressed file + mangz = gzip.GzipFile('dist/rteval.8.gz', 'w', 9) +-man = open('doc/rteval.8', 'r') ++man = open('doc/rteval.8', 'rb') + mangz.writelines(man) + man.close() + mangz.close() +-- +2.14.3 + diff --git a/SOURCES/rteval-systopology.py-Remove-underscore-from-sysread.patch b/SOURCES/rteval-systopology.py-Remove-underscore-from-sysread.patch new file mode 100644 index 0000000..bd87d23 --- /dev/null +++ b/SOURCES/rteval-systopology.py-Remove-underscore-from-sysread.patch @@ -0,0 +1,48 @@ +From 42d724f1a68815ecf7b44c7a2b9001363c93f4ce Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Thu, 18 May 2017 13:32:48 +0200 +Subject: [PATCH 08/18] rteval: systopology.py: Remove underscore from sysread + +Remove underscore from sysread. +I'm eseentially backporting this comment from the obsolete file +rteval/sysinfo/systopology.py + +Signed-off-by: John Kacur +--- + rteval/systopology.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/rteval/systopology.py b/rteval/systopology.py +index 7c0985e9d26e..fc3876c20bc9 100644 +--- a/rteval/systopology.py ++++ b/rteval/systopology.py +@@ -27,7 +27,7 @@ import os, sys + import os.path + import glob + +-def _sysread(path, obj): ++def sysread(path, obj): + fp = open(os.path.join(path,obj), "r") + return fp.readline().strip() + +@@ -117,7 +117,7 @@ class CpuList(object): + return True + path = os.path.join(CpuList.cpupath,'cpu%d' % n) + if os.path.exists(path): +- return _sysread(path, "online") == 1 ++ return sysread(path, "online") == 1 + return False + + # +@@ -132,7 +132,7 @@ class NumaNode(object): + def __init__(self, path): + self.path = path + self.nodeid = int(os.path.basename(path)[4:].strip()) +- self.cpus = CpuList(_sysread(self.path, "cpulist")) ++ self.cpus = CpuList(sysread(self.path, "cpulist")) + self.getmeminfo() + + # function for the 'in' operator +-- +2.14.3 + diff --git a/SOURCES/rtevalReport.py-Fix-time-format-in-report.patch b/SOURCES/rtevalReport.py-Fix-time-format-in-report.patch new file mode 100644 index 0000000..6fa3904 --- /dev/null +++ b/SOURCES/rtevalReport.py-Fix-time-format-in-report.patch @@ -0,0 +1,32 @@ +From 8a704e7b12b132d4e161bcc49f009a05350b98ca Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Fri, 12 Oct 2018 00:49:33 +0200 +Subject: [PATCH] rteval: rtevalReport.py: Fix time format in report + +Another case where python3 division generates floats +This can be fixed by converting the result to an int + +Signed-off-by: John Kacur +--- + rteval/rtevalReport.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/rteval/rtevalReport.py b/rteval/rtevalReport.py +index 55594ae8f0bc..a18dd41b36fc 100644 +--- a/rteval/rtevalReport.py ++++ b/rteval/rtevalReport.py +@@ -48,9 +48,9 @@ class rtevalReport(object): + + duration = datetime.now() - measure_start + seconds = duration.seconds +- hours = seconds / 3600 ++ hours = int(seconds / 3600) + if hours: seconds -= (hours * 3600) +- minutes = seconds / 60 ++ minutes = int(seconds / 60) + if minutes: seconds -= (minutes * 60) + + # Start new XML report +-- +2.14.4 + diff --git a/SOURCES/sysinfo-don-t-fail-if-we-don-t-know-the-init-system.patch b/SOURCES/sysinfo-don-t-fail-if-we-don-t-know-the-init-system.patch new file mode 100644 index 0000000..34c8a3a --- /dev/null +++ b/SOURCES/sysinfo-don-t-fail-if-we-don-t-know-the-init-system.patch @@ -0,0 +1,32 @@ +From 74432794f6bf0bcb984cf53982e9495163b76b3a Mon Sep 17 00:00:00 2001 +From: Clark Williams +Date: Tue, 12 Sep 2017 13:36:31 -0500 +Subject: [PATCH 10/18] sysinfo: don't fail if we don't know the init system + +Signed-off-by: Clark Williams +--- + rteval/sysinfo/services.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/rteval/sysinfo/services.py b/rteval/sysinfo/services.py +index e7c2fe0dc00e..6465d35e1b73 100644 +--- a/rteval/sysinfo/services.py ++++ b/rteval/sysinfo/services.py +@@ -95,7 +95,8 @@ class SystemServices(object): + self.__log(Log.DEBUG, "Using sysvinit to get services status") + return self.__get_services_sysvinit() + else: +- raise RuntimeError, "Unknown init system (%s)" % self.__init ++ self.__init = 'container' ++ self.__log(Log.DEBUG, "Running inside container") + return {} + + +@@ -133,4 +134,3 @@ def unit_test(rootdir): + + if __name__ == '__main__': + sys.exit(unit_test(None)) +- +-- +2.14.3 + diff --git a/SOURCES/update-rt-tests-URL-in-docs-README.patch b/SOURCES/update-rt-tests-URL-in-docs-README.patch new file mode 100644 index 0000000..d1f34bd --- /dev/null +++ b/SOURCES/update-rt-tests-URL-in-docs-README.patch @@ -0,0 +1,27 @@ +From ed5cb77f7bcfee9833e41d675246cec310143179 Mon Sep 17 00:00:00 2001 +From: Clark Williams +Date: Fri, 17 Mar 2017 16:44:32 -0500 +Subject: [PATCH 01/18] update rt-tests URL in docs/README + +Signed-off-by: Clark Williams +--- + README | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/README b/README +index 1fcc34749394..62b1cd25f4fd 100644 +--- a/README ++++ b/README +@@ -35,8 +35,7 @@ libxml2-python + http://xmlsoft.org/ + + rt-tests +- git://git.kernel.org/pub/scm/linux/kernel/git/clrkwllms/rt-tests.git +- ++ git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git + + Clark Williams wrote rteval + David Sommerseth wrote the XML-RPC and database +-- +2.14.3 + diff --git a/SPECS/rteval.spec b/SPECS/rteval.spec new file mode 100644 index 0000000..4d513d8 --- /dev/null +++ b/SPECS/rteval.spec @@ -0,0 +1,622 @@ +Name: rteval +Version: 2.14 +Release: 25%{?dist} +Summary: Utility to evaluate system suitability for RT Linux + +Group: Development/Tools +License: GPLv2 +URL: http://git.kernel.org/?p=linux/kernel/git/clrkwllms/rteval.git +Source0: rteval-%{version}.tar.bz2 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +BuildRequires: python3-devel +Requires: platform-python +Requires: python3-schedutils python3-ethtool python3-lxml +Requires: python3-dmidecode >= 3.10 +Requires: rt-tests >= 0.97 +Requires: rteval-loads >= 1.4 +Requires: rteval-common => %{version}-%{release} +Requires: sysstat +Requires: bzip2 +Requires: kernel-headers +Requires: sos +Requires: tar +BuildArch: noarch +Obsoletes: rteval <= 1.7 +Requires: numactl + +%description +The rteval script is a utility for measuring various aspects of +realtime behavior on a system under load. The script unpacks the +kernel source, and then goes into a loop, running hackbench and +compiling a kernel tree. During that loop the cyclictest program +is run to measure event response time. After the run time completes, +a statistical analysis of the event response times is done and printed +to the screen. + + +%package common +Summary: Common rteval files +BuildArch: noarch + +Patch1: update-rt-tests-URL-in-docs-README.patch +Patch2: rteval-Improve-error-handling-if-cyclictest-fails-to.patch +Patch3: rteval-systopology.py-Remove-underscore-from-sysread.patch +Patch4: rteval-Remove-rteval-sysinfo-systopology.py.patch +Patch5: sysinfo-don-t-fail-if-we-don-t-know-the-init-system.patch +Patch6: rteval-add-the-proc-cmdline-to-rteval-report.patch +Patch7: rteval-hackbench.py-Do-not-sleep-if-hackbench-fails-.patch +Patch8: rteval-cyclictest.py-Fix-spacing-problems.patch +Patch9: rteval-cyclictest.py-Remove-n-for-cyclictest-options.patch +Patch10: rteval-Explicitly-use-python3.patch +Patch11: rteval-2to3-transformations.patch +Patch12: rteval-setup.py-Open-byte-like-object.patch +Patch13: python-setup.py-Comment-out-os.unlink.patch +Patch14: rteval-Changes-for-python3-and-rt-tests-with-automat.patch +Patch15: rteval-fix-rtevalclient-import.patch +Patch16: rteval-remaining-time-fix.patch +Patch17: rteval-remove-unnecssary-encode.patch +Patch18: rtevalReport.py-Fix-time-format-in-report.patch +Patch19: rteval-Disable-options-for-remote-xmlrpc-server.patch +Patch20: rteval-Fix-typo-in-debug-output.patch + +%description common +Common files used by rteval, rteval-xmlrpc and rteval-parser + +%prep +%setup -q +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 + +# version sanity check (make sure specfile and rteval.py match) +#cp rteval/version.py rtevalversion.py +#srcver=$(%{__python3} -c "from rtevalversion import RTEVAL_VERSION; print RTEVAL_VERSION") +#rm -rf rtevalversion.py +#if [ $srcver != %{version} ]; then +# printf "\n***\n*** rteval spec file version do not match the rteval/rteval.py version\n***\n\n" +# exit -1 +#fi + +%build +%{__python3} setup.py build + +%install +%{__python3} setup.py install --root=$RPM_BUILD_ROOT + +%clean +rm -rf $RPM_BUILD_ROOT + +%files common +%doc COPYING +%dir %{_datadir}/%{name} +%{python3_sitelib}/rteval/rtevalclient.py* +%{python3_sitelib}/rteval/rtevalConfig.py* +%{python3_sitelib}/rteval/rtevalXMLRPC.py* +%{python3_sitelib}/rteval/version.py* +%{python3_sitelib}/rteval/Log.py* +%{python3_sitelib}/rteval/misc.py* +%{python3_sitelib}/rteval/systopology.py* + +%files +%defattr(-,root,root,-) +%{python3_sitelib}/*.egg-info + +%doc COPYING README doc/rteval.txt +%{_mandir}/man8/rteval.8.gz +%config(noreplace) %{_sysconfdir}/rteval.conf +%{_datadir}/%{name}/rteval_*.xsl +%{python3_sitelib}/rteval/__init__.py* +%{python3_sitelib}/rteval/rtevalMailer.py* +%{python3_sitelib}/rteval/rtevalReport.py* +%{python3_sitelib}/rteval/xmlout.py* +%{python3_sitelib}/rteval/modules +%{python3_sitelib}/rteval/sysinfo +/usr/bin/rteval + +%{python3_sitelib}/rteval/__pycache__/* + +%changelog +* Mon Apr 02 2019 Clark Williams - 2.14.25 +- fix incorrect test logic in gating tests +Resolves: rhbz#1682426 + +* Mon Apr 02 2019 Clark Williams - 2.14.24 +- add rteval-loads dependency to gating +- added second test (short_run) to gating +Resolves: rhbz#1682426 + +* Mon Apr 01 2019 Clark Williams - 2.14.23 +- add missing gating.yaml +Resolves: rhbz#1682426 + +* Mon Apr 01 2019 Clark Williams - 2.14.22 +- checkin OSCI gating framework +Resolves: rhbz#1682426 + +* Mon Dec 17 2018 John Kacur - 2.14-21 +- Fix typo in debug output +Resolves: rhbz#1659974 + +* Tue Oct 16 2018 John Kacur - 2.14-20 +- Disable options for the remote xmlrpc server, not currently supported +Resolves: rhbz#1628322 + +* Sat Oct 13 2018 John Kacur - 2.14-19 +- Fix Requires for python3 +Resolves: rhbz#1638135 + +* Fri Oct 12 2018 John Kacur - 2.14-18 +- Fix time format in report +Resolves: rhbz#1630733 + +* Fri Sep 28 2018 John Kacur - 2.14-17 +- Change python3 to platform-python +Resolves: rhbz#1633619 + +* Fri Aug 10 2018 John Kacur - 2.14-16 +- remove unnecssary encode that is causing problems +Resolves: rhbz#1614384 + +* Tue Aug 07 2018 John Kacur - 2.14-15 +- tar is required in kcompile.py. Make it a Require in the specfile +Resolves: rhbz#1612992 + +* Fri Aug 03 2018 John Kacur - 2.14-14 +- fix python3 division of integers +Resolves: rhbz#1611813 + +* Fri Aug 03 2018 John Kacur - 2.14-13 +-fix rtevalclient import +Resolves: rhbz#1608464 + +* Sat Jun 23 2018 John Kacur - 2.14-12 +- More python3 changes +- Changes for the new version of rt-tests that automates --numa +Resolves: rhbz#1594287 + +* Tue Jun 12 2018 John Kacur jkacur@redhat.com> - 2.14-11 +- More specfile changes for python3 build +Resolves: rhbz#1518699 + +* Wed May 30 2018 John Kacur - 2.14-10 +- Chnages for a python3 build +Resolves: rhbz#1518699 + +* Fri Oct 27 2017 John Kacur - 2.14-9 +- Remove redundant files for clarity. +Resolves: rhbz1504162 + +* Fri Oct 27 2017 John Kacur - 2.14-8 +- Don't fail if we don't know the init system +Resolves: rhbz1504168 + +* Fri Oct 20 2017 John Kacur - 2.14-7 +- Remove underscore from sysread function in systopology.py +Resolves: rhbz1504164 + +* Fri Oct 20 2017 John Kacur - 2.14-6 +- Improve error handling if cyclictest fails to run +Resolves: rhbz1504159 + +* Fri Oct 20 2017 John Kacur - 2.14-5 +- Remove trace-cmd from Requires, since it is not needed to run rteval +Resolves: rhbz1504173 + +* Mon Oct 16 2017 John Kacur - 2.14-4 +- Don't sleep if hackbench fails to launch due to out-of-memory +- Instead, exit gracefully +Resolves: rhbz1380144 + +* Wed Oct 11 2017 John Kacur - 2.14-3 +- Add sos as a requires since this package is needed to run sosreport +Resolves: rhbz1500722 + +* Wed Oct 11 2017 John Kacur - 2.14-2 +- Add the contents of the kernel boot command line to the summary report +Resolves: rhbz1452788 + +* Thu Mar 16 2017 Clark Williams - 2.14-1 +- removed leftover import of systopology from sysinfo + +* Wed Mar 15 2017 Clark Williams - 2.13-2 +- Updated specfile to correct version and bz [1382155] + +* Tue Sep 20 2016 Clark Williams - 2.12-1 +- handle empty environment variables SUDO_USER and USER [1312057] + +* Tue Aug 30 2016 Clark Williams - 2.11-1 +- make sure we return non-zero for early exit from tests + +* Wed Aug 3 2016 Clark Williams - 2.10-1 +- bumped version for RHEL 7.3 release + +* Mon May 9 2016 Clark Williams - 2.9.1 +- default cpulist for modules if only one specified [1333831] + +* Tue Apr 26 2016 Clark Williams - 2.8.1 +- add the --version option to print the rteval version +- made the --cyclictest-breaktrace option work properly [1209986] + +* Fri Apr 1 2016 Clark Williams - 2.7.1 +- treat SIGINT and SIGTERM as valid end-of-run events [1278757] +- added cpulist options to man page + +* Thu Feb 11 2016 Clark Williams - 2.6.1 +- update to make --loads-cpulist and --measurement-cpulist work [1306437] + +* Thu Dec 10 2015 Clark Williams - 2.5-1 +- stop using old numactl --cpubind argument + +* Wed Dec 9 2015 Clark Williams - 2.4.2 +- added Require of package numactl + +* Tue Nov 17 2015 Clark Williams - 2.4.1 +- rework hackbench load to not generate cross-node traffic [1282826] + +* Wed Aug 12 2015 Clark Williams - 2.3-1 +- comment out HWLatDetect module from default config [1245699] + +* Wed Jun 10 2015 Clark Williams - 2.2-1 +- add --loads-cpulist and --measurement-cpulist to allow cpu placement [1230401] + +* Thu Apr 23 2015 Luis Claudio R. Goncalves - 2.1-8 +- load default configs when no config file is specified (Jiri kastner) [1212452] + +* Wed Jan 14 2015 Clark Williams - 2.1-7 +- added requires of bzip2 to specfile [1151567] + +* Thu Jan 8 2015 Clark Williams - 2.1-6 +- cleaned up product documentation [1173315] + +* Mon Nov 10 2014 Luis Claudio R. Goncalves - 2.1-5 +- rebuild for RHEL-7.1 (1151567) + +* Thu Mar 27 2014 Clark Williams - 2.1-4 +- cherry-picked old commit to deal with installdir problem + +* Wed Mar 26 2014 Clark Williams - 2.1-3 +- added sysstat requires to specfile + +* Tue Mar 12 2013 David Sommerseth - 2.1-2 +- Migrated from libxslt-python to python-lxml + +* Fri Jan 18 2013 David Sommerseth - 2.1-1 +- Made some log lines clearer +- cyclictest: Added --cyclictest-breaktrace feature +- cyclictest: Removed --cyclictest-distance option +- cyclictest: Use a tempfile buffer for cyclictest's stdout data +- cyclictest: Report if breaktrace was triggered +- cyclictest: Make the unit test work again +- cyclictest: Only log and show statistic data when samples are collected +- Copyright updates + +* Thu Jan 17 2013 David Sommerseth - 2.0.1-1 +- Fix up type casting in the core module code +- hwlatdetect: Add some more useful debug info +- Reworked the run logic for modules - allow them to flag they won't run +- Fixed a few log messages in load modules +- Add a 30 seconds sleep before unleashing the measurement threads + +* Thu Jan 10 2013 David Sommerseth - 2.0-3 +- Separate out RTEVAL_VERSION into rteval.version, to avoid + massive BuildRequirements + +* Fri Dec 21 2012 David Sommerseth - 2.0-2 +- Split out common files into rteval-common + +* Fri Dec 21 2012 David Sommerseth - 2.0-1 +- Updated to rteval v2.0 and reworked spec file to use setup.py directly + +* Tue Oct 23 2012 Clark Williams - 1.36-1 +- deal with system not having dmidecode python module +- make sure to cast priority parameter to int +- from RaphaĆ«l Beamonte : + - Rewrite of the get_kthreads method to make it cross-distribution + - Adds getcmdpath method to use which to locate the used commands + - Rewrite of the get_services method to make it cross-distribution + +* Mon Apr 2 2012 Clark Williams - 1.35-1 +- fix thinko where SIGINT and SIGTERM handlers were commented out + +* Thu Jan 12 2012 Clark Williams - 1.34-1 +- fix missing config merge in rteval.py to pass parameters + down to cyclictest +- modify hackbench to use helper function to start process + +* Sat May 14 2011 Clark Williams - 1.33-1 +- modify hackbench cutoff to be 0.75GB/core + +* Mon Aug 23 2010 Clark Williams - 1.32-1 +- update docs +- refactor some RTEval methods to utility functions +- modify hackbench.py not to run under low memory conditions +- clean up XML generation to deal with new hackbench code +- clean up XSL code to deal with new XML 'run' attribute +- from David Sommerseth : + - improve CPU socket counting logic + - delay log directory creation until actually needed +- from Gowrishankar : + - check if the core id really exists (multithreading fix) + +* Mon Jul 26 2010 Clark Williams - 1.31-1 +- from David Sommerseth : + - Updated hackbench implementation to avoid overusing resources + - Don't show NUMA node information if it's missing in the summary.xml + - Show CPU cores properly + +* Wed Jul 21 2010 Clark Williams - 1.30-1 +- added code to hackbench to try to detect and ease memory pressure + +* Fri Jul 16 2010 Clark Williams - 1.29-1 +- fixed incorrect type value in kcompile.py + +* Fri Jul 16 2010 Clark Williams - 1.28-1 +- added logic to loads to adjust number of jobs based on ratio + of memory per core + +* Wed Jul 14 2010 Clark Williams - 1.27-1 +- modified hackbench to go back to using threads rather than + processes for units of work +- added memory size, number of numa nodes and run duration to the + parameter dictionary passed to all loads and cyclictest + +* Tue Jul 13 2010 Clark Williams - 1.26-1 +- modified hackbench parameters to reduce memory consumption + +* Mon Jul 12 2010 Clark Williams - 1.25-1 +- fixed cyclictest bug that caused everything to be uniprocessor +- updated source copyrights to 2010 + +* Fri Jul 9 2010 Clark Williams - 1.24-1 +- modified hackbench arguments and added new parameters for + hackbench in rteval.conf + +* Thu Jul 8 2010 Clark Williams - 1.23-1 +- version bump to deal with out-of-sync cvs issue + +* Thu Jul 8 2010 Clark Williams - 1.22-1 +- merged David Sommerseth changes to use + hackbench from rt-tests packages rather than carry local copy +- converted all loads and cyclictest to pass __init__ parameters + in a dictionary rather than as discrete parameters +- added logging for load output + + * Tue Apr 13 2010 Clark Williams - 1.21-1 +- from Luis Claudio Goncalves : + - remove unecessary wait() call in cyclictest.py + - close /dev/null after using it + - call subprocess.wait() when needed + - remove delayloop code in hackbench.py +- from David Sommerseth : + - add SIGINT handler + - handle non-root user case + - process DMI warnings before command line arguments + - added --annotate feature to rteval + - updates to xmlrpc code + + * Tue Apr 6 2010 Clark Williams - 1.20-1 +- code fixes from Luis Claudio Goncalves +- from David Sommerseth : + - xmlrpc server updates + - cputopology.py for recording topology in xml + - added NUMA node recording for run data + - rpmlint fixes +- added start of rteval whitepaper in docs dir + +* Tue Mar 16 2010 Clark Williams - 1.19-1 +- add ability for --summarize to read tarfiles +- from David Sommerseth + - gather info about loaded kernel modules for XML file + - added child tracking to hackbench to prevent zombies + +* Tue Feb 16 2010 Clark Williams - 1.18-1 +- fix usage of python 2.6 features on RHEL5 (python 2.4) + +* Tue Feb 16 2010 Clark Williams - 1.17-1 +- added logic to filter non-printables from service status output + so that we have legal XML output +- added logic to hackbench.py to cleanup properly at the end + of the test + +* Thu Feb 11 2010 Clark Williams - 1.16-1 +- fix errors in show_remaining_time() introduced because + time values are floats rather than ints + +* Thu Feb 11 2010 Clark Williams - 1.15-1 +- added logic to use --numa and --smp options of new cyclictest +- added countdown report for time remaining in a run + +* Tue Feb 9 2010 Clark Williams - 1.14-1 +- David Sommerseth : + merged XMLReport() changes for hwcert suite + +* Tue Dec 22 2009 Clark Williams - 1.13-1 +- added cyclictest default initializers +- added sanity checks to statistics reduction code +- updated release checklist to include origin push +- updated Makefile clean and help targets +- davids updates (mainly for v7 integration): + - Add explicit sys.path directory to the python sitelib+ + '/rteval' + - Send program arguments via RtEval() constructor + - Added more DMI data into the summary.xml report + - Fixed issue with not including all devices in the + OnBoardDeviceInfo tag + +* Thu Dec 3 2009 David Sommerseth - 1.12-2 +- fixed Makefile and specfile to include and install the + rteval/rteval_histogram_raw.py source file for gaining + raw access to histogram data +- Removed xmlrpc package during merge against master_ipv4 branch + +* Wed Nov 25 2009 Clark Williams - 1.12-1 +- fix incorrect reporting of measurement thread priorities + +* Mon Nov 16 2009 Clark Williams - 1.11-5 +- ensure that no double-slashes ("//") appear in the symlink + path for /usr/bin/rteval (problem with rpmdiff) + +* Tue Nov 10 2009 Clark Williams - 1.11-4 +- changed symlink back to install and tracked by %%files + +* Mon Nov 9 2009 Clark Williams - 1.11-3 +- changed symlink generation from %%post to %%posttrans + +* Mon Nov 9 2009 Clark Williams - 1.11-2 +- fixed incorrect dependency for libxslt + +* Fri Nov 6 2009 Clark Williams - 1.11-1 +- added base OS info to XML file and XSL report +- created new package rteval-loads for the load source code + +* Wed Nov 4 2009 Clark Williams - 1.10-1 +- added config file section for cyclictest and two settable + parameters, buckets and interval + +* Thu Oct 29 2009 Clark Williams - 1.9-1 +- merged davids updates: + -H option (raw histogram data) + cleaned up xsl files + fixed cpu sorting + +* Mon Oct 26 2009 David Sommerseth - 1.8-3 +- Fixed rpmlint complaints + +* Mon Oct 26 2009 David Sommerseth - 1.8-2 +- Added xmlrpc package, containing the XML-RPC mod_python modules + +* Tue Oct 20 2009 Clark Williams - 1.8-1 +- split kcompile and hackbench into sub-packages +- reworked Makefile (and specfile) install/uninstall logic +- fixed sysreport incorrect plugin option +- catch failure when running on root-squashed NFS + +* Tue Oct 13 2009 Clark Williams - 1.7-1 +- added kthread status to xml file +- merged davids changes for option processing and additions + to xml summary + +* Tue Oct 13 2009 Clark Williams - 1.6-1 +- changed stat calculation to loop less +- added methods to grab service and kthread status + +* Mon Oct 12 2009 Clark Williams - 1.5-1 +- changed cyclictest to use less memory when doing statisics + calculations +- updated debug output to use module name prefixes +- changed option processing to only process config file once + +* Fri Oct 9 2009 Clark Williams - 1.4-1 +- changed cyclictest to use histogram rather than sample array +- calcuated statistics directly from histogram +- changed sample interval to 100us +- added -a (affinity) argument to force cpu affinity for + measurement threads + +* Thu Sep 24 2009 David Sommerseth - 1.3-3 +- Cleaned up the spec file and made rpmlint happy + +* Wed Sep 23 2009 David Sommerseth - 1.3-2 +- Removed version number from /usr/share/rteval path + +* Tue Sep 22 2009 Clark Williams - 1.3-1 +- changes from davids: + * changed report code to sort by processor id + * added report submission retry logic + * added emailer class + +* Fri Sep 18 2009 Clark Williams - 1.2-1 +- added config file handling for modifying load behavior and + setting defaults +- added units in report per IBM request + +* Wed Aug 26 2009 Clark Williams - 1.1-2 +- missed a version change in rteval/rteval.py + +* Wed Aug 26 2009 Clark Williams - 1.1-1 +- modified cyclictest.py to start cyclictest threads with a + 'distance' of zero, meaning they all have the same measurement + interval + +* Tue Aug 25 2009 Clark Williams - 1.0-1 +- merged davids XMLRPC fixes +- fixed --workdir option +- verion bump to 1.0 + +* Thu Aug 13 2009 Clark Williams - 0.9-2 +- fixed problem with incorrect version in rteval.py + +* Tue Aug 4 2009 Clark Williams - 0.9-1 +- merged dsommers XMLRPC and database changes +- Specify minimum python-dmidecode version, which got native XML support +- Added rteval_dmi.xsl +- Fixed permission issues in /usr/share/rteval-x.xx + +* Wed Jul 22 2009 Clark Williams - 0.8-1 +- added code to capture clocksource info +- added code to copy dmesg info to report directory +- added code to display clocksource info in report +- added --summarize option to display summary of existing report +- added helpfile target to Makefile + +* Thu Mar 26 2009 Clark Williams - 0.7-1 +- added require for python-schedutils to specfile +- added default for cyclictest output file +- added help parameter to option parser data +- renamed xml output file to summary.xml +- added routine to create tarfile of result files + +* Wed Mar 18 2009 Clark Williams - 0.6-6 +- added code to handle binary data coming from DMI tables + +* Wed Mar 18 2009 Clark Williams - 0.6-5 +- fixed logic for locating XSL template (williams) +- fixed another stupid typo in specfile (williams) + +* Wed Mar 18 2009 Clark Williams - 0.6-4 +- fixed specfile to install rteval_text.xsl in /usr/share directory + +* Wed Mar 18 2009 Clark Williams - 0.6-3 +- added Requires for libxslt-python (williams) +- fixed race condition in xmlout constructor/destructor (williams) + +* Wed Mar 18 2009 Clark Williams - 0.6-2 +- added Requires for libxslt (williams) +- fixed stupid typo in rteval/rteval.py (williams) + +* Wed Mar 18 2009 Clark Williams - 0.6-1 +- added xml output logic (williams, dsommers) +- added xlst template for report generator (dsommers) +- added dmi/smbios output to report (williams) +- added __del__ method to hackbench to cleanup after run (williams) +- modified to always keep run data (williams) + +* Fri Feb 20 2009 Clark Williams - 0.5-1 +- fixed tab/space mix problem +- added report path line to report + +* Fri Feb 20 2009 Clark Williams - 0.4-1 +- reworked report output +- handle keyboard interrupt better +- removed duration mismatch between rteval and cyclictest + +* Mon Feb 2 2009 Clark Williams - 0.3-1 +- initial checkin