Skip to content

Commit 0269ce3

Browse files
committed
[GR-12578] add timeout to unittests runner
PullRequest: graalpython/280
2 parents 2b2e93b + a102130 commit 0269ce3

File tree

5 files changed

+42
-6
lines changed

5 files changed

+42
-6
lines changed

graalpython/com.oracle.graal.python.test/src/python_unittests.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
import subprocess
4545
from collections import defaultdict
4646
from json import dumps
47-
from multiprocessing import Pool
47+
from multiprocessing import Pool, TimeoutError
4848
from pprint import pformat
4949

5050
import argparse
@@ -136,19 +136,41 @@ def _run_unittest(test_path):
136136
return success, output
137137

138138

139-
def run_unittests(unittests):
139+
TIMEOUT = 60 * 20 # 20 mins per unittest wait time max ...
140+
141+
142+
def run_unittests(unittests, timeout):
140143
assert isinstance(unittests, (list, tuple))
141144
num_unittests = len(unittests)
142145
log("[EXEC] running {} unittests ... ", num_unittests)
146+
log("[EXEC] timeout per unittest: {} seconds", timeout)
143147
results = []
144148

145149
pool = Pool()
146150
for ut in unittests:
147151
results.append(pool.apply_async(_run_unittest, args=(ut, )))
148152
pool.close()
149-
pool.join()
150153

151-
return [res.get()[1] for res in results]
154+
log("[INFO] collect results ... ")
155+
out = []
156+
timed_out = []
157+
for i, res in enumerate(results):
158+
try:
159+
_, output = res.get(timeout)
160+
out.append(output)
161+
except TimeoutError:
162+
log("[ERR] timeout while getting results for {}, skipping!", unittests[i])
163+
timed_out.append(unittests[i])
164+
log("[PROGRESS] {} / {}: \t {}%", i+1, num_unittests, int(((i+1) * 100.0) / num_unittests))
165+
166+
log("".join(['-' for i in range(120)]))
167+
for t in timed_out:
168+
log("[TIMEOUT] skipped: {}", t)
169+
log("".join(['-' for i in range(120)]))
170+
log("[STATS] processed {} out of {} unitttests", num_unittests - len(timed_out), num_unittests)
171+
pool.terminate()
172+
pool.join()
173+
return out
152174

153175

154176
def get_unittests(base_tests_path, limit=None, sort=True, skip_tests=None):
@@ -628,6 +650,7 @@ def main(prog, args):
628650
parser.add_argument("-v", "--verbose", help="Verbose output.", action="store_true")
629651
parser.add_argument("-l", "--limit", help="Limit the number of unittests to run.", default=None, type=int)
630652
parser.add_argument("-t", "--tests_path", help="Unittests path.", default=PATH_UNITTESTS)
653+
parser.add_argument("-T", "--timeout", help="Timeout per unittest run.", default=TIMEOUT, type=int)
631654
parser.add_argument("-o", "--only_tests", help="Run only these unittests (comma sep values).", default=None)
632655
parser.add_argument("-s", "--skip_tests", help="Run all unittests except (comma sep values)."
633656
"the only_tets option takes precedence", default=None)
@@ -656,7 +679,7 @@ def _fmt(t):
656679
skip_tests = set([_fmt(test) for test in flags.skip_tests.split(",")]) if flags.skip_tests else None
657680
unittests = get_unittests(flags.tests_path, limit=flags.limit, skip_tests=skip_tests)
658681

659-
results = run_unittests(unittests)
682+
results = run_unittests(unittests, flags.timeout)
660683
txt_report_path = file_name(TXT_RESULTS_NAME, current_date)
661684
output = save_as_txt(txt_report_path, results)
662685

graalpython/lib-python/3/test/test_list.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ def test_basic(self):
3232
# thread for the details:
3333

3434
# http://sources.redhat.com/ml/newlib/2002/msg00369.html
35-
self.assertRaises(MemoryError, list, range(sys.maxsize // 2))
35+
# TODO: truffle GR-12581
36+
# self.assertRaises(MemoryError, list, range(sys.maxsize // 2))
37+
pass
3638

3739
# This code used to segfault in Py2.4a3
3840
x = []

graalpython/lib-python/3/test/test_queue.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ def test_queue_task_done(self):
184184
else:
185185
self.fail("Did not detect task count going negative")
186186

187+
@unittest.skipIfGraalPythonWitoutThreads
187188
def test_queue_join(self):
188189
# Test that a queue join()s successfully, and before anything else
189190
# (done twice for insurance).

graalpython/lib-python/3/test/test_sched.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def test_enterabs(self):
5858
scheduler.run()
5959
self.assertEqual(l, [0.01, 0.02, 0.03, 0.04, 0.05])
6060

61+
@unittest.skipIfGraalPythonWitoutThreads
6162
@unittest.skipUnless(threading, 'Threading required for this test.')
6263
def test_enter_concurrent(self):
6364
q = queue.Queue()
@@ -113,6 +114,7 @@ def test_cancel(self):
113114
scheduler.run()
114115
self.assertEqual(l, [0.02, 0.03, 0.04])
115116

117+
@unittest.skipIfGraalPythonWitoutThreads
116118
@unittest.skipUnless(threading, 'Threading required for this test.')
117119
def test_cancel_concurrent(self):
118120
q = queue.Queue()

graalpython/lib-python/3/unittest/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,11 @@ def load_tests(loader, tests, pattern):
8181

8282
def skipIfGraalPython(reason="Functionality not yet supported"):
8383
return skipIf(sys.implementation.name == 'graalpython', reason)
84+
85+
86+
def skipIfGraalPythonWitoutThreads(reason="Threading not yet enabled"):
87+
try:
88+
import _sysconfig as syscfg
89+
except Exception:
90+
import sysconfig as syscfg
91+
return skipIf(sys.implementation.name == 'graalpython' and not syscfg.get_config_var('WITH_THREAD'), reason)

0 commit comments

Comments
 (0)