Show More
@@ -374,34 +374,16 b' class IPTester(object):' | |||||
374 | # (on posix only, since win32 has no os.kill) |
|
374 | # (on posix only, since win32 has no os.kill) | |
375 | self.pids = [] |
|
375 | self.pids = [] | |
376 |
|
376 | |||
377 | if sys.platform == 'win32': |
|
377 | def _run_cmd(self): | |
378 | def _run_cmd(self): |
|
378 | # print >> sys.stderr, '*** CMD:', ' '.join(self.call_args) # dbg | |
379 | # On Windows, use os.system instead of subprocess.call, because I |
|
379 | subp = subprocess.Popen(self.call_args) | |
380 | # was having problems with subprocess and I just don't know enough |
|
380 | self.pids.append(subp.pid) | |
381 | # about win32 to debug this reliably. Os.system may be the 'old |
|
381 | # If this fails, the pid will be left in self.pids and cleaned up | |
382 | # fashioned' way to do it, but it works just fine. If someone |
|
382 | # later, but if the wait call succeeds, then we can clear the | |
383 | # later can clean this up that's fine, as long as the tests run |
|
383 | # stored pid. | |
384 | # reliably in win32. |
|
384 | retcode = subp.wait() | |
385 | # What types of problems are you having. They may be related to |
|
385 | self.pids.pop() | |
386 | # running Python in unboffered mode. BG. |
|
386 | return retcode | |
387 | for ndx, arg in enumerate(self.call_args): |
|
|||
388 | # Enclose in quotes if necessary and legal |
|
|||
389 | if ' ' in arg and os.path.isfile(arg) and arg[0] != '"': |
|
|||
390 | self.call_args[ndx] = '"%s"' % arg |
|
|||
391 | call_args = [py3compat.cast_unicode(x) for x in self.call_args] |
|
|||
392 | cmd = py3compat.unicode_to_str(u' '.join(call_args)) |
|
|||
393 | return os.system(cmd) |
|
|||
394 | else: |
|
|||
395 | def _run_cmd(self): |
|
|||
396 | # print >> sys.stderr, '*** CMD:', ' '.join(self.call_args) # dbg |
|
|||
397 | subp = subprocess.Popen(self.call_args) |
|
|||
398 | self.pids.append(subp.pid) |
|
|||
399 | # If this fails, the pid will be left in self.pids and cleaned up |
|
|||
400 | # later, but if the wait call succeeds, then we can clear the |
|
|||
401 | # stored pid. |
|
|||
402 | retcode = subp.wait() |
|
|||
403 | self.pids.pop() |
|
|||
404 | return retcode |
|
|||
405 |
|
387 | |||
406 | def run(self): |
|
388 | def run(self): | |
407 | """Run the stored commands""" |
|
389 | """Run the stored commands""" | |
@@ -416,17 +398,28 b' class IPTester(object):' | |||||
416 | subprocess.call(["coverage", "xml", "-o", self.coverage_xml]) |
|
398 | subprocess.call(["coverage", "xml", "-o", self.coverage_xml]) | |
417 | return retcode |
|
399 | return retcode | |
418 |
|
400 | |||
|
401 | @staticmethod | |||
|
402 | def _kill(pid): | |||
|
403 | """Attempt to kill the process on a best effort basis.""" | |||
|
404 | if hasattr(os, 'kill'): | |||
|
405 | os.kill(pid, signal.SIGKILL) | |||
|
406 | elif sys.platform == 'win32': | |||
|
407 | # Python 2.6 on Windows doesn't have os.kill. | |||
|
408 | from ctypes import windll | |||
|
409 | PROCESS_TERMINATE = 1 | |||
|
410 | handle = windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, pid) | |||
|
411 | windll.kernel32.TerminateProcess(handle, -1) | |||
|
412 | windll.kernel32.CloseHandle(handle) | |||
|
413 | else: | |||
|
414 | raise NotImplementedError | |||
|
415 | ||||
419 | def __del__(self): |
|
416 | def __del__(self): | |
420 | """Cleanup on exit by killing any leftover processes.""" |
|
417 | """Cleanup on exit by killing any leftover processes.""" | |
421 |
|
||||
422 | if not hasattr(os, 'kill'): |
|
|||
423 | return |
|
|||
424 |
|
||||
425 | for pid in self.pids: |
|
418 | for pid in self.pids: | |
426 | try: |
|
419 | try: | |
427 | print('Cleaning stale PID:', pid) |
|
420 | print('Cleaning stale PID:', pid) | |
428 |
|
|
421 | self._kill(pid) | |
429 | except OSError: |
|
422 | except (OSError, NotImplementedError): | |
430 | # This is just a best effort, if we fail or the process was |
|
423 | # This is just a best effort, if we fail or the process was | |
431 | # really gone, ignore it. |
|
424 | # really gone, ignore it. | |
432 | pass |
|
425 | pass |
General Comments 0
You need to be logged in to leave comments.
Login now