tests/run-tests.py
changeset 19279 3868c9ab4bf8
parent 19278 bc35b9ed3ae7
child 19280 eea17b7e601a
equal deleted inserted replaced
19278:bc35b9ed3ae7 19279:3868c9ab4bf8
   135         help="skip tests listed in the specified blacklist file")
   135         help="skip tests listed in the specified blacklist file")
   136     parser.add_option("--whitelist", action="append",
   136     parser.add_option("--whitelist", action="append",
   137         help="always run tests listed in the specified whitelist file")
   137         help="always run tests listed in the specified whitelist file")
   138     parser.add_option("-C", "--annotate", action="store_true",
   138     parser.add_option("-C", "--annotate", action="store_true",
   139         help="output files annotated with coverage")
   139         help="output files annotated with coverage")
   140     parser.add_option("--child", type="int",
       
   141         help="run as child process, summary to given fd")
       
   142     parser.add_option("-c", "--cover", action="store_true",
   140     parser.add_option("-c", "--cover", action="store_true",
   143         help="print a test coverage report")
   141         help="print a test coverage report")
   144     parser.add_option("-d", "--debug", action="store_true",
   142     parser.add_option("-d", "--debug", action="store_true",
   145         help="debug mode: write output of test scripts to console"
   143         help="debug mode: write output of test scripts to console"
   146              " rather than capturing and diff'ing it (disables timeout)")
   144              " rather than capturing and diff'ing it (disables timeout)")
   240         parser.error("sorry, coverage options do not work when --local "
   238         parser.error("sorry, coverage options do not work when --local "
   241                      "is specified")
   239                      "is specified")
   242 
   240 
   243     global verbose
   241     global verbose
   244     if options.verbose:
   242     if options.verbose:
   245         if options.jobs > 1 or options.child is not None:
   243         verbose = ''
   246             verbose = "[%d]" % os.getpid()
       
   247         else:
       
   248             verbose = ''
       
   249 
   244 
   250     if options.tmpdir:
   245     if options.tmpdir:
   251         options.tmpdir = os.path.expanduser(options.tmpdir)
   246         options.tmpdir = os.path.expanduser(options.tmpdir)
   252 
   247 
   253     if options.jobs < 1:
   248     if options.jobs < 1:
   270         if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0):
   265         if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0):
   271             parser.error('--py3k-warnings can only be used on Python 2.6+')
   266             parser.error('--py3k-warnings can only be used on Python 2.6+')
   272     if options.blacklist:
   267     if options.blacklist:
   273         options.blacklist = parselistfiles(options.blacklist, 'blacklist')
   268         options.blacklist = parselistfiles(options.blacklist, 'blacklist')
   274     if options.whitelist:
   269     if options.whitelist:
   275         options.whitelisted = parselistfiles(options.whitelist, 'whitelist',
   270         options.whitelisted = parselistfiles(options.whitelist, 'whitelist')
   276                                              warn=options.child is None)
       
   277     else:
   271     else:
   278         options.whitelisted = {}
   272         options.whitelisted = {}
   279 
   273 
   280     return (options, args)
   274     return (options, args)
   281 
   275 
   565 
   559 
   566     def covrun(*args):
   560     def covrun(*args):
   567         cmd = 'coverage %s' % ' '.join(args)
   561         cmd = 'coverage %s' % ' '.join(args)
   568         vlog('# Running: %s' % cmd)
   562         vlog('# Running: %s' % cmd)
   569         os.system(cmd)
   563         os.system(cmd)
   570 
       
   571     if options.child:
       
   572         return
       
   573 
   564 
   574     covrun('-c')
   565     covrun('-c')
   575     omit = ','.join(os.path.join(x, '*') for x in [BINDIR, TESTDIR])
   566     omit = ','.join(os.path.join(x, '*') for x in [BINDIR, TESTDIR])
   576     covrun('-i', '-r', '"--omit=%s"' % omit) # report
   567     covrun('-i', '-r', '"--omit=%s"' % omit) # report
   577     if options.htmlcov:
   568     if options.htmlcov:
  1131         failed = len(results['!'])
  1122         failed = len(results['!'])
  1132         tested = len(results['.']) + failed
  1123         tested = len(results['.']) + failed
  1133         skipped = len(results['s'])
  1124         skipped = len(results['s'])
  1134         ignored = len(results['i'])
  1125         ignored = len(results['i'])
  1135 
  1126 
  1136         if options.child:
  1127         print
  1137             fp = os.fdopen(options.child, 'wb')
  1128         for s in results['s']:
  1138             pickle.dump(results, fp, pickle.HIGHEST_PROTOCOL)
  1129             print "Skipped %s: %s" % s
  1139             if options.time:
  1130         for s in results['!']:
  1140                 pickle.dump(times, fp, pickle.HIGHEST_PROTOCOL)
  1131             print "Failed %s: %s" % s
  1141             fp.close()
  1132         _checkhglib("Tested")
  1142         else:
  1133         print "# Ran %d tests, %d skipped, %d failed." % (
  1143             print
  1134             tested, skipped + ignored, failed)
  1144             for s in results['s']:
  1135         if options.time:
  1145                 print "Skipped %s: %s" % s
  1136             outputtimes(options)
  1146             for s in results['!']:
       
  1147                 print "Failed %s: %s" % s
       
  1148             _checkhglib("Tested")
       
  1149             print "# Ran %d tests, %d skipped, %d failed." % (
       
  1150                 tested, skipped + ignored, failed)
       
  1151             if options.time:
       
  1152                 outputtimes(options)
       
  1153 
  1137 
  1154         if options.anycoverage:
  1138         if options.anycoverage:
  1155             outputcoverage(options)
  1139             outputcoverage(options)
  1156     except KeyboardInterrupt:
  1140     except KeyboardInterrupt:
  1157         failed = True
  1141         failed = True
  1158         if not options.child:
  1142         print "\ninterrupted!"
  1159             print "\ninterrupted!"
       
  1160 
  1143 
  1161     if failed:
  1144     if failed:
  1162         sys.exit(1)
  1145         sys.exit(1)
  1163 
  1146 
  1164 testtypes = [('.py', pytest, '.out'),
  1147 testtypes = [('.py', pytest, '.out'),
  1165              ('.t', tsttest, '')]
  1148              ('.t', tsttest, '')]
  1166 
  1149 
  1167 def main():
  1150 def main():
  1168     (options, args) = parseargs()
  1151     (options, args) = parseargs()
  1169     if not options.child:
  1152     os.umask(022)
  1170         os.umask(022)
  1153 
  1171 
  1154     checktools()
  1172         checktools()
  1155 
  1173 
  1156     if len(args) == 0:
  1174         if len(args) == 0:
  1157         args = [t for t in os.listdir(".")
  1175             args = [t for t in os.listdir(".")
  1158                 if t.startswith("test-")
  1176                     if t.startswith("test-")
  1159                 and (t.endswith(".py") or t.endswith(".t"))]
  1177                     and (t.endswith(".py") or t.endswith(".t"))]
       
  1178 
  1160 
  1179     tests = args
  1161     tests = args
  1180 
  1162 
  1181     if options.random:
  1163     if options.random:
  1182         random.shuffle(tests)
  1164         random.shuffle(tests)
  1191         print 'python hash seed:', os.environ['PYTHONHASHSEED']
  1173         print 'python hash seed:', os.environ['PYTHONHASHSEED']
  1192 
  1174 
  1193     global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE
  1175     global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE
  1194     TESTDIR = os.environ["TESTDIR"] = os.getcwd()
  1176     TESTDIR = os.environ["TESTDIR"] = os.getcwd()
  1195     if options.tmpdir:
  1177     if options.tmpdir:
  1196         if not options.child:
  1178         options.keep_tmpdir = True
  1197             options.keep_tmpdir = True
       
  1198         tmpdir = options.tmpdir
  1179         tmpdir = options.tmpdir
  1199         if os.path.exists(tmpdir):
  1180         if os.path.exists(tmpdir):
  1200             # Meaning of tmpdir has changed since 1.3: we used to create
  1181             # Meaning of tmpdir has changed since 1.3: we used to create
  1201             # HGTMP inside tmpdir; now HGTMP is tmpdir.  So fail if
  1182             # HGTMP inside tmpdir; now HGTMP is tmpdir.  So fail if
  1202             # tmpdir already exists.
  1183             # tmpdir already exists.
  1233         PYTHONDIR = os.path.join(INST, "lib", "python")
  1214         PYTHONDIR = os.path.join(INST, "lib", "python")
  1234 
  1215 
  1235     os.environ["BINDIR"] = BINDIR
  1216     os.environ["BINDIR"] = BINDIR
  1236     os.environ["PYTHON"] = PYTHON
  1217     os.environ["PYTHON"] = PYTHON
  1237 
  1218 
  1238     if not options.child:
  1219     path = [BINDIR] + os.environ["PATH"].split(os.pathsep)
  1239         path = [BINDIR] + os.environ["PATH"].split(os.pathsep)
  1220     os.environ["PATH"] = os.pathsep.join(path)
  1240         os.environ["PATH"] = os.pathsep.join(path)
  1221 
  1241 
  1222     # Include TESTDIR in PYTHONPATH so that out-of-tree extensions
  1242         # Include TESTDIR in PYTHONPATH so that out-of-tree extensions
  1223     # can run .../tests/run-tests.py test-foo where test-foo
  1243         # can run .../tests/run-tests.py test-foo where test-foo
  1224     # adds an extension to HGRC
  1244         # adds an extension to HGRC
  1225     pypath = [PYTHONDIR, TESTDIR]
  1245         pypath = [PYTHONDIR, TESTDIR]
  1226     # We have to augment PYTHONPATH, rather than simply replacing
  1246         # We have to augment PYTHONPATH, rather than simply replacing
  1227     # it, in case external libraries are only available via current
  1247         # it, in case external libraries are only available via current
  1228     # PYTHONPATH.  (In particular, the Subversion bindings on OS X
  1248         # PYTHONPATH.  (In particular, the Subversion bindings on OS X
  1229     # are in /opt/subversion.)
  1249         # are in /opt/subversion.)
  1230     oldpypath = os.environ.get(IMPL_PATH)
  1250         oldpypath = os.environ.get(IMPL_PATH)
  1231     if oldpypath:
  1251         if oldpypath:
  1232         pypath.append(oldpypath)
  1252             pypath.append(oldpypath)
  1233     os.environ[IMPL_PATH] = os.pathsep.join(pypath)
  1253         os.environ[IMPL_PATH] = os.pathsep.join(pypath)
       
  1254 
  1234 
  1255     COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
  1235     COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
  1256 
  1236 
  1257     vlog("# Using TESTDIR", TESTDIR)
  1237     vlog("# Using TESTDIR", TESTDIR)
  1258     vlog("# Using HGTMP", HGTMP)
  1238     vlog("# Using HGTMP", HGTMP)