fix build comparisio
diff --git a/wally/run_test.py b/wally/run_test.py
index 0dab8c7..0e8f6e9 100755
--- a/wally/run_test.py
+++ b/wally/run_test.py
@@ -590,9 +590,9 @@
ctx.results[tp] = map(cls.load, results)
-def load_data_from_path(var_dir, _, ctx):
- ctx.results = {}
+def load_data_from_path(var_dir):
res_dir = os.path.join(var_dir, 'results')
+ res = {}
for dir_name in os.listdir(res_dir):
dir_path = os.path.join(res_dir, dir_name)
if not os.path.isdir(dir_path):
@@ -601,12 +601,18 @@
if rr is None:
continue
tp = rr.group('type')
- arr = ctx.results.setdefault(tp, [])
+ arr = res.setdefault(tp, [])
arr.extend(TOOL_TYPE_MAPPER[tp].load(dir_path))
+ return res
+
+
+def load_data_from_path_stage(var_dir, _, ctx):
+ for tp, vals in load_data_from_path(var_dir).items():
+ ctx.results.setdefault(tp, []).extend(vals)
def load_data_from(var_dir):
- return functools.partial(load_data_from_path, var_dir)
+ return functools.partial(load_data_from_path_stage, var_dir)
def parse_args(argv):
@@ -724,6 +730,11 @@
opts = parse_args(argv)
+ # x = load_data_from_path("/var/wally_results/silky_virgen")
+ # y = load_data_from_path("/var/wally_results/cibarial_jacob")
+ # print(IOPerfTest.format_diff_for_console([x['io'], y['io']]))
+ # exit(1)
+
if opts.ls:
list_results(opts.config_file)
exit(0)
@@ -783,6 +794,7 @@
cfg_dict['var_dir']))
ctx = Context()
+ ctx.results = {}
ctx.build_meta['build_id'] = opts.build_id
ctx.build_meta['build_descrption'] = opts.build_description
ctx.build_meta['build_type'] = opts.build_type
diff --git a/wally/suits/io/fio.py b/wally/suits/io/fio.py
index c64523d..7b90091 100644
--- a/wally/suits/io/fio.py
+++ b/wally/suits/io/fio.py
@@ -588,7 +588,7 @@
lat_bw_limit_reached = set()
with ThreadPoolExecutor(len(self.config.nodes)) as pool:
- self.fio_configs.sort(key=lambda x: int(x.vals['numjobs']))
+ self.fio_configs.sort(key=lambda x: int(x.vals.get('numjobs', 1)))
for pos, fio_cfg in enumerate(self.fio_configs):
test_descr = get_test_summary(fio_cfg.vals).split("th")[0]
@@ -815,7 +815,7 @@
return begin, end
@classmethod
- def format_for_console(cls, results):
+ def prepare_data(cls, results):
"""
create a table with io performance report
for console
@@ -838,25 +838,9 @@
get_test_sync_mode(data.params['vals']),
ssize2b(p['blocksize']),
int(th_count) * len(data.config.nodes))
+ res = []
- tab = texttable.Texttable(max_width=120)
- tab.set_deco(tab.HEADER | tab.VLINES | tab.BORDER)
-
- header = ["Name", "Description", "iops\ncum", "KiBps\ncum",
- "Cnf\n95%", "Dev%", "iops\nper vm", "KiBps\nper vm", "lat ms\nmedian"]
- tab.set_cols_align(["l", "l"] + ['r'] * (len(header) - 2))
- sep = ["-------", "-----------"] + ["---"] * (len(header) - 2)
- tab.header(header)
-
- prev_k = None
for item in sorted(results, key=key_func):
- curr_k = key_func(item)[:4]
- if prev_k is not None:
- if prev_k != curr_k:
- tab.add_row(sep)
-
- prev_k = curr_k
-
test_dinfo = item.disk_perf_info()
iops, _ = test_dinfo.iops.rounded_average_conf()
@@ -866,25 +850,162 @@
conf_perc = int(round(bw_conf * 100 / bw))
dev_perc = int(round(bw_dev * 100 / bw))
- lat = round_3_digit(int(test_dinfo.lat))
+ lat_50 = round_3_digit(int(test_dinfo.lat_50))
+ lat_95 = round_3_digit(int(test_dinfo.lat_95))
testnodes_count = len(item.config.nodes)
iops_per_vm = round_3_digit(iops / testnodes_count)
bw_per_vm = round_3_digit(bw / testnodes_count)
iops = round_3_digit(iops)
- # iops_from_lat = round_3_digit(iops_from_lat)
bw = round_3_digit(bw)
- params = (item.name.rsplit('_', 1)[0],
- item.summary(),
- int(iops),
- int(bw),
- str(conf_perc),
- str(dev_perc),
- int(iops_per_vm),
- int(bw_per_vm),
- lat)
- tab.add_row(params)
+ res.append({"name": item.name.rsplit('_', 1)[0],
+ "key": key_func(item),
+ "summ": item.summary()[3:],
+ "iops": int(iops),
+ "bw": int(bw),
+ "iops_conf": str(conf_perc),
+ "iops_dev": str(dev_perc),
+ "iops_per_vm": int(iops_per_vm),
+ "bw_per_vm": int(bw_per_vm),
+ "lat_50": lat_50,
+ "lat_95": lat_95})
+ return res
+
+ Field = collections.namedtuple("Field", ("header", "attr", "allign", "size"))
+ fiels_and_header = [
+ Field("Name", "name", "l", 7),
+ Field("Description", "summ", "l", 10),
+ Field("IOPS\ncum", "iops", "r", 3),
+ Field("KiBps\ncum", "bw", "r", 3),
+ Field("Cnf %\n95%", "iops_conf", "r", 3),
+ Field("Dev%", "iops_dev", "r", 3),
+ Field("iops\nper vm", "iops_per_vm", "r", 3),
+ Field("KiBps\nper vm", "bw_per_vm", "r", 3),
+ Field("lat ms\nmedian", "lat_50", "r", 3),
+ Field("lat ms\n95%", "lat_95", "r", 3)
+ ]
+
+ fiels_and_header_dct = dict((item.attr, item) for item in fiels_and_header)
+
+ @classmethod
+ def format_for_console(cls, results):
+ """
+ create a table with io performance report
+ for console
+ """
+
+ tab = texttable.Texttable(max_width=120)
+ tab.set_deco(tab.HEADER | tab.VLINES | tab.BORDER)
+ tab.set_cols_align([f.allign for f in cls.fiels_and_header])
+ sep = ["-" * f.size for f in cls.fiels_and_header]
+ tab.header([f.header for f in cls.fiels_and_header])
+
+ prev_k = None
+ for item in cls.prepare_data(results):
+ curr_k = item['summ'][:4]
+ if prev_k is not None:
+ if prev_k != curr_k:
+ tab.add_row(sep)
+
+ prev_k = curr_k
+ tab.add_row([item[f.attr] for f in cls.fiels_and_header])
+
+ return tab.draw()
+
+ @classmethod
+ def format_diff_for_console(cls, list_of_results):
+ """
+ create a table with io performance report
+ for console
+ """
+
+ tab = texttable.Texttable(max_width=200)
+ tab.set_deco(tab.HEADER | tab.VLINES | tab.BORDER)
+
+ header = [
+ cls.fiels_and_header_dct["name"].header,
+ cls.fiels_and_header_dct["summ"].header,
+ ]
+ allign = ["l", "l"]
+
+ header.append("IOPS ~ Cnf% ~ Dev%")
+ allign.extend(["r"] * len(list_of_results))
+ header.extend(
+ "IOPS_{0} %".format(i + 2) for i in range(len(list_of_results[1:]))
+ )
+
+ header.append("BW")
+ allign.extend(["r"] * len(list_of_results))
+ header.extend(
+ "BW_{0} %".format(i + 2) for i in range(len(list_of_results[1:]))
+ )
+
+ header.append("LAT")
+ allign.extend(["r"] * len(list_of_results))
+ header.extend(
+ "LAT_{0}".format(i + 2) for i in range(len(list_of_results[1:]))
+ )
+
+ tab.header(header)
+ sep = ["-" * 3] * len(header)
+ processed_results = map(cls.prepare_data, list_of_results)
+
+ key2results = []
+ for res in processed_results:
+ key2results.append(dict(
+ ((item["name"], item["summ"]), item) for item in res
+ ))
+
+ prev_k = None
+ iops_frmt = "{0[iops]} ~ {0[iops_conf]:>2} ~ {0[iops_dev]:>2}"
+ for item in processed_results[0]:
+ curr_k = item['summ'][:4]
+ if prev_k is not None:
+ if prev_k != curr_k:
+ tab.add_row(sep)
+
+ prev_k = curr_k
+
+ key = (item['name'], item['summ'])
+ line = list(key)
+ base = key2results[0][key]
+
+ line.append(iops_frmt.format(base))
+
+ for test_results in key2results[1:]:
+ val = test_results.get(key)
+ if val is None:
+ line.append("-")
+ elif base['iops'] == 0:
+ line.append("Nan")
+ else:
+ prc_val = {'iops_dev': val['iops_dev'],
+ 'iops_conf': val['iops_conf']}
+ prc_val['iops'] = int(100 * val['iops'] / base['iops'])
+ line.append(iops_frmt.format(prc_val))
+
+ line.append(base['bw'])
+
+ for test_results in key2results[1:]:
+ val = test_results.get(key)
+ if val is None:
+ line.append("-")
+ elif base['bw'] == 0:
+ line.append("Nan")
+ else:
+ line.append(int(100 * val['bw'] / base['bw']))
+
+ for test_results in key2results:
+ val = test_results.get(key)
+ if val is None:
+ line.append("-")
+ else:
+ line.append("{0[lat_50]} - {0[lat_95]}".format(val))
+
+ tab.add_row(line)
+
+ tab.set_cols_align(allign)
return tab.draw()
diff --git a/wally/suits/io/rrd.cfg b/wally/suits/io/rrd.cfg
index 4cf9ca9..d5a92bb 100644
--- a/wally/suits/io/rrd.cfg
+++ b/wally/suits/io/rrd.cfg
@@ -8,9 +8,9 @@
blocksize=4k
rw=randwrite
sync=1
-ramp_time=0
+ramp_time=10
runtime=60
-numjobs=50
+numjobs={% 20,40,60,80,100,120,140 %}
# ---------------------------------------------------------------------
# [rws_{TEST_SUMM}]