Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gtest_output support #81

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions gtest_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,57 @@ def add_stats(stats, task, idx):
def flush(self):
self.out.flush_transient_output()

def join_gtest_output_files(files, output_filename):
'''join given files into a single one'''
from xml.dom import minidom

files = [f for f in files if os.path.exists(f) and os.path.getsize(f) > 0]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you insert a TODO to revisit how empty files / crashes are handled and highlight that we skip that for now?

Also could we make sure to print a summary of how many tests failed to generate output? I think this may go through list of files before stripping out the !exists/empty ones. It would be OK to print every single failure here I think and not necessarily print x/y tests aborted. Can we get the test name corresponding to the failure as well?


base_file = files[0]
del files[0]
doc = minidom.parse(base_file)
testsuites_root = doc.getElementsByTagName("testsuites")[0]

def sum_tags(base, other):
for k in base.attributes.keys():
v = base.attributes[k]
if k in ["tests", "failures", "disabled", "errors"]:
base.attributes[k].value = str(int(v.value) + int(other.attributes[k].value))
elif k == "time":
base.attributes[k].value = str(round(float(v.value) + float(other.attributes[k].value), 3))

def add_testsuite(ts):
tag = "testsuite"
other = ts.getElementsByTagName(tag)[0]
for s in doc.getElementsByTagName(tag):
if s.attributes['name'].value == other.attributes['name'].value:
sum_tags(s, other)
for tc in other.getElementsByTagName("testcase"):
s.appendChild(tc)
break
else:
testsuites_root.appendChild(other)

for f in files:
tmp_doc = minidom.parse(f)
sum_tags(
doc.getElementsByTagName("testsuites")[0],
tmp_doc.getElementsByTagName("testsuites")[0]
)
add_testsuite(tmp_doc)

xmlstr = doc.toprettyxml(indent=" ")
# remove empty lines from pretty print
lines = []
for line in xmlstr.replace("\r", "").split("\n"):
l = line.rstrip()
if l:
lines.append(l)
xmlstr = "\n".join(lines)

with open(output_filename, 'w', encoding='utf8') as f:
f.write(xmlstr)


class CollectTestResults(object):
def __init__(self, json_dump_filepath):
Expand Down Expand Up @@ -797,6 +848,8 @@ def default_options_parser():
default=False,
help='Do not run tests from the same test '
'case in parallel.')
parser.add_option('--gtest_output', type='string', default=None,
help="Save the results to a file. Needs to start with 'xml:'")
return parser


Expand Down Expand Up @@ -868,6 +921,19 @@ def main():
options.retry_failed, options.repeat + 1)

tasks = find_tests(binaries, additional_args, options, times)
gtest_output_files = []
if options.gtest_output:
if options.repeat != 1:
parser.error("gtest_output only works with repeat times 1")
if not options.gtest_output.startswith("xml:"):
parser.error("only xml is supported as gtest_output format")
for task in tasks:
(gtest_output_handle, gtest_output_file) = tempfile.mkstemp(prefix='gtest_parallel_out_',
suffix=".xml")
os.close(gtest_output_handle)
gtest_output_files.append(gtest_output_file)
task.gtest_output = gtest_output_file
task.test_command += ["--gtest_output=xml:{}".format(task.gtest_output)]
logger.log_tasks(len(tasks))
execute_tasks(tasks, options.workers, task_manager, options.timeout,
options.serialize_test_cases)
Expand Down Expand Up @@ -895,6 +961,8 @@ def main():
times.write_to_file(save_file)
if test_results:
test_results.dump_to_file_and_close()
if options.gtest_output:
join_gtest_output_files(gtest_output_files, options.gtest_output[4:])

if sigint_handler.got_sigint():
return -signal.SIGINT
Expand Down