Skip to content

Commit 005069b

Browse files
committed
Add HCL and date to disposable performance
The data parser may want to compare how the same hardware performed across different dates as well as how different hardware performs the test. The HCL tests have a prefix to not conflict with the properties keys, as they may have the same name, such as "memory", "kernel". For: QubesOS/qubes-issues#1512
1 parent 8f75ba1 commit 005069b

1 file changed

Lines changed: 69 additions & 2 deletions

File tree

tests/dispvm_perf.py

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@
3030
import asyncio
3131
import concurrent.futures
3232
import dataclasses
33-
import logging
3433
import json
34+
import logging
3535
import os
3636
import statistics
3737
import subprocess
3838
import time
39+
import yaml
40+
from datetime import datetime, timezone
3941

4042
from deepmerge import Merger
4143
import qubesadmin
@@ -249,6 +251,30 @@ def get_time():
249251
return time.clock_gettime(time.CLOCK_MONOTONIC)
250252

251253

254+
def hcl() -> dict:
255+
completed_process = subprocess.run(
256+
["qubes-hcl-report", "--yaml-only"], capture_output=True, check=True
257+
)
258+
report = yaml.safe_load(completed_process.stdout)
259+
data = {
260+
"hcl-qubes": report["versions"][0]["qubes"].rstrip(),
261+
"hcl-xen": report["versions"][0]["xen"].rstrip(),
262+
"hcl-kernel": report["versions"][0]["kernel"].rstrip(),
263+
"hcl-memory": int(report["memory"].rstrip()),
264+
}
265+
if os.environ.get("QUBES_TEST_PERF_HWINFO"):
266+
data.update(
267+
{
268+
"hcl-certified": report["certified"].rstrip() != "no",
269+
"hcl-brand": report["brand"].rstrip(),
270+
"hcl-model": report["model"].rstrip(),
271+
"hcl-bios": report["bios"].rstrip(),
272+
"hcl-cpu": report["cpu"].rstrip(),
273+
}
274+
)
275+
return data
276+
277+
252278
class TestRun:
253279
def __init__(self, dom0, dvm, vm1, vm2):
254280
self.dom0 = dom0
@@ -537,13 +563,52 @@ def report_result(self, test, result):
537563
else:
538564
total_time = result
539565
mean = round(total_time / self.iterations, ROUND_PRECISION)
566+
540567
data.update(
541568
{
542569
"iterations": self.iterations,
543570
"mean": mean,
544571
"total": total_time,
572+
"date": datetime.now(timezone.utc).strftime(
573+
"%Y-%m-%dT%H:%M:%S"
574+
),
545575
}
546576
)
577+
578+
template_properties = {}
579+
int_properties = [
580+
"memory",
581+
"maxmem",
582+
"vcpus",
583+
"qrexec_timeout",
584+
"shutdown_timeout",
585+
]
586+
wanted_properties = [*int_properties, "kernel", "kernelopts"]
587+
for prop in wanted_properties:
588+
val = getattr(self.vm1, prop, "")
589+
if prop in int_properties:
590+
val = int(val or 0)
591+
template_properties[prop] = val
592+
data.update(template_properties)
593+
594+
template_features = {}
595+
int_features = ["os-version"]
596+
wanted_features = [
597+
"template-buildtime",
598+
"last-update",
599+
"os",
600+
"os-distribution",
601+
*int_features,
602+
]
603+
for feature in wanted_features:
604+
val = self.vm1.features.check_with_template(feature, "")
605+
if feature in int_features:
606+
val = int(val or 0)
607+
template_features[feature] = val
608+
data.update(template_features)
609+
610+
data.update(hcl())
611+
547612
pretty_mean = f"{mean:.{ROUND_PRECISION}f}"
548613
pretty_total_time = f"{total_time:.{ROUND_PRECISION}f}"
549614
pretty_items = "iterations=" + str(self.iterations)
@@ -659,7 +724,9 @@ def run_test(self, test: TestConfig):
659724
def main():
660725
parser = argparse.ArgumentParser(
661726
epilog="You can set QUBES_TEST_PERF_FILE env variable to a path where "
662-
"machine-readable results should be saved."
727+
"machine-readable results should be saved. If you want to share a "
728+
"detailed result containing hardware information, set "
729+
"QUBES_TEST_PERF_HWINFO to a non empty value."
663730
)
664731
parser.add_argument("--dvm", required=True)
665732
parser.add_argument("--vm1", required=True)

0 commit comments

Comments
 (0)