aboutsummaryrefslogtreecommitdiff
path: root/tests/runner.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/runner.py')
-rwxr-xr-xtests/runner.py185
1 files changed, 146 insertions, 39 deletions
diff --git a/tests/runner.py b/tests/runner.py
index 5b0ef965..570bfbf2 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -78,6 +78,8 @@ class RunnerCore(unittest.TestCase):
stderr_redirect = STDOUT # This avoids cluttering the test runner output, which is stderr too, with compiler warnings etc.
# Change this to None to get stderr reporting, for debugging purposes
+ env = {}
+
def skipme(self): # used by tests we ask on the commandline to be skipped, see right before call to unittest.main
return self.skip('requested to be skipped')
@@ -238,10 +240,7 @@ process(sys.argv[1])
os.remove(f + '.o')
except:
pass
- compiler_flags = ['-emit-llvm']
- if not f.endswith('.c'):
- compiler_flags = compiler_flags + ['-std=c++03']
- args = [Building.COMPILER] + compiler_flags + COMPILER_OPTS + Building.COMPILER_TEST_OPTS + \
+ args = [PYTHON, EMCC] + Building.COMPILER_TEST_OPTS + \
['-I', dirname, '-I', os.path.join(dirname, 'include')] + \
map(lambda include: '-I' + include, includes) + \
['-c', f, '-o', f + '.o']
@@ -358,7 +357,8 @@ process(sys.argv[1])
build_dir = self.get_build_dir()
output_dir = self.get_dir()
- cache_name = name + cache_name_extra
+ cache_name = name + cache_name_extra + (self.env.get('EMCC_LLVM_TARGET') or '')
+
if self.library_cache is not None:
if cache and self.library_cache.get(cache_name):
print >> sys.stderr, '<load %s from cache> ' % cache_name,
@@ -455,7 +455,7 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows
if len(sys.argv) == 2 and 'ALL.' in sys.argv[1]:
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, 's_0_0.'+test, 's_0_1.'+test, 's_1_0.'+test, 's_1_1.'+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]
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.
@@ -506,6 +506,9 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows
output_nicerizer=output_nicerizer,
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'
+
def test_hello_world(self):
src = '''
#include <stdio.h>
@@ -1500,7 +1503,11 @@ Succeeded!
'''
# TODO: A version of this with int64s as well
- self.do_run(src, '*12 : 1 : 12\n328157500735811.0,23,416012775903557.0,99\n')
+
+ if self.is_le32():
+ return self.skip('LLVM marks the reads of s as fully aligned, making this test invalid')
+ else:
+ self.do_run(src, '*12 : 1 : 12\n328157500735811.0,23,416012775903557.0,99\n')
return # TODO: continue to the next part here
@@ -1534,6 +1541,62 @@ Succeeded!
except Exception, e:
assert 'must be aligned' in str(e), e # expected to fail without emulation
+ def test_align64(self):
+ src = r'''
+ #include <stdio.h>
+
+ // inspired by poppler
+
+ enum Type {
+ A = 10,
+ B = 20
+ };
+
+ struct Object {
+ Type type;
+ union {
+ int intg;
+ double real;
+ char *name;
+ };
+ };
+
+ struct Principal {
+ double x;
+ Object a;
+ double y;
+ };
+
+ int main(int argc, char **argv)
+ {
+ int base = argc-1;
+ Object *o = NULL;
+ printf("%d,%d\n", sizeof(Object), sizeof(Principal));
+ printf("%d,%d,%d,%d\n", (int)&o[base].type, (int)&o[base].intg, (int)&o[base].real, (int)&o[base].name);
+ printf("%d,%d,%d,%d\n", (int)&o[base+1].type, (int)&o[base+1].intg, (int)&o[base+1].real, (int)&o[base+1].name);
+ Principal p, q;
+ p.x = p.y = q.x = q.y = 0;
+ p.a.type = A;
+ p.a.real = 123.456;
+ *(&q.a) = p.a;
+ printf("%.2f,%d,%.2f,%.2f : %.2f,%d,%.2f,%.2f\n", p.x, p.a.type, p.a.real, p.y, q.x, q.a.type, q.a.real, q.y);
+ return 0;
+ }
+ '''
+
+ if self.is_le32():
+ self.do_run(src, '''16,32
+0,8,8,8
+16,24,24,24
+0.00,10,123.46,0.00 : 0.00,10,123.46,0.00
+''')
+ else:
+ self.do_run(src, '''12,28
+0,4,4,4
+12,16,16,16
+0.00,10,123.46,0.00 : 0.00,10,123.46,0.00
+''')
+
def test_unsigned(self):
Settings.CORRECT_SIGNS = 1 # We test for exactly this sort of thing here
Settings.CHECK_SIGNS = 0
@@ -3272,6 +3335,36 @@ Exiting setjmp function, level: 0, prev_jmp: -1
'''
self.do_run(src, '*0x1*')
+ def test_funcptr_namecollide(self):
+ src = r'''
+ #include <stdio.h>
+
+ void do_call(void (*puts)(const char *), const char *str);
+
+ void do_print(const char *str) {
+ if (!str) do_call(NULL, "delusion");
+ if ((int)str == -1) do_print(str+10);
+ puts("====");
+ puts(str);
+ puts("====");
+ }
+
+ void do_call(void (*puts)(const char *), const char *str) {
+ if (!str) do_print("confusion");
+ if ((int)str == -1) do_call(NULL, str-10);
+ (*puts)(str);
+ }
+
+ int main(int argc, char **argv)
+ {
+ for (int i = 0; i < argc; i++) {
+ do_call(i != 10 ? do_print : NULL, i != 15 ? "waka waka" : NULL);
+ }
+ return 0;
+ }
+ '''
+ self.do_run(src, 'waka', force_c=True)
+
def test_emptyclass(self):
if self.emcc_args is None: return self.skip('requires emcc')
src = '''
@@ -3650,7 +3743,10 @@ Exiting setjmp function, level: 0, prev_jmp: -1
# Compressed memory. Note that sizeof() does give the fat sizes, however!
self.do_run(src, '*0,0,0,1,2,3,4,5*\n*1,0,0*\n*0*\n0:1,1\n1:1,1\n2:1,1\n*12,20,5*')
else:
- self.do_run(src, '*0,0,0,4,8,12,16,20*\n*1,0,0*\n*0*\n0:1,1\n1:1,1\n2:1,1\n*12,20,20*')
+ if self.is_le32():
+ self.do_run(src, '*0,0,0,4,8,16,20,24*\n*1,0,0*\n*0*\n0:1,1\n1:1,1\n2:1,1\n*16,24,24*')
+ else:
+ self.do_run(src, '*0,0,0,4,8,12,16,20*\n*1,0,0*\n*0*\n0:1,1\n1:1,1\n2:1,1\n*12,20,20*')
def test_ptrtoint(self):
if self.emcc_args is None: return self.skip('requires emcc')
@@ -4073,6 +4169,7 @@ def process(filename):
def test_varargs_byval(self):
if Settings.USE_TYPED_ARRAYS != 2: return self.skip('FIXME: Add support for this')
+ if self.is_le32(): return self.skip('clang cannot compile this code with that target yet')
src = r'''
#include <stdio.h>
@@ -4247,7 +4344,10 @@ The current type of b is: 9
output = Popen([PYTHON, EMCC, all_name], stderr=PIPE).communicate()
# Check for warning in the generated code
generated = open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read()
- assert 'Casting a function pointer type to another with a different number of arguments' in output[1], 'Missing expected warning'
+ if 'i386-pc-linux-gnu' in COMPILER_OPTS:
+ assert 'Casting a function pointer type to another with a different number of arguments' in output[1], 'Missing expected warning'
+ else:
+ print >> sys.stderr, 'skipping C/C++ conventions warning check, since not i386-pc-linux-gnu'
def test_stdlibs(self):
if self.emcc_args is None: return self.skip('requires emcc')
@@ -7331,7 +7431,7 @@ operator new(size_t size)
self.do_run(src, 'new 4!\n*1,0*')
def test_dlmalloc_partial_2(self):
- if self.emcc_args is None or 'SAFE_HEAP' in str(self.emcc_args): return self.skip('only emcc will link in dlmalloc, and we do unsafe stuff')
+ if self.emcc_args is None or 'SAFE_HEAP' in str(self.emcc_args) or 'CHECK_HEAP_ALIGN' in str(self.emcc_args): return self.skip('only emcc will link in dlmalloc, and we do unsafe stuff')
# present part of the symbols of dlmalloc, not all. malloc is harder to link than new which is weak.
src = r'''
#include <stdio.h>
@@ -7594,20 +7694,14 @@ void*:16
def test_lua(self):
if self.emcc_args is None: return self.skip('requires emcc')
-
if Settings.QUANTUM_SIZE == 1: return self.skip('TODO: make this work')
- # Overflows in luaS_newlstr hash loop
- if self.emcc_args is None: Settings.SAFE_HEAP = 0 # Has various warnings, with copied HEAP_HISTORY values (fixed if we copy 'null' as the type)
- Settings.CORRECT_OVERFLOWS = 1
- Settings.CHECK_OVERFLOWS = 0
- Settings.CORRECT_SIGNS = 1 # Not sure why, but needed
-
- self.do_ll_run(path_from_root('tests', 'lua', 'lua.ll'),
- 'hello lua world!\n17\n1\n2\n3\n4\n7',
- args=['-e', '''print("hello lua world!");print(17);for x = 1,4 do print(x) end;print(10-3)'''],
- output_nicerizer=lambda string, err: (string + err).replace('\n\n', '\n').replace('\n\n', '\n'),
- extra_emscripten_args=['-H', 'libc/fcntl.h,libc/sys/unistd.h,poll.h,libc/math.h,libc/langinfo.h,libc/time.h'])
+ self.do_run('',
+ 'hello lua world!\n17\n1\n2\n3\n4\n7',
+ args=['-e', '''print("hello lua world!");print(17);for x = 1,4 do print(x) end;print(10-3)'''],
+ libraries=self.get_library('lua', [os.path.join('src', 'lua'), os.path.join('src', 'liblua.a')], make=['make', 'generic'], configure=None),
+ includes=[path_from_root('tests', 'lua')],
+ output_nicerizer=lambda string, err: (string + err).replace('\n\n', '\n').replace('\n\n', '\n'))
def get_freetype(self):
Settings.DEAD_FUNCTIONS += ['_inflateEnd', '_inflate', '_inflateReset', '_inflateInit2_']
@@ -7912,14 +8006,14 @@ def process(filename):
if self.emcc_args is None: return self.skip('requires emcc')
if Settings.QUANTUM_SIZE == 1: return self.skip('TODO: make this work')
- # Overflows in string_hash
- Settings.CORRECT_OVERFLOWS = 1
- Settings.CHECK_OVERFLOWS = 0
- if self.emcc_args is None: Settings.SAFE_HEAP = 0 # Has bitfields which are false positives. Also the PyFloat_Init tries to detect endianness.
- Settings.CORRECT_SIGNS = 1 # Not sure why, but needed
- Settings.EXPORTED_FUNCTIONS += ['_PyRun_SimpleStringFlags'] # for the demo
+ #Settings.EXPORTED_FUNCTIONS += ['_PyRun_SimpleStringFlags'] # for the demo
+
+ if self.is_le32():
+ bitcode = path_from_root('tests', 'python', 'python.le32.bc')
+ else:
+ bitcode = path_from_root('tests', 'python', 'python.small.bc')
- self.do_ll_run(path_from_root('tests', 'python', 'python.small.bc'),
+ self.do_ll_run(bitcode,
'hello python world!\n[0, 2, 4, 6]\n5\n22\n5.470000',
args=['-S', '-c' '''print "hello python world!"; print [x*2 for x in range(4)]; t=2; print 10-3-t; print (lambda x: x*2)(11); print '%f' % 5.47'''])
@@ -9155,15 +9249,24 @@ finalizing 3 (global == 0)
''')
# Generate tests for everything
- def make_run(fullname, name=-1, compiler=-1, llvm_opts=0, embetter=0, quantum_size=0, typed_arrays=0, emcc_args=None):
+ 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):
+ env = %s
+
def tearDown(self):
super(%s, self).tearDown()
+ for k, v in self.env.iteritems():
+ del os.environ[k]
+
def setUp(self):
super(%s, self).setUp()
+ for k, v in self.env.iteritems():
+ assert k not in os.environ, k + ' should not be in environment'
+ os.environ[k] = v
+
Building.COMPILER_TEST_OPTS = ['-g']
os.chdir(self.get_dir()) # Ensure the directory exists and go there
Building.COMPILER = %r
@@ -9207,7 +9310,7 @@ class %s(T):
Building.pick_llvm_opts(3)
TT = %s
-''' % (fullname, fullname, fullname, compiler, str(emcc_args), llvm_opts, embetter, quantum_size, typed_arrays, 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
@@ -9220,9 +9323,10 @@ TT = %s
exec('o2 = make_run("o2", compiler=CLANG, emcc_args=["-O2", "-s", "ASM_JS=0", "-s", "JS_CHUNK_SIZE=1024"])')
# asm.js
- exec('asm1 = make_run("asm1", compiler=CLANG, emcc_args=["-O1"])')
+ 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"}')''')
# Make custom runs with various options
for compiler, quantum, embetter, typed_arrays, llvm_opts in [
@@ -12671,7 +12775,7 @@ elif 'benchmark' in str(sys.argv):
'''
self.do_benchmark('corrections', src, [], 'final: 40006013:10225.', emcc_args=['-s', 'CORRECT_SIGNS=1', '-s', 'CORRECT_OVERFLOWS=1', '-s', 'CORRECT_ROUNDINGS=1'])
- def fasta(self, double_rep):
+ def fasta(self, name, double_rep, emcc_args=[]):
src = open(path_from_root('tests', 'fasta.cpp'), 'r').read().replace('double', double_rep)
src = src.replace(' const size_t n = ( argc > 1 ) ? atoi( argv[1] ) : 512;', '''
int n;
@@ -12690,10 +12794,13 @@ elif 'benchmark' in str(sys.argv):
self.do_benchmark('fasta', src, [], '''GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA\nTCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT\nAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG\nGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG\nCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT\nGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA\nGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA\nTTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG\nAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA\nGCCTGGGCGA''')
def test_fasta_float(self):
- self.fasta('float')
+ self.fasta('fasta_float', 'float')
+
+ def test_fasta_double(self):
+ self.fasta('fasta_double', 'double')
- def zzztest_fasta_double(self):
- self.fasta('double')
+ def test_fasta_double_full(self):
+ self.fasta('fasta_double_full', 'double', emcc_args=['-s', 'DOUBLE_MODE=1'])
def test_skinning(self):
src = open(path_from_root('tests', 'skinning_test_no_simd.cpp'), 'r').read()
@@ -13008,7 +13115,7 @@ fi
self.assertContained(SANITY_MESSAGE, output)
assert os.path.exists(SANITY_FILE) # EMCC should have checked sanity successfully
assert mtime(SANITY_FILE) >= mtime(CONFIG_FILE)
- assert open(SANITY_FILE).read() == EMSCRIPTEN_VERSION
+ assert generate_sanity() == open(SANITY_FILE).read()
self.assertNotContained(SANITY_FAIL_MESSAGE, output)
# emcc run again should not sanity check, because the sanity file is newer
@@ -13017,7 +13124,7 @@ fi
self.assertNotContained(SANITY_FAIL_MESSAGE, output)
# correct sanity contents mean we need not check
- open(SANITY_FILE, 'w').write(EMSCRIPTEN_VERSION)
+ open(SANITY_FILE, 'w').write(generate_sanity())
output = self.check_working(EMCC)
self.assertNotContained(SANITY_MESSAGE, output)
@@ -13241,7 +13348,7 @@ fi
print >> sys.stderr, args, input_file, expect_pre_save, expect_pre_load, expect_funcs_save, expect_funcs_load, expect_jsfuncs_save, expect_jsfuncs_load, expected
- out, err = Popen([PYTHON, EMCC, '-O2', path_from_root('tests', input_file)] + args, stdout=PIPE, stderr=PIPE).communicate()
+ out, err = Popen([PYTHON, EMCC, '-O2', '-g', path_from_root('tests', input_file)] + args, stdout=PIPE, stderr=PIPE).communicate()
errtail = err.split('emcc invocation')[-1]
self.assertContained('hello, world!', run_js('a.out.js'), errtail)
assert (PRE_SAVE_MSG in err) == expect_pre_save, errtail