aboutsummaryrefslogtreecommitdiff
path: root/tests/runner.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/runner.py')
-rwxr-xr-xtests/runner.py118
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))