Detect timeouts

extensions
Volodymyr Shymanskyy 5 years ago
parent a49639db41
commit df838aacd5

@ -13,13 +13,9 @@
# - Fix "Empty Stack" check
# - Check Canonical NaN and Arithmetic NaN separately
# - Fix names.wast
# - Detect timeout (hangs)
import argparse
import os
import os.path
import glob
import sys
import os, sys, glob, time
import json
import re
import struct
@ -186,14 +182,15 @@ class Wasm3():
def __init__(self, executable):
self.exe = executable
self.p = None
self.timeout = 3.0
def load(self, wasm):
def load(self, fn):
if self.p:
self.terminate()
self.wasm = wasm
self.loaded = fn
self.p = Popen(
[self.exe, "--repl", wasm],
[self.exe, "--repl", fn],
shell = False,
bufsize=0, stdin=PIPE, stdout=PIPE, stderr=STDOUT
)
@ -212,26 +209,31 @@ class Wasm3():
cmd = " ".join(map(str, cmd)) + "\n"
self._flush_input()
self._write(cmd)
res = self._read_until("\nwasm3> ")
#print("INVOKE", cmd, "=>", res)
return res
return self._read_until("\nwasm3> ")
def _read_until(self, token):
buff = ""
while True:
tout = time.time() + self.timeout
error = None
while time.time() < tout:
try:
data = self.q.get(timeout=0.2)
data = self.q.get(timeout=0.1)
if data == None:
error = "Crashed"
break
buff = buff + data.decode("utf-8")
if token in buff:
return buff
idx = buff.rfind(token)
if idx >= 0:
return buff[0:idx]
except Empty:
pass
else:
error = "Timeout"
# Crash => restart
self.load(self.wasm)
raise Exception("Crashed")
self.load(self.loaded)
raise Exception(error)
def _write(self, data):
if not self._is_running():
@ -282,10 +284,9 @@ blacklist = Blacklist([
"linking.wast:*",
"exports.wast:*",
"names.wast:*",
#"names.wast:608*",
])
stats = dotdict(total_run=0, skipped=0, failed=0, crashed=0, success=0, missing=0)
stats = dotdict(total_run=0, skipped=0, failed=0, crashed=0, timeout=0, success=0, missing=0)
# Convert some trap names from the original spec
trapmap = {
@ -300,7 +301,7 @@ def runInvoke(test):
test.cmd.append(arg['value'])
displayArgs.append(formatValue(arg['value'], arg['type']))
test_id = f"{test.source} {' '.join(test.cmd)}"
test_id = f"{test.source} -> {test.wasm} {' '.join(test.cmd)}"
if test_id in blacklist:
warning(f"Skipping {test_id}")
stats.skipped += 1
@ -317,7 +318,7 @@ def runInvoke(test):
try:
output = wasm3.invoke(test.cmd).strip()
except Exception as e:
stats.crashed += 1
output = ""
actual = f"<{e}>"
# Parse the actual output
@ -340,6 +341,10 @@ def runInvoke(test):
if actual == "error no operation ()":
actual = "<Not Implemented>"
stats.missing += 1
elif actual == "<Crashed>":
stats.crashed += 1
elif actual == "<Timeout>":
stats.timeout += 1
# Prepare the expected result
expect = None
@ -379,14 +384,13 @@ def runInvoke(test):
print(" ----------------------")
print(f"Test: {ansi.HEADER}{test.source}{ansi.ENDC} -> {' '.join(test.cmd)}")
print(f"Args: {', '.join(displayArgs)}")
#print(f"RetCode: {wasm3.returncode}")
print(f"Expected: {ansi.OKGREEN}{expect}{ansi.ENDC}")
print(f"Actual: {ansi.WARNING}{actual}{ansi.ENDC}")
if args.show_logs and len(output):
print(f"Log:")
print(output)
log.write(f"{test.source}\t|\t{filename(wasm)} {test.action.field}({', '.join(displayArgs)})\t=>\t\t")
log.write(f"{test.source}\t|\t{test.wasm} {test.action.field}({', '.join(displayArgs)})\t=>\t\t")
if actual == expect or (expect == "<Anything>" and actual != "<Crashed>"):
stats.success += 1
log.write(f"OK: {actual}\n")
@ -453,6 +457,7 @@ for fn in jsonFiles:
data = json.load(f)
wast_source = filename(data["source_filename"])
wast_module = ""
print(f"Running {fn}")
@ -460,13 +465,14 @@ for fn in jsonFiles:
test = dotdict()
test.line = int(cmd["line"])
test.source = wast_source + ":" + str(test.line)
test.wasm = wast_module
test.type = cmd["type"]
if test.type == "module":
module = cmd["filename"]
wast_module = cmd["filename"]
wasm = os.path.relpath(os.path.join(coreDir, module), curDir)
wasm3.load(wasm)
fn = os.path.relpath(os.path.join(coreDir, wast_module), curDir)
wasm3.load(fn)
elif ( test.type == "action" or
test.type == "assert_return" or

Loading…
Cancel
Save