|  | #!/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))) |