#!/usr/bin/env python # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. from cStringIO import StringIO import os import pexpect import signal import subprocess import sys import time TIMEOUT=10 RESULT_ID_TIMEOUT = 0 RESULT_ID_PASS = 1 RESULT_ID_FAIL = 2 RESULT_ID_EOF = 3 EXPECT_LIST = [pexpect.TIMEOUT, 'Pass!', 'Fail!', pexpect.EOF] PS_ARGS = ['ps', '--no-headers', '-o', 'stat', '--pid'] class Tee(object): def __init__(self, target): self._target = target def write(self, data): sys.stdout.write(data) self._target.write(data) def flush(self): sys.stdout.flush() self._target.flush() def RunOnce(test_name, log, env): child = pexpect.spawn('build/host/{0}/{0}.exe'.format(test_name), timeout=TIMEOUT, env=env) child.logfile = log try: return child.expect(EXPECT_LIST) finally: if child.isalive(): ps_cmd = PS_ARGS + ['%d' % (child.pid)] ps_stat = subprocess.check_output(ps_cmd).strip() log.write('\n*** test %s process %d in state %s ***\n' % (test_name, child.pid, ps_stat)) child.kill(signal.SIGTERM) child.read() # ASAN_OPTIONS environment variable is only required when test is built with # ASan, but is otherwise harmless. env = dict(os.environ) env["ASAN_OPTIONS"] = "log_path=stderr" log = StringIO() tee_log = Tee(log) test_name = sys.argv[1] start_time = time.time() result_id = RunOnce(test_name, tee_log, env) elapsed_time = time.time() - start_time if result_id == RESULT_ID_TIMEOUT: sys.stderr.write('Test %s timed out after %d seconds!\n' % (test_name, TIMEOUT)) failed = True elif result_id == RESULT_ID_PASS: sys.stderr.write('Test %s passed! (%.3f seconds)\n' % (test_name, elapsed_time)) failed = False elif result_id == RESULT_ID_FAIL: sys.stderr.write('Test %s failed! (%.3f seconds)\n' % (test_name, elapsed_time)) failed = True elif result_id == RESULT_ID_EOF: sys.stderr.write('Test %s terminated unexpectedly! (%.3f seconds)\n' % (test_name, elapsed_time)) failed = True if failed: sys.stderr.write('\n====== Emulator output ======\n') sys.stderr.write(log.getvalue()) sys.stderr.write('\n=============================\n') sys.exit(1) else: sys.exit(0)