comparison tests/run-tests.py @ 21514:59fe123dbb00

run-tests: refactor port number declaration Instead of making port numbers derived from count and a global initial port, we now pass a start port to Test.__init__ and do the calculation at a higher level.
author Gregory Szorc <gregory.szorc@gmail.com>
date Tue, 22 Apr 2014 12:10:25 -0700
parents acfd19f3e79c
children 9978ff48b1e8
comparison
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: