#!/usr/bin/env python2 #===- subzero/wasm-run-torture-tests.py - Subzero WASM Torture Test Driver ===// # # The Subzero Code Generator # # This file is distributed under the University of Illinois Open Source # License. See LICENSE.TXT for details. # #===-----------------------------------------------------------------------===// from __future__ import print_function import argparse import glob import multiprocessing import os import Queue import shutil import StringIO import sys import threading IGNORED_TESTS = set([ # The remaining tests are known waterfall failures '20010122-1.c.wasm', '20031003-1.c.wasm', '20071018-1.c.wasm', '20071120-1.c.wasm', '20071220-1.c.wasm', '20071220-2.c.wasm', '20101011-1.c.wasm', 'alloca-1.c.wasm', 'bitfld-3.c.wasm', 'bitfld-5.c.wasm', 'builtin-bitops-1.c.wasm', 'conversion.c.wasm', 'eeprof-1.c.wasm', 'frame-address.c.wasm', 'pr17377.c.wasm', 'pr32244-1.c.wasm', 'pr34971.c.wasm', 'pr36765.c.wasm', 'pr39228.c.wasm', 'pr43008.c.wasm', 'pr47237.c.wasm', 'pr60960.c.wasm', 'va-arg-pack-1.c.wasm', '20000717-5.c.wasm', # abort() (also works without emcc) '20001203-2.c.wasm', # assert fail (works without emcc) '20040811-1.c.wasm', # OOB trap '20070824-1.c.wasm', # abort() (also works without emcc) 'arith-rand-ll.c.wasm', # abort() (works without emcc) 'arith-rand.c.wasm', # abort() (works without emcc) 'pr23135.c.wasm', # OOB trap (works without emcc) 'pr34415.c.wasm', # (empty output?) 'pr36339.c.wasm', # abort() (works without emcc) 'pr38048-2.c.wasm', # abort() (works without emcc) 'pr42691.c.wasm', # abort() (works without emcc) 'pr43220.c.wasm', # OOB trap (works without emcc) 'pr43269.c.wasm', # abort() (works without emcc) 'vla-dealloc-1.c.wasm', # OOB trap (works without emcc) '20051012-1.c.wasm', # error reading binary '921208-2.c.wasm', # error reading binary '920501-1.c.wasm', # error reading binary 'call-trap-1.c.wasm', # error reading binary 'pr44942.c.wasm', # error reading binary '920625-1.c.wasm', # abort() (also fails without emcc) '931004-10.c.wasm', # abort() (also fails without emcc) '931004-12.c.wasm', # abort() (also fails without emcc) '931004-14.c.wasm', # abort() (also fails without emcc) '931004-6.c.wasm', # abort() (also fails without emcc) 'pr38051.c.wasm', # (empty output?) (fails without emcc) 'pr38151.c.wasm', # abort() (fails without emcc) 'pr44575.c.wasm', # abort() (fails without emcc) 'strct-stdarg-1.c.wasm', # abort() (fails without emcc) 'strct-varg-1.c.wasm', # abort() (fails without emcc) 'va-arg-22.c.wasm', # abort() (fails without emcc) 'stdarg-3.c.wasm', # abort() (fails without emcc) 'pr56982.c.wasm', # missing setjmp (wasm.js check did not catch) '20010605-2.c.wasm', # missing __netf2 '20020413-1.c.wasm', # missing __lttf2 '20030914-1.c.wasm', # missing __floatsitf '20040709-1.c.wasm', # missing __netf2 '20040709-2.c.wasm', # missing __netf2 '20050121-1.c.wasm', # missing __floatsitf '20080502-1.c.wasm', # missing __eqtf2 '920501-8.c.wasm', # missing __extenddftf2 '930513-1.c.wasm', # missing __extenddftf2 '930622-2.c.wasm', # missing __floatditf '960215-1.c.wasm', # missing __addtf3 '960405-1.c.wasm', # missing __eqtf2 '960513-1.c.wasm', # missing __subtf3 'align-2.c.wasm', # missing __eqtf2 'complex-6.c.wasm', # missing __subtf3 'complex-7.c.wasm', # missing __netf2 'pr49218.c.wasm', # missing __fixsfti 'pr54471.c.wasm', # missing __multi3 'regstack-1.c.wasm', # missing __addtf3 'stdarg-1.c.wasm', # missing __netf2 'stdarg-2.c.wasm', # missing __floatsitf 'va-arg-5.c.wasm', # missing __eqtf2 'va-arg-6.c.wasm', # missing __eqtf2 'struct-ret-1.c.wasm', # missing __extenddftf2 ]) parser = argparse.ArgumentParser() parser.add_argument('-v', '--verbose', action='store_true') parser.add_argument('--translate-only', action='store_true') parser.add_argument('tests', nargs='*') args = parser.parse_args() OUT_DIR = "./build/wasm-torture" results_lock = threading.Lock() compile_count = 0 compile_failures = [] run_count = 0 run_failures = [] def run_test(test_file, verbose=False): global args global compile_count global compile_failures global results_lock global run_count global run_failures global OUT_DIR global IGNORED_TESTS run_test = not args.translate_only test_name = os.path.basename(test_file) obj_file = os.path.join(OUT_DIR, test_name + ".o") exe_file = os.path.join(OUT_DIR, test_name + ".exe") if not verbose and test_name in IGNORED_TESTS: print("\033[1;34mSkipping {}\033[1;m".format(test_file)) return cmd = """LD_LIBRARY_PATH=../../../../v8/out/native/lib.target ./pnacl-sz \ -filetype=obj -target=x8632 {} -threads=0 -O2 \ -verbose=wasm -o {}""".format(test_file, obj_file) if not verbose: cmd += " &> /dev/null" out = StringIO.StringIO() out.write(test_file + " ..."); status = os.system(cmd); if status != 0: print('\033[1;31m[compile fail]\033[1;m', file=out) with results_lock: compile_failures.append(test_file) else: compile_count += 1 # Try to link and run the program. cmd = "clang -g -m32 {} -o {} " + \ "./runtime/szrt.c ./runtime/wasm-runtime.cpp -lm -lstdc++" cmd = cmd.format(obj_file, exe_file) if not run_test or os.system(cmd) == 0: if not run_test or os.system(exe_file) == 0: with results_lock: run_count += 1 print('\033[1;32m[ok]\033[1;m', file=out) else: with results_lock: run_failures.append(test_file) print('\033[1;33m[run fail]\033[1;m', file=out) else: with results_lock: run_failures.append(test_file) print('\033[1;33m[run fail]\033[1;m', file=out) sys.stdout.write(out.getvalue()) verbose = args.verbose if len(args.tests) > 0: test_files = args.tests else: test_files = glob.glob("./emwasm-torture-out/*.wasm") if os.path.exists(OUT_DIR): shutil.rmtree(OUT_DIR) os.mkdir(OUT_DIR) tasks = Queue.Queue() def worker(): while True: run_test(tasks.get(), verbose) tasks.task_done() for i in range(multiprocessing.cpu_count()): t = threading.Thread(target=worker) t.daemon = True t.start() for test_file in test_files: tasks.put(test_file) tasks.join() if len(compile_failures) > 0: print() print("Compilation failures:") print("=====================\n") for f in compile_failures: print(" \033[1;31m" + f + "\033[1;m") if len(run_failures) > 0: print() print("Run failures:") print("=============\n") for f in run_failures: print(" \033[1;33m" + f + "\033[1;m") print("\n\033[1;32m{}\033[1;m / \033[1;33m{}\033[1;m / {} tests passed" .format(run_count, compile_count - run_count, run_count + len(compile_failures) + len(run_failures)))