Show More
@@ -1,11 +1,12 b'' | |||||
1 | # http://travis-ci.org/#!/ipython/ipython |
|
1 | # http://travis-ci.org/#!/ipython/ipython | |
2 | language: python |
|
2 | language: python | |
3 | python: |
|
3 | python: | |
|
4 | - 3.4 | |||
4 | - 2.7 |
|
5 | - 2.7 | |
5 | - 3.3 |
|
6 | - 3.3 | |
6 | env: |
|
7 | env: | |
7 | - GROUP= |
|
|||
8 | - GROUP=js |
|
8 | - GROUP=js | |
|
9 | - GROUP= | |||
9 | before_install: |
|
10 | before_install: | |
10 | # workaround for https://github.com/travis-ci/travis-cookbooks/issues/155 |
|
11 | # workaround for https://github.com/travis-ci/travis-cookbooks/issues/155 | |
11 | - sudo rm -rf /dev/shm && sudo ln -s /run/shm /dev/shm |
|
12 | - sudo rm -rf /dev/shm && sudo ln -s /run/shm /dev/shm | |
@@ -18,3 +19,8 b' install:' | |||||
18 | - time python setup.py install -q |
|
19 | - time python setup.py install -q | |
19 | script: |
|
20 | script: | |
20 | - cd /tmp && iptest $GROUP |
|
21 | - cd /tmp && iptest $GROUP | |
|
22 | ||||
|
23 | matrix: | |||
|
24 | exclude: | |||
|
25 | - python: 3.3 | |||
|
26 | env: GROUP=js |
@@ -127,7 +127,10 b' class ZMQChannelHandler(AuthenticatedZMQStreamHandler):' | |||||
127 | # closed before the ZMQ streams are setup, they could be None. |
|
127 | # closed before the ZMQ streams are setup, they could be None. | |
128 | if self.zmq_stream is not None and not self.zmq_stream.closed(): |
|
128 | if self.zmq_stream is not None and not self.zmq_stream.closed(): | |
129 | self.zmq_stream.on_recv(None) |
|
129 | self.zmq_stream.on_recv(None) | |
|
130 | # close the socket directly, don't wait for the stream | |||
|
131 | socket = self.zmq_stream.socket | |||
130 | self.zmq_stream.close() |
|
132 | self.zmq_stream.close() | |
|
133 | socket.close() | |||
131 |
|
134 | |||
132 |
|
135 | |||
133 | class IOPubHandler(ZMQChannelHandler): |
|
136 | class IOPubHandler(ZMQChannelHandler): |
@@ -209,6 +209,7 b' class ShellChannel(ZMQSocketChannel):' | |||||
209 | def run(self): |
|
209 | def run(self): | |
210 | """The thread's main activity. Call start() instead.""" |
|
210 | """The thread's main activity. Call start() instead.""" | |
211 | self.socket = self.context.socket(zmq.DEALER) |
|
211 | self.socket = self.context.socket(zmq.DEALER) | |
|
212 | self.socket.linger = 1000 | |||
212 | self.socket.setsockopt(zmq.IDENTITY, self.session.bsession) |
|
213 | self.socket.setsockopt(zmq.IDENTITY, self.session.bsession) | |
213 | self.socket.connect(self.address) |
|
214 | self.socket.connect(self.address) | |
214 | self.stream = zmqstream.ZMQStream(self.socket, self.ioloop) |
|
215 | self.stream = zmqstream.ZMQStream(self.socket, self.ioloop) | |
@@ -408,6 +409,7 b' class IOPubChannel(ZMQSocketChannel):' | |||||
408 | def run(self): |
|
409 | def run(self): | |
409 | """The thread's main activity. Call start() instead.""" |
|
410 | """The thread's main activity. Call start() instead.""" | |
410 | self.socket = self.context.socket(zmq.SUB) |
|
411 | self.socket = self.context.socket(zmq.SUB) | |
|
412 | self.socket.linger = 1000 | |||
411 | self.socket.setsockopt(zmq.SUBSCRIBE,b'') |
|
413 | self.socket.setsockopt(zmq.SUBSCRIBE,b'') | |
412 | self.socket.setsockopt(zmq.IDENTITY, self.session.bsession) |
|
414 | self.socket.setsockopt(zmq.IDENTITY, self.session.bsession) | |
413 | self.socket.connect(self.address) |
|
415 | self.socket.connect(self.address) | |
@@ -468,6 +470,7 b' class StdInChannel(ZMQSocketChannel):' | |||||
468 | def run(self): |
|
470 | def run(self): | |
469 | """The thread's main activity. Call start() instead.""" |
|
471 | """The thread's main activity. Call start() instead.""" | |
470 | self.socket = self.context.socket(zmq.DEALER) |
|
472 | self.socket = self.context.socket(zmq.DEALER) | |
|
473 | self.socket.linger = 1000 | |||
471 | self.socket.setsockopt(zmq.IDENTITY, self.session.bsession) |
|
474 | self.socket.setsockopt(zmq.IDENTITY, self.session.bsession) | |
472 | self.socket.connect(self.address) |
|
475 | self.socket.connect(self.address) | |
473 | self.stream = zmqstream.ZMQStream(self.socket, self.ioloop) |
|
476 | self.stream = zmqstream.ZMQStream(self.socket, self.ioloop) | |
@@ -518,7 +521,7 b' class HBChannel(ZMQSocketChannel):' | |||||
518 | self.poller.unregister(self.socket) |
|
521 | self.poller.unregister(self.socket) | |
519 | self.socket.close() |
|
522 | self.socket.close() | |
520 | self.socket = self.context.socket(zmq.REQ) |
|
523 | self.socket = self.context.socket(zmq.REQ) | |
521 | self.socket.setsockopt(zmq.LINGER, 0) |
|
524 | self.socket.linger = 1000 | |
522 | self.socket.connect(self.address) |
|
525 | self.socket.connect(self.address) | |
523 |
|
526 | |||
524 | self.poller.register(self.socket, zmq.POLLIN) |
|
527 | self.poller.register(self.socket, zmq.POLLIN) |
@@ -531,6 +531,8 b' class ConnectionFileMixin(Configurable):' | |||||
531 | socket_type = channel_socket_types[channel] |
|
531 | socket_type = channel_socket_types[channel] | |
532 | self.log.debug("Connecting to: %s" % url) |
|
532 | self.log.debug("Connecting to: %s" % url) | |
533 | sock = self.context.socket(socket_type) |
|
533 | sock = self.context.socket(socket_type) | |
|
534 | # set linger to 1s to prevent hangs at exit | |||
|
535 | sock.linger = 1000 | |||
534 | if identity: |
|
536 | if identity: | |
535 | sock.identity = identity |
|
537 | sock.identity = identity | |
536 | sock.connect(url) |
|
538 | sock.connect(url) |
@@ -53,6 +53,7 b' class Heartbeat(Thread):' | |||||
53 |
|
53 | |||
54 | def run(self): |
|
54 | def run(self): | |
55 | self.socket = self.context.socket(zmq.REP) |
|
55 | self.socket = self.context.socket(zmq.REP) | |
|
56 | self.socket.linger = 1000 | |||
56 | c = ':' if self.transport == 'tcp' else '-' |
|
57 | c = ':' if self.transport == 'tcp' else '-' | |
57 | self.socket.bind('%s://%s' % (self.transport, self.ip) + c + str(self.port)) |
|
58 | self.socket.bind('%s://%s' % (self.transport, self.ip) + c + str(self.port)) | |
58 | while True: |
|
59 | while True: |
@@ -236,18 +236,22 b' class IPKernelApp(BaseIPythonApplication, InteractiveShellApp,' | |||||
236 | # atexit.register(context.term) |
|
236 | # atexit.register(context.term) | |
237 |
|
237 | |||
238 | self.shell_socket = context.socket(zmq.ROUTER) |
|
238 | self.shell_socket = context.socket(zmq.ROUTER) | |
|
239 | self.shell_socket.linger = 1000 | |||
239 | self.shell_port = self._bind_socket(self.shell_socket, self.shell_port) |
|
240 | self.shell_port = self._bind_socket(self.shell_socket, self.shell_port) | |
240 | self.log.debug("shell ROUTER Channel on port: %i" % self.shell_port) |
|
241 | self.log.debug("shell ROUTER Channel on port: %i" % self.shell_port) | |
241 |
|
242 | |||
242 | self.iopub_socket = context.socket(zmq.PUB) |
|
243 | self.iopub_socket = context.socket(zmq.PUB) | |
|
244 | self.iopub_socket.linger = 1000 | |||
243 | self.iopub_port = self._bind_socket(self.iopub_socket, self.iopub_port) |
|
245 | self.iopub_port = self._bind_socket(self.iopub_socket, self.iopub_port) | |
244 | self.log.debug("iopub PUB Channel on port: %i" % self.iopub_port) |
|
246 | self.log.debug("iopub PUB Channel on port: %i" % self.iopub_port) | |
245 |
|
247 | |||
246 | self.stdin_socket = context.socket(zmq.ROUTER) |
|
248 | self.stdin_socket = context.socket(zmq.ROUTER) | |
|
249 | self.stdin_socket.linger = 1000 | |||
247 | self.stdin_port = self._bind_socket(self.stdin_socket, self.stdin_port) |
|
250 | self.stdin_port = self._bind_socket(self.stdin_socket, self.stdin_port) | |
248 | self.log.debug("stdin ROUTER Channel on port: %i" % self.stdin_port) |
|
251 | self.log.debug("stdin ROUTER Channel on port: %i" % self.stdin_port) | |
249 |
|
252 | |||
250 | self.control_socket = context.socket(zmq.ROUTER) |
|
253 | self.control_socket = context.socket(zmq.ROUTER) | |
|
254 | self.control_socket.linger = 1000 | |||
251 | self.control_port = self._bind_socket(self.control_socket, self.control_port) |
|
255 | self.control_port = self._bind_socket(self.control_socket, self.control_port) | |
252 | self.log.debug("control ROUTER Channel on port: %i" % self.control_port) |
|
256 | self.log.debug("control ROUTER Channel on port: %i" % self.control_port) | |
253 |
|
257 |
@@ -6,16 +6,9 b' test suite.' | |||||
6 |
|
6 | |||
7 | """ |
|
7 | """ | |
8 |
|
8 | |||
9 | #----------------------------------------------------------------------------- |
|
9 | # Copyright (c) IPython Development Team. | |
10 | # Copyright (C) 2009-2011 The IPython Development Team |
|
10 | # Distributed under the terms of the Modified BSD License. | |
11 | # |
|
11 | ||
12 | # Distributed under the terms of the BSD License. The full license is in |
|
|||
13 | # the file COPYING, distributed as part of this software. |
|
|||
14 | #----------------------------------------------------------------------------- |
|
|||
15 |
|
||||
16 | #----------------------------------------------------------------------------- |
|
|||
17 | # Imports |
|
|||
18 | #----------------------------------------------------------------------------- |
|
|||
19 | from __future__ import print_function |
|
12 | from __future__ import print_function | |
20 |
|
13 | |||
21 | import argparse |
|
14 | import argparse | |
@@ -34,6 +27,24 b' from IPython.utils.py3compat import bytes_to_str' | |||||
34 | from IPython.utils.sysinfo import get_sys_info |
|
27 | from IPython.utils.sysinfo import get_sys_info | |
35 | from IPython.utils.tempdir import TemporaryDirectory |
|
28 | from IPython.utils.tempdir import TemporaryDirectory | |
36 |
|
29 | |||
|
30 | try: | |||
|
31 | # Python >= 3.3 | |||
|
32 | from subprocess import TimeoutExpired | |||
|
33 | def popen_wait(p, timeout): | |||
|
34 | return p.wait(timeout) | |||
|
35 | except ImportError: | |||
|
36 | class TimeoutExpired(Exception): | |||
|
37 | pass | |||
|
38 | def popen_wait(p, timeout): | |||
|
39 | """backport of Popen.wait from Python 3""" | |||
|
40 | for i in range(int(10 * timeout)): | |||
|
41 | if p.poll() is not None: | |||
|
42 | return | |||
|
43 | time.sleep(0.1) | |||
|
44 | if p.poll() is None: | |||
|
45 | raise TimeoutExpired | |||
|
46 | ||||
|
47 | NOTEBOOK_SHUTDOWN_TIMEOUT = 10 | |||
37 |
|
48 | |||
38 | class TestController(object): |
|
49 | class TestController(object): | |
39 | """Run tests in a subprocess |
|
50 | """Run tests in a subprocess | |
@@ -287,7 +298,27 b' class JSController(TestController):' | |||||
287 | except OSError: |
|
298 | except OSError: | |
288 | # already dead |
|
299 | # already dead | |
289 | pass |
|
300 | pass | |
290 | self.server.wait() |
|
301 | # wait 10s for the server to shutdown | |
|
302 | try: | |||
|
303 | popen_wait(self.server, NOTEBOOK_SHUTDOWN_TIMEOUT) | |||
|
304 | except TimeoutExpired: | |||
|
305 | # server didn't terminate, kill it | |||
|
306 | try: | |||
|
307 | print("Failed to terminate notebook server, killing it.", | |||
|
308 | file=sys.stderr | |||
|
309 | ) | |||
|
310 | self.server.kill() | |||
|
311 | except OSError: | |||
|
312 | # already dead | |||
|
313 | pass | |||
|
314 | # wait another 10s | |||
|
315 | try: | |||
|
316 | popen_wait(self.server, NOTEBOOK_SHUTDOWN_TIMEOUT) | |||
|
317 | except TimeoutExpired: | |||
|
318 | print("Notebook server still running (%s)" % self.server_info_file, | |||
|
319 | file=sys.stderr | |||
|
320 | ) | |||
|
321 | ||||
291 | self.stream_capturer.halt() |
|
322 | self.stream_capturer.halt() | |
292 | TestController.cleanup(self) |
|
323 | TestController.cleanup(self) | |
293 |
|
324 |
General Comments 0
You need to be logged in to leave comments.
Login now