-
Notifications
You must be signed in to change notification settings - Fork 5.6k
/
Copy pathcreate_bazel_test_report.py
77 lines (59 loc) · 2.13 KB
/
create_bazel_test_report.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import json
import time
import xml.etree.ElementTree as ET
from glob import glob
from typing import List
import typer
from typing_extensions import TypedDict
from util.expansions import get_expansion
class Result(TypedDict):
"""A single test result"""
status: str
test_file: str
log_raw: str
start: float
end: float
class Report(TypedDict):
"""Test report for Evergreen"""
results: List[Result]
def main(testlog_dir: str, silent_fail: bool = False):
"""Create an report.json for Evergreen from bazel test logs."""
if not get_expansion("create_bazel_test_report"):
print(
"Expansion create_bazel_test_report is not set, skipping creating a report from Bazel test logs."
)
return
report = Report({"results": []})
for test_xml in glob(f"{testlog_dir}/**/test.xml", recursive=True):
testsuite = ET.parse(test_xml).getroot().find("testsuite")
testcase = testsuite.find("testcase")
test_file = testcase.attrib["name"]
if testcase.find("error") is not None:
status = "silentfail" if silent_fail else "fail"
else:
status = "pass"
log_raw = testsuite.find("system-out").text
# Bazel gives just a duration, while Evergreen expects a start and end
# time to calculate the duration. Evergreen itself does something similar
# for when only a duration is known.
duration = testcase.attrib["time"]
start = time.time()
end = start + int(duration)
report["results"].append(
Result(
{
"test_file": test_file,
"status": status,
"start": start,
"end": end,
"log_raw": log_raw,
}
)
)
if report["results"]:
with open("report.json", "wt") as fh:
json.dump(report, fh)
else:
print(f"No test.xml found within {testlog_dir}. Not creating a report.")
if __name__ == "__main__":
typer.run(main)