78 строки
3.5 KiB
Python
78 строки
3.5 KiB
Python
import time, os, sys, logging
|
|
from subprocess import Popen, PIPE, STDOUT
|
|
|
|
TRACK_PROCESS_SPAWNS = True if (os.getenv('EM_BUILD_VERBOSE') and int(os.getenv('EM_BUILD_VERBOSE')) >= 3) else False
|
|
|
|
def timeout_run(proc, timeout=None, note='unnamed process', full_output=False):
|
|
start = time.time()
|
|
if timeout is not None:
|
|
while time.time() - start < timeout and proc.poll() is None:
|
|
time.sleep(0.1)
|
|
if proc.poll() is None:
|
|
proc.kill() # XXX bug: killing emscripten.py does not kill it's child process!
|
|
raise Exception("Timed out: " + note)
|
|
out = proc.communicate()
|
|
out = map(lambda o: '' if o is None else o, out)
|
|
if TRACK_PROCESS_SPAWNS:
|
|
logging.info('Process ' + str(proc.pid) + ' finished after ' + str(time.time() - start) + ' seconds. Exit code: ' + str(proc.returncode))
|
|
return '\n'.join(out) if full_output else out[0]
|
|
|
|
def make_command(filename, engine=None, args=[]):
|
|
if type(engine) is not list:
|
|
engine = [engine]
|
|
# Emscripten supports multiple javascript runtimes. The default is nodejs but
|
|
# it can also use d8 (the v8 engine shell) or jsc (JavaScript Core aka
|
|
# Safari). Both d8 and jsc require a '--' to delimit arguments to be passed
|
|
# to the executed script from d8/jsc options. Node does not require a
|
|
# delimeter--arguments after the filename are passed to the script.
|
|
#
|
|
# Check only the last part of the engine path to ensure we don't accidentally
|
|
# label a path to nodejs containing a 'd8' as spidermonkey instead.
|
|
jsengine = os.path.split(engine[0])[-1]
|
|
# Use "'d8' in" because the name can vary, e.g. d8_g, d8, etc.
|
|
return engine + [filename] + (['--'] if 'd8' in jsengine or 'jsc' in jsengine else []) + args
|
|
|
|
def run_js(filename, engine=None, args=[], check_timeout=False, stdin=None, stdout=PIPE, stderr=None, cwd=None, full_output=False, assert_returncode=0, error_limit=-1):
|
|
# # code to serialize out the test suite files
|
|
# # XXX make sure to disable memory init files, and clear out the base_dir. you may also need to manually grab e.g. paper.pdf.js from a run of test_poppler
|
|
# import shutil, json
|
|
# base_dir = '/tmp/emscripten_suite'
|
|
# if not os.path.exists(base_dir):
|
|
# os.makedirs(base_dir)
|
|
# commands_file = os.path.join(base_dir, 'commands.txt')
|
|
# commands = ''
|
|
# if os.path.exists(commands_file):
|
|
# commands = open(commands_file).read()
|
|
# i = 0
|
|
# while True:
|
|
# curr = os.path.join(base_dir, str(i) + '.js')
|
|
# if not os.path.exists(curr): break
|
|
# i += 1
|
|
# shutil.copyfile(filename, curr)
|
|
# commands += os.path.basename(curr) + ',' + json.dumps(args) + '\n'
|
|
# open(commands_file, 'w').write(commands)
|
|
|
|
command = make_command(filename, engine, args)
|
|
try:
|
|
if cwd is not None: os.environ['EMCC_BUILD_DIR'] = os.getcwd()
|
|
proc = Popen(
|
|
command,
|
|
stdin=stdin,
|
|
stdout=stdout,
|
|
stderr=stderr,
|
|
cwd=cwd)
|
|
finally:
|
|
if cwd is not None: del os.environ['EMCC_BUILD_DIR']
|
|
timeout = 15*60 if check_timeout else None
|
|
if TRACK_PROCESS_SPAWNS:
|
|
logging.info('Blocking on process ' + str(proc.pid) + ': ' + str(command) + (' for ' + str(timeout) + ' seconds' if timeout else ' until it finishes.'))
|
|
ret = timeout_run(
|
|
proc,
|
|
timeout,
|
|
'Execution',
|
|
full_output=full_output)
|
|
if assert_returncode is not None and proc.returncode is not assert_returncode:
|
|
raise Exception('Expected the command ' + str(command) + ' to finish with return code ' + str(assert_returncode) + ', but it returned with code ' + str(proc.returncode) + ' instead! Output: ' + str(ret)[:error_limit])
|
|
return ret
|
|
|