##// END OF EJS Templates
Remove most uses of ParametricTestCase
Thomas Kluyver -
Show More
@@ -1,380 +1,379 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Test Parallel magics
2 """Test Parallel magics
3
3
4 Authors:
4 Authors:
5
5
6 * Min RK
6 * Min RK
7 """
7 """
8 #-------------------------------------------------------------------------------
8 #-------------------------------------------------------------------------------
9 # Copyright (C) 2011 The IPython Development Team
9 # Copyright (C) 2011 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-------------------------------------------------------------------------------
13 #-------------------------------------------------------------------------------
14
14
15 #-------------------------------------------------------------------------------
15 #-------------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-------------------------------------------------------------------------------
17 #-------------------------------------------------------------------------------
18
18
19 import re
19 import re
20 import sys
20 import sys
21 import time
21 import time
22
22
23 import zmq
23 import zmq
24 from nose import SkipTest
24 from nose import SkipTest
25
25
26 from IPython.testing import decorators as dec
26 from IPython.testing import decorators as dec
27 from IPython.testing.ipunittest import ParametricTestCase
28 from IPython.utils.io import capture_output
27 from IPython.utils.io import capture_output
29
28
30 from IPython import parallel as pmod
29 from IPython import parallel as pmod
31 from IPython.parallel import error
30 from IPython.parallel import error
32 from IPython.parallel import AsyncResult
31 from IPython.parallel import AsyncResult
33 from IPython.parallel.util import interactive
32 from IPython.parallel.util import interactive
34
33
35 from IPython.parallel.tests import add_engines
34 from IPython.parallel.tests import add_engines
36
35
37 from .clienttest import ClusterTestCase, generate_output
36 from .clienttest import ClusterTestCase, generate_output
38
37
39 def setup():
38 def setup():
40 add_engines(3, total=True)
39 add_engines(3, total=True)
41
40
42 class TestParallelMagics(ClusterTestCase, ParametricTestCase):
41 class TestParallelMagics(ClusterTestCase):
43
42
44 def test_px_blocking(self):
43 def test_px_blocking(self):
45 ip = get_ipython()
44 ip = get_ipython()
46 v = self.client[-1:]
45 v = self.client[-1:]
47 v.activate()
46 v.activate()
48 v.block=True
47 v.block=True
49
48
50 ip.magic('px a=5')
49 ip.magic('px a=5')
51 self.assertEqual(v['a'], [5])
50 self.assertEqual(v['a'], [5])
52 ip.magic('px a=10')
51 ip.magic('px a=10')
53 self.assertEqual(v['a'], [10])
52 self.assertEqual(v['a'], [10])
54 # just 'print a' works ~99% of the time, but this ensures that
53 # just 'print a' works ~99% of the time, but this ensures that
55 # the stdout message has arrived when the result is finished:
54 # the stdout message has arrived when the result is finished:
56 with capture_output() as io:
55 with capture_output() as io:
57 ip.magic(
56 ip.magic(
58 'px import sys,time;print(a);sys.stdout.flush();time.sleep(0.2)'
57 'px import sys,time;print(a);sys.stdout.flush();time.sleep(0.2)'
59 )
58 )
60 self.assertIn('[stdout:', io.stdout)
59 self.assertIn('[stdout:', io.stdout)
61 self.assertNotIn('\n\n', io.stdout)
60 self.assertNotIn('\n\n', io.stdout)
62 assert io.stdout.rstrip().endswith('10')
61 assert io.stdout.rstrip().endswith('10')
63 self.assertRaisesRemote(ZeroDivisionError, ip.magic, 'px 1/0')
62 self.assertRaisesRemote(ZeroDivisionError, ip.magic, 'px 1/0')
64
63
65 def _check_generated_stderr(self, stderr, n):
64 def _check_generated_stderr(self, stderr, n):
66 expected = [
65 expected = [
67 r'\[stderr:\d+\]',
66 r'\[stderr:\d+\]',
68 '^stderr$',
67 '^stderr$',
69 '^stderr2$',
68 '^stderr2$',
70 ] * n
69 ] * n
71
70
72 self.assertNotIn('\n\n', stderr)
71 self.assertNotIn('\n\n', stderr)
73 lines = stderr.splitlines()
72 lines = stderr.splitlines()
74 self.assertEqual(len(lines), len(expected), stderr)
73 self.assertEqual(len(lines), len(expected), stderr)
75 for line,expect in zip(lines, expected):
74 for line,expect in zip(lines, expected):
76 if isinstance(expect, str):
75 if isinstance(expect, str):
77 expect = [expect]
76 expect = [expect]
78 for ex in expect:
77 for ex in expect:
79 assert re.search(ex, line) is not None, "Expected %r in %r" % (ex, line)
78 assert re.search(ex, line) is not None, "Expected %r in %r" % (ex, line)
80
79
81 def test_cellpx_block_args(self):
80 def test_cellpx_block_args(self):
82 """%%px --[no]block flags work"""
81 """%%px --[no]block flags work"""
83 ip = get_ipython()
82 ip = get_ipython()
84 v = self.client[-1:]
83 v = self.client[-1:]
85 v.activate()
84 v.activate()
86 v.block=False
85 v.block=False
87
86
88 for block in (True, False):
87 for block in (True, False):
89 v.block = block
88 v.block = block
90 ip.magic("pxconfig --verbose")
89 ip.magic("pxconfig --verbose")
91 with capture_output(display=False) as io:
90 with capture_output(display=False) as io:
92 ip.run_cell_magic("px", "", "1")
91 ip.run_cell_magic("px", "", "1")
93 if block:
92 if block:
94 assert io.stdout.startswith("Parallel"), io.stdout
93 assert io.stdout.startswith("Parallel"), io.stdout
95 else:
94 else:
96 assert io.stdout.startswith("Async"), io.stdout
95 assert io.stdout.startswith("Async"), io.stdout
97
96
98 with capture_output(display=False) as io:
97 with capture_output(display=False) as io:
99 ip.run_cell_magic("px", "--block", "1")
98 ip.run_cell_magic("px", "--block", "1")
100 assert io.stdout.startswith("Parallel"), io.stdout
99 assert io.stdout.startswith("Parallel"), io.stdout
101
100
102 with capture_output(display=False) as io:
101 with capture_output(display=False) as io:
103 ip.run_cell_magic("px", "--noblock", "1")
102 ip.run_cell_magic("px", "--noblock", "1")
104 assert io.stdout.startswith("Async"), io.stdout
103 assert io.stdout.startswith("Async"), io.stdout
105
104
106 def test_cellpx_groupby_engine(self):
105 def test_cellpx_groupby_engine(self):
107 """%%px --group-outputs=engine"""
106 """%%px --group-outputs=engine"""
108 ip = get_ipython()
107 ip = get_ipython()
109 v = self.client[:]
108 v = self.client[:]
110 v.block = True
109 v.block = True
111 v.activate()
110 v.activate()
112
111
113 v['generate_output'] = generate_output
112 v['generate_output'] = generate_output
114
113
115 with capture_output(display=False) as io:
114 with capture_output(display=False) as io:
116 ip.run_cell_magic('px', '--group-outputs=engine', 'generate_output()')
115 ip.run_cell_magic('px', '--group-outputs=engine', 'generate_output()')
117
116
118 self.assertNotIn('\n\n', io.stdout)
117 self.assertNotIn('\n\n', io.stdout)
119 lines = io.stdout.splitlines()
118 lines = io.stdout.splitlines()
120 expected = [
119 expected = [
121 r'\[stdout:\d+\]',
120 r'\[stdout:\d+\]',
122 'stdout',
121 'stdout',
123 'stdout2',
122 'stdout2',
124 r'\[output:\d+\]',
123 r'\[output:\d+\]',
125 r'IPython\.core\.display\.HTML',
124 r'IPython\.core\.display\.HTML',
126 r'IPython\.core\.display\.Math',
125 r'IPython\.core\.display\.Math',
127 r'Out\[\d+:\d+\]:.*IPython\.core\.display\.Math',
126 r'Out\[\d+:\d+\]:.*IPython\.core\.display\.Math',
128 ] * len(v)
127 ] * len(v)
129
128
130 self.assertEqual(len(lines), len(expected), io.stdout)
129 self.assertEqual(len(lines), len(expected), io.stdout)
131 for line,expect in zip(lines, expected):
130 for line,expect in zip(lines, expected):
132 if isinstance(expect, str):
131 if isinstance(expect, str):
133 expect = [expect]
132 expect = [expect]
134 for ex in expect:
133 for ex in expect:
135 assert re.search(ex, line) is not None, "Expected %r in %r" % (ex, line)
134 assert re.search(ex, line) is not None, "Expected %r in %r" % (ex, line)
136
135
137 self._check_generated_stderr(io.stderr, len(v))
136 self._check_generated_stderr(io.stderr, len(v))
138
137
139
138
140 def test_cellpx_groupby_order(self):
139 def test_cellpx_groupby_order(self):
141 """%%px --group-outputs=order"""
140 """%%px --group-outputs=order"""
142 ip = get_ipython()
141 ip = get_ipython()
143 v = self.client[:]
142 v = self.client[:]
144 v.block = True
143 v.block = True
145 v.activate()
144 v.activate()
146
145
147 v['generate_output'] = generate_output
146 v['generate_output'] = generate_output
148
147
149 with capture_output(display=False) as io:
148 with capture_output(display=False) as io:
150 ip.run_cell_magic('px', '--group-outputs=order', 'generate_output()')
149 ip.run_cell_magic('px', '--group-outputs=order', 'generate_output()')
151
150
152 self.assertNotIn('\n\n', io.stdout)
151 self.assertNotIn('\n\n', io.stdout)
153 lines = io.stdout.splitlines()
152 lines = io.stdout.splitlines()
154 expected = []
153 expected = []
155 expected.extend([
154 expected.extend([
156 r'\[stdout:\d+\]',
155 r'\[stdout:\d+\]',
157 'stdout',
156 'stdout',
158 'stdout2',
157 'stdout2',
159 ] * len(v))
158 ] * len(v))
160 expected.extend([
159 expected.extend([
161 r'\[output:\d+\]',
160 r'\[output:\d+\]',
162 'IPython.core.display.HTML',
161 'IPython.core.display.HTML',
163 ] * len(v))
162 ] * len(v))
164 expected.extend([
163 expected.extend([
165 r'\[output:\d+\]',
164 r'\[output:\d+\]',
166 'IPython.core.display.Math',
165 'IPython.core.display.Math',
167 ] * len(v))
166 ] * len(v))
168 expected.extend([
167 expected.extend([
169 r'Out\[\d+:\d+\]:.*IPython\.core\.display\.Math'
168 r'Out\[\d+:\d+\]:.*IPython\.core\.display\.Math'
170 ] * len(v))
169 ] * len(v))
171
170
172 self.assertEqual(len(lines), len(expected), io.stdout)
171 self.assertEqual(len(lines), len(expected), io.stdout)
173 for line,expect in zip(lines, expected):
172 for line,expect in zip(lines, expected):
174 if isinstance(expect, str):
173 if isinstance(expect, str):
175 expect = [expect]
174 expect = [expect]
176 for ex in expect:
175 for ex in expect:
177 assert re.search(ex, line) is not None, "Expected %r in %r" % (ex, line)
176 assert re.search(ex, line) is not None, "Expected %r in %r" % (ex, line)
178
177
179 self._check_generated_stderr(io.stderr, len(v))
178 self._check_generated_stderr(io.stderr, len(v))
180
179
181 def test_cellpx_groupby_type(self):
180 def test_cellpx_groupby_type(self):
182 """%%px --group-outputs=type"""
181 """%%px --group-outputs=type"""
183 ip = get_ipython()
182 ip = get_ipython()
184 v = self.client[:]
183 v = self.client[:]
185 v.block = True
184 v.block = True
186 v.activate()
185 v.activate()
187
186
188 v['generate_output'] = generate_output
187 v['generate_output'] = generate_output
189
188
190 with capture_output(display=False) as io:
189 with capture_output(display=False) as io:
191 ip.run_cell_magic('px', '--group-outputs=type', 'generate_output()')
190 ip.run_cell_magic('px', '--group-outputs=type', 'generate_output()')
192
191
193 self.assertNotIn('\n\n', io.stdout)
192 self.assertNotIn('\n\n', io.stdout)
194 lines = io.stdout.splitlines()
193 lines = io.stdout.splitlines()
195
194
196 expected = []
195 expected = []
197 expected.extend([
196 expected.extend([
198 r'\[stdout:\d+\]',
197 r'\[stdout:\d+\]',
199 'stdout',
198 'stdout',
200 'stdout2',
199 'stdout2',
201 ] * len(v))
200 ] * len(v))
202 expected.extend([
201 expected.extend([
203 r'\[output:\d+\]',
202 r'\[output:\d+\]',
204 r'IPython\.core\.display\.HTML',
203 r'IPython\.core\.display\.HTML',
205 r'IPython\.core\.display\.Math',
204 r'IPython\.core\.display\.Math',
206 ] * len(v))
205 ] * len(v))
207 expected.extend([
206 expected.extend([
208 (r'Out\[\d+:\d+\]', r'IPython\.core\.display\.Math')
207 (r'Out\[\d+:\d+\]', r'IPython\.core\.display\.Math')
209 ] * len(v))
208 ] * len(v))
210
209
211 self.assertEqual(len(lines), len(expected), io.stdout)
210 self.assertEqual(len(lines), len(expected), io.stdout)
212 for line,expect in zip(lines, expected):
211 for line,expect in zip(lines, expected):
213 if isinstance(expect, str):
212 if isinstance(expect, str):
214 expect = [expect]
213 expect = [expect]
215 for ex in expect:
214 for ex in expect:
216 assert re.search(ex, line) is not None, "Expected %r in %r" % (ex, line)
215 assert re.search(ex, line) is not None, "Expected %r in %r" % (ex, line)
217
216
218 self._check_generated_stderr(io.stderr, len(v))
217 self._check_generated_stderr(io.stderr, len(v))
219
218
220
219
221 def test_px_nonblocking(self):
220 def test_px_nonblocking(self):
222 ip = get_ipython()
221 ip = get_ipython()
223 v = self.client[-1:]
222 v = self.client[-1:]
224 v.activate()
223 v.activate()
225 v.block=False
224 v.block=False
226
225
227 ip.magic('px a=5')
226 ip.magic('px a=5')
228 self.assertEqual(v['a'], [5])
227 self.assertEqual(v['a'], [5])
229 ip.magic('px a=10')
228 ip.magic('px a=10')
230 self.assertEqual(v['a'], [10])
229 self.assertEqual(v['a'], [10])
231 ip.magic('pxconfig --verbose')
230 ip.magic('pxconfig --verbose')
232 with capture_output() as io:
231 with capture_output() as io:
233 ar = ip.magic('px print (a)')
232 ar = ip.magic('px print (a)')
234 self.assertIsInstance(ar, AsyncResult)
233 self.assertIsInstance(ar, AsyncResult)
235 self.assertIn('Async', io.stdout)
234 self.assertIn('Async', io.stdout)
236 self.assertNotIn('[stdout:', io.stdout)
235 self.assertNotIn('[stdout:', io.stdout)
237 self.assertNotIn('\n\n', io.stdout)
236 self.assertNotIn('\n\n', io.stdout)
238
237
239 ar = ip.magic('px 1/0')
238 ar = ip.magic('px 1/0')
240 self.assertRaisesRemote(ZeroDivisionError, ar.get)
239 self.assertRaisesRemote(ZeroDivisionError, ar.get)
241
240
242 def test_autopx_blocking(self):
241 def test_autopx_blocking(self):
243 ip = get_ipython()
242 ip = get_ipython()
244 v = self.client[-1]
243 v = self.client[-1]
245 v.activate()
244 v.activate()
246 v.block=True
245 v.block=True
247
246
248 with capture_output(display=False) as io:
247 with capture_output(display=False) as io:
249 ip.magic('autopx')
248 ip.magic('autopx')
250 ip.run_cell('\n'.join(('a=5','b=12345','c=0')))
249 ip.run_cell('\n'.join(('a=5','b=12345','c=0')))
251 ip.run_cell('b*=2')
250 ip.run_cell('b*=2')
252 ip.run_cell('print (b)')
251 ip.run_cell('print (b)')
253 ip.run_cell('b')
252 ip.run_cell('b')
254 ip.run_cell("b/c")
253 ip.run_cell("b/c")
255 ip.magic('autopx')
254 ip.magic('autopx')
256
255
257 output = io.stdout
256 output = io.stdout
258
257
259 assert output.startswith('%autopx enabled'), output
258 assert output.startswith('%autopx enabled'), output
260 assert output.rstrip().endswith('%autopx disabled'), output
259 assert output.rstrip().endswith('%autopx disabled'), output
261 self.assertIn('ZeroDivisionError', output)
260 self.assertIn('ZeroDivisionError', output)
262 self.assertIn('\nOut[', output)
261 self.assertIn('\nOut[', output)
263 self.assertIn(': 24690', output)
262 self.assertIn(': 24690', output)
264 ar = v.get_result(-1)
263 ar = v.get_result(-1)
265 self.assertEqual(v['a'], 5)
264 self.assertEqual(v['a'], 5)
266 self.assertEqual(v['b'], 24690)
265 self.assertEqual(v['b'], 24690)
267 self.assertRaisesRemote(ZeroDivisionError, ar.get)
266 self.assertRaisesRemote(ZeroDivisionError, ar.get)
268
267
269 def test_autopx_nonblocking(self):
268 def test_autopx_nonblocking(self):
270 ip = get_ipython()
269 ip = get_ipython()
271 v = self.client[-1]
270 v = self.client[-1]
272 v.activate()
271 v.activate()
273 v.block=False
272 v.block=False
274
273
275 with capture_output() as io:
274 with capture_output() as io:
276 ip.magic('autopx')
275 ip.magic('autopx')
277 ip.run_cell('\n'.join(('a=5','b=10','c=0')))
276 ip.run_cell('\n'.join(('a=5','b=10','c=0')))
278 ip.run_cell('print (b)')
277 ip.run_cell('print (b)')
279 ip.run_cell('import time; time.sleep(0.1)')
278 ip.run_cell('import time; time.sleep(0.1)')
280 ip.run_cell("b/c")
279 ip.run_cell("b/c")
281 ip.run_cell('b*=2')
280 ip.run_cell('b*=2')
282 ip.magic('autopx')
281 ip.magic('autopx')
283
282
284 output = io.stdout.rstrip()
283 output = io.stdout.rstrip()
285
284
286 assert output.startswith('%autopx enabled'), output
285 assert output.startswith('%autopx enabled'), output
287 assert output.endswith('%autopx disabled'), output
286 assert output.endswith('%autopx disabled'), output
288 self.assertNotIn('ZeroDivisionError', output)
287 self.assertNotIn('ZeroDivisionError', output)
289 ar = v.get_result(-2)
288 ar = v.get_result(-2)
290 self.assertRaisesRemote(ZeroDivisionError, ar.get)
289 self.assertRaisesRemote(ZeroDivisionError, ar.get)
291 # prevent TaskAborted on pulls, due to ZeroDivisionError
290 # prevent TaskAborted on pulls, due to ZeroDivisionError
292 time.sleep(0.5)
291 time.sleep(0.5)
293 self.assertEqual(v['a'], 5)
292 self.assertEqual(v['a'], 5)
294 # b*=2 will not fire, due to abort
293 # b*=2 will not fire, due to abort
295 self.assertEqual(v['b'], 10)
294 self.assertEqual(v['b'], 10)
296
295
297 def test_result(self):
296 def test_result(self):
298 ip = get_ipython()
297 ip = get_ipython()
299 v = self.client[-1]
298 v = self.client[-1]
300 v.activate()
299 v.activate()
301 data = dict(a=111,b=222)
300 data = dict(a=111,b=222)
302 v.push(data, block=True)
301 v.push(data, block=True)
303
302
304 for name in ('a', 'b'):
303 for name in ('a', 'b'):
305 ip.magic('px ' + name)
304 ip.magic('px ' + name)
306 with capture_output(display=False) as io:
305 with capture_output(display=False) as io:
307 ip.magic('pxresult')
306 ip.magic('pxresult')
308 self.assertIn(str(data[name]), io.stdout)
307 self.assertIn(str(data[name]), io.stdout)
309
308
310 @dec.skipif_not_matplotlib
309 @dec.skipif_not_matplotlib
311 def test_px_pylab(self):
310 def test_px_pylab(self):
312 """%pylab works on engines"""
311 """%pylab works on engines"""
313 ip = get_ipython()
312 ip = get_ipython()
314 v = self.client[-1]
313 v = self.client[-1]
315 v.block = True
314 v.block = True
316 v.activate()
315 v.activate()
317
316
318 with capture_output() as io:
317 with capture_output() as io:
319 ip.magic("px %pylab inline")
318 ip.magic("px %pylab inline")
320
319
321 self.assertIn("Populating the interactive namespace from numpy and matplotlib", io.stdout)
320 self.assertIn("Populating the interactive namespace from numpy and matplotlib", io.stdout)
322
321
323 with capture_output(display=False) as io:
322 with capture_output(display=False) as io:
324 ip.magic("px plot(rand(100))")
323 ip.magic("px plot(rand(100))")
325 self.assertIn('Out[', io.stdout)
324 self.assertIn('Out[', io.stdout)
326 self.assertIn('matplotlib.lines', io.stdout)
325 self.assertIn('matplotlib.lines', io.stdout)
327
326
328 def test_pxconfig(self):
327 def test_pxconfig(self):
329 ip = get_ipython()
328 ip = get_ipython()
330 rc = self.client
329 rc = self.client
331 v = rc.activate(-1, '_tst')
330 v = rc.activate(-1, '_tst')
332 self.assertEqual(v.targets, rc.ids[-1])
331 self.assertEqual(v.targets, rc.ids[-1])
333 ip.magic("%pxconfig_tst -t :")
332 ip.magic("%pxconfig_tst -t :")
334 self.assertEqual(v.targets, rc.ids)
333 self.assertEqual(v.targets, rc.ids)
335 ip.magic("%pxconfig_tst -t ::2")
334 ip.magic("%pxconfig_tst -t ::2")
336 self.assertEqual(v.targets, rc.ids[::2])
335 self.assertEqual(v.targets, rc.ids[::2])
337 ip.magic("%pxconfig_tst -t 1::2")
336 ip.magic("%pxconfig_tst -t 1::2")
338 self.assertEqual(v.targets, rc.ids[1::2])
337 self.assertEqual(v.targets, rc.ids[1::2])
339 ip.magic("%pxconfig_tst -t 1")
338 ip.magic("%pxconfig_tst -t 1")
340 self.assertEqual(v.targets, 1)
339 self.assertEqual(v.targets, 1)
341 ip.magic("%pxconfig_tst --block")
340 ip.magic("%pxconfig_tst --block")
342 self.assertEqual(v.block, True)
341 self.assertEqual(v.block, True)
343 ip.magic("%pxconfig_tst --noblock")
342 ip.magic("%pxconfig_tst --noblock")
344 self.assertEqual(v.block, False)
343 self.assertEqual(v.block, False)
345
344
346 def test_cellpx_targets(self):
345 def test_cellpx_targets(self):
347 """%%px --targets doesn't change defaults"""
346 """%%px --targets doesn't change defaults"""
348 ip = get_ipython()
347 ip = get_ipython()
349 rc = self.client
348 rc = self.client
350 view = rc.activate(rc.ids)
349 view = rc.activate(rc.ids)
351 self.assertEqual(view.targets, rc.ids)
350 self.assertEqual(view.targets, rc.ids)
352 ip.magic('pxconfig --verbose')
351 ip.magic('pxconfig --verbose')
353 for cell in ("pass", "1/0"):
352 for cell in ("pass", "1/0"):
354 with capture_output(display=False) as io:
353 with capture_output(display=False) as io:
355 try:
354 try:
356 ip.run_cell_magic("px", "--targets all", cell)
355 ip.run_cell_magic("px", "--targets all", cell)
357 except pmod.RemoteError:
356 except pmod.RemoteError:
358 pass
357 pass
359 self.assertIn('engine(s): all', io.stdout)
358 self.assertIn('engine(s): all', io.stdout)
360 self.assertEqual(view.targets, rc.ids)
359 self.assertEqual(view.targets, rc.ids)
361
360
362
361
363 def test_cellpx_block(self):
362 def test_cellpx_block(self):
364 """%%px --block doesn't change default"""
363 """%%px --block doesn't change default"""
365 ip = get_ipython()
364 ip = get_ipython()
366 rc = self.client
365 rc = self.client
367 view = rc.activate(rc.ids)
366 view = rc.activate(rc.ids)
368 view.block = False
367 view.block = False
369 self.assertEqual(view.targets, rc.ids)
368 self.assertEqual(view.targets, rc.ids)
370 ip.magic('pxconfig --verbose')
369 ip.magic('pxconfig --verbose')
371 for cell in ("pass", "1/0"):
370 for cell in ("pass", "1/0"):
372 with capture_output(display=False) as io:
371 with capture_output(display=False) as io:
373 try:
372 try:
374 ip.run_cell_magic("px", "--block", cell)
373 ip.run_cell_magic("px", "--block", cell)
375 except pmod.RemoteError:
374 except pmod.RemoteError:
376 pass
375 pass
377 self.assertNotIn('Async', io.stdout)
376 self.assertNotIn('Async', io.stdout)
378 self.assertEqual(view.block, False)
377 self.assertEqual(view.block, False)
379
378
380
379
@@ -1,814 +1,813 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """test View objects
2 """test View objects
3
3
4 Authors:
4 Authors:
5
5
6 * Min RK
6 * Min RK
7 """
7 """
8 #-------------------------------------------------------------------------------
8 #-------------------------------------------------------------------------------
9 # Copyright (C) 2011 The IPython Development Team
9 # Copyright (C) 2011 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-------------------------------------------------------------------------------
13 #-------------------------------------------------------------------------------
14
14
15 #-------------------------------------------------------------------------------
15 #-------------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-------------------------------------------------------------------------------
17 #-------------------------------------------------------------------------------
18
18
19 import base64
19 import base64
20 import sys
20 import sys
21 import platform
21 import platform
22 import time
22 import time
23 from collections import namedtuple
23 from collections import namedtuple
24 from tempfile import mktemp
24 from tempfile import mktemp
25 from StringIO import StringIO
25 from StringIO import StringIO
26
26
27 import zmq
27 import zmq
28 from nose import SkipTest
28 from nose import SkipTest
29 from nose.plugins.attrib import attr
29 from nose.plugins.attrib import attr
30
30
31 from IPython.testing import decorators as dec
31 from IPython.testing import decorators as dec
32 from IPython.testing.ipunittest import ParametricTestCase
33 from IPython.utils.io import capture_output
32 from IPython.utils.io import capture_output
34
33
35 from IPython import parallel as pmod
34 from IPython import parallel as pmod
36 from IPython.parallel import error
35 from IPython.parallel import error
37 from IPython.parallel import AsyncResult, AsyncHubResult, AsyncMapResult
36 from IPython.parallel import AsyncResult, AsyncHubResult, AsyncMapResult
38 from IPython.parallel import DirectView
37 from IPython.parallel import DirectView
39 from IPython.parallel.util import interactive
38 from IPython.parallel.util import interactive
40
39
41 from IPython.parallel.tests import add_engines
40 from IPython.parallel.tests import add_engines
42
41
43 from .clienttest import ClusterTestCase, crash, wait, skip_without
42 from .clienttest import ClusterTestCase, crash, wait, skip_without
44
43
45 def setup():
44 def setup():
46 add_engines(3, total=True)
45 add_engines(3, total=True)
47
46
48 point = namedtuple("point", "x y")
47 point = namedtuple("point", "x y")
49
48
50 class TestView(ClusterTestCase, ParametricTestCase):
49 class TestView(ClusterTestCase):
51
50
52 def setUp(self):
51 def setUp(self):
53 # On Win XP, wait for resource cleanup, else parallel test group fails
52 # On Win XP, wait for resource cleanup, else parallel test group fails
54 if platform.system() == "Windows" and platform.win32_ver()[0] == "XP":
53 if platform.system() == "Windows" and platform.win32_ver()[0] == "XP":
55 # 1 sec fails. 1.5 sec seems ok. Using 2 sec for margin of safety
54 # 1 sec fails. 1.5 sec seems ok. Using 2 sec for margin of safety
56 time.sleep(2)
55 time.sleep(2)
57 super(TestView, self).setUp()
56 super(TestView, self).setUp()
58
57
59 @attr('crash')
58 @attr('crash')
60 def test_z_crash_mux(self):
59 def test_z_crash_mux(self):
61 """test graceful handling of engine death (direct)"""
60 """test graceful handling of engine death (direct)"""
62 # self.add_engines(1)
61 # self.add_engines(1)
63 eid = self.client.ids[-1]
62 eid = self.client.ids[-1]
64 ar = self.client[eid].apply_async(crash)
63 ar = self.client[eid].apply_async(crash)
65 self.assertRaisesRemote(error.EngineError, ar.get, 10)
64 self.assertRaisesRemote(error.EngineError, ar.get, 10)
66 eid = ar.engine_id
65 eid = ar.engine_id
67 tic = time.time()
66 tic = time.time()
68 while eid in self.client.ids and time.time()-tic < 5:
67 while eid in self.client.ids and time.time()-tic < 5:
69 time.sleep(.01)
68 time.sleep(.01)
70 self.client.spin()
69 self.client.spin()
71 self.assertFalse(eid in self.client.ids, "Engine should have died")
70 self.assertFalse(eid in self.client.ids, "Engine should have died")
72
71
73 def test_push_pull(self):
72 def test_push_pull(self):
74 """test pushing and pulling"""
73 """test pushing and pulling"""
75 data = dict(a=10, b=1.05, c=range(10), d={'e':(1,2),'f':'hi'})
74 data = dict(a=10, b=1.05, c=range(10), d={'e':(1,2),'f':'hi'})
76 t = self.client.ids[-1]
75 t = self.client.ids[-1]
77 v = self.client[t]
76 v = self.client[t]
78 push = v.push
77 push = v.push
79 pull = v.pull
78 pull = v.pull
80 v.block=True
79 v.block=True
81 nengines = len(self.client)
80 nengines = len(self.client)
82 push({'data':data})
81 push({'data':data})
83 d = pull('data')
82 d = pull('data')
84 self.assertEqual(d, data)
83 self.assertEqual(d, data)
85 self.client[:].push({'data':data})
84 self.client[:].push({'data':data})
86 d = self.client[:].pull('data', block=True)
85 d = self.client[:].pull('data', block=True)
87 self.assertEqual(d, nengines*[data])
86 self.assertEqual(d, nengines*[data])
88 ar = push({'data':data}, block=False)
87 ar = push({'data':data}, block=False)
89 self.assertTrue(isinstance(ar, AsyncResult))
88 self.assertTrue(isinstance(ar, AsyncResult))
90 r = ar.get()
89 r = ar.get()
91 ar = self.client[:].pull('data', block=False)
90 ar = self.client[:].pull('data', block=False)
92 self.assertTrue(isinstance(ar, AsyncResult))
91 self.assertTrue(isinstance(ar, AsyncResult))
93 r = ar.get()
92 r = ar.get()
94 self.assertEqual(r, nengines*[data])
93 self.assertEqual(r, nengines*[data])
95 self.client[:].push(dict(a=10,b=20))
94 self.client[:].push(dict(a=10,b=20))
96 r = self.client[:].pull(('a','b'), block=True)
95 r = self.client[:].pull(('a','b'), block=True)
97 self.assertEqual(r, nengines*[[10,20]])
96 self.assertEqual(r, nengines*[[10,20]])
98
97
99 def test_push_pull_function(self):
98 def test_push_pull_function(self):
100 "test pushing and pulling functions"
99 "test pushing and pulling functions"
101 def testf(x):
100 def testf(x):
102 return 2.0*x
101 return 2.0*x
103
102
104 t = self.client.ids[-1]
103 t = self.client.ids[-1]
105 v = self.client[t]
104 v = self.client[t]
106 v.block=True
105 v.block=True
107 push = v.push
106 push = v.push
108 pull = v.pull
107 pull = v.pull
109 execute = v.execute
108 execute = v.execute
110 push({'testf':testf})
109 push({'testf':testf})
111 r = pull('testf')
110 r = pull('testf')
112 self.assertEqual(r(1.0), testf(1.0))
111 self.assertEqual(r(1.0), testf(1.0))
113 execute('r = testf(10)')
112 execute('r = testf(10)')
114 r = pull('r')
113 r = pull('r')
115 self.assertEqual(r, testf(10))
114 self.assertEqual(r, testf(10))
116 ar = self.client[:].push({'testf':testf}, block=False)
115 ar = self.client[:].push({'testf':testf}, block=False)
117 ar.get()
116 ar.get()
118 ar = self.client[:].pull('testf', block=False)
117 ar = self.client[:].pull('testf', block=False)
119 rlist = ar.get()
118 rlist = ar.get()
120 for r in rlist:
119 for r in rlist:
121 self.assertEqual(r(1.0), testf(1.0))
120 self.assertEqual(r(1.0), testf(1.0))
122 execute("def g(x): return x*x")
121 execute("def g(x): return x*x")
123 r = pull(('testf','g'))
122 r = pull(('testf','g'))
124 self.assertEqual((r[0](10),r[1](10)), (testf(10), 100))
123 self.assertEqual((r[0](10),r[1](10)), (testf(10), 100))
125
124
126 def test_push_function_globals(self):
125 def test_push_function_globals(self):
127 """test that pushed functions have access to globals"""
126 """test that pushed functions have access to globals"""
128 @interactive
127 @interactive
129 def geta():
128 def geta():
130 return a
129 return a
131 # self.add_engines(1)
130 # self.add_engines(1)
132 v = self.client[-1]
131 v = self.client[-1]
133 v.block=True
132 v.block=True
134 v['f'] = geta
133 v['f'] = geta
135 self.assertRaisesRemote(NameError, v.execute, 'b=f()')
134 self.assertRaisesRemote(NameError, v.execute, 'b=f()')
136 v.execute('a=5')
135 v.execute('a=5')
137 v.execute('b=f()')
136 v.execute('b=f()')
138 self.assertEqual(v['b'], 5)
137 self.assertEqual(v['b'], 5)
139
138
140 def test_push_function_defaults(self):
139 def test_push_function_defaults(self):
141 """test that pushed functions preserve default args"""
140 """test that pushed functions preserve default args"""
142 def echo(a=10):
141 def echo(a=10):
143 return a
142 return a
144 v = self.client[-1]
143 v = self.client[-1]
145 v.block=True
144 v.block=True
146 v['f'] = echo
145 v['f'] = echo
147 v.execute('b=f()')
146 v.execute('b=f()')
148 self.assertEqual(v['b'], 10)
147 self.assertEqual(v['b'], 10)
149
148
150 def test_get_result(self):
149 def test_get_result(self):
151 """test getting results from the Hub."""
150 """test getting results from the Hub."""
152 c = pmod.Client(profile='iptest')
151 c = pmod.Client(profile='iptest')
153 # self.add_engines(1)
152 # self.add_engines(1)
154 t = c.ids[-1]
153 t = c.ids[-1]
155 v = c[t]
154 v = c[t]
156 v2 = self.client[t]
155 v2 = self.client[t]
157 ar = v.apply_async(wait, 1)
156 ar = v.apply_async(wait, 1)
158 # give the monitor time to notice the message
157 # give the monitor time to notice the message
159 time.sleep(.25)
158 time.sleep(.25)
160 ahr = v2.get_result(ar.msg_ids[0])
159 ahr = v2.get_result(ar.msg_ids[0])
161 self.assertTrue(isinstance(ahr, AsyncHubResult))
160 self.assertTrue(isinstance(ahr, AsyncHubResult))
162 self.assertEqual(ahr.get(), ar.get())
161 self.assertEqual(ahr.get(), ar.get())
163 ar2 = v2.get_result(ar.msg_ids[0])
162 ar2 = v2.get_result(ar.msg_ids[0])
164 self.assertFalse(isinstance(ar2, AsyncHubResult))
163 self.assertFalse(isinstance(ar2, AsyncHubResult))
165 c.spin()
164 c.spin()
166 c.close()
165 c.close()
167
166
168 def test_run_newline(self):
167 def test_run_newline(self):
169 """test that run appends newline to files"""
168 """test that run appends newline to files"""
170 tmpfile = mktemp()
169 tmpfile = mktemp()
171 with open(tmpfile, 'w') as f:
170 with open(tmpfile, 'w') as f:
172 f.write("""def g():
171 f.write("""def g():
173 return 5
172 return 5
174 """)
173 """)
175 v = self.client[-1]
174 v = self.client[-1]
176 v.run(tmpfile, block=True)
175 v.run(tmpfile, block=True)
177 self.assertEqual(v.apply_sync(lambda f: f(), pmod.Reference('g')), 5)
176 self.assertEqual(v.apply_sync(lambda f: f(), pmod.Reference('g')), 5)
178
177
179 def test_apply_tracked(self):
178 def test_apply_tracked(self):
180 """test tracking for apply"""
179 """test tracking for apply"""
181 # self.add_engines(1)
180 # self.add_engines(1)
182 t = self.client.ids[-1]
181 t = self.client.ids[-1]
183 v = self.client[t]
182 v = self.client[t]
184 v.block=False
183 v.block=False
185 def echo(n=1024*1024, **kwargs):
184 def echo(n=1024*1024, **kwargs):
186 with v.temp_flags(**kwargs):
185 with v.temp_flags(**kwargs):
187 return v.apply(lambda x: x, 'x'*n)
186 return v.apply(lambda x: x, 'x'*n)
188 ar = echo(1, track=False)
187 ar = echo(1, track=False)
189 self.assertTrue(isinstance(ar._tracker, zmq.MessageTracker))
188 self.assertTrue(isinstance(ar._tracker, zmq.MessageTracker))
190 self.assertTrue(ar.sent)
189 self.assertTrue(ar.sent)
191 ar = echo(track=True)
190 ar = echo(track=True)
192 self.assertTrue(isinstance(ar._tracker, zmq.MessageTracker))
191 self.assertTrue(isinstance(ar._tracker, zmq.MessageTracker))
193 self.assertEqual(ar.sent, ar._tracker.done)
192 self.assertEqual(ar.sent, ar._tracker.done)
194 ar._tracker.wait()
193 ar._tracker.wait()
195 self.assertTrue(ar.sent)
194 self.assertTrue(ar.sent)
196
195
197 def test_push_tracked(self):
196 def test_push_tracked(self):
198 t = self.client.ids[-1]
197 t = self.client.ids[-1]
199 ns = dict(x='x'*1024*1024)
198 ns = dict(x='x'*1024*1024)
200 v = self.client[t]
199 v = self.client[t]
201 ar = v.push(ns, block=False, track=False)
200 ar = v.push(ns, block=False, track=False)
202 self.assertTrue(isinstance(ar._tracker, zmq.MessageTracker))
201 self.assertTrue(isinstance(ar._tracker, zmq.MessageTracker))
203 self.assertTrue(ar.sent)
202 self.assertTrue(ar.sent)
204
203
205 ar = v.push(ns, block=False, track=True)
204 ar = v.push(ns, block=False, track=True)
206 self.assertTrue(isinstance(ar._tracker, zmq.MessageTracker))
205 self.assertTrue(isinstance(ar._tracker, zmq.MessageTracker))
207 ar._tracker.wait()
206 ar._tracker.wait()
208 self.assertEqual(ar.sent, ar._tracker.done)
207 self.assertEqual(ar.sent, ar._tracker.done)
209 self.assertTrue(ar.sent)
208 self.assertTrue(ar.sent)
210 ar.get()
209 ar.get()
211
210
212 def test_scatter_tracked(self):
211 def test_scatter_tracked(self):
213 t = self.client.ids
212 t = self.client.ids
214 x='x'*1024*1024
213 x='x'*1024*1024
215 ar = self.client[t].scatter('x', x, block=False, track=False)
214 ar = self.client[t].scatter('x', x, block=False, track=False)
216 self.assertTrue(isinstance(ar._tracker, zmq.MessageTracker))
215 self.assertTrue(isinstance(ar._tracker, zmq.MessageTracker))
217 self.assertTrue(ar.sent)
216 self.assertTrue(ar.sent)
218
217
219 ar = self.client[t].scatter('x', x, block=False, track=True)
218 ar = self.client[t].scatter('x', x, block=False, track=True)
220 self.assertTrue(isinstance(ar._tracker, zmq.MessageTracker))
219 self.assertTrue(isinstance(ar._tracker, zmq.MessageTracker))
221 self.assertEqual(ar.sent, ar._tracker.done)
220 self.assertEqual(ar.sent, ar._tracker.done)
222 ar._tracker.wait()
221 ar._tracker.wait()
223 self.assertTrue(ar.sent)
222 self.assertTrue(ar.sent)
224 ar.get()
223 ar.get()
225
224
226 def test_remote_reference(self):
225 def test_remote_reference(self):
227 v = self.client[-1]
226 v = self.client[-1]
228 v['a'] = 123
227 v['a'] = 123
229 ra = pmod.Reference('a')
228 ra = pmod.Reference('a')
230 b = v.apply_sync(lambda x: x, ra)
229 b = v.apply_sync(lambda x: x, ra)
231 self.assertEqual(b, 123)
230 self.assertEqual(b, 123)
232
231
233
232
234 def test_scatter_gather(self):
233 def test_scatter_gather(self):
235 view = self.client[:]
234 view = self.client[:]
236 seq1 = range(16)
235 seq1 = range(16)
237 view.scatter('a', seq1)
236 view.scatter('a', seq1)
238 seq2 = view.gather('a', block=True)
237 seq2 = view.gather('a', block=True)
239 self.assertEqual(seq2, seq1)
238 self.assertEqual(seq2, seq1)
240 self.assertRaisesRemote(NameError, view.gather, 'asdf', block=True)
239 self.assertRaisesRemote(NameError, view.gather, 'asdf', block=True)
241
240
242 @skip_without('numpy')
241 @skip_without('numpy')
243 def test_scatter_gather_numpy(self):
242 def test_scatter_gather_numpy(self):
244 import numpy
243 import numpy
245 from numpy.testing.utils import assert_array_equal, assert_array_almost_equal
244 from numpy.testing.utils import assert_array_equal, assert_array_almost_equal
246 view = self.client[:]
245 view = self.client[:]
247 a = numpy.arange(64)
246 a = numpy.arange(64)
248 view.scatter('a', a, block=True)
247 view.scatter('a', a, block=True)
249 b = view.gather('a', block=True)
248 b = view.gather('a', block=True)
250 assert_array_equal(b, a)
249 assert_array_equal(b, a)
251
250
252 def test_scatter_gather_lazy(self):
251 def test_scatter_gather_lazy(self):
253 """scatter/gather with targets='all'"""
252 """scatter/gather with targets='all'"""
254 view = self.client.direct_view(targets='all')
253 view = self.client.direct_view(targets='all')
255 x = range(64)
254 x = range(64)
256 view.scatter('x', x)
255 view.scatter('x', x)
257 gathered = view.gather('x', block=True)
256 gathered = view.gather('x', block=True)
258 self.assertEqual(gathered, x)
257 self.assertEqual(gathered, x)
259
258
260
259
261 @dec.known_failure_py3
260 @dec.known_failure_py3
262 @skip_without('numpy')
261 @skip_without('numpy')
263 def test_push_numpy_nocopy(self):
262 def test_push_numpy_nocopy(self):
264 import numpy
263 import numpy
265 view = self.client[:]
264 view = self.client[:]
266 a = numpy.arange(64)
265 a = numpy.arange(64)
267 view['A'] = a
266 view['A'] = a
268 @interactive
267 @interactive
269 def check_writeable(x):
268 def check_writeable(x):
270 return x.flags.writeable
269 return x.flags.writeable
271
270
272 for flag in view.apply_sync(check_writeable, pmod.Reference('A')):
271 for flag in view.apply_sync(check_writeable, pmod.Reference('A')):
273 self.assertFalse(flag, "array is writeable, push shouldn't have pickled it")
272 self.assertFalse(flag, "array is writeable, push shouldn't have pickled it")
274
273
275 view.push(dict(B=a))
274 view.push(dict(B=a))
276 for flag in view.apply_sync(check_writeable, pmod.Reference('B')):
275 for flag in view.apply_sync(check_writeable, pmod.Reference('B')):
277 self.assertFalse(flag, "array is writeable, push shouldn't have pickled it")
276 self.assertFalse(flag, "array is writeable, push shouldn't have pickled it")
278
277
279 @skip_without('numpy')
278 @skip_without('numpy')
280 def test_apply_numpy(self):
279 def test_apply_numpy(self):
281 """view.apply(f, ndarray)"""
280 """view.apply(f, ndarray)"""
282 import numpy
281 import numpy
283 from numpy.testing.utils import assert_array_equal, assert_array_almost_equal
282 from numpy.testing.utils import assert_array_equal, assert_array_almost_equal
284
283
285 A = numpy.random.random((100,100))
284 A = numpy.random.random((100,100))
286 view = self.client[-1]
285 view = self.client[-1]
287 for dt in [ 'int32', 'uint8', 'float32', 'float64' ]:
286 for dt in [ 'int32', 'uint8', 'float32', 'float64' ]:
288 B = A.astype(dt)
287 B = A.astype(dt)
289 C = view.apply_sync(lambda x:x, B)
288 C = view.apply_sync(lambda x:x, B)
290 assert_array_equal(B,C)
289 assert_array_equal(B,C)
291
290
292 @skip_without('numpy')
291 @skip_without('numpy')
293 def test_push_pull_recarray(self):
292 def test_push_pull_recarray(self):
294 """push/pull recarrays"""
293 """push/pull recarrays"""
295 import numpy
294 import numpy
296 from numpy.testing.utils import assert_array_equal
295 from numpy.testing.utils import assert_array_equal
297
296
298 view = self.client[-1]
297 view = self.client[-1]
299
298
300 R = numpy.array([
299 R = numpy.array([
301 (1, 'hi', 0.),
300 (1, 'hi', 0.),
302 (2**30, 'there', 2.5),
301 (2**30, 'there', 2.5),
303 (-99999, 'world', -12345.6789),
302 (-99999, 'world', -12345.6789),
304 ], [('n', int), ('s', '|S10'), ('f', float)])
303 ], [('n', int), ('s', '|S10'), ('f', float)])
305
304
306 view['RR'] = R
305 view['RR'] = R
307 R2 = view['RR']
306 R2 = view['RR']
308
307
309 r_dtype, r_shape = view.apply_sync(interactive(lambda : (RR.dtype, RR.shape)))
308 r_dtype, r_shape = view.apply_sync(interactive(lambda : (RR.dtype, RR.shape)))
310 self.assertEqual(r_dtype, R.dtype)
309 self.assertEqual(r_dtype, R.dtype)
311 self.assertEqual(r_shape, R.shape)
310 self.assertEqual(r_shape, R.shape)
312 self.assertEqual(R2.dtype, R.dtype)
311 self.assertEqual(R2.dtype, R.dtype)
313 self.assertEqual(R2.shape, R.shape)
312 self.assertEqual(R2.shape, R.shape)
314 assert_array_equal(R2, R)
313 assert_array_equal(R2, R)
315
314
316 @skip_without('pandas')
315 @skip_without('pandas')
317 def test_push_pull_timeseries(self):
316 def test_push_pull_timeseries(self):
318 """push/pull pandas.TimeSeries"""
317 """push/pull pandas.TimeSeries"""
319 import pandas
318 import pandas
320
319
321 ts = pandas.TimeSeries(range(10))
320 ts = pandas.TimeSeries(range(10))
322
321
323 view = self.client[-1]
322 view = self.client[-1]
324
323
325 view.push(dict(ts=ts), block=True)
324 view.push(dict(ts=ts), block=True)
326 rts = view['ts']
325 rts = view['ts']
327
326
328 self.assertEqual(type(rts), type(ts))
327 self.assertEqual(type(rts), type(ts))
329 self.assertTrue((ts == rts).all())
328 self.assertTrue((ts == rts).all())
330
329
331 def test_map(self):
330 def test_map(self):
332 view = self.client[:]
331 view = self.client[:]
333 def f(x):
332 def f(x):
334 return x**2
333 return x**2
335 data = range(16)
334 data = range(16)
336 r = view.map_sync(f, data)
335 r = view.map_sync(f, data)
337 self.assertEqual(r, map(f, data))
336 self.assertEqual(r, map(f, data))
338
337
339 def test_map_iterable(self):
338 def test_map_iterable(self):
340 """test map on iterables (direct)"""
339 """test map on iterables (direct)"""
341 view = self.client[:]
340 view = self.client[:]
342 # 101 is prime, so it won't be evenly distributed
341 # 101 is prime, so it won't be evenly distributed
343 arr = range(101)
342 arr = range(101)
344 # ensure it will be an iterator, even in Python 3
343 # ensure it will be an iterator, even in Python 3
345 it = iter(arr)
344 it = iter(arr)
346 r = view.map_sync(lambda x: x, it)
345 r = view.map_sync(lambda x: x, it)
347 self.assertEqual(r, list(arr))
346 self.assertEqual(r, list(arr))
348
347
349 @skip_without('numpy')
348 @skip_without('numpy')
350 def test_map_numpy(self):
349 def test_map_numpy(self):
351 """test map on numpy arrays (direct)"""
350 """test map on numpy arrays (direct)"""
352 import numpy
351 import numpy
353 from numpy.testing.utils import assert_array_equal
352 from numpy.testing.utils import assert_array_equal
354
353
355 view = self.client[:]
354 view = self.client[:]
356 # 101 is prime, so it won't be evenly distributed
355 # 101 is prime, so it won't be evenly distributed
357 arr = numpy.arange(101)
356 arr = numpy.arange(101)
358 r = view.map_sync(lambda x: x, arr)
357 r = view.map_sync(lambda x: x, arr)
359 assert_array_equal(r, arr)
358 assert_array_equal(r, arr)
360
359
361 def test_scatter_gather_nonblocking(self):
360 def test_scatter_gather_nonblocking(self):
362 data = range(16)
361 data = range(16)
363 view = self.client[:]
362 view = self.client[:]
364 view.scatter('a', data, block=False)
363 view.scatter('a', data, block=False)
365 ar = view.gather('a', block=False)
364 ar = view.gather('a', block=False)
366 self.assertEqual(ar.get(), data)
365 self.assertEqual(ar.get(), data)
367
366
368 @skip_without('numpy')
367 @skip_without('numpy')
369 def test_scatter_gather_numpy_nonblocking(self):
368 def test_scatter_gather_numpy_nonblocking(self):
370 import numpy
369 import numpy
371 from numpy.testing.utils import assert_array_equal, assert_array_almost_equal
370 from numpy.testing.utils import assert_array_equal, assert_array_almost_equal
372 a = numpy.arange(64)
371 a = numpy.arange(64)
373 view = self.client[:]
372 view = self.client[:]
374 ar = view.scatter('a', a, block=False)
373 ar = view.scatter('a', a, block=False)
375 self.assertTrue(isinstance(ar, AsyncResult))
374 self.assertTrue(isinstance(ar, AsyncResult))
376 amr = view.gather('a', block=False)
375 amr = view.gather('a', block=False)
377 self.assertTrue(isinstance(amr, AsyncMapResult))
376 self.assertTrue(isinstance(amr, AsyncMapResult))
378 assert_array_equal(amr.get(), a)
377 assert_array_equal(amr.get(), a)
379
378
380 def test_execute(self):
379 def test_execute(self):
381 view = self.client[:]
380 view = self.client[:]
382 # self.client.debug=True
381 # self.client.debug=True
383 execute = view.execute
382 execute = view.execute
384 ar = execute('c=30', block=False)
383 ar = execute('c=30', block=False)
385 self.assertTrue(isinstance(ar, AsyncResult))
384 self.assertTrue(isinstance(ar, AsyncResult))
386 ar = execute('d=[0,1,2]', block=False)
385 ar = execute('d=[0,1,2]', block=False)
387 self.client.wait(ar, 1)
386 self.client.wait(ar, 1)
388 self.assertEqual(len(ar.get()), len(self.client))
387 self.assertEqual(len(ar.get()), len(self.client))
389 for c in view['c']:
388 for c in view['c']:
390 self.assertEqual(c, 30)
389 self.assertEqual(c, 30)
391
390
392 def test_abort(self):
391 def test_abort(self):
393 view = self.client[-1]
392 view = self.client[-1]
394 ar = view.execute('import time; time.sleep(1)', block=False)
393 ar = view.execute('import time; time.sleep(1)', block=False)
395 ar2 = view.apply_async(lambda : 2)
394 ar2 = view.apply_async(lambda : 2)
396 ar3 = view.apply_async(lambda : 3)
395 ar3 = view.apply_async(lambda : 3)
397 view.abort(ar2)
396 view.abort(ar2)
398 view.abort(ar3.msg_ids)
397 view.abort(ar3.msg_ids)
399 self.assertRaises(error.TaskAborted, ar2.get)
398 self.assertRaises(error.TaskAborted, ar2.get)
400 self.assertRaises(error.TaskAborted, ar3.get)
399 self.assertRaises(error.TaskAborted, ar3.get)
401
400
402 def test_abort_all(self):
401 def test_abort_all(self):
403 """view.abort() aborts all outstanding tasks"""
402 """view.abort() aborts all outstanding tasks"""
404 view = self.client[-1]
403 view = self.client[-1]
405 ars = [ view.apply_async(time.sleep, 0.25) for i in range(10) ]
404 ars = [ view.apply_async(time.sleep, 0.25) for i in range(10) ]
406 view.abort()
405 view.abort()
407 view.wait(timeout=5)
406 view.wait(timeout=5)
408 for ar in ars[5:]:
407 for ar in ars[5:]:
409 self.assertRaises(error.TaskAborted, ar.get)
408 self.assertRaises(error.TaskAborted, ar.get)
410
409
411 def test_temp_flags(self):
410 def test_temp_flags(self):
412 view = self.client[-1]
411 view = self.client[-1]
413 view.block=True
412 view.block=True
414 with view.temp_flags(block=False):
413 with view.temp_flags(block=False):
415 self.assertFalse(view.block)
414 self.assertFalse(view.block)
416 self.assertTrue(view.block)
415 self.assertTrue(view.block)
417
416
418 @dec.known_failure_py3
417 @dec.known_failure_py3
419 def test_importer(self):
418 def test_importer(self):
420 view = self.client[-1]
419 view = self.client[-1]
421 view.clear(block=True)
420 view.clear(block=True)
422 with view.importer:
421 with view.importer:
423 import re
422 import re
424
423
425 @interactive
424 @interactive
426 def findall(pat, s):
425 def findall(pat, s):
427 # this globals() step isn't necessary in real code
426 # this globals() step isn't necessary in real code
428 # only to prevent a closure in the test
427 # only to prevent a closure in the test
429 re = globals()['re']
428 re = globals()['re']
430 return re.findall(pat, s)
429 return re.findall(pat, s)
431
430
432 self.assertEqual(view.apply_sync(findall, '\w+', 'hello world'), 'hello world'.split())
431 self.assertEqual(view.apply_sync(findall, '\w+', 'hello world'), 'hello world'.split())
433
432
434 def test_unicode_execute(self):
433 def test_unicode_execute(self):
435 """test executing unicode strings"""
434 """test executing unicode strings"""
436 v = self.client[-1]
435 v = self.client[-1]
437 v.block=True
436 v.block=True
438 if sys.version_info[0] >= 3:
437 if sys.version_info[0] >= 3:
439 code="a='é'"
438 code="a='é'"
440 else:
439 else:
441 code=u"a=u'é'"
440 code=u"a=u'é'"
442 v.execute(code)
441 v.execute(code)
443 self.assertEqual(v['a'], u'é')
442 self.assertEqual(v['a'], u'é')
444
443
445 def test_unicode_apply_result(self):
444 def test_unicode_apply_result(self):
446 """test unicode apply results"""
445 """test unicode apply results"""
447 v = self.client[-1]
446 v = self.client[-1]
448 r = v.apply_sync(lambda : u'é')
447 r = v.apply_sync(lambda : u'é')
449 self.assertEqual(r, u'é')
448 self.assertEqual(r, u'é')
450
449
451 def test_unicode_apply_arg(self):
450 def test_unicode_apply_arg(self):
452 """test passing unicode arguments to apply"""
451 """test passing unicode arguments to apply"""
453 v = self.client[-1]
452 v = self.client[-1]
454
453
455 @interactive
454 @interactive
456 def check_unicode(a, check):
455 def check_unicode(a, check):
457 assert isinstance(a, unicode), "%r is not unicode"%a
456 assert isinstance(a, unicode), "%r is not unicode"%a
458 assert isinstance(check, bytes), "%r is not bytes"%check
457 assert isinstance(check, bytes), "%r is not bytes"%check
459 assert a.encode('utf8') == check, "%s != %s"%(a,check)
458 assert a.encode('utf8') == check, "%s != %s"%(a,check)
460
459
461 for s in [ u'é', u'ßø®∫',u'asdf' ]:
460 for s in [ u'é', u'ßø®∫',u'asdf' ]:
462 try:
461 try:
463 v.apply_sync(check_unicode, s, s.encode('utf8'))
462 v.apply_sync(check_unicode, s, s.encode('utf8'))
464 except error.RemoteError as e:
463 except error.RemoteError as e:
465 if e.ename == 'AssertionError':
464 if e.ename == 'AssertionError':
466 self.fail(e.evalue)
465 self.fail(e.evalue)
467 else:
466 else:
468 raise e
467 raise e
469
468
470 def test_map_reference(self):
469 def test_map_reference(self):
471 """view.map(<Reference>, *seqs) should work"""
470 """view.map(<Reference>, *seqs) should work"""
472 v = self.client[:]
471 v = self.client[:]
473 v.scatter('n', self.client.ids, flatten=True)
472 v.scatter('n', self.client.ids, flatten=True)
474 v.execute("f = lambda x,y: x*y")
473 v.execute("f = lambda x,y: x*y")
475 rf = pmod.Reference('f')
474 rf = pmod.Reference('f')
476 nlist = list(range(10))
475 nlist = list(range(10))
477 mlist = nlist[::-1]
476 mlist = nlist[::-1]
478 expected = [ m*n for m,n in zip(mlist, nlist) ]
477 expected = [ m*n for m,n in zip(mlist, nlist) ]
479 result = v.map_sync(rf, mlist, nlist)
478 result = v.map_sync(rf, mlist, nlist)
480 self.assertEqual(result, expected)
479 self.assertEqual(result, expected)
481
480
482 def test_apply_reference(self):
481 def test_apply_reference(self):
483 """view.apply(<Reference>, *args) should work"""
482 """view.apply(<Reference>, *args) should work"""
484 v = self.client[:]
483 v = self.client[:]
485 v.scatter('n', self.client.ids, flatten=True)
484 v.scatter('n', self.client.ids, flatten=True)
486 v.execute("f = lambda x: n*x")
485 v.execute("f = lambda x: n*x")
487 rf = pmod.Reference('f')
486 rf = pmod.Reference('f')
488 result = v.apply_sync(rf, 5)
487 result = v.apply_sync(rf, 5)
489 expected = [ 5*id for id in self.client.ids ]
488 expected = [ 5*id for id in self.client.ids ]
490 self.assertEqual(result, expected)
489 self.assertEqual(result, expected)
491
490
492 def test_eval_reference(self):
491 def test_eval_reference(self):
493 v = self.client[self.client.ids[0]]
492 v = self.client[self.client.ids[0]]
494 v['g'] = range(5)
493 v['g'] = range(5)
495 rg = pmod.Reference('g[0]')
494 rg = pmod.Reference('g[0]')
496 echo = lambda x:x
495 echo = lambda x:x
497 self.assertEqual(v.apply_sync(echo, rg), 0)
496 self.assertEqual(v.apply_sync(echo, rg), 0)
498
497
499 def test_reference_nameerror(self):
498 def test_reference_nameerror(self):
500 v = self.client[self.client.ids[0]]
499 v = self.client[self.client.ids[0]]
501 r = pmod.Reference('elvis_has_left')
500 r = pmod.Reference('elvis_has_left')
502 echo = lambda x:x
501 echo = lambda x:x
503 self.assertRaisesRemote(NameError, v.apply_sync, echo, r)
502 self.assertRaisesRemote(NameError, v.apply_sync, echo, r)
504
503
505 def test_single_engine_map(self):
504 def test_single_engine_map(self):
506 e0 = self.client[self.client.ids[0]]
505 e0 = self.client[self.client.ids[0]]
507 r = range(5)
506 r = range(5)
508 check = [ -1*i for i in r ]
507 check = [ -1*i for i in r ]
509 result = e0.map_sync(lambda x: -1*x, r)
508 result = e0.map_sync(lambda x: -1*x, r)
510 self.assertEqual(result, check)
509 self.assertEqual(result, check)
511
510
512 def test_len(self):
511 def test_len(self):
513 """len(view) makes sense"""
512 """len(view) makes sense"""
514 e0 = self.client[self.client.ids[0]]
513 e0 = self.client[self.client.ids[0]]
515 yield self.assertEqual(len(e0), 1)
514 self.assertEqual(len(e0), 1)
516 v = self.client[:]
515 v = self.client[:]
517 yield self.assertEqual(len(v), len(self.client.ids))
516 self.assertEqual(len(v), len(self.client.ids))
518 v = self.client.direct_view('all')
517 v = self.client.direct_view('all')
519 yield self.assertEqual(len(v), len(self.client.ids))
518 self.assertEqual(len(v), len(self.client.ids))
520 v = self.client[:2]
519 v = self.client[:2]
521 yield self.assertEqual(len(v), 2)
520 self.assertEqual(len(v), 2)
522 v = self.client[:1]
521 v = self.client[:1]
523 yield self.assertEqual(len(v), 1)
522 self.assertEqual(len(v), 1)
524 v = self.client.load_balanced_view()
523 v = self.client.load_balanced_view()
525 yield self.assertEqual(len(v), len(self.client.ids))
524 self.assertEqual(len(v), len(self.client.ids))
526 # parametric tests seem to require manual closing?
525 # parametric tests seem to require manual closing?
527 self.client.close()
526 self.client.close()
528
527
529
528
530 # begin execute tests
529 # begin execute tests
531
530
532 def test_execute_reply(self):
531 def test_execute_reply(self):
533 e0 = self.client[self.client.ids[0]]
532 e0 = self.client[self.client.ids[0]]
534 e0.block = True
533 e0.block = True
535 ar = e0.execute("5", silent=False)
534 ar = e0.execute("5", silent=False)
536 er = ar.get()
535 er = ar.get()
537 self.assertEqual(str(er), "<ExecuteReply[%i]: 5>" % er.execution_count)
536 self.assertEqual(str(er), "<ExecuteReply[%i]: 5>" % er.execution_count)
538 self.assertEqual(er.pyout['data']['text/plain'], '5')
537 self.assertEqual(er.pyout['data']['text/plain'], '5')
539
538
540 def test_execute_reply_rich(self):
539 def test_execute_reply_rich(self):
541 e0 = self.client[self.client.ids[0]]
540 e0 = self.client[self.client.ids[0]]
542 e0.block = True
541 e0.block = True
543 e0.execute("from IPython.display import Image, HTML")
542 e0.execute("from IPython.display import Image, HTML")
544 ar = e0.execute("Image(data=b'garbage', format='png', width=10)", silent=False)
543 ar = e0.execute("Image(data=b'garbage', format='png', width=10)", silent=False)
545 er = ar.get()
544 er = ar.get()
546 b64data = base64.encodestring(b'garbage').decode('ascii')
545 b64data = base64.encodestring(b'garbage').decode('ascii')
547 self.assertEqual(er._repr_png_(), (b64data, dict(width=10)))
546 self.assertEqual(er._repr_png_(), (b64data, dict(width=10)))
548 ar = e0.execute("HTML('<b>bold</b>')", silent=False)
547 ar = e0.execute("HTML('<b>bold</b>')", silent=False)
549 er = ar.get()
548 er = ar.get()
550 self.assertEqual(er._repr_html_(), "<b>bold</b>")
549 self.assertEqual(er._repr_html_(), "<b>bold</b>")
551
550
552 def test_execute_reply_stdout(self):
551 def test_execute_reply_stdout(self):
553 e0 = self.client[self.client.ids[0]]
552 e0 = self.client[self.client.ids[0]]
554 e0.block = True
553 e0.block = True
555 ar = e0.execute("print (5)", silent=False)
554 ar = e0.execute("print (5)", silent=False)
556 er = ar.get()
555 er = ar.get()
557 self.assertEqual(er.stdout.strip(), '5')
556 self.assertEqual(er.stdout.strip(), '5')
558
557
559 def test_execute_pyout(self):
558 def test_execute_pyout(self):
560 """execute triggers pyout with silent=False"""
559 """execute triggers pyout with silent=False"""
561 view = self.client[:]
560 view = self.client[:]
562 ar = view.execute("5", silent=False, block=True)
561 ar = view.execute("5", silent=False, block=True)
563
562
564 expected = [{'text/plain' : '5'}] * len(view)
563 expected = [{'text/plain' : '5'}] * len(view)
565 mimes = [ out['data'] for out in ar.pyout ]
564 mimes = [ out['data'] for out in ar.pyout ]
566 self.assertEqual(mimes, expected)
565 self.assertEqual(mimes, expected)
567
566
568 def test_execute_silent(self):
567 def test_execute_silent(self):
569 """execute does not trigger pyout with silent=True"""
568 """execute does not trigger pyout with silent=True"""
570 view = self.client[:]
569 view = self.client[:]
571 ar = view.execute("5", block=True)
570 ar = view.execute("5", block=True)
572 expected = [None] * len(view)
571 expected = [None] * len(view)
573 self.assertEqual(ar.pyout, expected)
572 self.assertEqual(ar.pyout, expected)
574
573
575 def test_execute_magic(self):
574 def test_execute_magic(self):
576 """execute accepts IPython commands"""
575 """execute accepts IPython commands"""
577 view = self.client[:]
576 view = self.client[:]
578 view.execute("a = 5")
577 view.execute("a = 5")
579 ar = view.execute("%whos", block=True)
578 ar = view.execute("%whos", block=True)
580 # this will raise, if that failed
579 # this will raise, if that failed
581 ar.get(5)
580 ar.get(5)
582 for stdout in ar.stdout:
581 for stdout in ar.stdout:
583 lines = stdout.splitlines()
582 lines = stdout.splitlines()
584 self.assertEqual(lines[0].split(), ['Variable', 'Type', 'Data/Info'])
583 self.assertEqual(lines[0].split(), ['Variable', 'Type', 'Data/Info'])
585 found = False
584 found = False
586 for line in lines[2:]:
585 for line in lines[2:]:
587 split = line.split()
586 split = line.split()
588 if split == ['a', 'int', '5']:
587 if split == ['a', 'int', '5']:
589 found = True
588 found = True
590 break
589 break
591 self.assertTrue(found, "whos output wrong: %s" % stdout)
590 self.assertTrue(found, "whos output wrong: %s" % stdout)
592
591
593 def test_execute_displaypub(self):
592 def test_execute_displaypub(self):
594 """execute tracks display_pub output"""
593 """execute tracks display_pub output"""
595 view = self.client[:]
594 view = self.client[:]
596 view.execute("from IPython.core.display import *")
595 view.execute("from IPython.core.display import *")
597 ar = view.execute("[ display(i) for i in range(5) ]", block=True)
596 ar = view.execute("[ display(i) for i in range(5) ]", block=True)
598
597
599 expected = [ {u'text/plain' : unicode(j)} for j in range(5) ]
598 expected = [ {u'text/plain' : unicode(j)} for j in range(5) ]
600 for outputs in ar.outputs:
599 for outputs in ar.outputs:
601 mimes = [ out['data'] for out in outputs ]
600 mimes = [ out['data'] for out in outputs ]
602 self.assertEqual(mimes, expected)
601 self.assertEqual(mimes, expected)
603
602
604 def test_apply_displaypub(self):
603 def test_apply_displaypub(self):
605 """apply tracks display_pub output"""
604 """apply tracks display_pub output"""
606 view = self.client[:]
605 view = self.client[:]
607 view.execute("from IPython.core.display import *")
606 view.execute("from IPython.core.display import *")
608
607
609 @interactive
608 @interactive
610 def publish():
609 def publish():
611 [ display(i) for i in range(5) ]
610 [ display(i) for i in range(5) ]
612
611
613 ar = view.apply_async(publish)
612 ar = view.apply_async(publish)
614 ar.get(5)
613 ar.get(5)
615 expected = [ {u'text/plain' : unicode(j)} for j in range(5) ]
614 expected = [ {u'text/plain' : unicode(j)} for j in range(5) ]
616 for outputs in ar.outputs:
615 for outputs in ar.outputs:
617 mimes = [ out['data'] for out in outputs ]
616 mimes = [ out['data'] for out in outputs ]
618 self.assertEqual(mimes, expected)
617 self.assertEqual(mimes, expected)
619
618
620 def test_execute_raises(self):
619 def test_execute_raises(self):
621 """exceptions in execute requests raise appropriately"""
620 """exceptions in execute requests raise appropriately"""
622 view = self.client[-1]
621 view = self.client[-1]
623 ar = view.execute("1/0")
622 ar = view.execute("1/0")
624 self.assertRaisesRemote(ZeroDivisionError, ar.get, 2)
623 self.assertRaisesRemote(ZeroDivisionError, ar.get, 2)
625
624
626 def test_remoteerror_render_exception(self):
625 def test_remoteerror_render_exception(self):
627 """RemoteErrors get nice tracebacks"""
626 """RemoteErrors get nice tracebacks"""
628 view = self.client[-1]
627 view = self.client[-1]
629 ar = view.execute("1/0")
628 ar = view.execute("1/0")
630 ip = get_ipython()
629 ip = get_ipython()
631 ip.user_ns['ar'] = ar
630 ip.user_ns['ar'] = ar
632 with capture_output() as io:
631 with capture_output() as io:
633 ip.run_cell("ar.get(2)")
632 ip.run_cell("ar.get(2)")
634
633
635 self.assertTrue('ZeroDivisionError' in io.stdout, io.stdout)
634 self.assertTrue('ZeroDivisionError' in io.stdout, io.stdout)
636
635
637 def test_compositeerror_render_exception(self):
636 def test_compositeerror_render_exception(self):
638 """CompositeErrors get nice tracebacks"""
637 """CompositeErrors get nice tracebacks"""
639 view = self.client[:]
638 view = self.client[:]
640 ar = view.execute("1/0")
639 ar = view.execute("1/0")
641 ip = get_ipython()
640 ip = get_ipython()
642 ip.user_ns['ar'] = ar
641 ip.user_ns['ar'] = ar
643
642
644 with capture_output() as io:
643 with capture_output() as io:
645 ip.run_cell("ar.get(2)")
644 ip.run_cell("ar.get(2)")
646
645
647 count = min(error.CompositeError.tb_limit, len(view))
646 count = min(error.CompositeError.tb_limit, len(view))
648
647
649 self.assertEqual(io.stdout.count('ZeroDivisionError'), count * 2, io.stdout)
648 self.assertEqual(io.stdout.count('ZeroDivisionError'), count * 2, io.stdout)
650 self.assertEqual(io.stdout.count('by zero'), count, io.stdout)
649 self.assertEqual(io.stdout.count('by zero'), count, io.stdout)
651 self.assertEqual(io.stdout.count(':execute'), count, io.stdout)
650 self.assertEqual(io.stdout.count(':execute'), count, io.stdout)
652
651
653 def test_compositeerror_truncate(self):
652 def test_compositeerror_truncate(self):
654 """Truncate CompositeErrors with many exceptions"""
653 """Truncate CompositeErrors with many exceptions"""
655 view = self.client[:]
654 view = self.client[:]
656 msg_ids = []
655 msg_ids = []
657 for i in range(10):
656 for i in range(10):
658 ar = view.execute("1/0")
657 ar = view.execute("1/0")
659 msg_ids.extend(ar.msg_ids)
658 msg_ids.extend(ar.msg_ids)
660
659
661 ar = self.client.get_result(msg_ids)
660 ar = self.client.get_result(msg_ids)
662 try:
661 try:
663 ar.get()
662 ar.get()
664 except error.CompositeError as _e:
663 except error.CompositeError as _e:
665 e = _e
664 e = _e
666 else:
665 else:
667 self.fail("Should have raised CompositeError")
666 self.fail("Should have raised CompositeError")
668
667
669 lines = e.render_traceback()
668 lines = e.render_traceback()
670 with capture_output() as io:
669 with capture_output() as io:
671 e.print_traceback()
670 e.print_traceback()
672
671
673 self.assertTrue("more exceptions" in lines[-1])
672 self.assertTrue("more exceptions" in lines[-1])
674 count = e.tb_limit
673 count = e.tb_limit
675
674
676 self.assertEqual(io.stdout.count('ZeroDivisionError'), 2 * count, io.stdout)
675 self.assertEqual(io.stdout.count('ZeroDivisionError'), 2 * count, io.stdout)
677 self.assertEqual(io.stdout.count('by zero'), count, io.stdout)
676 self.assertEqual(io.stdout.count('by zero'), count, io.stdout)
678 self.assertEqual(io.stdout.count(':execute'), count, io.stdout)
677 self.assertEqual(io.stdout.count(':execute'), count, io.stdout)
679
678
680 @dec.skipif_not_matplotlib
679 @dec.skipif_not_matplotlib
681 def test_magic_pylab(self):
680 def test_magic_pylab(self):
682 """%pylab works on engines"""
681 """%pylab works on engines"""
683 view = self.client[-1]
682 view = self.client[-1]
684 ar = view.execute("%pylab inline")
683 ar = view.execute("%pylab inline")
685 # at least check if this raised:
684 # at least check if this raised:
686 reply = ar.get(5)
685 reply = ar.get(5)
687 # include imports, in case user config
686 # include imports, in case user config
688 ar = view.execute("plot(rand(100))", silent=False)
687 ar = view.execute("plot(rand(100))", silent=False)
689 reply = ar.get(5)
688 reply = ar.get(5)
690 self.assertEqual(len(reply.outputs), 1)
689 self.assertEqual(len(reply.outputs), 1)
691 output = reply.outputs[0]
690 output = reply.outputs[0]
692 self.assertTrue("data" in output)
691 self.assertTrue("data" in output)
693 data = output['data']
692 data = output['data']
694 self.assertTrue("image/png" in data)
693 self.assertTrue("image/png" in data)
695
694
696 def test_func_default_func(self):
695 def test_func_default_func(self):
697 """interactively defined function as apply func default"""
696 """interactively defined function as apply func default"""
698 def foo():
697 def foo():
699 return 'foo'
698 return 'foo'
700
699
701 def bar(f=foo):
700 def bar(f=foo):
702 return f()
701 return f()
703
702
704 view = self.client[-1]
703 view = self.client[-1]
705 ar = view.apply_async(bar)
704 ar = view.apply_async(bar)
706 r = ar.get(10)
705 r = ar.get(10)
707 self.assertEqual(r, 'foo')
706 self.assertEqual(r, 'foo')
708 def test_data_pub_single(self):
707 def test_data_pub_single(self):
709 view = self.client[-1]
708 view = self.client[-1]
710 ar = view.execute('\n'.join([
709 ar = view.execute('\n'.join([
711 'from IPython.kernel.zmq.datapub import publish_data',
710 'from IPython.kernel.zmq.datapub import publish_data',
712 'for i in range(5):',
711 'for i in range(5):',
713 ' publish_data(dict(i=i))'
712 ' publish_data(dict(i=i))'
714 ]), block=False)
713 ]), block=False)
715 self.assertTrue(isinstance(ar.data, dict))
714 self.assertTrue(isinstance(ar.data, dict))
716 ar.get(5)
715 ar.get(5)
717 self.assertEqual(ar.data, dict(i=4))
716 self.assertEqual(ar.data, dict(i=4))
718
717
719 def test_data_pub(self):
718 def test_data_pub(self):
720 view = self.client[:]
719 view = self.client[:]
721 ar = view.execute('\n'.join([
720 ar = view.execute('\n'.join([
722 'from IPython.kernel.zmq.datapub import publish_data',
721 'from IPython.kernel.zmq.datapub import publish_data',
723 'for i in range(5):',
722 'for i in range(5):',
724 ' publish_data(dict(i=i))'
723 ' publish_data(dict(i=i))'
725 ]), block=False)
724 ]), block=False)
726 self.assertTrue(all(isinstance(d, dict) for d in ar.data))
725 self.assertTrue(all(isinstance(d, dict) for d in ar.data))
727 ar.get(5)
726 ar.get(5)
728 self.assertEqual(ar.data, [dict(i=4)] * len(ar))
727 self.assertEqual(ar.data, [dict(i=4)] * len(ar))
729
728
730 def test_can_list_arg(self):
729 def test_can_list_arg(self):
731 """args in lists are canned"""
730 """args in lists are canned"""
732 view = self.client[-1]
731 view = self.client[-1]
733 view['a'] = 128
732 view['a'] = 128
734 rA = pmod.Reference('a')
733 rA = pmod.Reference('a')
735 ar = view.apply_async(lambda x: x, [rA])
734 ar = view.apply_async(lambda x: x, [rA])
736 r = ar.get(5)
735 r = ar.get(5)
737 self.assertEqual(r, [128])
736 self.assertEqual(r, [128])
738
737
739 def test_can_dict_arg(self):
738 def test_can_dict_arg(self):
740 """args in dicts are canned"""
739 """args in dicts are canned"""
741 view = self.client[-1]
740 view = self.client[-1]
742 view['a'] = 128
741 view['a'] = 128
743 rA = pmod.Reference('a')
742 rA = pmod.Reference('a')
744 ar = view.apply_async(lambda x: x, dict(foo=rA))
743 ar = view.apply_async(lambda x: x, dict(foo=rA))
745 r = ar.get(5)
744 r = ar.get(5)
746 self.assertEqual(r, dict(foo=128))
745 self.assertEqual(r, dict(foo=128))
747
746
748 def test_can_list_kwarg(self):
747 def test_can_list_kwarg(self):
749 """kwargs in lists are canned"""
748 """kwargs in lists are canned"""
750 view = self.client[-1]
749 view = self.client[-1]
751 view['a'] = 128
750 view['a'] = 128
752 rA = pmod.Reference('a')
751 rA = pmod.Reference('a')
753 ar = view.apply_async(lambda x=5: x, x=[rA])
752 ar = view.apply_async(lambda x=5: x, x=[rA])
754 r = ar.get(5)
753 r = ar.get(5)
755 self.assertEqual(r, [128])
754 self.assertEqual(r, [128])
756
755
757 def test_can_dict_kwarg(self):
756 def test_can_dict_kwarg(self):
758 """kwargs in dicts are canned"""
757 """kwargs in dicts are canned"""
759 view = self.client[-1]
758 view = self.client[-1]
760 view['a'] = 128
759 view['a'] = 128
761 rA = pmod.Reference('a')
760 rA = pmod.Reference('a')
762 ar = view.apply_async(lambda x=5: x, dict(foo=rA))
761 ar = view.apply_async(lambda x=5: x, dict(foo=rA))
763 r = ar.get(5)
762 r = ar.get(5)
764 self.assertEqual(r, dict(foo=128))
763 self.assertEqual(r, dict(foo=128))
765
764
766 def test_map_ref(self):
765 def test_map_ref(self):
767 """view.map works with references"""
766 """view.map works with references"""
768 view = self.client[:]
767 view = self.client[:]
769 ranks = sorted(self.client.ids)
768 ranks = sorted(self.client.ids)
770 view.scatter('rank', ranks, flatten=True)
769 view.scatter('rank', ranks, flatten=True)
771 rrank = pmod.Reference('rank')
770 rrank = pmod.Reference('rank')
772
771
773 amr = view.map_async(lambda x: x*2, [rrank] * len(view))
772 amr = view.map_async(lambda x: x*2, [rrank] * len(view))
774 drank = amr.get(5)
773 drank = amr.get(5)
775 self.assertEqual(drank, [ r*2 for r in ranks ])
774 self.assertEqual(drank, [ r*2 for r in ranks ])
776
775
777 def test_nested_getitem_setitem(self):
776 def test_nested_getitem_setitem(self):
778 """get and set with view['a.b']"""
777 """get and set with view['a.b']"""
779 view = self.client[-1]
778 view = self.client[-1]
780 view.execute('\n'.join([
779 view.execute('\n'.join([
781 'class A(object): pass',
780 'class A(object): pass',
782 'a = A()',
781 'a = A()',
783 'a.b = 128',
782 'a.b = 128',
784 ]), block=True)
783 ]), block=True)
785 ra = pmod.Reference('a')
784 ra = pmod.Reference('a')
786
785
787 r = view.apply_sync(lambda x: x.b, ra)
786 r = view.apply_sync(lambda x: x.b, ra)
788 self.assertEqual(r, 128)
787 self.assertEqual(r, 128)
789 self.assertEqual(view['a.b'], 128)
788 self.assertEqual(view['a.b'], 128)
790
789
791 view['a.b'] = 0
790 view['a.b'] = 0
792
791
793 r = view.apply_sync(lambda x: x.b, ra)
792 r = view.apply_sync(lambda x: x.b, ra)
794 self.assertEqual(r, 0)
793 self.assertEqual(r, 0)
795 self.assertEqual(view['a.b'], 0)
794 self.assertEqual(view['a.b'], 0)
796
795
797 def test_return_namedtuple(self):
796 def test_return_namedtuple(self):
798 def namedtuplify(x, y):
797 def namedtuplify(x, y):
799 from IPython.parallel.tests.test_view import point
798 from IPython.parallel.tests.test_view import point
800 return point(x, y)
799 return point(x, y)
801
800
802 view = self.client[-1]
801 view = self.client[-1]
803 p = view.apply_sync(namedtuplify, 1, 2)
802 p = view.apply_sync(namedtuplify, 1, 2)
804 self.assertEqual(p.x, 1)
803 self.assertEqual(p.x, 1)
805 self.assertEqual(p.y, 2)
804 self.assertEqual(p.y, 2)
806
805
807 def test_apply_namedtuple(self):
806 def test_apply_namedtuple(self):
808 def echoxy(p):
807 def echoxy(p):
809 return p.y, p.x
808 return p.y, p.x
810
809
811 view = self.client[-1]
810 view = self.client[-1]
812 tup = view.apply_sync(echoxy, point(1, 2))
811 tup = view.apply_sync(echoxy, point(1, 2))
813 self.assertEqual(tup, (2,1))
812 self.assertEqual(tup, (2,1))
814
813
@@ -1,86 +1,86 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for io.py"""
2 """Tests for io.py"""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2008-2011 The IPython Development Team
5 # Copyright (C) 2008-2011 The IPython Development Team
6 #
6 #
7 # Distributed under the terms of the BSD License. The full license is in
7 # Distributed under the terms of the BSD License. The full license is in
8 # the file COPYING, distributed as part of this software.
8 # the file COPYING, distributed as part of this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15
15
16 import sys
16 import sys
17
17
18 from StringIO import StringIO
18 from StringIO import StringIO
19 from subprocess import Popen, PIPE
19 from subprocess import Popen, PIPE
20 import unittest
20
21
21 import nose.tools as nt
22 import nose.tools as nt
22
23
23 from IPython.testing.ipunittest import ParametricTestCase
24 from IPython.utils.io import Tee, capture_output
24 from IPython.utils.io import Tee, capture_output
25 from IPython.utils.py3compat import doctest_refactor_print
25 from IPython.utils.py3compat import doctest_refactor_print
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Tests
28 # Tests
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31
31
32 def test_tee_simple():
32 def test_tee_simple():
33 "Very simple check with stdout only"
33 "Very simple check with stdout only"
34 chan = StringIO()
34 chan = StringIO()
35 text = 'Hello'
35 text = 'Hello'
36 tee = Tee(chan, channel='stdout')
36 tee = Tee(chan, channel='stdout')
37 print(text, file=chan)
37 print(text, file=chan)
38 nt.assert_equal(chan.getvalue(), text+"\n")
38 nt.assert_equal(chan.getvalue(), text+"\n")
39
39
40
40
41 class TeeTestCase(ParametricTestCase):
41 class TeeTestCase(unittest.TestCase):
42
42
43 def tchan(self, channel, check='close'):
43 def tchan(self, channel, check='close'):
44 trap = StringIO()
44 trap = StringIO()
45 chan = StringIO()
45 chan = StringIO()
46 text = 'Hello'
46 text = 'Hello'
47
47
48 std_ori = getattr(sys, channel)
48 std_ori = getattr(sys, channel)
49 setattr(sys, channel, trap)
49 setattr(sys, channel, trap)
50
50
51 tee = Tee(chan, channel=channel)
51 tee = Tee(chan, channel=channel)
52 print(text, end='', file=chan)
52 print(text, end='', file=chan)
53 setattr(sys, channel, std_ori)
53 setattr(sys, channel, std_ori)
54 trap_val = trap.getvalue()
54 trap_val = trap.getvalue()
55 nt.assert_equal(chan.getvalue(), text)
55 nt.assert_equal(chan.getvalue(), text)
56 if check=='close':
56 if check=='close':
57 tee.close()
57 tee.close()
58 else:
58 else:
59 del tee
59 del tee
60
60
61 def test(self):
61 def test(self):
62 for chan in ['stdout', 'stderr']:
62 for chan in ['stdout', 'stderr']:
63 for check in ['close', 'del']:
63 for check in ['close', 'del']:
64 yield self.tchan(chan, check)
64 self.tchan(chan, check)
65
65
66 def test_io_init():
66 def test_io_init():
67 """Test that io.stdin/out/err exist at startup"""
67 """Test that io.stdin/out/err exist at startup"""
68 for name in ('stdin', 'stdout', 'stderr'):
68 for name in ('stdin', 'stdout', 'stderr'):
69 cmd = doctest_refactor_print("from IPython.utils import io;print io.%s.__class__"%name)
69 cmd = doctest_refactor_print("from IPython.utils import io;print io.%s.__class__"%name)
70 p = Popen([sys.executable, '-c', cmd],
70 p = Popen([sys.executable, '-c', cmd],
71 stdout=PIPE)
71 stdout=PIPE)
72 p.wait()
72 p.wait()
73 classname = p.stdout.read().strip().decode('ascii')
73 classname = p.stdout.read().strip().decode('ascii')
74 # __class__ is a reference to the class object in Python 3, so we can't
74 # __class__ is a reference to the class object in Python 3, so we can't
75 # just test for string equality.
75 # just test for string equality.
76 assert 'IPython.utils.io.IOStream' in classname, classname
76 assert 'IPython.utils.io.IOStream' in classname, classname
77
77
78 def test_capture_output():
78 def test_capture_output():
79 """capture_output() context works"""
79 """capture_output() context works"""
80
80
81 with capture_output() as io:
81 with capture_output() as io:
82 print('hi, stdout')
82 print('hi, stdout')
83 print('hi, stderr', file=sys.stderr)
83 print('hi, stderr', file=sys.stderr)
84
84
85 nt.assert_equal(io.stdout, 'hi, stdout\n')
85 nt.assert_equal(io.stdout, 'hi, stdout\n')
86 nt.assert_equal(io.stderr, 'hi, stderr\n')
86 nt.assert_equal(io.stderr, 'hi, stderr\n')
General Comments 0
You need to be logged in to leave comments. Login now