281 if found: |
282 if found: |
282 vlog("# Found prerequisite", p, "at", found) |
283 vlog("# Found prerequisite", p, "at", found) |
283 else: |
284 else: |
284 print "WARNING: Did not find prerequisite tool: "+p |
285 print "WARNING: Did not find prerequisite tool: "+p |
285 |
286 |
|
287 def killdaemons(): |
|
288 # Kill off any leftover daemon processes |
|
289 try: |
|
290 fp = open(DAEMON_PIDS) |
|
291 for line in fp: |
|
292 try: |
|
293 pid = int(line) |
|
294 except ValueError: |
|
295 continue |
|
296 try: |
|
297 os.kill(pid, 0) |
|
298 vlog('# Killing daemon process %d' % pid) |
|
299 os.kill(pid, signal.SIGTERM) |
|
300 time.sleep(0.25) |
|
301 os.kill(pid, 0) |
|
302 vlog('# Daemon process %d is stuck - really killing it' % pid) |
|
303 os.kill(pid, signal.SIGKILL) |
|
304 except OSError, err: |
|
305 if err.errno != errno.ESRCH: |
|
306 raise |
|
307 fp.close() |
|
308 os.unlink(DAEMON_PIDS) |
|
309 except IOError: |
|
310 pass |
|
311 |
286 def cleanup(options): |
312 def cleanup(options): |
287 if not options.keep_tmpdir: |
313 if not options.keep_tmpdir: |
288 vlog("# Cleaning up HGTMP", HGTMP) |
314 vlog("# Cleaning up HGTMP", HGTMP) |
289 shutil.rmtree(HGTMP, True) |
315 shutil.rmtree(HGTMP, True) |
290 |
316 |
430 ret = fromchild.close() |
456 ret = fromchild.close() |
431 if ret == None: |
457 if ret == None: |
432 ret = 0 |
458 ret = 0 |
433 else: |
459 else: |
434 proc = Popen4(cmd) |
460 proc = Popen4(cmd) |
|
461 def cleanup(): |
|
462 os.kill(proc.pid, signal.SIGTERM) |
|
463 ret = proc.wait() |
|
464 if ret == 0: |
|
465 ret = signal.SIGTERM << 8 |
|
466 killdaemons() |
|
467 return ret |
|
468 |
435 try: |
469 try: |
436 output = '' |
470 output = '' |
437 proc.tochild.close() |
471 proc.tochild.close() |
438 output = proc.fromchild.read() |
472 output = proc.fromchild.read() |
439 ret = proc.wait() |
473 ret = proc.wait() |
440 if os.WIFEXITED(ret): |
474 if os.WIFEXITED(ret): |
441 ret = os.WEXITSTATUS(ret) |
475 ret = os.WEXITSTATUS(ret) |
442 except Timeout: |
476 except Timeout: |
443 vlog('# Process %d timed out - killing it' % proc.pid) |
477 vlog('# Process %d timed out - killing it' % proc.pid) |
444 os.kill(proc.pid, signal.SIGTERM) |
478 ret = cleanup() |
445 ret = proc.wait() |
|
446 if ret == 0: |
|
447 ret = signal.SIGTERM << 8 |
|
448 output += ("\n### Abort: timeout after %d seconds.\n" |
479 output += ("\n### Abort: timeout after %d seconds.\n" |
449 % options.timeout) |
480 % options.timeout) |
|
481 except KeyboardInterrupt: |
|
482 vlog('# Handling keyboard interrupt') |
|
483 cleanup() |
|
484 raise |
|
485 |
450 return ret, splitnewlines(output) |
486 return ret, splitnewlines(output) |
451 |
487 |
452 def runone(options, test, skips, fails): |
488 def runone(options, test, skips, fails): |
453 '''tristate output: |
489 '''tristate output: |
454 None -> skipped |
490 None -> skipped |
587 f = open(err, "wb") |
623 f = open(err, "wb") |
588 for line in out: |
624 for line in out: |
589 f.write(line) |
625 f.write(line) |
590 f.close() |
626 f.close() |
591 |
627 |
592 # Kill off any leftover daemon processes |
628 killdaemons() |
593 try: |
|
594 fp = open(DAEMON_PIDS) |
|
595 for line in fp: |
|
596 try: |
|
597 pid = int(line) |
|
598 except ValueError: |
|
599 continue |
|
600 try: |
|
601 os.kill(pid, 0) |
|
602 vlog('# Killing daemon process %d' % pid) |
|
603 os.kill(pid, signal.SIGTERM) |
|
604 time.sleep(0.25) |
|
605 os.kill(pid, 0) |
|
606 vlog('# Daemon process %d is stuck - really killing it' % pid) |
|
607 os.kill(pid, signal.SIGKILL) |
|
608 except OSError, err: |
|
609 if err.errno != errno.ESRCH: |
|
610 raise |
|
611 fp.close() |
|
612 os.unlink(DAEMON_PIDS) |
|
613 except IOError: |
|
614 pass |
|
615 |
629 |
616 os.chdir(TESTDIR) |
630 os.chdir(TESTDIR) |
617 if not options.keep_tmpdir: |
631 if not options.keep_tmpdir: |
618 shutil.rmtree(tmpd, True) |
632 shutil.rmtree(tmpd, True) |
619 if skipped: |
633 if skipped: |
681 childopts += ['--tmpdir', childtmp] |
696 childopts += ['--tmpdir', childtmp] |
682 cmdline = [PYTHON, sys.argv[0]] + opts + childopts + job |
697 cmdline = [PYTHON, sys.argv[0]] + opts + childopts + job |
683 vlog(' '.join(cmdline)) |
698 vlog(' '.join(cmdline)) |
684 fps[os.spawnvp(os.P_NOWAIT, cmdline[0], cmdline)] = os.fdopen(rfd, 'r') |
699 fps[os.spawnvp(os.P_NOWAIT, cmdline[0], cmdline)] = os.fdopen(rfd, 'r') |
685 os.close(wfd) |
700 os.close(wfd) |
|
701 signal.signal(signal.SIGINT, signal.SIG_IGN) |
686 failures = 0 |
702 failures = 0 |
687 tested, skipped, failed = 0, 0, 0 |
703 tested, skipped, failed = 0, 0, 0 |
688 skips = [] |
704 skips = [] |
689 fails = [] |
705 fails = [] |
690 while fps: |
706 while fps: |
691 pid, status = os.wait() |
707 pid, status = os.wait() |
692 fp = fps.pop(pid) |
708 fp = fps.pop(pid) |
693 l = fp.read().splitlines() |
709 l = fp.read().splitlines() |
694 test, skip, fail = map(int, l[:3]) |
710 try: |
|
711 test, skip, fail = map(int, l[:3]) |
|
712 except ValueError: |
|
713 test, skip, fail = 0, 0, 0 |
695 split = -fail or len(l) |
714 split = -fail or len(l) |
696 for s in l[3:split]: |
715 for s in l[3:split]: |
697 skips.append(s.split(" ", 1)) |
716 skips.append(s.split(" ", 1)) |
698 for s in l[split:]: |
717 for s in l[split:]: |
699 fails.append(s.split(" ", 1)) |
718 fails.append(s.split(" ", 1)) |