Mercurial > hg
changeset 22104:70bdf59d27b6
run-tests: attempt to fix iolock handling
Ideally, when using -j and -i together, when a prompt comes up, we'd
like all other output to wait (but testing to continue!). This gets
other output to wait by adding back a bunch of the locking that
formerly existed. We switch to a recursive lock to deal with the
restructuring due to unittest compatibility.
Running tests continue to run, but now the scheduler doesn't schedule
any new tasks while waiting at a prompt because no task slots become
available due to result output happening in the thread and
blocking on the iolock.
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Mon, 11 Aug 2014 17:45:50 -0500 |
parents | fff8e1cec90f |
children | 3b5cf39ffcc4 |
files | tests/run-tests.py |
diffstat | 1 files changed, 15 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/tests/run-tests.py Mon Aug 11 11:24:05 2014 -0500 +++ b/tests/run-tests.py Mon Aug 11 17:45:50 2014 -0500 @@ -1073,7 +1073,7 @@ output = re.sub(s, r, output) return ret, output.splitlines(True) -iolock = threading.Lock() +iolock = threading.RLock() class SkipTest(Exception): """Raised to indicate that a test is to be skipped.""" @@ -1128,7 +1128,9 @@ iolock.release() def addSuccess(self, test): + iolock.acquire() super(TestResult, self).addSuccess(test) + iolock.release() self.successes.append(test) def addError(self, test, err): @@ -1139,14 +1141,17 @@ # Polyfill. def addSkip(self, test, reason): self.skipped.append((test, reason)) + iolock.acquire() if self.showAll: self.stream.writeln('skipped %s' % reason) else: self.stream.write('s') self.stream.flush() + iolock.release() def addIgnore(self, test, reason): self.ignored.append((test, reason)) + iolock.acquire() if self.showAll: self.stream.writeln('ignored %s' % reason) else: @@ -1155,6 +1160,7 @@ else: self.testsRun += 1 self.stream.flush() + iolock.release() def addWarn(self, test, reason): self.warned.append((test, reason)) @@ -1162,11 +1168,13 @@ if self._options.first: self.stop() + iolock.acquire() if self.showAll: self.stream.writeln('warned %s' % reason) else: self.stream.write('~') self.stream.flush() + iolock.release() def addOutputMismatch(self, test, ret, got, expected): """Record a mismatch in test output for a particular test.""" @@ -1231,8 +1239,10 @@ del self._stopped[test.name] if interrupted: + iolock.acquire() self.stream.writeln('INTERRUPTED: %s (after %d seconds)' % ( test.name, self.times[-1][3])) + iolock.release() class TestSuite(unittest.TestSuite): """Custom unitest TestSuite that knows how to execute Mercurial tests.""" @@ -1366,6 +1376,7 @@ skipped = len(result.skipped) ignored = len(result.ignored) + iolock.acquire() self.stream.writeln('') if not self._runner.options.noskips: @@ -1418,9 +1429,12 @@ if self._runner.options.time: self.printtimes(result.times) + iolock.release() + return result def printtimes(self, times): + # iolock held by run self.stream.writeln('# Producing time report') times.sort(key=lambda t: (t[3])) cols = '%7.3f %7.3f %7.3f %s'