Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Basic 2to3 + fixes transformation. Runs on py3k, but needs more testi…

…ng (esp. py2.6).
  • Loading branch information...
commit dda3e0cf4cca34303268c94d01d0de81d68c59c2 1 parent f69d8be
@tohojo authored
View
6 netperf-wrapper
@@ -48,7 +48,7 @@ try:
else:
raise RuntimeError("Aggregator not found: '%s'" % aggregator_name)
- for s in settings.DATA_SETS.items():
+ for s in list(settings.DATA_SETS.items()):
agg.add_instance(*s)
formatter_name = util.classname(settings.FORMAT, 'Formatter')
@@ -62,8 +62,8 @@ try:
results.dump_dir(os.path.dirname(settings.OUTPUT) or ".")
formatter.format(results)
- except RuntimeError, e:
- sys.stderr.write(u"Error occurred: %s\n"% unicode(e))
+ except RuntimeError as e:
+ sys.stderr.write("Error occurred: %s\n"% str(e))
sys.exit(1)
except KeyboardInterrupt:
try:
View
22 netperf_wrapper/__init__.py
@@ -0,0 +1,22 @@
+## -*- coding: utf-8 -*-
+##
+## __init__.py
+##
+## Author: Toke Høiland-Jørgensen (toke@toke.dk)
+## Date: 6 december 2012
+## Copyright (c) 2012, Toke Høiland-Jørgensen
+##
+## 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 3 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, see <http://www.gnu.org/licenses/>.
+
+__all__ = ['aggregators', 'build_info', 'formatters', 'orderreddict', 'resultset', 'runners', 'settings', 'transformers', 'util']
View
33 netperf_wrapper/aggregators.py
@@ -22,11 +22,12 @@
import math, pprint, signal
from datetime import datetime
-import runners, transformers
+from . import runners, transformers
-from util import classname
+from .util import classname
-from settings import settings
+from .settings import settings
+import collections
class Aggregator(object):
"""Basic aggregator. Runs all jobs and returns their result."""
@@ -59,7 +60,7 @@ def add_instance(self, name, config):
self.instances[name] = instance
duplicates = config.get('duplicates', None)
if duplicates is not None:
- for i in xrange(int(duplicates)-1):
+ for i in range(int(duplicates)-1):
self.instances["%s - %d" % (name, i+2)] = instance
def aggregate(self):
@@ -70,20 +71,20 @@ def collect(self):
for the threads to exit, then collect the results."""
if self.logfile:
- self.logfile.write(u"Start run at %s\n" % datetime.now())
+ self.logfile.write("Start run at %s\n" % datetime.now())
result = {}
try:
- for n,i in self.instances.items():
+ for n,i in list(self.instances.items()):
self.threads[n] = i['runner'](n, **i)
self.threads[n].start()
- for n,t in self.threads.items():
+ for n,t in list(self.threads.items()):
while t.isAlive():
t.join(1)
self._log(n,t)
if t.result is None:
continue
- elif callable(t.result):
+ elif isinstance(t.result, collections.Callable):
# If the result is callable, the runner is really a
# post-processor (Avg etc), and should be run as such (by the
# postprocess() method)
@@ -103,7 +104,7 @@ def collect(self):
return result
def kill_runners(self):
- for t in self.threads.values():
+ for t in list(self.threads.values()):
t.killed = True
if hasattr(t, 'prog'):
try:
@@ -135,7 +136,7 @@ def __init__(self, *args, **kwargs):
Aggregator.__init__(self, *args, **kwargs)
def aggregate(self, results):
- results.x_values = range(1, self.iterations+1)
+ results.x_values = list(range(1, self.iterations+1))
for i in range(self.iterations):
results.add_result(i+1, self.collect())
return results
@@ -155,16 +156,16 @@ def __init__(self, *args, **kwargs):
def aggregate(self, results):
measurements = self.collect()
if not measurements:
- raise RuntimeError(u"No data to aggregate. Run with -l and check log file to investigate.")
- results.create_series(measurements.keys())
+ raise RuntimeError("No data to aggregate. Run with -l and check log file to investigate.")
+ results.create_series(list(measurements.keys()))
# We start steps at the minimum time value, and do as many steps as are
# necessary to get past the maximum time value with the selected step
# size
- first_times = [i[0][0] for i in measurements.values() if i and i[0]]
- last_times = [i[-1][0] for i in measurements.values() if i and i[-1]]
+ first_times = [i[0][0] for i in list(measurements.values()) if i and i[0]]
+ last_times = [i[-1][0] for i in list(measurements.values()) if i and i[-1]]
if not (first_times and last_times):
- raise RuntimeError(u"No data to aggregate. Run with -l and check log file to investigate.")
+ raise RuntimeError("No data to aggregate. Run with -l and check log file to investigate.")
t_0 = min(first_times)
t_max = max(last_times)
steps = int(math.ceil((t_max-t_0)/self.step))
@@ -181,7 +182,7 @@ def aggregate(self, results):
result = {}
# n is the name of this measurement (from the config), r is the list
# of measurement pairs (time,value)
- for n,r in measurements.items():
+ for n,r in list(measurements.items()):
max_dist = self.max_distance
last = False
if not r:
View
41 netperf_wrapper/formatters.py
@@ -21,8 +21,9 @@
import pprint, sys, csv, math
-from settings import settings
-from util import cum_prob, frange
+from .settings import settings
+from .util import cum_prob, frange
+from functools import reduce
PLOT_KWARGS = (
'alpha',
@@ -53,7 +54,7 @@
class Formatter(object):
def __init__(self, output):
- if isinstance(output, basestring):
+ if isinstance(output, str):
if output == "-":
self.output = sys.stdout
else:
@@ -62,7 +63,7 @@ def __init__(self, output):
self.output = output
def format(self, results):
- sys.stderr.write(u"No output formatter selected.\nTest data is in %s (use with -i to format).\n" % results.dump_file)
+ sys.stderr.write("No output formatter selected.\nTest data is in %s (use with -i to format).\n" % results.dump_file)
DefaultFormatter = Formatter
@@ -76,21 +77,21 @@ def format(self, results):
name = results.meta("NAME")
if not results:
- self.output.write(unicode(name) + u" -- empty\n")
- keys = settings.DATA_SETS.keys()
+ self.output.write(str(name) + " -- empty\n")
+ keys = list(settings.DATA_SETS.keys())
header_row = [name] + keys
- self.output.write(u"| " + u" | ".join(header_row) + u" |\n")
- self.output.write(u"|-" + u"-+-".join([u"-"*len(i) for i in header_row]) + u"-|\n")
+ self.output.write("| " + " | ".join(header_row) + " |\n")
+ self.output.write("|-" + "-+-".join(["-"*len(i) for i in header_row]) + "-|\n")
def format_item(item):
if isinstance(item, float):
return "%.2f" % item
- return unicode(item)
+ return str(item)
for row in results.zipped(keys):
- self.output.write(u"| ")
- self.output.write(u" | ".join(map(format_item, row)))
- self.output.write(u" |\n")
+ self.output.write("| ")
+ self.output.write(" | ".join(map(format_item, row)))
+ self.output.write(" |\n")
@@ -104,17 +105,17 @@ def format(self, results):
return
writer = csv.writer(self.output)
- keys = settings.DATA_SETS.keys()
+ keys = list(settings.DATA_SETS.keys())
header_row = [name] + keys
writer.writerow(header_row)
def format_item(item):
if item is None:
return ""
- return unicode(item)
+ return str(item)
for row in results.zipped(keys):
- writer.writerow(map(format_item, row))
+ writer.writerow(list(map(format_item, row)))
class PlotFormatter(Formatter):
@@ -141,12 +142,12 @@ def __init__(self, output):
self.np = numpy
self._init_plots()
except ImportError:
- raise RuntimeError(u"Unable to plot -- matplotlib is missing! Please install it if you want plots.")
+ raise RuntimeError("Unable to plot -- matplotlib is missing! Please install it if you want plots.")
def _load_plotconfig(self, plot):
if not plot in settings.PLOTS:
- raise RuntimeError(u"Unable to find plot configuration '%s'" % plot)
+ raise RuntimeError("Unable to find plot configuration '%s'" % plot)
config = settings.PLOTS[plot]
if 'parent' in config:
parent_config = settings.PLOTS[config['parent']]
@@ -279,12 +280,12 @@ def _do_cdf_plot(self, results, config=None, axis=None):
# want the unloaded ping values
start,end = config['cutoff']
s_data = s_data[int(start/settings.STEP_SIZE):-int(end/settings.STEP_SIZE)]
- d = sorted(filter(lambda x: x is not None, s_data))
+ d = sorted([x for x in s_data if x is not None])
max_value = max([max_value]+d)
data.append(d)
for r in settings.SCALE_DATA:
- d_s = filter(lambda x: x is not None, r.series(s['data']))
+ d_s = [x for x in r.series(s['data']) if x is not None]
if d_s:
max_value = max([max_value]+d_s)
@@ -373,7 +374,7 @@ def _do_legend(self, config):
def _do_scaling(self, axis, data, btm, top):
"""Scale the axis to the selected bottom/top percentile"""
- data = filter(lambda x: x is not None, data)
+ data = [x for x in data if x is not None]
top_percentile = self.np.percentile(data, top)*1.05
btm_percentile = self.np.percentile(data, btm)*0.95
axis.set_ylim(ymin=btm_percentile, ymax=top_percentile)
View
254 netperf_wrapper/ordereddict.py
@@ -1,127 +1,127 @@
-# Copyright (c) 2009 Raymond Hettinger
-#
-# Permission is hereby granted, free of charge, to any person
-# obtaining a copy of this software and associated documentation files
-# (the "Software"), to deal in the Software without restriction,
-# including without limitation the rights to use, copy, modify, merge,
-# publish, distribute, sublicense, and/or sell copies of the Software,
-# and to permit persons to whom the Software is furnished to do so,
-# subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-# OTHER DEALINGS IN THE SOFTWARE.
-
-from UserDict import DictMixin
-
-class OrderedDict(dict, DictMixin):
-
- def __init__(self, *args, **kwds):
- if len(args) > 1:
- raise TypeError('expected at most 1 arguments, got %d' % len(args))
- try:
- self.__end
- except AttributeError:
- self.clear()
- self.update(*args, **kwds)
-
- def clear(self):
- self.__end = end = []
- end += [None, end, end] # sentinel node for doubly linked list
- self.__map = {} # key --> [key, prev, next]
- dict.clear(self)
-
- def __setitem__(self, key, value):
- if key not in self:
- end = self.__end
- curr = end[1]
- curr[2] = end[1] = self.__map[key] = [key, curr, end]
- dict.__setitem__(self, key, value)
-
- def __delitem__(self, key):
- dict.__delitem__(self, key)
- key, prev, next = self.__map.pop(key)
- prev[2] = next
- next[1] = prev
-
- def __iter__(self):
- end = self.__end
- curr = end[2]
- while curr is not end:
- yield curr[0]
- curr = curr[2]
-
- def __reversed__(self):
- end = self.__end
- curr = end[1]
- while curr is not end:
- yield curr[0]
- curr = curr[1]
-
- def popitem(self, last=True):
- if not self:
- raise KeyError('dictionary is empty')
- if last:
- key = reversed(self).next()
- else:
- key = iter(self).next()
- value = self.pop(key)
- return key, value
-
- def __reduce__(self):
- items = [[k, self[k]] for k in self]
- tmp = self.__map, self.__end
- del self.__map, self.__end
- inst_dict = vars(self).copy()
- self.__map, self.__end = tmp
- if inst_dict:
- return (self.__class__, (items,), inst_dict)
- return self.__class__, (items,)
-
- def keys(self):
- return list(self)
-
- setdefault = DictMixin.setdefault
- update = DictMixin.update
- pop = DictMixin.pop
- values = DictMixin.values
- items = DictMixin.items
- iterkeys = DictMixin.iterkeys
- itervalues = DictMixin.itervalues
- iteritems = DictMixin.iteritems
-
- def __repr__(self):
- if not self:
- return '%s()' % (self.__class__.__name__,)
- return '%s(%r)' % (self.__class__.__name__, self.items())
-
- def copy(self):
- return self.__class__(self)
-
- @classmethod
- def fromkeys(cls, iterable, value=None):
- d = cls()
- for key in iterable:
- d[key] = value
- return d
-
- def __eq__(self, other):
- if isinstance(other, OrderedDict):
- if len(self) != len(other):
- return False
- for p, q in zip(self.items(), other.items()):
- if p != q:
- return False
- return True
- return dict.__eq__(self, other)
-
- def __ne__(self, other):
- return not self == other
+# Copyright (c) 2009 Raymond Hettinger
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+from UserDict import DictMixin
+
+class OrderedDict(dict, DictMixin):
+
+ def __init__(self, *args, **kwds):
+ if len(args) > 1:
+ raise TypeError('expected at most 1 arguments, got %d' % len(args))
+ try:
+ self.__end
+ except AttributeError:
+ self.clear()
+ self.update(*args, **kwds)
+
+ def clear(self):
+ self.__end = end = []
+ end += [None, end, end] # sentinel node for doubly linked list
+ self.__map = {} # key --> [key, prev, next]
+ dict.clear(self)
+
+ def __setitem__(self, key, value):
+ if key not in self:
+ end = self.__end
+ curr = end[1]
+ curr[2] = end[1] = self.__map[key] = [key, curr, end]
+ dict.__setitem__(self, key, value)
+
+ def __delitem__(self, key):
+ dict.__delitem__(self, key)
+ key, prev, next = self.__map.pop(key)
+ prev[2] = next
+ next[1] = prev
+
+ def __iter__(self):
+ end = self.__end
+ curr = end[2]
+ while curr is not end:
+ yield curr[0]
+ curr = curr[2]
+
+ def __reversed__(self):
+ end = self.__end
+ curr = end[1]
+ while curr is not end:
+ yield curr[0]
+ curr = curr[1]
+
+ def popitem(self, last=True):
+ if not self:
+ raise KeyError('dictionary is empty')
+ if last:
+ key = next(reversed(self))
+ else:
+ key = next(iter(self))
+ value = self.pop(key)
+ return key, value
+
+ def __reduce__(self):
+ items = [[k, self[k]] for k in self]
+ tmp = self.__map, self.__end
+ del self.__map, self.__end
+ inst_dict = vars(self).copy()
+ self.__map, self.__end = tmp
+ if inst_dict:
+ return (self.__class__, (items,), inst_dict)
+ return self.__class__, (items,)
+
+ def keys(self):
+ return list(self)
+
+ setdefault = DictMixin.setdefault
+ update = DictMixin.update
+ pop = DictMixin.pop
+ values = DictMixin.values
+ items = DictMixin.items
+ iterkeys = DictMixin.iterkeys
+ itervalues = DictMixin.itervalues
+ iteritems = DictMixin.iteritems
+
+ def __repr__(self):
+ if not self:
+ return '%s()' % (self.__class__.__name__,)
+ return '%s(%r)' % (self.__class__.__name__, list(self.items()))
+
+ def copy(self):
+ return self.__class__(self)
+
+ @classmethod
+ def fromkeys(cls, iterable, value=None):
+ d = cls()
+ for key in iterable:
+ d[key] = value
+ return d
+
+ def __eq__(self, other):
+ if isinstance(other, OrderedDict):
+ if len(self) != len(other):
+ return False
+ for p, q in zip(list(self.items()), list(other.items())):
+ if p != q:
+ return False
+ return True
+ return dict.__eq__(self, other)
+
+ def __ne__(self, other):
+ return not self == other
View
19 netperf_wrapper/resultset.py
@@ -23,7 +23,10 @@
from datetime import datetime
from dateutil.parser import parse as parse_date
-from ordereddict import OrderedDict
+try:
+ from collections import OrderedDict
+except ImportError:
+ from .ordereddict import OrderedDict
# Controls pretty-printing of json dumps
JSON_INDENT=None
@@ -68,7 +71,7 @@ def append_datapoint(self, x, data):
"""
data = dict(data)
self._x_values.append(x)
- for k in self._results.keys():
+ for k in list(self._results.keys()):
if k in data:
self._results[k].append(data[k])
del data[k]
@@ -76,7 +79,7 @@ def append_datapoint(self, x, data):
self._results[k].append(None)
if data:
- raise RuntimeError("Unexpected data point(s): %s" % data.keys())
+ raise RuntimeError("Unexpected data point(s): %s" % list(data.keys()))
def last_datapoint(self, series):
if not self._results[series]:
@@ -92,8 +95,8 @@ def smoothed(self, name, amount):
res = self._results[name]
smooth_res = []
for i in range(len(res)):
- s = max(0,i-amount/2)
- e = min(len(res),i+amount/2)
+ s = int(max(0,i-amount/2))
+ e = int(min(len(res),i+amount/2))
window = [i for i in res[s:e] if i is not None]
if window:
smooth_res.append(math.fsum(window)/len(window))
@@ -104,7 +107,7 @@ def smoothed(self, name, amount):
@property
def series_names(self):
- return self._results.keys()
+ return list(self._results.keys())
def zipped(self, keys=None):
if keys is None:
@@ -148,7 +151,7 @@ def _gen_filename(self):
def dump_dir(self, dirname):
self._dump_file = os.path.join(dirname, self._gen_filename())
- with gzip.open(self._dump_file, "w") as fp:
+ with gzip.open(self._dump_file, "wt") as fp:
self.dump(fp)
@classmethod
@@ -158,7 +161,7 @@ def unserialise(cls, obj):
metadata['TIME'] = parse_date(metadata['TIME'])
rset = cls(**metadata)
rset.x_values = obj['x_values']
- for k,v in obj['results'].items():
+ for k,v in list(obj['results'].items()):
rset.add_result(k,v)
return rset
View
6 netperf_wrapper/runners.py
@@ -23,7 +23,7 @@
from datetime import datetime
-from settings import settings, Glob
+from .settings import settings, Glob
class ProcessRunner(threading.Thread):
"""Default process runner for any process."""
@@ -41,7 +41,7 @@ def run(self):
seconds, then open the subprocess, wait for it to finish, and collect
the last word of the output (whitespace-separated)."""
- for i in xrange(self.delay):
+ for i in range(self.delay):
time.sleep(1)
if self.killed:
return
@@ -191,7 +191,7 @@ def parse(self, output):
# values for the qdiscs are summed for the result (discarding
# what should be the root qdisc as per above).
while m is not None:
- for k,v in m.groupdict().items():
+ for k,v in list(m.groupdict().items()):
if not k in matches:
matches[k] = float(v)
else:
View
47 netperf_wrapper/settings.py
@@ -25,9 +25,12 @@
from fnmatch import fnmatch
-from ordereddict import OrderedDict
-from resultset import ResultSet
-from build_info import DATA_DIR, VERSION
+try:
+ from collections import OrderedDict
+except ImportError:
+ from netperf_wrapper.ordereddict import OrderedDict
+from netperf_wrapper.resultset import ResultSet
+from netperf_wrapper.build_info import DATA_DIR, VERSION
DEFAULT_SETTINGS = {
'HOST': None,
@@ -52,7 +55,7 @@
DICT_SETTINGS = ('DATA_SETS', 'PLOTS')
def version(*args):
- print "Netperf-wrapper v%s." %(VERSION)
+ print("Netperf-wrapper v%s." %(VERSION))
sys.exit(0)
@@ -68,7 +71,7 @@ def __init__(self, pattern, exclude=None):
def filter(self, values, exclude):
exclude += self.exclude
- return filter(lambda x: fnmatch(x, self.pattern) and x not in exclude, values)
+ return [x for x in values if fnmatch(x, self.pattern) and x not in exclude]
def __iter__(self):
return iter((self,)) # allow list(g) to return [g]
@@ -78,10 +81,10 @@ def filter_dict(cls, d):
# Expand glob patterns in parameters. Go through all items in the
# dictionary looking for subkeys that is a Glob instance or a list
# that has a Glob instance in it.
- for k,v in d.items():
- for g_k in v.keys():
+ for k,v in list(d.items()):
+ for g_k in list(v.keys()):
try:
- v[g_k] = cls.expand_list(v[g_k], d.keys(), [k])
+ v[g_k] = cls.expand_list(v[g_k], list(d.keys()), [k])
except TypeError:
continue
return d
@@ -112,7 +115,7 @@ def __init__(self, env={}):
def execute(self, filename):
try:
- execfile(filename, self.env)
+ exec(compile(open(filename).read(), filename, 'exec'), self.env)
return self.env
except (IOError, SyntaxError):
raise RuntimeError("Unable to read test config file: '%s'" % filename)
@@ -174,12 +177,12 @@ def load_test(self, test_name):
test_env = TestEnvironment(self.__dict__)
s = test_env.execute(os.path.join(TEST_PATH, test_name + ".conf"))
- for k,v in s.items():
+ for k,v in list(s.items()):
if k == k.upper():
setattr(self, k, v)
if 'DEFAULTS' in s:
- for k,v in s['DEFAULTS'].items():
+ for k,v in list(s['DEFAULTS'].items()):
if not hasattr(self, k):
setattr(self, k, v)
@@ -193,7 +196,7 @@ def __setattr__(self, k, v):
object.__setattr__(self, k, v)
def update(self, values):
- for k,v in values.items():
+ for k,v in list(values.items()):
setattr(self, k, v)
settings = Settings(DEFAULT_SETTINGS)
@@ -210,9 +213,11 @@ def load():
if settings.INPUT is not None:
try:
- with open(settings.INPUT) as fp:
- if settings.INPUT.endswith(".gz"):
- fp = gzip.GzipFile(fileobj=fp)
+ if settings.INPUT.endswith(".gz"):
+ o = gzip.open
+ else:
+ o = open
+ with o(settings.INPUT, 'rt') as fp:
results = ResultSet.load(fp)
settings.load_test(results.meta("NAME"))
settings.update(results.meta())
@@ -246,7 +251,7 @@ def load():
fp = gzip.GzipFile(fileobj=fp)
r = ResultSet.load(fp)
if r.meta("NAME") != settings.NAME:
- raise RuntimeError(u"Setting name mismatch between test "
+ raise RuntimeError("Setting name mismatch between test "
"data and scale file %s" % filename)
scale_data.append(r)
except IOError:
@@ -265,21 +270,21 @@ def load():
def list_tests():
tests = sorted([os.path.splitext(i)[0] for i in os.listdir(TEST_PATH) if i.endswith('.conf')])
sys.stderr.write('Available tests:\n')
- max_len = unicode(max([len(t) for t in tests]))
+ max_len = str(max([len(t) for t in tests]))
for t in tests:
settings.update(DEFAULT_SETTINGS)
settings.load_test(t)
- sys.stderr.write((u" %-"+max_len+u"s : %s\n") % (t, settings.DESCRIPTION))
+ sys.stderr.write((" %-"+max_len+"s : %s\n") % (t, settings.DESCRIPTION))
sys.exit(0)
def list_plots():
- plots = settings.PLOTS.keys()
+ plots = list(settings.PLOTS.keys())
if not plots:
sys.stderr.write("No plots available for test '%s'.\n" % settings.NAME)
sys.exit(0)
sys.stderr.write("Available plots for test '%s':\n" % settings.NAME)
- max_len = unicode(max([len(p) for p in plots]))
+ max_len = str(max([len(p) for p in plots]))
for p in plots:
- sys.stderr.write((u" %-"+max_len+u"s : %s\n") % (p, settings.PLOTS[p]['description']))
+ sys.stderr.write((" %-"+max_len+"s : %s\n") % (p, settings.PLOTS[p]['description']))
sys.exit(0)
View
2  netperf_wrapper/transformers.py
@@ -22,7 +22,7 @@
def transform_results(results, func):
"""Transform a list of (timestamp,value) pairs by applying a function to the
value."""
- for i in xrange(len(results)):
+ for i in range(len(results)):
results[i][1] = func(results[i][1])
return results
View
27 netperf_wrapper/util.py
@@ -19,9 +19,14 @@
## You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.
-import ConfigParser, math
+import math
from bisect import bisect_left
+try:
+ import configparser
+except ImportError:
+ import ConfigParser as configparser
+
def uscore_to_camel(s):
"""Turn a underscore style string (org_table) into a CamelCase style string
(OrgTable) for class names."""
@@ -54,16 +59,16 @@ def frange(limit1, limit2 = None, increment = 1.):
limit1 = float(limit1)
count = int(math.ceil((limit2 - limit1)/increment))
- return (limit1 + n*increment for n in xrange(count))
+ return (limit1 + n*increment for n in range(count))
-class DefaultConfigParser(ConfigParser.ConfigParser):
+class DefaultConfigParser(configparser.ConfigParser):
class _NoDefault(object):
pass
def get(self, section, option, default=_NoDefault):
try:
- return ConfigParser.ConfigParser.get(self, section, option)
- except ConfigParser.NoOptionError:
+ return configparser.ConfigParser.get(self, section, option)
+ except configparser.NoOptionError:
if default==self._NoDefault:
raise
else:
@@ -71,8 +76,8 @@ def get(self, section, option, default=_NoDefault):
def getint(self, section, option, default=_NoDefault):
try:
- return ConfigParser.ConfigParser.getint(self, section, option)
- except ConfigParser.NoOptionError:
+ return configparser.ConfigParser.getint(self, section, option)
+ except configparser.NoOptionError:
if default==self._NoDefault:
raise
else:
@@ -80,8 +85,8 @@ def getint(self, section, option, default=_NoDefault):
def getfloat(self, section, option, default=_NoDefault):
try:
- return ConfigParser.ConfigParser.getfloat(self, section, option)
- except ConfigParser.NoOptionError:
+ return configparser.ConfigParser.getfloat(self, section, option)
+ except configparser.NoOptionError:
if default==self._NoDefault:
raise
else:
@@ -89,8 +94,8 @@ def getfloat(self, section, option, default=_NoDefault):
def getboolean(self, section, option, default=_NoDefault):
try:
- return ConfigParser.ConfigParser.getboolean(self, section, option)
- except ConfigParser.NoOptionError:
+ return configparser.ConfigParser.getboolean(self, section, option)
+ except configparser.NoOptionError:
if default==self._NoDefault:
raise
else:
Please sign in to comment.
Something went wrong with that request. Please try again.