# HG changeset patch # User Christian Ebert # Date 1356103315 0 # Node ID f301599e705aa5192da378fc521d2cdd61be5c23 # Parent ca46d3dccb19eccbf8b841301476c46ca31aec02# Parent 62cc0851c70f644f99de03abba11132873189965 Merge with stable diff -r ca46d3dccb19 -r f301599e705a tests/run-tests.py --- a/tests/run-tests.py Wed Nov 28 23:59:39 2012 +0000 +++ b/tests/run-tests.py Fri Dec 21 15:21:55 2012 +0000 @@ -56,6 +56,7 @@ import threading import killdaemons as killmod import cPickle as pickle +import Queue as queue processlock = threading.Lock() @@ -94,7 +95,8 @@ if 'java' in sys.platform: IMPL_PATH = 'JYTHONPATH' -requiredtools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"] +requiredtools = [os.path.basename(sys.executable), "diff", "grep", "unzip", + "gunzip", "bunzip2", "sed"] defaults = { 'jobs': ('HGTEST_JOBS', 1), @@ -326,7 +328,7 @@ # Before we go any further, check for pre-requisite tools # stuff from coreutils (cat, rm, etc) are not tested for p in requiredtools: - if os.name == 'nt': + if os.name == 'nt' and not p.endswith('.exe'): p += '.exe' found = findprogram(p) if found: @@ -361,14 +363,26 @@ return else: exename = 'python' - vlog('# Making python executable in test path use correct Python') - mypython = os.path.join(BINDIR, exename) - try: - os.symlink(sys.executable, mypython) - except AttributeError: - # windows fallback - shutil.copyfile(sys.executable, mypython) - shutil.copymode(sys.executable, mypython) + if sys.platform == 'win32': + exename = 'python.exe' + if getattr(os, 'symlink', None): + vlog("# Making python executable in test path a symlink to '%s'" % + sys.executable) + mypython = os.path.join(BINDIR, exename) + try: + os.symlink(sys.executable, mypython) + except OSError, err: + # child processes may race, which is harmless + if err.errno != errno.EEXIST: + raise + else: + vlog("# Modifying search path to find %s in '%s'" % (exename, exedir)) + path = os.environ['PATH'].split(os.pathsep) + while exedir in path: + path.remove(exedir) + os.environ['PATH'] = os.pathsep.join([exedir] + path) + if not findprogram(exename): + print "WARNING: Cannot find %s in search path" % exename def installhg(options): vlog("# Performing temporary installation of HG") @@ -921,6 +935,8 @@ times.append((test, endtime - starttime)) vlog("# Ret was:", ret) + killdaemons() + mark = '.' skipped = (ret == SKIPPED_STATUS) @@ -991,8 +1007,6 @@ sys.stdout.flush() iolock.release() - killdaemons() - if not options.keep_tmpdir: shutil.rmtree(testtmp, True) if skipped: @@ -1030,6 +1044,8 @@ if INST: installhg(options) _checkhglib("Testing") + else: + usecorrectpython() optcopy = dict(options.__dict__) optcopy['jobs'] = 1 @@ -1072,7 +1088,13 @@ blacklisted.append(test) else: job.append(test) - fps = {} + + waitq = queue.Queue() + + # windows lacks os.wait, so we must emulate it + def waitfor(proc, rfd): + fp = os.fdopen(rfd, 'rb') + return lambda: waitq.put((proc.pid, proc.wait(), fp)) for j, job in enumerate(jobs): if not job: @@ -1083,16 +1105,18 @@ childopts += ['--tmpdir', childtmp] cmdline = [PYTHON, sys.argv[0]] + opts + childopts + job vlog(' '.join(cmdline)) - fps[os.spawnvp(os.P_NOWAIT, cmdline[0], cmdline)] = os.fdopen(rfd, 'rb') + proc = subprocess.Popen(cmdline, executable=cmdline[0]) + threading.Thread(target=waitfor(proc, rfd)).start() os.close(wfd) signal.signal(signal.SIGINT, signal.SIG_IGN) failures = 0 passed, skipped, failed = 0, 0, 0 skips = [] fails = [] - while fps: - pid, status = os.wait() - fp = fps.pop(pid) + for job in jobs: + if not job: + continue + pid, status, fp = waitq.get() try: childresults = pickle.load(fp) except pickle.UnpicklingError: @@ -1149,6 +1173,8 @@ if INST: installhg(options) _checkhglib("Testing") + else: + usecorrectpython() if options.restart: orig = list(tests)