tests/run-tests.py
changeset 21514 59fe123dbb00
parent 21513 acfd19f3e79c
child 21515 9978ff48b1e8
equal deleted inserted replaced
21513:acfd19f3e79c 21514:59fe123dbb00
   336     """
   336     """
   337 
   337 
   338     # Status code reserved for skipped tests (used by hghave).
   338     # Status code reserved for skipped tests (used by hghave).
   339     SKIPPED_STATUS = 80
   339     SKIPPED_STATUS = 80
   340 
   340 
   341     def __init__(self, options, path, count, tmpdir, abort, keeptmpdir=False,
   341     def __init__(self, options, path, tmpdir, abort, keeptmpdir=False,
   342                  debug=False, nodiff=False, diffviewer=None,
   342                  debug=False, nodiff=False, diffviewer=None,
   343                  interactive=False, timeout=defaults['timeout']):
   343                  interactive=False, timeout=defaults['timeout'],
       
   344                  startport=defaults['port']):
   344         """Create a test from parameters.
   345         """Create a test from parameters.
   345 
   346 
   346         options are parsed command line options that control test execution.
   347         options are parsed command line options that control test execution.
   347 
   348 
   348         path is the full path to the file defining the test.
   349         path is the full path to the file defining the test.
   349 
       
   350         count is an identifier used to denote this test instance.
       
   351 
   350 
   352         tmpdir is the main temporary directory to use for this test.
   351         tmpdir is the main temporary directory to use for this test.
   353 
   352 
   354         abort is a flag that turns to True if test execution should be aborted.
   353         abort is a flag that turns to True if test execution should be aborted.
   355         It is consulted periodically during the execution of tests.
   354         It is consulted periodically during the execution of tests.
   367 
   366 
   368         interactive controls whether the test will run interactively.
   367         interactive controls whether the test will run interactively.
   369 
   368 
   370         timeout controls the maximum run time of the test. It is ignored when
   369         timeout controls the maximum run time of the test. It is ignored when
   371         debug is True.
   370         debug is True.
       
   371 
       
   372         startport controls the starting port number to use for this test. Each
       
   373         test will reserve 3 port numbers for execution. It is the caller's
       
   374         responsibility to allocate a non-overlapping port range to Test
       
   375         instances.
   372         """
   376         """
   373 
   377 
   374         self.path = path
   378         self.path = path
   375         self.name = os.path.basename(path)
   379         self.name = os.path.basename(path)
   376         self._testdir = os.path.dirname(path)
   380         self._testdir = os.path.dirname(path)
   377         self.errpath = os.path.join(self._testdir, '%s.err' % self.name)
   381         self.errpath = os.path.join(self._testdir, '%s.err' % self.name)
   378 
   382 
   379         self._options = options
   383         self._options = options
   380         self._count = count
       
   381         self._threadtmp = tmpdir
   384         self._threadtmp = tmpdir
   382         self._abort = abort
   385         self._abort = abort
   383         self._keeptmpdir = keeptmpdir
   386         self._keeptmpdir = keeptmpdir
   384         self._debug = debug
   387         self._debug = debug
   385         self._nodiff = nodiff
   388         self._nodiff = nodiff
   386         self._diffviewer = diffviewer
   389         self._diffviewer = diffviewer
   387         self._interactive = interactive
   390         self._interactive = interactive
   388         self._timeout = timeout
   391         self._timeout = timeout
       
   392         self._startport = startport
   389         self._daemonpids = []
   393         self._daemonpids = []
   390 
   394 
   391         self._finished = None
   395         self._finished = None
   392         self._ret = None
   396         self._ret = None
   393         self._out = None
   397         self._out = None
   485     def runTest(self):
   489     def runTest(self):
   486         """Run this test instance.
   490         """Run this test instance.
   487 
   491 
   488         This will return a tuple describing the result of the test.
   492         This will return a tuple describing the result of the test.
   489         """
   493         """
   490         replacements, port = self._getreplacements()
   494         replacements = self._getreplacements()
   491         env = self._getenv(port)
   495         env = self._getenv()
   492         self._daemonpids.append(env['DAEMON_PIDS'])
   496         self._daemonpids.append(env['DAEMON_PIDS'])
   493         self._createhgrc(env['HGRCPATH'])
   497         self._createhgrc(env['HGRCPATH'])
   494 
   498 
   495         vlog('# Test', self.name)
   499         vlog('# Test', self.name)
   496 
   500 
   575     def _run(self, replacements, env):
   579     def _run(self, replacements, env):
   576         # This should be implemented in child classes to run tests.
   580         # This should be implemented in child classes to run tests.
   577         raise SkipTest('unknown test type')
   581         raise SkipTest('unknown test type')
   578 
   582 
   579     def _getreplacements(self):
   583     def _getreplacements(self):
   580         port = self._options.port + self._count * 3
       
   581         r = [
   584         r = [
   582             (r':%s\b' % port, ':$HGPORT'),
   585             (r':%s\b' % self._startport, ':$HGPORT'),
   583             (r':%s\b' % (port + 1), ':$HGPORT1'),
   586             (r':%s\b' % (self._startport + 1), ':$HGPORT1'),
   584             (r':%s\b' % (port + 2), ':$HGPORT2'),
   587             (r':%s\b' % (self._startport + 2), ':$HGPORT2'),
   585             ]
   588             ]
   586 
   589 
   587         if os.name == 'nt':
   590         if os.name == 'nt':
   588             r.append(
   591             r.append(
   589                 (''.join(c.isalpha() and '[%s%s]' % (c.lower(), c.upper()) or
   592                 (''.join(c.isalpha() and '[%s%s]' % (c.lower(), c.upper()) or
   590                     c in '/\\' and r'[/\\]' or c.isdigit() and c or '\\' + c
   593                     c in '/\\' and r'[/\\]' or c.isdigit() and c or '\\' + c
   591                     for c in self._testtmp), '$TESTTMP'))
   594                     for c in self._testtmp), '$TESTTMP'))
   592         else:
   595         else:
   593             r.append((re.escape(self._testtmp), '$TESTTMP'))
   596             r.append((re.escape(self._testtmp), '$TESTTMP'))
   594 
   597 
   595         return r, port
   598         return r
   596 
   599 
   597     def _getenv(self, port):
   600     def _getenv(self):
   598         env = os.environ.copy()
   601         env = os.environ.copy()
   599         env['TESTTMP'] = self._testtmp
   602         env['TESTTMP'] = self._testtmp
   600         env['HOME'] = self._testtmp
   603         env['HOME'] = self._testtmp
   601         env["HGPORT"] = str(port)
   604         env["HGPORT"] = str(self._startport)
   602         env["HGPORT1"] = str(port + 1)
   605         env["HGPORT1"] = str(self._startport + 1)
   603         env["HGPORT2"] = str(port + 2)
   606         env["HGPORT2"] = str(self._startport + 2)
   604         env["HGRCPATH"] = os.path.join(self._threadtmp, '.hgrc')
   607         env["HGRCPATH"] = os.path.join(self._threadtmp, '.hgrc')
   605         env["DAEMON_PIDS"] = os.path.join(self._threadtmp, 'daemon.pids')
   608         env["DAEMON_PIDS"] = os.path.join(self._threadtmp, 'daemon.pids')
   606         env["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"'
   609         env["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"'
   607         env["HGMERGE"] = "internal:merge"
   610         env["HGMERGE"] = "internal:merge"
   608         env["HGUSER"]   = "test"
   611         env["HGUSER"]   = "test"
  1505                 break
  1508                 break
  1506 
  1509 
  1507         refpath = os.path.join(self.testdir, test)
  1510         refpath = os.path.join(self.testdir, test)
  1508         tmpdir = os.path.join(self.hgtmp, 'child%d' % count)
  1511         tmpdir = os.path.join(self.hgtmp, 'child%d' % count)
  1509 
  1512 
  1510         return testcls(self.options, refpath, count, tmpdir, self.abort,
  1513         return testcls(self.options, refpath, tmpdir, self.abort,
  1511                        keeptmpdir=self.options.keep_tmpdir,
  1514                        keeptmpdir=self.options.keep_tmpdir,
  1512                        debug=self.options.debug,
  1515                        debug=self.options.debug,
  1513                        nodiff = self.options.nodiff,
  1516                        nodiff = self.options.nodiff,
  1514                        diffviewer=self.options.view,
  1517                        diffviewer=self.options.view,
  1515                        interactive=self.options.interactive,
  1518                        interactive=self.options.interactive,
  1516                        timeout=self.options.timeout)
  1519                        timeout=self.options.timeout,
       
  1520                        startport=self.options.port + count * 3)
  1517 
  1521 
  1518     def _cleanup(self):
  1522     def _cleanup(self):
  1519         """Clean up state from this test invocation."""
  1523         """Clean up state from this test invocation."""
  1520 
  1524 
  1521         if self.options.keep_tmpdir:
  1525         if self.options.keep_tmpdir: