aboutsummaryrefslogtreecommitdiff
path: root/tests/runner.py
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-01-28 21:29:02 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-01-28 21:29:02 -0800
commit687b8cfa3d105a634b3c9cfbc5fc287f1517fae3 (patch)
treeeea2952d7673296ba6a8cd2384061fc3ad270473 /tests/runner.py
parentc516fa7758636e15a7077c658db3c74533c7ee38 (diff)
parentb6ebeed2cfcebb220f2ce700c7cbe484e62cd2e2 (diff)
Merge branch 'master' into llvmopts
Diffstat (limited to 'tests/runner.py')
-rwxr-xr-xtests/runner.py140
1 files changed, 101 insertions, 39 deletions
diff --git a/tests/runner.py b/tests/runner.py
index 4cdd14f8..cbff37eb 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -14,7 +14,7 @@ will use 4 processes. To install nose do something like
'''
from subprocess import Popen, PIPE, STDOUT
-import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, tempfile, re, difflib, webbrowser
+import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, tempfile, re, difflib, webbrowser, hashlib, BaseHTTPServer, threading
# Setup
@@ -195,9 +195,6 @@ process(sys.argv[1])
assert 'strict warning:' not in ret, 'We should pass all strict mode checks: ' + ret
return ret
- def run_llvm_interpreter(self, args):
- return Popen([EXEC_LLVM] + args, stdout=PIPE, stderr=self.stderr_redirect).communicate()[0]
-
def build_native(self, filename):
Popen([CLANG, '-O2', filename, '-o', filename+'.native'], stdout=PIPE).communicate()[0]
@@ -266,7 +263,7 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv):
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.
- def do_run(self, src, expected_output=None, args=[], output_nicerizer=None, output_processor=None, no_build=False, main_file=None, additional_files=[], js_engines=None, post_build=None, basename='src.cpp', libraries=[], includes=[], force_c=False, build_ll_hook=None, extra_emscripten_args=[]):
+ def do_run(self, src, expected_output, args=[], output_nicerizer=None, output_processor=None, no_build=False, main_file=None, additional_files=[], js_engines=None, post_build=None, basename='src.cpp', libraries=[], includes=[], force_c=False, build_ll_hook=None, extra_emscripten_args=[]):
if force_c or (main_file is not None and main_file[-2:]) == '.c':
basename = 'src.c'
Building.COMPILER = to_cc(Building.COMPILER)
@@ -277,11 +274,6 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv):
self.build(src, dirname, filename, main_file=main_file, additional_files=additional_files, libraries=libraries, includes=includes,
build_ll_hook=build_ll_hook, extra_emscripten_args=extra_emscripten_args, post_build=post_build)
- # If not provided with expected output, then generate it right now, using lli
- if expected_output is None:
- expected_output = self.run_llvm_interpreter([filename + '.o'])
- print '[autogenerated expected output: %20s]' % (expected_output[0:30].replace('\n', '|')+'...')
-
# Run in both JavaScript engines, if optimizing - significant differences there (typed arrays)
if js_engines is None:
js_engines = JS_ENGINES
@@ -691,7 +683,7 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv):
return 0;
}
'''
- self.do_run(src)#, '*4294967295,0,4294967219*\n*-1,1,-1,1*\n*-2,1,-2,1*\n*246,296*\n*1,0*')
+ self.do_run(src, '*4294967295,0,4294967219*\n*-1,1,-1,1*\n*-2,1,-2,1*\n*246,296*\n*1,0*')
# Now let's see some code that should just work in USE_TYPED_ARRAYS == 2, but requires
# corrections otherwise
@@ -800,6 +792,7 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv):
def test_math(self):
src = '''
#include <stdio.h>
+ #include <stdlib.h>
#include <cmath>
int main()
{
@@ -812,11 +805,22 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv):
printf(",%d", isinf(INFINITY) != 0);
printf(",%d", isinf(-INFINITY) != 0);
printf(",%d", isinf(12.3) != 0);
+ div_t div_result = div(23, 10);
+ printf(",%d", div_result.quot);
+ printf(",%d", div_result.rem);
+ double sine = -1.0, cosine = -1.0;
+ sincos(0.0, &sine, &cosine);
+ printf(",%1.1lf", sine);
+ printf(",%1.1lf", cosine);
+ float fsine = -1.0f, fcosine = -1.0f;
+ sincosf(0.0, &fsine, &fcosine);
+ printf(",%1.1f", fsine);
+ printf(",%1.1f", fcosine);
printf("*\\n");
return 0;
}
'''
- self.do_run(src, '*3.14,-3.14,1,0,0,0,1,0,1,1,0*')
+ self.do_run(src, '*3.14,-3.14,1,0,0,0,1,0,1,1,0,2,3,0.0,1.0,0.0,1.0*')
def test_math_hyperbolic(self):
src = open(path_from_root('tests', 'hyperbolic', 'src.c'), 'r').read()
@@ -893,7 +897,7 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv):
}
'''
- self.do_run(src)
+ self.do_run(src, '*1800*')
generated = open('src.cpp.o.js', 'r').read()
assert '__label__ ==' not in generated, 'We should hoist into the loop'
@@ -2387,7 +2391,10 @@ def process(filename):
return 0;
}
'''
- self.do_run(src)
+ def check(result):
+ return hashlib.sha1(result).hexdigest()
+ self.do_run(src, '6c9cdfe937383b79e52ca7a2cce83a21d9f5422c',
+ output_nicerizer = check)
def test_memmove(self):
src = '''
@@ -2400,7 +2407,7 @@ def process(filename):
return 0;
}
'''
- self.do_run(src)
+ self.do_run(src, 'memmove can be very very useful')
def test_bsearch(self):
if Settings.QUANTUM_SIZE == 1: return self.skip('Test cannot work with q1')
@@ -3176,21 +3183,21 @@ at function.:blag
#include <stdlib.h>
int main () {
- printf("%d\n", atoi(""));
- printf("%d\n", atoi("a"));
- printf("%d\n", atoi(" b"));
- printf("%d\n", atoi(" c "));
- printf("%d\n", atoi("6"));
- printf("%d\n", atoi(" 5"));
- printf("%d\n", atoi("4 "));
- printf("%d\n", atoi("3 6"));
- printf("%d\n", atoi(" 3 7"));
- printf("%d\n", atoi("9 d"));
+ printf("%d*", atoi(""));
+ printf("%d*", atoi("a"));
+ printf("%d*", atoi(" b"));
+ printf("%d*", atoi(" c "));
+ printf("%d*", atoi("6"));
+ printf("%d*", atoi(" 5"));
+ printf("%d*", atoi("4 "));
+ printf("%d*", atoi("3 6"));
+ printf("%d*", atoi(" 3 7"));
+ printf("%d*", atoi("9 d"));
printf("%d\n", atoi(" 8 e"));
return 0;
}
'''
- self.do_run(src)
+ self.do_run(src, '0*0*0*0*6*5*4*3*3*9*8')
def test_sscanf(self):
src = r'''
@@ -3216,7 +3223,8 @@ at function.:blag
return 0;
}
'''
- self.do_run(src)
+ self.do_run(src, 'en-us : 2*en-r : 99*en : 3*1.234567, 0.000000',
+ output_nicerizer = lambda x: x.replace('\n', '*'))
# Part 2: doubles (issue 148)
if Settings.USE_TYPED_ARRAYS == 2:
@@ -3267,7 +3275,11 @@ Pass: 123456.789063 123456.789063
Pass: 0.000012 0.000012
Pass: 0.000012 0.000012''')
else:
- self.do_run(src)
+ self.do_run(src, '''Pass: 1.234568 1.234568
+Pass: 123456.789000 123456.789000
+Pass: 123456.789000 123456.789000
+Pass: 0.000012 0.000012
+Pass: 0.000012 0.000012''')
def test_langinfo(self):
src = open(path_from_root('tests', 'langinfo', 'test.c'), 'r').read()
@@ -3872,6 +3884,18 @@ def process(filename):
'''
self.do_run(src, re.sub('(^|\n)\s+', '\\1', expected))
+ def test_inet(self):
+ src = r'''
+ #include <stdio.h>
+ #include <arpa/inet.h>
+
+ int main() {
+ printf("*%x,%x,%x,%x*\n", htonl(0x12345678), htons(0xabcd), ntohl(0x43211234), ntohs(0xbeaf));
+ return 0;
+ }
+ '''
+ self.do_run(src, '*78563412,cdab,34122143,afbe*')
+
def test_ctype(self):
# The bit fiddling done by the macros using __ctype_b_loc requires this.
Settings.CORRECT_SIGNS = 1
@@ -4483,7 +4507,7 @@ def process(filename):
self.do_autodebug(filename)
# Compare to each other, and to expected output
- self.do_ll_run(path_from_root('tests', filename+'.o.ll.ll'))
+ self.do_ll_run(path_from_root('tests', filename+'.o.ll.ll'), '''AD:-1,1''')
assert open('stdout').read().startswith('AD:-1'), 'We must note when we enter functions'
# Test using build_ll_hook
@@ -4502,8 +4526,7 @@ def process(filename):
return 0;
}
'''
- self.do_run(src, build_ll_hook=self.do_autodebug)
- self.do_run(src, 'AD:', build_ll_hook=self.do_autodebug)
+ self.do_run(src, '''AD:-1,1''', build_ll_hook=self.do_autodebug)
def test_profiling(self):
src = '''
@@ -5351,10 +5374,16 @@ Options that are modified or new in %s include:
for args in [['-c'], ['-o', 'src.o'], ['-o', 'src.bc'], ['-o', 'js']]:
target = args[1] if len(args) == 2 else 'hello_world.o'
clear()
- output = Popen([compiler, path_from_root('tests', 'hello_world' + suffix)] + args, stdout=PIPE, stderr=PIPE).communicate()
+ Popen([compiler, path_from_root('tests', 'hello_world' + suffix)] + args, stdout=PIPE, stderr=PIPE).communicate()
+ syms = Building.llvm_nm(target)
+ assert len(syms.defs) == 1 and 'main' in syms.defs, 'Failed to generate valid bitcode'
+ if target == 'js': # make sure emcc can recognize the target as a bitcode file
+ shutil.move(target, target + '.bc')
+ target += '.bc'
+ output = Popen([compiler, target, '-o', target + '.js'], stdout = PIPE, stderr = PIPE).communicate()
assert len(output[0]) == 0, output[0]
- assert os.path.exists(target), 'Expected %s to exist since args are %s : %s' % (target, str(args), '\n'.join(output))
- self.assertContained('hello, world!', self.run_llvm_interpreter([target]))
+ assert os.path.exists(target + '.js'), 'Expected %s to exist since args are %s : %s' % (target + '.js', str(args), '\n'.join(output))
+ self.assertContained('hello, world!', run_js(target + '.js'))
# emcc src.ll ==> generates .js
clear()
@@ -5499,8 +5528,12 @@ Options that are modified or new in %s include:
try_delete(target)
assert not os.path.exists(target)
output = Popen([compiler, 'twopart_main.o', 'twopart_side.o', '-o', 'combined.bc'] + args, stdout=PIPE, stderr=PIPE).communicate()
- assert os.path.exists('combined.bc'), '\n'.join(output)
- self.assertContained('side got: hello from main, over', self.run_llvm_interpreter(['combined.bc']))
+ syms = Building.llvm_nm('combined.bc')
+ assert len(syms.defs) == 2 and 'main' in syms.defs, 'Failed to generate valid bitcode'
+ output = Popen([compiler, 'combined.bc', '-o', 'combined.bc.js'], stdout = PIPE, stderr = PIPE).communicate()
+ assert len(output[0]) == 0, output[0]
+ assert os.path.exists('combined.bc.js'), 'Expected %s to exist' % ('combined.bc.js')
+ self.assertContained('side got: hello from main, over', run_js('combined.bc.js'))
# --js-transform <transform>
clear()
@@ -5520,13 +5553,32 @@ f.close()
# TODO: test normal project linking, static and dynamic: get_library should not need to be told what to link!
# TODO: deprecate llvm optimizations, dlmalloc, etc. in emscripten.py.
+ # For browser tests which report their success
+ def run_test_server(expectedResult):
+ class TestServerHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+ def do_GET(s):
+ assert s.path == expectedResult, 'Expected %s, got %s' % (expectedResult, s.path)
+ httpd.shutdown()
+ def handle_timeout():
+ assert False, 'Timed out while waiting for the browser test to finish'
+ httpd.shutdown()
+ httpd = BaseHTTPServer.HTTPServer(('localhost', 8888), TestServerHandler)
+ httpd.timeout = 5;
+ server_thread = threading.Thread(target=httpd.serve_forever)
+ server_thread.daemon = True
+ server_thread.start()
+ server_thread.join(5.5)
+
# Finally, do some web browser tests
- def run_browser(html_file, message):
- webbrowser.open_new(html_file)
+ def run_browser(html_file, message, expectedResult = None):
+ webbrowser.open_new(os.path.abspath(html_file))
print 'A web browser window should have opened a page containing the results of a part of this test.'
print 'You need to manually look at the page to see that it works ok: ' + message
print '(sleeping for a bit to keep the directory alive for the web browser..)'
- time.sleep(5)
+ if expectedResult is not None:
+ run_test_server(expectedResult)
+ else:
+ time.sleep(5)
print '(moving on..)'
# test HTML generation.
@@ -5558,6 +5610,16 @@ f.close()
html_file.close()
run_browser('main.html', 'You should see that the worker was called, and said "hello from worker!"')
+ # test the OpenGL ES implementation
+ clear()
+ output = Popen([EMCC, path_from_root('tests', 'hello_world_gles.c'), '-o', 'something.html',
+ '-DHAVE_BUILTIN_SINCOS',
+ '--shell-file', path_from_root('tests', 'hello_world_gles_shell.html')],
+ stdout=PIPE, stderr=PIPE).communicate()
+ assert len(output[0]) == 0, output[0]
+ assert os.path.exists('something.html'), output
+ run_browser('something.html', 'You should see animating gears.', '/report_gl_result?true')
+
def test_eliminator(self):
input = open(path_from_root('tools', 'eliminator', 'eliminator-test.js')).read()
expected = open(path_from_root('tools', 'eliminator', 'eliminator-test-output.js')).read()