From 2d8b44932779f887ce47c43e25dbda72b817e45d Mon Sep 17 00:00:00 2001 From: Benoit Foucher Date: Tue, 11 Jul 2017 10:21:45 +0200 Subject: Added JUnit XML reports to allTests.py --- scripts/Util.py | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 4 deletions(-) (limited to 'scripts/Util.py') diff --git a/scripts/Util.py b/scripts/Util.py index 7d83362842d..c792a187257 100644 --- a/scripts/Util.py +++ b/scripts/Util.py @@ -9,6 +9,8 @@ import os, sys, runpy, getopt, traceback, types, threading, time, datetime, re, itertools, random, subprocess, shutil, copy, inspect +import xml.sax.saxutils + isPython2 = sys.version_info[0] == 2 if isPython2: import Queue as queue @@ -48,6 +50,13 @@ def val(v, escapeQuotes=False, quoteValue=True): else: return str(v) +def escape(s): + # Remove backspace characters from the output (they aren't accepted by Jenkins XML parser) + if isPython2: + return xml.sax.saxutils.escape("".join(ch for ch in unicode(s) if ch != u"\u0008").encode("utf-8")) + else: + return xml.sax.saxutils.escape("".join(ch for ch in s if ch != u"\u0008")) + def getIceSoVersion(): config = open(os.path.join(toplevel, "cpp", "include", "IceUtil", "Config.h"), "r") intVersion = int(re.search("ICE_INT_VERSION ([0-9]*)", config.read()).group(1)) @@ -1547,13 +1556,14 @@ class Result: def __init__(self, testsuite, writeToStdout): self.testsuite = testsuite - self._skipped = [] self._failed = {} self._succeeded = [] + self._skipped = [] self._stdout = StringIO() self._writeToStdout = writeToStdout self._testcases = {} self._duration = 0 + self._testCaseDuration = 0; def start(self): self._duration = time.time() @@ -1562,11 +1572,13 @@ class Result: self._duration = time.time() - self._duration def started(self, testcase): + self._testCaseDuration = time.time(); self._start = self._stdout.tell() def failed(self, testcase, exception): + self._testCaseDuration = time.time() - self._testCaseDuration; self.writeln("\ntest in {0} failed:\n{1}".format(self.testsuite, exception)) - self._testcases[testcase] = (self._start, self._stdout.tell()) + self._testcases[testcase] = (self._start, self._stdout.tell(), self._testCaseDuration) self._failed[testcase] = exception output = self.getOutput(testcase) for s in ["EADDRINUSE", "Address already in use"]: @@ -1578,9 +1590,16 @@ class Result: self.writeln(run("lsof -n -P -i; ps ax")) def succeeded(self, testcase): - self._testcases[testcase] = (self._start, self._stdout.tell()) + self._testCaseDuration = time.time() - self._testCaseDuration; + self._testcases[testcase] = (self._start, self._stdout.tell(), self._testCaseDuration) self._succeeded.append(testcase) + def skipped(self, testcase, reason): + self._start = self._stdout.tell() + self.writeln("skipped, " + reason) + self._testcases[testcase] = (self._start, self._stdout.tell(), 0) + self._skipped[testcase] = reason + def isSuccess(self): return len(self._failed) == 0 @@ -1593,7 +1612,7 @@ class Result: def getOutput(self, testcase=None): if testcase: if testcase in self._testcases: - (start, end) = self._testcases[testcase] + (start, end, duration) = self._testcases[testcase] self._stdout.seek(start) try: return self._stdout.read(end - start) @@ -1632,6 +1651,40 @@ class Result: self._stdout.write(msg) self._stdout.write("\n") + def writeAsXml(self, out, hostname=""): + out.write(' \n' + .format(len(self._testcases) - 2, + len(self._failed), + len(self._skipped), + self._duration, + self.testsuite)) + + for (tc, v) in self._testcases.items(): + if isinstance(tc, TestCase): + (s, e, d) = v + out.write(' \n' + .format(tc, + d, + self.testsuite.getMapping(), + self.testsuite.getId().replace("/", "."))) + if tc in self._failed: + last = self._failed[tc].strip().split('\n') + if len(last) > 0: + last = last[len(last) - 1] + if hostname: + last = "Failed on {0}\n{1}".format(hostname, last) + out.write(' {0}\n'.format(escape(self._failed[tc]), last)) + elif tc in self._skipped: + out.write(' \n'.format(escape(self._skipped[tc]))) + out.write(' \n') + if hostname: + out.write('Running on {0}\n'.format(hostname)) + out.write(escape(self.getOutput(tc))) + out.write(' \n') + out.write(' \n') + + out.write( '\n') + class TestSuite: def __init__(self, path, testcases=None, options=None, libDirs=None, runOnMainThread=False, chdir=False, -- cgit v1.2.3