tests/run-tests.py
branchstable
changeset 919 1666a4a68262
parent 918 3071ec5d085c
child 921 abb2a67ce631
equal deleted inserted replaced
918:3071ec5d085c 919:1666a4a68262
    53 import tempfile
    53 import tempfile
    54 import time
    54 import time
    55 import re
    55 import re
    56 import threading
    56 import threading
    57 
    57 
       
    58 processlock = threading.Lock()
       
    59 
    58 closefds = os.name == 'posix'
    60 closefds = os.name == 'posix'
    59 def Popen4(cmd, timeout):
    61 def Popen4(cmd, wd, timeout):
       
    62     processlock.acquire()
       
    63     orig = os.getcwd()
       
    64     os.chdir(wd)
    60     p = subprocess.Popen(cmd, shell=True, bufsize=-1,
    65     p = subprocess.Popen(cmd, shell=True, bufsize=-1,
    61                          close_fds=closefds,
    66                          close_fds=closefds,
    62                          stdin=subprocess.PIPE, stdout=subprocess.PIPE,
    67                          stdin=subprocess.PIPE, stdout=subprocess.PIPE,
    63                          stderr=subprocess.STDOUT)
    68                          stderr=subprocess.STDOUT)
       
    69     os.chdir(orig)
       
    70     processlock.release()
       
    71 
    64     p.fromchild = p.stdout
    72     p.fromchild = p.stdout
    65     p.tochild = p.stdin
    73     p.tochild = p.stdin
    66     p.childerr = p.stderr
    74     p.childerr = p.stderr
    67 
    75 
    68     if timeout:
    76     if timeout:
   455         adir = os.path.join(TESTDIR, 'annotated')
   463         adir = os.path.join(TESTDIR, 'annotated')
   456         if not os.path.isdir(adir):
   464         if not os.path.isdir(adir):
   457             os.mkdir(adir)
   465             os.mkdir(adir)
   458         covrun('-i', '-a', '"--directory=%s"' % adir, '"--omit=%s"' % omit)
   466         covrun('-i', '-a', '"--directory=%s"' % adir, '"--omit=%s"' % omit)
   459 
   467 
   460 def pytest(test, options, replacements):
   468 def pytest(test, wd, options, replacements):
   461     py3kswitch = options.py3k_warnings and ' -3' or ''
   469     py3kswitch = options.py3k_warnings and ' -3' or ''
   462     cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
   470     cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
   463     vlog("# Running", cmd)
   471     vlog("# Running", cmd)
   464     return run(cmd, options, replacements)
   472     return run(cmd, wd, options, replacements)
   465 
   473 
   466 def shtest(test, options, replacements):
   474 def shtest(test, wd, options, replacements):
   467     cmd = '"%s"' % test
   475     cmd = '"%s"' % test
   468     vlog("# Running", cmd)
   476     vlog("# Running", cmd)
   469     return run(cmd, options, replacements)
   477     return run(cmd, wd, options, replacements)
   470 
   478 
   471 needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search
   479 needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search
   472 escapesub = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub
   480 escapesub = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub
   473 escapemap = dict((chr(i), r'\x%02x' % i) for i in range(256))
   481 escapemap = dict((chr(i), r'\x%02x' % i) for i in range(256))
   474 escapemap.update({'\\': '\\\\', '\r': r'\r'})
   482 escapemap.update({'\\': '\\\\', '\r': r'\r'})
   475 def escapef(m):
   483 def escapef(m):
   476     return escapemap[m.group(0)]
   484     return escapemap[m.group(0)]
   477 def stringescape(s):
   485 def stringescape(s):
   478     return escapesub(escapef, s)
   486     return escapesub(escapef, s)
   479 
   487 
   480 def tsttest(test, options, replacements):
   488 def tsttest(test, wd, options, replacements):
   481     t = open(test)
   489     t = open(test)
   482     out = []
   490     out = []
   483     script = []
   491     script = []
   484     salt = "SALT" + str(time.time())
   492     salt = "SALT" + str(time.time())
   485 
   493 
   516             os.write(fd, l)
   524             os.write(fd, l)
   517         os.close(fd)
   525         os.close(fd)
   518 
   526 
   519         cmd = '/bin/sh "%s"' % name
   527         cmd = '/bin/sh "%s"' % name
   520         vlog("# Running", cmd)
   528         vlog("# Running", cmd)
   521         exitcode, output = run(cmd, options, replacements)
   529         exitcode, output = run(cmd, wd, options, replacements)
   522         # do not merge output if skipped, return hghave message instead
   530         # do not merge output if skipped, return hghave message instead
   523         # similarly, with --debug, output is None
   531         # similarly, with --debug, output is None
   524         if exitcode == SKIPPED_STATUS or output is None:
   532         if exitcode == SKIPPED_STATUS or output is None:
   525             return exitcode, output
   533             return exitcode, output
   526     finally:
   534     finally:
   595         postout += after.pop(pos)
   603         postout += after.pop(pos)
   596 
   604 
   597     return exitcode, postout
   605     return exitcode, postout
   598 
   606 
   599 wifexited = getattr(os, "WIFEXITED", lambda x: False)
   607 wifexited = getattr(os, "WIFEXITED", lambda x: False)
   600 def run(cmd, options, replacements):
   608 def run(cmd, wd, options, replacements):
   601     """Run command in a sub-process, capturing the output (stdout and stderr).
   609     """Run command in a sub-process, capturing the output (stdout and stderr).
   602     Return a tuple (exitcode, output).  output is None in debug mode."""
   610     Return a tuple (exitcode, output).  output is None in debug mode."""
   603     # TODO: Use subprocess.Popen if we're running on Python 2.4
   611     # TODO: Use subprocess.Popen if we're running on Python 2.4
   604     if options.debug:
   612     if options.debug:
   605         proc = subprocess.Popen(cmd, shell=True)
   613         proc = subprocess.Popen(cmd, shell=True)
   612         output = fromchild.read()
   620         output = fromchild.read()
   613         ret = fromchild.close()
   621         ret = fromchild.close()
   614         if ret is None:
   622         if ret is None:
   615             ret = 0
   623             ret = 0
   616     else:
   624     else:
   617         proc = Popen4(cmd, options.timeout)
   625         proc = Popen4(cmd, wd, options.timeout)
   618         def cleanup():
   626         def cleanup():
   619             try:
   627             try:
   620                 proc.terminate()
   628                 proc.terminate()
   621             except OSError:
   629             except OSError:
   622                 pass
   630                 pass
   773     # Make a tmp subdirectory to work in
   781     # Make a tmp subdirectory to work in
   774     testtmp = os.environ["TESTTMP"] = os.environ["HOME"] = \
   782     testtmp = os.environ["TESTTMP"] = os.environ["HOME"] = \
   775         os.path.join(HGTMP, test)
   783         os.path.join(HGTMP, test)
   776 
   784 
   777     os.mkdir(testtmp)
   785     os.mkdir(testtmp)
   778     os.chdir(testtmp)
   786     ret, out = runner(testpath, testtmp, options, [
   779 
       
   780     ret, out = runner(testpath, options, [
       
   781         (re.escape(testtmp), '$TESTTMP'),
   787         (re.escape(testtmp), '$TESTTMP'),
   782         (r':%s\b' % options.port, ':$HGPORT'),
   788         (r':%s\b' % options.port, ':$HGPORT'),
   783         (r':%s\b' % (options.port + 1), ':$HGPORT1'),
   789         (r':%s\b' % (options.port + 1), ':$HGPORT1'),
   784         (r':%s\b' % (options.port + 2), ':$HGPORT2'),
   790         (r':%s\b' % (options.port + 2), ':$HGPORT2'),
   785         ])
   791         ])
   850         sys.stdout.flush()
   856         sys.stdout.flush()
   851         iolock.release()
   857         iolock.release()
   852 
   858 
   853     killdaemons()
   859     killdaemons()
   854 
   860 
   855     os.chdir(TESTDIR)
       
   856     if not options.keep_tmpdir:
   861     if not options.keep_tmpdir:
   857         shutil.rmtree(testtmp, True)
   862         shutil.rmtree(testtmp, True)
   858     if skipped:
   863     if skipped:
   859         return None
   864         return None
   860     return ret == 0
   865     return ret == 0