Skip to content

Commit 068b89e

Browse files
committed
[GR-44220] Add test reporting for our gates
PullRequest: graalpython/2632
2 parents d2d18e5 + e83ac76 commit 068b89e

File tree

3 files changed

+97
-40
lines changed

3 files changed

+97
-40
lines changed

ci.jsonnet

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "overlay": "d59023a625716d3e6f01e70af51cbbaeb0468497" }
1+
{ "overlay": "9e9ffef3db814e665b8c28d12226550cd4319fb7" }

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

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ def _pytest_skip():
281281
sys.modules["pytest"] = _pytest_module
282282

283283
verbose = False
284-
284+
reportfile = None
285285

286286
def _cleanup_tempdirs():
287287
import shutil
@@ -423,19 +423,19 @@ def run_test(self, func):
423423
def do_run():
424424
if hasattr(self, "setUp"):
425425
if not self.run_safely(self.setUp, print_immediately=True):
426-
self.failure(0)
426+
self.failure(func, 0)
427427
return
428428
start = time.monotonic()
429429
r = self.run_safely(func)
430430
end = time.monotonic() - start
431431
if hasattr(self, "tearDown"):
432432
if not self.run_safely(self.tearDown):
433-
self.failure(end)
433+
self.failure(func, end)
434434
with print_lock:
435435
if r is _skipped_marker:
436-
self.skipped()
436+
self.skipped(func)
437437
elif r:
438-
self.success(end)
438+
self.success(func, end)
439439
else:
440440
transient_marker = [name for name in TRANSIENTS if name in func.__qualname__]
441441
if transient_marker:
@@ -453,7 +453,7 @@ def do_run():
453453
pass
454454
do_run()
455455
else:
456-
self.failure(end)
456+
self.failure(func, end)
457457
if TestCase.fail_fast:
458458
if verbose:
459459
print(FAIL, BOLD)
@@ -468,22 +468,40 @@ def do_run():
468468
if force_serial_execution:
469469
ThreadPool.shutdown()
470470

471-
def success(self, time):
471+
def success(self, func, time):
472472
self.passed += 1
473473
if verbose:
474474
print("[%.3fs]" % time, end=" ")
475475
print(".", end="", flush=True)
476-
477-
def failure(self, time):
476+
if reportfile:
477+
reportfile.append({
478+
"name": f"{func.__module__}.{func.__qualname__}",
479+
"status": "PASSED",
480+
"duration": int(time * 1000),
481+
})
482+
483+
def failure(self, func, time):
478484
self.failed += 1
479485
fail_msg = FAIL + BOLD + "F" + ENDC if verbose else "F"
480486
if verbose:
481487
print("[%.3fs]" % time, end=" ")
482488
print(fail_msg, end="", flush=True)
483-
484-
def skipped(self):
489+
if reportfile:
490+
reportfile.append({
491+
"name": f"{func.__module__}.{func.__qualname__}",
492+
"status": "FAILED",
493+
"duration": int(time * 1000),
494+
})
495+
496+
def skipped(self, func):
485497
self.skipped_n += 1
486498
print("s ", end="", flush=True)
499+
if reportfile:
500+
reportfile.append({
501+
"name": f"{func.__module__}.{func.__qualname__}",
502+
"status": "IGNORED",
503+
"duration": 0,
504+
})
487505

488506
def assertIsInstance(self, value, cls):
489507
assert isinstance(value, cls), "Expected %r to be instance of %r" % (value, cls)
@@ -803,7 +821,19 @@ class TestSuite:
803821
argv = sys.argv[:]
804822
idx = 0
805823
while idx < len(argv):
806-
if argv[idx] == "-k":
824+
if argv[idx].startswith("--report"):
825+
argv.pop(idx)
826+
try:
827+
import json
828+
except:
829+
print("--report needs working json module")
830+
raise
831+
try:
832+
reportfile = [argv.pop(idx),]
833+
except:
834+
print("--report needs argument path to the json output")
835+
raise
836+
elif argv[idx] == "-k":
807837
argv.pop(idx)
808838
try:
809839
pattern = argv.pop(idx)
@@ -835,4 +865,7 @@ class TestSuite:
835865
try:
836866
TestRunner(paths).run()
837867
finally:
868+
if reportfile:
869+
with open(reportfile[0], 'w') as f:
870+
json.dump(reportfile[1:], f)
838871
_cleanup_tempdirs()

mx.graalpython/mx_graalpython.py

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import shlex
3737
import shutil
3838
import sys
39+
import time
3940
from functools import wraps
4041

4142
HPY_IMPORT_ORPHAN_BRANCH_NAME = "hpy-import"
@@ -281,7 +282,7 @@ def _dev_pythonhome():
281282
return os.path.join(SUITE.dir, "graalpython")
282283

283284

284-
def punittest(ars):
285+
def punittest(ars, report=False):
285286
"""
286287
Runs GraalPython junit tests and memory leak tests, which can be skipped using --no-leak-tests.
287288
@@ -300,7 +301,7 @@ def punittest(ars):
300301
args += ars
301302
args2 += ars
302303
with _pythonhome_context():
303-
mx_unittest.unittest(args)
304+
mx_unittest.unittest(args, test_report_tags=({"task": "punittest"} if report else None))
304305
if len(args2) > len(ars):
305306
mx_unittest.unittest(args2)
306307

@@ -854,7 +855,7 @@ def is_included(path):
854855

855856

856857
def run_python_unittests(python_binary, args=None, paths=None, aot_compatible=False, exclude=None, env=None,
857-
use_pytest=False, cwd=None, lock=None, out=None, err=None, nonZeroIsFatal=True, javaAsserts=False, timeout=None):
858+
use_pytest=False, cwd=None, lock=None, out=None, err=None, nonZeroIsFatal=True, javaAsserts=False, timeout=None, report=False):
858859
if lock:
859860
lock.acquire()
860861
# ensure that the test distribution is up-to-date
@@ -888,6 +889,14 @@ def run_python_unittests(python_binary, args=None, paths=None, aot_compatible=Fa
888889
else:
889890
args += [_graalpytest_driver(), "-v"]
890891

892+
if report:
893+
reportfile = None
894+
t0 = time.time()
895+
if not use_pytest:
896+
reportfile = os.path.abspath(tempfile.mktemp(prefix="test-report-", suffix=".json"))
897+
args += ["--report", reportfile]
898+
899+
result = 0
891900
if is_collectiong_coverage():
892901
env['ENABLE_THREADED_GRAALPYTEST'] = "false"
893902
if mx_gate.get_jacoco_agent_args():
@@ -906,7 +915,18 @@ def run_python_unittests(python_binary, args=None, paths=None, aot_compatible=Fa
906915
mx.logv(" ".join([python_binary] + args))
907916
if lock:
908917
lock.release()
909-
return mx.run([python_binary] + args, nonZeroIsFatal=nonZeroIsFatal, env=env, cwd=cwd, out=out, err=err, timeout=timeout)
918+
result = mx.run([python_binary] + args, nonZeroIsFatal=nonZeroIsFatal, env=env, cwd=cwd, out=out, err=err, timeout=timeout)
919+
920+
if report:
921+
if reportfile:
922+
mx_gate.make_test_report(reportfile, report.title)
923+
else:
924+
mx_gate.make_test_report([{
925+
"name": report.title,
926+
"status": "PASSED" if result == 0 else "FAILED",
927+
"duration": int((time.time() - t0) * 1000)
928+
}], report.title)
929+
return result
910930

911931

912932
def get_venv_env(env_dir):
@@ -966,7 +986,7 @@ def patch_batch_launcher(launcher_path, jvm_args):
966986
launcher.writelines(lines)
967987

968988

969-
def run_hpy_unittests(python_binary, args=None, include_native=True, env=None, nonZeroIsFatal=True, timeout=None):
989+
def run_hpy_unittests(python_binary, args=None, include_native=True, env=None, nonZeroIsFatal=True, timeout=None, report=False):
970990
args = [] if args is None else args
971991
with tempfile.TemporaryDirectory(prefix='hpy-test-site-') as d:
972992
env = env or os.environ.copy()
@@ -997,7 +1017,7 @@ def run(self):
9971017
try:
9981018
self.result = run_python_unittests(python_binary, args=args, paths=[_hpy_test_root()],
9991019
env=tenv, use_pytest=True, lock=lock, nonZeroIsFatal=False,
1000-
out=self.out, err=self.out, timeout=timeout)
1020+
out=self.out, err=self.out, timeout=timeout, report=report)
10011021
except BaseException as e: # pylint: disable=broad-except;
10021022
self.result = e
10031023
else:
@@ -1010,7 +1030,7 @@ def __init__(self, name):
10101030
def start(self):
10111031
self.result = run_python_unittests(python_binary, args=args, paths=[_hpy_test_root()],
10121032
env=tenv, use_pytest=True, nonZeroIsFatal=nonZeroIsFatal,
1013-
timeout=timeout)
1033+
timeout=timeout, report=report)
10141034

10151035
def join(self, *args, **kwargs):
10161036
return
@@ -1045,7 +1065,7 @@ def is_alive(self):
10451065

10461066

10471067
def run_tagged_unittests(python_binary, env=None, cwd=None, javaAsserts=False, nonZeroIsFatal=True,
1048-
checkIfWithGraalPythonEE=False):
1068+
checkIfWithGraalPythonEE=False, report=False):
10491069
python_path = os.path.join(_dev_pythonhome(), 'lib-python/3')
10501070
sub_env = dict(
10511071
ENABLE_THREADED_GRAALPYTEST="true",
@@ -1068,20 +1088,24 @@ def run_tagged_unittests(python_binary, env=None, cwd=None, javaAsserts=False, n
10681088
cwd=cwd,
10691089
javaAsserts=javaAsserts,
10701090
nonZeroIsFatal=nonZeroIsFatal,
1091+
report=report,
10711092
)
10721093

10731094

10741095
def graalpython_gate_runner(args, tasks):
1096+
report = lambda: (not is_collectiong_coverage()) and task
1097+
nonZeroIsFatal = not is_collectiong_coverage()
1098+
10751099
# JUnit tests
10761100
with Task('GraalPython JUnit', tasks, tags=[GraalPythonTags.junit]) as task:
10771101
if task:
1078-
punittest(['--verbose'])
1102+
punittest(['--verbose'], report=report())
10791103

10801104
# Unittests on JVM
10811105
with Task('GraalPython Python unittests', tasks, tags=[GraalPythonTags.unittest]) as task:
10821106
if task:
10831107
mx.run(["env"])
1084-
run_python_unittests(python_gvm(), javaAsserts=True, nonZeroIsFatal=(not is_collectiong_coverage()))
1108+
run_python_unittests(python_gvm(), javaAsserts=True, nonZeroIsFatal=nonZeroIsFatal, report=report())
10851109

10861110
with Task('GraalPython Python unittests with CPython', tasks, tags=[GraalPythonTags.unittest_cpython]) as task:
10871111
if task:
@@ -1097,64 +1121,64 @@ def graalpython_gate_runner(args, tasks):
10971121

10981122
with Task('GraalPython sandboxed tests', tasks, tags=[GraalPythonTags.unittest_sandboxed]) as task:
10991123
if task:
1100-
run_python_unittests(python_managed_gvm(), javaAsserts=True)
1124+
run_python_unittests(python_managed_gvm(), javaAsserts=True, report=report())
11011125

11021126
with Task('GraalPython multi-context unittests', tasks, tags=[GraalPythonTags.unittest_multi]) as task:
11031127
if task:
1104-
run_python_unittests(python_gvm(), args=["-multi-context"], javaAsserts=True, nonZeroIsFatal=(not is_collectiong_coverage()))
1128+
run_python_unittests(python_gvm(), args=["-multi-context"], javaAsserts=True, nonZeroIsFatal=nonZeroIsFatal, report=report())
11051129

11061130
with Task('GraalPython Jython emulation tests', tasks, tags=[GraalPythonTags.unittest_jython]) as task:
11071131
if task:
1108-
run_python_unittests(python_gvm(), args=["--python.EmulateJython"], paths=["test_interop.py"], javaAsserts=True)
1132+
run_python_unittests(python_gvm(), args=["--python.EmulateJython"], paths=["test_interop.py"], javaAsserts=True, report=report(), nonZeroIsFatal=nonZeroIsFatal)
11091133

1110-
with Task('GraalPython ginstall', tasks, tags=[GraalPythonTags.ginstall]) as task:
1134+
with Task('GraalPython ginstall', tasks, tags=[GraalPythonTags.ginstall], report=True) as task:
11111135
if task:
11121136
run_ginstall(python_gvm(), args=["--quiet"])
11131137

11141138
with Task('GraalPython HPy tests', tasks, tags=[GraalPythonTags.unittest_hpy]) as task:
11151139
if task:
1116-
run_hpy_unittests(python_svm(), nonZeroIsFatal=(not is_collectiong_coverage()))
1140+
run_hpy_unittests(python_svm(), nonZeroIsFatal=nonZeroIsFatal, report=report())
11171141

11181142
with Task('GraalPython HPy sandboxed tests', tasks, tags=[GraalPythonTags.unittest_hpy_sandboxed]) as task:
11191143
if task:
1120-
run_hpy_unittests(python_managed_svm(), include_native=False)
1144+
run_hpy_unittests(python_managed_svm(), include_native=False, report=report())
11211145

11221146
with Task('GraalPython posix module tests', tasks, tags=[GraalPythonTags.unittest_posix]) as task:
11231147
if task:
1124-
run_python_unittests(python_gvm(), args=["--PosixModuleBackend=native"], paths=["test_posix.py", "test_mmap.py"], javaAsserts=True)
1125-
run_python_unittests(python_gvm(), args=["--PosixModuleBackend=java"], paths=["test_posix.py", "test_mmap.py"], javaAsserts=True)
1148+
run_python_unittests(python_gvm(), args=["--PosixModuleBackend=native"], paths=["test_posix.py", "test_mmap.py"], javaAsserts=True, report=report())
1149+
run_python_unittests(python_gvm(), args=["--PosixModuleBackend=java"], paths=["test_posix.py", "test_mmap.py"], javaAsserts=True, report=report())
11261150

11271151
with Task('GraalPython Python tests', tasks, tags=[GraalPythonTags.tagged]) as task:
11281152
if task:
11291153
# don't fail this task if we're running with the jacoco agent, we know that some tests don't pass with it enabled
1130-
run_tagged_unittests(python_svm(), nonZeroIsFatal=(not is_collectiong_coverage()))
1154+
run_tagged_unittests(python_svm(), nonZeroIsFatal=(not is_collectiong_coverage()), report=report())
11311155

11321156
with Task('GraalPython sandboxed Python tests', tasks, tags=[GraalPythonTags.tagged_sandboxed]) as task:
11331157
if task:
1134-
run_tagged_unittests(python_managed_gvm(), checkIfWithGraalPythonEE=True, cwd=SUITE.dir)
1158+
run_tagged_unittests(python_managed_gvm(), checkIfWithGraalPythonEE=True, cwd=SUITE.dir, report=report())
11351159

11361160
# Unittests on SVM
11371161
with Task('GraalPython tests on SVM', tasks, tags=[GraalPythonTags.svmunit]) as task:
11381162
if task:
1139-
run_python_unittests(python_svm(), aot_compatible=True)
1163+
run_python_unittests(python_svm(), aot_compatible=True, report=report())
11401164

11411165
with Task('GraalPython sandboxed tests on SVM', tasks, tags=[GraalPythonTags.svmunit_sandboxed]) as task:
11421166
if task:
1143-
run_python_unittests(python_managed_svm(), aot_compatible=True)
1167+
run_python_unittests(python_managed_svm(), aot_compatible=True, report=report())
11441168

11451169
with Task('GraalPython license header update', tasks, tags=[GraalPythonTags.license]) as task:
11461170
if task:
11471171
python_checkcopyrights([])
11481172

1149-
with Task('GraalPython GraalVM shared-library build', tasks, tags=[GraalPythonTags.shared_object, GraalPythonTags.graalvm]) as task:
1173+
with Task('GraalPython GraalVM shared-library build', tasks, tags=[GraalPythonTags.shared_object, GraalPythonTags.graalvm], report=True) as task:
11501174
if task:
11511175
run_shared_lib_test(python_so())
11521176

1153-
with Task('GraalPython GraalVM sandboxed shared-library build', tasks, tags=[GraalPythonTags.shared_object_sandboxed, GraalPythonTags.graalvm_sandboxed]) as task:
1177+
with Task('GraalPython GraalVM sandboxed shared-library build', tasks, tags=[GraalPythonTags.shared_object_sandboxed, GraalPythonTags.graalvm_sandboxed], report=True) as task:
11541178
if task:
11551179
run_shared_lib_test(python_managed_so(), ("sandboxed",))
11561180

1157-
with Task('GraalPython GraalVM build', tasks, tags=[GraalPythonTags.svm, GraalPythonTags.graalvm]) as task:
1181+
with Task('GraalPython GraalVM build', tasks, tags=[GraalPythonTags.svm, GraalPythonTags.graalvm], report=True) as task:
11581182
if task:
11591183
svm_image = python_svm()
11601184
benchmark = os.path.join(PATH_MESO, "image-magix.py")
@@ -1169,7 +1193,7 @@ def graalpython_gate_runner(args, tasks):
11691193

11701194
with Task('GraalPy win32 smoketests', tasks, tags=[GraalPythonTags.windows]) as task:
11711195
if task:
1172-
punittest(["--no-leak-tests", "--regex", r'(com\.oracle\.truffle\.tck\.tests)|(graal\.python\.test\.(advance\.Benchmark|basic|builtin|decorator|generator|interop|util))'])
1196+
punittest(["--no-leak-tests", "--regex", r'(com\.oracle\.truffle\.tck\.tests)|(graal\.python\.test\.(advance\.Benchmark|basic|builtin|decorator|generator|interop|util))'], report=True)
11731197
svm_image = python_svm()
11741198
out = mx.OutputCapture()
11751199
mx.run([svm_image, "-v", "-S", "--log.python.level=FINEST", "-c", "import sys; print(sys.platform)"], nonZeroIsFatal=True, out=mx.TeeOutputCapture(out), err=mx.TeeOutputCapture(out))
@@ -1181,7 +1205,7 @@ def graalpython_gate_runner(args, tasks):
11811205
if success not in out.data:
11821206
mx.abort(f'Output from generated SVM image "{svm_image}" did not match success pattern:\nExpected\n{success}\nGot\n{out.data}')
11831207

1184-
with Task('Python SVM Truffle TCK', tasks, tags=[GraalPythonTags.language_checker]) as task:
1208+
with Task('Python SVM Truffle TCK', tasks, tags=[GraalPythonTags.language_checker], report=True) as task:
11851209
if task:
11861210
mx.run_mx([
11871211
"--dy", "graalpython,/substratevm",

0 commit comments

Comments
 (0)