1ffe3c632Sopenharmony_ci"""Gathers output from test runs and create an XML file in JUnit format. 2ffe3c632Sopenharmony_ci 3ffe3c632Sopenharmony_ciThe output files from the individual tests have been written in a directory 4ffe3c632Sopenharmony_cistructure like: 5ffe3c632Sopenharmony_ci 6ffe3c632Sopenharmony_ci $DIR/joblog (output from "parallel --joblog joblog") 7ffe3c632Sopenharmony_ci $DIR/logs/1/cpp/stdout 8ffe3c632Sopenharmony_ci $DIR/logs/1/cpp/stderr 9ffe3c632Sopenharmony_ci $DIR/logs/1/csharp/stdout 10ffe3c632Sopenharmony_ci $DIR/logs/1/csharp/stderr 11ffe3c632Sopenharmony_ci $DIR/logs/1/java_jdk7/stdout 12ffe3c632Sopenharmony_ci $DIR/logs/1/java_jdk7/stderr 13ffe3c632Sopenharmony_ci etc. 14ffe3c632Sopenharmony_ci 15ffe3c632Sopenharmony_ciThis script bundles them into a single output XML file so Jenkins can show 16ffe3c632Sopenharmony_cidetailed test results. It runs as the last step before the Jenkins build 17ffe3c632Sopenharmony_cifinishes. 18ffe3c632Sopenharmony_ci""" 19ffe3c632Sopenharmony_ci 20ffe3c632Sopenharmony_ciimport os 21ffe3c632Sopenharmony_ciimport sys 22ffe3c632Sopenharmony_cifrom yattag import Doc 23ffe3c632Sopenharmony_cifrom collections import defaultdict 24ffe3c632Sopenharmony_ci 25ffe3c632Sopenharmony_ci 26ffe3c632Sopenharmony_cidef readtests(basedir): 27ffe3c632Sopenharmony_ci tests = defaultdict(dict) 28ffe3c632Sopenharmony_ci 29ffe3c632Sopenharmony_ci # Sample input (note: separators are tabs). 30ffe3c632Sopenharmony_ci # 31ffe3c632Sopenharmony_ci # Seq Host Starttime Runtime Send Receive Exitval Signal Command 32ffe3c632Sopenharmony_ci # 1 : 1456263838.313 0.005 0 0 0 0 echo A 33ffe3c632Sopenharmony_ci with open(basedir + "/joblog") as jobs: 34ffe3c632Sopenharmony_ci firstline = next(jobs) 35ffe3c632Sopenharmony_ci for line in jobs: 36ffe3c632Sopenharmony_ci values = line.split("\t") 37ffe3c632Sopenharmony_ci 38ffe3c632Sopenharmony_ci name = values[8].split()[-1] 39ffe3c632Sopenharmony_ci test = tests[name] 40ffe3c632Sopenharmony_ci test["name"] = name 41ffe3c632Sopenharmony_ci test["time"] = values[3] 42ffe3c632Sopenharmony_ci 43ffe3c632Sopenharmony_ci exitval = values[6] 44ffe3c632Sopenharmony_ci if int(exitval): 45ffe3c632Sopenharmony_ci # We don't have a more specific message. User should look at stderr. 46ffe3c632Sopenharmony_ci test["failure"] = "TEST FAILURE" 47ffe3c632Sopenharmony_ci else: 48ffe3c632Sopenharmony_ci test["failure"] = False 49ffe3c632Sopenharmony_ci 50ffe3c632Sopenharmony_ci for testname in os.listdir(basedir + "/logs/1"): 51ffe3c632Sopenharmony_ci test = tests[testname] 52ffe3c632Sopenharmony_ci 53ffe3c632Sopenharmony_ci with open(basedir + "/logs/1/" + testname + "/stdout") as f: 54ffe3c632Sopenharmony_ci test["stdout"] = f.read() 55ffe3c632Sopenharmony_ci 56ffe3c632Sopenharmony_ci with open(basedir + "/logs/1/" + testname + "/stderr") as f: 57ffe3c632Sopenharmony_ci test["stderr"] = f.read() 58ffe3c632Sopenharmony_ci 59ffe3c632Sopenharmony_ci # The cpp test is special since it doesn't run under parallel so doesn't show 60ffe3c632Sopenharmony_ci # up in the job log. 61ffe3c632Sopenharmony_ci tests["cpp"]["name"] = "cpp" 62ffe3c632Sopenharmony_ci 63ffe3c632Sopenharmony_ci with open(basedir + '/logs/1/cpp/build_time', 'r') as f: 64ffe3c632Sopenharmony_ci tests["cpp"]["time"] = f.read().strip() 65ffe3c632Sopenharmony_ci tests["cpp"]["failure"] = False 66ffe3c632Sopenharmony_ci 67ffe3c632Sopenharmony_ci ret = tests.values() 68ffe3c632Sopenharmony_ci ret.sort(key=lambda x: x["name"]) 69ffe3c632Sopenharmony_ci 70ffe3c632Sopenharmony_ci return ret 71ffe3c632Sopenharmony_ci 72ffe3c632Sopenharmony_ci 73ffe3c632Sopenharmony_cidef genxml(tests): 74ffe3c632Sopenharmony_ci doc, tag, text = Doc().tagtext() 75ffe3c632Sopenharmony_ci 76ffe3c632Sopenharmony_ci with tag("testsuites"): 77ffe3c632Sopenharmony_ci with tag("testsuite", name="Protobuf Tests"): 78ffe3c632Sopenharmony_ci for test in tests: 79ffe3c632Sopenharmony_ci with tag("testcase", name=test["name"], classname=test["name"], 80ffe3c632Sopenharmony_ci time=test["time"]): 81ffe3c632Sopenharmony_ci with tag("system-out"): 82ffe3c632Sopenharmony_ci text(test["stdout"]) 83ffe3c632Sopenharmony_ci with tag("system-err"): 84ffe3c632Sopenharmony_ci text(test["stderr"]) 85ffe3c632Sopenharmony_ci if test["failure"]: 86ffe3c632Sopenharmony_ci with tag("failure"): 87ffe3c632Sopenharmony_ci text(test["failure"]) 88ffe3c632Sopenharmony_ci 89ffe3c632Sopenharmony_ci return doc.getvalue() 90ffe3c632Sopenharmony_ci 91ffe3c632Sopenharmony_ci 92ffe3c632Sopenharmony_cisys.stderr.write("make_test_output.py: writing XML from directory: " + 93ffe3c632Sopenharmony_ci sys.argv[1] + "\n") 94ffe3c632Sopenharmony_ciprint(genxml(readtests(sys.argv[1]))) 95