diff options
author | Joel Martin <github@martintribe.org> | 2012-10-31 15:51:23 -0500 |
---|---|---|
committer | Joel Martin <github@martintribe.org> | 2012-11-01 09:22:08 -0500 |
commit | 99e238901bcdce6d8e6ef32b310c64a6fca0216b (patch) | |
tree | 24e1229b39c658656720f3e12c7582e6ca29d7b1 /tests/runner.py | |
parent | 2c4a776b6f48317127f9ea57d749484fc7b3741c (diff) |
Update websockify, fix websocket tests, refactor websocket harness.
- pull in websockify c00c0eed from
https://github.com/kanaka/websockify with one-shot socket listener
cleanup and other misc updates.
- import the WebSocketProxy class directly and launch it one-shot
using the run_once parameter rather than spawning a separate
websockify via shell.
- create a python version of socket_server.sh and in the harness and
remove socket_server.sh.
- refactor clean_pids to use a two phase cleanup where it sends
a SIGTERM (to give the parent the chance to cleanup children) and
then send a SIGTERM 1 second later. This still has risk of leaving
child processes around (for example, the nc process in the original
socket_server.sh which would also hold onto the listen port).
Conflicts:
tests/runner.py
Diffstat (limited to 'tests/runner.py')
-rwxr-xr-x | tests/runner.py | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/tests/runner.py b/tests/runner.py index ccdff82c..f24756f6 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -57,7 +57,7 @@ an individual test with __rootpath__ = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) def path_from_root(*pathelems): return os.path.join(__rootpath__, *pathelems) -sys.path += [path_from_root('')] +sys.path += [path_from_root(''), path_from_root('third_party/websockify')] import tools.shared from tools.shared import * @@ -9232,15 +9232,30 @@ elif 'browser' in str(sys.argv): pids_to_clean = [] def clean_pids(self): - return - import signal - for pid in browser.pids_to_clean: - print '[killing %d]' % pid + import signal, errno + def pid_exists(pid): try: - os.kill(pid, signal.SIGKILL) # With this commented, we leave no children, but we hang the test harness on exit XXX - print '[kill succeeded]' - except: - print '[kill fail]' + # NOTE: may just kill the process in Windows + os.kill(pid, 0) + except OSError, e: + return e.errno == errno.EPERM + else: + return True + def kill_pids(pids, sig): + for pid in pids: + if not pid_exists(pid): + break + print '[killing %d]' % pid + try: + os.kill(pid, sig) + print '[kill succeeded]' + except: + print '[kill fail]' + # ask nicely (to try and catch the children) + kill_pids(browser.pids_to_clean, signal.SIGTERM) + time.sleep(1) + # extreme prejudice, may leave children + kill_pids(browser.pids_to_clean, signal.SIGKILL) browser.pids_to_clean = [] # Runs a websocket server at a specific port. port is the true tcp socket we forward to, port+1 is the websocket one @@ -9251,11 +9266,17 @@ elif 'browser' in str(sys.argv): self.no_server = no_server def __enter__(self): + import socket, websockify if not self.no_server: def server_func(q): - proc = Popen([path_from_root('tests', 'socket_server.sh'), str(self.port)]) - q.put(proc.pid) - proc.communicate() + q.put(None) # No sub-process to start + ssock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + ssock.bind(("127.0.0.1", self.port)) + ssock.listen(2) + while True: + csock, addr = ssock.accept() + print "Connection from %s" % repr(addr) + csock.send("te\x01\xff\x79st\x02") server_func = self.server_func or server_func @@ -9265,31 +9286,26 @@ elif 'browser' in str(sys.argv): browser.pids_to_clean.append(self.server.pid) while True: if not server_queue.empty(): - browser.pids_to_clean.append(server_queue.get()) + spid = server_queue.get() + if spid: + browser.pids_to_clean.append(spid) break time.sleep(0.1) print '[Socket server on processes %s]' % str(browser.pids_to_clean[-2:]) - def websockify_func(q): - print >> sys.stderr, 'running websockify on %d, forward to tcp %d' % (self.port+1, self.port) - #proc = Popen([path_from_root('third_party', 'websockify', 'other', 'websockify'), '-vvv', str(self.port+1), '127.0.0.1:' + str(self.port)]) - proc = Popen([path_from_root('third_party', 'websockify', 'websockify.py'), '-vvv', str(self.port+1), '127.0.0.1:' + str(self.port)]) - q.put(proc.pid) - proc.communicate() + def websockify_func(wsp): wsp.start_server() - websockify_queue = multiprocessing.Queue() - self.websockify = multiprocessing.Process(target=websockify_func, args=(websockify_queue,)) + print >> sys.stderr, 'running websockify on %d, forward to tcp %d' % (self.port+1, self.port) + wsp = websockify.WebSocketProxy(verbose=True, listen_port=self.port+1, target_host="127.0.0.1", target_port=self.port, run_once=True) + self.websockify = multiprocessing.Process(target=websockify_func, args=(wsp,)) self.websockify.start() browser.pids_to_clean.append(self.websockify.pid) - while True: - if not websockify_queue.empty(): - browser.pids_to_clean.append(websockify_queue.get()) - break - time.sleep(0.1) print '[Websockify on processes %s]' % str(browser.pids_to_clean[-2:]) def __exit__(self, *args, **kwargs): - time.sleep(1) + if self.websockify.is_alive(): + self.websockify.terminate() + self.websockify.join() # always run these tests last # make sure to use different ports in each one because it takes a while for the processes to be cleaned up |