Merge with stable
authorChristian Ebert <blacktrash@gmx.net>
Fri, 21 Dec 2012 15:21:55 +0000
changeset 1176 f301599e705a
parent 1167 ca46d3dccb19 (current diff)
parent 1175 62cc0851c70f (diff)
child 1179 e4157fb1161d
Merge with stable
--- 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)