# HG changeset patch # User Matt Harbison # Date 2018-02-25 22:22:25 # Node ID 5c1cea8a3e60116d79a483f7c4e641e2715f87b4 # Parent 51a9f0246931bfd3f49fa88e81682701d47b8535 run-tests: cache hghave results Spawning a process on Windows is expensive. I've got a version of test-lfs-test-server.t locally which prints the http request/responses that totals 819 lines, with 149 conditional lines, 11 #if tests, and 2 test cases. It takes just under 1 minute with this change to run both cases, vs just over 2 minutes without this change. Worse, when I explored adding ui.debug to the test, it takes 13 minutes due to all of the mismatches and retests, vs less than 1 minute with this change. Overall, the difference when running all tests is negligible- 103 minutes with this change, vs 105 without when using -j9. It also looks like an exit value of 2 from `hghave` is treated specially, but there's nothing preventing 2 missing features from also using this value. diff --git a/tests/run-tests.py b/tests/run-tests.py --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -1236,6 +1236,7 @@ class TTest(Test): self.name = '%s (case %s)' % (self.name, _strpath(case)) self.errpath = b'%s.%s.err' % (self.errpath[:-4], case) self._tmpname += b'-%s' % case + self._have = {} @property def refpath(self): @@ -1275,11 +1276,15 @@ class TTest(Test): return self._processoutput(exitcode, output, salt, after, expected) def _hghave(self, reqs): + allreqs = b' '.join(reqs) + if allreqs in self._have: + return self._have.get(allreqs) + # TODO do something smarter when all other uses of hghave are gone. runtestdir = os.path.abspath(os.path.dirname(_bytespath(__file__))) tdir = runtestdir.replace(b'\\', b'/') proc = Popen4(b'%s -c "%s/hghave %s"' % - (self._shell, tdir, b' '.join(reqs)), + (self._shell, tdir, allreqs), self._testtmp, 0, self._getenv()) stdout, stderr = proc.communicate() ret = proc.wait() @@ -1290,10 +1295,13 @@ class TTest(Test): sys.exit(1) if ret != 0: + self._have[allreqs] = (False, stdout) return False, stdout if b'slow' in reqs: self._timeout = self._slowtimeout + + self._have[allreqs] = (True, None) return True, None def _iftest(self, args):