diff options
Diffstat (limited to 'tools/run_tests/jobset.py')
-rwxr-xr-x | tools/run_tests/jobset.py | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py index 058a30d1ce..8694b8f6bd 100755 --- a/tools/run_tests/jobset.py +++ b/tools/run_tests/jobset.py @@ -34,10 +34,12 @@ import multiprocessing import os import platform import signal +import string import subprocess import sys import tempfile import time +import xml.etree.cElementTree as ET _DEFAULT_MAX_JOBS = 16 * multiprocessing.cpu_count() @@ -159,7 +161,7 @@ class JobSpec(object): class Job(object): """Manages one job.""" - def __init__(self, spec, bin_hash, newline_on_success, travis): + def __init__(self, spec, bin_hash, newline_on_success, travis, xml_report): self._spec = spec self._bin_hash = bin_hash self._tempfile = tempfile.TemporaryFile() @@ -176,19 +178,27 @@ class Job(object): self._state = _RUNNING self._newline_on_success = newline_on_success self._travis = travis + self._xml_test = ET.SubElement(xml_report, 'testcase', + name=self._spec.shortname) if xml_report is not None else None message('START', spec.shortname, do_newline=self._travis) def state(self, update_cache): """Poll current state of the job. Prints messages at completion.""" if self._state == _RUNNING and self._process.poll() is not None: elapsed = time.time() - self._start + self._tempfile.seek(0) + stdout = self._tempfile.read() + filtered_stdout = filter(lambda x: x in string.printable, stdout.decode(errors='ignore')) + if self._xml_test is not None: + self._xml_test.set('time', str(elapsed)) + ET.SubElement(self._xml_test, 'system-out').text = filtered_stdout if self._process.returncode != 0: self._state = _FAILURE - self._tempfile.seek(0) - stdout = self._tempfile.read() message('FAILED', '%s [ret=%d, pid=%d]' % ( self._spec.shortname, self._process.returncode, self._process.pid), stdout, do_newline=True) + if self._xml_test is not None: + ET.SubElement(self._xml_test, 'failure', message='Failure').text else: self._state = _SUCCESS message('PASSED', '%s [time=%.1fsec]' % (self._spec.shortname, elapsed), @@ -200,6 +210,9 @@ class Job(object): stdout = self._tempfile.read() message('TIMEOUT', self._spec.shortname, stdout, do_newline=True) self.kill() + if self._xml_test is not None: + ET.SubElement(self._xml_test, 'system-out').text = stdout + ET.SubElement(self._xml_test, 'error', message='Timeout') return self._state def kill(self): @@ -212,7 +225,7 @@ class Jobset(object): """Manages one run of jobs.""" def __init__(self, check_cancelled, maxjobs, newline_on_success, travis, - stop_on_failure, cache): + stop_on_failure, cache, xml_report): self._running = set() self._check_cancelled = check_cancelled self._cancelled = False @@ -224,6 +237,7 @@ class Jobset(object): self._cache = cache self._stop_on_failure = stop_on_failure self._hashes = {} + self._xml_report = xml_report def start(self, spec): """Start a job. Return True on success, False on failure.""" @@ -250,7 +264,8 @@ class Jobset(object): self._running.add(Job(spec, bin_hash, self._newline_on_success, - self._travis)) + self._travis, + self._xml_report)) except: message('FAILED', spec.shortname) self._cancelled = True @@ -324,11 +339,13 @@ def run(cmdlines, travis=False, infinite_runs=False, stop_on_failure=False, - cache=None): + cache=None, + xml_report=None): js = Jobset(check_cancelled, maxjobs if maxjobs is not None else _DEFAULT_MAX_JOBS, newline_on_success, travis, stop_on_failure, - cache if cache is not None else NoCache()) + cache if cache is not None else NoCache(), + xml_report) for cmdline in cmdlines: if not js.start(cmdline): break |