Permalink
Browse files

add tests for parallel magics

tests revealed some changes that should be made:

%px also prints remote stdout in blocking mode,
and actually raises the RemoteError (not just display)
if there is one
  • Loading branch information...
1 parent 31c15b8 commit 8cf5bb69b5750be6c22e883acee6c69ede3f9777 @minrk committed Apr 10, 2011
Showing with 152 additions and 27 deletions.
  1. +41 −27 IPython/extensions/parallelmagic.py
  2. +111 −0 IPython/parallel/tests/test_view.py
@@ -34,7 +34,7 @@
class ParalleMagic(Plugin):
"""A component to manage the %result, %px and %autopx magics."""
- active_view = Any()
+ active_view = Instance('IPython.parallel.client.view.DirectView')
verbose = Bool(False, config=True)
shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
@@ -103,8 +103,10 @@ def magic_px(self, ipself, parameter_s=''):
print NO_ACTIVE_VIEW
return
print "Parallel execution on engines: %s" % self.active_view.targets
- result = self.active_view.execute(parameter_s)
- return result
+ result = self.active_view.execute(parameter_s, block=False)
+ if self.active_view.block:
+ result.get()
+ self._maybe_display_output(result)
@testdec.skip_doctest
def magic_autopx(self, ipself, parameter_s=''):
@@ -123,9 +125,13 @@ def magic_autopx(self, ipself, parameter_s=''):
%autopx to enabled
In [26]: a = 10
- <Results List>
- [0] In [8]: a = 10
- [1] In [8]: a = 10
+ Parallel execution on engines: [0,1,2,3]
+ In [27]: print a
+ Parallel execution on engines: [0,1,2,3]
+ [stdout:0] 10
+ [stdout:1] 10
+ [stdout:2] 10
+ [stdout:3] 10
In [27]: %autopx
@@ -168,23 +174,15 @@ def _maybe_display_output(self, result):
If self.active_view.block is True, wait for the result
and display the result. Otherwise, this is a noop.
"""
- if self.active_view.block:
- try:
- result.get()
- except:
- self.shell.showtraceback()
- return True
- else:
- targets = self.active_view.targets
- if isinstance(targets, int):
- targets = [targets]
- if targets == 'all':
- targets = self.active_view.client.ids
- stdout = [s.rstrip() for s in result.stdout]
- if any(stdout):
- for i,eid in enumerate(targets):
- print '[stdout:%i]'%eid, stdout[i]
- return False
+ targets = self.active_view.targets
+ if isinstance(targets, int):
+ targets = [targets]
+ if targets == 'all':
+ targets = self.active_view.client.ids
+ stdout = [s.rstrip() for s in result.stdout]
+ if any(stdout):
+ for i,eid in enumerate(targets):
+ print '[stdout:%i]'%eid, stdout[i]
def pxrun_cell(self, cell, store_history=True):
@@ -234,9 +232,17 @@ def pxrun_cell(self, cell, store_history=True):
result = self.active_view.execute(cell, block=False)
except:
ipself.showtraceback()
- return False
+ return True
else:
- return self._maybe_display_output(result)
+ if self.active_view.block:
+ try:
+ result.get()
+ except:
+ self.shell.showtraceback()
+ return True
+ else:
+ self._maybe_display_output(result)
+ return False
def pxrun_code(self, code_obj, post_execute=True):
"""drop-in replacement for InteractiveShell.run_code.
@@ -256,9 +262,17 @@ def pxrun_code(self, code_obj, post_execute=True):
result = self.active_view.execute(code_obj, block=False)
except:
ipself.showtraceback()
- return False
+ return True
else:
- return self._maybe_display_output(result)
+ if self.active_view.block:
+ try:
+ result.get()
+ except:
+ self.shell.showtraceback()
+ return True
+ else:
+ self._maybe_display_output(result)
+ return False
@@ -10,8 +10,10 @@
# Imports
#-------------------------------------------------------------------------------
+import sys
import time
from tempfile import mktemp
+from StringIO import StringIO
import zmq
@@ -300,3 +302,112 @@ def findall(pat, s):
self.assertEquals(view.apply_sync(findall, '\w+', 'hello world'), 'hello world'.split())
+ # parallel magic tests
+
+ def test_magic_px_blocking(self):
+ ip = get_ipython()
+ v = self.client[-1]
+ v.activate()
+ v.block=True
+
+ ip.magic_px('a=5')
+ self.assertEquals(v['a'], 5)
+ ip.magic_px('a=10')
+ self.assertEquals(v['a'], 10)
+ sio = StringIO()
+ savestdout = sys.stdout
+ sys.stdout = sio
+ ip.magic_px('print a')
+ sys.stdout = savestdout
+ sio.read()
+ self.assertTrue('[stdout:%i]'%v.targets in sio.buf)
+ self.assertRaisesRemote(ZeroDivisionError, ip.magic_px, '1/0')
+
+ def test_magic_px_nonblocking(self):
+ ip = get_ipython()
+ v = self.client[-1]
+ v.activate()
+ v.block=False
+
+ ip.magic_px('a=5')
+ self.assertEquals(v['a'], 5)
+ ip.magic_px('a=10')
+ self.assertEquals(v['a'], 10)
+ sio = StringIO()
+ savestdout = sys.stdout
+ sys.stdout = sio
+ ip.magic_px('print a')
+ sys.stdout = savestdout
+ sio.read()
+ self.assertFalse('[stdout:%i]'%v.targets in sio.buf)
+ ip.magic_px('1/0')
+ ar = v.get_result(-1)
+ self.assertRaisesRemote(ZeroDivisionError, ar.get)
+
+ def test_magic_autopx_blocking(self):
+ ip = get_ipython()
+ v = self.client[-1]
+ v.activate()
+ v.block=True
+
+ sio = StringIO()
+ savestdout = sys.stdout
+ sys.stdout = sio
+ ip.magic_autopx()
+ ip.run_cell('\n'.join(('a=5','b=10','c=0')))
+ ip.run_cell('print b')
+ ip.run_cell("b/c")
+ ip.run_code(compile('b*=2', '', 'single'))
+ ip.magic_autopx()
+ sys.stdout = savestdout
+ sio.read()
+ output = sio.buf.strip()
+ self.assertTrue(output.startswith('%autopx enabled'))
+ self.assertTrue(output.endswith('%autopx disabled'))
+ self.assertTrue('RemoteError: ZeroDivisionError' in output)
+ ar = v.get_result(-2)
+ self.assertEquals(v['a'], 5)
+ self.assertEquals(v['b'], 20)
+ self.assertRaisesRemote(ZeroDivisionError, ar.get)
+
+ def test_magic_autopx_nonblocking(self):
+ ip = get_ipython()
+ v = self.client[-1]
+ v.activate()
+ v.block=False
+
+ sio = StringIO()
+ savestdout = sys.stdout
+ sys.stdout = sio
+ ip.magic_autopx()
+ ip.run_cell('\n'.join(('a=5','b=10','c=0')))
+ ip.run_cell('print b')
+ ip.run_cell("b/c")
+ ip.run_code(compile('b*=2', '', 'single'))
+ ip.magic_autopx()
+ sys.stdout = savestdout
+ sio.read()
+ output = sio.buf.strip()
+ self.assertTrue(output.startswith('%autopx enabled'))
+ self.assertTrue(output.endswith('%autopx disabled'))
+ self.assertFalse('ZeroDivisionError' in output)
+ ar = v.get_result(-2)
+ self.assertEquals(v['a'], 5)
+ self.assertEquals(v['b'], 20)
+ self.assertRaisesRemote(ZeroDivisionError, ar.get)
+
+ def test_magic_result(self):
+ ip = get_ipython()
+ v = self.client[-1]
+ v.activate()
+ v['a'] = 111
+ ra = v['a']
+
+ ar = ip.magic_result()
+ self.assertEquals(ar.msg_ids, [v.history[-1]])
+ self.assertEquals(ar.get(), 111)
+ ar = ip.magic_result('-2')
+ self.assertEquals(ar.msg_ids, [v.history[-2]])
+
+
+

0 comments on commit 8cf5bb6

Please sign in to comment.