Show More
@@ -22,6 +22,7 b' will change in the future.' | |||||
22 |
|
22 | |||
23 | import os |
|
23 | import os | |
24 | import os.path as path |
|
24 | import os.path as path | |
|
25 | import signal | |||
25 | import sys |
|
26 | import sys | |
26 | import subprocess |
|
27 | import subprocess | |
27 | import tempfile |
|
28 | import tempfile | |
@@ -148,8 +149,17 b' def make_exclude():' | |||||
148 | class IPTester(object): |
|
149 | class IPTester(object): | |
149 | """Call that calls iptest or trial in a subprocess. |
|
150 | """Call that calls iptest or trial in a subprocess. | |
150 | """ |
|
151 | """ | |
|
152 | #: string, name of test runner that will be called | |||
|
153 | runner = None | |||
|
154 | #: list, parameters for test runner | |||
|
155 | params = None | |||
|
156 | #: list, arguments of system call to be made to call test runner | |||
|
157 | call_args = None | |||
|
158 | #: list, process ids of subprocesses we start (for cleanup) | |||
|
159 | pids = None | |||
|
160 | ||||
151 | def __init__(self,runner='iptest',params=None): |
|
161 | def __init__(self,runner='iptest',params=None): | |
152 | """ """ |
|
162 | """Create new test runner.""" | |
153 | if runner == 'iptest': |
|
163 | if runner == 'iptest': | |
154 | # Find our own 'iptest' script OS-level entry point |
|
164 | # Find our own 'iptest' script OS-level entry point | |
155 | try: |
|
165 | try: | |
@@ -172,6 +182,10 b' class IPTester(object):' | |||||
172 | # Assemble call |
|
182 | # Assemble call | |
173 | self.call_args = self.runner+self.params |
|
183 | self.call_args = self.runner+self.params | |
174 |
|
184 | |||
|
185 | # Store pids of anything we start to clean up on deletion, if possible | |||
|
186 | # (on posix only, since win32 has no os.kill) | |||
|
187 | self.pids = [] | |||
|
188 | ||||
175 | if sys.platform == 'win32': |
|
189 | if sys.platform == 'win32': | |
176 | def _run_cmd(self): |
|
190 | def _run_cmd(self): | |
177 | # On Windows, use os.system instead of subprocess.call, because I |
|
191 | # On Windows, use os.system instead of subprocess.call, because I | |
@@ -183,7 +197,14 b' class IPTester(object):' | |||||
183 | return os.system(' '.join(self.call_args)) |
|
197 | return os.system(' '.join(self.call_args)) | |
184 | else: |
|
198 | else: | |
185 | def _run_cmd(self): |
|
199 | def _run_cmd(self): | |
186 |
|
|
200 | subp = subprocess.Popen(self.call_args) | |
|
201 | self.pids.append(subp.pid) | |||
|
202 | # If this fails, the pid will be left in self.pids and cleaned up | |||
|
203 | # later, but if the wait call succeeds, then we can clear the | |||
|
204 | # stored pid. | |||
|
205 | retcode = subp.wait() | |||
|
206 | self.pids.pop() | |||
|
207 | return retcode | |||
187 |
|
208 | |||
188 | def run(self): |
|
209 | def run(self): | |
189 | """Run the stored commands""" |
|
210 | """Run the stored commands""" | |
@@ -194,6 +215,22 b' class IPTester(object):' | |||||
194 | traceback.print_exc() |
|
215 | traceback.print_exc() | |
195 | return 1 # signal failure |
|
216 | return 1 # signal failure | |
196 |
|
217 | |||
|
218 | def __del__(self): | |||
|
219 | """Cleanup on exit by killing any leftover processes.""" | |||
|
220 | ||||
|
221 | if not hasattr(os, 'kill'): | |||
|
222 | return | |||
|
223 | ||||
|
224 | for pid in self.pids: | |||
|
225 | try: | |||
|
226 | print 'Cleaning stale PID:', pid | |||
|
227 | os.kill(pid, signal.SIGKILL) | |||
|
228 | except OSError: | |||
|
229 | # This is just a best effort, if we fail or the process was | |||
|
230 | # really gone, ignore it. | |||
|
231 | pass | |||
|
232 | ||||
|
233 | ||||
197 |
|
234 | |||
198 | def make_runners(): |
|
235 | def make_runners(): | |
199 | """Define the top-level packages that need to be tested. |
|
236 | """Define the top-level packages that need to be tested. |
General Comments 0
You need to be logged in to leave comments.
Login now