mirror of https://github.com/svaarala/duktape.git
Browse Source
The matrix compile test relied on DUK_OPT_xxx and needs to be reworked if it is added back.pull/1255/head
Sami Vaarala
8 years ago
2 changed files with 0 additions and 575 deletions
@ -1,561 +0,0 @@ |
|||||
#!/usr/bin/env python2 |
|
||||
# |
|
||||
# Compile test for a lot of option combinations |
|
||||
# |
|
||||
|
|
||||
# XXX: rewrite as nodejs and parallelize (large indices handling need bigint) |
|
||||
|
|
||||
import os |
|
||||
import sys |
|
||||
import time |
|
||||
import datetime |
|
||||
import json |
|
||||
import random |
|
||||
import optparse |
|
||||
import subprocess |
|
||||
import StringIO # no need for cStringIO |
|
||||
|
|
||||
# |
|
||||
# Test matrix helper: given a specification of combinations, count the |
|
||||
# total number of combinations and allow a specific combination to be |
|
||||
# fetched using an index. This avoids creating the combinations explicitly |
|
||||
# and also allows random sampling of the combination space (which can be |
|
||||
# very large). |
|
||||
# |
|
||||
|
|
||||
# Select one: Select([ 1, 2, 3 ]) -> [ 1 ], [ 2 ], [ 3 ] |
|
||||
class Select: |
|
||||
val = None |
|
||||
|
|
||||
def __init__(self, val): |
|
||||
self.val = val |
|
||||
|
|
||||
# Combine: Combine([ 1, 2 ], 'foo') -> [ 1 'foo' ], [ 2 'foo' ] |
|
||||
class Combine: |
|
||||
val = None |
|
||||
|
|
||||
def __init__(self, val): |
|
||||
self.val = val |
|
||||
|
|
||||
# Subset: Subset([ 'foo', 'bar' ]) -> Combine([ [ '', 'foo' ], [ '', 'bar' ] ]) |
|
||||
# -> [ '' '' ], [ 'foo' '' ], [ '' 'bar' ], [ 'foo' 'bar' ] |
|
||||
class Subset: |
|
||||
val = None |
|
||||
|
|
||||
def __init__(self, val): |
|
||||
self.val = val |
|
||||
|
|
||||
# Sequence: Sequence([ 'foo', 'bar', 'quux' ]) -> [ 'foo', 'bar', 'quux' ] |
|
||||
# Plain list is also interpreted as a Sequence. |
|
||||
class Sequence: |
|
||||
val = None |
|
||||
|
|
||||
def __init__(self, val): |
|
||||
self.val = val |
|
||||
|
|
||||
# Prepare a combination lookup structure. |
|
||||
def prepcomb(val): |
|
||||
if isinstance(val, (str, unicode)): |
|
||||
return { 'size': 1, 'value': val, 'type': 'terminal' } |
|
||||
if isinstance(val, Sequence): |
|
||||
return { 'size': 1, 'value': val.val, 'type': 'sequence' } |
|
||||
if isinstance(val, list): |
|
||||
# interpret as Sequence |
|
||||
return { 'size': 1, 'value': val, 'type': 'sequence' } |
|
||||
if isinstance(val, Select): |
|
||||
nodes = [] |
|
||||
size = 0 |
|
||||
for i in val.val: |
|
||||
node = prepcomb(i) |
|
||||
nodes.append(node) |
|
||||
size += node['size'] |
|
||||
return { 'size': size, 'value': nodes, 'type': 'select' } |
|
||||
if isinstance(val, Combine): |
|
||||
nodes = [] |
|
||||
size = 1 |
|
||||
for i in val.val: |
|
||||
node = prepcomb(i) |
|
||||
nodes.append(node) |
|
||||
size *= node['size'] |
|
||||
return { 'size': size, 'value': nodes, 'type': 'combine' } |
|
||||
if isinstance(val, Subset): |
|
||||
nodes = [] |
|
||||
size = 1 |
|
||||
for i in val.val: |
|
||||
node = prepcomb(i) |
|
||||
nodes.append(node) |
|
||||
size *= (node['size'] + 1) # value or not present |
|
||||
return { 'size': size, 'value': nodes, 'type': 'subset' } |
|
||||
raise Exception('invalid argument') |
|
||||
|
|
||||
# Return number of combinations for input lists. |
|
||||
def countcombinations(prepped): |
|
||||
return prepped['size'] |
|
||||
|
|
||||
# Return a combination for index, for index in [0,countcombinations(lists)[. |
|
||||
# This allows random selection of combinations using a PRNG. |
|
||||
def getcomb(prepped, index): |
|
||||
if prepped['type'] == 'terminal': |
|
||||
return [ prepped['value'] ], index |
|
||||
if prepped['type'] == 'sequence': |
|
||||
return prepped['value'], index |
|
||||
if prepped['type'] == 'select': |
|
||||
idx = index % prepped['size'] |
|
||||
index = index / prepped['size'] |
|
||||
|
|
||||
for i in prepped['value']: |
|
||||
if idx >= i['size']: |
|
||||
idx -= i['size'] |
|
||||
continue |
|
||||
ret, ign_index = getcomb(i, idx) |
|
||||
return ret, index |
|
||||
|
|
||||
raise Exception('should not be here') |
|
||||
if prepped['type'] == 'combine': |
|
||||
ret = [] |
|
||||
for i in prepped['value']: |
|
||||
idx = index % i['size'] |
|
||||
index = index / i['size'] |
|
||||
tmp, tmp_index = getcomb(i, idx) |
|
||||
ret.append(tmp) |
|
||||
return ret, index |
|
||||
if prepped['type'] == 'subset': |
|
||||
ret = [] |
|
||||
for i in prepped['value']: |
|
||||
idx = index % (i['size'] + 1) |
|
||||
index = index / (i['size'] + 1) |
|
||||
if idx == 0: |
|
||||
# no value |
|
||||
ret.append('') |
|
||||
else: |
|
||||
tmp, tmp_index = getcomb(i, idx - 1) |
|
||||
ret.append(tmp) |
|
||||
return ret, index |
|
||||
raise Exception('invalid prepped value') |
|
||||
|
|
||||
def flatten(v): |
|
||||
if isinstance(v, (str, unicode)): |
|
||||
return [ v ] |
|
||||
if isinstance(v, list): |
|
||||
ret = [] |
|
||||
for i in v: |
|
||||
ret += flatten(i) |
|
||||
return ret |
|
||||
raise Exception('invalid value: %s' % repr(v)) |
|
||||
|
|
||||
|
|
||||
def getcombination(val, index): |
|
||||
res, res_index = getcomb(val, index) |
|
||||
if res_index != 0: |
|
||||
sys.stderr.write('WARNING: index not consumed entirely, invalid index? (input index %d, output index %d)\n' % (index, res_index)) |
|
||||
|
|
||||
return res |
|
||||
|
|
||||
# Generate all combinations. |
|
||||
def getcombinations(val): |
|
||||
res = [] |
|
||||
for i in xrange(countcombinations(val)): |
|
||||
res.append(getcombination(val, i)) |
|
||||
return res |
|
||||
|
|
||||
# |
|
||||
# Test matrix |
|
||||
# |
|
||||
|
|
||||
def create_matrix(fn_duk): |
|
||||
# A lot of compiler versions are used, must install at least: |
|
||||
# |
|
||||
# gcc-4.6 |
|
||||
# gcc-4.7 |
|
||||
# gcc-4.8 |
|
||||
# gcc-4.6-multilib |
|
||||
# g++-4.6-multilib |
|
||||
# gcc-4.7-multilib |
|
||||
# g++-4.7-multilib |
|
||||
# gcc-4.8-multilib |
|
||||
# g++-4.8-multilib |
|
||||
# gcc-multilib |
|
||||
# g++-multilib |
|
||||
# llvm-gcc-4.6 |
|
||||
# llvm-gcc-4.7 |
|
||||
# llvm-3.4 |
|
||||
# clang |
|
||||
# |
|
||||
# The set of compilers tested is distribution specific and not ery |
|
||||
# stable, so you may need to edit the compilers manually. |
|
||||
|
|
||||
gcc_cmd_dialect_options = Select([ |
|
||||
# Some dialects and architectures are only available for newer g++ versions |
|
||||
Combine([ |
|
||||
# -m32 with older llvm causes self test failure (double union) |
|
||||
Select([ 'llvm-gcc' ]), |
|
||||
Select([ '-m64' ]), |
|
||||
Select([ |
|
||||
'', |
|
||||
'-std=c89', |
|
||||
'-std=c99', |
|
||||
[ '-std=c99', '-pedantic' ] |
|
||||
]) |
|
||||
]), |
|
||||
Combine([ |
|
||||
Select([ 'gcc', 'gcc-4.6' ]), |
|
||||
Select([ '-m64', '-m32' ]), |
|
||||
Select([ |
|
||||
'', |
|
||||
'-std=c89', |
|
||||
'-std=c99', |
|
||||
[ '-std=c99', '-pedantic' ] |
|
||||
]) |
|
||||
]), |
|
||||
Combine([ |
|
||||
Select([ 'gcc-4.7', 'gcc-4.8' ]), |
|
||||
Select([ '-m64', '-m32', '-mx32' ]), |
|
||||
Select([ |
|
||||
'', |
|
||||
'-std=c89', |
|
||||
'-std=c99', |
|
||||
[ '-std=c99', '-pedantic' ] |
|
||||
]) |
|
||||
]), |
|
||||
]) |
|
||||
gxx_cmd_dialect_options = Select([ |
|
||||
# Some dialects and architectures are only available for newer g++ versions |
|
||||
Combine([ |
|
||||
Select([ 'llvm-g++' ]), |
|
||||
Select([ '-m64' ]), |
|
||||
Select([ |
|
||||
'', |
|
||||
'-std=c++98', |
|
||||
[ '-std=c++11', '-pedantic' ] |
|
||||
]) |
|
||||
]), |
|
||||
Combine([ |
|
||||
Select([ 'g++', 'g++-4.6' ]), |
|
||||
Select([ '-m64', '-m32' ]), |
|
||||
Select([ |
|
||||
'', |
|
||||
'-std=c++98', |
|
||||
]) |
|
||||
]), |
|
||||
Combine([ |
|
||||
Select([ 'g++-4.7', 'g++-4.8' ]), |
|
||||
Select([ '-m64', '-m32', '-mx32' ]), |
|
||||
Select([ |
|
||||
'', |
|
||||
'-std=c++98', |
|
||||
[ '-std=c++11', '-pedantic' ] |
|
||||
]) |
|
||||
]), |
|
||||
Combine([ |
|
||||
Select([ 'g++', 'g++-4.8' ]), |
|
||||
Select([ '-m64', '-m32', '-mx32' ]), |
|
||||
Select([ |
|
||||
'-std=c++1y', |
|
||||
'-std=gnu++1y' |
|
||||
]) |
|
||||
]), |
|
||||
]) |
|
||||
gcc_gxx_debug_options = Select([ |
|
||||
'', |
|
||||
[ '-g', '-ggdb' ] |
|
||||
]) |
|
||||
gcc_gxx_warning_options = Select([ |
|
||||
'', |
|
||||
#'-Wall', |
|
||||
[ '-Wall', '-Wextra' ] |
|
||||
#XXX: -Wfloat-equal |
|
||||
# [ '-Wall', '-Wextra', '-Werror' ] |
|
||||
]) |
|
||||
gcc_gxx_optimization_options = Select([ |
|
||||
'-O0', |
|
||||
'-O1', |
|
||||
'-O2', |
|
||||
|
|
||||
# -O3 and -O4 produces spurious warnings on gcc 4.8.1, e.g. "error: assuming signed overflow does not occur when assuming that (X - c) > X is always false [-Werror=strict-overflow]" |
|
||||
# Not sure what causes these, but perhaps GCC converts signed comparisons into subtractions and then runs into: https://gcc.gnu.org/wiki/FAQ#signed_overflow |
|
||||
|
|
||||
[ '-O3', '-fno-strict-overflow' ], |
|
||||
#'-O3' |
|
||||
|
|
||||
[ '-O4', '-fno-strict-overflow' ], |
|
||||
#'-O4' |
|
||||
|
|
||||
'-Os' |
|
||||
]) |
|
||||
clang_cmd_dialect_options = Select([ |
|
||||
Combine([ |
|
||||
'clang', |
|
||||
Select([ '-m64', '-m32' ]), |
|
||||
Select([ |
|
||||
'', |
|
||||
'-std=c89', |
|
||||
'-std=c99', |
|
||||
[ '-std=c99', '-pedantic' ] |
|
||||
]) |
|
||||
]) |
|
||||
]) |
|
||||
clang_debug_options = Select([ |
|
||||
'', |
|
||||
[ '-g', '-ggdb' ] |
|
||||
]) |
|
||||
clang_warning_options = Select([ |
|
||||
'', |
|
||||
[ '-Wall', '-Wextra' ], |
|
||||
[ '-Wall', '-Wextra', '-Wcast-align' ] |
|
||||
#XXX: -Wfloat-equal |
|
||||
#[ '-Wall', '-Wextra', '-Werror' ] |
|
||||
]) |
|
||||
clang_optimization_options = Select([ |
|
||||
'-O0', |
|
||||
'-O1', |
|
||||
'-O2', |
|
||||
'-O3', |
|
||||
#'-O4', |
|
||||
'-Os' |
|
||||
]) |
|
||||
|
|
||||
# Feature options in suitable chunks that can be subsetted arbitrarily. |
|
||||
|
|
||||
duktape_options = Subset([ |
|
||||
Select([ '-DDUK_OPT_NO_REFERENCE_COUNTING', |
|
||||
'-DDUK_OPT_NO_MARK_AND_SWEEP', |
|
||||
'-DDUK_OPT_GC_TORTURE' ]), |
|
||||
'-DDUK_OPT_SHUFFLE_TORTURE', |
|
||||
'-DDUK_OPT_NO_VOLUNTARY_GC', |
|
||||
'-DDUK_OPT_NO_PACKED_TVAL', |
|
||||
Select([ '', '-DDUK_OPT_FORCE_ALIGN=4', '-DDUK_OPT_FORCE_ALIGN=8' ]), |
|
||||
'-DDUK_OPT_NO_TRACEBACKS', |
|
||||
'-DDUK_OPT_NO_VERBOSE_ERRORS', |
|
||||
'-DDUK_OPT_PARANOID_ERRORS', |
|
||||
'-DDUK_OPT_NO_MS_RESIZE_STRINGTABLE', |
|
||||
'-DDUK_OPT_NO_STRICT_DECL', |
|
||||
'-DDUK_OPT_NO_REGEXP_SUPPORT', |
|
||||
'-DDUK_OPT_NO_ES6_REGEXP_SYNTAX', |
|
||||
'-DDUK_OPT_NO_SOURCE_NONBMP', |
|
||||
'-DDUK_OPT_STRICT_UTF8_SOURCE', |
|
||||
'-DDUK_OPT_NO_SECTION_B', |
|
||||
'-DDUK_OPT_NO_JX', |
|
||||
'-DDUK_OPT_NO_JC', |
|
||||
'-DDUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT', |
|
||||
'-DDUK_OPT_NO_NONSTD_FUNC_STMT', |
|
||||
'-DDUK_OPT_NONSTD_FUNC_CALLER_PROPERTY', |
|
||||
'-DDUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY', |
|
||||
'-DDUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT', |
|
||||
'-DDUK_OPT_NO_NONSTD_ARRAY_CONCAT_TRAILER', |
|
||||
'-DDUK_OPT_NO_NONSTD_ARRAY_MAP_TRAILER', |
|
||||
'-DDUK_OPT_NO_NONSTD_JSON_ESC_U2028_U2029', |
|
||||
'-DDUK_OPT_NO_BYTECODE_DUMP_SUPPORT', |
|
||||
'-DDUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY', |
|
||||
'-DDUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF', |
|
||||
'-DDUK_OPT_NO_ES6_PROXY', |
|
||||
'-DDUK_OPT_NO_ZERO_BUFFER_DATA', |
|
||||
'-DDUK_OPT_LIGHTFUNC_BUILTINS', |
|
||||
'-DDUK_OPT_ASSERTIONS', |
|
||||
[ '-DDUK_OPT_DEBUG', '-DDUK_OPT_DEBUG_WRITE(level,file,line,func,msg)=do {fprintf(stderr, "%ld %s %ld %s %s\\n", (long) (level), (file), (long) (line), (func), (msg));} while(0)', '-DDUK_OPT_DPRINT', '-DDUK_OPT_DDDPRINT' ], |
|
||||
'-DDUK_OPT_SELF_TESTS', |
|
||||
[ '-DDUK_OPT_STRTAB_CHAIN', '-DDUK_OPT_STRTAB_CHAIN_SIZE=64' ], |
|
||||
|
|
||||
# DUK_OPT_DEBUGGER_SUPPORT depends on having pc2line and |
|
||||
# interrupt counter, so avoid invalid combinations. |
|
||||
Select([ |
|
||||
Subset([ '-DDUK_OPT_NO_PC2LINE', '-DDUK_OPT_INTERRUPT_COUNTER' ]), |
|
||||
[ '-DDUK_OPT_DEBUGGER_SUPPORT', '-DDUK_OPT_INTERRUPT_COUNTER' ] |
|
||||
]), |
|
||||
'-DDUK_OPT_DEBUGGER_FWD_LOGGING', |
|
||||
'-DDUK_OPT_DEBUGGER_DUMPHEAP', |
|
||||
'-DDUK_OPT_DEBUGGER_INSPECT', |
|
||||
'-DDUK_OPT_NO_DEBUGGER_THROW_NOTIFY', |
|
||||
'-DDUK_OPT_DEBUGGER_PAUSE_UNCAUGHT', |
|
||||
'-DDUK_OPT_JSON_STRINGIFY_FASTPATH' |
|
||||
|
|
||||
# XXX: 16-bit options |
|
||||
]) |
|
||||
|
|
||||
# XXX: DUK_USE_LEXER_SLIDING_WINDOW |
|
||||
|
|
||||
# The final command is compiler specific because e.g. include path |
|
||||
# and link option syntax could (in principle) differ between compilers. |
|
||||
|
|
||||
gcc_cmd_matrix = Combine([ |
|
||||
gcc_cmd_dialect_options, |
|
||||
gcc_gxx_debug_options, |
|
||||
gcc_gxx_warning_options, |
|
||||
gcc_gxx_optimization_options, |
|
||||
duktape_options, |
|
||||
[ '-DDUK_CMDLINE_PRINTALERT_SUPPORT', '-Isrc', '-Iextras/print-alert', 'src/duktape.c', 'extras/print-alert/duk_print_alert.c', 'examples/cmdline/duk_cmdline.c', '-o', fn_duk, '-lm' ] |
|
||||
]) |
|
||||
|
|
||||
gxx_cmd_matrix = Combine([ |
|
||||
gxx_cmd_dialect_options, |
|
||||
gcc_gxx_debug_options, |
|
||||
gcc_gxx_warning_options, |
|
||||
gcc_gxx_optimization_options, |
|
||||
duktape_options, |
|
||||
[ '-DDUK_CMDLINE_PRINTALERT_SUPPORT', '-Isrc', '-Iextras/print-alert', 'src/duktape.c', 'extras/print-alert/duk_print_alert.c', 'examples/cmdline/duk_cmdline.c', '-o', fn_duk, '-lm' ] |
|
||||
]) |
|
||||
|
|
||||
clang_cmd_matrix = Combine([ |
|
||||
clang_cmd_dialect_options, |
|
||||
clang_debug_options, |
|
||||
clang_warning_options, |
|
||||
clang_optimization_options, |
|
||||
duktape_options, |
|
||||
[ '-DDUK_CMDLINE_PRINTALERT_SUPPORT', '-Isrc', '-Iextras/print-alert', 'src/duktape.c', 'extras/print-alert/duk_print_alert.c', 'examples/cmdline/duk_cmdline.c', '-o', fn_duk, '-lm' ] |
|
||||
]) |
|
||||
|
|
||||
matrix = Select([ gcc_cmd_matrix, gxx_cmd_matrix, clang_cmd_matrix ]) |
|
||||
return matrix |
|
||||
|
|
||||
# |
|
||||
# Main |
|
||||
# |
|
||||
|
|
||||
def check_unlink(filename): |
|
||||
if os.path.exists(filename): |
|
||||
os.unlink(filename) |
|
||||
|
|
||||
def main(): |
|
||||
# XXX: add option for testcase(s) to run? |
|
||||
# XXX: add valgrind support, restrict to -m64 compilation? |
|
||||
# XXX: proper tempfile usage and cleanup |
|
||||
|
|
||||
time_str = str(long(time.time() * 1000.0)) |
|
||||
|
|
||||
parser = optparse.OptionParser() |
|
||||
parser.add_option('--count', dest='count', default='1000') |
|
||||
parser.add_option('--seed', dest='seed', default='default_seed_' + time_str) |
|
||||
parser.add_option('--out-results-json', dest='out_results_json', default='/tmp/matrix_results%s.json' % time_str) |
|
||||
parser.add_option('--out-failed', dest='out_failed', default='/tmp/matrix_failed%s.txt' % time_str) |
|
||||
parser.add_option('--verbose', dest='verbose', default=False, action='store_true') |
|
||||
(opts, args) = parser.parse_args() |
|
||||
|
|
||||
fn_testjs = '/tmp/test%s.js' % time_str |
|
||||
fn_duk = '/tmp/duk%s' % time_str |
|
||||
|
|
||||
# Avoid any optional features (like JSON or RegExps) in the test. |
|
||||
# Don't make the test very long, as it executes very slowly when |
|
||||
# DUK_OPT_DDDPRINT and DUK_OPT_ASSERTIONS are enabled. |
|
||||
|
|
||||
f = open(fn_testjs, 'wb') |
|
||||
f.write(''' |
|
||||
// Fibonacci using try-catch, exercises setjmp/longjmp a lot |
|
||||
function fibthrow(n) { |
|
||||
var f1, f2; |
|
||||
if (n === 0) { throw 0; } |
|
||||
if (n === 1) { throw 1; } |
|
||||
try { fibthrow(n-1); } catch (e) { f1 = e; } |
|
||||
try { fibthrow(n-2); } catch (e) { f2 = e; } |
|
||||
throw f1 + f2; |
|
||||
} |
|
||||
print('Hello world'); |
|
||||
print(1 + 2); |
|
||||
print(Math.PI); // tests constant endianness |
|
||||
print(JSON.stringify({ foo: 'bar' })); |
|
||||
try { fibthrow(9); } catch (e) { print(e); } |
|
||||
''') |
|
||||
f.close() |
|
||||
expect = 'Hello world\n3\n3.141592653589793\n{"foo":"bar"}\n34\n' |
|
||||
|
|
||||
print('Using seed: ' + repr(opts.seed)) |
|
||||
random.seed(opts.seed) |
|
||||
matrix = create_matrix(fn_duk) |
|
||||
prepped = prepcomb(matrix) |
|
||||
# print(json.dumps(prepped, indent=4)) |
|
||||
# print(json.dumps(getcombinations(prepped), indent=4)) |
|
||||
numcombinations = countcombinations(prepped) |
|
||||
|
|
||||
# The number of combinations is large so do (pseudo) random |
|
||||
# testing over the matrix. Ideally we'd avoid re-testing the |
|
||||
# same combination twice, but with the matrix space in billions |
|
||||
# this doesn't need to be checked. |
|
||||
|
|
||||
res = [] |
|
||||
failed = [] |
|
||||
for i in xrange(long(opts.count)): |
|
||||
fail = False |
|
||||
idx = random.randrange(0, numcombinations) |
|
||||
cmd = getcombination(prepped, idx) |
|
||||
#cmd = getcombination(prepped, idx) |
|
||||
compile_command = flatten(cmd) |
|
||||
compile_command = [ elem for elem in compile_command if elem != '' ] # remove empty strings |
|
||||
|
|
||||
print('%d/%d (combination %d, count %d)' % (i + 1, long(opts.count), idx, numcombinations)) |
|
||||
#print('%d/%d (combination %d, count %d) %s' % (i + 1, long(opts.count), idx, numcombinations, repr(compile_command))) |
|
||||
if opts.verbose: |
|
||||
print(' '.join(compile_command)) |
|
||||
|
|
||||
check_unlink(fn_duk) |
|
||||
#print(repr(compile_command)) |
|
||||
compile_p = subprocess.Popen(compile_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
|
||||
compile_stdout, compile_stderr = compile_p.communicate() |
|
||||
compile_exitcode = compile_p.returncode |
|
||||
|
|
||||
if compile_exitcode != 0: |
|
||||
fail = True |
|
||||
else: |
|
||||
if not os.path.exists(fn_duk): |
|
||||
print('*** WARNING: compile success but no %s ***' % fn_duk) |
|
||||
|
|
||||
run_command = [ fn_duk, fn_testjs ] |
|
||||
if fail: |
|
||||
run_stdout = None |
|
||||
run_stderr = None |
|
||||
run_exitcode = 1 |
|
||||
else: |
|
||||
run_p = subprocess.Popen(run_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
|
||||
run_stdout, run_stderr = run_p.communicate() |
|
||||
run_exitcode = run_p.returncode |
|
||||
|
|
||||
if run_exitcode != 0: |
|
||||
fail = True |
|
||||
if run_stdout != expect: |
|
||||
fail = True |
|
||||
|
|
||||
if fail: |
|
||||
print('------------------------------------------------------------------------------') |
|
||||
print('*** FAILED: %s' % repr(compile_command)) |
|
||||
print(' '.join(compile_command)) |
|
||||
failed.append(' '.join(compile_command)) |
|
||||
|
|
||||
print('COMPILE STDOUT:') |
|
||||
print(compile_stdout) |
|
||||
print('COMPILE STDERR:') |
|
||||
print(compile_stderr) |
|
||||
print('RUN STDOUT:') |
|
||||
print(run_stdout) |
|
||||
print('RUN STDERR:') |
|
||||
print(run_stderr) |
|
||||
print('------------------------------------------------------------------------------') |
|
||||
|
|
||||
res.append({ |
|
||||
'compile_command': compile_command, |
|
||||
'compile_stdout': compile_stdout, |
|
||||
'compile_stderr': compile_stderr, |
|
||||
'compile_exitcode': compile_exitcode, |
|
||||
'run_command': run_command, |
|
||||
'run_stdout': run_stdout, |
|
||||
# Don't include debug output, it's huge with DUK_OPT_DDDPRINT |
|
||||
#'run_stderr': run_stderr, |
|
||||
'run_exitcode': run_exitcode, |
|
||||
'run_expect': expect, |
|
||||
'success': not fail |
|
||||
}) |
|
||||
|
|
||||
sys.stdout.flush() |
|
||||
sys.stderr.flush() |
|
||||
|
|
||||
f = open(opts.out_results_json, 'wb') |
|
||||
f.write(json.dumps(res, indent=4, sort_keys=True)) |
|
||||
f.close() |
|
||||
|
|
||||
f = open(opts.out_failed, 'wb') |
|
||||
f.write('\n'.join(failed) + '\n') |
|
||||
f.close() |
|
||||
|
|
||||
check_unlink(fn_duk) |
|
||||
check_unlink(fn_testjs) |
|
||||
|
|
||||
# XXX: summary of success/failure/warnings (= stderr got anything) |
|
||||
|
|
||||
if __name__ == '__main__': |
|
||||
main() |
|
Loading…
Reference in new issue