tests/run-tests.py
changeset 948 65b0318770d1
parent 947 23f0eeb598b5
child 951 0af8a73dfe14
--- a/tests/run-tests.py	Sat May 14 13:26:49 2011 +0200
+++ b/tests/run-tests.py	Tue May 17 13:45:25 2011 +0200
@@ -60,21 +60,18 @@
 closefds = os.name == 'posix'
 def Popen4(cmd, wd, timeout):
     processlock.acquire()
-    orig = os.getcwd()
-    os.chdir(wd)
-    p = subprocess.Popen(cmd, shell=True, bufsize=-1,
+    p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd,
                          close_fds=closefds,
                          stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                          stderr=subprocess.STDOUT)
-    os.chdir(orig)
     processlock.release()
 
     p.fromchild = p.stdout
     p.tochild = p.stdin
     p.childerr = p.stderr
 
+    p.timeout = False
     if timeout:
-        p.timeout = False
         def t():
             start = time.time()
             while time.time() - start < timeout and p.returncode is None:
@@ -242,6 +239,10 @@
             sys.stderr.write(
                 'warning: --timeout option ignored with --debug\n')
         options.timeout = 0
+    if options.timeout and not hasattr(subprocess.Popen, 'terminate'):
+        sys.stderr.write('warning: timeout is not supported on this '
+                         'platform and will be ignored')
+        options.timeout = 0
     if options.py3k_warnings:
         if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0):
             parser.error('--py3k-warnings can only be used on Python 2.6+')
@@ -316,7 +317,7 @@
     """Search PATH for a executable program"""
     for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
         name = os.path.join(p, program)
-        if os.access(name, os.X_OK):
+        if os.name == 'nt' or os.access(name, os.X_OK):
             return name
     return None
 
@@ -366,12 +367,14 @@
     # some tests run python interpreter. they must use same
     # interpreter we use or bad things will happen.
     exedir, exename = os.path.split(sys.executable)
-    if exename == 'python':
-        path = findprogram('python')
+    if exename in ('python', 'python.exe'):
+        path = findprogram(exename)
         if os.path.dirname(path) == exedir:
             return
+    else:
+        exename = 'python'
     vlog('# Making python executable in test path use correct Python')
-    mypython = os.path.join(BINDIR, 'python')
+    mypython = os.path.join(BINDIR, exename)
     try:
         os.symlink(sys.executable, mypython)
     except AttributeError:
@@ -438,6 +441,22 @@
             f.write(line + '\n')
         f.close()
 
+    hgbat = os.path.join(BINDIR, 'hg.bat')
+    if os.path.isfile(hgbat):
+        # hg.bat expects to be put in bin/scripts while run-tests.py
+        # installation layout put it in bin/ directly. Fix it
+        f = open(hgbat, 'rb')
+        data = f.read()
+        f.close()
+        if '"%~dp0..\python" "%~dp0hg" %*' in data:
+            data = data.replace('"%~dp0..\python" "%~dp0hg" %*',
+                                '"%~dp0python" "%~dp0hg" %*')
+            f = open(hgbat, 'wb')
+            f.write(data)
+            f.close()
+        else:
+            print 'WARNING: cannot fix hg.bat reference to python.exe'
+
     if options.anycoverage:
         custom = os.path.join(TESTDIR, 'sitecustomize.py')
         target = os.path.join(PYTHONDIR, 'sitecustomize.py')
@@ -616,49 +635,41 @@
     Return a tuple (exitcode, output).  output is None in debug mode."""
     # TODO: Use subprocess.Popen if we're running on Python 2.4
     if options.debug:
-        proc = subprocess.Popen(cmd, shell=True)
+        proc = subprocess.Popen(cmd, shell=True, cwd=wd)
         ret = proc.wait()
         return (ret, None)
 
-    if os.name == 'nt' or sys.platform.startswith('java'):
-        tochild, fromchild = os.popen4(cmd)
-        tochild.close()
-        output = fromchild.read()
-        ret = fromchild.close()
-        if ret is None:
-            ret = 0
-    else:
-        proc = Popen4(cmd, wd, options.timeout)
-        def cleanup():
-            try:
-                proc.terminate()
-            except OSError:
-                pass
-            ret = proc.wait()
-            if ret == 0:
-                ret = signal.SIGTERM << 8
-            killdaemons()
-            return ret
+    proc = Popen4(cmd, wd, options.timeout)
+    def cleanup():
+        try:
+            proc.terminate()
+        except OSError:
+            pass
+        ret = proc.wait()
+        if ret == 0:
+            ret = signal.SIGTERM << 8
+        killdaemons()
+        return ret
+
+    output = ''
+    proc.tochild.close()
 
-        output = ''
-        proc.tochild.close()
-
-        try:
-            output = proc.fromchild.read()
-        except KeyboardInterrupt:
-            vlog('# Handling keyboard interrupt')
-            cleanup()
-            raise
+    try:
+        output = proc.fromchild.read()
+    except KeyboardInterrupt:
+        vlog('# Handling keyboard interrupt')
+        cleanup()
+        raise
 
-        ret = proc.wait()
-        if wifexited(ret):
-            ret = os.WEXITSTATUS(ret)
+    ret = proc.wait()
+    if wifexited(ret):
+        ret = os.WEXITSTATUS(ret)
 
-        if proc.timeout:
-            ret = 'timeout'
+    if proc.timeout:
+        ret = 'timeout'
 
-        if ret:
-            killdaemons()
+    if ret:
+        killdaemons()
 
     for s, r in replacements:
         output = re.sub(s, r, output)