[svn r63869] * moving execnet events to become api plugin calls.
* defining Execnet hooks in an explicit API --HG-- branch : trunk
This commit is contained in:
		
							parent
							
								
									92a06c3787
								
							
						
					
					
						commit
						66c64e6b97
					
				|  | @ -25,8 +25,8 @@ version = "1.0.0b1" | |||
| 
 | ||||
| initpkg(__name__, | ||||
|     description = "pylib and py.test: agile development and test support library", | ||||
|     revision = int('$LastChangedRevision: 63808 $'.split(':')[1][:-1]), | ||||
|     lastchangedate = '$LastChangedDate: 2009-04-07 22:46:50 +0200 (Tue, 07 Apr 2009) $', | ||||
|     revision = int('$LastChangedRevision: 63869 $'.split(':')[1][:-1]), | ||||
|     lastchangedate = '$LastChangedDate: 2009-04-08 19:50:14 +0200 (Wed, 08 Apr 2009) $', | ||||
|     version = version,  | ||||
|     url = "http://pylib.org",  | ||||
|     download_url = "http://codespeak.net/py/%s/download.html" % version, | ||||
|  | @ -146,6 +146,7 @@ initpkg(__name__, | |||
| 
 | ||||
|     # gateways into remote contexts | ||||
|     'execnet.__doc__'        : ('./execnet/__init__.py', '__doc__'), | ||||
|     'execnet._API'           : ('./execnet/gateway.py', 'ExecnetAPI'), | ||||
|     'execnet.SocketGateway'  : ('./execnet/register.py', 'SocketGateway'), | ||||
|     'execnet.PopenGateway'   : ('./execnet/register.py', 'PopenGateway'), | ||||
|     'execnet.SshGateway'     : ('./execnet/register.py', 'SshGateway'), | ||||
|  |  | |||
							
								
								
									
										44
									
								
								py/_com.py
								
								
								
								
							
							
						
						
									
										44
									
								
								py/_com.py
								
								
								
								
							|  | @ -36,26 +36,8 @@ class MultiCall: | |||
| 
 | ||||
|     def execute(self, firstresult=False): | ||||
|         while self.methods: | ||||
|             self.currentmethod = currentmethod = self.methods.pop() | ||||
|             # provide call introspection if "__call__" is the first positional argument  | ||||
|             if hasattr(currentmethod, 'im_self'): | ||||
|                 varnames = currentmethod.im_func.func_code.co_varnames | ||||
|                 needscall = varnames[1:2] == ('__call__',) | ||||
|             else: | ||||
|                 try: | ||||
|                     varnames = currentmethod.func_code.co_varnames | ||||
|                 except AttributeError: | ||||
|                     # builtin function | ||||
|                     varnames = () | ||||
|                 needscall = varnames[:1] == ('__call__',) | ||||
|             if needscall: | ||||
|                 res = currentmethod(self, *self.args, **self.kwargs) | ||||
|             else: | ||||
|                 #try: | ||||
|                     res = currentmethod(*self.args, **self.kwargs) | ||||
|                 #except TypeError: | ||||
|                 #    print currentmethod.__module__, currentmethod.__name__, self.args, self.kwargs | ||||
|                 #    raise | ||||
|             currentmethod = self.methods.pop() | ||||
|             res = self.execute_method(currentmethod) | ||||
|             if hasattr(self, '_ex1'): | ||||
|                 self.results = [res] | ||||
|                 break | ||||
|  | @ -70,6 +52,28 @@ class MultiCall: | |||
|         if self.results: | ||||
|             return self.results[-1]  | ||||
| 
 | ||||
|     def execute_method(self, currentmethod): | ||||
|         self.currentmethod = currentmethod | ||||
|         # provide call introspection if "__call__" is the first positional argument  | ||||
|         if hasattr(currentmethod, 'im_self'): | ||||
|             varnames = currentmethod.im_func.func_code.co_varnames | ||||
|             needscall = varnames[1:2] == ('__call__',) | ||||
|         else: | ||||
|             try: | ||||
|                 varnames = currentmethod.func_code.co_varnames | ||||
|             except AttributeError: | ||||
|                 # builtin function | ||||
|                 varnames = () | ||||
|             needscall = varnames[:1] == ('__call__',) | ||||
|         if needscall: | ||||
|             return currentmethod(self, *self.args, **self.kwargs) | ||||
|         else: | ||||
|             #try: | ||||
|                 return currentmethod(*self.args, **self.kwargs) | ||||
|             #except TypeError: | ||||
|             #    print currentmethod.__module__, currentmethod.__name__, self.args, self.kwargs | ||||
|             #    raise | ||||
| 
 | ||||
|     def exclude_other_results(self): | ||||
|         self._ex1 = True | ||||
| 
 | ||||
|  |  | |||
|  | @ -58,6 +58,17 @@ class ExecnetAPI: | |||
|     def pyexecnet_gateway_exit(self, gateway): | ||||
|         """ signal exitting of gateway. """  | ||||
| 
 | ||||
|     def pyexecnet_gwmanage_newgateway(self, gateway, platinfo): | ||||
|         """ called when a manager has made a new gateway. """  | ||||
| 
 | ||||
|     def pyexecnet_gwmanage_rsyncstart(self, source, gateways): | ||||
|         """ called before rsyncing a directory to remote gateways takes place. """ | ||||
| 
 | ||||
|     def pyexecnet_gwmanage_rsyncfinish(self, source, gateways): | ||||
|         """ called after rsyncing a directory to remote gateways takes place. """ | ||||
| 
 | ||||
|          | ||||
|          | ||||
| # ---------------------------------------------------------- | ||||
| # Base Gateway (used for both remote and local side)  | ||||
| # ---------------------------------------------------------- | ||||
|  | @ -76,12 +87,11 @@ class Gateway(object): | |||
|         self._io = io | ||||
|         self._channelfactory = ChannelFactory(self, _startcount) | ||||
|         self._cleanup.register(self)  | ||||
|         try: | ||||
|         if _startcount == 1: # only import 'py' on the "client" side  | ||||
|             from py._com import PluginAPI  | ||||
|         except ImportError: | ||||
|             self.api = ExecnetAPI() | ||||
|         else: | ||||
|             self.api = PluginAPI(ExecnetAPI) | ||||
|         else: | ||||
|             self.api = ExecnetAPI() | ||||
| 
 | ||||
|     def _initreceive(self, requestqueue=False): | ||||
|         if requestqueue:  | ||||
|  |  | |||
|  | @ -21,6 +21,7 @@ class GatewayManager: | |||
|             if not spec.chdir and not spec.popen: | ||||
|                 spec.chdir = defaultchdir | ||||
|             self.specs.append(spec) | ||||
|         self.api = py._com.PluginAPI(py.execnet._API) | ||||
| 
 | ||||
|     def trace(self, msg): | ||||
|         self.notify("trace", "gatewaymanage", msg) | ||||
|  | @ -34,7 +35,8 @@ class GatewayManager: | |||
|             gw = py.execnet.makegateway(spec) | ||||
|             self.gateways.append(gw) | ||||
|             gw.id = "[%s]" % len(self.gateways) | ||||
|             self.notify("gwmanage_newgateway", gw, gw._rinfo()) | ||||
|             self.api.pyexecnet_gwmanage_newgateway( | ||||
|                 gateway=gw, platinfo=gw._rinfo()) | ||||
| 
 | ||||
|     def getgateways(self, remote=True, inplacelocal=True): | ||||
|         if not self.gateways and self.specs: | ||||
|  | @ -79,9 +81,15 @@ class GatewayManager: | |||
|                 rsync.add_target_host(gateway, finished=finished) | ||||
|                 seen[spec] = gateway | ||||
|         if seen: | ||||
|             self.notify("gwmanage_rsyncstart", source=source, gateways=seen.values()) | ||||
|             self.api.pyexecnet_gwmanage_rsyncstart( | ||||
|                 source=source,  | ||||
|                 gateways=seen.values(), | ||||
|             ) | ||||
|             rsync.send() | ||||
|             self.notify("gwmanage_rsyncfinish", source=source, gateways=seen.values()) | ||||
|             self.api.pyexecnet_gwmanage_rsyncfinish( | ||||
|                 source=source,  | ||||
|                 gateways=seen.values() | ||||
|             ) | ||||
|         else: | ||||
|             self.trace("rsync: nothing to do.") | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,16 +20,15 @@ class TestGatewayManagerPopen: | |||
|         for spec in GatewayManager(l, defaultchdir="abc").specs: | ||||
|             assert spec.chdir == "abc" | ||||
|          | ||||
|     def test_popen_makegateway_events(self, eventrecorder): | ||||
|     def test_popen_makegateway_events(self, _pytest): | ||||
|         rec = _pytest.getcallrecorder(py.execnet._API) | ||||
|         hm = GatewayManager(["popen"] * 2) | ||||
|         hm.makegateways() | ||||
|         event = eventrecorder.popevent("gwmanage_newgateway") | ||||
|         gw, platinfo = event.args[:2] | ||||
|         assert gw.id == "[1]"  | ||||
|         platinfo.executable = gw._rinfo().executable | ||||
|         event = eventrecorder.popevent("gwmanage_newgateway") | ||||
|         gw, platinfo = event.args[:2] | ||||
|         assert gw.id == "[2]"  | ||||
|         call = rec.popcall("pyexecnet_gwmanage_newgateway") | ||||
|         assert call.gateway.id == "[1]"  | ||||
|         assert call.platinfo.executable == call.gateway._rinfo().executable | ||||
|         call = rec.popcall("pyexecnet_gwmanage_newgateway") | ||||
|         assert call.gateway.id == "[2]"  | ||||
|         assert len(hm.gateways) == 2 | ||||
|         hm.exit() | ||||
|         assert not len(hm.gateways)  | ||||
|  | @ -60,18 +59,17 @@ class TestGatewayManagerPopen: | |||
|         assert dest.join("dir1", "dir2").check() | ||||
|         assert dest.join("dir1", "dir2", 'hello').check() | ||||
| 
 | ||||
|     def test_hostmanage_rsync_same_popen_twice(self, source, dest, eventrecorder): | ||||
|     def test_hostmanage_rsync_same_popen_twice(self, source, dest, _pytest): | ||||
|         rec = _pytest.getcallrecorder(py.execnet._API) | ||||
|         hm = GatewayManager(["popen//chdir=%s" %dest] * 2) | ||||
|         hm.makegateways() | ||||
|         source.ensure("dir1", "dir2", "hello") | ||||
|         hm.rsync(source) | ||||
|         event = eventrecorder.popevent("gwmanage_rsyncstart")  | ||||
|         source2 = event.kwargs['source']  | ||||
|         gws = event.kwargs['gateways']  | ||||
|         assert source2 == source  | ||||
|         assert len(gws) == 1 | ||||
|         assert hm.gateways[0] == gws[0] | ||||
|         event = eventrecorder.popevent("gwmanage_rsyncfinish")  | ||||
|         call = rec.popcall("pyexecnet_gwmanage_rsyncstart")  | ||||
|         assert call.source == source  | ||||
|         assert len(call.gateways) == 1 | ||||
|         assert hm.gateways[0] == call.gateways[0] | ||||
|         call = rec.popcall("pyexecnet_gwmanage_rsyncfinish")  | ||||
| 
 | ||||
|     def test_multi_chdir_popen_with_path(self, testdir): | ||||
|         import os | ||||
|  |  | |||
|  | @ -77,18 +77,6 @@ class Events: | |||
|     def pyevent__NOP(self, *args, **kwargs): | ||||
|         """ the no-operation call. """  | ||||
| 
 | ||||
|     def pyevent__gateway_init(self, gateway): | ||||
|         """ called after a gateway has been initialized. """ | ||||
| 
 | ||||
|     def pyevent__gateway_exit(self, gateway): | ||||
|         """ called when gateway is being exited. """ | ||||
| 
 | ||||
|     def pyevent__gwmanage_rsyncstart(self, source, gateways): | ||||
|         """ called before rsyncing a directory to remote gateways takes place. """ | ||||
| 
 | ||||
|     def pyevent__gwmanage_rsyncfinish(self, source, gateways): | ||||
|         """ called after rsyncing a directory to remote gateways takes place. """ | ||||
| 
 | ||||
|     def pyevent__trace(self, category, msg): | ||||
|         """ called for tracing events. """ | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,12 +11,12 @@ class ExecnetcleanupPlugin: | |||
|         if self._debug: | ||||
|             print "[execnetcleanup %0x] %s %s" %(id(self), msg, args) | ||||
|          | ||||
|     def pyevent__gateway_init(self, gateway): | ||||
|     def pyexecnet_gateway_init(self, gateway): | ||||
|         self.trace("init", gateway) | ||||
|         if self._gateways is not None: | ||||
|             self._gateways.append(gateway) | ||||
|          | ||||
|     def pyevent__gateway_exit(self, gateway): | ||||
|     def pyexecnet_gateway_exit(self, gateway): | ||||
|         self.trace("exit", gateway) | ||||
|         if self._gateways is not None: | ||||
|             self._gateways.remove(gateway) | ||||
|  |  | |||
|  | @ -86,18 +86,18 @@ class TerminalReporter: | |||
|         for line in str(excrepr).split("\n"): | ||||
|             self.write_line("INTERNALERROR> " + line) | ||||
| 
 | ||||
|     def pyevent__gwmanage_newgateway(self, gateway, rinfo): | ||||
|     def pyexecnet_gwmanage_newgateway(self, gateway, platinfo): | ||||
|         #self.write_line("%s instantiated gateway from spec %r" %(gateway.id, gateway.spec._spec)) | ||||
|         d = {} | ||||
|         d['version'] = repr_pythonversion(rinfo.version_info) | ||||
|         d['version'] = repr_pythonversion(platinfo.version_info) | ||||
|         d['id'] = gateway.id | ||||
|         d['spec'] = gateway.spec._spec  | ||||
|         d['platform'] = rinfo.platform  | ||||
|         d['platform'] = platinfo.platform  | ||||
|         if self.config.option.verbose: | ||||
|             d['extra'] = "- " + rinfo.executable | ||||
|             d['extra'] = "- " + platinfo.executable | ||||
|         else: | ||||
|             d['extra'] = "" | ||||
|         d['cwd'] = rinfo.cwd | ||||
|         d['cwd'] = platinfo.cwd | ||||
|         infoline = ("%(id)s %(spec)s -- platform %(platform)s, " | ||||
|                         "Python %(version)s " | ||||
|                         "cwd: %(cwd)s" | ||||
|  | @ -105,14 +105,14 @@ class TerminalReporter: | |||
|         self.write_line(infoline) | ||||
|         self.gateway2info[gateway] = infoline | ||||
| 
 | ||||
|     def pyevent__gwmanage_rsyncstart(self, source, gateways): | ||||
|     def pyexecnet_gwmanage_rsyncstart(self, source, gateways): | ||||
|         targets = ", ".join([gw.id for gw in gateways]) | ||||
|         msg = "rsyncstart: %s -> %s" %(source, targets) | ||||
|         if not self.config.option.verbose: | ||||
|             msg += " # use --verbose to see rsync progress" | ||||
|         self.write_line(msg) | ||||
| 
 | ||||
|     def pyevent__gwmanage_rsyncfinish(self, source, gateways): | ||||
|     def pyexecnet_gwmanage_rsyncfinish(self, source, gateways): | ||||
|         targets = ", ".join([gw.id for gw in gateways]) | ||||
|         self.write_line("rsyncfinish: %s -> %s" %(source, targets)) | ||||
| 
 | ||||
|  | @ -461,16 +461,16 @@ class TestTerminal: | |||
|             platform = "xyz" | ||||
|             cwd = "qwe" | ||||
|          | ||||
|         rep.pyevent__gwmanage_newgateway(gw1, rinfo) | ||||
|         rep.pyexecnet_gwmanage_newgateway(gw1, rinfo) | ||||
|         linecomp.assert_contains_lines([ | ||||
|             "X1*popen*xyz*2.5*" | ||||
|         ]) | ||||
| 
 | ||||
|         rep.pyevent__gwmanage_rsyncstart(source="hello", gateways=[gw1, gw2]) | ||||
|         rep.pyexecnet_gwmanage_rsyncstart(source="hello", gateways=[gw1, gw2]) | ||||
|         linecomp.assert_contains_lines([ | ||||
|             "rsyncstart: hello -> X1, X2" | ||||
|         ]) | ||||
|         rep.pyevent__gwmanage_rsyncfinish(source="hello", gateways=[gw1, gw2]) | ||||
|         rep.pyexecnet_gwmanage_rsyncfinish(source="hello", gateways=[gw1, gw2]) | ||||
|         linecomp.assert_contains_lines([ | ||||
|             "rsyncfinish: hello -> X1, X2" | ||||
|         ]) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue