##// END OF EJS Templates
Fix calls to validate_message
Thomas Kluyver -
Show More
@@ -1,484 +1,484 b''
1 """Test suite for our zeromq-based messaging specification.
1 """Test suite for our zeromq-based messaging specification.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2010-2011 The IPython Development Team
4 # Copyright (C) 2010-2011 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.
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9
9
10 import re
10 import re
11 from subprocess import PIPE
11 from subprocess import PIPE
12 from Queue import Empty
12 from Queue import Empty
13
13
14 import nose.tools as nt
14 import nose.tools as nt
15
15
16 from IPython.kernel import KernelManager
16 from IPython.kernel import KernelManager
17
17
18 from IPython.utils.traitlets import (
18 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 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Global setup and utilities
23 # Global setup and utilities
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 STARTUP_TIMEOUT = 60
26 STARTUP_TIMEOUT = 60
27 TIMEOUT = 15
27 TIMEOUT = 15
28
28
29 def setup():
29 def setup():
30 global KM, KC
30 global KM, KC
31 KM = KernelManager()
31 KM = KernelManager()
32 KM.start_kernel(stdout=PIPE, stderr=PIPE)
32 KM.start_kernel(stdout=PIPE, stderr=PIPE)
33 KC = KM.client()
33 KC = KM.client()
34 KC.start_channels()
34 KC.start_channels()
35
35
36 # wait for kernel to be ready
36 # wait for kernel to be ready
37 try:
37 try:
38 msg = KC.iopub_channel.get_msg(block=True, timeout=STARTUP_TIMEOUT)
38 msg = KC.iopub_channel.get_msg(block=True, timeout=STARTUP_TIMEOUT)
39 except Empty:
39 except Empty:
40 pass
40 pass
41 msg_id = KC.kernel_info()
41 msg_id = KC.kernel_info()
42 KC.get_shell_msg(block=True, timeout=STARTUP_TIMEOUT)
42 KC.get_shell_msg(block=True, timeout=STARTUP_TIMEOUT)
43 flush_channels()
43 flush_channels()
44
44
45
45
46 def teardown():
46 def teardown():
47 KC.stop_channels()
47 KC.stop_channels()
48 KM.shutdown_kernel()
48 KM.shutdown_kernel()
49
49
50
50
51 def flush_channels(kc=None):
51 def flush_channels(kc=None):
52 """flush any messages waiting on the queue"""
52 """flush any messages waiting on the queue"""
53 if kc is None:
53 if kc is None:
54 kc = KC
54 kc = KC
55 for channel in (kc.shell_channel, kc.iopub_channel):
55 for channel in (kc.shell_channel, kc.iopub_channel):
56 while True:
56 while True:
57 try:
57 try:
58 msg = channel.get_msg(block=True, timeout=0.1)
58 msg = channel.get_msg(block=True, timeout=0.1)
59 except Empty:
59 except Empty:
60 break
60 break
61 else:
61 else:
62 list(validate_message(msg))
62 validate_message(msg)
63
63
64
64
65 def execute(code='', kc=None, **kwargs):
65 def execute(code='', kc=None, **kwargs):
66 """wrapper for doing common steps for validating an execution request"""
66 """wrapper for doing common steps for validating an execution request"""
67 if kc is None:
67 if kc is None:
68 kc = KC
68 kc = KC
69 msg_id = kc.execute(code=code, **kwargs)
69 msg_id = kc.execute(code=code, **kwargs)
70 reply = kc.get_shell_msg(timeout=TIMEOUT)
70 reply = kc.get_shell_msg(timeout=TIMEOUT)
71 list(validate_message(reply, 'execute_reply', msg_id))
71 validate_message(reply, 'execute_reply', msg_id)
72 busy = kc.get_iopub_msg(timeout=TIMEOUT)
72 busy = kc.get_iopub_msg(timeout=TIMEOUT)
73 list(validate_message(busy, 'status', msg_id))
73 validate_message(busy, 'status', msg_id)
74 nt.assert_equal(busy['content']['execution_state'], 'busy')
74 nt.assert_equal(busy['content']['execution_state'], 'busy')
75
75
76 if not kwargs.get('silent'):
76 if not kwargs.get('silent'):
77 pyin = kc.get_iopub_msg(timeout=TIMEOUT)
77 pyin = kc.get_iopub_msg(timeout=TIMEOUT)
78 list(validate_message(pyin, 'pyin', msg_id))
78 validate_message(pyin, 'pyin', msg_id)
79 nt.assert_equal(pyin['content']['code'], code)
79 nt.assert_equal(pyin['content']['code'], code)
80
80
81 return msg_id, reply['content']
81 return msg_id, reply['content']
82
82
83 #-----------------------------------------------------------------------------
83 #-----------------------------------------------------------------------------
84 # MSG Spec References
84 # MSG Spec References
85 #-----------------------------------------------------------------------------
85 #-----------------------------------------------------------------------------
86
86
87
87
88 class Reference(HasTraits):
88 class Reference(HasTraits):
89
89
90 """
90 """
91 Base class for message spec specification testing.
91 Base class for message spec specification testing.
92
92
93 This class is the core of the message specification test. The
93 This class is the core of the message specification test. The
94 idea is that child classes implement trait attributes for each
94 idea is that child classes implement trait attributes for each
95 message keys, so that message keys can be tested against these
95 message keys, so that message keys can be tested against these
96 traits using :meth:`check` method.
96 traits using :meth:`check` method.
97
97
98 """
98 """
99
99
100 def check(self, d):
100 def check(self, d):
101 """validate a dict against our traits"""
101 """validate a dict against our traits"""
102 for key in self.trait_names():
102 for key in self.trait_names():
103 nt.assert_in(key, d)
103 nt.assert_in(key, d)
104 # FIXME: always allow None, probably not a good idea
104 # FIXME: always allow None, probably not a good idea
105 if d[key] is None:
105 if d[key] is None:
106 continue
106 continue
107 try:
107 try:
108 setattr(self, key, d[key])
108 setattr(self, key, d[key])
109 except TraitError as e:
109 except TraitError as e:
110 nt.assert_true(False, str(e))
110 nt.assert_true(False, str(e))
111
111
112
112
113 class RMessage(Reference):
113 class RMessage(Reference):
114 msg_id = Unicode()
114 msg_id = Unicode()
115 msg_type = Unicode()
115 msg_type = Unicode()
116 header = Dict()
116 header = Dict()
117 parent_header = Dict()
117 parent_header = Dict()
118 content = Dict()
118 content = Dict()
119
119
120 class RHeader(Reference):
120 class RHeader(Reference):
121 msg_id = Unicode()
121 msg_id = Unicode()
122 msg_type = Unicode()
122 msg_type = Unicode()
123 session = Unicode()
123 session = Unicode()
124 username = Unicode()
124 username = Unicode()
125
125
126 class RContent(Reference):
126 class RContent(Reference):
127 status = Enum((u'ok', u'error'))
127 status = Enum((u'ok', u'error'))
128
128
129
129
130 class ExecuteReply(Reference):
130 class ExecuteReply(Reference):
131 execution_count = Integer()
131 execution_count = Integer()
132 status = Enum((u'ok', u'error'))
132 status = Enum((u'ok', u'error'))
133
133
134 def check(self, d):
134 def check(self, d):
135 Reference.check(self, d)
135 Reference.check(self, d)
136 if d['status'] == 'ok':
136 if d['status'] == 'ok':
137 ExecuteReplyOkay().check(d)
137 ExecuteReplyOkay().check(d)
138 elif d['status'] == 'error':
138 elif d['status'] == 'error':
139 ExecuteReplyError().check(d)
139 ExecuteReplyError().check(d)
140
140
141
141
142 class ExecuteReplyOkay(Reference):
142 class ExecuteReplyOkay(Reference):
143 payload = List(Dict)
143 payload = List(Dict)
144 user_variables = Dict()
144 user_variables = Dict()
145 user_expressions = Dict()
145 user_expressions = Dict()
146
146
147
147
148 class ExecuteReplyError(Reference):
148 class ExecuteReplyError(Reference):
149 ename = Unicode()
149 ename = Unicode()
150 evalue = Unicode()
150 evalue = Unicode()
151 traceback = List(Unicode)
151 traceback = List(Unicode)
152
152
153
153
154 class OInfoReply(Reference):
154 class OInfoReply(Reference):
155 name = Unicode()
155 name = Unicode()
156 found = Bool()
156 found = Bool()
157 ismagic = Bool()
157 ismagic = Bool()
158 isalias = Bool()
158 isalias = Bool()
159 namespace = Enum((u'builtin', u'magics', u'alias', u'Interactive'))
159 namespace = Enum((u'builtin', u'magics', u'alias', u'Interactive'))
160 type_name = Unicode()
160 type_name = Unicode()
161 string_form = Unicode()
161 string_form = Unicode()
162 base_class = Unicode()
162 base_class = Unicode()
163 length = Integer()
163 length = Integer()
164 file = Unicode()
164 file = Unicode()
165 definition = Unicode()
165 definition = Unicode()
166 argspec = Dict()
166 argspec = Dict()
167 init_definition = Unicode()
167 init_definition = Unicode()
168 docstring = Unicode()
168 docstring = Unicode()
169 init_docstring = Unicode()
169 init_docstring = Unicode()
170 class_docstring = Unicode()
170 class_docstring = Unicode()
171 call_def = Unicode()
171 call_def = Unicode()
172 call_docstring = Unicode()
172 call_docstring = Unicode()
173 source = Unicode()
173 source = Unicode()
174
174
175 def check(self, d):
175 def check(self, d):
176 Reference.check(self, d)
176 Reference.check(self, d)
177 if d['argspec'] is not None:
177 if d['argspec'] is not None:
178 ArgSpec().check(d['argspec'])
178 ArgSpec().check(d['argspec'])
179
179
180
180
181 class ArgSpec(Reference):
181 class ArgSpec(Reference):
182 args = List(Unicode)
182 args = List(Unicode)
183 varargs = Unicode()
183 varargs = Unicode()
184 varkw = Unicode()
184 varkw = Unicode()
185 defaults = List()
185 defaults = List()
186
186
187
187
188 class Status(Reference):
188 class Status(Reference):
189 execution_state = Enum((u'busy', u'idle', u'starting'))
189 execution_state = Enum((u'busy', u'idle', u'starting'))
190
190
191
191
192 class CompleteReply(Reference):
192 class CompleteReply(Reference):
193 matches = List(Unicode)
193 matches = List(Unicode)
194
194
195
195
196 def Version(num, trait=Integer):
196 def Version(num, trait=Integer):
197 return List(trait, default_value=[0] * num, minlen=num, maxlen=num)
197 return List(trait, default_value=[0] * num, minlen=num, maxlen=num)
198
198
199
199
200 class KernelInfoReply(Reference):
200 class KernelInfoReply(Reference):
201
201
202 protocol_version = Version(2)
202 protocol_version = Version(2)
203 ipython_version = Version(4, Any)
203 ipython_version = Version(4, Any)
204 language_version = Version(3)
204 language_version = Version(3)
205 language = Unicode()
205 language = Unicode()
206
206
207 def _ipython_version_changed(self, name, old, new):
207 def _ipython_version_changed(self, name, old, new):
208 for v in new:
208 for v in new:
209 assert isinstance(v, int) or isinstance(v, basestring), \
209 assert isinstance(v, int) or isinstance(v, basestring), \
210 'expected int or string as version component, got {0!r}'.format(v)
210 'expected int or string as version component, got {0!r}'.format(v)
211
211
212
212
213 # IOPub messages
213 # IOPub messages
214
214
215 class PyIn(Reference):
215 class PyIn(Reference):
216 code = Unicode()
216 code = Unicode()
217 execution_count = Integer()
217 execution_count = Integer()
218
218
219
219
220 PyErr = ExecuteReplyError
220 PyErr = ExecuteReplyError
221
221
222
222
223 class Stream(Reference):
223 class Stream(Reference):
224 name = Enum((u'stdout', u'stderr'))
224 name = Enum((u'stdout', u'stderr'))
225 data = Unicode()
225 data = Unicode()
226
226
227
227
228 mime_pat = re.compile(r'\w+/\w+')
228 mime_pat = re.compile(r'\w+/\w+')
229
229
230 class DisplayData(Reference):
230 class DisplayData(Reference):
231 source = Unicode()
231 source = Unicode()
232 metadata = Dict()
232 metadata = Dict()
233 data = Dict()
233 data = Dict()
234 def _data_changed(self, name, old, new):
234 def _data_changed(self, name, old, new):
235 for k,v in new.iteritems():
235 for k,v in new.iteritems():
236 assert mime_pat.match(k)
236 assert mime_pat.match(k)
237 nt.assert_is_instance(v, basestring)
237 nt.assert_is_instance(v, basestring)
238
238
239
239
240 class PyOut(Reference):
240 class PyOut(Reference):
241 execution_count = Integer()
241 execution_count = Integer()
242 data = Dict()
242 data = Dict()
243 def _data_changed(self, name, old, new):
243 def _data_changed(self, name, old, new):
244 for k,v in new.iteritems():
244 for k,v in new.iteritems():
245 assert mime_pat.match(k)
245 assert mime_pat.match(k)
246 nt.assert_is_instance(v, basestring)
246 nt.assert_is_instance(v, basestring)
247
247
248
248
249 references = {
249 references = {
250 'execute_reply' : ExecuteReply(),
250 'execute_reply' : ExecuteReply(),
251 'object_info_reply' : OInfoReply(),
251 'object_info_reply' : OInfoReply(),
252 'status' : Status(),
252 'status' : Status(),
253 'complete_reply' : CompleteReply(),
253 'complete_reply' : CompleteReply(),
254 'kernel_info_reply': KernelInfoReply(),
254 'kernel_info_reply': KernelInfoReply(),
255 'pyin' : PyIn(),
255 'pyin' : PyIn(),
256 'pyout' : PyOut(),
256 'pyout' : PyOut(),
257 'pyerr' : PyErr(),
257 'pyerr' : PyErr(),
258 'stream' : Stream(),
258 'stream' : Stream(),
259 'display_data' : DisplayData(),
259 'display_data' : DisplayData(),
260 }
260 }
261 """
261 """
262 Specifications of `content` part of the reply messages.
262 Specifications of `content` part of the reply messages.
263 """
263 """
264
264
265
265
266 def validate_message(msg, msg_type=None, parent=None):
266 def validate_message(msg, msg_type=None, parent=None):
267 """validate a message
267 """validate a message
268
268
269 This is a generator, and must be iterated through to actually
269 This is a generator, and must be iterated through to actually
270 trigger each test.
270 trigger each test.
271
271
272 If msg_type and/or parent are given, the msg_type and/or parent msg_id
272 If msg_type and/or parent are given, the msg_type and/or parent msg_id
273 are compared with the given values.
273 are compared with the given values.
274 """
274 """
275 RMessage().check(msg)
275 RMessage().check(msg)
276 if msg_type:
276 if msg_type:
277 nt.assert_equal(msg['msg_type'], msg_type)
277 nt.assert_equal(msg['msg_type'], msg_type)
278 if parent:
278 if parent:
279 nt.assert_equal(msg['parent_header']['msg_id'], parent)
279 nt.assert_equal(msg['parent_header']['msg_id'], parent)
280 content = msg['content']
280 content = msg['content']
281 ref = references[msg['msg_type']]
281 ref = references[msg['msg_type']]
282 ref.check(content)
282 ref.check(content)
283
283
284
284
285 #-----------------------------------------------------------------------------
285 #-----------------------------------------------------------------------------
286 # Tests
286 # Tests
287 #-----------------------------------------------------------------------------
287 #-----------------------------------------------------------------------------
288
288
289 # Shell channel
289 # Shell channel
290
290
291 def test_execute():
291 def test_execute():
292 flush_channels()
292 flush_channels()
293
293
294 msg_id = KC.execute(code='x=1')
294 msg_id = KC.execute(code='x=1')
295 reply = KC.get_shell_msg(timeout=TIMEOUT)
295 reply = KC.get_shell_msg(timeout=TIMEOUT)
296 validate_message(reply, 'execute_reply', msg_id)
296 validate_message(reply, 'execute_reply', msg_id)
297
297
298
298
299 def test_execute_silent():
299 def test_execute_silent():
300 flush_channels()
300 flush_channels()
301 msg_id, reply = execute(code='x=1', silent=True)
301 msg_id, reply = execute(code='x=1', silent=True)
302
302
303 # flush status=idle
303 # flush status=idle
304 status = KC.iopub_channel.get_msg(timeout=TIMEOUT)
304 status = KC.iopub_channel.get_msg(timeout=TIMEOUT)
305 validate_message(status, 'status', msg_id)
305 validate_message(status, 'status', msg_id)
306 nt.assert_equal(status['content']['execution_state'], 'idle')
306 nt.assert_equal(status['content']['execution_state'], 'idle')
307
307
308 nt.assert_raises(Empty, KC.iopub_channel.get_msg, timeout=0.1)
308 nt.assert_raises(Empty, KC.iopub_channel.get_msg, timeout=0.1)
309 count = reply['execution_count']
309 count = reply['execution_count']
310
310
311 msg_id, reply = execute(code='x=2', silent=True)
311 msg_id, reply = execute(code='x=2', silent=True)
312
312
313 # flush status=idle
313 # flush status=idle
314 status = KC.iopub_channel.get_msg(timeout=TIMEOUT)
314 status = KC.iopub_channel.get_msg(timeout=TIMEOUT)
315 validate_message(status, 'status', msg_id)
315 validate_message(status, 'status', msg_id)
316 nt.assert_equal(status['content']['execution_state'], 'idle')
316 nt.assert_equal(status['content']['execution_state'], 'idle')
317
317
318 nt.assert_raises(Empty, KC.iopub_channel.get_msg, timeout=0.1)
318 nt.assert_raises(Empty, KC.iopub_channel.get_msg, timeout=0.1)
319 count_2 = reply['execution_count']
319 count_2 = reply['execution_count']
320 nt.assert_equal(count_2, count)
320 nt.assert_equal(count_2, count)
321
321
322
322
323 def test_execute_error():
323 def test_execute_error():
324 flush_channels()
324 flush_channels()
325
325
326 msg_id, reply = execute(code='1/0')
326 msg_id, reply = execute(code='1/0')
327 nt.assert_equal(reply['status'], 'error')
327 nt.assert_equal(reply['status'], 'error')
328 nt.assert_equal(reply['ename'], 'ZeroDivisionError')
328 nt.assert_equal(reply['ename'], 'ZeroDivisionError')
329
329
330 pyerr = KC.iopub_channel.get_msg(timeout=TIMEOUT)
330 pyerr = KC.iopub_channel.get_msg(timeout=TIMEOUT)
331 validate_message(pyerr, 'pyerr', msg_id)
331 validate_message(pyerr, 'pyerr', msg_id)
332
332
333
333
334 def test_execute_inc():
334 def test_execute_inc():
335 """execute request should increment execution_count"""
335 """execute request should increment execution_count"""
336 flush_channels()
336 flush_channels()
337
337
338 msg_id, reply = execute(code='x=1')
338 msg_id, reply = execute(code='x=1')
339 count = reply['execution_count']
339 count = reply['execution_count']
340
340
341 flush_channels()
341 flush_channels()
342
342
343 msg_id, reply = execute(code='x=2')
343 msg_id, reply = execute(code='x=2')
344 count_2 = reply['execution_count']
344 count_2 = reply['execution_count']
345 nt.assert_equal(count_2, count+1)
345 nt.assert_equal(count_2, count+1)
346
346
347
347
348 def test_user_variables():
348 def test_user_variables():
349 flush_channels()
349 flush_channels()
350
350
351 msg_id, reply = execute(code='x=1', user_variables=['x'])
351 msg_id, reply = execute(code='x=1', user_variables=['x'])
352 user_variables = reply['user_variables']
352 user_variables = reply['user_variables']
353 nt.assert_equal(user_variables, {u'x': {
353 nt.assert_equal(user_variables, {u'x': {
354 u'status': u'ok',
354 u'status': u'ok',
355 u'data': {u'text/plain': u'1'},
355 u'data': {u'text/plain': u'1'},
356 u'metadata': {},
356 u'metadata': {},
357 }})
357 }})
358
358
359
359
360 def test_user_variables_fail():
360 def test_user_variables_fail():
361 flush_channels()
361 flush_channels()
362
362
363 msg_id, reply = execute(code='x=1', user_variables=['nosuchname'])
363 msg_id, reply = execute(code='x=1', user_variables=['nosuchname'])
364 user_variables = reply['user_variables']
364 user_variables = reply['user_variables']
365 foo = user_variables['nosuchname']
365 foo = user_variables['nosuchname']
366 nt.assert_equal(foo['status'], 'error')
366 nt.assert_equal(foo['status'], 'error')
367 nt.assert_equal(foo['ename'], 'KeyError')
367 nt.assert_equal(foo['ename'], 'KeyError')
368
368
369
369
370 def test_user_expressions():
370 def test_user_expressions():
371 flush_channels()
371 flush_channels()
372
372
373 msg_id, reply = execute(code='x=1', user_expressions=dict(foo='x+1'))
373 msg_id, reply = execute(code='x=1', user_expressions=dict(foo='x+1'))
374 user_expressions = reply['user_expressions']
374 user_expressions = reply['user_expressions']
375 nt.assert_equal(user_expressions, {u'foo': {
375 nt.assert_equal(user_expressions, {u'foo': {
376 u'status': u'ok',
376 u'status': u'ok',
377 u'data': {u'text/plain': u'2'},
377 u'data': {u'text/plain': u'2'},
378 u'metadata': {},
378 u'metadata': {},
379 }})
379 }})
380
380
381
381
382 def test_user_expressions_fail():
382 def test_user_expressions_fail():
383 flush_channels()
383 flush_channels()
384
384
385 msg_id, reply = execute(code='x=0', user_expressions=dict(foo='nosuchname'))
385 msg_id, reply = execute(code='x=0', user_expressions=dict(foo='nosuchname'))
386 user_expressions = reply['user_expressions']
386 user_expressions = reply['user_expressions']
387 foo = user_expressions['foo']
387 foo = user_expressions['foo']
388 nt.assert_equal(foo['status'], 'error')
388 nt.assert_equal(foo['status'], 'error')
389 nt.assert_equal(foo['ename'], 'NameError')
389 nt.assert_equal(foo['ename'], 'NameError')
390
390
391
391
392 def test_oinfo():
392 def test_oinfo():
393 flush_channels()
393 flush_channels()
394
394
395 msg_id = KC.object_info('a')
395 msg_id = KC.object_info('a')
396 reply = KC.get_shell_msg(timeout=TIMEOUT)
396 reply = KC.get_shell_msg(timeout=TIMEOUT)
397 validate_message(reply, 'object_info_reply', msg_id)
397 validate_message(reply, 'object_info_reply', msg_id)
398
398
399
399
400 def test_oinfo_found():
400 def test_oinfo_found():
401 flush_channels()
401 flush_channels()
402
402
403 msg_id, reply = execute(code='a=5')
403 msg_id, reply = execute(code='a=5')
404
404
405 msg_id = KC.object_info('a')
405 msg_id = KC.object_info('a')
406 reply = KC.get_shell_msg(timeout=TIMEOUT)
406 reply = KC.get_shell_msg(timeout=TIMEOUT)
407 validate_message(reply, 'object_info_reply', msg_id)
407 validate_message(reply, 'object_info_reply', msg_id)
408 content = reply['content']
408 content = reply['content']
409 assert content['found']
409 assert content['found']
410 argspec = content['argspec']
410 argspec = content['argspec']
411 nt.assert_is(argspec, None)
411 nt.assert_is(argspec, None)
412
412
413
413
414 def test_oinfo_detail():
414 def test_oinfo_detail():
415 flush_channels()
415 flush_channels()
416
416
417 msg_id, reply = execute(code='ip=get_ipython()')
417 msg_id, reply = execute(code='ip=get_ipython()')
418
418
419 msg_id = KC.object_info('ip.object_inspect', detail_level=2)
419 msg_id = KC.object_info('ip.object_inspect', detail_level=2)
420 reply = KC.get_shell_msg(timeout=TIMEOUT)
420 reply = KC.get_shell_msg(timeout=TIMEOUT)
421 validate_message(reply, 'object_info_reply', msg_id)
421 validate_message(reply, 'object_info_reply', msg_id)
422 content = reply['content']
422 content = reply['content']
423 assert content['found']
423 assert content['found']
424 argspec = content['argspec']
424 argspec = content['argspec']
425 nt.assert_is_instance(argspec, dict, "expected non-empty argspec dict, got %r" % argspec)
425 nt.assert_is_instance(argspec, dict, "expected non-empty argspec dict, got %r" % argspec)
426 nt.assert_equal(argspec['defaults'], [0])
426 nt.assert_equal(argspec['defaults'], [0])
427
427
428
428
429 def test_oinfo_not_found():
429 def test_oinfo_not_found():
430 flush_channels()
430 flush_channels()
431
431
432 msg_id = KC.object_info('dne')
432 msg_id = KC.object_info('dne')
433 reply = KC.get_shell_msg(timeout=TIMEOUT)
433 reply = KC.get_shell_msg(timeout=TIMEOUT)
434 validate_message(reply, 'object_info_reply', msg_id)
434 validate_message(reply, 'object_info_reply', msg_id)
435 content = reply['content']
435 content = reply['content']
436 nt.assert_false(content['found'])
436 nt.assert_false(content['found'])
437
437
438
438
439 def test_complete():
439 def test_complete():
440 flush_channels()
440 flush_channels()
441
441
442 msg_id, reply = execute(code="alpha = albert = 5")
442 msg_id, reply = execute(code="alpha = albert = 5")
443
443
444 msg_id = KC.complete('al', 'al', 2)
444 msg_id = KC.complete('al', 'al', 2)
445 reply = KC.get_shell_msg(timeout=TIMEOUT)
445 reply = KC.get_shell_msg(timeout=TIMEOUT)
446 validate_message(reply, 'complete_reply', msg_id)
446 validate_message(reply, 'complete_reply', msg_id)
447 matches = reply['content']['matches']
447 matches = reply['content']['matches']
448 for name in ('alpha', 'albert'):
448 for name in ('alpha', 'albert'):
449 nt.assert_in(name, matches)
449 nt.assert_in(name, matches)
450
450
451
451
452 def test_kernel_info_request():
452 def test_kernel_info_request():
453 flush_channels()
453 flush_channels()
454
454
455 msg_id = KC.kernel_info()
455 msg_id = KC.kernel_info()
456 reply = KC.get_shell_msg(timeout=TIMEOUT)
456 reply = KC.get_shell_msg(timeout=TIMEOUT)
457 validate_message(reply, 'kernel_info_reply', msg_id)
457 validate_message(reply, 'kernel_info_reply', msg_id)
458
458
459
459
460 # IOPub channel
460 # IOPub channel
461
461
462
462
463 def test_stream():
463 def test_stream():
464 flush_channels()
464 flush_channels()
465
465
466 msg_id, reply = execute("print('hi')")
466 msg_id, reply = execute("print('hi')")
467
467
468 stdout = KC.iopub_channel.get_msg(timeout=TIMEOUT)
468 stdout = KC.iopub_channel.get_msg(timeout=TIMEOUT)
469 validate_message(stdout, 'stream', msg_id)
469 validate_message(stdout, 'stream', msg_id)
470 content = stdout['content']
470 content = stdout['content']
471 nt.assert_equal(content['name'], u'stdout')
471 nt.assert_equal(content['name'], u'stdout')
472 nt.assert_equal(content['data'], u'hi\n')
472 nt.assert_equal(content['data'], u'hi\n')
473
473
474
474
475 def test_display_data():
475 def test_display_data():
476 flush_channels()
476 flush_channels()
477
477
478 msg_id, reply = execute("from IPython.core.display import display; display(1)")
478 msg_id, reply = execute("from IPython.core.display import display; display(1)")
479
479
480 display = KC.iopub_channel.get_msg(timeout=TIMEOUT)
480 display = KC.iopub_channel.get_msg(timeout=TIMEOUT)
481 validate_message(display, 'display_data', parent=msg_id)
481 validate_message(display, 'display_data', parent=msg_id)
482 data = display['content']['data']
482 data = display['content']['data']
483 nt.assert_equal(data['text/plain'], u'1')
483 nt.assert_equal(data['text/plain'], u'1')
484
484
General Comments 0
You need to be logged in to leave comments. Login now