comparison tests/run-tests.py @ 18057:6b88ded2a993

run-tests: support running tests in parallel on windows Previously, we used os.spawnvp, which doesn't exist on Windows, and isn't needed anyway (the command line begins with an absolute path). We also need a slightly more convoluted way to wait for processes without specifying an order on Windows, as it lacks os.wait.
author Bryan O'Sullivan <bryano@fb.com>
date Tue, 11 Dec 2012 15:13:23 -0800
parents 5522a7951bd7
children fe5a41144982
comparison
equal deleted inserted replaced
18056:7c9b07f0da73 18057:6b88ded2a993
54 import time 54 import time
55 import re 55 import re
56 import threading 56 import threading
57 import killdaemons as killmod 57 import killdaemons as killmod
58 import cPickle as pickle 58 import cPickle as pickle
59 import Queue as queue
59 60
60 processlock = threading.Lock() 61 processlock = threading.Lock()
61 62
62 closefds = os.name == 'posix' 63 closefds = os.name == 'posix'
63 def Popen4(cmd, wd, timeout): 64 def Popen4(cmd, wd, timeout):
1077 test = tests.pop() 1078 test = tests.pop()
1078 if test not in whitelist and test in blacklist: 1079 if test not in whitelist and test in blacklist:
1079 blacklisted.append(test) 1080 blacklisted.append(test)
1080 else: 1081 else:
1081 job.append(test) 1082 job.append(test)
1082 fps = {} 1083
1084 waitq = queue.Queue()
1085
1086 # windows lacks os.wait, so we must emulate it
1087 def waitfor(proc, rfd):
1088 fp = os.fdopen(rfd, 'rb')
1089 return lambda: waitq.put((proc.pid, proc.wait(), fp))
1083 1090
1084 for j, job in enumerate(jobs): 1091 for j, job in enumerate(jobs):
1085 if not job: 1092 if not job:
1086 continue 1093 continue
1087 rfd, wfd = os.pipe() 1094 rfd, wfd = os.pipe()
1088 childopts = ['--child=%d' % wfd, '--port=%d' % (options.port + j * 3)] 1095 childopts = ['--child=%d' % wfd, '--port=%d' % (options.port + j * 3)]
1089 childtmp = os.path.join(HGTMP, 'child%d' % j) 1096 childtmp = os.path.join(HGTMP, 'child%d' % j)
1090 childopts += ['--tmpdir', childtmp] 1097 childopts += ['--tmpdir', childtmp]
1091 cmdline = [PYTHON, sys.argv[0]] + opts + childopts + job 1098 cmdline = [PYTHON, sys.argv[0]] + opts + childopts + job
1092 vlog(' '.join(cmdline)) 1099 vlog(' '.join(cmdline))
1093 fps[os.spawnvp(os.P_NOWAIT, cmdline[0], cmdline)] = os.fdopen(rfd, 'rb') 1100 proc = subprocess.Popen(cmdline, executable=cmdline[0])
1101 threading.Thread(target=waitfor(proc, rfd)).start()
1094 os.close(wfd) 1102 os.close(wfd)
1095 signal.signal(signal.SIGINT, signal.SIG_IGN) 1103 signal.signal(signal.SIGINT, signal.SIG_IGN)
1096 failures = 0 1104 failures = 0
1097 passed, skipped, failed = 0, 0, 0 1105 passed, skipped, failed = 0, 0, 0
1098 skips = [] 1106 skips = []
1099 fails = [] 1107 fails = []
1100 while fps: 1108 for job in jobs:
1101 pid, status = os.wait() 1109 if not job:
1102 fp = fps.pop(pid) 1110 continue
1111 pid, status, fp = waitq.get()
1103 try: 1112 try:
1104 childresults = pickle.load(fp) 1113 childresults = pickle.load(fp)
1105 except pickle.UnpicklingError: 1114 except pickle.UnpicklingError:
1106 pass 1115 pass
1107 else: 1116 else: