mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-07 12:16:24 +00:00
fix(runtest.py): A workaround to bypass errors that occur when deleting temporary files (#4093)
- Replace sys.exit with exceptions for better error handling in test assertions - Update exception handling in compile_wast_to_wasm to catch all exceptions - Improve error messages and logging - Use `--ignore-whitespace` option for git apply in spec_test function - Use raw string notation for regex patterns. *The "SyntaxWarning: invalid escape sequence" in Python The warning has been upgraded to SyntaxWarning since Python 3.12, and it is expected to become a SyntaxError in future versions.* - Add early return for non-loadable AOT compilation to prevent unnecessary assertions - Redirect stderr to stdout in test_case for unified output - Update `create_tmpfiles()` to improve clarity and handling of temporary files
This commit is contained in:
parent
1f14f4ec0a
commit
06ea960e76
|
@ -145,7 +145,7 @@ def run_clang_format_diff(root: Path, commits: str) -> bool:
|
|||
found = False
|
||||
for summary in [x for x in diff_content if x.startswith("diff --git")]:
|
||||
# b/path/to/file -> path/to/file
|
||||
with_invalid_format = re.split("\s+", summary)[-1][2:]
|
||||
with_invalid_format = re.split(r"\s+", summary)[-1][2:]
|
||||
if not is_excluded(with_invalid_format):
|
||||
print(f"--- {with_invalid_format} failed on code style checking.")
|
||||
found = True
|
||||
|
|
|
@ -206,7 +206,7 @@ def get_line_info_from_function_addr_sourcemapping(
|
|||
if not line:
|
||||
continue
|
||||
|
||||
m = re.match("(.*):(\d+):(\d+)", line)
|
||||
m = re.match(r"(.*):(\d+):(\d+)", line)
|
||||
if m:
|
||||
function_file, function_line, function_column = m.groups()
|
||||
continue
|
||||
|
|
|
@ -247,7 +247,7 @@ def test_case(
|
|||
CMD,
|
||||
bufsize=1,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
universal_newlines=True,
|
||||
) as p:
|
||||
try:
|
||||
|
@ -285,7 +285,9 @@ def test_case(
|
|||
except subprocess.TimeoutExpired:
|
||||
print("failed with TimeoutExpired")
|
||||
raise Exception(case_name)
|
||||
|
||||
except Exception as e:
|
||||
print(f"An unexpected error occurred: {e}")
|
||||
raise e
|
||||
|
||||
def test_suite(
|
||||
target,
|
||||
|
|
|
@ -7,6 +7,7 @@ import array
|
|||
import atexit
|
||||
import math
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
import shutil
|
||||
import struct
|
||||
|
@ -81,9 +82,8 @@ def log(data, end='\n'):
|
|||
print(data, end=end)
|
||||
sys.stdout.flush()
|
||||
|
||||
def create_tmp_file(suffix: str) -> str:
|
||||
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp_file:
|
||||
return tmp_file.name
|
||||
def create_tmp_file(prefix: str, suffix: str) -> str:
|
||||
return tempfile.NamedTemporaryFile(prefix=prefix, suffix=suffix, delete=False).name
|
||||
|
||||
# TODO: do we need to support '\n' too
|
||||
import platform
|
||||
|
@ -181,7 +181,16 @@ class Runner():
|
|||
# queue, so we keep it for non-windows platforms.
|
||||
[outs,_,_] = select([self.stdout], [], [], 1)
|
||||
if self.stdout in outs:
|
||||
return True, self.stdout.read(1)
|
||||
try:
|
||||
stdout_byte = self.stdout.read(1)
|
||||
except ValueError:
|
||||
return True, None
|
||||
except OSError:
|
||||
return True, None
|
||||
except Exception as e:
|
||||
print("Exception: ", e)
|
||||
return False, None
|
||||
return True, stdout_byte
|
||||
else:
|
||||
return False, None
|
||||
|
||||
|
@ -212,6 +221,8 @@ class Runner():
|
|||
buf = self.buf[0:end-len(prompt)]
|
||||
self.buf = self.buf[end:]
|
||||
return buf
|
||||
|
||||
log("left read_to_prompt() because of timeout")
|
||||
return None
|
||||
|
||||
def writeline(self, str):
|
||||
|
@ -249,14 +260,14 @@ def assert_prompt(runner, prompts, timeout, is_need_execute_result):
|
|||
header = runner.read_to_prompt(prompts, timeout=timeout)
|
||||
if not header and is_need_execute_result:
|
||||
log(" ---------- will terminate cause the case needs result while there is none inside of buf. ----------")
|
||||
sys.exit(1)
|
||||
raise Exception("get nothing from Runner")
|
||||
if not header == None:
|
||||
if header:
|
||||
log("Started with:\n%s" % header)
|
||||
else:
|
||||
log("Did not one of following prompt(s): %s" % repr(prompts))
|
||||
log(" Got : %s" % repr(r.buf))
|
||||
sys.exit(1)
|
||||
raise Exception("Did not one of following prompt(s)")
|
||||
|
||||
|
||||
### WebAssembly specific
|
||||
|
@ -551,7 +562,7 @@ def parse_assertion_value(val):
|
|||
if not val:
|
||||
return None, ""
|
||||
|
||||
splitted = re.split('\s+', val)
|
||||
splitted = re.split(r'\s+', val)
|
||||
splitted = [s for s in splitted if s]
|
||||
type = splitted[0].split(".")[0]
|
||||
lane_type = splitted[1] if len(splitted) > 2 else ""
|
||||
|
@ -790,8 +801,8 @@ def test_assert(r, opts, mode, cmd, expected):
|
|||
return True
|
||||
|
||||
## 0x9:i32,-0x1:i32 -> ['0x9:i32', '-0x1:i32']
|
||||
expected_list = re.split(',', expected)
|
||||
out_list = re.split(',', out)
|
||||
expected_list = re.split(r',', expected)
|
||||
out_list = re.split(r',', out)
|
||||
if len(expected_list) != len(out_list):
|
||||
raise Exception("Failed:\n Results count incorrect:\n expected: '%s'\n got: '%s'" % (expected, out))
|
||||
for i in range(len(expected_list)):
|
||||
|
@ -806,34 +817,34 @@ def test_assert_return(r, opts, form):
|
|||
n. to search a pattern like (assert_return (invoke $module_name function_name ... ) ...)
|
||||
"""
|
||||
# params, return
|
||||
m = re.search('^\(assert_return\s+\(invoke\s+"((?:[^"]|\\\")*)"\s+(\(.*\))\s*\)\s*(\(.*\))\s*\)\s*$', form, re.S)
|
||||
m = re.search(r'^\(assert_return\s+\(invoke\s+"((?:[^"]|\\\")*)"\s+(\(.*\))\s*\)\s*(\(.*\))\s*\)\s*$', form, re.S)
|
||||
# judge if assert_return cmd includes the module name
|
||||
n = re.search('^\(assert_return\s+\(invoke\s+\$((?:[^\s])*)\s+"((?:[^"]|\\\")*)"\s+(\(.*\))\s*\)\s*(\(.*\))\s*\)\s*$', form, re.S)
|
||||
n = re.search(r'^\(assert_return\s+\(invoke\s+\$((?:[^\s])*)\s+"((?:[^"]|\\\")*)"\s+(\(.*\))\s*\)\s*(\(.*\))\s*\)\s*$', form, re.S)
|
||||
|
||||
# print("assert_return with {}".format(form))
|
||||
|
||||
if not m:
|
||||
# no params, return
|
||||
m = re.search('^\(assert_return\s+\(invoke\s+"((?:[^"]|\\\")*)"\s*\)\s+()(\(.*\))\s*\)\s*$', form, re.S)
|
||||
m = re.search(r'^\(assert_return\s+\(invoke\s+"((?:[^"]|\\\")*)"\s*\)\s+()(\(.*\))\s*\)\s*$', form, re.S)
|
||||
if not m:
|
||||
# params, no return
|
||||
m = re.search('^\(assert_return\s+\(invoke\s+"([^"]*)"\s+(\(.*\))()\s*\)\s*\)\s*$', form, re.S)
|
||||
m = re.search(r'^\(assert_return\s+\(invoke\s+"([^"]*)"\s+(\(.*\))()\s*\)\s*\)\s*$', form, re.S)
|
||||
if not m:
|
||||
# no params, no return
|
||||
m = re.search('^\(assert_return\s+\(invoke\s+"([^"]*)"\s*()()\)\s*\)\s*$', form, re.S)
|
||||
m = re.search(r'^\(assert_return\s+\(invoke\s+"([^"]*)"\s*()()\)\s*\)\s*$', form, re.S)
|
||||
if not m:
|
||||
# params, return
|
||||
if not n:
|
||||
# no params, return
|
||||
n = re.search('^\(assert_return\s+\(invoke\s+\$((?:[^\s])*)\s+"((?:[^"]|\\\")*)"\s*\)\s+()(\(.*\))\s*\)\s*$', form, re.S)
|
||||
n = re.search(r'^\(assert_return\s+\(invoke\s+\$((?:[^\s])*)\s+"((?:[^"]|\\\")*)"\s*\)\s+()(\(.*\))\s*\)\s*$', form, re.S)
|
||||
if not n:
|
||||
# params, no return
|
||||
n = re.search('^\(assert_return\s+\(invoke\s+\$((?:[^\s])*)\s+"([^"]*)"\s+(\(.*\))()\s*\)\s*\)\s*$', form, re.S)
|
||||
n = re.search(r'^\(assert_return\s+\(invoke\s+\$((?:[^\s])*)\s+"([^"]*)"\s+(\(.*\))()\s*\)\s*\)\s*$', form, re.S)
|
||||
if not n:
|
||||
# no params, no return
|
||||
n = re.search('^\(assert_return\s+\(invoke\s+\$((?:[^\s])*)\s+"([^"]*)"*()()\)\s*\)\s*$', form, re.S)
|
||||
n = re.search(r'^\(assert_return\s+\(invoke\s+\$((?:[^\s])*)\s+"([^"]*)"*()()\)\s*\)\s*$', form, re.S)
|
||||
if not m and not n:
|
||||
if re.search('^\(assert_return\s+\(get.*\).*\)$', form, re.S):
|
||||
if re.search(r'^\(assert_return\s+\(get.*\).*\)$', form, re.S):
|
||||
log("ignoring assert_return get")
|
||||
return
|
||||
else:
|
||||
|
@ -852,7 +863,7 @@ def test_assert_return(r, opts, form):
|
|||
if m.group(2) == '':
|
||||
args = []
|
||||
else:
|
||||
#args = [re.split(' +', v)[1].replace('_', "") for v in re.split("\)\s*\(", m.group(2)[1:-1])]
|
||||
#args = [re.split(r' +', v)[1].replace('_', "") for v in re.split(r"\)\s*\(", m.group(2)[1:-1])]
|
||||
# split arguments with ')spaces(', remove leading and tailing ) and (
|
||||
args_type_and_value = re.split(r'\)\s+\(', m.group(2)[1:-1])
|
||||
args_type_and_value = [s.replace('_', '') for s in args_type_and_value]
|
||||
|
@ -863,7 +874,7 @@ def test_assert_return(r, opts, form):
|
|||
for arg in args_type_and_value:
|
||||
# remove leading and tailing spaces, it might confuse following assertions
|
||||
arg = arg.strip()
|
||||
splitted = re.split('\s+', arg)
|
||||
splitted = re.split(r'\s+', arg)
|
||||
splitted = [s for s in splitted if s]
|
||||
|
||||
if splitted[0] in ["i32.const", "i64.const"]:
|
||||
|
@ -881,7 +892,7 @@ def test_assert_return(r, opts, form):
|
|||
numbers, _ = cast_v128_to_i64x2(splitted[2:], 'v128', splitted[1])
|
||||
|
||||
assert(len(numbers) == 2), "has to reform arguments into i64x2"
|
||||
args.append(f"{numbers[0]:#x}\{numbers[1]:#x}")
|
||||
args.append(f"{numbers[0]:#x}\\{numbers[1]:#x}")
|
||||
elif "ref.null" == splitted[0]:
|
||||
args.append("null")
|
||||
elif "ref.extern" == splitted[0]:
|
||||
|
@ -896,7 +907,7 @@ def test_assert_return(r, opts, form):
|
|||
if m.group(3) == '':
|
||||
returns= []
|
||||
else:
|
||||
returns = re.split("\)\s*\(", m.group(3)[1:-1])
|
||||
returns = re.split(r"\)\s*\(", m.group(3)[1:-1])
|
||||
# processed numbers in strings
|
||||
if len(returns) == 1 and returns[0] in ["ref.array", "ref.struct", "ref.i31",
|
||||
"ref.eq", "ref.any", "ref.extern",
|
||||
|
@ -921,8 +932,7 @@ def test_assert_return(r, opts, form):
|
|||
except:
|
||||
_, exc, _ = sys.exc_info()
|
||||
log("Run wamrc failed:\n got: '%s'" % r.buf)
|
||||
ret_code = 1
|
||||
sys.exit(1)
|
||||
raise Exception("Run wamrc failed 1")
|
||||
r = run_wasm_with_repl(module+".wasm", module+".aot" if test_aot else module, opts, r)
|
||||
# Wait for the initial prompt
|
||||
try:
|
||||
|
@ -941,23 +951,23 @@ def test_assert_return(r, opts, form):
|
|||
# convert (ref.null extern/func) into (ref.null null)
|
||||
n1 = n.group(3).replace("(ref.null extern)", "(ref.null null)")
|
||||
n1 = n1.replace("ref.null func)", "(ref.null null)")
|
||||
args = [re.split(' +', v)[1] for v in re.split("\)\s*\(", n1[1:-1])]
|
||||
args = [re.split(r' +', v)[1] for v in re.split(r"\)\s*\(", n1[1:-1])]
|
||||
|
||||
_, expected = parse_assertion_value(n.group(4)[1:-1])
|
||||
test_assert(r, opts, "return", "%s %s" % (func, " ".join(args)), expected)
|
||||
|
||||
def test_assert_trap(r, opts, form):
|
||||
# params
|
||||
m = re.search('^\(assert_trap\s+\(invoke\s+"([^"]*)"\s+(\(.*\))\s*\)\s*"([^"]+)"\s*\)\s*$', form)
|
||||
m = re.search(r'^\(assert_trap\s+\(invoke\s+"([^"]*)"\s+(\(.*\))\s*\)\s*"([^"]+)"\s*\)\s*$', form)
|
||||
# judge if assert_return cmd includes the module name
|
||||
n = re.search('^\(assert_trap\s+\(invoke\s+\$((?:[^\s])*)\s+"([^"]*)"\s+(\(.*\))\s*\)\s*"([^"]+)"\s*\)\s*$', form, re.S)
|
||||
n = re.search(r'^\(assert_trap\s+\(invoke\s+\$((?:[^\s])*)\s+"([^"]*)"\s+(\(.*\))\s*\)\s*"([^"]+)"\s*\)\s*$', form, re.S)
|
||||
if not m:
|
||||
# no params
|
||||
m = re.search('^\(assert_trap\s+\(invoke\s+"([^"]*)"\s*()\)\s*"([^"]+)"\s*\)\s*$', form)
|
||||
m = re.search(r'^\(assert_trap\s+\(invoke\s+"([^"]*)"\s*()\)\s*"([^"]+)"\s*\)\s*$', form)
|
||||
if not m:
|
||||
if not n:
|
||||
# no params
|
||||
n = re.search('^\(assert_trap\s+\(invoke\s+\$((?:[^\s])*)\s+"([^"]*)"\s*()\)\s*"([^"]+)"\s*\)\s*$', form, re.S)
|
||||
n = re.search(r'^\(assert_trap\s+\(invoke\s+\$((?:[^\s])*)\s+"([^"]*)"\s*()\)\s*"([^"]+)"\s*\)\s*$', form, re.S)
|
||||
if not m and not n:
|
||||
raise Exception("unparsed assert_trap: '%s'" % form)
|
||||
|
||||
|
@ -969,7 +979,7 @@ def test_assert_trap(r, opts, form):
|
|||
# convert (ref.null extern/func) into (ref.null null)
|
||||
m1 = m.group(2).replace("(ref.null extern)", "(ref.null null)")
|
||||
m1 = m1.replace("ref.null func)", "(ref.null null)")
|
||||
args = [re.split(' +', v)[1] for v in re.split("\)\s*\(", m1[1:-1])]
|
||||
args = [re.split(r' +', v)[1] for v in re.split(r"\)\s*\(", m1[1:-1])]
|
||||
|
||||
expected = "Exception: %s" % m.group(3)
|
||||
test_assert(r, opts, "trap", "%s %s" % (func, " ".join(args)), expected)
|
||||
|
@ -987,8 +997,7 @@ def test_assert_trap(r, opts, form):
|
|||
except:
|
||||
_, exc, _ = sys.exc_info()
|
||||
log("Run wamrc failed:\n got: '%s'" % r.buf)
|
||||
ret_code = 1
|
||||
sys.exit(1)
|
||||
raise Exception("Run wamrc failed 2")
|
||||
r = run_wasm_with_repl(module+".wasm", module+".aot" if test_aot else module, opts, r)
|
||||
# Wait for the initial prompt
|
||||
try:
|
||||
|
@ -1002,23 +1011,23 @@ def test_assert_trap(r, opts, form):
|
|||
if n.group(3) == '':
|
||||
args = []
|
||||
else:
|
||||
args = [re.split(' +', v)[1] for v in re.split("\)\s*\(", n.group(3)[1:-1])]
|
||||
args = [re.split(r' +', v)[1] for v in re.split(r"\)\s*\(", n.group(3)[1:-1])]
|
||||
expected = "Exception: %s" % n.group(4)
|
||||
test_assert(r, opts, "trap", "%s %s" % (func, " ".join(args)), expected)
|
||||
|
||||
def test_assert_exhaustion(r,opts,form):
|
||||
# params
|
||||
m = re.search('^\(assert_exhaustion\s+\(invoke\s+"([^"]*)"\s+(\(.*\))\s*\)\s*"([^"]+)"\s*\)\s*$', form)
|
||||
m = re.search(r'^\(assert_exhaustion\s+\(invoke\s+"([^"]*)"\s+(\(.*\))\s*\)\s*"([^"]+)"\s*\)\s*$', form)
|
||||
if not m:
|
||||
# no params
|
||||
m = re.search('^\(assert_exhaustion\s+\(invoke\s+"([^"]*)"\s*()\)\s*"([^"]+)"\s*\)\s*$', form)
|
||||
m = re.search(r'^\(assert_exhaustion\s+\(invoke\s+"([^"]*)"\s*()\)\s*"([^"]+)"\s*\)\s*$', form)
|
||||
if not m:
|
||||
raise Exception("unparsed assert_exhaustion: '%s'" % form)
|
||||
func = m.group(1)
|
||||
if m.group(2) == '':
|
||||
args = []
|
||||
else:
|
||||
args = [re.split(' +', v)[1] for v in re.split("\)\s*\(", m.group(2)[1:-1])]
|
||||
args = [re.split(r' +', v)[1] for v in re.split(r"\)\s*\(", m.group(2)[1:-1])]
|
||||
expected = "Exception: %s\n" % m.group(3)
|
||||
test_assert(r, opts, "exhaustion", "%s %s" % (func, " ".join(args)), expected)
|
||||
|
||||
|
@ -1035,7 +1044,7 @@ def test_assert_wasmexception(r,opts,form):
|
|||
# \)\s*
|
||||
# \)\s*
|
||||
# $
|
||||
m = re.search('^\(assert_exception\s+\(invoke\s+"([^"]+)"\s+(\(.*\))\s*\)\s*\)\s*$', form)
|
||||
m = re.search(r'^\(assert_exception\s+\(invoke\s+"([^"]+)"\s+(\(.*\))\s*\)\s*\)\s*$', form)
|
||||
if not m:
|
||||
# no params
|
||||
|
||||
|
@ -1046,24 +1055,24 @@ def test_assert_wasmexception(r,opts,form):
|
|||
# \)\s*
|
||||
# \)\s*
|
||||
# $
|
||||
m = re.search('^\(assert_exception\s+\(invoke\s+"([^"]+)"\s*()\)\s*\)\s*$', form)
|
||||
m = re.search(r'^\(assert_exception\s+\(invoke\s+"([^"]+)"\s*()\)\s*\)\s*$', form)
|
||||
if not m:
|
||||
raise Exception("unparsed assert_exception: '%s'" % form)
|
||||
func = m.group(1) # function name
|
||||
if m.group(2) == '': # arguments
|
||||
args = []
|
||||
else:
|
||||
args = [re.split(' +', v)[1] for v in re.split("\)\s*\(", m.group(2)[1:-1])]
|
||||
args = [re.split(r' +', v)[1] for v in re.split(r"\)\s*\(", m.group(2)[1:-1])]
|
||||
|
||||
expected = "Exception: uncaught wasm exception\n"
|
||||
test_assert(r, opts, "wasmexception", "%s %s" % (func, " ".join(args)), expected)
|
||||
|
||||
def do_invoke(r, opts, form):
|
||||
# params
|
||||
m = re.search('^\(invoke\s+"([^"]+)"\s+(\(.*\))\s*\)\s*$', form)
|
||||
m = re.search(r'^\(invoke\s+"([^"]+)"\s+(\(.*\))\s*\)\s*$', form)
|
||||
if not m:
|
||||
# no params
|
||||
m = re.search('^\(invoke\s+"([^"]+)"\s*()\)\s*$', form)
|
||||
m = re.search(r'^\(invoke\s+"([^"]+)"\s*()\)\s*$', form)
|
||||
if not m:
|
||||
raise Exception("unparsed invoke: '%s'" % form)
|
||||
func = m.group(1)
|
||||
|
@ -1074,7 +1083,7 @@ def do_invoke(r, opts, form):
|
|||
if m.group(2) == '':
|
||||
args = []
|
||||
else:
|
||||
args = [re.split(' +', v)[1] for v in re.split("\)\s*\(", m.group(2)[1:-1])]
|
||||
args = [re.split(r' +', v)[1] for v in re.split(r"\)\s*\(", m.group(2)[1:-1])]
|
||||
|
||||
log("Invoking %s(%s)" % (
|
||||
func, ", ".join([str(a) for a in args])))
|
||||
|
@ -1114,8 +1123,8 @@ def compile_wast_to_wasm(form, wast_tempfile, wasm_tempfile, opts):
|
|||
log("Running: %s" % " ".join(cmd))
|
||||
try:
|
||||
subprocess.check_call(cmd)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(str(e))
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
@ -1238,13 +1247,17 @@ def run_wasm_with_repl(wasm_tempfile, aot_tempfile, opts, r):
|
|||
|
||||
return r
|
||||
|
||||
def create_tmpfiles(wast_name):
|
||||
def create_tmpfiles(file_name, test_aot, temp_file_repo):
|
||||
tempfiles = []
|
||||
|
||||
tempfiles.append(create_tmp_file(".wast"))
|
||||
tempfiles.append(create_tmp_file(".wasm"))
|
||||
tempfiles.append(create_tmp_file(file_name, ".wast"))
|
||||
tempfiles.append(create_tmp_file(file_name, ".wasm"))
|
||||
if test_aot:
|
||||
tempfiles.append(create_tmp_file(".aot"))
|
||||
tempfiles.append(create_tmp_file(file_name, ".aot"))
|
||||
else:
|
||||
tempfiles.append(None)
|
||||
|
||||
assert len(tempfiles) == 3, "tempfiles should have 3 elements"
|
||||
|
||||
# add these temp file to temporal repo, will be deleted when finishing the test
|
||||
temp_file_repo.extend(tempfiles)
|
||||
|
@ -1263,6 +1276,9 @@ def test_assert_with_exception(form, wast_tempfile, wasm_tempfile, aot_tempfile,
|
|||
|
||||
if test_aot:
|
||||
r = compile_wasm_to_aot(wasm_tempfile, aot_tempfile, True, opts, r)
|
||||
if not loadable:
|
||||
return
|
||||
|
||||
try:
|
||||
assert_prompt(r, ['Compile success'], opts.start_fail_timeout, True)
|
||||
except:
|
||||
|
@ -1275,8 +1291,7 @@ def test_assert_with_exception(form, wast_tempfile, wasm_tempfile, aot_tempfile,
|
|||
else:
|
||||
log("Run wamrc failed:\n expected: '%s'\n got: '%s'" % \
|
||||
(expected, r.buf))
|
||||
ret_code = 1
|
||||
sys.exit(1)
|
||||
raise Exception("Run wamrc failed 3")
|
||||
|
||||
r = run_wasm_with_repl(wasm_tempfile, aot_tempfile if test_aot else None, opts, r)
|
||||
|
||||
|
@ -1296,6 +1311,20 @@ def test_assert_with_exception(form, wast_tempfile, wasm_tempfile, aot_tempfile,
|
|||
raise Exception("Failed:\n expected: '%s'\n got: '%s'" % \
|
||||
(expected, r.buf))
|
||||
|
||||
def recently_added_wasm(temp_file_repo):
|
||||
for f in reversed(temp_file_repo):
|
||||
if not f:
|
||||
continue
|
||||
|
||||
assert os.path.exists(f), f"temp file {f} should exist"
|
||||
|
||||
if os.path.getsize(f) == 0:
|
||||
continue
|
||||
|
||||
if f.endswith(".wasm"):
|
||||
return f
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
opts = parser.parse_args(sys.argv[1:])
|
||||
# print('Input param :',opts)
|
||||
|
@ -1314,16 +1343,10 @@ if __name__ == "__main__":
|
|||
else:
|
||||
SKIP_TESTS = C_SKIP_TESTS
|
||||
|
||||
wast_tempfile = create_tmp_file(".wast")
|
||||
wasm_tempfile = create_tmp_file(".wasm")
|
||||
if test_aot:
|
||||
aot_tempfile = create_tmp_file(".aot")
|
||||
# could be potientially compiled to aot
|
||||
# with the future following call test_assert_xxx,
|
||||
# add them to temp_file_repo now even if no actual following file,
|
||||
# it will be simple ignore during final deletion if not exist
|
||||
prefix = wasm_tempfile.split(".wasm")[0]
|
||||
temp_file_repo.append(prefix + ".aot")
|
||||
case_file = pathlib.Path(opts.test_file.name)
|
||||
assert(case_file.exists()), f"Test file {case_file} doesn't exist"
|
||||
|
||||
tmpfile_stem = case_file.stem + "_"
|
||||
|
||||
ret_code = 0
|
||||
try:
|
||||
|
@ -1335,22 +1358,26 @@ if __name__ == "__main__":
|
|||
|
||||
for form in forms:
|
||||
# log("\n### Current Case is " + form + "\n")
|
||||
|
||||
wast_tempfile, wasm_tempfile, aot_tempfile = create_tmpfiles(
|
||||
tmpfile_stem, test_aot, temp_file_repo)
|
||||
|
||||
if ";;" == form[0:2]:
|
||||
log(form)
|
||||
elif skip_test(form, SKIP_TESTS):
|
||||
log("Skipping test: %s" % form[0:60])
|
||||
elif re.match("^\(assert_trap\s+\(module", form):
|
||||
elif re.match(r"^\(assert_trap\s+\(module", form):
|
||||
test_assert_with_exception(form, wast_tempfile, wasm_tempfile, aot_tempfile if test_aot else None, opts, r)
|
||||
elif re.match("^\(assert_exhaustion\\b.*", form):
|
||||
elif re.match(r"^\(assert_exhaustion\b.*", form):
|
||||
test_assert_exhaustion(r, opts, form)
|
||||
elif re.match("^\(assert_exception\\b.*", form):
|
||||
elif re.match(r"^\(assert_exception\b.*", form):
|
||||
test_assert_wasmexception(r, opts, form)
|
||||
elif re.match("^\(assert_unlinkable\\b.*", form):
|
||||
elif re.match(r"^\(assert_unlinkable\b.*", form):
|
||||
test_assert_with_exception(form, wast_tempfile, wasm_tempfile, aot_tempfile if test_aot else None, opts, r, False)
|
||||
elif re.match("^\(assert_malformed\\b.*", form):
|
||||
elif re.match(r"^\(assert_malformed\b.*", form):
|
||||
# remove comments in wast
|
||||
form,n = re.subn(";;.*\n", "", form)
|
||||
m = re.match("^\(assert_malformed\s*\(module binary\s*(\".*\").*\)\s*\"(.*)\"\s*\)$", form, re.DOTALL)
|
||||
m = re.match(r"^\(assert_malformed\s*\(module binary\s*(\".*\").*\)\s*\"(.*)\"\s*\)$", form, re.DOTALL)
|
||||
|
||||
if m:
|
||||
# workaround: spec test changes error message to "malformed" while iwasm still use "invalid"
|
||||
|
@ -1359,7 +1386,7 @@ if __name__ == "__main__":
|
|||
with open(wasm_tempfile, 'wb') as f:
|
||||
s = m.group(1)
|
||||
while s:
|
||||
res = re.match("[^\"]*\"([^\"]*)\"(.*)", s, re.DOTALL)
|
||||
res = re.match(r"[^\"]*\"([^\"]*)\"(.*)", s, re.DOTALL)
|
||||
if IS_PY_3:
|
||||
context = res.group(1).replace("\\", "\\x").encode("latin1").decode("unicode-escape").encode("latin1")
|
||||
f.write(context)
|
||||
|
@ -1414,51 +1441,43 @@ if __name__ == "__main__":
|
|||
else:
|
||||
log("Run wamrc failed:\n expected: '%s'\n got: '%s'" % \
|
||||
(error_msg, r.buf))
|
||||
ret_code = 1
|
||||
sys.exit(1)
|
||||
raise Exception("Run wamrc failed 4")
|
||||
|
||||
r = run_wasm_with_repl(wasm_tempfile, aot_tempfile if test_aot else None, opts, r)
|
||||
|
||||
elif re.match("^\(assert_malformed\s*\(module quote", form):
|
||||
elif re.match(r"^\(assert_malformed\s*\(module quote", form):
|
||||
log("ignoring assert_malformed module quote")
|
||||
else:
|
||||
log("unrecognized assert_malformed")
|
||||
elif re.match("^\(assert_return[_a-z]*_nan\\b.*", form):
|
||||
elif re.match(r"^\(assert_return[_a-z]*_nan\b.*", form):
|
||||
log("ignoring assert_return_.*_nan")
|
||||
pass
|
||||
elif re.match(".*\(invoke\s+\$\\b.*", form):
|
||||
elif re.match(r".*\(invoke\s+\$\b.*", form):
|
||||
# invoke a particular named module's function
|
||||
if form.startswith("(assert_return"):
|
||||
test_assert_return(r,opts,form)
|
||||
elif form.startswith("(assert_trap"):
|
||||
test_assert_trap(r,opts,form)
|
||||
elif re.match("^\(module\\b.*", form):
|
||||
elif re.match(r"^\(module\b.*", form):
|
||||
# if the module includes the particular name startswith $
|
||||
m = re.search("^\(module\s+\$.\S+", form)
|
||||
m = re.search(r"^\(module\s+\$.\S+", form)
|
||||
if m:
|
||||
# get module name
|
||||
module_name = re.split('\$', m.group(0).strip())[1]
|
||||
module_name = re.split(r'\$', m.group(0).strip())[1]
|
||||
if module_name:
|
||||
# create temporal files
|
||||
temp_files = create_tmpfiles(module_name)
|
||||
temp_files = create_tmpfiles(module_name, test_aot, temp_file_repo)
|
||||
if not compile_wast_to_wasm(form, temp_files[0], temp_files[1], opts):
|
||||
raise Exception("compile wast to wasm failed")
|
||||
|
||||
if test_aot:
|
||||
r = compile_wasm_to_aot(temp_files[1], temp_files[2], True, opts, r)
|
||||
# could be potientially compiled to aot
|
||||
# with the future following call test_assert_xxx,
|
||||
# add them to temp_file_repo now even if no actual following file,
|
||||
# it will be simple ignore during final deletion if not exist
|
||||
prefix = temp_files[1].split(".wasm")[0]
|
||||
temp_file_repo.append(prefix + ".aot")
|
||||
try:
|
||||
assert_prompt(r, ['Compile success'], opts.start_timeout, False)
|
||||
except:
|
||||
_, exc, _ = sys.exc_info()
|
||||
log("Run wamrc failed:\n got: '%s'" % r.buf)
|
||||
ret_code = 1
|
||||
sys.exit(1)
|
||||
raise Exception("Run wamrc failed 5")
|
||||
temp_module_table[module_name] = temp_files[1]
|
||||
r = run_wasm_with_repl(temp_files[1], temp_files[2] if test_aot else None, opts, r)
|
||||
else:
|
||||
|
@ -1472,8 +1491,7 @@ if __name__ == "__main__":
|
|||
except:
|
||||
_, exc, _ = sys.exc_info()
|
||||
log("Run wamrc failed:\n got: '%s'" % r.buf)
|
||||
ret_code = 1
|
||||
sys.exit(1)
|
||||
raise Exception("Run wamrc failed 6")
|
||||
|
||||
r = run_wasm_with_repl(wasm_tempfile, aot_tempfile if test_aot else None, opts, r)
|
||||
|
||||
|
@ -1485,38 +1503,51 @@ if __name__ == "__main__":
|
|||
raise Exception("Failed:\n expected: '%s'\n got: '%s'" % \
|
||||
(repr(exc), r.buf))
|
||||
|
||||
elif re.match("^\(assert_return\\b.*", form):
|
||||
elif re.match(r"^\(assert_return\b.*", form):
|
||||
assert(r), "iwasm repl runtime should be not null"
|
||||
test_assert_return(r, opts, form)
|
||||
elif re.match("^\(assert_trap\\b.*", form):
|
||||
elif re.match(r"^\(assert_trap\b.*", form):
|
||||
test_assert_trap(r, opts, form)
|
||||
elif re.match("^\(invoke\\b.*", form):
|
||||
elif re.match(r"^\(invoke\b.*", form):
|
||||
assert(r), "iwasm repl runtime should be not null"
|
||||
do_invoke(r, opts, form)
|
||||
elif re.match("^\(assert_invalid\\b.*", form):
|
||||
test_assert_with_exception(form, wast_tempfile, wasm_tempfile, aot_tempfile if test_aot else None, opts, r)
|
||||
elif re.match("^\(register\\b.*", form):
|
||||
elif re.match(r"^\(assert_invalid\b.*", form):
|
||||
# loading invalid module will raise an error directly, so shell prompt won't show here
|
||||
test_assert_with_exception(form, wast_tempfile, wasm_tempfile, aot_tempfile if test_aot else None, opts, r, False)
|
||||
elif re.match(r"^\(register\b.*", form):
|
||||
# get module's new name from the register cmd
|
||||
name_new =re.split('\"',re.search('\".*\"',form).group(0))[1]
|
||||
if name_new:
|
||||
new_module = os.path.join(tempfile.gettempdir(), name_new + ".wasm")
|
||||
shutil.copyfile(temp_module_table.get(name_new, wasm_tempfile), new_module)
|
||||
|
||||
# add new_module copied from the old into temp_file_repo[]
|
||||
temp_file_repo.append(new_module)
|
||||
|
||||
if test_aot:
|
||||
new_module_aot = os.path.join(tempfile.gettempdir(), name_new + ".aot")
|
||||
r = compile_wasm_to_aot(new_module, new_module_aot, True, opts, r)
|
||||
try:
|
||||
assert_prompt(r, ['Compile success'], opts.start_timeout, True)
|
||||
except:
|
||||
raise Exception("compile wasm to aot failed")
|
||||
# add aot module into temp_file_repo[]
|
||||
temp_file_repo.append(new_module_aot)
|
||||
else:
|
||||
name_new =re.split(r'\"',re.search(r'\".*\"',form).group(0))[1]
|
||||
if not name_new:
|
||||
# there is no name defined in register cmd
|
||||
raise Exception("can not find module name from the register")
|
||||
raise Exception(f"Not following register cmd pattern {form}")
|
||||
|
||||
# assumption
|
||||
# - There exists a module in the form of (module $name).
|
||||
# - The nearest module in the form of (module), without $name, is the candidate for registration.
|
||||
recently_wasm = recently_added_wasm(temp_file_repo)
|
||||
if not name_new in temp_module_table:
|
||||
print(temp_file_repo)
|
||||
print(f"Module {name_new} is not found in temp_module_table. use the nearest module {recently_wasm}")
|
||||
|
||||
for_registration = temp_module_table.get(name_new, recently_wasm)
|
||||
assert os.path.exists(for_registration), f"module {for_registration} is not found"
|
||||
|
||||
new_module = os.path.join(tempfile.gettempdir(), name_new + ".wasm")
|
||||
# for_registration(tmpfile) --copy-> name_new.wasm
|
||||
shutil.copyfile(for_registration, new_module)
|
||||
|
||||
# add new_module copied from the old into temp_file_repo[]
|
||||
temp_file_repo.append(new_module)
|
||||
|
||||
if test_aot:
|
||||
new_module_aot = os.path.join(tempfile.gettempdir(), name_new + ".aot")
|
||||
r = compile_wasm_to_aot(new_module, new_module_aot, True, opts, r)
|
||||
try:
|
||||
assert_prompt(r, ['Compile success'], opts.start_timeout, True)
|
||||
except:
|
||||
raise Exception("compile wasm to aot failed")
|
||||
# add aot module into temp_file_repo[]
|
||||
temp_file_repo.append(new_module_aot)
|
||||
else:
|
||||
raise Exception("unrecognized form '%s...'" % form[0:40])
|
||||
except Exception as e:
|
||||
|
@ -1524,35 +1555,42 @@ if __name__ == "__main__":
|
|||
print("THE FINAL EXCEPTION IS {}".format(e))
|
||||
ret_code = 101
|
||||
|
||||
shutil.copyfile(wasm_tempfile, os.path.join(opts.log_dir, os.path.basename(wasm_tempfile)))
|
||||
|
||||
if opts.aot or opts.xip:
|
||||
shutil.copyfile(aot_tempfile, os.path.join(opts.log_dir,os.path.basename(aot_tempfile)))
|
||||
if "indirect-mode" in str(e):
|
||||
compile_wasm_to_aot(wasm_tempfile, aot_tempfile, None, opts, None, "object")
|
||||
shutil.copyfile(aot_tempfile, os.path.join(opts.log_dir,os.path.basename(aot_tempfile)+'.o'))
|
||||
subprocess.check_call(["llvm-objdump", "-r", aot_tempfile])
|
||||
compile_wasm_to_aot(wasm_tempfile, aot_tempfile, None, opts, None, "ir")
|
||||
shutil.copyfile(aot_tempfile, os.path.join(opts.log_dir,os.path.basename(aot_tempfile)+".ir"))
|
||||
try:
|
||||
shutil.copyfile(wasm_tempfile, os.path.join(opts.log_dir, os.path.basename(wasm_tempfile)))
|
||||
|
||||
if opts.aot or opts.xip:
|
||||
shutil.copyfile(aot_tempfile, os.path.join(opts.log_dir,os.path.basename(aot_tempfile)))
|
||||
if "indirect-mode" in str(e):
|
||||
compile_wasm_to_aot(wasm_tempfile, aot_tempfile, None, opts, None, "object")
|
||||
shutil.copyfile(aot_tempfile, os.path.join(opts.log_dir,os.path.basename(aot_tempfile)+'.o'))
|
||||
subprocess.check_call(["llvm-objdump", "-r", aot_tempfile])
|
||||
compile_wasm_to_aot(wasm_tempfile, aot_tempfile, None, opts, None, "ir")
|
||||
shutil.copyfile(aot_tempfile, os.path.join(opts.log_dir,os.path.basename(aot_tempfile)+".ir"))
|
||||
except Exception as e:
|
||||
print("Failed to copy files to log directory: %s" % e)
|
||||
ret_code = 102
|
||||
else:
|
||||
ret_code = 0
|
||||
finally:
|
||||
if not opts.no_cleanup:
|
||||
log("Removing tempfiles")
|
||||
os.remove(wast_tempfile)
|
||||
os.remove(wasm_tempfile)
|
||||
if test_aot:
|
||||
os.remove(aot_tempfile)
|
||||
try:
|
||||
if not opts.no_cleanup:
|
||||
# remove the files under /tempfiles/ and copy of .wasm files
|
||||
log(f"Removing {temp_file_repo}")
|
||||
|
||||
# remove the files under /tempfiles/ and copy of .wasm files
|
||||
if temp_file_repo:
|
||||
for t in temp_file_repo:
|
||||
if(len(str(t))!=0 and os.path.exists(t)):
|
||||
# None and empty
|
||||
if not t:
|
||||
continue
|
||||
|
||||
if os.path.exists(t):
|
||||
os.remove(t)
|
||||
else:
|
||||
log(f"Leaving {temp_file_repo}")
|
||||
|
||||
log("### End testing %s" % opts.test_file.name)
|
||||
else:
|
||||
log("Leaving tempfiles: %s" % ([wast_tempfile, wasm_tempfile]))
|
||||
except Exception as e:
|
||||
print("Failed to remove tempfiles: %s" % e)
|
||||
# ignore the exception
|
||||
ret_code = 0
|
||||
|
||||
log(f"### End testing {opts.test_file.name} with {ret_code}")
|
||||
sys.exit(ret_code)
|
||||
|
|
|
@ -448,9 +448,9 @@ function spec_test()
|
|||
|
||||
# May 31, 2012 [interpreter] implement atomic.wait and atomic.notify (#194)
|
||||
git reset --hard 09f2831349bf409187abb6f7868482a8079f2264
|
||||
git apply ../../spec-test-script/thread_proposal_ignore_cases.patch || exit 1
|
||||
git apply ../../spec-test-script/thread_proposal_fix_atomic_case.patch || exit 1
|
||||
git apply ../../spec-test-script/thread_proposal_remove_memory64_flag_case.patch
|
||||
git apply --ignore-whitespace ../../spec-test-script/thread_proposal_ignore_cases.patch || exit 1
|
||||
git apply --ignore-whitespace ../../spec-test-script/thread_proposal_fix_atomic_case.patch || exit 1
|
||||
git apply --ignore-whitespace ../../spec-test-script/thread_proposal_remove_memory64_flag_case.patch
|
||||
elif [ ${ENABLE_EH} == 1 ]; then
|
||||
echo "checkout exception-handling test cases"
|
||||
|
||||
|
@ -459,7 +459,7 @@ function spec_test()
|
|||
|
||||
# Jun 6, 2023 Merge branch 'upstream' into merge-upstream
|
||||
git reset --hard 51c721661b671bb7dc4b3a3acb9e079b49778d36
|
||||
git apply ../../spec-test-script/exception_handling.patch || exit 1
|
||||
git apply --ignore-whitespace ../../spec-test-script/exception_handling.patch || exit 1
|
||||
elif [[ ${ENABLE_GC} == 1 ]]; then
|
||||
echo "checkout spec for GC proposal"
|
||||
|
||||
|
@ -469,12 +469,12 @@ function spec_test()
|
|||
|
||||
# Dec 9, 2024. Merge branch 'funcref'
|
||||
git reset --hard 756060f5816c7e2159f4817fbdee76cf52f9c923
|
||||
git apply ../../spec-test-script/gc_ignore_cases.patch || exit 1
|
||||
git apply --ignore-whitespace ../../spec-test-script/gc_ignore_cases.patch || exit 1
|
||||
|
||||
if [[ ${ENABLE_QEMU} == 1 ]]; then
|
||||
# Decrease the recursive count for tail call cases as nuttx qemu's
|
||||
# native stack size is much smaller
|
||||
git apply ../../spec-test-script/gc_nuttx_tail_call.patch || exit 1
|
||||
git apply --ignore-whitespace ../../spec-test-script/gc_nuttx_tail_call.patch || exit 1
|
||||
fi
|
||||
|
||||
# As of version 1.0.36, wabt is still unable to correctly handle the GC proposal.
|
||||
|
@ -497,7 +497,7 @@ function spec_test()
|
|||
git checkout 044d0d2e77bdcbe891f7e0b9dd2ac01d56435f0b -- test/core/elem.wast test/core/data.wast
|
||||
# Patch table64 extension
|
||||
git checkout 940398cd4823522a9b36bec4984be4b153dedb81 -- test/core/call_indirect.wast test/core/table.wast test/core/table_copy.wast test/core/table_copy_mixed.wast test/core/table_fill.wast test/core/table_get.wast test/core/table_grow.wast test/core/table_init.wast test/core/table_set.wast test/core/table_size.wast
|
||||
git apply ../../spec-test-script/memory64_ignore_cases.patch || exit 1
|
||||
git apply --ignore-whitespace ../../spec-test-script/memory64_ignore_cases.patch || exit 1
|
||||
elif [[ ${ENABLE_MULTI_MEMORY} == 1 ]]; then
|
||||
echo "checkout spec for multi memory proposal"
|
||||
|
||||
|
@ -508,9 +508,9 @@ function spec_test()
|
|||
# Reset to commit: "Merge pull request #48 from backes/specify-memcpy-immediate-order"
|
||||
git reset --hard fbc99efd7a788db300aec3dd62a14577ec404f1b
|
||||
git checkout 044d0d2e77bdcbe891f7e0b9dd2ac01d56435f0b -- test/core/elem.wast
|
||||
git apply ../../spec-test-script/multi_memory_ignore_cases.patch || exit 1
|
||||
git apply --ignore-whitespace ../../spec-test-script/multi_memory_ignore_cases.patch || exit 1
|
||||
if [[ ${RUNNING_MODE} == "aot" ]]; then
|
||||
git apply ../../spec-test-script/multi_module_aot_ignore_cases.patch || exit 1
|
||||
git apply --ignore-whitespace ../../spec-test-script/multi_module_aot_ignore_cases.patch || exit 1
|
||||
fi
|
||||
else
|
||||
echo "checkout spec for default proposal"
|
||||
|
@ -520,15 +520,15 @@ function spec_test()
|
|||
|
||||
# Dec 20, 2024. Use WPT version of test harness for HTML core test conversion (#1859)
|
||||
git reset --hard f3a0e06235d2d84bb0f3b5014da4370613886965
|
||||
git apply ../../spec-test-script/ignore_cases.patch || exit 1
|
||||
git apply --ignore-whitespace ../../spec-test-script/ignore_cases.patch || exit 1
|
||||
if [[ ${ENABLE_SIMD} == 1 ]]; then
|
||||
git apply ../../spec-test-script/simd_ignore_cases.patch || exit 1
|
||||
git apply --ignore-whitespace ../../spec-test-script/simd_ignore_cases.patch || exit 1
|
||||
fi
|
||||
if [[ ${ENABLE_MULTI_MODULE} == 1 ]]; then
|
||||
git apply ../../spec-test-script/multi_module_ignore_cases.patch || exit 1
|
||||
git apply --ignore-whitespace ../../spec-test-script/multi_module_ignore_cases.patch || exit 1
|
||||
|
||||
if [[ ${RUNNING_MODE} == "aot" ]]; then
|
||||
git apply ../../spec-test-script/multi_module_aot_ignore_cases.patch || exit 1
|
||||
git apply --ignore-whitespace ../../spec-test-script/multi_module_aot_ignore_cases.patch || exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
|
Loading…
Reference in New Issue
Block a user