aboutsummaryrefslogtreecommitdiff
path: root/tests/runner.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/runner.py')
-rwxr-xr-xtests/runner.py142
1 files changed, 100 insertions, 42 deletions
diff --git a/tests/runner.py b/tests/runner.py
index 46096213..75b1f348 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -16,7 +16,7 @@ so you may prefer to use fewer cores here.
'''
from subprocess import Popen, PIPE, STDOUT
-import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, re, difflib, webbrowser, hashlib, threading, platform, BaseHTTPServer, multiprocessing, functools, stat
+import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, re, difflib, webbrowser, hashlib, threading, platform, BaseHTTPServer, multiprocessing, functools, stat, string
if len(sys.argv) == 1:
print '''
@@ -353,7 +353,10 @@ process(sys.argv[1])
build_dir = self.get_build_dir()
output_dir = self.get_dir()
- cache_name = name + cache_name_extra + (self.env.get('EMCC_LLVM_TARGET') or '')
+ cache_name = name + str(Building.COMPILER_TEST_OPTS) + cache_name_extra + (self.env.get('EMCC_LLVM_TARGET') or '')
+
+ valid_chars = "_%s%s" % (string.ascii_letters, string.digits)
+ cache_name = ''.join([(c if c in valid_chars else '_') for c in cache_name])
if self.library_cache is not None:
if cache and self.library_cache.get(cache_name):
@@ -1984,6 +1987,24 @@ Succeeded!
self.do_run(src, "1.0 2.0 -1.0 -2.0 2.0 3.0 -2.0 -3.0 "
"1 2 -1 -2 2 2 -2 -2")
+ # This example borrowed from MSDN documentation
+ def test_fcvt(self):
+ src = '''
+ #include <stdlib.h>
+ #include <stdio.h>
+
+ int main() {
+ int decimal, sign;
+ char *buffer;
+ double source = 3.1415926535;
+
+ buffer = fcvt(source, 7, &decimal, &sign);
+ printf("source: %2.10f buffer: '%s' decimal: %d sign: %d\\n",
+ source, buffer, decimal, sign);
+ }
+ '''
+ self.do_run(src, "source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0");
+
def test_llrint(self):
if Settings.USE_TYPED_ARRAYS != 2: return self.skip('requires ta2')
src = r'''
@@ -4062,17 +4083,11 @@ def process(filename):
self.do_run(src, 'Inline JS is very cool\n3.64')
- def zzztest_inlinejs2(self):
+ def test_inlinejs2(self):
if Settings.ASM_JS: return self.skip('asm does not support random code, TODO: something that works in asm')
src = r'''
#include <stdio.h>
- double get() {
- double ret = 0;
- __asm __volatile__("Math.abs(-12/3.3)":"=r"(ret)); // write to a variable
- return ret;
- }
-
int mix(int x, int y) {
int ret;
asm("Math.pow(2, %0+%1+1)" : "=r"(ret) : "r"(x), "r"(y)); // read and write
@@ -4085,15 +4100,13 @@ def process(filename):
}
int main(int argc, char **argv) {
- asm("Module.print('Inline JS is very cool')");
- printf("%.2f\n", get());
printf("%d\n", mix(argc, argc/2));
mult();
return 0;
}
'''
- self.do_run(src, 'Inline JS is very cool\n3.64\nwaka\nzakai\n')
+ self.do_run(src, '4\n200\n')
def test_memorygrowth(self):
if Settings.USE_TYPED_ARRAYS == 0: return self.skip('memory growth is only supported with typed arrays')
@@ -7089,7 +7102,7 @@ def process(filename):
other.close()
src = open(path_from_root('tests', 'files.cpp'), 'r').read()
- self.do_run(src, 'size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\nok.\ntexte\n',
+ self.do_run(src, ('size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\nok.\ntexte\n', 'size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\ntexte\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\nok.\n'),
post_build=post, extra_emscripten_args=['-H', 'libc/fcntl.h'])
def test_files_m(self):
@@ -7121,7 +7134,7 @@ def process(filename):
return 0;
}
'''
- self.do_run(src, 'got: 35\ngot: 45\ngot: 25\ngot: 15\nisatty? 0,0,1\n', post_build=post)
+ self.do_run(src, ('got: 35\ngot: 45\ngot: 25\ngot: 15\nisatty? 0,0,1\n', 'isatty? 0,0,1\ngot: 35\ngot: 45\ngot: 25\ngot: 15\n'), post_build=post)
def test_fwrite_0(self):
src = r'''
@@ -7764,6 +7777,8 @@ def process(filename):
self.do_run(src, '120.86.52.18\n120.86.52.18\n')
def test_inet4(self):
+ if Settings.USE_TYPED_ARRAYS != 2: return self.skip('requires ta2')
+
src = r'''
#include <stdio.h>
#include <arpa/inet.h>
@@ -9161,24 +9176,14 @@ def process(filename):
}
int main(int argc, char **argv) {
- // keep them alive
- if (argc == 10) return get_int();
- if (argc == 11) return get_float();
- if (argc == 12) return get_string()[0];
- if (argc == 13) print_int(argv[0][0]);
- if (argc == 14) print_float(argv[0][0]);
- if (argc == 15) print_string(argv[0]);
- if (argc == 16) pointer((int*)argv[0]);
- if (argc % 17 == 12) return multi(argc, float(argc)/2, argc+1, argv[0]);
- // return 0;
- exit(0);
+ return 0;
}
'''
post = '''
def process(filename):
src = \'\'\'
- var Module = { noInitialRun: true };
+ var Module = { 'noInitialRun': true };
\'\'\' + open(filename, 'r').read() + \'\'\'
Module.addOnExit(function () {
Module.print('*');
@@ -11051,6 +11056,24 @@ f.close()
voidfunc sidey(voidfunc f) { return f; }
''', 'hello from funcptr\n')
+ # function pointers with 'return' in the name
+ test('fp2', 'typedef void (*voidfunc)();', r'''
+ #include <stdio.h>
+ #include "header.h"
+ int sidey(voidfunc f);
+ void areturn0() { printf("hello 0\n"); }
+ void areturn1() { printf("hello 1\n"); }
+ void areturn2() { printf("hello 2\n"); }
+ int main(int argc, char **argv) {
+ voidfunc table[3] = { areturn0, areturn1, areturn2 };
+ table[sidey(NULL)]();
+ return 0;
+ }
+ ''', '''
+ #include "header.h"
+ int sidey(voidfunc f) { if (f) f(); return 1; }
+ ''', 'hello 1\n')
+
# Global initializer
test('global init', '', r'''
#include <stdio.h>
@@ -11200,7 +11223,7 @@ f.close()
def test_outline(self):
- def test(name, src, libs, expected, expected_ranges, args=[], suffix='cpp'):
+ def test(name, src, libs, expected, expected_ranges, args=[], suffix='cpp', test_sizes=True):
print name
def measure_funcs(filename):
@@ -11240,21 +11263,23 @@ f.close()
seen = max(measure_funcs('test.js').values())
high = expected_ranges[outlining_limit][1]
print outlining_limit, ' ', low, '<=', seen, '<=', high
- assert low <= seen <= high
-
- test('zlib', path_from_root('tests', 'zlib', 'example.c'),
- self.get_library('zlib', os.path.join('libz.a'), make_args=['libz.a']),
- open(path_from_root('tests', 'zlib', 'ref.txt'), 'r').read(),
- {
- 100: (190, 250),
- 250: (300, 330),
- 500: (250, 310),
- 1000: (230, 300),
- 2000: (380, 450),
- 5000: (800, 1100),
- 0: (1500, 1800)
- },
- args=['-I' + path_from_root('tests', 'zlib')], suffix='c')
+ if test_sizes: assert low <= seen <= high
+
+ for test_opts, test_sizes in [([], True), (['-O2'], False)]:
+ Building.COMPILER_TEST_OPTS = test_opts
+ test('zlib', path_from_root('tests', 'zlib', 'example.c'),
+ self.get_library('zlib', os.path.join('libz.a'), make_args=['libz.a']),
+ open(path_from_root('tests', 'zlib', 'ref.txt'), 'r').read(),
+ {
+ 100: (190, 250),
+ 250: (200, 330),
+ 500: (250, 310),
+ 1000: (230, 300),
+ 2000: (380, 450),
+ 5000: (800, 1100),
+ 0: (1500, 1800)
+ },
+ args=['-I' + path_from_root('tests', 'zlib')], suffix='c', test_sizes=test_sizes)
def test_symlink(self):
if os.name == 'nt':
@@ -11652,6 +11677,39 @@ int main(int argc, char const *argv[])
self.assertContained('a\nb\n', run_js(os.path.join(self.get_dir(), 'a.out.js')))
+ def test_export_in_a(self):
+ export_name = 'this_is_an_entry_point'
+
+ open('export.c', 'w').write(r'''
+ #include <stdio.h>
+ void %s(void) {
+ printf("Hello, world!\n");
+ }
+ ''' % export_name)
+ Popen([PYTHON, EMCC, 'export.c', '-c', '-o', 'export.o']).communicate()
+ Popen([PYTHON, EMAR, 'rc', 'libexport.a', 'export.o']).communicate()
+
+ open('main.c', 'w').write(r'''
+ int main() {
+ return 0;
+ }
+ ''')
+
+ definition = 'function _%s(' % export_name
+
+ # Sanity check: the symbol should not be linked in if not requested.
+ Popen([PYTHON, EMCC, 'main.c', '-L.', '-lexport']).communicate()
+ self.assertNotContained(definition, open(os.path.join(self.get_dir(), 'a.out.js')).read())
+
+ # Sanity check: exporting without a definition does not cause it to appear.
+ # Note: exporting main prevents emcc from warning that it generated no code.
+ Popen([PYTHON, EMCC, 'main.c', '-s', '''EXPORTED_FUNCTIONS=['_main', '_%s']''' % export_name]).communicate()
+ self.assertNotContained(definition, open(os.path.join(self.get_dir(), 'a.out.js')).read())
+
+ # Actual test: defining symbol in library and exporting it causes it to appear in the output.
+ Popen([PYTHON, EMCC, 'main.c', '-L.', '-lexport', '-s', '''EXPORTED_FUNCTIONS=['_%s']''' % export_name]).communicate()
+ self.assertContained(definition, open(os.path.join(self.get_dir(), 'a.out.js')).read())
+
def test_embed_file(self):
open(os.path.join(self.get_dir(), 'somefile.txt'), 'w').write('''hello from a file with lots of data and stuff in it thank you very much''')
open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(r'''