[svn r63014] streamlining multichannel interface, fixing test work with -n 3
--HG-- branch : trunk
This commit is contained in:
		
							parent
							
								
									9db14e19e8
								
							
						
					
					
						commit
						c3e5ca560a
					
				|  | @ -19,7 +19,9 @@ import py | |||
| import sys, os | ||||
| from py.__.test.dsession.masterslave import MasterNode | ||||
| from py.__.test import event | ||||
| from py.__.execnet.channel import RemoteError | ||||
| 
 | ||||
| NO_ENDMARKER_WANTED = object() | ||||
| 
 | ||||
| class GatewaySpec(object): | ||||
|     def __init__(self, spec, defaultjoinpath="pyexecnetcache"): | ||||
|  | @ -81,20 +83,49 @@ class MultiChannel: | |||
|     def __init__(self, channels): | ||||
|         self._channels = channels | ||||
| 
 | ||||
|     def receive_items(self): | ||||
|         items = [] | ||||
|     def send_each(self, item): | ||||
|         for ch in self._channels: | ||||
|             items.append((ch, ch.receive())) | ||||
|         return items | ||||
|             ch.send(item) | ||||
| 
 | ||||
|     def receive_each(self, withchannel=False): | ||||
|         assert not hasattr(self, '_queue') | ||||
|         l = [] | ||||
|         for ch in self._channels: | ||||
|             obj = ch.receive() | ||||
|             if withchannel: | ||||
|                 l.append((ch, obj)) | ||||
|             else: | ||||
|                 l.append(obj) | ||||
|         return l  | ||||
| 
 | ||||
|     def make_receive_queue(self, endmarker=NO_ENDMARKER_WANTED): | ||||
|         try: | ||||
|             return self._queue | ||||
|         except AttributeError: | ||||
|             self._queue = py.std.Queue.Queue() | ||||
|             for ch in self._channels: | ||||
|                 def putreceived(obj, channel=ch): | ||||
|                     self._queue.put((channel, obj)) | ||||
|                 if endmarker is NO_ENDMARKER_WANTED: | ||||
|                     ch.setcallback(putreceived) | ||||
|                 else: | ||||
|                     ch.setcallback(putreceived, endmarker=endmarker) | ||||
|             return self._queue | ||||
| 
 | ||||
|     def receive(self): | ||||
|         return [x[1] for x in self.receive_items()] | ||||
| 
 | ||||
|     def waitclose(self): | ||||
|         first = None | ||||
|         for ch in self._channels: | ||||
|             ch.waitclose() | ||||
|             try: | ||||
|                 ch.waitclose() | ||||
|             except ch.RemoteError: | ||||
|                 if first is None: | ||||
|                     first = py.std.sys.exc_info() | ||||
|         if first: | ||||
|             raise first[0], first[1], first[2] | ||||
| 
 | ||||
| class MultiGateway: | ||||
|     RemoteError = RemoteError | ||||
|     def __init__(self, gateways): | ||||
|         self.gateways = gateways | ||||
|     def remote_exec(self, source): | ||||
|  | @ -104,6 +135,8 @@ class MultiGateway: | |||
|         return MultiChannel(channels) | ||||
| 
 | ||||
| class GatewayManager: | ||||
|     RemoteError = RemoteError | ||||
| 
 | ||||
|     def __init__(self, specs): | ||||
|         self.specs = [GatewaySpec(spec) for spec in specs] | ||||
|         self.gateways = [] | ||||
|  | @ -118,6 +151,8 @@ class GatewayManager: | |||
|             self.gateways.append(spec.makegateway()) | ||||
| 
 | ||||
|     def getgateways(self, remote=True, inplacelocal=True): | ||||
|         if not self.gateways and self.specs: | ||||
|             self.makegateways() | ||||
|         l = [] | ||||
|         for gw in self.gateways: | ||||
|             if gw.spec.inplacelocal(): | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| """  | ||||
|     tests for  | ||||
|     - host specifications | ||||
|     - managing hosts  | ||||
|     - gateway specifications | ||||
|     - multi channels and multi gateways  | ||||
|     - gateway management  | ||||
|     - manage rsyncing of hosts  | ||||
| 
 | ||||
| """ | ||||
|  | @ -25,10 +26,6 @@ class TestGatewaySpec: | |||
|             assert spec.type == "popen" | ||||
|             spec2 = GatewaySpec("popen" + joinpath) | ||||
|             self._equality(spec, spec2) | ||||
|             if joinpath == "": | ||||
|                 assert spec.inplacelocal() | ||||
|             else: | ||||
|                 assert not spec.inplacelocal() | ||||
| 
 | ||||
|     def test_ssh(self): | ||||
|         for prefix in ('ssh:', ''): # ssh is default | ||||
|  | @ -44,7 +41,6 @@ class TestGatewaySpec: | |||
|                     assert spec.type == "ssh" | ||||
|                     spec2 = GatewaySpec(specstring) | ||||
|                     self._equality(spec, spec2)  | ||||
|                     assert not spec.inplacelocal() | ||||
|      | ||||
|     def test_socket(self): | ||||
|         for hostpart in ('x.y', 'x', 'popen'): | ||||
|  | @ -59,7 +55,6 @@ class TestGatewaySpec: | |||
|                     assert spec.type == "socket" | ||||
|                     spec2 = GatewaySpec("socket:" + hostpart + port + joinpath) | ||||
|                     self._equality(spec, spec2)  | ||||
|                     assert not spec.inplacelocal() | ||||
| 
 | ||||
|     def _equality(self, spec1, spec2): | ||||
|         assert spec1 != spec2 | ||||
|  | @ -155,16 +150,13 @@ class TestGatewayManagerPopen: | |||
|         testdir.tmpdir.chdir() | ||||
|         hellopath = testdir.tmpdir.mkdir("hello") | ||||
|         hm.makegateways() | ||||
|         l = [x[1] for x in hm.multi_exec( | ||||
|                       "import os ; channel.send(os.getcwd())" | ||||
|                   ).receive_items() | ||||
|             ] | ||||
|         l = hm.multi_exec("import os ; channel.send(os.getcwd())").receive_each() | ||||
|         paths = [x[1] for x in l] | ||||
|         assert l == [str(hellopath)] * 2 | ||||
|         py.test.raises(Exception, 'hm.multi_chdir("world", inplacelocal=False)') | ||||
|         py.test.raises(hm.RemoteError, 'hm.multi_chdir("world", inplacelocal=False)') | ||||
|         worldpath = hellopath.mkdir("world") | ||||
|         hm.multi_chdir("world", inplacelocal=False) | ||||
|         l = hm.multi_exec("import os ; channel.send(os.getcwd())").receive() | ||||
|         l = hm.multi_exec("import os ; channel.send(os.getcwd())").receive_each() | ||||
|         assert len(l) == 2 | ||||
|         assert l[0] == l[1] | ||||
|         curwd = os.getcwd() | ||||
|  | @ -178,12 +170,12 @@ class TestGatewayManagerPopen: | |||
|         hellopath = testdir.tmpdir.mkdir("hello") | ||||
|         hm.makegateways() | ||||
|         hm.multi_chdir("hello", inplacelocal=False) | ||||
|         l = hm.multi_exec("import os ; channel.send(os.getcwd())").receive() | ||||
|         l = hm.multi_exec("import os ; channel.send(os.getcwd())").receive_each() | ||||
|         assert len(l) == 2 | ||||
|         assert l == [os.getcwd()] * 2 | ||||
| 
 | ||||
|         hm.multi_chdir("hello") | ||||
|         l = hm.multi_exec("import os ; channel.send(os.getcwd())").receive() | ||||
|         l = hm.multi_exec("import os ; channel.send(os.getcwd())").receive_each() | ||||
|         assert len(l) == 2 | ||||
|         assert l[0] == l[1] | ||||
|         curwd = os.getcwd() | ||||
|  | @ -192,7 +184,7 @@ class TestGatewayManagerPopen: | |||
| 
 | ||||
| from py.__.execnet.gwmanage import MultiChannel | ||||
| class TestMultiChannel: | ||||
|     def test_multichannel_receive_items(self): | ||||
|     def test_multichannel_receive_each(self): | ||||
|         class pseudochannel: | ||||
|             def receive(self): | ||||
|                 return 12 | ||||
|  | @ -200,9 +192,35 @@ class TestMultiChannel: | |||
|         pc1 = pseudochannel() | ||||
|         pc2 = pseudochannel() | ||||
|         multichannel = MultiChannel([pc1, pc2]) | ||||
|         l = multichannel.receive_items() | ||||
|         l = multichannel.receive_each(withchannel=True) | ||||
|         assert len(l) == 2 | ||||
|         assert l == [(pc1, 12), (pc2, 12)] | ||||
|         l = multichannel.receive_each(withchannel=False) | ||||
|         assert l == [12,12] | ||||
| 
 | ||||
|     def test_multichannel_send_each(self): | ||||
|         gm = GatewayManager(['popen'] * 2) | ||||
|         mc = gm.multi_exec(""" | ||||
|             import os | ||||
|             channel.send(channel.receive() + 1) | ||||
|         """) | ||||
|         mc.send_each(41) | ||||
|         l = mc.receive_each()  | ||||
|         assert l == [42,42] | ||||
|         | ||||
|     def test_multichannel_receive_queue(self): | ||||
|         gm = GatewayManager(['popen'] * 2) | ||||
|         mc = gm.multi_exec(""" | ||||
|             import os | ||||
|             channel.send(os.getpid()) | ||||
|         """) | ||||
|         queue = mc.make_receive_queue() | ||||
|         ch, item = queue.get(timeout=0.5) | ||||
|         ch2, item2 = queue.get(timeout=0.5) | ||||
|         assert ch != ch2 | ||||
|         assert ch.gateway != ch2.gateway | ||||
|         assert item != item2 | ||||
|         mc.waitclose() | ||||
| 
 | ||||
|     def test_multichannel_waitclose(self): | ||||
|         l = [] | ||||
|  |  | |||
|  | @ -51,7 +51,7 @@ class HostManager(object): | |||
|             for ch, result in self.gwmanager.multi_exec(""" | ||||
|                 import sys, os | ||||
|                 channel.send((sys.executable, os.getcwd(), sys.path)) | ||||
|             """).receive_items(): | ||||
|             """).receive_each(withchannel=True): | ||||
|                 self.trace("spec %r, execuable %r, cwd %r, syspath %r" %( | ||||
|                     ch.gateway.spec, result[0], result[1], result[2])) | ||||
| 
 | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ class TestHostManager: | |||
|         hm = HostManager(config, hosts=["popen:%s" % dest]) | ||||
|         assert hm.config.topdir == source == config.topdir | ||||
|         hm.rsync_roots() | ||||
|         p, = hm.gwmanager.multi_exec("import os ; channel.send(os.getcwd())").receive() | ||||
|         p, = hm.gwmanager.multi_exec("import os ; channel.send(os.getcwd())").receive_each() | ||||
|         p = py.path.local(p) | ||||
|         print "remote curdir", p | ||||
|         assert p == dest.join(config.topdir.basename) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue