Skip to content

Commit a92b243

Browse files
authored
Merge pull request #1162 from cloudbees-oss/AIENG-255
[AIENG-255] capture output from bazel test runs
2 parents a738e1e + 8c408f1 commit a92b243

File tree

6 files changed

+49
-15
lines changed

6 files changed

+49
-15
lines changed

launchable/test_runners/bazel.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
2-
import os
32
import sys
3+
import xml.etree.ElementTree as ET
4+
from os import path
45
from pathlib import Path
56
from typing import Generator, List
67

@@ -61,15 +62,45 @@ def f(case: TestCase, suite: TestSuite, report_file: str) -> TestPath:
6162

6263
# last path component is the target, the rest is package
6364
# TODO: does this work correctly when on Windows?
64-
path = make_test_path(os.path.dirname(pkgNtarget), os.path.basename(pkgNtarget))
65+
tp = make_test_path(path.dirname(pkgNtarget), path.basename(pkgNtarget))
6566

6667
# let the normal path building kicks in
67-
path.extend(default_path_builder(case, suite, report_file))
68-
return path
68+
tp.extend(default_path_builder(case, suite, report_file))
69+
return tp
6970

7071
client.path_builder = f
7172
client.check_timestamp = False
7273

74+
def parse_func(report: str) -> ET.ElementTree:
75+
"""
76+
test result XML generated by Bazel's java_test rule (and possibly others) do not capture system-out/system-err.
77+
The whole thing gets captured separately as test.log file in the same directory as test.xml.
78+
This limits our ability to do useful things with data, so we go out of our way to capture it.
79+
Ideally Bazel should do this. test.log captures the entire output from the whole session, and therefore
80+
it is incapable of splitting log between different test classes.
81+
"""
82+
tree = ET.parse(report)
83+
root = tree.getroot()
84+
for ts in root.findall('testsuite'):
85+
# be defensive -- future/non-Java test rules might capture those
86+
if ts.findtext('system-out', '') == "" and ts.findtext('system-err', '') == "":
87+
logfile = path.join(path.dirname(report), 'test.log')
88+
if path.exists(logfile):
89+
print("Found {}".format(logfile))
90+
for x in ts.findall('system-out'):
91+
ts.remove(x)
92+
with open(logfile, 'r', encoding='utf-8', errors='replace') as log_file:
93+
log = log_file.read()
94+
95+
for c in ts.findall('testcase'):
96+
if c.findtext('system-out', '') == "" and c.findtext('system-err', '') == "":
97+
system_out = ET.SubElement(c, 'system-out')
98+
system_out.text = log
99+
100+
return tree
101+
102+
client.junitxml_parse_func = parse_func
103+
73104
if build_event_json_files:
74105
for l in parse_build_event_json(build_event_json_files):
75106
if l is None:
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Dummy standard output
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
<?xml version='1.0' encoding='UTF-8'?>
22
<testsuites>
3-
<testsuite name='com.ninjinkun.MyLibTest1' timestamp='2020-12-16T03:11:43.526Z' hostname='localhost' tests='1' failures='0' errors='0' time='2.02' package='' id='0'>
3+
<testsuite name='com.ninjinkun.MyLibTest1' timestamp='2020-12-16T03:11:43.526Z' hostname='localhost' tests='1' failures='1' errors='0' time='2.02' package='' id='0'>
44
<properties />
5-
<testcase name='testFibonacci' classname='com.ninjinkun.MyLibTest1' time='2.02' />
5+
<testcase name='testFibonacci' classname='com.ninjinkun.MyLibTest1' time='2.02'>
6+
<failure message='Yo!' type='java.lang.Exception'>java.lang.Exception: Yo!
7+
at somewhere(Somewhere.java:33)</failure></testcase>
68
<system-out />
79
<system-err /></testsuite></testsuites>

tests/data/bazel/record_test_result.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
{ "type": "testcase", "name": "testFibonacci" }
2424
],
2525
"duration": 2.02,
26-
"status": 1,
27-
"stdout": "",
28-
"stderr": "",
26+
"status": 0,
27+
"stdout": "Dummy standard output\n",
28+
"stderr": "java.lang.Exception: Yo!\n at somewhere(Somewhere.java:33)",
2929
"data": null
3030
},
3131
{

tests/data/bazel/record_test_with_build_event_json_result.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
{ "type": "testcase", "name": "testFibonacci" }
1010
],
1111
"duration": 2.02,
12-
"status": 1,
13-
"stdout": "",
14-
"stderr": "",
12+
"status": 0,
13+
"stdout": "Dummy standard output\n",
14+
"stderr": "java.lang.Exception: Yo!\n at somewhere(Somewhere.java:33)",
1515
"data": null
1616
},
1717
{

tests/data/bazel/record_test_with_multiple_build_event_json_result.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
{ "type": "testcase", "name": "testFibonacci" }
1010
],
1111
"duration": 2.02,
12-
"status": 1,
13-
"stdout": "",
14-
"stderr": "",
12+
"status": 0,
13+
"stdout": "Dummy standard output\n",
14+
"stderr": "java.lang.Exception: Yo!\n at somewhere(Somewhere.java:33)",
1515
"data": null
1616
},
1717
{

0 commit comments

Comments
 (0)