Skip to content

Commit f0d6980

Browse files
authored
Display additional run information on data points on charts (#148)
This allows arbitrary run information to be displayed on the charts when clicking the data point. The content of the run information is controled by the submitter of that run, which allows a great deal of flexibility. Folks will want to avoid attaching too much information to the runs to avoid making graphs too slow, but that's on them. Fixes #75
1 parent 25c2f4b commit f0d6980

File tree

5 files changed

+114
-12
lines changed

5 files changed

+114
-12
lines changed

docs/developer_guide.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ virtual environment and installing the development dependencies::
1919
pip install ".[dev]"
2020

2121
This will install the current version of the package, along with the dependencies
22-
required for development (``lit``, ``filecheck``, etc).
22+
required for development (``lit``, ``filecheck``, etc). Note that ``curl`` and
23+
``jq`` are also required for running the tests.
2324

2425
Running LNT's Regression Tests
2526
------------------------------

docs/importing_data.rst

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,23 @@ First, make sure you've understood the underlying :ref:`concepts` used by LNT.
5858
]
5959
}
6060
61+
Any optional fields provided in the ``run`` section will be associated to that run and visible
62+
in the UI when looking at that run. This allows annotating runs with useful additional information,
63+
such as the commit information related to this run or similar. This data will also be visible on
64+
charts when viewing historical results. Arbitrary data can be provided, however including too much
65+
run-related information can cause very large amounts of data to have to be transfered to display
66+
graphs.
67+
6168
A concrete small example is
6269

6370
.. literalinclude:: report-example.json
6471
:language: json
6572

6673

67-
Given how simple it is to make your own results and send them to LNT,
68-
it is common to not use the LNT client application at all, and just have a
69-
custom script run your tests and submit the data to the LNT server. Details
70-
on how to do this are in :mod:`lnt.testing`
74+
Given how simple it is to make your own results and send them to LNT, it is common to
75+
not use the LNT client application at all, and just have a custom script run your tests
76+
and submit the data to the LNT server in JSON format.
77+
7178

7279
.. _nts_suite:
7380

lnt/server/ui/static/lnt_graph.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,15 @@ function plotly_show_tooltip(data) {
101101
get_run_url(db_name, test_suite_name, point.meta.runID) +
102102
"\">" + point.meta.runID + "</a><br>";
103103
}
104-
104+
105+
// Display any additional run parameters
106+
var known_fields = ['order', 'orderID', 'date', 'runID', 'state'];
107+
for (var key in point.meta) {
108+
if (point.meta.hasOwnProperty(key) && known_fields.indexOf(key) === -1) {
109+
tip_body += "<b>" + key + ":</b> " + point.meta[key] + "<br>";
110+
}
111+
}
112+
105113
if (point.meta.runID && point.data.url) { // url = machine.id/test.id/field_index
106114
tip_body += "<a href=\"" +
107115
get_manual_regression_url(db_name, test_suite_name, point.data.url, point.meta.runID) +

lnt/server/ui/views.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,7 @@ def load_graph_data(plot_parameter, show_failures, limit, xaxis_date, revision_c
899899
# FIXME: Don't join to Order here, aggregate this across all the tests
900900
# we want to load. Actually, we should just make this a single query.
901901
values = session.query(plot_parameter.field.column, ts.Order,
902-
ts.Run.start_time, ts.Run.id) \
902+
ts.Run.start_time, ts.Run.id, ts.Run.parameters_data) \
903903
.select_from(ts.Sample) \
904904
.join(ts.Run).join(ts.Order) \
905905
.filter(ts.Run.machine_id == plot_parameter.machine.id) \
@@ -916,15 +916,15 @@ def load_graph_data(plot_parameter, show_failures, limit, xaxis_date, revision_c
916916
if xaxis_date:
917917
# Aggregate by date.
918918
data = list(multidict.multidict(
919-
(date, (val, order, date, run_id))
920-
for val, order, date, run_id in values).items())
919+
(date, (val, order, date, run_id, parameters_data))
920+
for val, order, date, run_id, parameters_data in values).items())
921921
# Sort data points according to date.
922922
data.sort(key=lambda sample: sample[0])
923923
else:
924924
# Aggregate by order (revision).
925925
data = list(multidict.multidict(
926-
(order.llvm_project_revision, (val, order, date, run_id))
927-
for val, order, date, run_id in values).items())
926+
(order.llvm_project_revision, (val, order, date, run_id, parameters_data))
927+
for val, order, date, run_id, parameters_data in values).items())
928928
# Sort data points according to order (revision).
929929
data.sort(key=lambda sample: convert_revision(sample[0], cache=revision_cache))
930930

@@ -1194,7 +1194,9 @@ def trace_name(name, test_name, field_name):
11941194
# And the date on which they were taken.
11951195
dates = [data_array[2] for data_array in datapoints]
11961196
# Run ID where this point was collected.
1197-
run_ids = [data_array[3] for data_array in datapoints if len(data_array) == 4]
1197+
run_ids = [data_array[3] for data_array in datapoints if len(data_array) >= 4]
1198+
# Run parameters (JSON-encoded binary data)
1199+
run_parameters_list = [data_array[4] for data_array in datapoints if len(data_array) >= 5]
11981200

11991201
values = [v * normalize_by for v in values]
12001202

@@ -1224,6 +1226,13 @@ def trace_name(name, test_name, field_name):
12241226
"date": str(dates[agg_index])}
12251227
if run_ids:
12261228
point_metadata["runID"] = str(run_ids[agg_index])
1229+
1230+
# Add run parameters to metadata if available
1231+
if run_parameters_list:
1232+
run_params = run_parameters_list[agg_index]
1233+
if run_params:
1234+
point_metadata.update(json.loads(run_params.decode('utf-8')))
1235+
12271236
meta.append(point_metadata)
12281237

12291238
# Add the multisample points, if requested.
@@ -1235,6 +1244,13 @@ def trace_name(name, test_name, field_name):
12351244
"date": str(dates[i])}
12361245
if run_ids:
12371246
multisample_metadata["runID"] = str(run_ids[i])
1247+
1248+
# Add run parameters to metadata if available
1249+
if run_parameters_list:
1250+
run_params = run_parameters_list[i]
1251+
if run_params:
1252+
multisample_metadata.update(json.loads(run_params.decode('utf-8')))
1253+
12381254
multisample_points_data["x"].append(point_label)
12391255
multisample_points_data["y"].append(v)
12401256
multisample_points_data["meta"].append(multisample_metadata)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/bin/bash
2+
# RUN: rm -rf %t && mkdir -p %t
3+
# RUN: lnt create %t/instance
4+
# RUN: %{shared_inputs}/server_wrapper.sh --fail-on-error %t/instance 9094 \
5+
# RUN: /bin/sh %s %t
6+
7+
#
8+
# Make sure that we can have extra information in the run, and that such information
9+
# is saved into the DB.
10+
#
11+
12+
set -eux
13+
14+
t="$1"
15+
HOST="http://localhost:9094"
16+
17+
# Simple case
18+
cat <<EOF > "$t/report1.json"
19+
{
20+
"format_version": "2",
21+
"machine": {
22+
"name": "machine-foo"
23+
},
24+
"run": {
25+
"start_time": "2026-01-01T11:28:33.00000",
26+
"end_time": "2026-01-01T11:28:23.991076",
27+
"llvm_project_revision": "1",
28+
"some_extra_information1": "some tokens",
29+
"some_extra_information2": "more tokens"
30+
},
31+
"tests": [
32+
{
33+
"name": "benchmark1",
34+
"execution_time": [ 0.1056, 0.1055 ]
35+
}
36+
]
37+
}
38+
EOF
39+
40+
lnt submit "${HOST}/db_default/v4/nts/submitRun" "$t/report1.json"
41+
curl -sS "${HOST}/api/db_default/v4/nts/runs/1" > "$t/run1.json"
42+
jq .run.some_extra_information1 "$t/run1.json" | grep "some tokens"
43+
jq .run.some_extra_information2 "$t/run1.json" | grep "more tokens"
44+
45+
46+
# Add different fields with another run
47+
cat <<EOF > "$t/report2.json"
48+
{
49+
"format_version": "2",
50+
"machine": {
51+
"name": "machine-foo"
52+
},
53+
"run": {
54+
"start_time": "2026-01-02T11:28:33.00000",
55+
"end_time": "2026-01-02T11:28:23.991076",
56+
"llvm_project_revision": "2",
57+
"some_extra_information3": "some tokens 3"
58+
},
59+
"tests": [
60+
{
61+
"name": "benchmark1",
62+
"execution_time": [ 0.1056, 0.1055 ]
63+
}
64+
]
65+
}
66+
EOF
67+
68+
lnt submit "${HOST}/db_default/v4/nts/submitRun" "$t/report2.json"
69+
curl -sS "${HOST}/api/db_default/v4/nts/runs/2" > "$t/run2.json"
70+
jq .run.some_extra_information3 "$t/run2.json" | grep "some tokens 3"

0 commit comments

Comments
 (0)