diff options
Diffstat (limited to 'tests/runner.py')
-rwxr-xr-x | tests/runner.py | 118 |
1 files changed, 100 insertions, 18 deletions
diff --git a/tests/runner.py b/tests/runner.py index 503458c0..a553620f 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -131,7 +131,11 @@ process(sys.argv[1]) f = open(filename, 'w') f.write(src) f.close() - assert len(additional_files) == 0 + final_additional_files = [] + for f in additional_files: + final_additional_files.append(os.path.join(dirname, os.path.basename(f))) + shutil.copyfile(f, final_additional_files[-1]) + additional_files = final_additional_files else: # copy whole directory, and use a specific main .cpp file shutil.rmtree(dirname) @@ -139,10 +143,9 @@ process(sys.argv[1]) shutil.move(os.path.join(dirname, main_file), filename) # the additional files were copied; alter additional_files to point to their full paths now additional_files = map(lambda f: os.path.join(dirname, f), additional_files) + os.chdir(self.get_dir()) # C++ => LLVM binary - os.chdir(dirname) - cwd = os.getcwd() for f in [filename] + additional_files: try: @@ -157,8 +160,6 @@ process(sys.argv[1]) output = Popen(args, stdout=PIPE, stderr=self.stderr_redirect).communicate()[0] assert os.path.exists(f + '.o'), 'Source compilation error: ' + output - os.chdir(cwd) - # Link all files if len(additional_files) + len(libraries) > 0: shutil.move(filename + '.o', filename + '.o.alone') @@ -254,6 +255,8 @@ process(sys.argv[1]) sys.argv = map(lambda arg: arg if not arg.startswith('test_') else 'default.' + arg, sys.argv) +Cache.erase() # Wipe the cache, so that we always test populating it in the tests, benchmarks, etc. + if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv): # Tests @@ -2490,6 +2493,9 @@ def process(filename): def test_runtimelink(self): if Building.LLVM_OPTS: return self.skip('LLVM opts will optimize printf into puts in the parent, and the child will still look for puts') + + Settings.LINKABLE = 1 + self.banned_js_engines = [NODE_JS] # node's global scope behaves differently than everything else, needs investigation FIXME header = r''' @@ -2550,6 +2556,8 @@ def process(filename): self.do_run(main, 'supp: 54,2\nmain: 56\nsupp see: 543\nmain see: 76\nok.') def test_dlfcn_basic(self): + Settings.LINKABLE = 1 + lib_src = ''' #include <cstdio> @@ -2599,6 +2607,8 @@ def process(filename): post_build=add_pre_run_and_checks) def test_dlfcn_qsort(self): + Settings.LINKABLE = 1 + if Settings.USE_TYPED_ARRAYS == 2: Settings.CORRECT_SIGNS = 1 # Needed for unsafe optimizations @@ -2691,6 +2701,8 @@ def process(filename): def test_dlfcn_data_and_fptr(self): if Building.LLVM_OPTS: return self.skip('LLVM opts will optimize out parent_func') + Settings.LINKABLE = 1 + lib_src = ''' #include <stdio.h> @@ -2789,6 +2801,8 @@ def process(filename): post_build=add_pre_run_and_checks) def test_dlfcn_alias(self): + Settings.LINKABLE = 1 + if Building.LLVM_OPTS == 2: return self.skip('LLVM LTO will optimize away stuff we expect from the shared library') lib_src = r''' @@ -2841,6 +2855,8 @@ def process(filename): Settings.INCLUDE_FULL_LIBRARY = 0 def test_dlfcn_varargs(self): + Settings.LINKABLE = 1 + if Building.LLVM_OPTS == 2: return self.skip('LLVM LTO will optimize things that prevent shared objects from working') if Settings.QUANTUM_SIZE == 1: return self.skip('FIXME: Add support for this') @@ -3822,6 +3838,30 @@ def process(filename): self.do_run(src, expected) CORRECT_SIGNS = 0 + def test_atomic(self): + src = ''' + #include <stdio.h> + int main() { + int x = 10; + int y = __sync_add_and_fetch(&x, 5); + printf("*%d,%d*\\n", x, y); + x = 10; + y = __sync_fetch_and_add(&x, 5); + printf("*%d,%d*\\n", x, y); + x = 10; + y = __sync_lock_test_and_set(&x, 6); + printf("*%d,%d*\\n", x, y); + x = 10; + y = __sync_bool_compare_and_swap(&x, 9, 7); + printf("*%d,%d*\\n", x, y); + y = __sync_bool_compare_and_swap(&x, 10, 7); + printf("*%d,%d*\\n", x, y); + return 0; + } + ''' + + self.do_run(src, '*15,15*\n*15,10*\n*6,10*\n*10,0*\n*7,1*') + # libc++ tests def test_iostream(self): @@ -3835,7 +3875,8 @@ def process(filename): } ''' - self.do_run(src, 'hello world\n77.\n') + # FIXME: should not have so many newlines in output here + self.do_run(src, 'hello world\n\n77.\n') def test_stdvec(self): src = ''' @@ -3899,7 +3940,7 @@ def process(filename): Settings.CORRECT_SIGNS_LINES = ['src.cpp:' + str(i+4) for i in [4816, 4191, 4246, 4199, 4205, 4235, 4227]] Settings.TOTAL_MEMORY = 100*1024*1024 # needed with typed arrays - src = open(path_from_root('src', 'dlmalloc.c'), 'r').read() + '\n\n\n' + open(path_from_root('tests', 'dlmalloc_test.c'), 'r').read() + src = open(path_from_root('system', 'lib', 'dlmalloc.c'), 'r').read() + '\n\n\n' + open(path_from_root('tests', 'dlmalloc_test.c'), 'r').read() self.do_run(src, '*1,0*', ['200', '1']) self.do_run(src, '*400,0*', ['400', '400'], no_build=True) @@ -3930,13 +3971,9 @@ def process(filename): self.do_run(src.replace('{{{ NEW }}}', new).replace('{{{ DELETE }}}', delete), '*1,0*') def test_libcxx(self): - self.do_run(path_from_root('tests', 'libcxx'), - 'june -> 30\nPrevious (in alphabetical order) is july\nNext (in alphabetical order) is march', - main_file='main.cpp', additional_files=['hash.cpp']) + self.do_run(open(path_from_root('tests', 'hashtest.cpp')).read(), + 'june -> 30\nPrevious (in alphabetical order) is july\nNext (in alphabetical order) is march') - # This will fail without using libcxx, as libstdc++ (gnu c++ lib) will use but not link in - # __ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_ - # So a way to avoid that problem is to include libcxx, as done here self.do_run(''' #include <set> #include <stdio.h> @@ -3946,7 +3983,7 @@ def process(filename): printf("hello world\\n"); return 1; } - ''', 'hello world', includes=[path_from_root('tests', 'libcxx', 'include')]); + ''', 'hello world'); def test_static_variable(self): Settings.SAFE_HEAP = 0 # LLVM mixes i64 and i8 in the guard check @@ -4394,6 +4431,7 @@ def process(filename): # Compare to each other, and to expected output self.do_ll_run(path_from_root('tests', filename+'.o.ll.ll')) + assert open('stdout').read().startswith('AD:-1'), 'We must note when we enter functions' # Test using build_ll_hook src = ''' @@ -5847,7 +5885,7 @@ elif 'benchmark' in str(sys.argv): def test_dlmalloc(self): # XXX This seems to have regressed slightly with emcc. Are -g and the signs lines passed properly? - src = open(path_from_root('src', 'dlmalloc.c'), 'r').read() + '\n\n\n' + open(path_from_root('tests', 'dlmalloc_test.c'), 'r').read() + src = open(path_from_root('system', 'lib', 'dlmalloc.c'), 'r').read() + '\n\n\n' + open(path_from_root('tests', 'dlmalloc_test.c'), 'r').read() self.do_benchmark(src, ['400', '400'], '*400,0*', emcc_args=['-g', '-s', 'CORRECT_SIGNS=2', '-s', 'CORRECT_SIGNS_LINES=[4820, 4195, 4250, 4203, 4209, 4239, 4231]']) elif 'sanity' in str(sys.argv): @@ -5875,6 +5913,9 @@ elif 'sanity' in str(sys.argv): commands = [[EMCC], ['python', path_from_root('tests', 'runner.py'), 'blahblah']] + def mtime(filename): + return os.stat(filename).st_mtime + class sanity(RunnerCore): def setUp(self): wipe() @@ -5962,9 +6003,6 @@ elif 'sanity' in str(sys.argv): assert os.path.exists('a.out.js') def test_emcc(self): - def mtime(filename): - return os.stat(filename).st_mtime - SANITY_MESSAGE = 'Emscripten: Running sanity checks' SANITY_FAIL_MESSAGE = 'sanity check failed to run' @@ -6002,6 +6040,50 @@ elif 'sanity' in str(sys.argv): assert mtime(SANITY_FILE) >= mtime(CONFIG_FILE) self.assertNotContained(SANITY_FAIL_MESSAGE, output) + def test_emcc_caching(self): + INCLUDING_MESSAGE = 'emcc: including X' + BUILDING_MESSAGE = 'emcc: building X for cache' + + EMCC_CACHE = Cache.dirname + + restore() + + Cache.erase() + assert not os.path.exists(EMCC_CACHE) + + try: + emcc_debug = os.environ.get('EMCC_DEBUG') + os.environ['EMCC_DEBUG'] ='1' + + # Building a file that doesn't need cached stuff should not trigger cache generation + output = self.do([EMCC, path_from_root('tests', 'hello_world.cpp')]) + assert INCLUDING_MESSAGE.replace('X', 'dlmalloc') not in output + assert BUILDING_MESSAGE.replace('X', 'dlmalloc') not in output + self.assertContained('hello, world!', run_js('a.out.js')) + assert not os.path.exists(EMCC_CACHE) + try_delete('a.out.js') + + # Building a file that *does* need dlmalloc *should* trigger cache generation, but only the first time + for filename, libname in [('hello_malloc.cpp', 'dlmalloc'), ('hello_libcxx.cpp', 'libcxx')]: + for i in range(3): + try_delete(os.path.join(EMSCRIPTEN_TEMP_DIR, 'emcc-0-bc.bc')) # we might need to check this file later + output = self.do([EMCC, path_from_root('tests', filename)]) + assert INCLUDING_MESSAGE.replace('X', libname) in output + if libname == 'dlmalloc': + assert INCLUDING_MESSAGE.replace('X', 'libcxx') not in output # we don't need libcxx in this code + else: + assert INCLUDING_MESSAGE.replace('X', 'dlmalloc') in output # libcxx always forces inclusion of dlmalloc + assert (BUILDING_MESSAGE.replace('X', libname) in output) == (i == 0), 'Must only build the first time' + self.assertContained('hello, world!', run_js('a.out.js')) + assert os.path.exists(EMCC_CACHE) + assert os.path.exists(os.path.join(EMCC_CACHE, libname + '.bc')) + if libname == 'libcxx': + assert os.stat(os.path.join(EMCC_CACHE, libname + '.bc')).st_size > 4000000, 'libc++ is big' + assert os.stat(os.path.join(EMSCRIPTEN_TEMP_DIR, 'emcc-0-bc.bc')).st_size < 2000000, 'Dead code elimination must remove most of libc++' + finally: + if emcc_debug: + os.environ['EMCC_DEBUG'] = emcc_debug + else: raise Exception('Test runner is confused: ' + str(sys.argv)) |