| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 | """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 directorystructure like:  $DIR/joblog  (output from "parallel --joblog joblog")  $DIR/logs/1/cpp/stdout  $DIR/logs/1/cpp/stderr  $DIR/logs/1/csharp/stdout  $DIR/logs/1/csharp/stderr  $DIR/logs/1/java_jdk7/stdout  $DIR/logs/1/java_jdk7/stderr  etc.This script bundles them into a single output XML file so Jenkins can showdetailed test results.  It runs as the last step before the Jenkins buildfinishes."""import os;import sys;from yattag import Docfrom collections import defaultdictdef 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"      else:        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"] = f.read()    with open(basedir + "/logs/1/" + testname + "/stderr") as f:      test["stderr"] = f.read()  # 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"] = f.read().strip()  tests["cpp"]["failure"] = False  ret = tests.values()  ret.sort(key=lambda x: x["name"])  return retdef 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"],                             time=test["time"]):          with tag("system-out"):            text(test["stdout"])          with tag("system-err"):            text(test["stderr"])          if test["failure"]:            with tag("failure"):              text(test["failure"])  return doc.getvalue()sys.stderr.write("make_test_output.py: writing XML from directory: " +                 sys.argv[1] + "\n");print genxml(readtests(sys.argv[1]))
 |