Show More
@@ -545,22 +545,25 b' def outputcoverage(options):' | |||||
545 | covrun('-i', '-a', '"--directory=%s"' % adir, '"--omit=%s"' % omit) |
|
545 | covrun('-i', '-a', '"--directory=%s"' % adir, '"--omit=%s"' % omit) | |
546 |
|
546 | |||
547 | class Test(object): |
|
547 | class Test(object): | |
548 |
"""Encapsulates a single, runnable test. |
|
548 | """Encapsulates a single, runnable test. | |
|
549 | ||||
|
550 | Test instances can be run multiple times via run(). However, multiple | |||
|
551 | runs cannot be run concurrently. | |||
|
552 | """ | |||
549 |
|
553 | |||
550 | def __init__(self, path, options, count): |
|
554 | def __init__(self, path, options, count): | |
551 | self._path = path |
|
555 | self._path = path | |
552 | self._options = options |
|
556 | self._options = options | |
|
557 | self._count = count | |||
553 |
|
558 | |||
554 | self.threadtmp = os.path.join(HGTMP, 'child%d' % count) |
|
559 | self.threadtmp = os.path.join(HGTMP, 'child%d' % count) | |
555 | os.mkdir(self.threadtmp) |
|
560 | os.mkdir(self.threadtmp) | |
556 |
|
561 | |||
557 | self._testtmp = os.path.join(self.threadtmp, os.path.basename(path)) |
|
|||
558 | os.mkdir(self._testtmp) |
|
|||
559 |
|
||||
560 | self._setreplacements(count) |
|
|||
561 |
|
||||
562 | def run(self, result, refpath): |
|
562 | def run(self, result, refpath): | |
563 | env = self._getenv() |
|
563 | testtmp = os.path.join(self.threadtmp, os.path.basename(self._path)) | |
|
564 | os.mkdir(testtmp) | |||
|
565 | replacements, port = self._getreplacements(testtmp) | |||
|
566 | env = self._getenv(testtmp, port) | |||
564 | createhgrc(env['HGRCPATH'], self._options) |
|
567 | createhgrc(env['HGRCPATH'], self._options) | |
565 |
|
568 | |||
566 | starttime = time.time() |
|
569 | starttime = time.time() | |
@@ -569,7 +572,7 b' class Test(object):' | |||||
569 | result.duration = time.time() - starttime |
|
572 | result.duration = time.time() - starttime | |
570 |
|
573 | |||
571 | try: |
|
574 | try: | |
572 |
ret, out = self._run( |
|
575 | ret, out = self._run(testtmp, replacements, env) | |
573 | updateduration() |
|
576 | updateduration() | |
574 | result.ret = ret |
|
577 | result.ret = ret | |
575 | result.out = out |
|
578 | result.out = out | |
@@ -593,11 +596,14 b' class Test(object):' | |||||
593 | else: |
|
596 | else: | |
594 | result.refout = [] |
|
597 | result.refout = [] | |
595 |
|
598 | |||
596 | def _run(self, replacements, env): |
|
599 | if not self._options.keep_tmpdir: | |
|
600 | shutil.rmtree(testtmp) | |||
|
601 | ||||
|
602 | def _run(self, testtmp, replacements, env): | |||
597 | raise NotImplemented('Subclasses must implement Test.run()') |
|
603 | raise NotImplemented('Subclasses must implement Test.run()') | |
598 |
|
604 | |||
599 |
def _ |
|
605 | def _getreplacements(self, testtmp): | |
600 | port = self._options.port + count * 3 |
|
606 | port = self._options.port + self._count * 3 | |
601 | r = [ |
|
607 | r = [ | |
602 | (r':%s\b' % port, ':$HGPORT'), |
|
608 | (r':%s\b' % port, ':$HGPORT'), | |
603 | (r':%s\b' % (port + 1), ':$HGPORT1'), |
|
609 | (r':%s\b' % (port + 1), ':$HGPORT1'), | |
@@ -608,20 +614,19 b' class Test(object):' | |||||
608 | r.append( |
|
614 | r.append( | |
609 | (''.join(c.isalpha() and '[%s%s]' % (c.lower(), c.upper()) or |
|
615 | (''.join(c.isalpha() and '[%s%s]' % (c.lower(), c.upper()) or | |
610 | c in '/\\' and r'[/\\]' or c.isdigit() and c or '\\' + c |
|
616 | c in '/\\' and r'[/\\]' or c.isdigit() and c or '\\' + c | |
611 |
for c in |
|
617 | for c in testtmp), '$TESTTMP')) | |
612 | else: |
|
618 | else: | |
613 |
r.append((re.escape( |
|
619 | r.append((re.escape(testtmp), '$TESTTMP')) | |
614 |
|
620 | |||
615 | self._replacements = r |
|
621 | return r, port | |
616 | self._port = port |
|
|||
617 |
|
622 | |||
618 | def _getenv(self): |
|
623 | def _getenv(self, testtmp, port): | |
619 | env = os.environ.copy() |
|
624 | env = os.environ.copy() | |
620 |
env['TESTTMP'] = |
|
625 | env['TESTTMP'] = testtmp | |
621 |
env['HOME'] = |
|
626 | env['HOME'] = testtmp | |
622 |
env["HGPORT"] = str( |
|
627 | env["HGPORT"] = str(port) | |
623 |
env["HGPORT1"] = str( |
|
628 | env["HGPORT1"] = str(port + 1) | |
624 |
env["HGPORT2"] = str( |
|
629 | env["HGPORT2"] = str(port + 2) | |
625 | env["HGRCPATH"] = os.path.join(self.threadtmp, '.hgrc') |
|
630 | env["HGRCPATH"] = os.path.join(self.threadtmp, '.hgrc') | |
626 | env["DAEMON_PIDS"] = os.path.join(self.threadtmp, 'daemon.pids') |
|
631 | env["DAEMON_PIDS"] = os.path.join(self.threadtmp, 'daemon.pids') | |
627 | env["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"' |
|
632 | env["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"' | |
@@ -676,8 +681,8 b' def pytest(test, wd, options, replacemen' | |||||
676 |
|
681 | |||
677 | class PythonTest(Test): |
|
682 | class PythonTest(Test): | |
678 | """A Python-based test.""" |
|
683 | """A Python-based test.""" | |
679 | def _run(self, replacements, env): |
|
684 | def _run(self, testtmp, replacements, env): | |
680 |
return pytest(self._path, |
|
685 | return pytest(self._path, testtmp, self._options, replacements, | |
681 | env) |
|
686 | env) | |
682 |
|
687 | |||
683 | needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search |
|
688 | needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search | |
@@ -939,8 +944,8 b' def tsttest(test, wd, options, replaceme' | |||||
939 | class TTest(Test): |
|
944 | class TTest(Test): | |
940 | """A "t test" is a test backed by a .t file.""" |
|
945 | """A "t test" is a test backed by a .t file.""" | |
941 |
|
946 | |||
942 | def _run(self, replacements, env): |
|
947 | def _run(self, testtmp, replacements, env): | |
943 |
return tsttest(self._path, |
|
948 | return tsttest(self._path, testtmp, self._options, replacements, | |
944 | env) |
|
949 | env) | |
945 |
|
950 | |||
946 | wifexited = getattr(os, "WIFEXITED", lambda x: False) |
|
951 | wifexited = getattr(os, "WIFEXITED", lambda x: False) |
General Comments 0
You need to be logged in to leave comments.
Login now