tests/run-tests.py
changeset 21296 cd8776030833
parent 21231 1ce16c7b7fb4
child 21297 dd8e94601417
equal deleted inserted replaced
21295:883e268cb860 21296:cd8776030833
   577         adir = os.path.join(TESTDIR, 'annotated')
   577         adir = os.path.join(TESTDIR, 'annotated')
   578         if not os.path.isdir(adir):
   578         if not os.path.isdir(adir):
   579             os.mkdir(adir)
   579             os.mkdir(adir)
   580         covrun('-i', '-a', '"--directory=%s"' % adir, '"--omit=%s"' % omit)
   580         covrun('-i', '-a', '"--directory=%s"' % adir, '"--omit=%s"' % omit)
   581 
   581 
       
   582 class Test(object):
       
   583     """Encapsulates a single, runnable test."""
       
   584 
       
   585     def __init__(self, path, options):
       
   586         self._path = path
       
   587         self._options = options
       
   588 
       
   589     def run(self, testtmp, replacements, env):
       
   590         return self._run(testtmp, replacements, env)
       
   591 
       
   592     def _run(self, testtmp, replacements, env):
       
   593         raise NotImplemented('Subclasses must implement Test.run()')
       
   594 
   582 def pytest(test, wd, options, replacements, env):
   595 def pytest(test, wd, options, replacements, env):
   583     py3kswitch = options.py3k_warnings and ' -3' or ''
   596     py3kswitch = options.py3k_warnings and ' -3' or ''
   584     cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
   597     cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
   585     vlog("# Running", cmd)
   598     vlog("# Running", cmd)
   586     if os.name == 'nt':
   599     if os.name == 'nt':
   587         replacements.append((r'\r\n', '\n'))
   600         replacements.append((r'\r\n', '\n'))
   588     return run(cmd, wd, options, replacements, env)
   601     return run(cmd, wd, options, replacements, env)
       
   602 
       
   603 class PythonTest(Test):
       
   604     """A Python-based test."""
       
   605     def _run(self, testtmp, replacements, env):
       
   606         return pytest(self._path, testtmp, self._options, replacements, env)
   589 
   607 
   590 needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search
   608 needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search
   591 escapesub = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub
   609 escapesub = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub
   592 escapemap = dict((chr(i), r'\x%02x' % i) for i in range(256))
   610 escapemap = dict((chr(i), r'\x%02x' % i) for i in range(256))
   593 escapemap.update({'\\': '\\\\', '\r': r'\r'})
   611 escapemap.update({'\\': '\\\\', '\r': r'\r'})
   841 
   859 
   842     if warnonly == 2:
   860     if warnonly == 2:
   843         exitcode = False # set exitcode to warned
   861         exitcode = False # set exitcode to warned
   844     return exitcode, postout
   862     return exitcode, postout
   845 
   863 
       
   864 class TTest(Test):
       
   865     """A "t test" is a test backed by a .t file."""
       
   866 
       
   867     def _run(self, testtmp, replacements, env):
       
   868         return tsttest(self._path, testtmp, self._options, replacements, env)
       
   869 
   846 wifexited = getattr(os, "WIFEXITED", lambda x: False)
   870 wifexited = getattr(os, "WIFEXITED", lambda x: False)
   847 def run(cmd, wd, options, replacements, env):
   871 def run(cmd, wd, options, replacements, env):
   848     """Run command in a sub-process, capturing the output (stdout and stderr).
   872     """Run command in a sub-process, capturing the output (stdout and stderr).
   849     Return a tuple (exitcode, output).  output is None in debug mode."""
   873     Return a tuple (exitcode, output).  output is None in debug mode."""
   850     # TODO: Use subprocess.Popen if we're running on Python 2.4
   874     # TODO: Use subprocess.Popen if we're running on Python 2.4
   950                 else:
   974                 else:
   951                     return ignore("doesn't match keyword")
   975                     return ignore("doesn't match keyword")
   952 
   976 
   953     if not os.path.basename(lctest).startswith("test-"):
   977     if not os.path.basename(lctest).startswith("test-"):
   954         return skip("not a test file")
   978         return skip("not a test file")
   955     for ext, func, out in testtypes:
   979     for ext, cls, out in testtypes:
   956         if lctest.endswith(ext):
   980         if lctest.endswith(ext):
   957             runner = func
   981             runner = cls
   958             ref = os.path.join(TESTDIR, test + out)
   982             ref = os.path.join(TESTDIR, test + out)
   959             break
   983             break
   960     else:
   984     else:
   961         return skip("unknown test type")
   985         return skip("unknown test type")
   962 
   986 
   963     vlog("# Test", test)
   987     vlog("# Test", test)
   964 
   988 
   965     if os.path.exists(err):
   989     if os.path.exists(err):
   966         os.remove(err)       # Remove any previous output files
   990         os.remove(err)       # Remove any previous output files
       
   991 
       
   992     t = runner(testpath, options)
   967 
   993 
   968     # Make a tmp subdirectory to work in
   994     # Make a tmp subdirectory to work in
   969     threadtmp = os.path.join(HGTMP, "child%d" % count)
   995     threadtmp = os.path.join(HGTMP, "child%d" % count)
   970     testtmp = os.path.join(threadtmp, os.path.basename(test))
   996     testtmp = os.path.join(threadtmp, os.path.basename(test))
   971     os.mkdir(threadtmp)
   997     os.mkdir(threadtmp)
   990     env = createenv(options, testtmp, threadtmp, port)
  1016     env = createenv(options, testtmp, threadtmp, port)
   991     createhgrc(env['HGRCPATH'], options)
  1017     createhgrc(env['HGRCPATH'], options)
   992 
  1018 
   993     starttime = time.time()
  1019     starttime = time.time()
   994     try:
  1020     try:
   995         ret, out = runner(testpath, testtmp, options, replacements, env)
  1021         ret, out = t.run(testtmp, replacements, env)
   996     except KeyboardInterrupt:
  1022     except KeyboardInterrupt:
   997         endtime = time.time()
  1023         endtime = time.time()
   998         log('INTERRUPTED: %s (after %d seconds)' % (test, endtime - starttime))
  1024         log('INTERRUPTED: %s (after %d seconds)' % (test, endtime - starttime))
   999         raise
  1025         raise
  1000     endtime = time.time()
  1026     endtime = time.time()
  1190     if failed:
  1216     if failed:
  1191         return 1
  1217         return 1
  1192     if warned:
  1218     if warned:
  1193         return 80
  1219         return 80
  1194 
  1220 
  1195 testtypes = [('.py', pytest, '.out'),
  1221 testtypes = [('.py', PythonTest, '.out'),
  1196              ('.t', tsttest, '')]
  1222              ('.t', TTest, '')]
  1197 
  1223 
  1198 def main(args, parser=None):
  1224 def main(args, parser=None):
  1199     parser = parser or getparser()
  1225     parser = parser or getparser()
  1200     (options, args) = parseargs(args, parser)
  1226     (options, args) = parseargs(args, parser)
  1201     os.umask(022)
  1227     os.umask(022)