diff options
-rwxr-xr-x | check.py | 788 |
1 files changed, 408 insertions, 380 deletions
@@ -39,136 +39,66 @@ if options.interpreter: # tests -print '[ checking --help is useful... ]\n' - -not_executable_suffix = ['.txt', '.js', '.ilk', '.pdb', '.dll'] -executables = sorted(filter(lambda x: not any(x.endswith(s) for s in - not_executable_suffix) and os.path.isfile(x), - os.listdir(options.binaryen_bin))) -for e in executables: - print '.. %s --help' % e - out, err = subprocess.Popen([os.path.join(options.binaryen_bin, e), '--help'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE).communicate() - assert len(out) == 0, 'Expected no stdout, got:\n%s' % out - assert e.replace('.exe', '') in err, 'Expected help to contain program name, got:\n%s' % err - assert len(err.split('\n')) > 8, 'Expected some help, got:\n%s' % err - -print '\n[ checking wasm-opt -o notation... ]\n' - -wast = os.path.join(options.binaryen_test, 'hello_world.wast') -delete_from_orbit('a.wast') -cmd = WASM_OPT + [wast, '-o', 'a.wast', '-S'] -run_command(cmd) -fail_if_not_identical(open('a.wast').read(), open(wast).read()) - -print '\n[ checking wasm-opt binary reading/writing... ]\n' - -shutil.copyfile(os.path.join(options.binaryen_test, 'hello_world.wast'), 'a.wast') -delete_from_orbit('a.wasm') -delete_from_orbit('b.wast') -run_command(WASM_OPT + ['a.wast', '-o', 'a.wasm']) -assert open('a.wasm', 'rb').read()[0] == '\0', 'we emit binary by default' -run_command(WASM_OPT + ['a.wasm', '-o', 'b.wast', '-S']) -assert open('b.wast', 'rb').read()[0] != '\0', 'we emit text with -S' - -print '\n[ checking wasm-opt passes... ]\n' - -for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'passes'))): - if t.endswith(('.wast', '.wasm')): - print '..', t - binary = '.wasm' in t - passname = os.path.basename(t).replace('.wast', '').replace('.wasm', '') - opts = [('--' + p if not p.startswith('O') else '-' + p) for p in passname.split('_')] - t = os.path.join(options.binaryen_test, 'passes', t) - actual = '' - for module, asserts in split_wast(t): - assert len(asserts) == 0 - with open('split.wast', 'w') as o: o.write(module) - cmd = WASM_OPT + opts + ['split.wast', '--print'] - curr = run_command(cmd) - actual += curr - # also check debug mode output is valid - debugged = run_command(cmd + ['--debug'], stderr=subprocess.PIPE) - fail_if_not_contained(actual, debugged) - # also check pass-debug mode - old_pass_debug = os.environ.get('BINARYEN_PASS_DEBUG') - try: - os.environ['BINARYEN_PASS_DEBUG'] = '1' - pass_debug = run_command(cmd) - fail_if_not_identical(curr, pass_debug) - finally: - if old_pass_debug is not None: - os.environ['BINARYEN_PASS_DEBUG'] = old_pass_debug - else: - if 'BINARYEN_PASS_DEBUG' in os.environ: - del os.environ['BINARYEN_PASS_DEBUG'] - - fail_if_not_identical(actual, open(os.path.join('test', 'passes', passname + ('.bin' if binary else '') + '.txt'), 'rb').read()) - - if 'emit-js-wrapper' in t: - with open('a.js') as actual: - with open(t + '.js') as expected: - fail_if_not_identical(actual.read(), expected.read()) - if 'emit-spec-wrapper' in t: - with open('a.wat') as actual: - with open(t + '.wat') as expected: - fail_if_not_identical(actual.read(), expected.read()) - -print '[ checking asm2wasm testcases... ]\n' - -for asm in tests: - if asm.endswith('.asm.js'): - for precise in [0, 1, 2]: - for opts in [1, 0]: - cmd = ASM2WASM + [os.path.join(options.binaryen_test, asm)] - wasm = asm.replace('.asm.js', '.fromasm') - if not precise: - cmd += ['--emit-potential-traps', '--ignore-implicit-traps'] - wasm += '.imprecise' - elif precise == 2: - cmd += ['--emit-clamped-potential-traps'] - wasm += '.clamp' - if not opts: - wasm += '.no-opts' - if precise: - cmd += ['-O0'] # test that -O0 does nothing - else: - cmd += ['-O'] - if 'debugInfo' in asm: - cmd += ['-g'] - if 'noffi' in asm: - cmd += ['--no-legalize-javascript-ffi'] - if precise and opts: - # test mem init importing - open('a.mem', 'wb').write(asm) - cmd += ['--mem-init=a.mem'] - if asm[0] == 'e': - cmd += ['--mem-base=1024'] - if 'i64' in asm or 'wasm-only' in asm or 'noffi' in asm: - cmd += ['--wasm-only'] - wasm = os.path.join(options.binaryen_test, wasm) - print '..', asm, wasm - - def do_asm2wasm_test(): - actual = run_command(cmd) - - # verify output - if not os.path.exists(wasm): - fail_with_error('output .wast file %s does not exist' % wasm) - expected = open(wasm, 'rb').read() - if actual != expected: - fail(actual, expected) - - binary_format_check(wasm, verify_final_result=False) - - # test both normally and with pass debug (so each inter-pass state is validated) +def run_help_tests(): + print '[ checking --help is useful... ]\n' + + not_executable_suffix = ['.txt', '.js', '.ilk', '.pdb', '.dll'] + executables = sorted(filter(lambda x: not any(x.endswith(s) for s in + not_executable_suffix) and os.path.isfile(x), + os.listdir(options.binaryen_bin))) + for e in executables: + print '.. %s --help' % e + out, err = subprocess.Popen([os.path.join(options.binaryen_bin, e), '--help'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE).communicate() + assert len(out) == 0, 'Expected no stdout, got:\n%s' % out + assert e.replace('.exe', '') in err, 'Expected help to contain program name, got:\n%s' % err + assert len(err.split('\n')) > 8, 'Expected some help, got:\n%s' % err + +def run_wasm_opt_tests(): + print '\n[ checking wasm-opt -o notation... ]\n' + + wast = os.path.join(options.binaryen_test, 'hello_world.wast') + delete_from_orbit('a.wast') + cmd = WASM_OPT + [wast, '-o', 'a.wast', '-S'] + run_command(cmd) + fail_if_not_identical(open('a.wast').read(), open(wast).read()) + + print '\n[ checking wasm-opt binary reading/writing... ]\n' + + shutil.copyfile(os.path.join(options.binaryen_test, 'hello_world.wast'), 'a.wast') + delete_from_orbit('a.wasm') + delete_from_orbit('b.wast') + run_command(WASM_OPT + ['a.wast', '-o', 'a.wasm']) + assert open('a.wasm', 'rb').read()[0] == '\0', 'we emit binary by default' + run_command(WASM_OPT + ['a.wasm', '-o', 'b.wast', '-S']) + assert open('b.wast', 'rb').read()[0] != '\0', 'we emit text with -S' + + print '\n[ checking wasm-opt passes... ]\n' + + for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'passes'))): + if t.endswith(('.wast', '.wasm')): + print '..', t + binary = '.wasm' in t + passname = os.path.basename(t).replace('.wast', '').replace('.wasm', '') + opts = [('--' + p if not p.startswith('O') else '-' + p) for p in passname.split('_')] + t = os.path.join(options.binaryen_test, 'passes', t) + actual = '' + for module, asserts in split_wast(t): + assert len(asserts) == 0 + with open('split.wast', 'w') as o: o.write(module) + cmd = WASM_OPT + opts + ['split.wast', '--print'] + curr = run_command(cmd) + actual += curr + # also check debug mode output is valid + debugged = run_command(cmd + ['--debug'], stderr=subprocess.PIPE) + fail_if_not_contained(actual, debugged) + # also check pass-debug mode old_pass_debug = os.environ.get('BINARYEN_PASS_DEBUG') try: os.environ['BINARYEN_PASS_DEBUG'] = '1' - do_asm2wasm_test() - del os.environ['BINARYEN_PASS_DEBUG'] - do_asm2wasm_test() + pass_debug = run_command(cmd) + fail_if_not_identical(curr, pass_debug) finally: if old_pass_debug is not None: os.environ['BINARYEN_PASS_DEBUG'] = old_pass_debug @@ -176,152 +106,228 @@ for asm in tests: if 'BINARYEN_PASS_DEBUG' in os.environ: del os.environ['BINARYEN_PASS_DEBUG'] - # verify in wasm - if options.interpreter: - # remove imports, spec interpreter doesn't know what to do with them - subprocess.check_call(WASM_OPT + ['--remove-imports', wasm], stdout=open('ztemp.wast', 'w'), stderr=subprocess.PIPE) - proc = subprocess.Popen([options.interpreter, 'ztemp.wast'], stderr=subprocess.PIPE) - out, err = proc.communicate() - if proc.returncode != 0: - try: # to parse the error - reported = err.split(':')[1] - start, end = reported.split('-') - start_line, start_col = map(int, start.split('.')) - lines = open('ztemp.wast').read().split('\n') - print - print '='*80 - print lines[start_line-1] - print (' '*(start_col-1)) + '^' - print (' '*(start_col-2)) + '/_\\' - print '='*80 - print err - except Exception, e: - fail_with_error('wasm interpreter error: ' + err) # failed to pretty-print - fail_with_error('wasm interpreter error') - - # verify debug info - if 'debugInfo' in asm: - jsmap = 'a.wasm.map' - cmd += ['--source-map', jsmap, - '--source-map-url', 'http://example.org/' + jsmap, - '-o', 'a.wasm'] - run_command(cmd) - if not os.path.isfile(jsmap): - fail_with_error('Debug info map not created: %s' % jsmap) - with open(wasm + '.map', 'rb') as expected: - with open(jsmap, 'rb') as actual: - fail_if_not_identical(actual.read(), expected.read()) - with open('a.wasm', 'rb') as binary: - url_section_name = bytearray([16]) + bytearray('sourceMappingURL') - payload = 'http://example.org/' + jsmap - assert len(payload) < 256, 'name too long' - url_section_contents = bytearray([len(payload)]) + bytearray(payload) - print url_section_name - binary_contents = bytearray(binary.read()) - if url_section_name not in binary_contents: - fail_with_error('source map url section not found in binary') - if url_section_contents not in binary_contents[binary_contents.index(url_section_name):]: - fail_with_error('source map url not found in url section') - - -print '\n[ checking asm2wasm binary reading/writing... ]\n' - -asmjs = os.path.join(options.binaryen_test, 'hello_world.asm.js') -delete_from_orbit('a.wasm') -delete_from_orbit('b.wast') -run_command(ASM2WASM + [asmjs, '-o', 'a.wasm']) -assert open('a.wasm', 'rb').read()[0] == '\0', 'we emit binary by default' -run_command(ASM2WASM + [asmjs, '-o', 'b.wast', '-S']) -assert open('b.wast', 'rb').read()[0] != '\0', 'we emit text with -S' - -print '\n[ checking wasm-opt parsing & printing... ]\n' - -for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'print'))): - if t.endswith('.wast'): - print '..', t - wasm = os.path.basename(t).replace('.wast', '') - cmd = WASM_OPT + [os.path.join(options.binaryen_test, 'print', t), '--print'] - print ' ', ' '.join(cmd) - actual, err = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() - fail_if_not_identical(actual, open(os.path.join(options.binaryen_test, 'print', wasm + '.txt')).read()) - cmd = WASM_OPT + [os.path.join(options.binaryen_test, 'print', t), '--print-minified'] - print ' ', ' '.join(cmd) - actual, err = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() - fail_if_not_identical(actual.strip(), open(os.path.join(options.binaryen_test, 'print', wasm + '.minified.txt')).read().strip()) - -print '\n[ checking wasm-opt testcases... ]\n' - -for t in tests: - if t.endswith('.wast') and not t.startswith('spec'): - print '..', t - t = os.path.join(options.binaryen_test, t) - f = t + '.from-wast' - cmd = WASM_OPT + [t, '--print'] - actual = run_command(cmd) - actual = actual.replace('printing before:\n', '') - - expected = open(f, 'rb').read() - if actual != expected: - fail(actual, expected) - - binary_format_check(t, wasm_as_args=['-g']) # test with debuginfo - binary_format_check(t, wasm_as_args=[], binary_suffix='.fromBinary.noDebugInfo') # test without debuginfo - - minify_check(t) - -print '\n[ checking wasm-dis on provided binaries... ]\n' - -for t in tests: - if t.endswith('.wasm') and not t.startswith('spec'): - print '..', t - t = os.path.join(options.binaryen_test, t) - cmd = WASM_DIS + [t] - if os.path.isfile(t + '.map'): cmd += ['--source-map', t + '.map'] - - actual = run_command(cmd) - - with open(t + '.fromBinary') as f: - expected = f.read() + fail_if_not_identical(actual, open(os.path.join('test', 'passes', passname + ('.bin' if binary else '') + '.txt'), 'rb').read()) + + if 'emit-js-wrapper' in t: + with open('a.js') as actual: + with open(t + '.js') as expected: + fail_if_not_identical(actual.read(), expected.read()) + if 'emit-spec-wrapper' in t: + with open('a.wat') as actual: + with open(t + '.wat') as expected: + fail_if_not_identical(actual.read(), expected.read()) + + print '\n[ checking wasm-opt parsing & printing... ]\n' + + for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'print'))): + if t.endswith('.wast'): + print '..', t + wasm = os.path.basename(t).replace('.wast', '') + cmd = WASM_OPT + [os.path.join(options.binaryen_test, 'print', t), '--print'] + print ' ', ' '.join(cmd) + actual, err = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() + fail_if_not_identical(actual, open(os.path.join(options.binaryen_test, 'print', wasm + '.txt')).read()) + cmd = WASM_OPT + [os.path.join(options.binaryen_test, 'print', t), '--print-minified'] + print ' ', ' '.join(cmd) + actual, err = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() + fail_if_not_identical(actual.strip(), open(os.path.join(options.binaryen_test, 'print', wasm + '.minified.txt')).read().strip()) + + print '\n[ checking wasm-opt testcases... ]\n' + + for t in tests: + if t.endswith('.wast') and not t.startswith('spec'): + print '..', t + t = os.path.join(options.binaryen_test, t) + f = t + '.from-wast' + cmd = WASM_OPT + [t, '--print'] + actual = run_command(cmd) + actual = actual.replace('printing before:\n', '') + + expected = open(f, 'rb').read() if actual != expected: fail(actual, expected) -print '\n[ checking wasm-merge... ]\n' - -for t in os.listdir(os.path.join('test', 'merge')): - if t.endswith(('.wast', '.wasm')): - print '..', t - t = os.path.join('test', 'merge', t) - u = t + '.toMerge' - for finalize in [0, 1]: - for opt in [0, 1]: - cmd = WASM_MERGE + [t, u, '-o', 'a.wast', '-S', '--verbose'] - if finalize: cmd += ['--finalize-memory-base=1024', '--finalize-table-base=8'] - if opt: cmd += ['-O'] - stdout = run_command(cmd) - actual = open('a.wast').read() - out = t + '.combined' - if finalize: out += '.finalized' - if opt: out += '.opt' - with open(out) as f: - fail_if_not_identical(f.read(), actual) - with open(out + '.stdout') as f: - fail_if_not_identical(f.read(), stdout) - -print '\n[ checking wasm-ctor-eval... ]\n' - -for t in os.listdir(os.path.join('test', 'ctor-eval')): - if t.endswith(('.wast', '.wasm')): - print '..', t - t = os.path.join('test', 'ctor-eval', t) - ctors = open(t + '.ctors').read().strip() - cmd = WASM_CTOR_EVAL + [t, '-o', 'a.wast', '-S', '--ctors', ctors] - stdout = run_command(cmd) - actual = open('a.wast').read() - out = t + '.out' - with open(out) as f: - fail_if_not_identical(f.read(), actual) + binary_format_check(t, wasm_as_args=['-g']) # test with debuginfo + binary_format_check(t, wasm_as_args=[], binary_suffix='.fromBinary.noDebugInfo') # test without debuginfo + + minify_check(t) + +def run_asm2wasm_tests(): + print '[ checking asm2wasm testcases... ]\n' + + for asm in tests: + if asm.endswith('.asm.js'): + for precise in [0, 1, 2]: + for opts in [1, 0]: + cmd = ASM2WASM + [os.path.join(options.binaryen_test, asm)] + wasm = asm.replace('.asm.js', '.fromasm') + if not precise: + cmd += ['--emit-potential-traps', '--ignore-implicit-traps'] + wasm += '.imprecise' + elif precise == 2: + cmd += ['--emit-clamped-potential-traps'] + wasm += '.clamp' + if not opts: + wasm += '.no-opts' + if precise: + cmd += ['-O0'] # test that -O0 does nothing + else: + cmd += ['-O'] + if 'debugInfo' in asm: + cmd += ['-g'] + if 'noffi' in asm: + cmd += ['--no-legalize-javascript-ffi'] + if precise and opts: + # test mem init importing + open('a.mem', 'wb').write(asm) + cmd += ['--mem-init=a.mem'] + if asm[0] == 'e': + cmd += ['--mem-base=1024'] + if 'i64' in asm or 'wasm-only' in asm or 'noffi' in asm: + cmd += ['--wasm-only'] + wasm = os.path.join(options.binaryen_test, wasm) + print '..', asm, wasm + + def do_asm2wasm_test(): + actual = run_command(cmd) + + # verify output + if not os.path.exists(wasm): + fail_with_error('output .wast file %s does not exist' % wasm) + expected = open(wasm, 'rb').read() + if actual != expected: + fail(actual, expected) + + binary_format_check(wasm, verify_final_result=False) + + # test both normally and with pass debug (so each inter-pass state is validated) + old_pass_debug = os.environ.get('BINARYEN_PASS_DEBUG') + try: + os.environ['BINARYEN_PASS_DEBUG'] = '1' + do_asm2wasm_test() + del os.environ['BINARYEN_PASS_DEBUG'] + do_asm2wasm_test() + finally: + if old_pass_debug is not None: + os.environ['BINARYEN_PASS_DEBUG'] = old_pass_debug + else: + if 'BINARYEN_PASS_DEBUG' in os.environ: + del os.environ['BINARYEN_PASS_DEBUG'] + + # verify in wasm + if options.interpreter: + # remove imports, spec interpreter doesn't know what to do with them + subprocess.check_call(WASM_OPT + ['--remove-imports', wasm], stdout=open('ztemp.wast', 'w'), stderr=subprocess.PIPE) + proc = subprocess.Popen([options.interpreter, 'ztemp.wast'], stderr=subprocess.PIPE) + out, err = proc.communicate() + if proc.returncode != 0: + try: # to parse the error + reported = err.split(':')[1] + start, end = reported.split('-') + start_line, start_col = map(int, start.split('.')) + lines = open('ztemp.wast').read().split('\n') + print + print '='*80 + print lines[start_line-1] + print (' '*(start_col-1)) + '^' + print (' '*(start_col-2)) + '/_\\' + print '='*80 + print err + except Exception, e: + fail_with_error('wasm interpreter error: ' + err) # failed to pretty-print + fail_with_error('wasm interpreter error') + + # verify debug info + if 'debugInfo' in asm: + jsmap = 'a.wasm.map' + cmd += ['--source-map', jsmap, + '--source-map-url', 'http://example.org/' + jsmap, + '-o', 'a.wasm'] + run_command(cmd) + if not os.path.isfile(jsmap): + fail_with_error('Debug info map not created: %s' % jsmap) + with open(wasm + '.map', 'rb') as expected: + with open(jsmap, 'rb') as actual: + fail_if_not_identical(actual.read(), expected.read()) + with open('a.wasm', 'rb') as binary: + url_section_name = bytearray([16]) + bytearray('sourceMappingURL') + payload = 'http://example.org/' + jsmap + assert len(payload) < 256, 'name too long' + url_section_contents = bytearray([len(payload)]) + bytearray(payload) + print url_section_name + binary_contents = bytearray(binary.read()) + if url_section_name not in binary_contents: + fail_with_error('source map url section not found in binary') + if url_section_contents not in binary_contents[binary_contents.index(url_section_name):]: + fail_with_error('source map url not found in url section') + + + print '\n[ checking asm2wasm binary reading/writing... ]\n' + + asmjs = os.path.join(options.binaryen_test, 'hello_world.asm.js') + delete_from_orbit('a.wasm') + delete_from_orbit('b.wast') + run_command(ASM2WASM + [asmjs, '-o', 'a.wasm']) + assert open('a.wasm', 'rb').read()[0] == '\0', 'we emit binary by default' + run_command(ASM2WASM + [asmjs, '-o', 'b.wast', '-S']) + assert open('b.wast', 'rb').read()[0] != '\0', 'we emit text with -S' + +def run_wasm_dis_tests(): + print '\n[ checking wasm-dis on provided binaries... ]\n' + + for t in tests: + if t.endswith('.wasm') and not t.startswith('spec'): + print '..', t + t = os.path.join(options.binaryen_test, t) + cmd = WASM_DIS + [t] + if os.path.isfile(t + '.map'): cmd += ['--source-map', t + '.map'] -if has_shell_timeout(): + actual = run_command(cmd) + + with open(t + '.fromBinary') as f: + expected = f.read() + if actual != expected: + fail(actual, expected) + +def run_wasm_merge_tests(): + print '\n[ checking wasm-merge... ]\n' + + for t in os.listdir(os.path.join('test', 'merge')): + if t.endswith(('.wast', '.wasm')): + print '..', t + t = os.path.join('test', 'merge', t) + u = t + '.toMerge' + for finalize in [0, 1]: + for opt in [0, 1]: + cmd = WASM_MERGE + [t, u, '-o', 'a.wast', '-S', '--verbose'] + if finalize: cmd += ['--finalize-memory-base=1024', '--finalize-table-base=8'] + if opt: cmd += ['-O'] + stdout = run_command(cmd) + actual = open('a.wast').read() + out = t + '.combined' + if finalize: out += '.finalized' + if opt: out += '.opt' + with open(out) as f: + fail_if_not_identical(f.read(), actual) + with open(out + '.stdout') as f: + fail_if_not_identical(f.read(), stdout) + +def run_ctor_eval_tests(): + print '\n[ checking wasm-ctor-eval... ]\n' + + for t in os.listdir(os.path.join('test', 'ctor-eval')): + if t.endswith(('.wast', '.wasm')): + print '..', t + t = os.path.join('test', 'ctor-eval', t) + ctors = open(t + '.ctors').read().strip() + cmd = WASM_CTOR_EVAL + [t, '-o', 'a.wast', '-S', '--ctors', ctors] + stdout = run_command(cmd) + actual = open('a.wast').read() + out = t + '.out' + with open(out) as f: + fail_if_not_identical(f.read(), actual) + +def run_wasm_reduce_tests(): print '\n[ checking wasm-reduce ]\n' for t in os.listdir(os.path.join('test', 'reduce')): @@ -330,108 +336,109 @@ if has_shell_timeout(): t = os.path.join('test', 'reduce', t) # convert to wasm run_command(WASM_AS + [t, '-o', 'a.wasm']) - print run_command(WASM_REDUCE + ['a.wasm', '--command=bin/wasm-opt b.wasm --fuzz-exec', '-t', 'b.wasm', '-w', 'c.wasm']) + print run_command(WASM_REDUCE + ['a.wasm', '--command=%s b.wasm --fuzz-exec' % WASM_OPT[0], '-t', 'b.wasm', '-w', 'c.wasm']) expected = t + '.txt' run_command(WASM_DIS + ['c.wasm', '-o', 'a.wast']) with open('a.wast') as seen: with open(expected) as correct: fail_if_not_identical(seen.read(), correct.read()) -print '\n[ checking wasm-shell spec testcases... ]\n' +def run_spec_tests(): + print '\n[ checking wasm-shell spec testcases... ]\n' -if len(requested) == 0: - BLACKLIST = ['memory.wast', 'binary.wast'] # FIXME we support old and new memory formats, for now, until 0xc, and so can't pass this old-style test. - # FIXME to update the spec to 0xd, we need to implement (register "name") for import.wast - spec_tests = [os.path.join('spec', t) for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'spec'))) if t not in BLACKLIST] -else: - spec_tests = requested[:] + if len(requested) == 0: + BLACKLIST = ['memory.wast', 'binary.wast'] # FIXME we support old and new memory formats, for now, until 0xc, and so can't pass this old-style test. + # FIXME to update the spec to 0xd, we need to implement (register "name") for import.wast + spec_tests = [os.path.join('spec', t) for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'spec'))) if t not in BLACKLIST] + else: + spec_tests = requested[:] -for t in spec_tests: - if t.startswith('spec') and t.endswith('.wast'): - print '..', t - wast = os.path.join(options.binaryen_test, t) + for t in spec_tests: + if t.startswith('spec') and t.endswith('.wast'): + print '..', t + wast = os.path.join(options.binaryen_test, t) - # skip checks for some tests - if os.path.basename(wast) in ['linking.wast', 'nop.wast', 'stack.wast', 'typecheck.wast', 'unwind.wast']: # FIXME - continue + # skip checks for some tests + if os.path.basename(wast) in ['linking.wast', 'nop.wast', 'stack.wast', 'typecheck.wast', 'unwind.wast']: # FIXME + continue - def run_spec_test(wast): - cmd = WASM_SHELL + [wast] - # we must skip the stack machine portions of spec tests or apply other extra args - extra = { - } - cmd = cmd + (extra.get(os.path.basename(wast)) or []) - return run_command(cmd, stderr=subprocess.PIPE) - - def run_opt_test(wast): - # check optimization validation - cmd = WASM_OPT + [wast, '-O'] - run_command(cmd) - - def check_expected(actual, expected): - if expected and os.path.exists(expected): - expected = open(expected).read() - # fix it up, our pretty (i32.const 83) must become compared to a homely 83 : i32 - def fix(x): - x = x.strip() - if not x: return x - v, t = x.split(' : ') - if v.endswith('.'): v = v[:-1] # remove trailing '.' - return '(' + t + '.const ' + v + ')' - expected = '\n'.join(map(fix, expected.split('\n'))) - print ' (using expected output)' - actual = actual.strip() - expected = expected.strip() - if actual != expected: - fail(actual, expected) + def run_spec_test(wast): + cmd = WASM_SHELL + [wast] + # we must skip the stack machine portions of spec tests or apply other extra args + extra = { + } + cmd = cmd + (extra.get(os.path.basename(wast)) or []) + return run_command(cmd, stderr=subprocess.PIPE) + + def run_opt_test(wast): + # check optimization validation + cmd = WASM_OPT + [wast, '-O'] + run_command(cmd) + + def check_expected(actual, expected): + if expected and os.path.exists(expected): + expected = open(expected).read() + # fix it up, our pretty (i32.const 83) must become compared to a homely 83 : i32 + def fix(x): + x = x.strip() + if not x: return x + v, t = x.split(' : ') + if v.endswith('.'): v = v[:-1] # remove trailing '.' + return '(' + t + '.const ' + v + ')' + expected = '\n'.join(map(fix, expected.split('\n'))) + print ' (using expected output)' + actual = actual.strip() + expected = expected.strip() + if actual != expected: + fail(actual, expected) - expected = os.path.join(options.binaryen_test, 'spec', 'expected-output', os.path.basename(wast) + '.log') + expected = os.path.join(options.binaryen_test, 'spec', 'expected-output', os.path.basename(wast) + '.log') - # some spec tests should fail (actual process failure, not just assert_invalid) - try: - actual = run_spec_test(wast) - except Exception, e: - if ('wasm-validator error' in str(e) or 'parse exception' in str(e)) and '.fail.' in t: - print '<< test failed as expected >>' - continue # don't try all the binary format stuff TODO - else: - fail_with_error(str(e)) + # some spec tests should fail (actual process failure, not just assert_invalid) + try: + actual = run_spec_test(wast) + except Exception, e: + if ('wasm-validator error' in str(e) or 'parse exception' in str(e)) and '.fail.' in t: + print '<< test failed as expected >>' + continue # don't try all the binary format stuff TODO + else: + fail_with_error(str(e)) - check_expected(actual, expected) + check_expected(actual, expected) - # skip binary checks for tests that reuse previous modules by name, as that's a wast-only feature - if os.path.basename(wast) in ['exports.wast']: # FIXME - continue + # skip binary checks for tests that reuse previous modules by name, as that's a wast-only feature + if os.path.basename(wast) in ['exports.wast']: # FIXME + continue - # we must ignore some binary format splits - splits_to_skip = { - 'func.wast': [2], - 'return.wast': [2] - } + # we must ignore some binary format splits + splits_to_skip = { + 'func.wast': [2], + 'return.wast': [2] + } - # check binary format. here we can verify execution of the final result, no need for an output verification - split_num = 0 - if os.path.basename(wast) not in []: # avoid some tests with things still being sorted out in the spec - actual = '' - for module, asserts in split_wast(wast): - skip = splits_to_skip.get(os.path.basename(wast)) or [] - if split_num in skip: - print ' skipping split module', split_num - 1 + # check binary format. here we can verify execution of the final result, no need for an output verification + split_num = 0 + if os.path.basename(wast) not in []: # avoid some tests with things still being sorted out in the spec + actual = '' + for module, asserts in split_wast(wast): + skip = splits_to_skip.get(os.path.basename(wast)) or [] + if split_num in skip: + print ' skipping split module', split_num - 1 + split_num += 1 + continue + print ' testing split module', split_num split_num += 1 - continue - print ' testing split module', split_num - split_num += 1 - with open('split.wast', 'w') as o: o.write(module + '\n' + '\n'.join(asserts)) - run_spec_test('split.wast') # before binary stuff - just check it's still ok split out - run_opt_test('split.wast') # also that our optimizer doesn't break on it - result_wast = binary_format_check('split.wast', verify_final_result=False) - # add the asserts, and verify that the test still passes - open(result_wast, 'a').write('\n' + '\n'.join(asserts)) - actual += run_spec_test(result_wast) - # compare all the outputs to the expected output - check_expected(actual, os.path.join(options.binaryen_test, 'spec', 'expected-output', os.path.basename(wast) + '.log')) - -if MOZJS: + with open('split.wast', 'w') as o: o.write(module + '\n' + '\n'.join(asserts)) + run_spec_test('split.wast') # before binary stuff - just check it's still ok split out + run_opt_test('split.wast') # also that our optimizer doesn't break on it + result_wast = binary_format_check('split.wast', verify_final_result=False) + # add the asserts, and verify that the test still passes + open(result_wast, 'a').write('\n' + '\n'.join(asserts)) + actual += run_spec_test(result_wast) + # compare all the outputs to the expected output + check_expected(actual, os.path.join(options.binaryen_test, 'spec', 'expected-output', os.path.basename(wast) + '.log')) + +def run_binaryen_js_tests(): print '\n[ checking binaryen.js testcases... ]\n' for s in sorted(os.listdir(os.path.join(options.binaryen_test, 'binaryen.js'))): @@ -447,25 +454,21 @@ if MOZJS: if expected not in out: fail(out, expected) -s2wasm.test_s2wasm() -s2wasm.test_linker() -wasm2asm.test_wasm2asm() - -print '\n[ running validation tests... ]\n' -# Ensure the tests validate by default -cmd = WASM_AS + [os.path.join(options.binaryen_test, 'validator', 'invalid_export.wast')] -run_command(cmd) -cmd = WASM_AS + [os.path.join(options.binaryen_test, 'validator', 'invalid_import.wast')] -run_command(cmd) -cmd = WASM_AS + ['--validate=web', os.path.join(options.binaryen_test, 'validator', 'invalid_export.wast')] -run_command(cmd, expected_status=1) -cmd = WASM_AS + ['--validate=web', os.path.join(options.binaryen_test, 'validator', 'invalid_import.wast')] -run_command(cmd, expected_status=1) -cmd = WASM_AS + ['--validate=none', os.path.join(options.binaryen_test, 'validator', 'invalid_return.wast')] -run_command(cmd) - -if options.torture and options.test_waterfall: - +def run_validator_tests(): + print '\n[ running validation tests... ]\n' + # Ensure the tests validate by default + cmd = WASM_AS + [os.path.join(options.binaryen_test, 'validator', 'invalid_export.wast')] + run_command(cmd) + cmd = WASM_AS + [os.path.join(options.binaryen_test, 'validator', 'invalid_import.wast')] + run_command(cmd) + cmd = WASM_AS + ['--validate=web', os.path.join(options.binaryen_test, 'validator', 'invalid_export.wast')] + run_command(cmd, expected_status=1) + cmd = WASM_AS + ['--validate=web', os.path.join(options.binaryen_test, 'validator', 'invalid_import.wast')] + run_command(cmd, expected_status=1) + cmd = WASM_AS + ['--validate=none', os.path.join(options.binaryen_test, 'validator', 'invalid_return.wast')] + run_command(cmd) + +def run_torture_tests(): print '\n[ checking torture testcases... ]\n' unexpected_result_count = 0 @@ -494,8 +497,7 @@ if options.torture and options.test_waterfall: if unexpected_result_count: fail('%s failures' % unexpected_result_count, '0 failures') -if has_vanilla_emcc and has_vanilla_llvm and 0: - +def run_vanilla_tests(): print '\n[ checking emcc WASM_BACKEND testcases...]\n' try: @@ -535,9 +537,7 @@ if has_vanilla_emcc and has_vanilla_llvm and 0: else: del os.environ['EMCC_WASM_BACKEND'] -print '\n[ checking example testcases... ]\n' - -if options.run_gcc_tests: +def run_gcc_torture_tests(): print '\n[ checking native gcc testcases...]\n' if not NATIVECC or not NATIVEXX: fail_with_error('Native compiler (e.g. gcc/g++) was not found in PATH!') @@ -590,8 +590,7 @@ if options.run_gcc_tests: if actual != expected: fail(actual, expected) -if EMCC: - +def run_emscripten_tests(): if MOZJS and 0: print '\n[ checking native wasm support ]\n' @@ -714,6 +713,35 @@ if EMCC: shutil.copyfile(recreated, 'a.wasm.wast') execute() + +# Run all the tests +run_help_tests() +run_wasm_opt_tests() +run_asm2wasm_tests() +run_wasm_dis_tests() +run_wasm_merge_tests() +run_ctor_eval_tests() +if has_shell_timeout(): + run_wasm_reduce_tests() + +run_spec_tests() +if MOZJS: + run_binaryen_js_tests() +s2wasm.test_s2wasm() +s2wasm.test_linker() +wasm2asm.test_wasm2asm() +run_validator_tests() +if options.torture and options.test_waterfall: + run_torture_tests() +if has_vanilla_emcc and has_vanilla_llvm and 0: + run_vanilla_tests() +print '\n[ checking example testcases... ]\n' +if options.run_gcc_tests: + run_gcc_torture_tests() +if EMCC: + run_emscripten_tests() + +# Check/display the results if num_failures == 0: print '\n[ success! ]' |