#! /usr/bin/env python import py, sys, os, time, atexit print time.ctime() from toolbox import svn_up, write_index_html import toolbox import summarize # pypy defaults, overridable in autotestconfig HTML = "html" TOP = py.path.local('pypy-dist') ROOT = TOP.join('pypy') INTERP = None # list [interp, arg1, arg2, ...] TESTDRIVER = None # list [(py.test) script, arg1, arg2, ...] CHERRYPICK = None # explicit list of test dirs def cleanup(testdir): pass def get_test_driver(testdir): """ Get the test runner for a specific directory. Note that this function must be defined before the config loading, so that can be overridden in the autotestconfig.py file. """ return TESTDRIVER # collect test logic def is_test_py_file(p): name = p.basename return name.startswith('test_') and name.endswith('.py') def collect_testdirs(testdirs, p, root=None): if root is None: root = p def reltoroot(p): rel = p.relto(root) return rel.replace(os.sep, '/') reldir = reltoroot(p) entries = [p1 for p1 in p.listdir() if p1.check(dotfile=0)] if p != root: for p1 in entries: if is_test_py_file(p1): collect_one_testdir(testdirs, reldir, [reltoroot(t) for t in entries if is_test_py_file(t)]) return for p1 in entries: if p1.check(dir=1, link=0): collect_testdirs(testdirs, p1, root) # override this if needed def collect_one_testdir(testdirs, reldir, tests): if (reldir.startswith('jit/codegen/i386/') or reldir.startswith('jit/timeshifter/') or reldir.startswith('translator/c/')): testdirs.extend(tests) else: testdirs.append(reldir) # cfg = {} execfile('autotestconfig.py', cfg) globals().update(cfg) assert PARALLEL_RUNS >= 1 root = ROOT # ____________________________________________________________ if os.name != 'nt': try: os.symlink(str(os.getpid()), 'LOCK') except OSError: # stale lock detection oldpid = os.readlink('LOCK').strip() for line in os.popen('ps -p %s' % oldpid, 'r'): if 'python' in line: print >> sys.stderr, ("LOCK file present and pointing to " "already-running pid %s" % oldpid) sys.exit(1) print >> sys.stderr, ("Removed stale LOCK file pointing to " "non-existing pid %s" % oldpid) os.unlink('LOCK') os.symlink(str(os.getpid()), 'LOCK') atexit.register(os.unlink, 'LOCK') REV = svn_up(True, TOP) print REV if py.path.local(HTML).join(REV).check(dir=1): print '%s/%s already exists. Stopping.' % (HTML, REV) sys.exit(0) revpath = py.path.local(HTML).ensure(REV, dir=1) s = str(py.path.local(HTML).join("latest")) try: toolbox.unlink(s) except OSError: pass toolbox.symlink(REV, s, fallback='shortcut') # run each 'test' directory in its own process testdirs = [] if CHERRYPICK is not None: for p in CHERRYPICK: collect_testdirs(testdirs, root.join(p), root) else: collect_testdirs(testdirs, root) testdirs.sort() for _dir in testdirs: print '..', _dir starttime = time.time() htmldir = py.path.local(HTML).join(str(REV)) # ____________________________________________________________ # import thread from Queue import Queue def execute_once(outqueue, testdir): errfilename = testdir.replace('/', '.') + '.html' rawhtmlindex = htmldir.join(errfilename) outqueue.put(('start', rawhtmlindex, None)) test_driver = get_test_driver(testdir) result = toolbox.execute(testdir, errfilename, htmldir, rawhtmlindex, test_driver=test_driver, root=ROOT, interp=INTERP) outqueue.put(('done', rawhtmlindex, result)) def runner(testdirs, outqueue): toolbox.thread_init() while 1: try: testdir = testdirs.pop(0) except IndexError: outqueue.put(('finished', None, None)) return execute_once(outqueue, testdir) cleanup(testdir) outqueue = Queue() for n in range(PARALLEL_RUNS): thread.start_new_thread(runner, (testdirs, outqueue)) currents = [] results = [] while True: action, rawhtmlindex, result = outqueue.get() if action == 'start': currents.append(rawhtmlindex) write_index_html(htmldir, results, REV, currents, starttime=starttime) elif action == 'done': currents.remove(rawhtmlindex) results.append(result) write_index_html(htmldir, results, REV, currents, starttime=starttime) summarize.main(HTML, cfg) elif action == 'finished': if not currents: break write_index_html(htmldir, results, REV, starttime=starttime) summarize.main(HTML, cfg)