tests/run-tests.py
changeset 21507 d839e4820da7
parent 21506 bfe2616a2b0e
child 21508 4cc3aaa3a2ee
equal deleted inserted replaced
21506:bfe2616a2b0e 21507:d839e4820da7
   351 
   351 
   352         abort is a flag that turns to True if test execution should be aborted.
   352         abort is a flag that turns to True if test execution should be aborted.
   353         It is consulted periodically during the execution of tests.
   353         It is consulted periodically during the execution of tests.
   354         """
   354         """
   355 
   355 
   356         self._path = path
   356         self.path = path
   357         self.name = os.path.basename(path)
   357         self.name = os.path.basename(path)
   358         self._testdir = os.path.dirname(path)
   358         self._testdir = os.path.dirname(path)
   359         self._errpath = os.path.join(self._testdir, '%s.err' % self.name)
   359         self.errpath = os.path.join(self._testdir, '%s.err' % self.name)
   360 
   360 
   361         self._options = options
   361         self._options = options
   362         self._count = count
   362         self._count = count
   363         self._threadtmp = tmpdir
   363         self._threadtmp = tmpdir
   364         self._abort = abort
   364         self._abort = abort
   399         except OSError, e:
   399         except OSError, e:
   400             if e.errno != errno.EEXIST:
   400             if e.errno != errno.EEXIST:
   401                 raise
   401                 raise
   402 
   402 
   403         self._testtmp = os.path.join(self._threadtmp,
   403         self._testtmp = os.path.join(self._threadtmp,
   404                                      os.path.basename(self._path))
   404                                      os.path.basename(self.path))
   405         os.mkdir(self._testtmp)
   405         os.mkdir(self._testtmp)
   406 
   406 
   407         # Remove any previous output files.
   407         # Remove any previous output files.
   408         if os.path.exists(self._errpath):
   408         if os.path.exists(self.errpath):
   409             os.remove(self._errpath)
   409             os.remove(self.errpath)
   410 
   410 
   411     def run(self, result):
   411     def run(self, result):
   412         result.startTest(self)
   412         result.startTest(self)
   413         interrupted = False
   413         interrupted = False
   414         try:
   414         try:
   461     def runTest(self):
   461     def runTest(self):
   462         """Run this test instance.
   462         """Run this test instance.
   463 
   463 
   464         This will return a tuple describing the result of the test.
   464         This will return a tuple describing the result of the test.
   465         """
   465         """
   466         if not os.path.exists(self._path):
       
   467             raise SkipTest("Doesn't exist")
       
   468 
       
   469         options = self._options
   466         options = self._options
   470         if not (options.whitelisted and self.name in options.whitelisted):
       
   471             if options.blacklist and self.name in options.blacklist:
       
   472                 raise SkipTest('blacklisted')
       
   473 
       
   474             if options.retest and not os.path.exists('%s.err' % self.name):
       
   475                 raise IgnoreTest('not retesting')
       
   476 
       
   477             if options.keywords:
       
   478                 f = open(self.name)
       
   479                 t = f.read().lower() + self.name.lower()
       
   480                 f.close()
       
   481                 for k in options.keywords.lower().split():
       
   482                     if k in t:
       
   483                         break
       
   484                     else:
       
   485                         raise IgnoreTest("doesn't match keyword")
       
   486 
       
   487         if not os.path.basename(self.name.lower()).startswith('test-'):
       
   488             raise SkipTest('not a test file')
       
   489 
   467 
   490         replacements, port = self._getreplacements()
   468         replacements, port = self._getreplacements()
   491         env = self._getenv(port)
   469         env = self._getenv(port)
   492         self._daemonpids.append(env['DAEMON_PIDS'])
   470         self._daemonpids.append(env['DAEMON_PIDS'])
   493         self._createhgrc(env['HGRCPATH'])
   471         self._createhgrc(env['HGRCPATH'])
   527             info = {}
   505             info = {}
   528             if not options.nodiff:
   506             if not options.nodiff:
   529                 iolock.acquire()
   507                 iolock.acquire()
   530                 if options.view:
   508                 if options.view:
   531                     os.system("%s %s %s" % (options.view, self._refpath,
   509                     os.system("%s %s %s" % (options.view, self._refpath,
   532                                             self._errpath))
   510                                             self.errpath))
   533                 else:
   511                 else:
   534                     info = showdiff(self._refout, out, self._refpath,
   512                     info = showdiff(self._refout, out, self._refpath,
   535                                     self._errpath)
   513                                     self.errpath)
   536                 iolock.release()
   514                 iolock.release()
   537             msg = ''
   515             msg = ''
   538             if info.get('servefail'):
   516             if info.get('servefail'):
   539                 msg += 'serve failed and '
   517                 msg += 'serve failed and '
   540             if ret:
   518             if ret:
   542             else:
   520             else:
   543                 msg += 'output changed'
   521                 msg += 'output changed'
   544 
   522 
   545             if (ret != 0 or out != self._refout) and not self._skipped \
   523             if (ret != 0 or out != self._refout) and not self._skipped \
   546                 and not options.debug:
   524                 and not options.debug:
   547                 f = open(self._errpath, 'wb')
   525                 f = open(self.errpath, 'wb')
   548                 for line in out:
   526                 for line in out:
   549                     f.write(line)
   527                     f.write(line)
   550             f.close()
   528             f.close()
   551 
   529 
   552             self.fail(msg, ret)
   530             self.fail(msg, ret)
   563             shutil.rmtree(self._testtmp, True)
   541             shutil.rmtree(self._testtmp, True)
   564             shutil.rmtree(self._threadtmp, True)
   542             shutil.rmtree(self._threadtmp, True)
   565 
   543 
   566         if (self._ret != 0 or self._out != self._refout) and not self._skipped \
   544         if (self._ret != 0 or self._out != self._refout) and not self._skipped \
   567             and not self._options.debug and self._out:
   545             and not self._options.debug and self._out:
   568             f = open(self._errpath, 'wb')
   546             f = open(self.errpath, 'wb')
   569             for line in self._out:
   547             for line in self._out:
   570                 f.write(line)
   548                 f.write(line)
   571             f.close()
   549             f.close()
   572 
   550 
   573         vlog("# Ret was:", self._ret)
   551         vlog("# Ret was:", self._ret)
   652         warned = ret is False
   630         warned = ret is False
   653         if not self._options.nodiff:
   631         if not self._options.nodiff:
   654             log("\n%s: %s %s" % (warned and 'Warning' or 'ERROR', self.name,
   632             log("\n%s: %s %s" % (warned and 'Warning' or 'ERROR', self.name,
   655                                  msg))
   633                                  msg))
   656         if (not ret and self._options.interactive and
   634         if (not ret and self._options.interactive and
   657             os.path.exists(self._errpath)):
   635             os.path.exists(self.errpath)):
   658             iolock.acquire()
   636             iolock.acquire()
   659             print 'Accept this change? [n] ',
   637             print 'Accept this change? [n] ',
   660             answer = sys.stdin.readline().strip()
   638             answer = sys.stdin.readline().strip()
   661             iolock.release()
   639             iolock.release()
   662             if answer.lower() in ('y', 'yes'):
   640             if answer.lower() in ('y', 'yes'):
   663                 if self.name.endswith('.t'):
   641                 if self.name.endswith('.t'):
   664                     rename(self._errpath, self._path)
   642                     rename(self.errpath, self.path)
   665                 else:
   643                 else:
   666                     rename(self._errpath, '%s.out' % self._path)
   644                     rename(self.errpath, '%s.out' % self.path)
   667 
   645 
   668                 return '.', self.name, ''
   646                 return '.', self.name, ''
   669 
   647 
   670         if warned:
   648         if warned:
   671             raise WarnTest(msg)
   649             raise WarnTest(msg)
   681     def _refpath(self):
   659     def _refpath(self):
   682         return os.path.join(self._testdir, '%s.out' % self.name)
   660         return os.path.join(self._testdir, '%s.out' % self.name)
   683 
   661 
   684     def _run(self, replacements, env):
   662     def _run(self, replacements, env):
   685         py3kswitch = self._options.py3k_warnings and ' -3' or ''
   663         py3kswitch = self._options.py3k_warnings and ' -3' or ''
   686         cmd = '%s%s "%s"' % (PYTHON, py3kswitch, self._path)
   664         cmd = '%s%s "%s"' % (PYTHON, py3kswitch, self.path)
   687         vlog("# Running", cmd)
   665         vlog("# Running", cmd)
   688         if os.name == 'nt':
   666         if os.name == 'nt':
   689             replacements.append((r'\r\n', '\n'))
   667             replacements.append((r'\r\n', '\n'))
   690         return run(cmd, self._testtmp, replacements, env, self._abort,
   668         return run(cmd, self._testtmp, replacements, env, self._abort,
   691                    debug=self._options.debug, timeout=self._options.timeout)
   669                    debug=self._options.debug, timeout=self._options.timeout)
   704     @property
   682     @property
   705     def _refpath(self):
   683     def _refpath(self):
   706         return os.path.join(self._testdir, self.name)
   684         return os.path.join(self._testdir, self.name)
   707 
   685 
   708     def _run(self, replacements, env):
   686     def _run(self, replacements, env):
   709         f = open(self._path)
   687         f = open(self.path)
   710         lines = f.readlines()
   688         lines = f.readlines()
   711         f.close()
   689         f.close()
   712 
   690 
   713         salt, script, after, expected = self._parsetest(lines)
   691         salt, script, after, expected = self._parsetest(lines)
   714 
   692 
  1147         super(TestSuite, self).__init__(*args, **kwargs)
  1125         super(TestSuite, self).__init__(*args, **kwargs)
  1148 
  1126 
  1149         self._runner = runner
  1127         self._runner = runner
  1150 
  1128 
  1151     def run(self, result):
  1129     def run(self, result):
  1152         # We modify the list, so copy so callers aren't confused.
  1130         options = self._runner.options
  1153         tests = list(self._tests)
  1131 
       
  1132         # We have a number of filters that need to be applied. We do this
       
  1133         # here instead of inside Test because it makes the running logic for
       
  1134         # Test simpler.
       
  1135         tests = []
       
  1136         for test in self._tests:
       
  1137             if not os.path.exists(test.path):
       
  1138                 result.addSkip(test, "Doesn't exist")
       
  1139                 continue
       
  1140 
       
  1141             if not (options.whitelisted and test.name in options.whitelisted):
       
  1142                 if options.blacklist and test.name in options.blacklist:
       
  1143                     result.addSkip(test, 'blacklisted')
       
  1144                     continue
       
  1145 
       
  1146                 if options.retest and not os.path.exists(test.errpath):
       
  1147                     result.addIgnore(test, 'not retesting')
       
  1148                     continue
       
  1149 
       
  1150                 if options.keywords:
       
  1151                     f = open(test.path)
       
  1152                     t = f.read().lower() + test.name.lower()
       
  1153                     f.close()
       
  1154                     ignored = False
       
  1155                     for k in options.keywords.lower().split():
       
  1156                         if k not in t:
       
  1157                             result.addIgnore(test, "doesn't match keyword")
       
  1158                             ignored = True
       
  1159                             break
       
  1160 
       
  1161                     if ignored:
       
  1162                         continue
       
  1163 
       
  1164                 if not test.name.lower().startswith('test-'):
       
  1165                     result.addSkip(test, 'not a test file')
       
  1166                     continue
       
  1167 
       
  1168             tests.append(test)
  1154 
  1169 
  1155         jobs = self._runner.options.jobs
  1170         jobs = self._runner.options.jobs
  1156         done = queue.Queue()
  1171         done = queue.Queue()
  1157         running = 0
  1172         running = 0
  1158 
  1173