diff --git a/lnst/Controller/RunSummaryFormatters/JsonRunSummaryFormatter.py b/lnst/Controller/RunSummaryFormatters/JsonRunSummaryFormatter.py index 8b8422366..1b35b5616 100644 --- a/lnst/Controller/RunSummaryFormatters/JsonRunSummaryFormatter.py +++ b/lnst/Controller/RunSummaryFormatters/JsonRunSummaryFormatter.py @@ -3,7 +3,16 @@ import json from lnst.Controller.Recipe import RecipeRun -from lnst.Controller.RecipeResults import DeviceMethodCallResult, JobResult, JobStartResult, MeasurementResult, Result +from lnst.Controller.RecipeResults import ( + DeviceAttrSetResult, + DeviceConfigResult, + DeviceCreateResult, + DeviceMethodCallResult, + JobResult, + JobStartResult, + MeasurementResult, + BaseResult, +) from .RunSummaryFormatter import RunSummaryFormatter @@ -32,7 +41,7 @@ def format_run(self, run: RecipeRun) -> str: indent=4 if self.pretty else None, ) - def _transform_result(self, result: Result) -> Optional[dict]: + def _transform_result(self, result: BaseResult) -> Optional[dict]: ret = { "result": str(result.result), } @@ -52,18 +61,43 @@ def _transform_result(self, result: Result) -> Optional[dict]: "action": "start" if isinstance(result, JobStartResult) else "end", "job": job_info, } - elif isinstance(result, DeviceMethodCallResult): + elif isinstance(result, DeviceConfigResult): + if isinstance(result, DeviceCreateResult): + action_info = { + "action": "create", + "device": { + "cls_name": result.device._dev_cls.__name__, + "args": [repr(arg) for arg in result.device._dev_args], + "kwargs": [f"{k}={v!r}" for k, v in result.device._dev_kwargs.items()], + }, + } + elif isinstance(result, DeviceMethodCallResult): + action_info = { + "action": "method_call", + "method": { + "name": result.method_name, + "args": [repr(arg) for arg in result.args], + "kwargs": [f"{k}={v!r}" for k, v in result.kwargs.items()], + }, + } + elif isinstance(result, DeviceAttrSetResult): + action_info = { + "action": "attr_set", + "attr": { + "name": result.attr_name, + "value": result.value, + "old_value": result.old_value, + }, + } + else: + logging.warning(f"unhandled device config result: {result.__class__.__name__}") + action_info = {"action": "unknown"} return ret | { - "type": "device_method_call", + "type": "device_config", "host": result.device.host.hostid, "netns": result.device.netns.name if result.device.netns and result.device.netns.name else "", "dev_id": result.device._id, - "method": { - "name": result.method_name, - "args": [repr(arg) for arg in result.args], - "kwargs": [f"{k}={v!r}" for k, v in result.kwargs.items()], - }, - } + } | action_info elif isinstance(result, MeasurementResult): if result.measurement_type == "ping": measurement_data = result.data @@ -85,23 +119,20 @@ def _transform_result(self, result: Result) -> Optional[dict]: } elif result.measurement_type == "linuxperf": # linuxperf measurement just generates files - return None + measurement_data = {} else: logging.warning(f"unhandled measurement result type: {result.measurement_type}") - return None + measurement_data = None return ret | { "type": "measurement", "measurement_type": result.measurement_type, "data": measurement_data, } - elif isinstance(result, Result): - if result.data is None: - return ret | { - "type": "unknown", - "description": result.description, - } - else: - logging.warning(f"unhandled recipe result type: {repr(result)} with data of type {type(result.data)}") else: - logging.warning(f"unhandled recipe result type: {repr(result)}") - return None + if result.data is not None: + logging.warning(f"unhandled recipe result type: {repr(result)}, can't format its data") + + return ret | { + "type": "unknown", + "description": result.description, + } diff --git a/lnst/RecipeCommon/Perf/Evaluators/BaselineEvaluator.py b/lnst/RecipeCommon/Perf/Evaluators/BaselineEvaluator.py index 1dc900cff..6c072b55f 100644 --- a/lnst/RecipeCommon/Perf/Evaluators/BaselineEvaluator.py +++ b/lnst/RecipeCommon/Perf/Evaluators/BaselineEvaluator.py @@ -78,6 +78,7 @@ def evaluate_group_results( comparisons.extend( [ { + "measurement_type": result.measurement.__class__.__name__, "current_result": result, "baseline_result": baseline, "comparison_result": metric.result,