Move to new sensor selector, fix some bugs
diff --git a/wally/console_report.py b/wally/console_report.py
index 6490329..381d9ff 100644
--- a/wally/console_report.py
+++ b/wally/console_report.py
@@ -1,52 +1,73 @@
import logging
-
+from typing import cast, Iterator, List, Union
import numpy
from cephlib.common import float2str
-from cephlib import texttable
+from cephlib.texttable import Texttable
from cephlib.statistic import calc_norm_stat_props, calc_histo_stat_props
from .stage import Stage, StepOrder
from .test_run_class import TestRun
+from .result_classes import SuiteConfig
from .suits.io.fio import FioTest
+from .suits.io.fio_job import FioJobParams
from .suits.io.fio_hist import get_lat_vals
from .data_selectors import get_aggregated
+from .result_storage import IWallyStorage
logger = logging.getLogger("wally")
+
+console_report_headers = ["Description", "IOPS ~ Dev", "BW, MiBps", 'Skew/Kurt', 'lat med, ms', 'lat 95, ms']
+console_report_align = ['l', 'r', 'r', 'r', 'r', 'r']
+
+def get_console_report_table(suite: SuiteConfig, rstorage: IWallyStorage) -> List[Union[List[str], Texttable.HLINE]]:
+ table = [] # type: List[Union[List[str], Texttable.HLINE]]
+ prev_params = None
+ for job in sorted(rstorage.iter_job(suite), key=lambda job: job.params):
+ fparams = cast(FioJobParams, job.params)
+ fparams['qd'] = None
+
+ if prev_params is not None and fparams.char_tpl != prev_params:
+ table.append(Texttable.HLINE)
+
+ prev_params = fparams.char_tpl
+
+ bw_ts = get_aggregated(rstorage, suite.storage_id, job.storage_id, metric='bw',
+ trange=job.reliable_info_range_s)
+ props = calc_norm_stat_props(bw_ts)
+ avg_iops = props.average // job.params.params['bsize']
+ iops_dev = props.deviation // job.params.params['bsize']
+
+ lat_ts = get_aggregated(rstorage, suite.storage_id, job.storage_id, metric='lat',
+ trange=job.reliable_info_range_s)
+ bins_edges = numpy.array(get_lat_vals(lat_ts.data.shape[1]), dtype='float32') / 1000 # convert us to ms
+ lat_props = calc_histo_stat_props(lat_ts, bins_edges)
+ table.append([job.params.summary,
+ "{:>6s} ~ {:>6s}".format(float2str(avg_iops), float2str(iops_dev)),
+ float2str(props.average / 1024), # Ki -> Mi
+ "{:>5.1f}/{:>5.1f}".format(props.skew, props.kurt),
+ float2str(lat_props.perc_50), float2str(lat_props.perc_95)])
+ return table
+
+
class ConsoleReportStage(Stage):
priority = StepOrder.REPORT
def run(self, ctx: TestRun) -> None:
for suite in ctx.rstorage.iter_suite(FioTest.name):
- table = texttable.Texttable(max_width=200)
-
+ table = Texttable(max_width=200)
+ table.set_deco(Texttable.VLINES | Texttable.BORDER | Texttable.HEADER)
tbl = ctx.rstorage.get_txt_report(suite)
if tbl is None:
- table.header(["Description", "IOPS ~ Dev", "BW, MiBps", 'Skew/Kurt', 'lat med, ms', 'lat 95, ms'])
- table.set_cols_align(('l', 'r', 'r', 'r', 'r', 'r'))
-
- for job in sorted(ctx.rstorage.iter_job(suite), key=lambda job: job.params):
- bw_ts = get_aggregated(ctx.rstorage, suite.storage_id, job.storage_id, metric='bw',
- trange=job.reliable_info_range_s)
- props = calc_norm_stat_props(bw_ts)
- avg_iops = props.average // job.params.params['bsize']
- iops_dev = props.deviation // job.params.params['bsize']
-
- lat_ts = get_aggregated(ctx.rstorage, suite.storage_id, job.storage_id, metric='lat',
- trange=job.reliable_info_range_s)
- bins_edges = numpy.array(get_lat_vals(lat_ts.data.shape[1]), dtype='float32') / 1000 # convert us to ms
- lat_props = calc_histo_stat_props(lat_ts, bins_edges)
- table.add_row([job.params.summary,
- "{} ~ {}".format(float2str(avg_iops), float2str(iops_dev)),
- float2str(props.average / 1024), # Ki -> Mi
- "{}/{}".format(float2str(props.skew), float2str(props.kurt)),
- float2str(lat_props.perc_50), float2str(lat_props.perc_95)])
-
+ table.header(console_report_headers)
+ table.set_cols_align(console_report_align)
+ for line in get_console_report_table(suite, ctx.rstorage):
+ table.add_row(line)
tbl = table.draw()
ctx.rstorage.put_txt_report(suite, tbl)
print(tbl)