The Gaudi Framework
master (5c735ca6)
Toggle main menu visibility
Loading...
Searching...
No Matches
ctest_measurements_reporter.py
Go to the documentation of this file.
1
11
import
os
12
import
re
13
import
xml.sax.saxutils
as
XSS
14
from
collections
import
defaultdict
15
16
# This plugin integrates with pytest to capture and report test results
17
# in a format compatible with CTest using DartMeasurement tags
18
# Key functions and hooks include:
19
# - sanitize_for_xml: Sanitize a string by escaping non-XML characters.
20
# - pytest_report_header: Add strings to the pytest header.
21
# - pytest_runtest_logreport: Collect test results and durations.
22
# - pytest_sessionfinish: Output the collected test information in a format
23
# suitable for CTest.
24
25
results = {}
26
27
28
def
sanitize_for_xml
(data):
29
bad_chars = re.compile(
"[\x00-\x08\x0b\x0c\x0e-\x1f\ud800-\udfff\ufffe\uffff]"
)
30
31
def
quote(match):
32
"helper function"
33
return
""
.join(
"[NON-XML-CHAR-0x%2X]"
% ord(c)
for
c
in
match.group())
34
35
return
bad_chars.sub(quote, data)
36
37
38
def
pytest_report_header
(config, start_path):
39
# make sure CTest does not drop output lines on successful tests
40
return
"CTEST_FULL_OUTPUT"
41
42
43
def
pytest_runtest_logreport
(report):
44
# collect user properties
45
head_line = report.head_line
46
results.update(
47
{
48
f
"{head_line}.{k}"
: v
49
for
k, v
in
report.user_properties
50
if
f
"{head_line}.{k}"
not
in
results
51
}
52
)
53
54
# collect test outcome
55
if
not
report.passed:
56
results[f
"{report.head_line}.outcome"
] = report.outcome
57
else
:
58
results.setdefault(f
"{report.head_line}.outcome"
,
"passed"
)
59
60
# collect test duration
61
if
report.when ==
"call"
:
62
results[f
"{report.head_line}.duration"
] = round(report.duration, 2)
63
64
65
def
pytest_sessionfinish
(session, exitstatus):
66
if
not
hasattr(session,
"items"
):
67
# no test run, nothing to report
68
return
69
if
os.environ.get(
"DISABLE_CTEST_MEASUREMENTS"
) ==
"1"
:
70
# user requested to disable CTest measurements printouts
71
return
72
73
outcomes = defaultdict(list)
74
for
key
in
results:
75
if
key.endswith(
".outcome"
):
76
outcomes[results[key]].append(key[:-8])
77
results.update(
78
(f
"outcome.{outcome}"
, sorted(tests))
for
outcome, tests
in
outcomes.items()
79
)
80
81
ignore_keys = {
"test_fixture_setup.completed_process"
}
82
template = (
83
'<DartMeasurement type="text/string" name="{name}">{value}</DartMeasurement>'
84
)
85
86
to_print = [
87
(key, value)
88
for
key, value
in
results.items()
89
if
not
any(key.endswith(ignore_key)
for
ignore_key
in
ignore_keys)
and
value
90
]
91
to_print.sort()
92
for
key, value
in
to_print:
93
sanitized_value = XSS.escape(
sanitize_for_xml
(str(value)))
94
# workaround for a limitation of CTestXML2HTML
95
key = key.replace(
"/"
,
"_"
)
96
print(template.format(name=key, value=sanitized_value), end=
""
)
ctest_measurements_reporter.pytest_report_header
pytest_report_header(config, start_path)
Definition
ctest_measurements_reporter.py:38
ctest_measurements_reporter.sanitize_for_xml
sanitize_for_xml(data)
Definition
ctest_measurements_reporter.py:28
ctest_measurements_reporter.pytest_sessionfinish
pytest_sessionfinish(session, exitstatus)
Definition
ctest_measurements_reporter.py:65
ctest_measurements_reporter.pytest_runtest_logreport
pytest_runtest_logreport(report)
Definition
ctest_measurements_reporter.py:43
GaudiPolicy
python
GaudiTesting
pytest
ctest_measurements_reporter.py
Generated on
for The Gaudi Framework by
1.17.0