Defining Metrics
buildtest provides a method to define test metrics in the buildspecs which can be used to
store arbitrary content from the output/error file or an arbitrary file into named metric. The
metrics
property is used to define a list of metric names using regular expression to assign a value
to the metric. In this example, we have two tests that define metrics hpcg_rate_stream
, hpcg_state_stream
in the first test and hpcg_rate_file
, hpcg_state_file
in the second test. The stream
property is used
to read from stdout/stderr and apply the regular expression defined by exp
, whereas file_regex
is used
to define metrics from an arbitrary file where file
is the path to file.
buildspecs:
metric_regex_example:
executor: generic.local.bash
type: script
description: capture result metric from output
run: echo "HPCG result is VALID with a GFLOP/s rating of=63.6515"
tags: tutorials
metrics:
hpcg_rating_stream:
type: float
regex:
exp: '(\d+\.\d+)$'
stream: stdout
hpcg_state_stream:
type: str
regex:
exp: '(VALID)'
stream: stdout
metric_file_regex:
executor: generic.local.bash
type: script
description: capture result metric from file path
run: echo "HPCG result is VALID with a GFLOP/s rating of=63.6515" > hpcg.txt
tags: tutorials
metrics:
hpcg_rating_file:
type: float
file_regex:
exp: '(\d+\.\d+)$'
file: hpcg.txt
hpcg_state_file:
type: str
file_regex:
exp: '(VALID)'
file: hpcg.txt
The metrics can be used with Comparison Operators for performing more sophisticated status checks.
By default, a metric will be an empty dictionary if there is no metrics
property. If we fail to match
a regular expression, the metric will be defined as an empty string (''
).
Note
If your regular expression contains an escape character \
you must surround your
string in single quotes '
as pose to double quotes "
Let’s build this test.
buildtest build -b tutorials/metrics/metrics_regex.yml
$ buildtest build -b tutorials/metrics/metrics_regex.yml
╭───────────────────────────── buildtest summary ──────────────────────────────╮
│ │
│ User: docs │
│ Hostname: build-25534835-project-280831-buildtest │
│ Platform: Linux │
│ Current Time: 2024/09/05 15:37:52 │
│ buildtest path: /home/docs/checkouts/readthedocs.org/user_builds/buildte │
│ buildtest version: 2.1 │
│ python path: /home/docs/checkouts/readthedocs.org/user_builds/buildte │
│ python version: 3.9.19 │
│ Configuration File: /tmp/tmpr88132k2/config.yml │
│ Test Directory: /tmp/tmpr88132k2/var/tests │
│ Report File: /tmp/tmpr88132k2/var/report.json │
│ Command: /home/docs/checkouts/readthedocs.org/user_builds/buildte │
│ │
╰──────────────────────────────────────────────────────────────────────────────╯
─────────────────────────── Discovering Buildspecs ────────────────────────────
Discovered buildspecs
╔══════════════════════════════════════════════════════════════════════════════╗
║ buildspec ║
╟──────────────────────────────────────────────────────────────────────────────╢
║ /home/docs/checkouts/readthedocs.org/user_builds/buildtest/checkouts/stable/ ║
║ tutorials/metrics/metrics_regex.yml ║
╟──────────────────────────────────────────────────────────────────────────────╢
║ Total: 1 ║
╚══════════════════════════════════════════════════════════════════════════════╝
Total Discovered Buildspecs: 1
Total Excluded Buildspecs: 0
Detected Buildspecs after exclusion: 1
────────────────────────────── Parsing Buildspecs ──────────────────────────────
Valid Buildspecs: 1
Invalid Buildspecs: 0
/home/docs/checkouts/readthedocs.org/user_builds/buildtest/checkouts/stable/tutorials/metrics/metrics_regex.yml: VALID
Total builder objects created: 2
Builders by type=script
┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┓
┃ ┃ ┃ ┃ ┃ ┃ ┃ descript ┃ buildsp ┃
┃ builder ┃ type ┃ executor ┃ compiler ┃ nodes ┃ procs ┃ ion ┃ ecs ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━┩
│ metric_r │ script │ generic. │ None │ None │ None │ capture │ /home/d │
│ egex_exa │ │ local.ba │ │ │ │ result │ ocs/che │
│ mple/de7 │ │ sh │ │ │ │ metric │ ckouts/ │
│ abe5f │ │ │ │ │ │ from │ readthe │
│ │ │ │ │ │ │ output │ docs.or │
│ │ │ │ │ │ │ │ g/user_ │
│ │ │ │ │ │ │ │ builds/ │
│ │ │ │ │ │ │ │ buildte │
│ │ │ │ │ │ │ │ st/chec │
│ │ │ │ │ │ │ │ kouts/s │
│ │ │ │ │ │ │ │ table/t │
│ │ │ │ │ │ │ │ utorial │
│ │ │ │ │ │ │ │ s/metri │
│ │ │ │ │ │ │ │ cs/metr │
│ │ │ │ │ │ │ │ ics_reg │
│ │ │ │ │ │ │ │ ex.yml │
├──────────┼────────┼──────────┼──────────┼───────┼───────┼──────────┼─────────┤
│ metric_f │ script │ generic. │ None │ None │ None │ capture │ /home/d │
│ ile_rege │ │ local.ba │ │ │ │ result │ ocs/che │
│ x/d4b90d │ │ sh │ │ │ │ metric │ ckouts/ │
│ 87 │ │ │ │ │ │ from │ readthe │
│ │ │ │ │ │ │ file │ docs.or │
│ │ │ │ │ │ │ path │ g/user_ │
│ │ │ │ │ │ │ │ builds/ │
│ │ │ │ │ │ │ │ buildte │
│ │ │ │ │ │ │ │ st/chec │
│ │ │ │ │ │ │ │ kouts/s │
│ │ │ │ │ │ │ │ table/t │
│ │ │ │ │ │ │ │ utorial │
│ │ │ │ │ │ │ │ s/metri │
│ │ │ │ │ │ │ │ cs/metr │
│ │ │ │ │ │ │ │ ics_reg │
│ │ │ │ │ │ │ │ ex.yml │
└──────────┴────────┴──────────┴──────────┴───────┴───────┴──────────┴─────────┘
──────────────────────────────── Building Test ─────────────────────────────────
metric_regex_example/de7abe5f: Creating Test Directory: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_regex_example/de7abe5f
metric_file_regex/d4b90d87: Creating Test Directory: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_file_regex/d4b90d87
──────────────────────────────── Running Tests ─────────────────────────────────
Spawning 1 processes for processing builders
───────────────────────────────── Iteration 1 ──────────────────────────────────
metric_file_regex/d4b90d87 does not have any dependencies adding test to queue
metric_regex_example/de7abe5f does not have any dependencies adding test to queue
Builders Eligible to Run
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Builder ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ metric_file_regex/d4b90d87 │
│ metric_regex_example/de7abe5f │
└───────────────────────────────┘
metric_file_regex/d4b90d87: Current Working Directory : /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_file_regex/d4b90d87/stage
metric_file_regex/d4b90d87: Running Test via command: bash metric_file_regex_build.sh
metric_file_regex/d4b90d87: Test completed in 0.008771 seconds with returncode: 0
metric_file_regex/d4b90d87: Writing output file - /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_file_regex/d4b90d87/metric_file_regex.out
metric_file_regex/d4b90d87: Writing error file - /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_file_regex/d4b90d87/metric_file_regex.err
metric_regex_example/de7abe5f: Current Working Directory : /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_regex_example/de7abe5f/stage
metric_regex_example/de7abe5f: Running Test via command: bash metric_regex_example_build.sh
metric_regex_example/de7abe5f: Test completed in 0.008798 seconds with returncode: 0
metric_regex_example/de7abe5f: Writing output file - /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_regex_example/de7abe5f/metric_regex_example.out
metric_regex_example/de7abe5f: Writing error file - /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_regex_example/de7abe5f/metric_regex_example.err
Test Summary
┏━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━┓
┃ builder ┃ executor ┃ status ┃ returncode ┃ runtime ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━┩
│ metric_regex_example/de │ generic.local.bash │ PASS │ 0 │ 0.009 │
│ 7abe5f │ │ │ │ │
├─────────────────────────┼────────────────────┼────────┼────────────┼─────────┤
│ metric_file_regex/d4b90 │ generic.local.bash │ PASS │ 0 │ 0.009 │
│ d87 │ │ │ │ │
└─────────────────────────┴────────────────────┴────────┴────────────┴─────────┘
Passed Tests: 2/2 Percentage: 100.000%
Failed Tests: 0/2 Percentage: 0.000%
Adding 2 test results to report file: /tmp/tmpr88132k2/var/report.json
Writing Logfile to /tmp/tmpr88132k2/var/logs/buildtest_92d4a4xs.log
The metrics are captured in the test report which can
be queried via buildtest report
or buildtest inspect query
. Metrics can be seen in the test metadata,
for instance you can run buildtest inspect query
and you will see metrics shown in table output.
buildtest inspect query metric_regex_example metric_file_regex
$ buildtest inspect query metric_regex_example metric_file_regex
──────────── metric_file_regex/d4b90d87-973d-4d4d-848d-cdeadf63b195 ────────────
Executor: generic.local.bash
Description: capture result metric from file path
State: PASS
Returncode: 0
Runtime: 0.008771 sec
Starttime: 2024/09/05 15:37:52
Endtime: 2024/09/05 15:37:52
Command: bash metric_file_regex_build.sh
Test Script: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_file_regex/d4b90d87/metric_file_regex.sh
Build Script: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_file_regex/d4b90d87/metric_file_regex_build.sh
Output File: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_file_regex/d4b90d87/metric_file_regex.out
Error File: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_file_regex/d4b90d87/metric_file_regex.err
Log File: /tmp/tmpr88132k2/var/logs/buildtest_92d4a4xs.log
Metrics
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Name ┃ Value ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ hpcg_rating_file │ 63.6515 │
│ hpcg_state_file │ VALID │
└──────────────────┴─────────┘
────────── metric_regex_example/de7abe5f-7a6a-4d6d-bd58-94f399d04b72 ───────────
Executor: generic.local.bash
Description: capture result metric from output
State: PASS
Returncode: 0
Runtime: 0.008798 sec
Starttime: 2024/09/05 15:37:52
Endtime: 2024/09/05 15:37:52
Command: bash metric_regex_example_build.sh
Test Script: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_regex_example/de7abe5f/metric_regex_example.sh
Build Script: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_regex_example/de7abe5f/metric_regex_example_build.sh
Output File: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_regex_example/de7abe5f/metric_regex_example.out
Error File: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex/metric_regex_example/de7abe5f/metric_regex_example.err
Log File: /tmp/tmpr88132k2/var/logs/buildtest_92d4a4xs.log
Metrics
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Name ┃ Value ┃
┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ hpcg_rating_stream │ 63.6515 │
│ hpcg_state_stream │ VALID │
└────────────────────┴─────────┘
We can query the metrics via buildtest report
which will display all metrics as a comma seperated
Key/Value pair. We can use buildtest report --format metrics
to extract all metrics for a test.
Internally, we store the metrics as a dictionary but when we print them out via buildtest report
we
join them together into a single string. Shown below is the metrics for the previous build.
buildtest report --filter buildspec=tutorials/metrics/metrics_regex.yml --format name,metrics
$ buildtest report --filter buildspec=tutorials/metrics/metrics_regex.yml --format name,metrics
Report File: /tmp/tmpr88132k2/var/report.json
┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ name ┃ metrics ┃
┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ metric_regex_example │ hpcg_rating_stream=63.6515,hpcg_state_stream=VALID │
│ metric_file_regex │ hpcg_rating_file=63.6515,hpcg_state_file=VALID │
└──────────────────────┴────────────────────────────────────────────────────┘
Metrics with Regex Type via ‘re’
Building on the previous example, we will use the re
property specify the regular expression type to use. By default, buildtest will
use re.search if re is not specified; however you can specify re to use re.match,
re.fullmatch, or re.search.
In this example, we will define 4 metrics hpcg_text, hpcg_result, hpcg_file_text, hpcg_file_result. The first two
metrics will capture from stdout using the regex
property while the last two will capture from a file using the file_regex
property.
The re.match
will be used to capture the text HPCG result is VALID and HPCG result is INVALID from stdout and file, whereas
the re.search
will be used to capture the test result 63.6515 and 28.1215 from stdout and file.
Finally, we will use the comparison operator assert_eq: Equal to compare the metrics with reference value.
buildspecs:
metric_regex_example_with_re:
executor: generic.local.bash
type: script
description: capture metric with different regex types
tags: tutorials
run: |
echo "HPCG result is VALID with a GFLOP/s rating of=63.6515"
echo "HPCG result is INVALID with a GFLOP/s rating of=28.1215" > hpcg.txt
metrics:
hpcg_result:
type: float
regex:
re: "re.search"
exp: '(\d+\.\d+)$'
stream: stdout
hpcg_text:
type: str
regex:
re: "re.match"
exp: '^HPCG result is VALID'
stream: stdout
hpcg_file_text:
type: str
file_regex:
re: "re.match"
exp: '^HPCG result is INVALID'
file: hpcg.txt
hpcg_file_result:
type: float
file_regex:
re: "re.search"
exp: '(\d+\.\d+)$'
file: hpcg.txt
status:
assert_eq:
comparisons:
- name: hpcg_text
ref: "HPCG result is VALID"
- name: hpcg_result
ref: 63.6515
- name: hpcg_file_text
ref: "HPCG result is INVALID"
- name: hpcg_file_result
ref: 28.1215
Let’s attempt to build this test
buildtest build -b tutorials/metrics/metrics_with_regex_type.yml
$ buildtest build -b tutorials/metrics/metrics_with_regex_type.yml
╭───────────────────────────── buildtest summary ──────────────────────────────╮
│ │
│ User: docs │
│ Hostname: build-25534835-project-280831-buildtest │
│ Platform: Linux │
│ Current Time: 2024/09/05 15:37:55 │
│ buildtest path: /home/docs/checkouts/readthedocs.org/user_builds/buildte │
│ buildtest version: 2.1 │
│ python path: /home/docs/checkouts/readthedocs.org/user_builds/buildte │
│ python version: 3.9.19 │
│ Configuration File: /tmp/tmpr88132k2/config.yml │
│ Test Directory: /tmp/tmpr88132k2/var/tests │
│ Report File: /tmp/tmpr88132k2/var/report.json │
│ Command: /home/docs/checkouts/readthedocs.org/user_builds/buildte │
│ │
╰──────────────────────────────────────────────────────────────────────────────╯
─────────────────────────── Discovering Buildspecs ────────────────────────────
Discovered buildspecs
╔══════════════════════════════════════════════════════════════════════════════╗
║ buildspec ║
╟──────────────────────────────────────────────────────────────────────────────╢
║ /home/docs/checkouts/readthedocs.org/user_builds/buildtest/checkouts/stable/ ║
║ tutorials/metrics/metrics_with_regex_type.yml ║
╟──────────────────────────────────────────────────────────────────────────────╢
║ Total: 1 ║
╚══════════════════════════════════════════════════════════════════════════════╝
Total Discovered Buildspecs: 1
Total Excluded Buildspecs: 0
Detected Buildspecs after exclusion: 1
────────────────────────────── Parsing Buildspecs ──────────────────────────────
Valid Buildspecs: 1
Invalid Buildspecs: 0
/home/docs/checkouts/readthedocs.org/user_builds/buildtest/checkouts/stable/tutorials/metrics/metrics_with_regex_type.yml: VALID
Total builder objects created: 1
Builders by type=script
┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┓
┃ ┃ ┃ ┃ ┃ ┃ ┃ descript ┃ buildsp ┃
┃ builder ┃ type ┃ executor ┃ compiler ┃ nodes ┃ procs ┃ ion ┃ ecs ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━┩
│ metric_r │ script │ generic. │ None │ None │ None │ capture │ /home/d │
│ egex_exa │ │ local.ba │ │ │ │ metric │ ocs/che │
│ mple_wit │ │ sh │ │ │ │ with │ ckouts/ │
│ h_re/e9f │ │ │ │ │ │ differen │ readthe │
│ 8d5f0 │ │ │ │ │ │ t regex │ docs.or │
│ │ │ │ │ │ │ types │ g/user_ │
│ │ │ │ │ │ │ │ builds/ │
│ │ │ │ │ │ │ │ buildte │
│ │ │ │ │ │ │ │ st/chec │
│ │ │ │ │ │ │ │ kouts/s │
│ │ │ │ │ │ │ │ table/t │
│ │ │ │ │ │ │ │ utorial │
│ │ │ │ │ │ │ │ s/metri │
│ │ │ │ │ │ │ │ cs/metr │
│ │ │ │ │ │ │ │ ics_wit │
│ │ │ │ │ │ │ │ h_regex │
│ │ │ │ │ │ │ │ _type.y │
│ │ │ │ │ │ │ │ ml │
└──────────┴────────┴──────────┴──────────┴───────┴───────┴──────────┴─────────┘
──────────────────────────────── Building Test ─────────────────────────────────
metric_regex_example_with_re/e9f8d5f0: Creating Test Directory: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_with_regex_type/metric_regex_example_with_re/e9f8d5f0
──────────────────────────────── Running Tests ─────────────────────────────────
Spawning 1 processes for processing builders
───────────────────────────────── Iteration 1 ──────────────────────────────────
metric_regex_example_with_re/e9f8d5f0 does not have any dependencies adding test to queue
Builders Eligible to Run
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Builder ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ metric_regex_example_with_re/e9f8d5f0 │
└───────────────────────────────────────┘
metric_regex_example_with_re/e9f8d5f0: Current Working Directory : /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_with_regex_type/metric_regex_example_with_re/e9f8d5f0/stage
metric_regex_example_with_re/e9f8d5f0: Running Test via command: bash metric_regex_example_with_re_build.sh
metric_regex_example_with_re/e9f8d5f0: Test completed in 0.008932 seconds with returncode: 0
metric_regex_example_with_re/e9f8d5f0: Writing output file - /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_with_regex_type/metric_regex_example_with_re/e9f8d5f0/metric_regex_example_with_re.out
metric_regex_example_with_re/e9f8d5f0: Writing error file - /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_with_regex_type/metric_regex_example_with_re/e9f8d5f0/metric_regex_example_with_re.err
metric_regex_example_with_re/e9f8d5f0: testing metric: hpcg_text if HPCG result is VALID == HPCG result is VALID - Check: True
metric_regex_example_with_re/e9f8d5f0: testing metric: hpcg_result if 63.6515 == 63.6515 - Check: True
metric_regex_example_with_re/e9f8d5f0: testing metric: hpcg_file_text if HPCG result is INVALID == HPCG result is INVALID - Check: True
metric_regex_example_with_re/e9f8d5f0: testing metric: hpcg_file_result if 28.1215 == 28.1215 - Check: True
metric_regex_example_with_re/e9f8d5f0: eq check: True
Test Summary
┏━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━┓
┃ builder ┃ executor ┃ status ┃ returncode ┃ runtime ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━┩
│ metric_regex_example_wi │ generic.local.bash │ PASS │ 0 │ 0.009 │
│ th_re/e9f8d5f0 │ │ │ │ │
└─────────────────────────┴────────────────────┴────────┴────────────┴─────────┘
Passed Tests: 1/1 Percentage: 100.000%
Failed Tests: 0/1 Percentage: 0.000%
Adding 1 test results to report file: /tmp/tmpr88132k2/var/report.json
Writing Logfile to /tmp/tmpr88132k2/var/logs/buildtest_mdffofnd.log
Upon completion, lets take a look at the metrics for this test, we can see this by running buildtest inspect query
which shows the name of captured metrics and its corresponding values.
buildtest inspect query metric_regex_example_with_re
$ buildtest inspect query metric_regex_example_with_re
────── metric_regex_example_with_re/e9f8d5f0-cce1-4bc8-b7d8-24ce016cea3b ───────
Executor: generic.local.bash
Description: capture metric with different regex types
State: PASS
Returncode: 0
Runtime: 0.008932 sec
Starttime: 2024/09/05 15:37:55
Endtime: 2024/09/05 15:37:55
Command: bash metric_regex_example_with_re_build.sh
Test Script: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_with_regex_type/metric_regex_example_with_re/e9f8d5f0/metric_regex_example_with_re.sh
Build Script: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_with_regex_type/metric_regex_example_with_re/e9f8d5f0/metric_regex_example_with_re_build.sh
Output File: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_with_regex_type/metric_regex_example_with_re/e9f8d5f0/metric_regex_example_with_re.out
Error File: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_with_regex_type/metric_regex_example_with_re/e9f8d5f0/metric_regex_example_with_re.err
Log File: /tmp/tmpr88132k2/var/logs/buildtest_mdffofnd.log
Metrics
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Name ┃ Value ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ hpcg_result │ 63.6515 │
│ hpcg_text │ HPCG result is VALID │
│ hpcg_file_text │ HPCG result is INVALID │
│ hpcg_file_result │ 28.1215 │
└──────────────────┴────────────────────────┘
Extract line numbers in Metrics
We can specify linenum
property in metrics to capture text from a specific line.
In the first example, we will define 2 metrics second_line and without_linenum using regex
The former metrics captures the text This is line: 2
, whereas the latter captures the text This is line: 1
.
buildspecs:
metric_regex_with_linenum_example:
executor: generic.local.bash
type: script
description: capture result metric from output
run: |
echo "This is line: 1"
echo "This is line: 2"
echo "This is line: 3"
echo "This is line: 4"
tags: tutorials
metrics:
second_line:
type: str
regex:
exp: 'This is line: \d'
stream: stdout
linenum: 1
without_linenum:
type: str
regex:
exp: 'This is line: \d'
stream: stdout
status:
assert_eq:
comparisons:
- name: second_line
ref: "This is line: 2"
- name: without_linenum
ref: "This is line: 1"
Let’s build the test and take a look at the metrics for this test.
buildtest build -b tutorials/metrics/metrics_regex_with_linenum.yml
$ buildtest build -b tutorials/metrics/metrics_regex_with_linenum.yml
╭───────────────────────────── buildtest summary ──────────────────────────────╮
│ │
│ User: docs │
│ Hostname: build-25534835-project-280831-buildtest │
│ Platform: Linux │
│ Current Time: 2024/09/05 15:37:57 │
│ buildtest path: /home/docs/checkouts/readthedocs.org/user_builds/buildte │
│ buildtest version: 2.1 │
│ python path: /home/docs/checkouts/readthedocs.org/user_builds/buildte │
│ python version: 3.9.19 │
│ Configuration File: /tmp/tmpr88132k2/config.yml │
│ Test Directory: /tmp/tmpr88132k2/var/tests │
│ Report File: /tmp/tmpr88132k2/var/report.json │
│ Command: /home/docs/checkouts/readthedocs.org/user_builds/buildte │
│ │
╰──────────────────────────────────────────────────────────────────────────────╯
─────────────────────────── Discovering Buildspecs ────────────────────────────
Discovered buildspecs
╔══════════════════════════════════════════════════════════════════════════════╗
║ buildspec ║
╟──────────────────────────────────────────────────────────────────────────────╢
║ /home/docs/checkouts/readthedocs.org/user_builds/buildtest/checkouts/stable/ ║
║ tutorials/metrics/metrics_regex_with_linenum.yml ║
╟──────────────────────────────────────────────────────────────────────────────╢
║ Total: 1 ║
╚══════════════════════════════════════════════════════════════════════════════╝
Total Discovered Buildspecs: 1
Total Excluded Buildspecs: 0
Detected Buildspecs after exclusion: 1
────────────────────────────── Parsing Buildspecs ──────────────────────────────
Valid Buildspecs: 1
Invalid Buildspecs: 0
/home/docs/checkouts/readthedocs.org/user_builds/buildtest/checkouts/stable/tutorials/metrics/metrics_regex_with_linenum.yml: VALID
Total builder objects created: 1
Builders by type=script
┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┓
┃ ┃ ┃ ┃ ┃ ┃ ┃ descript ┃ buildsp ┃
┃ builder ┃ type ┃ executor ┃ compiler ┃ nodes ┃ procs ┃ ion ┃ ecs ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━┩
│ metric_r │ script │ generic. │ None │ None │ None │ capture │ /home/d │
│ egex_wit │ │ local.ba │ │ │ │ result │ ocs/che │
│ h_linenu │ │ sh │ │ │ │ metric │ ckouts/ │
│ m_exampl │ │ │ │ │ │ from │ readthe │
│ e/963d8f │ │ │ │ │ │ output │ docs.or │
│ d5 │ │ │ │ │ │ │ g/user_ │
│ │ │ │ │ │ │ │ builds/ │
│ │ │ │ │ │ │ │ buildte │
│ │ │ │ │ │ │ │ st/chec │
│ │ │ │ │ │ │ │ kouts/s │
│ │ │ │ │ │ │ │ table/t │
│ │ │ │ │ │ │ │ utorial │
│ │ │ │ │ │ │ │ s/metri │
│ │ │ │ │ │ │ │ cs/metr │
│ │ │ │ │ │ │ │ ics_reg │
│ │ │ │ │ │ │ │ ex_with │
│ │ │ │ │ │ │ │ _linenu │
│ │ │ │ │ │ │ │ m.yml │
└──────────┴────────┴──────────┴──────────┴───────┴───────┴──────────┴─────────┘
──────────────────────────────── Building Test ─────────────────────────────────
metric_regex_with_linenum_example/963d8fd5: Creating Test Directory: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex_with_linenum/metric_regex_with_linenum_example/963d8fd5
──────────────────────────────── Running Tests ─────────────────────────────────
Spawning 1 processes for processing builders
───────────────────────────────── Iteration 1 ──────────────────────────────────
metric_regex_with_linenum_example/963d8fd5 does not have any dependencies adding test to queue
Builders Eligible to Run
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Builder ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ metric_regex_with_linenum_example/963d8fd5 │
└────────────────────────────────────────────┘
metric_regex_with_linenum_example/963d8fd5: Current Working Directory : /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex_with_linenum/metric_regex_with_linenum_example/963d8fd5/stage
metric_regex_with_linenum_example/963d8fd5: Running Test via command: bash metric_regex_with_linenum_example_build.sh
metric_regex_with_linenum_example/963d8fd5: Test completed in 0.009031 seconds with returncode: 0
metric_regex_with_linenum_example/963d8fd5: Writing output file - /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex_with_linenum/metric_regex_with_linenum_example/963d8fd5/metric_regex_with_linenum_example.out
metric_regex_with_linenum_example/963d8fd5: Writing error file - /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex_with_linenum/metric_regex_with_linenum_example/963d8fd5/metric_regex_with_linenum_example.err
metric_regex_with_linenum_example/963d8fd5: testing metric: second_line if This is line: 2 == This is line: 2 - Check: True
metric_regex_with_linenum_example/963d8fd5: testing metric: without_linenum if This is line: 1 == This is line: 1 - Check: True
metric_regex_with_linenum_example/963d8fd5: eq check: True
Test Summary
┏━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━┓
┃ builder ┃ executor ┃ status ┃ returncode ┃ runtime ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━┩
│ metric_regex_with_linen │ generic.local.bash │ PASS │ 0 │ 0.009 │
│ um_example/963d8fd5 │ │ │ │ │
└─────────────────────────┴────────────────────┴────────┴────────────┴─────────┘
Passed Tests: 1/1 Percentage: 100.000%
Failed Tests: 0/1 Percentage: 0.000%
Adding 1 test results to report file: /tmp/tmpr88132k2/var/report.json
Writing Logfile to /tmp/tmpr88132k2/var/logs/buildtest_tnzstshs.log
buildtest inspect query metric_regex_with_linenum_example
$ buildtest inspect query metric_regex_with_linenum_example
──── metric_regex_with_linenum_example/963d8fd5-3d6d-4b5a-a900-7235d40512db ────
Executor: generic.local.bash
Description: capture result metric from output
State: PASS
Returncode: 0
Runtime: 0.009031 sec
Starttime: 2024/09/05 15:37:57
Endtime: 2024/09/05 15:37:57
Command: bash metric_regex_with_linenum_example_build.sh
Test Script: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex_with_linenum/metric_regex_with_linenum_example/963d8fd5/metric_regex_with_linenum_example.sh
Build Script: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex_with_linenum/metric_regex_with_linenum_example/963d8fd5/metric_regex_with_linenum_example_build.sh
Output File: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex_with_linenum/metric_regex_with_linenum_example/963d8fd5/metric_regex_with_linenum_example.out
Error File: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_regex_with_linenum/metric_regex_with_linenum_example/963d8fd5/metric_regex_with_linenum_example.err
Log File: /tmp/tmpr88132k2/var/logs/buildtest_tnzstshs.log
Metrics
┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃ Name ┃ Value ┃
┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩
│ second_line │ This is line: 2 │
│ without_linenum │ This is line: 1 │
└─────────────────┴─────────────────┘
linenum
property can also be applied with file regular expression (file_regex
). In the example below,
we define 2 metrics with the same regular expression defined via exp. Its worth noting that the regular expression
will attempt to find the first match. When linenum is specified the content from file is extracted by line first
and regular expression is applied afterwards.
buildspecs:
metric_file_regex_with_linenum_example:
executor: generic.local.bash
type: script
description: capture result metric from file path
run: |
echo -e "HPCG result is INVALID with a GFLOP/s rating of=28.1215" > hpcg.txt
echo -e "HPCG result is VALID with a GFLOP/s rating of=68.9888" >> hpcg.txt
tags: tutorials
metrics:
last_line:
type: float
file_regex:
exp: '(\d+\.\d+)$'
linenum: -1
file: hpcg.txt
without_linenum:
type: float
file_regex:
exp: '(\d+\.\d+)$'
file: hpcg.txt
status:
assert_eq:
comparisons:
- name: last_line
ref: 68.9888
- name: without_linenum
ref: 28.1215
Let’s build the test and take a look at the captured metrics.
buildtest build -b tutorials/metrics/metrics_file_regex_with_linenum.yml
$ buildtest build -b tutorials/metrics/metrics_file_regex_with_linenum.yml
╭───────────────────────────── buildtest summary ──────────────────────────────╮
│ │
│ User: docs │
│ Hostname: build-25534835-project-280831-buildtest │
│ Platform: Linux │
│ Current Time: 2024/09/05 15:37:59 │
│ buildtest path: /home/docs/checkouts/readthedocs.org/user_builds/buildte │
│ buildtest version: 2.1 │
│ python path: /home/docs/checkouts/readthedocs.org/user_builds/buildte │
│ python version: 3.9.19 │
│ Configuration File: /tmp/tmpr88132k2/config.yml │
│ Test Directory: /tmp/tmpr88132k2/var/tests │
│ Report File: /tmp/tmpr88132k2/var/report.json │
│ Command: /home/docs/checkouts/readthedocs.org/user_builds/buildte │
│ │
╰──────────────────────────────────────────────────────────────────────────────╯
─────────────────────────── Discovering Buildspecs ────────────────────────────
Discovered buildspecs
╔══════════════════════════════════════════════════════════════════════════════╗
║ buildspec ║
╟──────────────────────────────────────────────────────────────────────────────╢
║ /home/docs/checkouts/readthedocs.org/user_builds/buildtest/checkouts/stable/ ║
║ tutorials/metrics/metrics_file_regex_with_linenum.yml ║
╟──────────────────────────────────────────────────────────────────────────────╢
║ Total: 1 ║
╚══════════════════════════════════════════════════════════════════════════════╝
Total Discovered Buildspecs: 1
Total Excluded Buildspecs: 0
Detected Buildspecs after exclusion: 1
────────────────────────────── Parsing Buildspecs ──────────────────────────────
Valid Buildspecs: 1
Invalid Buildspecs: 0
/home/docs/checkouts/readthedocs.org/user_builds/buildtest/checkouts/stable/tutorials/metrics/metrics_file_regex_with_linenum.yml: VALID
Total builder objects created: 1
Builders by type=script
┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┓
┃ ┃ ┃ ┃ ┃ ┃ ┃ descript ┃ buildsp ┃
┃ builder ┃ type ┃ executor ┃ compiler ┃ nodes ┃ procs ┃ ion ┃ ecs ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━┩
│ metric_f │ script │ generic. │ None │ None │ None │ capture │ /home/d │
│ ile_rege │ │ local.ba │ │ │ │ result │ ocs/che │
│ x_with_l │ │ sh │ │ │ │ metric │ ckouts/ │
│ inenum_e │ │ │ │ │ │ from │ readthe │
│ xample/2 │ │ │ │ │ │ file │ docs.or │
│ 352a61e │ │ │ │ │ │ path │ g/user_ │
│ │ │ │ │ │ │ │ builds/ │
│ │ │ │ │ │ │ │ buildte │
│ │ │ │ │ │ │ │ st/chec │
│ │ │ │ │ │ │ │ kouts/s │
│ │ │ │ │ │ │ │ table/t │
│ │ │ │ │ │ │ │ utorial │
│ │ │ │ │ │ │ │ s/metri │
│ │ │ │ │ │ │ │ cs/metr │
│ │ │ │ │ │ │ │ ics_fil │
│ │ │ │ │ │ │ │ e_regex │
│ │ │ │ │ │ │ │ _with_l │
│ │ │ │ │ │ │ │ inenum. │
│ │ │ │ │ │ │ │ yml │
└──────────┴────────┴──────────┴──────────┴───────┴───────┴──────────┴─────────┘
──────────────────────────────── Building Test ─────────────────────────────────
metric_file_regex_with_linenum_example/2352a61e: Creating Test Directory: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_file_regex_with_linenum/metric_file_regex_with_linenum_example/2352a61e
──────────────────────────────── Running Tests ─────────────────────────────────
Spawning 1 processes for processing builders
───────────────────────────────── Iteration 1 ──────────────────────────────────
metric_file_regex_with_linenum_example/2352a61e does not have any dependencies adding test to queue
Builders Eligible to Run
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Builder ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ metric_file_regex_with_linenum_example/2352a61e │
└─────────────────────────────────────────────────┘
metric_file_regex_with_linenum_example/2352a61e: Current Working Directory : /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_file_regex_with_linenum/metric_file_regex_with_linenum_example/2352a61e/stage
metric_file_regex_with_linenum_example/2352a61e: Running Test via command: bash metric_file_regex_with_linenum_example_build.sh
metric_file_regex_with_linenum_example/2352a61e: Test completed in 0.008989 seconds with returncode: 0
metric_file_regex_with_linenum_example/2352a61e: Writing output file - /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_file_regex_with_linenum/metric_file_regex_with_linenum_example/2352a61e/metric_file_regex_with_linenum_example.out
metric_file_regex_with_linenum_example/2352a61e: Writing error file - /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_file_regex_with_linenum/metric_file_regex_with_linenum_example/2352a61e/metric_file_regex_with_linenum_example.err
metric_file_regex_with_linenum_example/2352a61e: testing metric: last_line if 68.9888 == 68.9888 - Check: True
metric_file_regex_with_linenum_example/2352a61e: testing metric: without_linenum if 28.1215 == 28.1215 - Check: True
metric_file_regex_with_linenum_example/2352a61e: eq check: True
Test Summary
┏━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━┓
┃ builder ┃ executor ┃ status ┃ returncode ┃ runtime ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━┩
│ metric_file_regex_with_ │ generic.local.bash │ PASS │ 0 │ 0.009 │
│ linenum_example/2352a61 │ │ │ │ │
│ e │ │ │ │ │
└─────────────────────────┴────────────────────┴────────┴────────────┴─────────┘
Passed Tests: 1/1 Percentage: 100.000%
Failed Tests: 0/1 Percentage: 0.000%
Adding 1 test results to report file: /tmp/tmpr88132k2/var/report.json
Writing Logfile to /tmp/tmpr88132k2/var/logs/buildtest_ch4y7k13.log
buildtest inspect query metric_file_regex_with_linenum_example
$ buildtest inspect query metric_file_regex_with_linenum_example
─ metric_file_regex_with_linenum_example/2352a61e-6a03-4911-9d7e-d4d19ef148fc ──
Executor: generic.local.bash
Description: capture result metric from file path
State: PASS
Returncode: 0
Runtime: 0.008989 sec
Starttime: 2024/09/05 15:37:59
Endtime: 2024/09/05 15:37:59
Command: bash metric_file_regex_with_linenum_example_build.sh
Test Script: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_file_regex_with_linenum/metric_file_regex_with_linenum_example/2352a61e/metric_file_regex_with_linenum_example.sh
Build Script: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_file_regex_with_linenum/metric_file_regex_with_linenum_example/2352a61e/metric_file_regex_with_linenum_example_build.sh
Output File: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_file_regex_with_linenum/metric_file_regex_with_linenum_example/2352a61e/metric_file_regex_with_linenum_example.out
Error File: /tmp/tmpr88132k2/var/tests/generic.local.bash/metrics_file_regex_with_linenum/metric_file_regex_with_linenum_example/2352a61e/metric_file_regex_with_linenum_example.err
Log File: /tmp/tmpr88132k2/var/logs/buildtest_ch4y7k13.log
Metrics
┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Name ┃ Value ┃
┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ last_line │ 68.9888 │
│ without_linenum │ 28.1215 │
└─────────────────┴─────────┘
Invalid Metrics
We will discuss a few edge-cases when defining metrics that can lead to validation error. The file_regex and
regex property can’t be declared at the same time when defining a metric. In example below
we have defined a metric named hello
that uses both regex
and file_regex
.
buildspecs:
metrics_with_regex_and_file_regex_not_allowed:
type: script
executor: generic.local.bash
description: This is an invalid metric because 'file_regex' and 'regex' are both specified
run: echo "hello" > file.txt
metrics:
hello:
type: str
file_regex:
file: file.txt
exp: "BAR"
regex:
stream: stdout
exp: "BAR"
If we try to validate this buildspec, we will get an error message that regex
and file_regex
can’t be specified
at the same time.
buildtest buildspec validate -b tutorials/metrics/invalid_metrics.yml
$ buildtest buildspec validate -b tutorials/metrics/invalid_metrics.yml
─ /home/docs/checkouts/readthedocs.org/user_builds/buildtest/checkouts/stable… ─
{'type': 'str', 'file_regex': {'file': 'file.txt', 'exp': 'BAR'}, 'regex': {'stream': 'stdout', 'exp': 'BAR'}} is valid under each of {'required': ['file_regex']}, {'required': ['regex']}
Failed validating 'oneOf' in schema['properties']['metrics']['additionalProperties']:
{'type': 'object',
'additionalProperties': False,
'required': ['type'],
'properties': {'type': {'type': 'string',
'description': 'Specify python data-type '
'(str, int, float) to convert '
'metric. ',
'enum': ['str', 'int', 'float']},
'regex': {'$ref': '#/definitions/regex'},
'file_regex': {'$ref': '#/definitions/file_regex_in_metrics'}},
'oneOf': [{'required': ['regex']}, {'required': ['file_regex']}]}
On instance['metrics']['hello']:
{'type': 'str',
'file_regex': {'file': 'file.txt', 'exp': 'BAR'},
'regex': {'stream': 'stdout', 'exp': 'BAR'}}
1 buildspecs failed to validate
When defining a metrics, you must specify regex
or file_regex
property in order to capture metric. If its not
specified, you will run into validation error. In this example, we define a metrics named foo
, but we don’t
specify the regex
or file_regex
property therefore, this metric is invalid.
buildspecs:
required_property_in_metrics:
type: script
executor: generic.local.bash
description: metrics must have a file_regex or regex property to define how to capture metric
run: echo "hello"
metrics:
foo:
type: str
The metrics must follow a pattern, this is typically alphanumeric characters including dot (.
), hypen (-
)
and underscore (_
). In this example below, we have an invalid metric that doesn’t conform to pattern.
buildspecs:
invalid_metrics_name:
type: script
executor: generic.local.bash
description: "Metrics name does not follow pattern"
run: echo "hello" > file.txt
metrics:
(foo-bar:
type: str
regex:
stream: stdout
exp: "BAR"
Let’s try validating the buildspec to see the error message.
buildtest buildspec validate -b tutorials/metrics/invalid_metric_name.yml
$ buildtest buildspec validate -b tutorials/metrics/invalid_metric_name.yml
─ /home/docs/checkouts/readthedocs.org/user_builds/buildtest/checkouts/stable… ─
'(foo-bar' does not match '^[A-Za-z0-9_.-]+$'
Failed validating 'pattern' in schema['properties']['metrics']['propertyNames']:
{'pattern': '^[A-Za-z0-9_.-]+$'}
On instance['metrics']:
'(foo-bar'
1 buildspecs failed to validate