diff --git a/py/_com.py b/py/_com.py index de0d79bd3..c9736b388 100644 --- a/py/_com.py +++ b/py/_com.py @@ -36,22 +36,22 @@ class MultiCall: def execute(self, firstresult=False): while self.methods: - self.currentmethod = self.methods.pop() + self.currentmethod = currentmethod = self.methods.pop() # provide call introspection if "__call__" is the first positional argument - if hasattr(self.currentmethod, 'im_self'): - varnames = self.currentmethod.im_func.func_code.co_varnames + if hasattr(currentmethod, 'im_self'): + varnames = currentmethod.im_func.func_code.co_varnames needscall = varnames[1:2] == ('__call__',) else: try: - varnames = self.currentmethod.func_code.co_varnames + varnames = currentmethod.func_code.co_varnames except AttributeError: # builtin function varnames = () needscall = varnames[:1] == ('__call__',) if needscall: - res = self.currentmethod(self, *self.args, **self.kwargs) + res = currentmethod(self, *self.args, **self.kwargs) else: - res = self.currentmethod(*self.args, **self.kwargs) + res = currentmethod(*self.args, **self.kwargs) if hasattr(self, '_ex1'): self.results = [res] break diff --git a/py/execnet/gateway.py b/py/execnet/gateway.py index b95d85bb8..581bf6a32 100644 --- a/py/execnet/gateway.py +++ b/py/execnet/gateway.py @@ -249,6 +249,7 @@ class Gateway(object): channel.send(dict( executable = sys.executable, version_info = sys.version_info, + platform = sys.platform, cwd = os.getcwd(), )) """).receive()) diff --git a/py/execnet/gwmanage.py b/py/execnet/gwmanage.py index 1ef613e54..eb89654c0 100644 --- a/py/execnet/gwmanage.py +++ b/py/execnet/gwmanage.py @@ -34,7 +34,7 @@ class GatewayManager: gw = py.execnet.makegateway(spec) self.gateways.append(gw) gw.id = "[%s]" % len(self.gateways) - self.notify("gwmanage_newgateway", gw) + self.notify("gwmanage_newgateway", gw, gw._rinfo()) def getgateways(self, remote=True, inplacelocal=True): if not self.gateways and self.specs: diff --git a/py/execnet/testing/conftest.py b/py/execnet/testing/conftest.py new file mode 100644 index 000000000..c3afb248d --- /dev/null +++ b/py/execnet/testing/conftest.py @@ -0,0 +1,3 @@ + +pytest_plugins = "pytest_pytester" + diff --git a/py/execnet/testing/test_gwmanage.py b/py/execnet/testing/test_gwmanage.py index 74a1b6716..34acf38a8 100644 --- a/py/execnet/testing/test_gwmanage.py +++ b/py/execnet/testing/test_gwmanage.py @@ -8,8 +8,6 @@ import py from py.__.execnet.gwmanage import GatewayManager, HostRSync -pytest_plugins = "pytest_pytester" - class TestGatewayManagerPopen: def test_popen_no_default_chdir(self): gm = GatewayManager(["popen"]) @@ -22,20 +20,21 @@ class TestGatewayManagerPopen: for spec in GatewayManager(l, defaultchdir="abc").specs: assert spec.chdir == "abc" - def test_hostmanager_popen_makegateway(self, eventrecorder): + def test_popen_makegateway_events(self, eventrecorder): hm = GatewayManager(["popen"] * 2) hm.makegateways() event = eventrecorder.popevent("gwmanage_newgateway") - gw = event.args[0] + gw, platinfo = event.args[:2] assert gw.id == "[1]" + platinfo.executable = gw._rinfo().executable event = eventrecorder.popevent("gwmanage_newgateway") - gw = event.args[0] + gw, platinfo = event.args[:2] assert gw.id == "[2]" assert len(hm.gateways) == 2 hm.exit() assert not len(hm.gateways) - def test_hostmanager_popens_rsync(self, source): + def test_popens_rsync(self, source): hm = GatewayManager(["popen"] * 2) hm.makegateways() assert len(hm.gateways) == 2 @@ -47,7 +46,7 @@ class TestGatewayManagerPopen: hm.exit() assert not len(hm.gateways) - def test_hostmanager_rsync_popen_with_path(self, source, dest): + def test_rsync_popen_with_path(self, source, dest): hm = GatewayManager(["popen//chdir=%s" %dest] * 1) hm.makegateways() source.ensure("dir1", "dir2", "hello") diff --git a/py/test/config.py b/py/test/config.py index 8695aec2f..9816246a6 100644 --- a/py/test/config.py +++ b/py/test/config.py @@ -250,6 +250,45 @@ class Config(object): else: raise ValueError("unknown io capturing: " + iocapture) + def getxspecs(self): + config = self + if config.option.numprocesses: + if config.option.executable: + s = 'popen//python=%s' % config.option.executable + else: + s = 'popen' + xspec = [s] * config.option.numprocesses + else: + xspec = config.option.xspec + if not xspec: + xspec = config.getvalue("xspec") + if xspec is None: + raise config.Error("MISSING test execution (tx) nodes: please specify --tx") + #print "option value for xspecs", xspec + return [py.execnet.XSpec(x) for x in xspec] + + def getrsyncdirs(self): + config = self + roots = config.option.rsyncdirs + if roots: + roots = [py.path.local(x) for x in roots.split(',')] + else: + roots = [] + conftestroots = config.getconftest_pathlist("rsyncdirs") + if conftestroots: + roots.extend(conftestroots) + pydir = py.path.local(py.__file__).dirpath() + for root in roots: + if not root.check(): + raise ValueError("rsyncdir doesn't exist: %r" %(root,)) + if pydir is not None and root.basename == "py": + if root != pydir: + raise ValueError("root %r conflicts with current %r" %(root, pydir)) + pydir = None + if pydir is not None: + roots.append(pydir) + return roots + # # helpers diff --git a/py/test/dsession/dsession.py b/py/test/dsession/dsession.py index c78d36777..59f4a0ab2 100644 --- a/py/test/dsession/dsession.py +++ b/py/test/dsession/dsession.py @@ -9,7 +9,7 @@ from py.__.test import event from py.__.test.runner import basic_run_report, basic_collect_report from py.__.test.session import Session from py.__.test import outcome -from py.__.test.dsession.nodemanage import NodeManager, getxspecs +from py.__.test.dsession.nodemanage import NodeManager import Queue @@ -82,7 +82,7 @@ class DSession(Session): if option.executable and not option.dist and not option.numprocesses: option.numprocesses = 1 try: - getxspecs(self.config) + self.config.getxspecs() except self.config.Error: print "Please specify test environments for distribution of tests:" print "py.test --tx ssh=user@somehost --tx popen//python=python2.5" diff --git a/py/test/dsession/nodemanage.py b/py/test/dsession/nodemanage.py index 5114da2f6..06ebeb1cd 100644 --- a/py/test/dsession/nodemanage.py +++ b/py/test/dsession/nodemanage.py @@ -8,8 +8,8 @@ class NodeManager(object): def __init__(self, config, specs=None): self.config = config if specs is None: - specs = getxspecs(self.config) - self.roots = getconfigroots(config) + specs = self.config.getxspecs() + self.roots = self.config.getrsyncdirs() self.gwmanager = GatewayManager(specs) self.nodes = [] @@ -88,39 +88,3 @@ class NodeManager(object): # XXX teardown nodes? self.gwmanager.exit() -def getxspecs(config): - if config.option.numprocesses: - if config.option.executable: - s = 'popen//python=%s' % config.option.executable - else: - s = 'popen' - xspecs = [s] * config.option.numprocesses - else: - xspecs = config.option.xspecs - if not xspecs: - xspecs = config.getvalue("xspecs") - if xspecs is None: - raise config.Error("MISSING test execution (tx) nodes: please specify --tx") - #print "option value for xspecs", xspecs - return [py.execnet.XSpec(x) for x in xspecs] - -def getconfigroots(config): - roots = config.option.rsyncdirs - if roots: - roots = [py.path.local(x) for x in roots.split(',')] - else: - roots = [] - conftestroots = config.getconftest_pathlist("rsyncdirs") - if conftestroots: - roots.extend(conftestroots) - pydir = py.path.local(py.__file__).dirpath() - for root in roots: - if not root.check(): - raise ValueError("rsyncdir doesn't exist: %r" %(root,)) - if pydir is not None and root.basename == "py": - if root != pydir: - raise ValueError("root %r conflicts with current %r" %(root, pydir)) - pydir = None - if pydir is not None: - roots.append(pydir) - return roots diff --git a/py/test/dsession/testing/test_functional_dsession.py b/py/test/dsession/testing/test_functional_dsession.py index 09f9827a0..bdedea0aa 100644 --- a/py/test/dsession/testing/test_functional_dsession.py +++ b/py/test/dsession/testing/test_functional_dsession.py @@ -68,7 +68,7 @@ class TestAsyncFunctional: "--tx=popen//chdir=%(dest)s" % locals(), p) assert result.ret == 0 result.stdout.fnmatch_lines([ - "*1* instantiated gateway *popen*", + "*1* new *popen*platform*", #"RSyncStart: [G1]", #"RSyncFinished: [G1]", "*1 passed*" diff --git a/py/test/dsession/testing/test_nodemanage.py b/py/test/dsession/testing/test_nodemanage.py index cb4fd0e24..1ce18964b 100644 --- a/py/test/dsession/testing/test_nodemanage.py +++ b/py/test/dsession/testing/test_nodemanage.py @@ -3,7 +3,7 @@ """ import py -from py.__.test.dsession.nodemanage import NodeManager, getxspecs, getconfigroots +from py.__.test.dsession.nodemanage import NodeManager from py.__.test import event @@ -120,12 +120,12 @@ class TestNodeManager: class TestOptionsAndConfiguration: def test_getxspecs_numprocesses(self, testdir): config = testdir.parseconfig("-n3") - xspecs = getxspecs(config) + xspecs = config.getxspecs() assert len(xspecs) == 3 def test_getxspecs(self, testdir): config = testdir.parseconfig("--tx=popen", "--tx", "ssh=xyz") - xspecs = getxspecs(config) + xspecs = config.getxspecs() assert len(xspecs) == 2 print xspecs assert xspecs[0].popen @@ -133,7 +133,7 @@ class TestOptionsAndConfiguration: def test_getconfigroots(self, testdir): config = testdir.parseconfig('--rsyncdirs=' + str(testdir.tmpdir)) - roots = getconfigroots(config) + roots = config.getrsyncdirs() assert len(roots) == 1 + 1 assert testdir.tmpdir in roots @@ -146,7 +146,7 @@ class TestOptionsAndConfiguration: rsyncdirs= 'x', """) config = testdir.parseconfig(testdir.tmpdir, '--rsyncdirs=y,z') - roots = getconfigroots(config) + roots = config.getrsyncdirs() assert len(roots) == 3 + 1 assert py.path.local('y') in roots assert py.path.local('z') in roots diff --git a/py/test/plugin/pytest_default.py b/py/test/plugin/pytest_default.py index b16a7b828..05fbc5fc9 100644 --- a/py/test/plugin/pytest_default.py +++ b/py/test/plugin/pytest_default.py @@ -97,7 +97,7 @@ class DefaultPlugin: group.addoption('--rsyncdirs', dest="rsyncdirs", default=None, metavar="dir1,dir2,...", help="comma-separated list of directories to rsync. All those roots will be rsynced " "into a corresponding subdir on the remote sides. ") - group.addoption('--tx', dest="xspecs", action="append", + group._addoption('--xspec', '--tx', '-t', dest="xspec", action="append", help=("add a test environment, specified in XSpec syntax. examples: " "--tx popen//python=python2.5 --tx socket=192.168.1.102")) group._addoption('--exec', diff --git a/py/test/plugin/pytest_terminal.py b/py/test/plugin/pytest_terminal.py index be14cc010..b0b5a6def 100644 --- a/py/test/plugin/pytest_terminal.py +++ b/py/test/plugin/pytest_terminal.py @@ -84,8 +84,22 @@ class TerminalReporter: for line in str(event.repr).split("\n"): self.write_line("InternalException: " + line) - def pyevent_gwmanage_newgateway(self, gateway): - self.write_line("%s instantiated gateway from spec %r" %(gateway.id, gateway.spec._spec)) + def pyevent_gwmanage_newgateway(self, gateway, rinfo): + #self.write_line("%s instantiated gateway from spec %r" %(gateway.id, gateway.spec._spec)) + d = {} + d['version'] = repr_pythonversion(rinfo.version_info) + d['id'] = gateway.id + d['spec'] = gateway.spec._spec + d['platform'] = rinfo.platform + if self.config.option.verbose: + d['extra'] = "- " + rinfo.executable + else: + d['extra'] = "" + d['cwd'] = rinfo.cwd + self.write_line("%(id)s new %(spec)r -- platform %(platform)s, " + "Python %(version)s " + "cwd: %(cwd)s" + "%(extra)s" % d) def pyevent_gwmanage_rsyncstart(self, source, gateways): targets = ", ".join([gw.id for gw in gateways]) @@ -107,19 +121,12 @@ class TerminalReporter: self.write_line(msg) def pyevent_testnodeready(self, node): - # XXX - self.write_line("Node Ready: %r, spec %r" % (node,node.gateway.spec)) + self.write_line("%s node ready to receive tests" %(node.gateway.id,)) - #d = event.platinfo.copy() - #d['host'] = getattr(event.host, 'address', event.host) - #d['version'] = repr_pythonversion(d['sys.version_info']) - #self.write_line("HOSTUP: %(host)s %(sys.platform)s " - # "%(sys.executable)s - Python %(version)s" % - # d) def pyevent_testnodedown(self, node, error): if error: - self.write_line("Node Down: %r: %r" %(node, error)) + self.write_line("%s node down, error: %s" %(node.gateway.id, error)) def pyevent_trace(self, category, msg): if self.config.option.debug or \ @@ -175,6 +182,13 @@ class TerminalReporter: def pyevent_testrunstart(self, event): self.write_sep("=", "test session starts", bold=True) self._sessionstarttime = py.std.time.time() + + verinfo = ".".join(map(str, sys.version_info[:3])) + msg = "python: platform %s -- Python %s" % (sys.platform, verinfo) + if self.config.option.verbose or self.config.option.debug: + msg += " -- " + str(sys.executable) + self.write_line(msg) + rev = py.__pkg__.getrev() self.write_line("using py lib: %s " % ( py.path.local(py.__file__).dirpath(), rev)) @@ -431,9 +445,15 @@ class TestTerminal: class gw2: id = "X2" spec = py.execnet.XSpec("popen") - rep.pyevent_gwmanage_newgateway(gateway=gw1) + class rinfo: + version_info = (2, 5, 1, 'final', 0) + executable = "hello" + platform = "xyz" + cwd = "qwe" + + rep.pyevent_gwmanage_newgateway(gw1, rinfo) linecomp.assert_contains_lines([ - "X1 instantiated gateway from spec*", + "X1 new 'popen' *xyz*2.5*" ]) rep.pyevent_gwmanage_rsyncstart(source="hello", gateways=[gw1, gw2]) diff --git a/py/test/testing/acceptance_test.py b/py/test/testing/acceptance_test.py index 81cea934c..3c326c0b5 100644 --- a/py/test/testing/acceptance_test.py +++ b/py/test/testing/acceptance_test.py @@ -179,8 +179,8 @@ class TestPyTest: verinfo = ".".join(map(str, py.std.sys.version_info[:3])) extra = result.stdout.fnmatch_lines([ "*===== test session starts ====*", - "HOSTUP*INPROCESS* %s %s - Python %s*" %( - py.std.sys.platform, py.std.sys.executable, verinfo), + "python: platform %s -- Python %s*" %( + py.std.sys.platform, verinfo), # , py.std.sys.executable), "*test_header_trailer_info.py .", "=* 1 passed in *.[0-9][0-9] seconds *=", ]) @@ -265,11 +265,10 @@ class TestPyTest: py.test.skip("hello") """, ) - result = testdir.runpytest(p1, '-d', '--tx popen --tx popen') + result = testdir.runpytest(p1, '-d', '--tx=popen', '--tx=popen') result.stdout.fnmatch_lines([ - "HOSTUP: popen*Python*", - #"HOSTUP: localhost*Python*", - #"HOSTUP: localhost*Python*", + "*1*popen*Python*", + "*2*popen*Python*", "*2 failed, 1 passed, 1 skipped*", ]) assert result.ret == 1 @@ -288,13 +287,13 @@ class TestPyTest: """, ) testdir.makeconftest(""" - pytest_option_tx = 'popen popen popen'.split() + pytest_option_xspec = 'popen popen popen'.split() """) result = testdir.runpytest(p1, '-d') result.stdout.fnmatch_lines([ - "HOSTUP: popen*Python*", - #"HOSTUP: localhost*Python*", - #"HOSTUP: localhost*Python*", + "*1*popen*Python*", + "*2*popen*Python*", + "*3*popen*Python*", "*2 failed, 1 passed, 1 skipped*", ]) assert result.ret == 1 @@ -325,7 +324,7 @@ class TestPyTest: "*popen*Python*", "*popen*Python*", "*popen*Python*", - "HostDown*TERMINATED*", + "*node down*", "*3 failed, 1 passed, 1 skipped*" ]) assert result.ret == 1 diff --git a/py/test/testing/test_config.py b/py/test/testing/test_config.py index d5053e414..853584515 100644 --- a/py/test/testing/test_config.py +++ b/py/test/testing/test_config.py @@ -111,8 +111,6 @@ class TestConfigTmpdir: assert config2.basetemp != config3.basetemp class TestConfigAPI: - - def test_config_getvalue_honours_conftest(self, testdir): testdir.makepyfile(conftest="x=1") testdir.mkdir("sub").join("conftest.py").write("x=2 ; y = 3")