summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorTill Schneidereit <till@tillschneidereit.net>2016-02-08 17:36:15 +0100
committerTill Schneidereit <till@tillschneidereit.net>2016-02-08 17:40:16 +0100
commit7ae29d49aedb82e9d13fca159057e4b37ce36f02 (patch)
treea521178b3c0aee8707107d2cd7d80e259501580a /tools
parent26aeed1428c9d4a1c860e7ac8b43e7e578863396 (diff)
downloadqtdeclarative-testsuites-7ae29d49aedb82e9d13fca159057e4b37ce36f02.tar.gz
Enable parallel test execution in console runner
Adds a `-j`/`--workers-count` parameter to `tools/packaging/test262.py`, defaulting to `[number of cores] - 1`. Speeds up running the test suite by about ~3x on my 4-core machine, with the SpiderMonkey shell. This could certainly be optimized more by just appending test results to per-thread lists and merging them at the end, but it's better than nothing.
Diffstat (limited to 'tools')
-rwxr-xr-xtools/packaging/test262.py84
1 files changed, 73 insertions, 11 deletions
diff --git a/tools/packaging/test262.py b/tools/packaging/test262.py
index 921360a05..1192005fc 100755
--- a/tools/packaging/test262.py
+++ b/tools/packaging/test262.py
@@ -18,6 +18,7 @@ import subprocess
import sys
import tempfile
import time
+import threading
import xml.dom.minidom
import datetime
import shutil
@@ -54,6 +55,8 @@ EXCLUDE_LIST = [x.getAttribute("id") for x in EXCLUDE_LIST]
def BuildOptions():
result = optparse.OptionParser()
result.add_option("--command", default=None, help="The command-line to run")
+ result.add_option("-j", "--workers-count", type=int, default=max(1, GetCPUCount() - 1),
+ help="Number of tests to run in parallel (default %default)")
result.add_option("--tests", default=path.abspath('.'),
help="Path to the tests")
result.add_option("--cat", default=False, action="store_true",
@@ -92,6 +95,35 @@ def IsWindows():
p = platform.system()
return (p == 'Windows') or (p == 'Microsoft')
+def GetCPUCount():
+ """
+ Guess at a reasonable parallelism count to set as the default for the
+ current machine and run.
+ """
+ # Python 2.6+
+ try:
+ import multiprocessing
+ return multiprocessing.cpu_count()
+ except (ImportError, NotImplementedError):
+ pass
+
+ # POSIX
+ try:
+ res = int(os.sysconf('SC_NPROCESSORS_ONLN'))
+ if res > 0:
+ return res
+ except (AttributeError, ValueError):
+ pass
+
+ # Windows
+ try:
+ res = int(os.environ['NUMBER_OF_PROCESSORS'])
+ if res > 0:
+ return res
+ except (KeyError, ValueError):
+ pass
+
+ return 1
class TempFile(object):
@@ -526,7 +558,7 @@ class TestSuite(object):
print
result.ReportOutcome(False)
- def Run(self, command_template, tests, print_summary, full_summary, logname, junitfile):
+ def Run(self, command_template, tests, print_summary, full_summary, logname, junitfile, workers_count):
if not "{{path}}" in command_template:
command_template += " {{path}}"
cases = self.EnumerateTests(tests)
@@ -551,16 +583,41 @@ class TestSuite(object):
SkipCaseElement.append(SkipElement)
TestSuiteElement.append(SkipCaseElement)
+ if workers_count > 1:
+ pool_sem = threading.Semaphore(workers_count)
+ log_lock = threading.Lock()
+ else:
+ log_lock = None
+
for case in cases:
- result = case.Run(command_template)
- if junitfile:
- TestCaseElement = result.XmlAssemble(result)
- TestSuiteElement.append(TestCaseElement)
- if case == cases[len(cases)-1]:
- xmlj.ElementTree(TestSuitesElement).write(junitfile, "UTF-8")
- if logname:
- self.WriteLog(result)
- progress.HasRun(result)
+ def exec_case():
+ result = case.Run(command_template)
+
+ try:
+ if workers_count > 1:
+ log_lock.acquire()
+
+ if junitfile:
+ TestCaseElement = result.XmlAssemble(result)
+ TestSuiteElement.append(TestCaseElement)
+ if case == cases[len(cases)-1]:
+ xmlj.ElementTree(TestSuitesElement).write(junitfile, "UTF-8")
+ if logname:
+ self.WriteLog(result)
+ finally:
+ if workers_count > 1:
+ log_lock.release()
+
+ progress.HasRun(result)
+ if workers_count == 1:
+ exec_case()
+ else:
+ pool_sem.acquire()
+ threading.Thread(target=exec_case).start()
+ pool_sem.release()
+
+ if workers_count > 1:
+ log_lock.acquire()
if print_summary:
self.PrintSummary(progress, logname)
@@ -570,6 +627,10 @@ class TestSuite(object):
print
print "Use --full-summary to see output from failed tests"
print
+
+ if workers_count > 1:
+ log_lock.release()
+
return progress.failed
def WriteLog(self, result):
@@ -634,7 +695,8 @@ def Main():
options.summary or options.full_summary,
options.full_summary,
options.logname,
- options.junitname)
+ options.junitname,
+ options.workers_count)
return code
if __name__ == '__main__':