diff options
Diffstat (limited to 'tests/runner.py')
-rwxr-xr-x | tests/runner.py | 412 |
1 files changed, 317 insertions, 95 deletions
diff --git a/tests/runner.py b/tests/runner.py index b44632bc..9ec2f57d 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -291,7 +291,7 @@ process(sys.argv[1]) out = open(stdout, 'r').read() err = open(stderr, 'r').read() if engine == SPIDERMONKEY_ENGINE and Settings.ASM_JS: - if 'Successfully compiled asm.js code' in err and 'asm.js link error' not in err: + if 'uccessfully compiled asm.js code' in err and 'asm.js link error' not in err: print >> sys.stderr, "[was asm.js'ified]" elif 'asm.js' in err: # if no asm.js error, then not an odin build raise Exception("did NOT asm.js'ify") @@ -366,7 +366,7 @@ process(sys.argv[1]) print >> sys.stderr, '<load %s from cache> ' % cache_name, generated_libs = [] for basename, contents in self.library_cache[cache_name]: - bc_file = os.path.join(build_dir, basename) + bc_file = os.path.join(build_dir, cache_name + '_' + basename) f = open(bc_file, 'wb') f.write(contents) f.close() @@ -447,6 +447,8 @@ process(sys.argv[1]) sys.argv = map(lambda arg: arg if not arg.startswith('test_') else 'default.' + arg, sys.argv) +test_modes = ['default', 'o1', 'o2', 'asm1', 'asm2', 'asm2g', 'asm2x86', 's_0_0', 's_0_1', 's_1_0', 's_1_1'] + test_index = 0 if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'browser' not in str(sys.argv): @@ -454,10 +456,10 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows print "Running Emscripten tests..." - if len(sys.argv) == 2 and 'ALL.' in sys.argv[1]: + if len(sys.argv) == 2 and sys.argv[1].startswith('ALL.'): ignore, test = sys.argv[1].split('.') print 'Running all test modes on test "%s"' % test - sys.argv = [sys.argv[0], 'default.'+test, 'o1.'+test, 'o2.'+test, 'asm1.'+test, 'asm2.'+test, 'asm2g.'+test, 'asm2le32.'+test, 's_0_0.'+test, 's_0_1.'+test, 's_1_0.'+test, 's_1_1.'+test] + sys.argv = [sys.argv[0]] + map(lambda mode: mode+'.'+test, test_modes) class T(RunnerCore): # Short name, to make it more fun to use manually on the commandline ## Does a complete test - builds, runs, checks output, etc. @@ -509,7 +511,7 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows post_build=None) # post_build was already done in ll_to_js, this do_run call is just to test the output def is_le32(self): - return 'le32-unknown-nacl' in COMPILER_OPTS or self.env.get('EMCC_LLVM_TARGET') == 'le32-unknown-nacl' + return not ('i386-pc-linux-gnu' in COMPILER_OPTS or self.env.get('EMCC_LLVM_TARGET') == 'i386-pc-linux-gnu') def test_hello_world(self): src = ''' @@ -1177,6 +1179,53 @@ m_divisor is 1091269979 ''' self.do_run(src, 'Succeeded!') + def test_i64_varargs(self): + if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') + + src = r''' + #include <stdio.h> + #include <stdint.h> + #include <stdarg.h> + + int64_t ccv_cache_generate_signature(char *msg, int len, int64_t sig_start, ...) { + if (sig_start < 10123) + printf("%s\n", msg+len); + va_list v; + va_start(v, sig_start); + if (sig_start > 1413) + printf("%d\n", va_arg(v, int)); + else + printf("nada\n"); + va_end(v); + return len*sig_start*(msg[0]+1); + } + + int main(int argc, char **argv) + { + for (int i = 0; i < argc; i++) { + int64_t x; + if (i % 123123 == 0) + x = ccv_cache_generate_signature(argv[i], i+2, (int64_t)argc*argc, 54.111); + else + x = ccv_cache_generate_signature(argv[i], i+2, (int64_t)argc*argc, 13); + printf("%lld\n", x); + } + }; + ''' + self.do_run(src, '''in/this.program +nada +1536 +a +nada +5760 +fl +nada +6592 +sdfasdfasdf +nada +7840 +''', 'waka fleefl asdfasdfasdfasdf'.split(' ')) + def test_i32_mul_precise(self): if self.emcc_args == None: return self.skip('needs ta2') @@ -3315,10 +3364,10 @@ Exiting setjmp function, level: 0, prev_jmp: -1 #include <stdio.h> int - main(void) { - float (*fn)(float) = &sqrtf; - float (*fn2)(float) = &fabsf; - float (*fn3)(float) = &erff; + main(int argc, char **argv) { + float (*fn)(float) = argc != 12 ? &sqrtf : &fabsf; + float (*fn2)(float) = argc != 13 ? &fabsf : &sqrtf; + float (*fn3)(float) = argc != 14 ? &erff : &fabsf; printf("fn2(-5) = %d, fn(10) = %.2f, erf(10) = %.2f\\n", (int)fn2(-5), fn(10), fn3(10)); return 0; } @@ -3408,6 +3457,35 @@ Exiting setjmp function, level: 0, prev_jmp: -1 ''' self.do_run(src, 'z:1*', force_c=True) + def test_rename(self): + src = ''' + #include <stdio.h> + #include <sys/stat.h> + #include <sys/types.h> + #include <assert.h> + + int main() { + int err; + FILE* fid; + + err = mkdir("/foo", 0777); + err = mkdir("/bar", 0777); + fid = fopen("/foo/bar", "w+"); + fclose(fid); + + err = rename("/foo/bar", "/foo/bar2"); + printf("%d\\n", err); + + err = rename("/foo", "/foo/foo"); + printf("%d\\n", err); + + err = rename("/foo", "/bar/foo"); + printf("%d\\n", err); + return 0; + } + ''' + self.do_run(src, '0\n-1\n0\n', force_c=True) + def test_alloca_stack(self): if self.emcc_args is None: return # too slow in other modes @@ -5624,7 +5702,7 @@ at function.:blag open(path_from_root('tests', 'printf', 'output_i64_1.txt'), 'r').read()] self.do_run(src, expected) - def test_printf_types(self): + def test_printf_2(self): src = r''' #include <stdio.h> @@ -5637,11 +5715,12 @@ at function.:blag double d = 6.6; printf("%c,%hd,%d,%lld,%.1f,%.1llf\n", c, s, i, l, f, d); + printf("%#x,%#x\n", 1, 0); return 0; } ''' - self.do_run(src, '1,2,3,4,5.5,6.6\n') + self.do_run(src, '1,2,3,4,5.5,6.6\n0x1,0\n') def test_vprintf(self): src = r''' @@ -6045,6 +6124,40 @@ Pass: 0.000012 0.000012''') ''' self.do_run(src, '''0:173,16 1:16,173 2:183,173 3:17,287 4:98,123''') + def test_sscanf_other_whitespace(self): + Settings.SAFE_HEAP = 0 # use i16s in printf + + src = r''' + #include<stdio.h> + + int main() { + short int x; + short int y; + + const char* buffer[] = { + "\t2\t3\t", /* TAB - horizontal tab */ + "\t\t5\t\t7\t\t", + "\n11\n13\n", /* LF - line feed */ + "\n\n17\n\n19\n\n", + "\v23\v29\v", /* VT - vertical tab */ + "\v\v31\v\v37\v\v", + "\f41\f43\f", /* FF - form feed */ + "\f\f47\f\f53\f\f", + "\r59\r61\r", /* CR - carrage return */ + "\r\r67\r\r71\r\r" + }; + + for (int i=0; i<10; ++i) { + x = 0; y = 0; + sscanf(buffer[i], " %d %d ", &x, &y); + printf("%d, %d, ", x, y); + } + + return 0; + } + ''' + self.do_run(src, '''2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, ''') + def test_sscanf_3(self): # i64 if not Settings.USE_TYPED_ARRAYS == 2: return self.skip('64-bit sscanf only supported in ta2') @@ -6256,6 +6369,31 @@ def process(filename): self.emcc_args += ['--embed-file', 'eol.txt'] self.do_run(src, 'SUCCESS\n') + def test_fscanf(self): + if self.emcc_args is None: return self.skip('requires emcc') + open(os.path.join(self.get_dir(), 'three_numbers.txt'), 'w').write('''-1 0.1 -.1''') + src = r''' + #include <stdio.h> + #include <assert.h> + #include <float.h> + int main() + { + float x = FLT_MAX, y = FLT_MAX, z = FLT_MAX; + + FILE* fp = fopen("three_numbers.txt", "r"); + if (fp) { + int match = fscanf(fp, " %f %f %f ", &x, &y, &z); + printf("match = %d\n", match); + printf("x = %0.1f, y = %0.1f, z = %0.1f\n", x, y, z); + } else { + printf("failed to open three_numbers.txt\n"); + } + return 0; + } + ''' + self.emcc_args += ['--embed-file', 'three_numbers.txt'] + self.do_run(src, 'match = 3\nx = -1.0, y = 0.1, z = -0.1\n') + def test_folders(self): add_pre_run = ''' def process(filename): @@ -7396,6 +7534,10 @@ extern "C" { src = open(path_from_root('tests', 'fasta.cpp'), 'r').read() self.do_run(src, j, [str(i)], lambda x, err: x.replace('\n', '*'), no_build=i>1) + def test_whets(self): + if not Settings.ASM_JS: return self.skip('mainly a test for asm validation here') + self.do_run(open(path_from_root('tests', 'whets.cpp')).read(), 'Single Precision C Whetstone Benchmark') + def test_dlmalloc(self): if self.emcc_args is None: self.emcc_args = [] # dlmalloc auto-inclusion is only done if we use emcc @@ -7677,7 +7819,7 @@ void*:16 def test_cubescript(self): if self.emcc_args is None: return self.skip('requires emcc') - if self.emcc_args is not None and '-O2' in self.emcc_args: + if self.run_name == 'o2': self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage Building.COMPILER_TEST_OPTS = [] # remove -g, so we have one test without it by default @@ -7692,6 +7834,23 @@ void*:16 self.do_run(path_from_root('tests', 'cubescript'), '*\nTemp is 33\n9\n5\nhello, everyone\n*', main_file='command.cpp') + assert 'asm2g' in test_modes + if self.run_name == 'asm2g': + results = {} + original = open('src.cpp.o.js').read() + results[Settings.ALIASING_FUNCTION_POINTERS] = len(original) + Settings.ALIASING_FUNCTION_POINTERS = 1 - Settings.ALIASING_FUNCTION_POINTERS + self.do_run(path_from_root('tests', 'cubescript'), '*\nTemp is 33\n9\n5\nhello, everyone\n*', main_file='command.cpp') + final = open('src.cpp.o.js').read() + results[Settings.ALIASING_FUNCTION_POINTERS] = len(final) + open('original.js', 'w').write(original) + print results + assert results[1] < 0.99*results[0] + assert ' & 3]()' in original, 'small function table exists' + assert ' & 3]()' not in final, 'small function table does not exist' + assert ' & 255]()' not in original, 'big function table does not exist' + assert ' & 255]()' in final, 'big function table exists' + def test_gcc_unmangler(self): Settings.NAMED_GLOBALS = 1 # test coverage for this @@ -7810,6 +7969,9 @@ def process(filename): force_c=True) def test_zlib(self): + if Settings.ASM_JS: + self.banned_js_engines = [NODE_JS] # TODO investigate + if self.emcc_args is not None and '-O2' in self.emcc_args: self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage @@ -7834,15 +7996,29 @@ def process(filename): Settings.SAFE_HEAP_LINES = ['btVoronoiSimplexSolver.h:40', 'btVoronoiSimplexSolver.h:41', 'btVoronoiSimplexSolver.h:42', 'btVoronoiSimplexSolver.h:43'] - self.do_run(open(path_from_root('tests', 'bullet', 'Demos', 'HelloWorld', 'HelloWorld.cpp'), 'r').read(), - [open(path_from_root('tests', 'bullet', 'output.txt'), 'r').read(), # different roundings - open(path_from_root('tests', 'bullet', 'output2.txt'), 'r').read(), - open(path_from_root('tests', 'bullet', 'output3.txt'), 'r').read()], - libraries=self.get_library('bullet', [os.path.join('src', '.libs', 'libBulletDynamics.a'), - os.path.join('src', '.libs', 'libBulletCollision.a'), - os.path.join('src', '.libs', 'libLinearMath.a')], - configure_args=['--disable-demos','--disable-dependency-tracking']), - includes=[path_from_root('tests', 'bullet', 'src')]) + def test(): + self.do_run(open(path_from_root('tests', 'bullet', 'Demos', 'HelloWorld', 'HelloWorld.cpp'), 'r').read(), + [open(path_from_root('tests', 'bullet', 'output.txt'), 'r').read(), # different roundings + open(path_from_root('tests', 'bullet', 'output2.txt'), 'r').read(), + open(path_from_root('tests', 'bullet', 'output3.txt'), 'r').read()], + libraries=self.get_library('bullet', [os.path.join('src', '.libs', 'libBulletDynamics.a'), + os.path.join('src', '.libs', 'libBulletCollision.a'), + os.path.join('src', '.libs', 'libLinearMath.a')], + configure_args=['--disable-demos','--disable-dependency-tracking']), + includes=[path_from_root('tests', 'bullet', 'src')]) + test() + + assert 'asm2g' in test_modes + if self.run_name == 'asm2g': + # Test forced alignment + print >> sys.stderr, 'testing FORCE_ALIGNED_MEMORY' + old = open('src.cpp.o.js').read() + Settings.FORCE_ALIGNED_MEMORY = 1 + test() + new = open('src.cpp.o.js').read() + print len(old), len(new), old.count('tempBigInt'), new.count('tempBigInt') + assert len(old) > len(new) + assert old.count('tempBigInt') > new.count('tempBigInt') def test_poppler(self): if self.emcc_args is None: return self.skip('very slow, we only do this in emcc runs') @@ -8464,6 +8640,10 @@ def process(filename): self.do_run(src, '''Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.''') generated = open('src.cpp.o.js').read() assert 'jsCall' not in generated + Settings.RESERVED_FUNCTION_POINTERS = 1 + + Settings.ALIASING_FUNCTION_POINTERS = 1 - Settings.ALIASING_FUNCTION_POINTERS # flip the test + self.do_run(src, '''Hello 7 from JS!''') def test_scriptaclass(self): if self.emcc_args is None: return self.skip('requires emcc') @@ -9271,6 +9451,7 @@ finalizing 3 (global == 0) def make_run(fullname, name=-1, compiler=-1, llvm_opts=0, embetter=0, quantum_size=0, typed_arrays=0, emcc_args=None, env='{}'): exec(''' class %s(T): + run_name = '%s' env = %s def tearDown(self): @@ -9335,7 +9516,7 @@ class %s(T): Building.pick_llvm_opts(3) TT = %s -''' % (fullname, env, fullname, fullname, compiler, str(emcc_args), llvm_opts, embetter, quantum_size, typed_arrays, fullname)) +''' % (fullname, fullname, env, fullname, fullname, compiler, str(emcc_args), llvm_opts, embetter, quantum_size, typed_arrays, fullname)) return TT # Make one run with the defaults @@ -9351,7 +9532,7 @@ TT = %s exec('asm1 = make_run("asm1", compiler=CLANG, emcc_args=["-O1", "-s", "CHECK_HEAP_ALIGN=1"])') exec('asm2 = make_run("asm2", compiler=CLANG, emcc_args=["-O2"])') exec('asm2g = make_run("asm2g", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "ASSERTIONS=1", "--memory-init-file", "1"])') - exec('''asm2le32 = make_run("asm2le32", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "CHECK_HEAP_ALIGN=1"], env='{"EMCC_LLVM_TARGET": "le32-unknown-nacl"}')''') + exec('''asm2x86 = make_run("asm2x86", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "CHECK_HEAP_ALIGN=1"], env='{"EMCC_LLVM_TARGET": "i386-pc-linux-gnu"}')''') # Make custom runs with various options for compiler, quantum, embetter, typed_arrays, llvm_opts in [ @@ -9488,8 +9669,8 @@ Options that are modified or new in %s include: (['-o', 'something.js'], 0, None, 0, 1), (['-o', 'something.js', '-O0'], 0, None, 0, 0), (['-o', 'something.js', '-O1'], 1, None, 0, 0), - (['-o', 'something.js', '-O1', '-g'], 1, None, 0, 0), - (['-o', 'something.js', '-O1', '--closure', '1'], 1, None, 0, 0), # no closure when asm.js is on + (['-o', 'something.js', '-O1', '-g'], 1, None, 0, 0), # no closure since debug + (['-o', 'something.js', '-O1', '--closure', '1'], 1, None, 1, 0), (['-o', 'something.js', '-O1', '--closure', '1', '-s', 'ASM_JS=0'], 1, None, 1, 0), (['-o', 'something.js', '-O2'], 2, None, 0, 1), (['-o', 'something.js', '-O2', '-g'], 2, None, 0, 0), @@ -9542,6 +9723,8 @@ Options that are modified or new in %s include: # emcc -s RELOOP=1 src.cpp ==> should pass -s to emscripten.py. --typed-arrays is a convenient alias for -s USE_TYPED_ARRAYS for params, test, text in [ + (['-O2'], lambda generated: 'function intArrayToString' in generated, 'shell has unminified utilities'), + (['-O2', '--closure', '1'], lambda generated: 'function intArrayToString' not in generated, 'closure minifies the shell'), (['-O2'], lambda generated: 'var b=0' in generated and not 'function _main' in generated, 'registerize/minify is run by default in -O2'), (['-O2', '--minify', '0'], lambda generated: 'var b = 0' in generated and not 'function _main' in generated, 'minify is cancelled, but not registerize'), (['-O2', '-g'], lambda generated: 'var b=0' not in generated and 'var b = 0' not in generated and 'function _main' in generated, 'registerize/minify is cancelled by -g'), @@ -11636,7 +11819,7 @@ elif 'browser' in str(sys.argv): open(os.path.join(self.get_dir(), 'sdl_audio.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio.c')).read())) # use closure to check for a possible bug with closure minifying away newer Audio() attributes - Popen([PYTHON, EMCC, '-O2', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio.c'), '--preload-file', 'sound.ogg', '--preload-file', 'sound2.wav', '--preload-file', 'bad.ogg', '-o', 'page.html', '-s', 'EXPORTED_FUNCTIONS=["_main", "_play", "_play2"]']).communicate() + Popen([PYTHON, EMCC, '-O2', '--closure', '1', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio.c'), '--preload-file', 'sound.ogg', '--preload-file', 'sound2.wav', '--preload-file', 'bad.ogg', '-o', 'page.html', '-s', 'EXPORTED_FUNCTIONS=["_main", "_play", "_play2"]']).communicate() self.run_browser('page.html', '', '/report_result?1') def test_sdl_audio_mix(self): @@ -11644,14 +11827,12 @@ elif 'browser' in str(sys.argv): shutil.copyfile(path_from_root('tests', 'sounds', 'the_entertainer.ogg'), os.path.join(self.get_dir(), 'music.ogg')) open(os.path.join(self.get_dir(), 'sdl_audio_mix.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_mix.c')).read())) - # use closure to check for a possible bug with closure minifying away newer Audio() attributes Popen([PYTHON, EMCC, '-O2', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_mix.c'), '--preload-file', 'sound.ogg', '--preload-file', 'music.ogg', '-o', 'page.html']).communicate() self.run_browser('page.html', '', '/report_result?1') def test_sdl_audio_quickload(self): open(os.path.join(self.get_dir(), 'sdl_audio_quickload.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_quickload.c')).read())) - # use closure to check for a possible bug with closure minifying away newer Audio() attributes Popen([PYTHON, EMCC, '-O2', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_quickload.c'), '-o', 'page.html', '-s', 'EXPORTED_FUNCTIONS=["_main", "_play"]']).communicate() self.run_browser('page.html', '', '/report_result?1') @@ -11662,14 +11843,12 @@ elif 'browser' in str(sys.argv): self.run_browser('something.html', '.', '/report_result?1') def test_sdl_ogl(self): - # SDL, OpenGL, textures, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-gray-purple.png')) Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_ogl.c'), '-O2', '--minify', '0', '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png', '-s', 'GL_TESTING=1']).communicate() self.run_browser('something.html', 'You should see an image with gray at the top.', '/report_result?0') def test_sdl_ogl_defaultmatrixmode(self): - # SDL, OpenGL, textures, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-gray-purple.png')) Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_ogl_defaultMatrixMode.c'), '--minify', '0', '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png', '-s', 'GL_TESTING=1']).communicate() @@ -11683,35 +11862,30 @@ elif 'browser' in str(sys.argv): self.run_browser('something.html', 'You should see an image with gray at the top.', '/report_result?0') def test_sdl_fog_simple(self): - # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-fog-simple.png')) Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_fog_simple.c'), '-O2', '--minify', '0', '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png', '-s', 'GL_TESTING=1']).communicate() self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') def test_sdl_fog_negative(self): - # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-fog-negative.png')) Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_fog_negative.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png', '-s', 'GL_TESTING=1']).communicate() self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') def test_sdl_fog_density(self): - # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-fog-density.png')) Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_fog_density.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png', '-s', 'GL_TESTING=1']).communicate() self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') def test_sdl_fog_exp2(self): - # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-fog-exp2.png')) Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_fog_exp2.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png', '-s', 'GL_TESTING=1']).communicate() self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') def test_sdl_fog_linear(self): - # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) self.reftest(path_from_root('tests', 'screenshot-fog-linear.png')) Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_fog_linear.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png', '-s', 'GL_TESTING=1']).communicate() @@ -11730,6 +11904,12 @@ elif 'browser' in str(sys.argv): Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'glfw.c'), '-o', 'page.html']).communicate() self.run_browser('page.html', '', '/report_result?1') + def test_egl_width_height(self): + open(os.path.join(self.get_dir(), 'test_egl_width_height.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'test_egl_width_height.c')).read())) + + Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'test_egl_width_height.c'), '-o', 'page.html']).communicate() + self.run_browser('page.html', 'Should print "(300, 150)" -- the size of the canvas in pixels', '/report_result?1') + def test_freealut(self): programs = self.get_library('freealut', os.path.join('examples', 'hello_world.bc'), make_args=['EXEEXT=.bc']) for program in programs: @@ -11994,7 +12174,7 @@ elif 'browser' in str(sys.argv): self.btest('glshaderinfo.cpp', '1') def test_sdlglshader(self): - self.btest('sdlglshader.c', reference='sdlglshader.png', args=['--closure', '1']) + self.btest('sdlglshader.c', reference='sdlglshader.png', args=['-O2', '--closure', '1']) def test_gl_ps(self): # pointers and a shader @@ -12040,7 +12220,7 @@ elif 'browser' in str(sys.argv): self.btest('cubegeom.c', args=['-O2', '-g'], expected=['188641320', '1522377227', '-1054007155', '-1111866053']) def test_cubegeom_glew(self): - self.btest('cubegeom_glew.c', expected=['188641320', '1522377227', '-1054007155', '-1111866053']) + self.btest('cubegeom_glew.c', args=['-O2', '--closure', '1'], expected=['188641320', '1522377227', '-1054007155', '-1111866053']) def test_cubegeom_color(self): self.btest('cubegeom_color.c', expected=['588472350', '-687660609', '-818120875']) @@ -12491,9 +12671,18 @@ elif 'benchmark' in str(sys.argv): Building.COMPILER_TEST_OPTS = [] - TEST_REPS = 4 + TEST_REPS = 2 TOTAL_TESTS = 8 + # standard arguments for timing: + # 0: no runtime, just startup + # 1: very little runtime + # 2: 0.5 seconds + # 3: 1 second + # 4: 5 seconds + # 5: 10 seconds + DEFAULT_ARG = '4' + tests_done = 0 total_times = map(lambda x: 0., range(TOTAL_TESTS)) total_native_times = map(lambda x: 0., range(TOTAL_TESTS)) @@ -12531,7 +12720,10 @@ elif 'benchmark' in str(sys.argv): print ' JavaScript: mean: %.3f (+-%.3f) secs median: %.3f range: %.3f-%.3f (noise: %3.3f%%) (%d runs)' % (mean, std, median, min(times), max(times), 100*std/mean, reps) print ' Native : mean: %.3f (+-%.3f) secs median: %.3f range: %.3f-%.3f (noise: %3.3f%%) JS is %.2f X slower' % (mean_native, std_native, median_native, min(native_times), max(native_times), 100*std_native/mean_native, final) - def do_benchmark(self, name, src, args=[], expected_output='FAIL', emcc_args=[], native_args=[], shared_args=[], force_c=False, reps=TEST_REPS): + def do_benchmark(self, name, src, expected_output='FAIL', args=[], emcc_args=[], native_args=[], shared_args=[], force_c=False, reps=TEST_REPS, native_exec=None, output_parser=None, args_processor=None): + args = args or [DEFAULT_ARG] + if args_processor: args = args_processor(args) + dirname = self.get_dir() filename = os.path.join(dirname, name + '.c' + ('' if force_c else 'pp')) f = open(filename, 'w') @@ -12544,6 +12736,7 @@ elif 'benchmark' in str(sys.argv): '-O2', '-s', 'DOUBLE_MODE=0', '-s', 'PRECISE_I64_MATH=0', '--llvm-lto', '1', '--memory-init-file', '0', '-s', 'TOTAL_MEMORY=128*1024*1024', + '--closure', '1', '-o', final_filename] + shared_args + emcc_args, stdout=PIPE, stderr=self.stderr_redirect).communicate() assert os.path.exists(final_filename), 'Failed to compile file: ' + output[0] @@ -12555,10 +12748,14 @@ elif 'benchmark' in str(sys.argv): for i in range(reps): start = time.time() js_output = run_js(final_filename, engine=JS_ENGINE, args=args, stderr=PIPE, full_output=True) - if i == 0 and 'Successfully compiled asm.js code' in js_output: + + if i == 0 and 'uccessfully compiled asm.js code' in js_output: if 'asm.js link error' not in js_output: print "[%s was asm.js'ified]" % name - curr = time.time()-start + if not output_parser: + curr = time.time()-start + else: + curr = output_parser(js_output) times.append(curr) total_times[tests_done] += curr if i == 0: @@ -12566,7 +12763,11 @@ elif 'benchmark' in str(sys.argv): self.assertContained(expected_output, js_output) # Run natively - self.build_native(filename, shared_args + native_args) + if not native_exec: + self.build_native(filename, shared_args + native_args) + else: + shutil.copyfile(native_exec, filename + '.native') + shutil.copymode(native_exec, filename + '.native') global total_native_times native_times = [] for i in range(reps): @@ -12575,7 +12776,10 @@ elif 'benchmark' in str(sys.argv): if i == 0: # Sanity check on output self.assertContained(expected_output, native_output) - curr = time.time()-start + if not output_parser: + curr = time.time()-start + else: + curr = output_parser(native_output) native_times.append(curr) total_native_times[tests_done] += curr @@ -12620,7 +12824,7 @@ elif 'benchmark' in str(sys.argv): return 0; } ''' - self.do_benchmark('primes', src, [], 'lastprime: 3043739.') + self.do_benchmark('primes', src, 'lastprime:') def test_memops(self): src = ''' @@ -12653,7 +12857,7 @@ elif 'benchmark' in str(sys.argv): return 0; } ''' - self.do_benchmark('memops', src, [], 'final: 400.') + self.do_benchmark('memops', src, 'final:') def zzztest_files(self): src = r''' @@ -12696,7 +12900,7 @@ elif 'benchmark' in str(sys.argv): return 0; } ''' - self.do_benchmark(src, [], 'ok') + self.do_benchmark(src, 'ok') def test_copy(self): src = r''' @@ -12750,7 +12954,7 @@ elif 'benchmark' in str(sys.argv): return 0; } ''' - self.do_benchmark('copy', src, [], 'sum:2836\n') + self.do_benchmark('copy', src, 'sum:') def test_fannkuch(self): src = open(path_from_root('tests', 'fannkuch.cpp'), 'r').read().replace( @@ -12770,7 +12974,7 @@ elif 'benchmark' in str(sys.argv): ''' ) assert 'switch(arg)' in src - self.do_benchmark('fannkuch', src, [], 'Pfannkuchen(11) = 51.') + self.do_benchmark('fannkuch', src, 'Pfannkuchen(') def test_corrections(self): src = r''' @@ -12803,7 +13007,7 @@ elif 'benchmark' in str(sys.argv): return 0; } ''' - self.do_benchmark('corrections', src, [], 'final: 40006013:10225.', emcc_args=['-s', 'CORRECT_SIGNS=1', '-s', 'CORRECT_OVERFLOWS=1', '-s', 'CORRECT_ROUNDINGS=1']) + self.do_benchmark('corrections', src, 'final:', emcc_args=['-s', 'CORRECT_SIGNS=1', '-s', 'CORRECT_OVERFLOWS=1', '-s', 'CORRECT_ROUNDINGS=1']) def fasta(self, name, double_rep, emcc_args=[]): src = open(path_from_root('tests', 'fasta.cpp'), 'r').read().replace('double', double_rep) @@ -12821,7 +13025,7 @@ elif 'benchmark' in str(sys.argv): } ''') assert 'switch(arg)' in src - self.do_benchmark('fasta', src, [], '''GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA\nTCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT\nAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG\nGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG\nCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT\nGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA\nGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA\nTTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG\nAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA\nGCCTGGGCGA''') + self.do_benchmark('fasta', src, '') def test_fasta_float(self): self.fasta('fasta_float', 'float') @@ -12834,57 +13038,66 @@ elif 'benchmark' in str(sys.argv): def test_skinning(self): src = open(path_from_root('tests', 'skinning_test_no_simd.cpp'), 'r').read() - self.do_benchmark('skinning', src, [], 'blah=0.000000') + self.do_benchmark('skinning', src, 'blah=0.000000') def test_life(self): src = open(path_from_root('tests', 'life.c'), 'r').read() - self.do_benchmark('life', src, [], '''-------------------------------- - [][] [] [] - [][] [][] [] [] - [][] [] [] - [][] [] [] - [] [][] [] - [][] [] [] [] [] - [][] [] [] [] [] - [] [][] [] - [][] [][] - [][] [][] [] [] - [][] [][] [][] [] - [][] [] - [] - [] - [] [] -[] [][][] [] [] - [] [][][][][][] [] [][] - [] [][] [] [] [][] [] [] -[] [] [][] [] [] - [][] [] [][][] [][] - [] [] [][][] - [][] [][][][] - [][] [][] [] - [] [][] [] - [][] - [][] [] - [] [][][][][] -[][][] [][] - [][] [] [][][] - [] [] [][] - [] - [] [][] [][][] ---------------------------------''', shared_args=['-std=c99'], force_c=True) - - def test_zlib(self): + self.do_benchmark('life', src, '''--------------------------------''', shared_args=['-std=c99'], force_c=True) + + def test_zzz_java_nbody(self): # tests xmlvm compiled java, including bitcasts of doubles, i64 math, etc. + args = [path_from_root('tests', 'nbody-java', x) for x in os.listdir(path_from_root('tests', 'nbody-java')) if x.endswith('.c')] + \ + ['-I' + path_from_root('tests', 'nbody-java')] + self.do_benchmark('nbody_java', '', '''Time(s)''', + force_c=True, emcc_args=args + ['-s', 'PRECISE_I64_MATH=1', '--llvm-lto', '0'], native_args=args + ['-lgc', '-std=c99', '-target', 'x86_64-pc-linux-gnu', '-lm']) + + def lua(self, benchmark, expected, output_parser=None, args_processor=None): + shutil.copyfile(path_from_root('tests', 'lua', benchmark + '.lua'), benchmark + '.lua') + #shutil.copyfile(path_from_root('tests', 'lua', 'binarytrees.lua'), 'binarytrees.lua') + #shutil.copyfile(path_from_root('tests', 'lua', 'scimark.lua'), 'scimark.lua') + emcc_args = self.get_library('lua', [os.path.join('src', 'lua'), os.path.join('src', 'liblua.a')], make=['make', 'generic'], configure=None) + \ + ['--embed-file', benchmark + '.lua'] + #['--embed-file', 'binarytrees.lua', '--embed-file', 'scimark.lua'] + ['--minify', '0'] + shutil.copyfile(emcc_args[0], emcc_args[0] + '.bc') + emcc_args[0] += '.bc' + native_args = self.get_library('lua_native', [os.path.join('src', 'lua'), os.path.join('src', 'liblua.a')], make=['make', 'generic'], configure=None, native=True) + + self.do_benchmark('lua_' + benchmark, '', expected, + force_c=True, args=[benchmark + '.lua'], emcc_args=emcc_args, native_args=native_args, native_exec=os.path.join('building', 'lua_native', 'src', 'lua'), + output_parser=output_parser, args_processor=args_processor) + + def test_zzz_lua_scimark(self): + def output_parser(output): + return 1.0/float(re.search('\nSciMark +([\d\.]+) ', output).group(1)) + + self.lua('scimark', '[small problem sizes]', output_parser=output_parser) + + def test_zzz_lua_binarytrees(self): + def args_processor(args): + arg = int(DEFAULT_ARG) + if arg == 0: + return args + ['0'] + elif arg == 1: + return args + ['9.5'] + elif arg == 2: + return args + ['11.99'] + elif arg == 3: + return args + ['12.85'] + elif arg == 4: + return args + ['14.72'] + elif arg == 5: + return args + ['15.82'] + self.lua('binarytrees', 'long lived tree of depth', args_processor=args_processor) + + def test_zzz_zlib(self): src = open(path_from_root('tests', 'zlib', 'benchmark.c'), 'r').read() emcc_args = self.get_library('zlib', os.path.join('libz.a'), make_args=['libz.a']) + \ ['-I' + path_from_root('tests', 'zlib')] native_args = self.get_library('zlib_native', os.path.join('libz.a'), make_args=['libz.a'], native=True) + \ ['-I' + path_from_root('tests', 'zlib')] - self.do_benchmark('zlib', src, [], '''sizes: 100000,25906 -ok. -''', + self.do_benchmark('zlib', src, '''ok.''', force_c=True, emcc_args=emcc_args, native_args=native_args) - def test_yyy_box2d(self): # Called thus so it runs late in the alphabetical cycle... it is long + def test_zzz_box2d(self): # Called thus so it runs late in the alphabetical cycle... it is long src = open(path_from_root('tests', 'box2d', 'Benchmark.cpp'), 'r').read() js_lib = self.get_library('box2d', [os.path.join('box2d.a')], configure=None) @@ -12893,7 +13106,7 @@ ok. emcc_args = js_lib + ['-I' + path_from_root('tests', 'box2d')] native_args = native_lib + ['-I' + path_from_root('tests', 'box2d')] - self.do_benchmark('box2d', src, [], 'frame averages', emcc_args=emcc_args, native_args=native_args) + self.do_benchmark('box2d', src, 'frame averages', emcc_args=emcc_args, native_args=native_args) def test_zzz_bullet(self): # Called thus so it runs late in the alphabetical cycle... it is long src = open(path_from_root('tests', 'bullet', 'Demos', 'Benchmarks', 'BenchmarkDemo.cpp'), 'r').read() + \ @@ -12915,7 +13128,7 @@ ok. native_args = native_lib + ['-I' + path_from_root('tests', 'bullet', 'src'), '-I' + path_from_root('tests', 'bullet', 'Demos', 'Benchmarks')] - self.do_benchmark('bullet', src, [], '\nok.\n', emcc_args=emcc_args, native_args=native_args) + self.do_benchmark('bullet', src, '\nok.\n', emcc_args=emcc_args, native_args=native_args) elif 'sanity' in str(sys.argv): @@ -13419,8 +13632,17 @@ if __name__ == '__main__': arg = sys.argv[i] if arg.startswith('skip:'): which = arg.split('skip:')[1] - print >> sys.stderr, 'will skip "%s"' % which - exec(which + ' = RunnerCore.skipme') + if which.startswith('ALL.'): + ignore, test = which.split('.') + which = map(lambda mode: mode+'.'+test, test_modes) + else: + which = [which] + + print >> sys.stderr, ','.join(which) + for test in which: + print >> sys.stderr, 'will skip "%s"' % test + exec(test + ' = RunnerCore.skipme') + sys.argv[i] = '' sys.argv = filter(lambda arg: arg, sys.argv) |