aboutsummaryrefslogtreecommitdiff
path: root/tests/runner.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/runner.py')
-rwxr-xr-xtests/runner.py239
1 files changed, 215 insertions, 24 deletions
diff --git a/tests/runner.py b/tests/runner.py
index 99c536e3..529dcc48 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -829,11 +829,14 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows
int add_low = add;
int add_high = add >> 32;
printf("*%lld,%lld,%u,%u*\n", mul, add, add_low, add_high);
+ int64 x = sec + (usec << 25);
+ x >>= argc*3;
+ printf("*%llu*\n", x);
return 0;
}
'''
- self.do_run(src, '*1329409676000000,1329412005509675,3663280683,309527*\n')
+ self.do_run(src, '*1329409676000000,1329412005509675,3663280683,309527*\n*9770671914067409*\n')
def test_i64_cmp(self):
if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2')
@@ -1003,12 +1006,6 @@ m_divisor is 1091269979
'''
self.do_run(src, open(path_from_root('tests', 'i64_precise.txt')).read())
- # Verify that without precision, we do not include the precision code
- Settings.PRECISE_I64_MATH = 0
- self.do_run(src, 'unsigned')
- code = open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read()
- assert 'goog.math.Long' not in code, 'i64 precise math should not have been included if not asked for'
-
# Verify that even if we ask for precision, if it is not needed it is not included
Settings.PRECISE_I64_MATH = 1
src = '''
@@ -1890,13 +1887,34 @@ Succeeded!
printf("%s\\n", strdup_val);
free(strdup_val);
+ {
+ char *one = "one 1 ONE !";
+ char *two = "two 2 TWO ?";
+ char three[1024];
+ memset(three, '.', 1024);
+ three[50] = 0;
+ strncpy(three + argc, one + (argc/2), argc+1);
+ strncpy(three + argc*3, two + (argc/3), argc+2);
+ printf("waka %s\\n", three);
+ }
+
+ {
+ char *one = "string number one top notch";
+ char *two = "fa la sa ho fi FI FO FUM WHEN WHERE WHY HOW WHO";
+ char three[1000];
+ strcpy(three, &one[argc*2]);
+ strcat(three, &two[argc*3]);
+ printf("cat |%s|\\n", three);
+ }
+
return 0;
}
'''
for named in (0, 1):
print named
Settings.NAMED_GLOBALS = named
- self.do_run(src, '4:10,177,543,def\n4\nwowie\ntoo\n76\n5\n(null)\n/* a comment */\n// another\ntest\n', ['wowie', 'too', '74'])
+ self.do_run(src, '''4:10,177,543,def\n4\nwowie\ntoo\n76\n5\n(null)\n/* a comment */\n// another\ntest\nwaka ....e 1 O...wo 2 T................................
+cat |umber one top notchfi FI FO FUM WHEN WHERE WHY HOW WHO|''', ['wowie', 'too', '74'])
if self.emcc_args == []:
gen = open(self.in_dir('src.cpp.o.js')).read()
assert ('var __str1;' in gen) == named
@@ -4117,10 +4135,12 @@ The current type of b is: 9
#define CONSTRLEN 32
+ char * (*func)(char *, const char *) = NULL;
+
void conoutfv(const char *fmt)
{
static char buf[CONSTRLEN];
- strcpy(buf, fmt);
+ func(buf, fmt); // call by function pointer to make sure we test strcpy here
puts(buf);
}
@@ -4142,6 +4162,7 @@ The current type of b is: 9
};
int main() {
+ func = &strcpy;
conoutfv("*staticccz*");
printf("*%.2f,%.2f,%.2f*\\n", S::getIdentity().x, S::getIdentity().y, S::getIdentity().z);
return 0;
@@ -5232,6 +5253,62 @@ at function.:blag
'''
self.do_run(src, re.sub('(^|\n)\s+', '\\1', expected))
+ def test_vsnprintf(self):
+ if self.emcc_args is None: return self.skip('needs i64 math')
+
+ src = r'''
+ #include <stdio.h>
+ #include <stdarg.h>
+ #include <stdint.h>
+
+ void printy(const char *f, ...)
+ {
+ char buffer[256];
+ va_list args;
+ va_start(args, f);
+ vsnprintf(buffer, 256, f, args);
+ puts(buffer);
+ va_end(args);
+ }
+
+ int main(int argc, char **argv) {
+ int64_t x = argc - 1;
+ int64_t y = argc - 1 + 0x400000;
+ if (x % 3 == 2) y *= 2;
+
+ printy("0x%llx_0x%llx", x, y);
+ printy("0x%llx_0x%llx", x, x);
+ printy("0x%llx_0x%llx", y, x);
+ printy("0x%llx_0x%llx", y, y);
+
+ {
+ uint64_t A = 0x800000;
+ uint64_t B = 0x800000000000ULL;
+ printy("0x%llx_0x%llx", A, B);
+ }
+ {
+ uint64_t A = 0x800;
+ uint64_t B = 0x12340000000000ULL;
+ printy("0x%llx_0x%llx", A, B);
+ }
+ {
+ uint64_t A = 0x000009182746756;
+ uint64_t B = 0x192837465631ACBDULL;
+ printy("0x%llx_0x%llx", A, B);
+ }
+
+ return 0;
+ }
+ '''
+ self.do_run(src, '''0x0_0x400000
+0x0_0x0
+0x400000_0x0
+0x400000_0x400000
+0x800000_0x800000000000
+0x800_0x12340000000000
+0x9182746756_0x192837465631acbd
+''')
+
def test_printf_more(self):
src = r'''
#include <stdio.h>
@@ -6497,6 +6574,90 @@ PORT: 3979
expected = open(path_from_root('tests', 'ctype', 'output.txt'), 'r').read()
self.do_run(src, expected)
+ def test_strcasecmp(self):
+ src = r'''
+ #include <stdio.h>
+ #include <strings.h>
+ int sign(int x) {
+ if (x < 0) return -1;
+ if (x > 0) return 1;
+ return 0;
+ }
+ int main() {
+ printf("*\n");
+
+ printf("%d\n", sign(strcasecmp("hello", "hello")));
+ printf("%d\n", sign(strcasecmp("hello1", "hello")));
+ printf("%d\n", sign(strcasecmp("hello", "hello1")));
+ printf("%d\n", sign(strcasecmp("hello1", "hello1")));
+ printf("%d\n", sign(strcasecmp("iello", "hello")));
+ printf("%d\n", sign(strcasecmp("hello", "iello")));
+ printf("%d\n", sign(strcasecmp("A", "hello")));
+ printf("%d\n", sign(strcasecmp("Z", "hello")));
+ printf("%d\n", sign(strcasecmp("a", "hello")));
+ printf("%d\n", sign(strcasecmp("z", "hello")));
+ printf("%d\n", sign(strcasecmp("hello", "a")));
+ printf("%d\n", sign(strcasecmp("hello", "z")));
+
+ printf("%d\n", sign(strcasecmp("Hello", "hello")));
+ printf("%d\n", sign(strcasecmp("Hello1", "hello")));
+ printf("%d\n", sign(strcasecmp("Hello", "hello1")));
+ printf("%d\n", sign(strcasecmp("Hello1", "hello1")));
+ printf("%d\n", sign(strcasecmp("Iello", "hello")));
+ printf("%d\n", sign(strcasecmp("Hello", "iello")));
+ printf("%d\n", sign(strcasecmp("A", "hello")));
+ printf("%d\n", sign(strcasecmp("Z", "hello")));
+ printf("%d\n", sign(strcasecmp("a", "hello")));
+ printf("%d\n", sign(strcasecmp("z", "hello")));
+ printf("%d\n", sign(strcasecmp("Hello", "a")));
+ printf("%d\n", sign(strcasecmp("Hello", "z")));
+
+ printf("%d\n", sign(strcasecmp("hello", "Hello")));
+ printf("%d\n", sign(strcasecmp("hello1", "Hello")));
+ printf("%d\n", sign(strcasecmp("hello", "Hello1")));
+ printf("%d\n", sign(strcasecmp("hello1", "Hello1")));
+ printf("%d\n", sign(strcasecmp("iello", "Hello")));
+ printf("%d\n", sign(strcasecmp("hello", "Iello")));
+ printf("%d\n", sign(strcasecmp("A", "Hello")));
+ printf("%d\n", sign(strcasecmp("Z", "Hello")));
+ printf("%d\n", sign(strcasecmp("a", "Hello")));
+ printf("%d\n", sign(strcasecmp("z", "Hello")));
+ printf("%d\n", sign(strcasecmp("hello", "a")));
+ printf("%d\n", sign(strcasecmp("hello", "z")));
+
+ printf("%d\n", sign(strcasecmp("Hello", "Hello")));
+ printf("%d\n", sign(strcasecmp("Hello1", "Hello")));
+ printf("%d\n", sign(strcasecmp("Hello", "Hello1")));
+ printf("%d\n", sign(strcasecmp("Hello1", "Hello1")));
+ printf("%d\n", sign(strcasecmp("Iello", "Hello")));
+ printf("%d\n", sign(strcasecmp("Hello", "Iello")));
+ printf("%d\n", sign(strcasecmp("A", "Hello")));
+ printf("%d\n", sign(strcasecmp("Z", "Hello")));
+ printf("%d\n", sign(strcasecmp("a", "Hello")));
+ printf("%d\n", sign(strcasecmp("z", "Hello")));
+ printf("%d\n", sign(strcasecmp("Hello", "a")));
+ printf("%d\n", sign(strcasecmp("Hello", "z")));
+
+ printf("%d\n", sign(strncasecmp("hello", "hello", 3)));
+ printf("%d\n", sign(strncasecmp("hello1", "hello", 3)));
+ printf("%d\n", sign(strncasecmp("hello", "hello1", 3)));
+ printf("%d\n", sign(strncasecmp("hello1", "hello1", 3)));
+ printf("%d\n", sign(strncasecmp("iello", "hello", 3)));
+ printf("%d\n", sign(strncasecmp("hello", "iello", 3)));
+ printf("%d\n", sign(strncasecmp("A", "hello", 3)));
+ printf("%d\n", sign(strncasecmp("Z", "hello", 3)));
+ printf("%d\n", sign(strncasecmp("a", "hello", 3)));
+ printf("%d\n", sign(strncasecmp("z", "hello", 3)));
+ printf("%d\n", sign(strncasecmp("hello", "a", 3)));
+ printf("%d\n", sign(strncasecmp("hello", "z", 3)));
+
+ printf("*\n");
+
+ return 0;
+ }
+ '''
+ self.do_run(src, '''*\n0\n1\n-1\n0\n1\n-1\n-1\n1\n-1\n1\n1\n-1\n0\n1\n-1\n0\n1\n-1\n-1\n1\n-1\n1\n1\n-1\n0\n1\n-1\n0\n1\n-1\n-1\n1\n-1\n1\n1\n-1\n0\n1\n-1\n0\n1\n-1\n-1\n1\n-1\n1\n1\n-1\n0\n0\n0\n0\n1\n-1\n-1\n1\n-1\n1\n1\n-1\n*\n''')
+
def test_atomic(self):
src = '''
#include <stdio.h>
@@ -7202,6 +7363,8 @@ def process(filename):
if self.emcc_args is None: return self.skip('requires emcc')
if Building.LLVM_OPTS and self.emcc_args is None: Settings.SAFE_HEAP = 0 # Optimizations make it so we do not have debug info on the line we need to ignore
+ Settings.DEAD_FUNCTIONS = ['__ZSt9terminatev']
+
# Note: this is also a good test of per-file and per-line changes (since we have multiple files, and correct specific lines)
if Settings.SAFE_HEAP:
# Ignore bitfield warnings
@@ -7782,20 +7945,32 @@ def process(filename):
self.emcc_args = map(lambda x: 'ASM_JS=1' if x == 'ASM_JS=0' else x, self.emcc_args)
shutil.move(self.in_dir('src.cpp.o.js'), self.in_dir('pgo.js'))
- pgo_output = run_js(self.in_dir('pgo.js'))
+ pgo_output = run_js(self.in_dir('pgo.js')).split('\n')[1]
+ open('pgo_data', 'w').write(pgo_output)
+
+ # with response file
- open('pgo_data', 'w').write(pgo_output.split('\n')[1])
self.emcc_args += ['@pgo_data']
self.do_run(src, output)
+ self.emcc_args.pop()
shutil.move(self.in_dir('src.cpp.o.js'), self.in_dir('pgoed.js'))
before = len(open('normal.js').read())
after = len(open('pgoed.js').read())
assert after < 0.66 * before, [before, after] # expect a big size reduction
+ # with response in settings element itself
+
+ open('dead_funcs', 'w').write(pgo_output[pgo_output.find('['):-1])
+ self.emcc_args += ['-s', 'DEAD_FUNCTIONS=@' + self.in_dir('dead_funcs')]
+ self.do_run(src, output)
+ shutil.move(self.in_dir('src.cpp.o.js'), self.in_dir('pgoed2.js'))
+ assert open('pgoed.js').read() == open('pgoed2.js').read()
+
def test_scriptaclass(self):
if self.emcc_args is None: return self.skip('requires emcc')
- if Settings.ASM_JS: return self.skip('asm does not bindings generator yet')
+
+ Settings.EXPORT_BINDINGS = 1
header_filename = os.path.join(self.get_dir(), 'header.h')
header = '''
@@ -7970,6 +8145,7 @@ def process(filename):
Module.Child2.prototype.runVirtualFunc(c2);
c2.virtualFunc2();
+''' + ('' if Settings.ASM_JS else '''
// extend the class from JS
var c3 = new Module.Child2;
Module.customizeVTable(c3, [{
@@ -7990,6 +8166,7 @@ def process(filename):
c2.virtualFunc(); // original should remain the same
Module.Child2.prototype.runVirtualFunc(c2);
c2.virtualFunc2();
+''') + '''
Module.print('*ok*');
\'\'\'
@@ -8028,7 +8205,7 @@ Child2:9
*static*
*virtualf*
*virtualf*
-*virtualf2*
+*virtualf2*''' + ('' if Settings.ASM_JS else '''
Parent:9
Child2:9
*js virtualf replacement*
@@ -8036,13 +8213,14 @@ Child2:9
*js virtualf2 replacement*
*virtualf*
*virtualf*
-*virtualf2*
+*virtualf2*''') + '''
*ok*
''', post_build=[post2, post3])
def test_scriptaclass_2(self):
if self.emcc_args is None: return self.skip('requires emcc')
- if Settings.ASM_JS: return self.skip('asm does not bindings generator yet')
+
+ Settings.EXPORT_BINDINGS = 1
header_filename = os.path.join(self.get_dir(), 'header.h')
header = '''
@@ -9196,7 +9374,7 @@ f.close()
filename = self.in_dir('src.cpp')
open(filename, 'w').write(src)
out, err = Popen([PYTHON, EMCC, filename, '-s', 'ASM_JS=1', '-O2'], stderr=PIPE).communicate()
- assert 'Warning: Unresolved symbol' in err, 'always warn on undefs in asm, since it breaks validation'
+ assert 'Unresolved symbol' in err, 'always warn on undefs in asm, since it breaks validation: ' + err
def test_redundant_link(self):
lib = "int mult() { return 1; }"
@@ -9841,11 +10019,11 @@ f.close()
try:
os.environ['EMCC_DEBUG'] = '1'
for asm, linkable, chunks, js_chunks in [
- (0, 0, 3, 2), (0, 1, 3, 4),
- (1, 0, 3, 2), (1, 1, 3, 4)
+ (0, 0, 3, 2), (0, 1, 4, 4),
+ (1, 0, 3, 2), (1, 1, 4, 5)
]:
print asm, linkable, chunks, js_chunks
- output, err = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_libcxx.cpp'), '-O1', '-s', 'LINKABLE=%d' % linkable, '-s', 'ASM_JS=%d' % asm], stdout=PIPE, stderr=PIPE).communicate()
+ output, err = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_libcxx.cpp'), '-O1', '-s', 'LINKABLE=%d' % linkable, '-s', 'ASM_JS=%d' % asm, '-s', 'UNRESOLVED_AS_DEAD=1'], stdout=PIPE, stderr=PIPE).communicate()
assert 'phase 2 working on %d chunks' %chunks in err, err
assert 'splitting up js optimization into %d chunks' % js_chunks in err, err
finally:
@@ -10892,6 +11070,13 @@ elif 'browser' in str(sys.argv):
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()
self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0')
+ def test_openal_playback(self):
+ shutil.copyfile(path_from_root('tests', 'sounds', 'audio.wav'), os.path.join(self.get_dir(), 'audio.wav'))
+ open(os.path.join(self.get_dir(), 'openal_playback.cpp'), 'w').write(self.with_report_result(open(path_from_root('tests', 'openal_playback.cpp')).read()))
+
+ Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'openal_playback.cpp'), '--preload-file', 'audio.wav', '-o', 'page.html']).communicate()
+ self.run_browser('page.html', '', '/report_result?1')
+
def test_worker(self):
# Test running in a web worker
output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_worker.cpp'), '-o', 'worker.js'], stdout=PIPE, stderr=PIPE).communicate()
@@ -11178,6 +11363,10 @@ elif 'browser' in str(sys.argv):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('gl_ps_workaround2.c', reference='gl_ps.png', args=['--preload-file', 'screenshot.png'])
+ def test_gl_ps_strides(self):
+ shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
+ self.btest('gl_ps_strides.c', reference='gl_ps_strides.png', args=['--preload-file', 'screenshot.png'])
+
def test_matrix_identity(self):
self.btest('gl_matrix_identity.c', expected=['-1882984448', '460451840'])
@@ -11639,7 +11828,8 @@ elif 'benchmark' in str(sys.argv):
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:
- print "[%s was asm.js'ified]" % name
+ if 'asm.js link error' not in js_output:
+ print "[%s was asm.js'ified]" % name
curr = time.time()-start
times.append(curr)
total_times[tests_done] += curr
@@ -11907,7 +12097,8 @@ ok.
native=True)
emcc_args = js_lib + ['-I' + path_from_root('tests', 'bullet', 'src'),
- '-I' + path_from_root('tests', 'bullet', 'Demos', 'Benchmarks')]
+ '-I' + path_from_root('tests', 'bullet', 'Demos', 'Benchmarks'),
+ '-s', 'DEAD_FUNCTIONS=["__ZSt9terminatev"]']
native_args = native_lib + ['-I' + path_from_root('tests', 'bullet', 'src'),
'-I' + path_from_root('tests', 'bullet', 'Demos', 'Benchmarks')]
@@ -12306,9 +12497,9 @@ fi
assert ('bootstrapping relooper succeeded' in output) == (i == 2), 'only bootstrap on first O2: ' + output
assert os.path.exists(RELOOPER) == (i >= 2), 'have relooper on O2: ' + output
src = open('a.out.js').read()
- main = src.split('function _main() {')[1].split('\n}\n')[0]
- assert ('while (1) {' in main) == (i >= 2), 'reloop code on O2: ' + src
- assert ('switch' not in main) == (i >= 2), 'reloop code on O2: ' + src
+ main = src.split('function _main()')[1].split('\n}\n')[0]
+ assert ('while (1) {' in main or 'while(1){' in main) == (i >= 2), 'reloop code on O2: ' + main
+ assert ('switch' not in main) == (i >= 2), 'reloop code on O2: ' + main
def test_jcache(self):
PRE_LOAD_MSG = 'loading pre from jcache'