##// END OF EJS Templates
move kernel-test utilities to kernel.tests.utils...
MinRK -
Show More
@@ -0,0 +1,168 b''
1 """utilities for testing IPython kernels"""
2
3 #-------------------------------------------------------------------------------
4 # Copyright (C) 2013 The IPython Development Team
5 #
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
8 #-------------------------------------------------------------------------------
9
10 #-------------------------------------------------------------------------------
11 # Imports
12 #-------------------------------------------------------------------------------
13
14 import atexit
15
16 from contextlib import contextmanager
17 from subprocess import PIPE
18 from Queue import Empty
19
20 import nose.tools as nt
21
22 from IPython.kernel import KernelManager
23
24 #-------------------------------------------------------------------------------
25 # Globals
26 #-------------------------------------------------------------------------------
27
28 STARTUP_TIMEOUT = 60
29 TIMEOUT = 15
30
31 KM = None
32 KC = None
33
34 #-------------------------------------------------------------------------------
35 # code
36 #-------------------------------------------------------------------------------
37
38
39 def start_new_kernel():
40 """start a new kernel, and return its Manager and Client"""
41 km = KernelManager()
42 km.start_kernel(stdout=PIPE, stderr=PIPE)
43 kc = km.client()
44 kc.start_channels()
45
46 msg_id = kc.kernel_info()
47 kc.get_shell_msg(block=True, timeout=STARTUP_TIMEOUT)
48 flush_channels(kc)
49 return km, kc
50
51 def flush_channels(kc=None):
52 """flush any messages waiting on the queue"""
53 from .test_message_spec import validate_message
54
55 if kc is None:
56 kc = KC
57 for channel in (kc.shell_channel, kc.iopub_channel):
58 while True:
59 try:
60 msg = channel.get_msg(block=True, timeout=0.1)
61 except Empty:
62 break
63 else:
64 validate_message(msg)
65
66
67 def execute(code='', kc=None, **kwargs):
68 """wrapper for doing common steps for validating an execution request"""
69 from .test_message_spec import validate_message
70 if kc is None:
71 kc = KC
72 msg_id = kc.execute(code=code, **kwargs)
73 reply = kc.get_shell_msg(timeout=TIMEOUT)
74 validate_message(reply, 'execute_reply', msg_id)
75 busy = kc.get_iopub_msg(timeout=TIMEOUT)
76 validate_message(busy, 'status', msg_id)
77 nt.assert_equal(busy['content']['execution_state'], 'busy')
78
79 if not kwargs.get('silent'):
80 pyin = kc.get_iopub_msg(timeout=TIMEOUT)
81 validate_message(pyin, 'pyin', msg_id)
82 nt.assert_equal(pyin['content']['code'], code)
83
84 return msg_id, reply['content']
85
86 def start_global_kernel():
87 """start the global kernel (if it isn't running) and return its client"""
88 global KM, KC
89 print KM, KC
90 if KM is None:
91 KM, KC = start_new_kernel()
92 atexit.register(stop_global_kernel)
93 return KC
94
95 @contextmanager
96 def kernel():
97 """Context manager for the global kernel instance
98
99 Should be used for most kernel tests
100
101 Returns
102 -------
103 kernel_client: connected KernelClient instance
104 """
105 yield start_global_kernel()
106
107 def uses_kernel(test_f):
108 """Decorator for tests that use the global kernel"""
109 def wrapped_test():
110 with kernel() as kc:
111 test_f(kc)
112 wrapped_test.__doc__ = test_f.__doc__
113 wrapped_test.__name__ = test_f.__name__
114 return wrapped_test
115
116 def stop_global_kernel():
117 """Stop the global shared kernel instance, if it exists"""
118 global KM, KC
119 KC.stop_channels()
120 KC = None
121 if KM is None:
122 return
123 KM.shutdown_kernel(now=True)
124 KM = None
125
126 @contextmanager
127 def new_kernel():
128 """Context manager for a new kernel in a subprocess
129
130 Should only be used for tests where the kernel must not be re-used.
131
132 Returns
133 -------
134 kernel_client: connected KernelClient instance
135 """
136 km, kc = start_new_kernel()
137 try:
138 yield kc
139 finally:
140 kc.stop_channels()
141 km.shutdown_kernel()
142
143
144 def assemble_output(iopub):
145 """assemble stdout/err from an execution"""
146 stdout = ''
147 stderr = ''
148 while True:
149 msg = iopub.get_msg(block=True, timeout=1)
150 msg_type = msg['msg_type']
151 content = msg['content']
152 if msg_type == 'status' and content['execution_state'] == 'idle':
153 # idle message signals end of output
154 break
155 elif msg['msg_type'] == 'stream':
156 if content['name'] == 'stdout':
157 stdout = stdout + content['data']
158 elif content['name'] == 'stderr':
159 stderr = stderr + content['data']
160 else:
161 raise KeyError("bad stream: %r" % content['name'])
162 else:
163 # other output, ignored
164 pass
165 return stdout, stderr
166
167
168
@@ -0,0 +1,58 b''
1 """test the IPython Kernel"""
2
3 #-------------------------------------------------------------------------------
4 # Copyright (C) 2013 The IPython Development Team
5 #
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
8 #-------------------------------------------------------------------------------
9
10 #-------------------------------------------------------------------------------
11 # Imports
12 #-------------------------------------------------------------------------------
13
14 import os
15 import shutil
16 import sys
17 import tempfile
18
19 import nose.tools as nt
20
21 from IPython.testing import decorators as dec
22 from IPython.utils import path, py3compat
23
24 from .utils import new_kernel, kernel, TIMEOUT, assemble_output, execute, flush_channels
25
26 #-------------------------------------------------------------------------------
27 # Tests
28 #-------------------------------------------------------------------------------
29 IPYTHONDIR = None
30 save_env = None
31 save_get_ipython_dir = None
32
33 def setup():
34 """setup temporary IPYTHONDIR for tests"""
35 global IPYTHONDIR
36 global save_env
37 global save_get_ipython_dir
38
39 IPYTHONDIR = tempfile.mkdtemp()
40
41 save_env = os.environ.copy()
42 os.environ["IPYTHONDIR"] = IPYTHONDIR
43
44 save_get_ipython_dir = path.get_ipython_dir
45 path.get_ipython_dir = lambda : IPYTHONDIR
46 print 'setup'
47
48
49 def teardown():
50 print 'tearing down'
51 path.get_ipython_dir = save_get_ipython_dir
52 os.environ = save_env
53
54 try:
55 shutil.rmtree(IPYTHONDIR)
56 except (OSError, IOError):
57 # no such file
58 pass
@@ -11,104 +11,18 b''
11 # Imports
11 # Imports
12 #-------------------------------------------------------------------------------
12 #-------------------------------------------------------------------------------
13
13
14 import os
15 import shutil
16 import sys
14 import sys
17 import tempfile
18
19 from contextlib import contextmanager
20 from subprocess import PIPE
21
15
22 import nose.tools as nt
16 import nose.tools as nt
23
17
24 from IPython.kernel import KernelManager
25 from IPython.kernel.tests.test_message_spec import execute, flush_channels
26 from IPython.testing import decorators as dec, tools as tt
18 from IPython.testing import decorators as dec, tools as tt
27 from IPython.utils import path, py3compat
19 from IPython.utils import py3compat
20
21 from .utils import new_kernel, kernel, TIMEOUT, assemble_output, execute, flush_channels
28
22
29 #-------------------------------------------------------------------------------
23 #-------------------------------------------------------------------------------
30 # Tests
24 # Tests
31 #-------------------------------------------------------------------------------
25 #-------------------------------------------------------------------------------
32 IPYTHONDIR = None
33 save_env = None
34 save_get_ipython_dir = None
35
36 STARTUP_TIMEOUT = 60
37 TIMEOUT = 15
38
39 def setup():
40 """setup temporary IPYTHONDIR for tests"""
41 global IPYTHONDIR
42 global save_env
43 global save_get_ipython_dir
44
45 IPYTHONDIR = tempfile.mkdtemp()
46
47 save_env = os.environ.copy()
48 os.environ["IPYTHONDIR"] = IPYTHONDIR
49
50 save_get_ipython_dir = path.get_ipython_dir
51 path.get_ipython_dir = lambda : IPYTHONDIR
52
53
54 def teardown():
55 path.get_ipython_dir = save_get_ipython_dir
56 os.environ = save_env
57
58 try:
59 shutil.rmtree(IPYTHONDIR)
60 except (OSError, IOError):
61 # no such file
62 pass
63
64
65 @contextmanager
66 def new_kernel():
67 """start a kernel in a subprocess, and wait for it to be ready
68
69 Returns
70 -------
71 kernel_manager: connected KernelManager instance
72 """
73 KM = KernelManager()
74
75 KM.start_kernel(stdout=PIPE, stderr=PIPE)
76 KC = KM.client()
77 KC.start_channels()
78
79 # wait for kernel to be ready
80 KC.shell_channel.execute("import sys")
81 KC.shell_channel.get_msg(block=True, timeout=STARTUP_TIMEOUT)
82 flush_channels(KC)
83 try:
84 yield KC
85 finally:
86 KC.stop_channels()
87 KM.shutdown_kernel()
88
89
90 def assemble_output(iopub):
91 """assemble stdout/err from an execution"""
92 stdout = ''
93 stderr = ''
94 while True:
95 msg = iopub.get_msg(block=True, timeout=1)
96 msg_type = msg['msg_type']
97 content = msg['content']
98 if msg_type == 'status' and content['execution_state'] == 'idle':
99 # idle message signals end of output
100 break
101 elif msg['msg_type'] == 'stream':
102 if content['name'] == 'stdout':
103 stdout = stdout + content['data']
104 elif content['name'] == 'stderr':
105 stderr = stderr + content['data']
106 else:
107 raise KeyError("bad stream: %r" % content['name'])
108 else:
109 # other output, ignored
110 pass
111 return stdout, stderr
112
26
113
27
114 def _check_mp_mode(kc, expected=False, stream="stdout"):
28 def _check_mp_mode(kc, expected=False, stream="stdout"):
@@ -123,7 +37,7 b' def _check_mp_mode(kc, expected=False, stream="stdout"):'
123
37
124 def test_simple_print():
38 def test_simple_print():
125 """simple print statement in kernel"""
39 """simple print statement in kernel"""
126 with new_kernel() as kc:
40 with kernel() as kc:
127 iopub = kc.iopub_channel
41 iopub = kc.iopub_channel
128 msg_id, content = execute(kc=kc, code="print ('hi')")
42 msg_id, content = execute(kc=kc, code="print ('hi')")
129 stdout, stderr = assemble_output(iopub)
43 stdout, stderr = assemble_output(iopub)
@@ -165,7 +79,7 b' def test_subprocess_print():'
165
79
166 def test_subprocess_noprint():
80 def test_subprocess_noprint():
167 """mp.Process without print doesn't trigger iostream mp_mode"""
81 """mp.Process without print doesn't trigger iostream mp_mode"""
168 with new_kernel() as kc:
82 with kernel() as kc:
169 iopub = kc.iopub_channel
83 iopub = kc.iopub_channel
170
84
171 np = 5
85 np = 5
@@ -210,7 +124,7 b' def test_subprocess_error():'
210
124
211 def test_raw_input():
125 def test_raw_input():
212 """test [raw_]input"""
126 """test [raw_]input"""
213 with new_kernel() as kc:
127 with kernel() as kc:
214 iopub = kc.iopub_channel
128 iopub = kc.iopub_channel
215
129
216 input_f = "input" if py3compat.PY3 else "raw_input"
130 input_f = "input" if py3compat.PY3 else "raw_input"
@@ -232,7 +146,7 b' def test_raw_input():'
232 @dec.skipif(py3compat.PY3)
146 @dec.skipif(py3compat.PY3)
233 def test_eval_input():
147 def test_eval_input():
234 """test input() on Python 2"""
148 """test input() on Python 2"""
235 with new_kernel() as kc:
149 with kernel() as kc:
236 iopub = kc.iopub_channel
150 iopub = kc.iopub_channel
237
151
238 input_f = "input" if py3compat.PY3 else "raw_input"
152 input_f = "input" if py3compat.PY3 else "raw_input"
@@ -1,7 +1,7 b''
1 """Test suite for our zeromq-based messaging specification.
1 """Test suite for our zeromq-based message specification.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2010-2011 The IPython Development Team
4 # Copyright (C) 2010 The IPython Development Team
5 #
5 #
6 # Distributed under the terms of the BSD License. The full license is in
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING.txt, distributed as part of this software.
7 # the file COPYING.txt, distributed as part of this software.
@@ -19,72 +19,21 b' from IPython.utils.traitlets import ('
19 HasTraits, TraitError, Bool, Unicode, Dict, Integer, List, Enum, Any,
19 HasTraits, TraitError, Bool, Unicode, Dict, Integer, List, Enum, Any,
20 )
20 )
21
21
22 from .utils import TIMEOUT, start_global_kernel, flush_channels, execute
23
22 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
23 # Global setup and utilities
25 # Globals
24 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
25
27 KC = None
26 STARTUP_TIMEOUT = 60
27 TIMEOUT = 15
28
28
29 def setup():
29 def setup():
30 global KM, KC
30 global KC
31 KM = KernelManager()
31 KC = start_global_kernel()
32 KM.start_kernel(stdout=PIPE, stderr=PIPE)
33 KC = KM.client()
34 KC.start_channels()
35
36 # wait for kernel to be ready
37 try:
38 msg = KC.iopub_channel.get_msg(block=True, timeout=STARTUP_TIMEOUT)
39 except Empty:
40 pass
41 msg_id = KC.kernel_info()
42 KC.get_shell_msg(block=True, timeout=STARTUP_TIMEOUT)
43 flush_channels()
44
45
46 def teardown():
47 KC.stop_channels()
48 KM.shutdown_kernel()
49
50
51 def flush_channels(kc=None):
52 """flush any messages waiting on the queue"""
53 if kc is None:
54 kc = KC
55 for channel in (kc.shell_channel, kc.iopub_channel):
56 while True:
57 try:
58 msg = channel.get_msg(block=True, timeout=0.1)
59 except Empty:
60 break
61 else:
62 validate_message(msg)
63
64
65 def execute(code='', kc=None, **kwargs):
66 """wrapper for doing common steps for validating an execution request"""
67 if kc is None:
68 kc = KC
69 msg_id = kc.execute(code=code, **kwargs)
70 reply = kc.get_shell_msg(timeout=TIMEOUT)
71 validate_message(reply, 'execute_reply', msg_id)
72 busy = kc.get_iopub_msg(timeout=TIMEOUT)
73 validate_message(busy, 'status', msg_id)
74 nt.assert_equal(busy['content']['execution_state'], 'busy')
75
76 if not kwargs.get('silent'):
77 pyin = kc.get_iopub_msg(timeout=TIMEOUT)
78 validate_message(pyin, 'pyin', msg_id)
79 nt.assert_equal(pyin['content']['code'], code)
80
81 return msg_id, reply['content']
82
32
83 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
84 # MSG Spec References
34 # Message Spec References
85 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
86
36
87
88 class Reference(HasTraits):
37 class Reference(HasTraits):
89
38
90 """
39 """
General Comments 0
You need to be logged in to leave comments. Login now