def open_raw_results(respaths, toolname, reportids=None, reportid_additional_chars=None): """ Opens the input raw test results, and returns the list of 'RORawResult' objects. * respaths - list of paths to raw results. * toolname - name of the tool opening raw results. * reportids - list of reportids to override report IDs in raw results. * reportid_additional_chars - string of characters allowed in report ID on top of default characters. """ if reportids: reportids = Trivial.split_csv_line(reportids) else: reportids = [] if len(reportids) > len(respaths): raise Error(f"there are {len(reportids)} report IDs to assign to {len(respaths)} input " f"test results. Please, provide {len(respaths)} or less report IDs.") # Append the required amount of 'None's to make the 'reportids' list be of the same length as # the 'respaths' list. reportids += [None] * (len(respaths) - len(reportids)) rsts = [] for respath, reportid in zip(respaths, reportids): if reportid: ReportID.validate_reportid(reportid, additional_chars=reportid_additional_chars) res = RORawResult.RORawResult(respath, reportid=reportid) if toolname != res.info["toolname"]: raise Error(f"cannot generate '{toolname}' report, results are collected with the" f"'{res.info['toolname']}':\n{respath}") rsts.append(res) return rsts
def calc_command(args): """Implements the 'calc' command for the 'wult' and 'ndl' tools.""" if args.list_funcs: for name, descr in RORawResult.get_smry_funcs(): _LOG.info("%s: %s", name, descr) return if args.funcs: funcnames = Trivial.split_csv_line(args.funcs) all_funcs = True else: funcnames = None all_funcs = False res = RORawResult.RORawResult(args.respath) apply_filters(args, res) non_numeric = res.get_non_numeric_colnames() if non_numeric and (args.csel or args.cfilt): non_numeric = ", ".join(non_numeric) _LOG.warning("skipping non-numeric column(s): %s", non_numeric) res.calc_smrys(funcnames=funcnames, all_funcs=all_funcs) _LOG.info("Datapoints count: %d", len(res.df)) YAML.dump(res.smrys, sys.stdout, float_format="%.2f")
def _validate_range(rng, what, single_ok): """Implements 'parse_ldist()'.""" if single_ok: min_len = 1 else: min_len = 2 split_rng = Trivial.split_csv_line(rng) if len(split_rng) < min_len: raise Error(f"bad {what} range '{rng}', it should include {min_len} numbers") if len(split_rng) > 2: raise Error(f"bad {what} range '{rng}', it should not include more than 2 numbers") vals = [None] * len(split_rng) for idx, val in enumerate(split_rng): vals[idx] = Human.parse_duration_ns(val, default_unit="us", name=what) if vals[idx] < 0: raise Error(f"bad {what} value '{split_rng[idx]}', should be greater than zero") if len(vals) == 2 and vals[1] - vals[0] < 0: raise Error(f"bad {what} range '{rng}', first number cannot be greater than the second " f"number") if len(vals) == 1: vals.append(vals[0]) return vals
def _parse_ip_address_show(raw): """ Parse output of the 'ip address show <IFNAME>' command and return the resulting dictionary. """ info = {} for line in raw.splitlines(): line = line.strip() elts = Trivial.split_csv_line(line, sep=" ") if re.match(r"^\d+:$", elts[0]): info["ifname"] = elts[1][:-1] elif elts[0] == "inet": ipnet = ipaddress.IPv4Network(elts[1], strict=False) info["ipv4"] = {} info["ipv4"]["ip"] = ipnet.network_address info["ipv4"]["mask"] = ipnet.netmask info["ipv4"]["bcast"] = ipnet.broadcast_address info["ipv4"]["ip_cidr"] = elts[1] info["ipv4"]["cidr"] = str(ipnet) elif elts[0] == "link/ether": info["ether"] = {} info["ether"]["mac"] = elts[1] info["ether"]["bcast"] = elts[3] return info
def set_filter(res, ops): """Set filter operations in 'ops' to test result 'res'.""" res.clear_filts() for name, expr in ops.items(): # The '--csel' and '--cfilt' options may have comma-separated list of column names. if name.startswith("c"): expr = Trivial.split_csv_line(expr) getattr(res, f"set_{name}")(expr)
def _get_deployables(srcpath, proc=None): """ Returns the list of "deployables" (driver names or helper tool names) provided by tools or drivers source code directory 'srcpath' on a host defined by 'proc'. """ if not proc: proc = Procs.Proc() cmd = f"make --silent -C '{srcpath}' list_deployables" deployables, _ = proc.run_verify(cmd) if deployables: deployables = Trivial.split_csv_line(deployables, sep=" ") return deployables
def _get_latency(self): """ Read the next latency data line from the 'ndlrunner' helper, parse it, and ireturn the resulting dictionary. """ line = self._get_line(prefix="datapoint") line = Trivial.split_csv_line(line) if len(line) != 2: msg = self._unexpected_line_error_prefix(line) raise Error( f"{msg}\nExpected 2 comma-separated integers, got {len(line)}") for val in line: if not Trivial.is_int(val): msg = self._unexpected_line_error_prefix(line) raise Error( f"{msg}\n: Expected 2 comma-separated integers, got a non-integer " f"'{val}'") # Convert nanoseconds to microseconds. line = [int(val) / 1000 for val in line] return {"RTD": line[0], "LDist": line[1]}