Skip to content

Commit 0de4e96

Browse files
committed
unittest_runner: track test stats, generated reports are not precise
1 parent 0698a59 commit 0de4e96

File tree

1 file changed

+84
-9
lines changed

1 file changed

+84
-9
lines changed

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

Lines changed: 84 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@
7676
PTRN_IMPORT_ERROR = re.compile(r".*cannot import name \'(?P<module>.*)\'.*", re.DOTALL)
7777
PTRN_REMOTE_HOST = re.compile(r"(?P<user>\w+)@(?P<host>[\w.]+):(?P<path>.+)")
7878
PTRN_VALID_CSV_NAME = re.compile(r"unittests-\d{4}-\d{2}-\d{2}.csv")
79+
PTRN_TEST_STATUS_INDIVIDUAL = re.compile(r"(?P<name>test_[\w_]+ \(.+\)) ... (?P<status>.+)")
80+
PTRN_TEST_STATUS_ERROR = re.compile(r"(?P<status>.+): (?P<name>test_[\w_]+ \(.+\))")
7981

8082

8183
# ----------------------------------------------------------------------------------------------------------------------
@@ -216,6 +218,13 @@ def read_csv(path):
216218
return rows
217219

218220

221+
class TestStatus(object):
222+
ERROR = 'error'
223+
FAIL = 'fail'
224+
SKIPPED = 'skipped'
225+
OK = 'ok'
226+
227+
219228
# ----------------------------------------------------------------------------------------------------------------------
220229
#
221230
# result (output processing)
@@ -224,35 +233,81 @@ def read_csv(path):
224233
class StatEntry(object):
225234
def __init__(self):
226235
self.num_tests = -1
227-
self.num_errors = -1
228-
self.num_fails = -1
229-
self.num_skipped = -1
236+
# reported stats
237+
self._num_errors = -1
238+
self._num_fails = -1
239+
self._num_skipped = -1
240+
# tracked stats
241+
self._tracked = False
230242

231243
def all_ok(self):
232-
self.num_fails = 0
233-
self.num_errors = 0
234-
self.num_skipped = 0
244+
self._num_fails = 0
245+
self._num_errors = 0
246+
self._num_skipped = 0
247+
248+
@property
249+
def num_errors(self):
250+
return self._num_errors
251+
252+
@num_errors.setter
253+
def num_errors(self, value):
254+
if not self._tracked:
255+
self._num_errors = value
256+
257+
@property
258+
def num_fails(self):
259+
return self._num_fails
260+
261+
@num_fails.setter
262+
def num_fails(self, value):
263+
if not self._tracked:
264+
self._num_fails = value
265+
266+
@property
267+
def num_skipped(self):
268+
return self._num_skipped
269+
270+
@num_skipped.setter
271+
def num_skipped(self, value):
272+
if not self._tracked:
273+
self._num_fails = value
235274

236275
@property
237276
def num_passes(self):
238277
if self.num_tests > 0:
239-
return self.num_tests - (self.num_fails + self.num_errors + self.num_skipped)
278+
return self.num_tests - (self._num_fails + self._num_errors + self._num_skipped)
240279
return -1
241280

281+
def update(self, test_detailed_stats):
282+
for test, stats in test_detailed_stats.items():
283+
self._tracked = True
284+
stats = {s.lower() for s in stats}
285+
if TestStatus.ERROR in stats:
286+
self._num_errors = 1 if self._num_errors == -1 else self._num_errors + 1
287+
elif TestStatus.FAIL in stats:
288+
self._num_fails = 1 if self._num_fails == -1 else self._num_fails + 1
289+
else:
290+
for s in stats:
291+
if s.startswith(TestStatus.SKIPPED):
292+
self._num_skipped = 1 if self._num_skipped == -1 else self._num_skipped + 1
293+
break
294+
242295

243296
def process_output(output_lines):
244297
if isinstance(output_lines, str):
245298
output_lines = output_lines.split("\n")
246299

247300
unittests = []
301+
unittest_tests = defaultdict(list)
248302
error_messages = defaultdict(set)
249303
java_exceptions = defaultdict(set)
250304
stats = defaultdict(StatEntry)
251305

252306
for line in output_lines:
253307
match = re.match(PTRN_UNITTEST, line)
254308
if match:
255-
unittests.append(match.group('unittest'))
309+
unittest = match.group('unittest')
310+
unittests.append(unittest)
256311
continue
257312

258313
# extract python reported python error messages
@@ -268,6 +323,21 @@ def process_output(output_lines):
268323
continue
269324

270325
# stats
326+
# tracking
327+
match = re.match(PTRN_TEST_STATUS_INDIVIDUAL, line)
328+
if match:
329+
name = match.group('name')
330+
status = match.group('status')
331+
unittest_tests[name].append(status)
332+
continue
333+
334+
match = re.match(PTRN_TEST_STATUS_ERROR, line)
335+
if match:
336+
name = match.group('name')
337+
status = match.group('status')
338+
unittest_tests[name].append(status)
339+
continue
340+
271341
if line.strip() == 'OK':
272342
stats[unittests[-1]].all_ok()
273343
continue
@@ -286,6 +356,8 @@ def process_output(output_lines):
286356
match = re.match(PTRN_NUM_TESTS, line)
287357
if match:
288358
stats[unittests[-1]].num_tests = int(match.group('num_tests'))
359+
stats[unittests[-1]].update(unittest_tests)
360+
unittest_tests.clear()
289361
continue
290362

291363
match = re.match(PTRN_FAILED, line)
@@ -299,6 +371,7 @@ def process_output(output_lines):
299371
stats[unittests[-1]].num_fails = int(fails) if fails else 0
300372
stats[unittests[-1]].num_errors = int(errs) if errs else 0
301373
stats[unittests[-1]].num_skipped = int(skipped) if skipped else 0
374+
continue
302375

303376
return unittests, error_messages, java_exceptions, stats
304377

@@ -712,6 +785,8 @@ def main(prog, args):
712785
parser = argparse.ArgumentParser(prog=prog,
713786
description="Run the standard python unittests.")
714787
parser.add_argument("-v", "--verbose", help="Verbose output.", action="store_true")
788+
parser.add_argument("-n", "--no_cpython", help="Do not run the tests with cpython (for comparison).",
789+
action="store_true")
715790
parser.add_argument("-l", "--limit", help="Limit the number of unittests to run.", default=None, type=int)
716791
parser.add_argument("-t", "--tests_path", help="Unittests path.", default=PATH_UNITTESTS)
717792
parser.add_argument("-T", "--timeout", help="Timeout per unittest run.", default=TIMEOUT, type=int)
@@ -754,7 +829,7 @@ def _fmt(t):
754829
unittests = get_unittests(flags.tests_path, limit=flags.limit, skip_tests=skip_tests)
755830

756831
# get cpython stats
757-
if not flags.gate:
832+
if not flags.gate and not flags.no_cpython:
758833
log(HR)
759834
log("[INFO] get cpython stats")
760835
cpy_results = run_unittests(unittests, 60 * 5, with_cpython=True)

0 commit comments

Comments
 (0)