GitLab will be upgraded on June 2nd 2020 at 2.00 pm (AEDT) to 3.00 pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to local Gitlab admin team.

Commit b5606cac authored by John Zhang's avatar John Zhang

refactor using python decorator: run whole tests in separate processes

parent 60066172
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rlib import rmu_fast as rmu
from util import fncptr_from_rpy_func, fncptr_from_py_script, call_and_check
from util import fncptr_from_rpy_func, fncptr_from_py_script, may_spawn_proc
import ctypes
......@@ -18,17 +18,17 @@ def rand_list_of(n):
# --------------------------
# tests
@may_spawn_proc
def test_add():
def add(a, b):
return a + b
fn, _ = fncptr_from_rpy_func(add, [rffi.LONGLONG, rffi.LONGLONG], rffi.LONGLONG)
def check(s):
assert s == 3
call_and_check(fn, (1, 2), check)
assert fn(1, 2) == 3
@may_spawn_proc
def test_vec3prod():
def prod(v1, v2):
a = v1[0] * v2[0]
......@@ -47,11 +47,10 @@ def test_vec3prod():
vec2[1] = 5
vec2[2] = 6
def check(s):
assert s == 32
call_and_check(fnc, (vec1, vec2), check)
assert fnc(vec1, vec2) == 32
@may_spawn_proc
def test_find_min():
def find_min(xs, sz):
m = xs[0]
......@@ -68,11 +67,10 @@ def test_find_min():
for i, k in enumerate(lst):
arr[i] = k
def check(m):
assert m == -5
call_and_check(fnc, (arr, 5), check)
fnc(arr, 5) == -5
@may_spawn_proc
def test_arraysum():
from rpython.rlib.jit import JitDriver
d = JitDriver(greens=[], reds='auto')
......@@ -92,11 +90,10 @@ def test_arraysum():
for i, k in enumerate(lst):
arr[i] = k
def check(s):
assert s == sum(lst)
call_and_check(fnc, (arr, rffi.cast(rffi.SIZE_T, n)), check)
assert fnc(arr, rffi.cast(rffi.SIZE_T, n)) == sum(lst)
@may_spawn_proc
def test_quicksort():
# algorithm taken from Wikipedia
def swap(arr, i, j):
......@@ -130,13 +127,14 @@ def test_quicksort():
for i, k in enumerate(lst):
arr[i] = k
def check():
lst_s = sorted(lst)
for i in range(n):
assert lst_s[i] == arr[i], "%d != %d" % (lst_s[i], arr[i])
call_and_check(fnc, (arr, rffi.cast(rffi.SIZE_T, 0), rffi.cast(rffi.SIZE_T, n - 1)), check)
fnc(arr, rffi.cast(rffi.SIZE_T, 0), rffi.cast(rffi.SIZE_T, n - 1)) # inplace sort
lst_s = sorted(lst)
for i in range(n):
assert lst_s[i] == arr[i], "%d != %d" % (lst_s[i], arr[i])
@may_spawn_proc
def test_linkedlist_reversal():
def reverse_linkedlist(head):
h = head
......@@ -171,16 +169,16 @@ def test_linkedlist_reversal():
d.val = 'd'
d.nxt = lltype.nullptr(Node)
def check(h):
print '%s -> %s -> %s -> %s' % (h.val, h.nxt.val, h.nxt.nxt.val, h.nxt.nxt.nxt.val)
assert h.val == 'd'
assert h.nxt.val == 'c'
assert h.nxt.nxt.val == 'b'
assert h.nxt.nxt.nxt.val == 'a'
assert h.nxt.nxt.nxt.nxt == lltype.nullptr(Node)
call_and_check(fnc, (a,), check)
h = fnc(a)
print '%s -> %s -> %s -> %s' % (h.val, h.nxt.val, h.nxt.nxt.val, h.nxt.nxt.nxt.val)
assert h.val == 'd'
assert h.nxt.val == 'c'
assert h.nxt.nxt.val == 'b'
assert h.nxt.nxt.nxt.val == 'a'
assert h.nxt.nxt.nxt.nxt == lltype.nullptr(Node)
@may_spawn_proc
def test_threadtran_fib():
def build_test_bundle(bldr, rmu):
"""
......@@ -284,11 +282,10 @@ def test_threadtran_fib():
mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
def check(res):
assert res == 6765
call_and_check(fnp, (20,), check)
assert fnp(20) == 6765
@may_spawn_proc
def test_new():
def build_test_bundle(bldr, rmu):
"""
......@@ -355,11 +352,10 @@ def test_new():
fnp, (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, 'test_fnc')
mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
def check(res):
assert res == 1
call_and_check(fnp, tuple(), check)
assert fnp() == 1
@may_spawn_proc
def test_new_cmpeq():
def build_test_bundle(bldr, rmu):
"""
......@@ -422,9 +418,8 @@ def test_new_cmpeq():
fnp, (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, 'test_fnc')
mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
def check(res):
assert res == 0
call_and_check(fnp, tuple(), check)
assert fnp() == 0
if __name__ == '__main__':
import argparse
......
......@@ -66,7 +66,7 @@ def fncptr_from_c_script(c_src_name, name, argtypes=[], restype=ctypes.c_ulonglo
return fncptr_from_lib(lib, name, argtypes, restype), lib
def fncptr_from_py_script(py_fnc, name, argtypes=[], restype=ctypes.c_longlong, spawn_proc=True):
def fncptr_from_py_script(py_fnc, name, argtypes=[], restype=ctypes.c_longlong):
# NOTE: requires mu-client-pypy
from rpython.rlib import rmu_fast as rmu
......@@ -80,10 +80,7 @@ def fncptr_from_py_script(py_fnc, name, argtypes=[], restype=ctypes.c_longlong,
id_dict = py_fnc(bldr, rmu)
bldr.load()
libname = 'lib%(name)s.dylib' % locals()
if spawn_proc:
proc_call(mu.compile_to_sharedlib, (libname, []))
else:
mu.compile_to_sharedlib(libname, [])
mu.compile_to_sharedlib(libname, [])
lib = ctypes.CDLL('emit/%(libname)s' % locals())
return fncptr_from_lib(lib, name, argtypes, restype), (mu, ctx, bldr)
......@@ -94,42 +91,17 @@ def preload_libmu():
return ctypes.CDLL(libmu_path.strpath, ctypes.RTLD_GLOBAL)
def proc_call(fnc, args):
# call function with an extra Queue parameter to pass the return value in a separate process
q = Queue()
rtn = None
proc = Process(target=lambda *args: args[-1].put(fnc(*args[:-1])), args=args + (q,))
proc.start()
from Queue import Empty
while proc.is_alive():
try:
rtn = q.get(False)
break
except Empty:
pass
if proc.is_alive():
proc.join()
if proc.exitcode != 0:
proc.join()
raise ProcessError("calling %(fnc)s with args %(args)s crashed with " % locals() + str(proc.exitcode))
return rtn
spawn_proc = bool(int(os.environ.get('SPAWN_PROC', '1')))
def call_and_check(fnc, args, check_fnc):
def inner():
res = fnc(*args)
if res is None:
check_fnc()
def may_spawn_proc(test_fnc):
def wrapper():
if spawn_proc:
p = Process(target=test_fnc, args=tuple())
p.start()
p.join()
assert p.exitcode == 0
else:
check_fnc(res)
if spawn_proc:
proc_call(inner, tuple())
else:
inner()
test_fnc()
return wrapper
def fncptr_from_rpy_func(rpy_fnc, llargtypes, llrestype, **kwargs):
......@@ -150,11 +122,7 @@ def fncptr_from_rpy_func(rpy_fnc, llargtypes, llrestype, **kwargs):
if kwargs['backend'] == 'mu':
db, bdlgen, fnc_name = t.compile_mu()
libname = 'lib%(fnc_name)s.dylib' % locals()
if spawn_proc:
# run in a different process
proc_call(bdlgen.mu.compile_to_sharedlib, args=(libname, []))
else:
bdlgen.mu.compile_to_sharedlib(libname, [])
bdlgen.mu.compile_to_sharedlib(libname, [])
eci = rffi.ExternalCompilationInfo(libraries=[test_jit_dir.join('emit', libname).strpath])
extras = (db, bdlgen)
else:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment