Show More
@@ -76,6 +76,8 b' processlock = threading.Lock()' | |||||
76 | if sys.version_info < (2, 5): |
|
76 | if sys.version_info < (2, 5): | |
77 | subprocess._cleanup = lambda: None |
|
77 | subprocess._cleanup = lambda: None | |
78 |
|
78 | |||
|
79 | wifexited = getattr(os, "WIFEXITED", lambda x: False) | |||
|
80 | ||||
79 | closefds = os.name == 'posix' |
|
81 | closefds = os.name == 'posix' | |
80 | def Popen4(cmd, wd, timeout, env=None): |
|
82 | def Popen4(cmd, wd, timeout, env=None): | |
81 | processlock.acquire() |
|
83 | processlock.acquire() | |
@@ -720,6 +722,51 b' class Test(unittest.TestCase):' | |||||
720 | # Failed is denoted by AssertionError (by default at least). |
|
722 | # Failed is denoted by AssertionError (by default at least). | |
721 | raise AssertionError(msg) |
|
723 | raise AssertionError(msg) | |
722 |
|
724 | |||
|
725 | def _runcommand(self, cmd, wd, replacements, env, debug=False, | |||
|
726 | timeout=None): | |||
|
727 | """Run command in a sub-process, capturing the output (stdout and | |||
|
728 | stderr). | |||
|
729 | ||||
|
730 | Return a tuple (exitcode, output). output is None in debug mode. | |||
|
731 | """ | |||
|
732 | if debug: | |||
|
733 | proc = subprocess.Popen(cmd, shell=True, cwd=wd, env=env) | |||
|
734 | ret = proc.wait() | |||
|
735 | return (ret, None) | |||
|
736 | ||||
|
737 | proc = Popen4(cmd, wd, timeout, env) | |||
|
738 | def cleanup(): | |||
|
739 | terminate(proc) | |||
|
740 | ret = proc.wait() | |||
|
741 | if ret == 0: | |||
|
742 | ret = signal.SIGTERM << 8 | |||
|
743 | killdaemons(env['DAEMON_PIDS']) | |||
|
744 | return ret | |||
|
745 | ||||
|
746 | output = '' | |||
|
747 | proc.tochild.close() | |||
|
748 | ||||
|
749 | try: | |||
|
750 | output = proc.fromchild.read() | |||
|
751 | except KeyboardInterrupt: | |||
|
752 | vlog('# Handling keyboard interrupt') | |||
|
753 | cleanup() | |||
|
754 | raise | |||
|
755 | ||||
|
756 | ret = proc.wait() | |||
|
757 | if wifexited(ret): | |||
|
758 | ret = os.WEXITSTATUS(ret) | |||
|
759 | ||||
|
760 | if proc.timeout: | |||
|
761 | ret = 'timeout' | |||
|
762 | ||||
|
763 | if ret: | |||
|
764 | killdaemons(env['DAEMON_PIDS']) | |||
|
765 | ||||
|
766 | for s, r in replacements: | |||
|
767 | output = re.sub(s, r, output) | |||
|
768 | return ret, output.splitlines(True) | |||
|
769 | ||||
723 | class PythonTest(Test): |
|
770 | class PythonTest(Test): | |
724 | """A Python-based test.""" |
|
771 | """A Python-based test.""" | |
725 |
|
772 | |||
@@ -733,8 +780,8 b' class PythonTest(Test):' | |||||
733 | vlog("# Running", cmd) |
|
780 | vlog("# Running", cmd) | |
734 | if os.name == 'nt': |
|
781 | if os.name == 'nt': | |
735 | replacements.append((r'\r\n', '\n')) |
|
782 | replacements.append((r'\r\n', '\n')) | |
736 | result = run(cmd, self._testtmp, replacements, env, |
|
783 | result = self._runcommand(cmd, self._testtmp, replacements, env, | |
737 | debug=self._debug, timeout=self._timeout) |
|
784 | debug=self._debug, timeout=self._timeout) | |
738 | if self._aborted: |
|
785 | if self._aborted: | |
739 | raise KeyboardInterrupt() |
|
786 | raise KeyboardInterrupt() | |
740 |
|
787 | |||
@@ -781,8 +828,9 b' class TTest(Test):' | |||||
781 | cmd = '%s "%s"' % (self._shell, fname) |
|
828 | cmd = '%s "%s"' % (self._shell, fname) | |
782 | vlog("# Running", cmd) |
|
829 | vlog("# Running", cmd) | |
783 |
|
830 | |||
784 |
exitcode, output = run(cmd, self._testtmp, replacements, |
|
831 | exitcode, output = self._runcommand(cmd, self._testtmp, replacements, | |
785 |
debug=self._debug, |
|
832 | env, debug=self._debug, | |
|
833 | timeout=self._timeout) | |||
786 |
|
834 | |||
787 | if self._aborted: |
|
835 | if self._aborted: | |
788 | raise KeyboardInterrupt() |
|
836 | raise KeyboardInterrupt() | |
@@ -1075,49 +1123,6 b' class TTest(Test):' | |||||
1075 | def _stringescape(s): |
|
1123 | def _stringescape(s): | |
1076 | return TTest.ESCAPESUB(TTest._escapef, s) |
|
1124 | return TTest.ESCAPESUB(TTest._escapef, s) | |
1077 |
|
1125 | |||
1078 |
|
||||
1079 | wifexited = getattr(os, "WIFEXITED", lambda x: False) |
|
|||
1080 | def run(cmd, wd, replacements, env, debug=False, timeout=None): |
|
|||
1081 | """Run command in a sub-process, capturing the output (stdout and stderr). |
|
|||
1082 | Return a tuple (exitcode, output). output is None in debug mode.""" |
|
|||
1083 | if debug: |
|
|||
1084 | proc = subprocess.Popen(cmd, shell=True, cwd=wd, env=env) |
|
|||
1085 | ret = proc.wait() |
|
|||
1086 | return (ret, None) |
|
|||
1087 |
|
||||
1088 | proc = Popen4(cmd, wd, timeout, env) |
|
|||
1089 | def cleanup(): |
|
|||
1090 | terminate(proc) |
|
|||
1091 | ret = proc.wait() |
|
|||
1092 | if ret == 0: |
|
|||
1093 | ret = signal.SIGTERM << 8 |
|
|||
1094 | killdaemons(env['DAEMON_PIDS']) |
|
|||
1095 | return ret |
|
|||
1096 |
|
||||
1097 | output = '' |
|
|||
1098 | proc.tochild.close() |
|
|||
1099 |
|
||||
1100 | try: |
|
|||
1101 | output = proc.fromchild.read() |
|
|||
1102 | except KeyboardInterrupt: |
|
|||
1103 | vlog('# Handling keyboard interrupt') |
|
|||
1104 | cleanup() |
|
|||
1105 | raise |
|
|||
1106 |
|
||||
1107 | ret = proc.wait() |
|
|||
1108 | if wifexited(ret): |
|
|||
1109 | ret = os.WEXITSTATUS(ret) |
|
|||
1110 |
|
||||
1111 | if proc.timeout: |
|
|||
1112 | ret = 'timeout' |
|
|||
1113 |
|
||||
1114 | if ret: |
|
|||
1115 | killdaemons(env['DAEMON_PIDS']) |
|
|||
1116 |
|
||||
1117 | for s, r in replacements: |
|
|||
1118 | output = re.sub(s, r, output) |
|
|||
1119 | return ret, output.splitlines(True) |
|
|||
1120 |
|
||||
1121 | iolock = threading.RLock() |
|
1126 | iolock = threading.RLock() | |
1122 |
|
1127 | |||
1123 | class SkipTest(Exception): |
|
1128 | class SkipTest(Exception): |
General Comments 0
You need to be logged in to leave comments.
Login now