blob: b1f2e2c0bb67fd9b39c4e993342bd07098bb52d7 [file] [log] [blame]
"""Gathers output from test runs and create an XML file in JUnit format.
The output files from the individual tests have been written in a directory
structure like:
$DIR/joblog (output from "parallel --joblog joblog")
This script bundles them into a single output XML file so Jenkins can show
detailed test results. It runs as the last step before the Jenkins build
import os;
import sys;
from yattag import Doc
from collections import defaultdict
def readtests(basedir):
tests = defaultdict(dict)
# Sample input (note: separators are tabs).
# Seq Host Starttime Runtime Send Receive Exitval Signal Command
# 1 : 1456263838.313 0.005 0 0 0 0 echo A
with open(basedir + "/joblog") as jobs:
firstline = next(jobs)
for line in jobs:
values = line.split("\t")
name = values[8].split()[-1]
test = tests[name]
test["name"] = name
test["time"] = values[3]
exitval = values[6]
if int(exitval):
# We don't have a more specific message. User should look at stderr.
test["failure"] = "TEST FAILURE"
test["failure"] = False
for testname in os.listdir(basedir + "/logs/1"):
test = tests[testname]
with open(basedir + "/logs/1/" + testname + "/stdout") as f:
test["stdout"] =
with open(basedir + "/logs/1/" + testname + "/stderr") as f:
test["stderr"] =
# The cpp test is special since it doesn't run under parallel so doesn't show
# up in the job log.
tests["cpp"]["name"] = "cpp"
with open(basedir + '/logs/1/cpp/build_time', 'r') as f:
tests["cpp"]["time"] =
tests["cpp"]["failure"] = False
ret = tests.values()
ret.sort(key=lambda x: x["name"])
return ret
def genxml(tests):
doc, tag, text = Doc().tagtext()
with tag("testsuites"):
with tag("testsuite", name="Protobuf Tests"):
for test in tests:
with tag("testcase", name=test["name"], classname=test["name"],
with tag("system-out"):
with tag("system-err"):
if test["failure"]:
with tag("failure"):
return doc.getvalue()
sys.stderr.write(" writing XML from directory: " +
sys.argv[1] + "\n");
print genxml(readtests(sys.argv[1]))