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