[svn r62978] * introduce --hosts and --rsyncdirs optiosn
* re-sort option groups, disable some options for now * add docstrings to execnet gatewaymanage * streamline tests a bit * unify debugging and tracing --HG-- branch : trunk
This commit is contained in:
parent
2aea0a73e2
commit
b5a1f95856
|
@ -22,7 +22,6 @@ from py.__.test import event
|
||||||
|
|
||||||
|
|
||||||
class GatewaySpec(object):
|
class GatewaySpec(object):
|
||||||
type = "ssh"
|
|
||||||
def __init__(self, spec, defaultjoinpath="pyexecnetcache"):
|
def __init__(self, spec, defaultjoinpath="pyexecnetcache"):
|
||||||
if spec == "popen" or spec.startswith("popen:"):
|
if spec == "popen" or spec.startswith("popen:"):
|
||||||
self.address = "popen"
|
self.address = "popen"
|
||||||
|
@ -42,6 +41,7 @@ class GatewaySpec(object):
|
||||||
parts = spec.split(":", 1)
|
parts = spec.split(":", 1)
|
||||||
self.address = parts.pop(0)
|
self.address = parts.pop(0)
|
||||||
self.joinpath = parts and parts.pop(0) or ""
|
self.joinpath = parts and parts.pop(0) or ""
|
||||||
|
self.type = "ssh"
|
||||||
if not self.joinpath and not self.inplacelocal():
|
if not self.joinpath and not self.inplacelocal():
|
||||||
self.joinpath = defaultjoinpath
|
self.joinpath = defaultjoinpath
|
||||||
|
|
||||||
|
@ -60,8 +60,15 @@ class GatewaySpec(object):
|
||||||
elif self.type == "ssh":
|
elif self.type == "ssh":
|
||||||
gw = py.execnet.SshGateway(self.address, remotepython=python)
|
gw = py.execnet.SshGateway(self.address, remotepython=python)
|
||||||
if self.joinpath:
|
if self.joinpath:
|
||||||
channel = gw.remote_exec("import os ; os.chdir(channel.receive())")
|
channel = gw.remote_exec("""
|
||||||
channel.send(self.joinpath)
|
import os
|
||||||
|
path = %r
|
||||||
|
try:
|
||||||
|
os.chdir(path)
|
||||||
|
except OSError:
|
||||||
|
os.mkdir(path)
|
||||||
|
os.chdir(path)
|
||||||
|
""" % self.joinpath)
|
||||||
if waitclose:
|
if waitclose:
|
||||||
channel.waitclose()
|
channel.waitclose()
|
||||||
else:
|
else:
|
||||||
|
@ -74,13 +81,16 @@ class MultiChannel:
|
||||||
def __init__(self, channels):
|
def __init__(self, channels):
|
||||||
self._channels = channels
|
self._channels = channels
|
||||||
|
|
||||||
def receive(self):
|
def receive_items(self):
|
||||||
values = []
|
items = []
|
||||||
for ch in self._channels:
|
for ch in self._channels:
|
||||||
values.append(ch.receive())
|
items.append((ch, ch.receive()))
|
||||||
return values
|
return items
|
||||||
|
|
||||||
def wait(self):
|
def receive(self):
|
||||||
|
return [x[1] for x in self.receive_items()]
|
||||||
|
|
||||||
|
def waitclose(self):
|
||||||
for ch in self._channels:
|
for ch in self._channels:
|
||||||
ch.waitclose()
|
ch.waitclose()
|
||||||
|
|
||||||
|
@ -91,8 +101,7 @@ class GatewayManager:
|
||||||
self.spec2gateway[GatewaySpec(spec)] = None
|
self.spec2gateway[GatewaySpec(spec)] = None
|
||||||
|
|
||||||
def trace(self, msg):
|
def trace(self, msg):
|
||||||
py._com.pyplugins.notify("trace_gatewaymanage", msg)
|
py._com.pyplugins.notify("trace", "gatewaymanage", msg)
|
||||||
#print "trace", msg
|
|
||||||
|
|
||||||
def makegateways(self):
|
def makegateways(self):
|
||||||
for spec, value in self.spec2gateway.items():
|
for spec, value in self.spec2gateway.items():
|
||||||
|
@ -101,6 +110,9 @@ class GatewayManager:
|
||||||
self.spec2gateway[spec] = spec.makegateway()
|
self.spec2gateway[spec] = spec.makegateway()
|
||||||
|
|
||||||
def multi_exec(self, source, inplacelocal=True):
|
def multi_exec(self, source, inplacelocal=True):
|
||||||
|
""" remote execute code on all gateways.
|
||||||
|
@param inplacelocal=False: don't send code to inplacelocal hosts.
|
||||||
|
"""
|
||||||
source = py.code.Source(source)
|
source = py.code.Source(source)
|
||||||
channels = []
|
channels = []
|
||||||
for spec, gw in self.spec2gateway.items():
|
for spec, gw in self.spec2gateway.items():
|
||||||
|
@ -109,10 +121,15 @@ class GatewayManager:
|
||||||
return MultiChannel(channels)
|
return MultiChannel(channels)
|
||||||
|
|
||||||
def multi_chdir(self, basename, inplacelocal=True):
|
def multi_chdir(self, basename, inplacelocal=True):
|
||||||
|
""" perform a remote chdir to the given path, may be relative.
|
||||||
|
@param inplacelocal=False: don't send code to inplacelocal hosts.
|
||||||
|
"""
|
||||||
self.multi_exec("import os ; os.chdir(%r)" % basename,
|
self.multi_exec("import os ; os.chdir(%r)" % basename,
|
||||||
inplacelocal=inplacelocal).wait()
|
inplacelocal=inplacelocal).waitclose()
|
||||||
|
|
||||||
def rsync(self, source, notify=None, verbose=False, ignores=None):
|
def rsync(self, source, notify=None, verbose=False, ignores=None):
|
||||||
|
""" perform rsync to all remote hosts.
|
||||||
|
"""
|
||||||
rsync = HostRSync(source, verbose=verbose, ignores=ignores)
|
rsync = HostRSync(source, verbose=verbose, ignores=ignores)
|
||||||
added = False
|
added = False
|
||||||
for spec, gateway in self.spec2gateway.items():
|
for spec, gateway in self.spec2gateway.items():
|
||||||
|
|
|
@ -155,7 +155,11 @@ class TestGatewayManagerPopen:
|
||||||
testdir.tmpdir.chdir()
|
testdir.tmpdir.chdir()
|
||||||
hellopath = testdir.tmpdir.mkdir("hello")
|
hellopath = testdir.tmpdir.mkdir("hello")
|
||||||
hm.makegateways()
|
hm.makegateways()
|
||||||
l = hm.multi_exec("import os ; channel.send(os.getcwd())").receive()
|
l = [x[1] for x in hm.multi_exec(
|
||||||
|
"import os ; channel.send(os.getcwd())"
|
||||||
|
).receive_items()
|
||||||
|
]
|
||||||
|
paths = [x[1] for x in l]
|
||||||
assert l == [str(hellopath)] * 2
|
assert l == [str(hellopath)] * 2
|
||||||
py.test.raises(Exception, 'hm.multi_chdir("world", inplacelocal=False)')
|
py.test.raises(Exception, 'hm.multi_chdir("world", inplacelocal=False)')
|
||||||
worldpath = hellopath.mkdir("world")
|
worldpath = hellopath.mkdir("world")
|
||||||
|
@ -188,22 +192,25 @@ class TestGatewayManagerPopen:
|
||||||
|
|
||||||
from py.__.execnet.gwmanage import MultiChannel
|
from py.__.execnet.gwmanage import MultiChannel
|
||||||
class TestMultiChannel:
|
class TestMultiChannel:
|
||||||
def test_multichannel_receive(self):
|
def test_multichannel_receive_items(self):
|
||||||
class pseudochannel:
|
class pseudochannel:
|
||||||
def receive(self):
|
def receive(self):
|
||||||
return 12
|
return 12
|
||||||
multichannel = MultiChannel([pseudochannel(), pseudochannel()])
|
|
||||||
l = multichannel.receive()
|
|
||||||
assert len(l) == 2
|
|
||||||
assert l == [12, 12]
|
|
||||||
|
|
||||||
def test_multichannel_wait(self):
|
pc1 = pseudochannel()
|
||||||
|
pc2 = pseudochannel()
|
||||||
|
multichannel = MultiChannel([pc1, pc2])
|
||||||
|
l = multichannel.receive_items()
|
||||||
|
assert len(l) == 2
|
||||||
|
assert l == [(pc1, 12), (pc2, 12)]
|
||||||
|
|
||||||
|
def test_multichannel_waitclose(self):
|
||||||
l = []
|
l = []
|
||||||
class pseudochannel:
|
class pseudochannel:
|
||||||
def waitclose(self):
|
def waitclose(self):
|
||||||
l.append(0)
|
l.append(0)
|
||||||
multichannel = MultiChannel([pseudochannel(), pseudochannel()])
|
multichannel = MultiChannel([pseudochannel(), pseudochannel()])
|
||||||
multichannel.wait()
|
multichannel.waitclose()
|
||||||
assert len(l) == 2
|
assert len(l) == 2
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,17 @@ class Config(object):
|
||||||
assert isinstance(pytestplugins, py.test._PytestPlugins)
|
assert isinstance(pytestplugins, py.test._PytestPlugins)
|
||||||
self.bus = pytestplugins.pyplugins
|
self.bus = pytestplugins.pyplugins
|
||||||
self.pytestplugins = pytestplugins
|
self.pytestplugins = pytestplugins
|
||||||
self._conftest = Conftest(onimport=self.pytestplugins.consider_conftest)
|
self._conftest = Conftest(onimport=self._onimportconftest)
|
||||||
self._setupstate = SetupState()
|
self._setupstate = SetupState()
|
||||||
|
|
||||||
|
def _onimportconftest(self, conftestmodule):
|
||||||
|
self.trace("loaded conftestmodule %r" %(conftestmodule,))
|
||||||
|
self.pytestplugins.consider_conftest(conftestmodule)
|
||||||
|
|
||||||
|
def trace(self, msg):
|
||||||
|
if getattr(self.option, 'traceconfig', None):
|
||||||
|
self.bus.notify("trace", "config", msg)
|
||||||
|
|
||||||
def _processopt(self, opt):
|
def _processopt(self, opt):
|
||||||
if hasattr(opt, 'default') and opt.dest:
|
if hasattr(opt, 'default') and opt.dest:
|
||||||
val = os.environ.get("PYTEST_OPTION_" + opt.dest.upper(), None)
|
val = os.environ.get("PYTEST_OPTION_" + opt.dest.upper(), None)
|
||||||
|
@ -119,15 +127,12 @@ class Config(object):
|
||||||
col = Dir(pkgpath, config=self)
|
col = Dir(pkgpath, config=self)
|
||||||
return col._getfsnode(path)
|
return col._getfsnode(path)
|
||||||
|
|
||||||
def getvalue_pathlist(self, name, path=None):
|
def getconftest_pathlist(self, name, path=None):
|
||||||
""" return a matching value, which needs to be sequence
|
""" return a matching value, which needs to be sequence
|
||||||
of filenames that will be returned as a list of Path
|
of filenames that will be returned as a list of Path
|
||||||
objects (they can be relative to the location
|
objects (they can be relative to the location
|
||||||
where they were found).
|
where they were found).
|
||||||
"""
|
"""
|
||||||
try:
|
|
||||||
return getattr(self.option, name)
|
|
||||||
except AttributeError:
|
|
||||||
try:
|
try:
|
||||||
mod, relroots = self._conftest.rget_with_confmod(name, path)
|
mod, relroots = self._conftest.rget_with_confmod(name, path)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|
|
@ -44,9 +44,9 @@ class DSession(Session):
|
||||||
def fixoptions(self):
|
def fixoptions(self):
|
||||||
""" check, fix and determine conflicting options. """
|
""" check, fix and determine conflicting options. """
|
||||||
option = self.config.option
|
option = self.config.option
|
||||||
if option.runbrowser and not option.startserver:
|
#if option.runbrowser and not option.startserver:
|
||||||
#print "--runbrowser implies --startserver"
|
# #print "--runbrowser implies --startserver"
|
||||||
option.startserver = True
|
# option.startserver = True
|
||||||
if self.config.getvalue("dist_boxed") and option.dist:
|
if self.config.getvalue("dist_boxed") and option.dist:
|
||||||
option.boxed = True
|
option.boxed = True
|
||||||
# conflicting options
|
# conflicting options
|
||||||
|
|
|
@ -8,19 +8,34 @@ def getconfighosts(config):
|
||||||
if config.option.numprocesses:
|
if config.option.numprocesses:
|
||||||
hosts = ['localhost'] * config.option.numprocesses
|
hosts = ['localhost'] * config.option.numprocesses
|
||||||
else:
|
else:
|
||||||
hosts = config.getvalue("dist_hosts")
|
hosts = config.option.hosts
|
||||||
|
if not hosts:
|
||||||
|
hosts = config.getvalue("hosts")
|
||||||
|
else:
|
||||||
|
hosts = hosts.split(",")
|
||||||
assert hosts is not None
|
assert hosts is not None
|
||||||
return hosts
|
return hosts
|
||||||
|
|
||||||
|
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)
|
||||||
|
for root in roots:
|
||||||
|
if not root.check():
|
||||||
|
raise ValueError("rsyncdir doesn't exist: %r" %(root,))
|
||||||
|
return roots
|
||||||
|
|
||||||
class HostManager(object):
|
class HostManager(object):
|
||||||
def __init__(self, config, hosts=None):
|
def __init__(self, config, hosts=None):
|
||||||
self.config = config
|
self.config = config
|
||||||
roots = self.config.getvalue_pathlist("rsyncroots")
|
|
||||||
if not roots:
|
|
||||||
roots = self.config.getvalue_pathlist("dist_rsync_roots")
|
|
||||||
self.roots = roots
|
|
||||||
if hosts is None:
|
if hosts is None:
|
||||||
hosts = getconfighosts(self.config)
|
hosts = getconfighosts(self.config)
|
||||||
|
self.roots = getconfigroots(config)
|
||||||
self.gwmanager = GatewayManager(hosts)
|
self.gwmanager = GatewayManager(hosts)
|
||||||
|
|
||||||
def makegateways(self):
|
def makegateways(self):
|
||||||
|
@ -29,6 +44,19 @@ class HostManager(object):
|
||||||
self.gwmanager.makegateways()
|
self.gwmanager.makegateways()
|
||||||
finally:
|
finally:
|
||||||
old.chdir()
|
old.chdir()
|
||||||
|
self.trace_hoststatus()
|
||||||
|
|
||||||
|
def trace_hoststatus(self):
|
||||||
|
if self.config.option.debug:
|
||||||
|
for ch, result in self.gwmanager.multi_exec("""
|
||||||
|
import sys, os
|
||||||
|
channel.send((sys.executable, os.getcwd(), sys.path))
|
||||||
|
""").receive_items():
|
||||||
|
self.trace("spec %r, execuable %r, cwd %r, syspath %r" %(
|
||||||
|
ch.gateway.spec, result[0], result[1], result[2]))
|
||||||
|
|
||||||
|
def config_getignores(self):
|
||||||
|
return self.config.getconftest_pathlist("rsyncignore")
|
||||||
|
|
||||||
def rsync_roots(self):
|
def rsync_roots(self):
|
||||||
""" make sure that all remote gateways
|
""" make sure that all remote gateways
|
||||||
|
@ -42,8 +70,8 @@ class HostManager(object):
|
||||||
# (for other gateways this chdir is irrelevant)
|
# (for other gateways this chdir is irrelevant)
|
||||||
self.makegateways()
|
self.makegateways()
|
||||||
options = {
|
options = {
|
||||||
'ignores': self.config.getvalue_pathlist("dist_rsync_ignore"),
|
'ignores': self.config_getignores(),
|
||||||
'verbose': self.config.option.verbose
|
'verbose': 1, # self.config.option.verbose
|
||||||
}
|
}
|
||||||
if self.roots:
|
if self.roots:
|
||||||
# send each rsync root
|
# send each rsync root
|
||||||
|
@ -51,11 +79,14 @@ class HostManager(object):
|
||||||
self.gwmanager.rsync(root, **options)
|
self.gwmanager.rsync(root, **options)
|
||||||
else:
|
else:
|
||||||
# we transfer our topdir as the root
|
# we transfer our topdir as the root
|
||||||
# but need to be careful regarding
|
|
||||||
self.gwmanager.rsync(self.config.topdir, **options)
|
self.gwmanager.rsync(self.config.topdir, **options)
|
||||||
|
# and cd into it
|
||||||
self.gwmanager.multi_chdir(self.config.topdir.basename, inplacelocal=False)
|
self.gwmanager.multi_chdir(self.config.topdir.basename, inplacelocal=False)
|
||||||
self.config.bus.notify("rsyncfinished", event.RsyncFinished())
|
self.config.bus.notify("rsyncfinished", event.RsyncFinished())
|
||||||
|
|
||||||
|
def trace(self, msg):
|
||||||
|
self.config.bus.notify("trace", "testhostmanage", msg)
|
||||||
|
|
||||||
def setup_hosts(self, putevent):
|
def setup_hosts(self, putevent):
|
||||||
self.rsync_roots()
|
self.rsync_roots()
|
||||||
nice = self.config.getvalue("dist_nicelevel")
|
nice = self.config.getvalue("dist_nicelevel")
|
||||||
|
@ -64,7 +95,9 @@ class HostManager(object):
|
||||||
import os
|
import os
|
||||||
if hasattr(os, 'nice'):
|
if hasattr(os, 'nice'):
|
||||||
os.nice(%r)
|
os.nice(%r)
|
||||||
""" % nice).wait()
|
""" % nice).waitclose()
|
||||||
|
|
||||||
|
self.trace_hoststatus()
|
||||||
|
|
||||||
for host, gateway in self.gwmanager.spec2gateway.items():
|
for host, gateway in self.gwmanager.spec2gateway.items():
|
||||||
host.node = MasterNode(host,
|
host.node = MasterNode(host,
|
||||||
|
|
|
@ -39,7 +39,6 @@ class TestAsyncFunctional:
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_dist_some_tests(self, testdir):
|
def test_dist_some_tests(self, testdir):
|
||||||
testdir.makepyfile(conftest="dist_hosts=['localhost']\n")
|
|
||||||
p1 = testdir.makepyfile(test_one="""
|
p1 = testdir.makepyfile(test_one="""
|
||||||
def test_1():
|
def test_1():
|
||||||
pass
|
pass
|
||||||
|
@ -49,7 +48,7 @@ class TestAsyncFunctional:
|
||||||
def test_fail():
|
def test_fail():
|
||||||
assert 0
|
assert 0
|
||||||
""")
|
""")
|
||||||
config = testdir.parseconfig('-d', p1)
|
config = testdir.parseconfig('-d', p1, '--hosts=popen')
|
||||||
dsession = DSession(config)
|
dsession = DSession(config)
|
||||||
eq = EventQueue(config.bus)
|
eq = EventQueue(config.bus)
|
||||||
dsession.main([config.getfsnode(p1)])
|
dsession.main([config.getfsnode(p1)])
|
||||||
|
@ -61,7 +60,7 @@ class TestAsyncFunctional:
|
||||||
assert ev.failed
|
assert ev.failed
|
||||||
# see that the host is really down
|
# see that the host is really down
|
||||||
ev, = eq.geteventargs("hostdown")
|
ev, = eq.geteventargs("hostdown")
|
||||||
assert ev.host.address == "localhost"
|
assert ev.host.address == "popen"
|
||||||
ev, = eq.geteventargs("testrunfinish")
|
ev, = eq.geteventargs("testrunfinish")
|
||||||
|
|
||||||
def test_distribution_rsync_roots_example(self, testdir):
|
def test_distribution_rsync_roots_example(self, testdir):
|
||||||
|
@ -70,8 +69,8 @@ class TestAsyncFunctional:
|
||||||
subdir = "sub_example_dist"
|
subdir = "sub_example_dist"
|
||||||
sourcedir = self.tmpdir.mkdir("source")
|
sourcedir = self.tmpdir.mkdir("source")
|
||||||
sourcedir.ensure(subdir, "conftest.py").write(py.code.Source("""
|
sourcedir.ensure(subdir, "conftest.py").write(py.code.Source("""
|
||||||
dist_hosts = ["localhost:%s"]
|
hosts = ["popen:%s"]
|
||||||
dist_rsync_roots = ["%s", "../py"]
|
rsyncdirs = ["%s", "../py"]
|
||||||
""" % (destdir, tmpdir.join(subdir), )))
|
""" % (destdir, tmpdir.join(subdir), )))
|
||||||
tmpdir.ensure(subdir, "__init__.py")
|
tmpdir.ensure(subdir, "__init__.py")
|
||||||
tmpdir.ensure(subdir, "test_one.py").write(py.code.Source("""
|
tmpdir.ensure(subdir, "test_one.py").write(py.code.Source("""
|
||||||
|
@ -102,7 +101,6 @@ class TestAsyncFunctional:
|
||||||
if not hasattr(os, 'nice'):
|
if not hasattr(os, 'nice'):
|
||||||
py.test.skip("no os.nice() available")
|
py.test.skip("no os.nice() available")
|
||||||
testdir.makepyfile(conftest="""
|
testdir.makepyfile(conftest="""
|
||||||
dist_hosts=['localhost']
|
|
||||||
dist_nicelevel = 10
|
dist_nicelevel = 10
|
||||||
""")
|
""")
|
||||||
p1 = testdir.makepyfile("""
|
p1 = testdir.makepyfile("""
|
||||||
|
@ -110,7 +108,7 @@ class TestAsyncFunctional:
|
||||||
import os
|
import os
|
||||||
assert os.nice(0) == 10
|
assert os.nice(0) == 10
|
||||||
""")
|
""")
|
||||||
evrec = testdir.inline_run('-d', p1)
|
evrec = testdir.inline_run('-d', p1, '--hosts=popen')
|
||||||
ev = evrec.getreport('test_nice')
|
ev = evrec.getreport('test_nice')
|
||||||
assert ev.passed
|
assert ev.passed
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import py
|
import py
|
||||||
from py.__.test.dsession.hostmanage import HostManager, getconfighosts
|
from py.__.test.dsession.hostmanage import HostManager, getconfighosts, getconfigroots
|
||||||
from py.__.execnet.gwmanage import GatewaySpec as Host
|
from py.__.execnet.gwmanage import GatewaySpec as Host
|
||||||
|
|
||||||
from py.__.test import event
|
from py.__.test import event
|
||||||
|
@ -15,12 +15,14 @@ def pytest_pyfuncarg_dest(pyfuncitem):
|
||||||
return dest
|
return dest
|
||||||
|
|
||||||
class TestHostManager:
|
class TestHostManager:
|
||||||
def gethostmanager(self, source, dist_hosts, dist_rsync_roots=None):
|
def gethostmanager(self, source, hosts, rsyncdirs=None):
|
||||||
l = ["dist_hosts = %r" % dist_hosts]
|
def opt(optname, l):
|
||||||
if dist_rsync_roots:
|
return '%s=%s' % (optname, ",".join(map(str, l)))
|
||||||
l.append("dist_rsync_roots = %r" % dist_rsync_roots)
|
args = [opt('--hosts', hosts)]
|
||||||
source.join("conftest.py").write("\n".join(l))
|
if rsyncdirs:
|
||||||
config = py.test.config._reparse([source])
|
args.append(opt('--rsyncdir', [source.join(x, abs=True) for x in rsyncdirs]))
|
||||||
|
args.append(source)
|
||||||
|
config = py.test.config._reparse(args)
|
||||||
assert config.topdir == source
|
assert config.topdir == source
|
||||||
hm = HostManager(config)
|
hm = HostManager(config)
|
||||||
assert hm.gwmanager.spec2gateway
|
assert hm.gwmanager.spec2gateway
|
||||||
|
@ -34,7 +36,7 @@ class TestHostManager:
|
||||||
def test_hostmanager_rsync_roots_no_roots(self, source, dest):
|
def test_hostmanager_rsync_roots_no_roots(self, source, dest):
|
||||||
source.ensure("dir1", "file1").write("hello")
|
source.ensure("dir1", "file1").write("hello")
|
||||||
config = py.test.config._reparse([source])
|
config = py.test.config._reparse([source])
|
||||||
hm = HostManager(config, hosts=["localhost:%s" % dest])
|
hm = HostManager(config, hosts=["popen:%s" % dest])
|
||||||
assert hm.config.topdir == source == config.topdir
|
assert hm.config.topdir == source == config.topdir
|
||||||
hm.rsync_roots()
|
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()
|
||||||
|
@ -48,8 +50,8 @@ class TestHostManager:
|
||||||
dir2 = source.ensure("dir1", "dir2", dir=1)
|
dir2 = source.ensure("dir1", "dir2", dir=1)
|
||||||
dir2.ensure("hello")
|
dir2.ensure("hello")
|
||||||
hm = self.gethostmanager(source,
|
hm = self.gethostmanager(source,
|
||||||
dist_hosts = ["localhost:%s" % dest],
|
hosts = ["popen:%s" % dest],
|
||||||
dist_rsync_roots = ['dir1']
|
rsyncdirs = ['dir1']
|
||||||
)
|
)
|
||||||
assert hm.config.topdir == source
|
assert hm.config.topdir == source
|
||||||
hm.rsync_roots()
|
hm.rsync_roots()
|
||||||
|
@ -61,8 +63,8 @@ class TestHostManager:
|
||||||
dir2 = source.ensure("dir1", "dir2", dir=1)
|
dir2 = source.ensure("dir1", "dir2", dir=1)
|
||||||
dir2.ensure("hello")
|
dir2.ensure("hello")
|
||||||
hm = self.gethostmanager(source,
|
hm = self.gethostmanager(source,
|
||||||
dist_hosts = ["localhost:%s" % dest],
|
hosts = ["popen:%s" % dest],
|
||||||
dist_rsync_roots = [str(source)]
|
rsyncdirs = [str(source)]
|
||||||
)
|
)
|
||||||
assert hm.config.topdir == source
|
assert hm.config.topdir == source
|
||||||
hm.rsync_roots()
|
hm.rsync_roots()
|
||||||
|
@ -77,37 +79,37 @@ class TestHostManager:
|
||||||
dir2.ensure("hello")
|
dir2.ensure("hello")
|
||||||
source.ensure("bogusdir", "file")
|
source.ensure("bogusdir", "file")
|
||||||
source.join("conftest.py").write(py.code.Source("""
|
source.join("conftest.py").write(py.code.Source("""
|
||||||
dist_rsync_roots = ['dir1/dir2']
|
rsyncdirs = ['dir1/dir2']
|
||||||
"""))
|
"""))
|
||||||
session = py.test.config._reparse([source]).initsession()
|
session = py.test.config._reparse([source]).initsession()
|
||||||
hm = HostManager(session.config,
|
hm = HostManager(session.config,
|
||||||
hosts=["localhost:" + str(dest)])
|
hosts=["popen:" + str(dest)])
|
||||||
hm.rsync_roots()
|
hm.rsync_roots()
|
||||||
assert dest.join("dir2").check()
|
assert dest.join("dir2").check()
|
||||||
assert not dest.join("dir1").check()
|
assert not dest.join("dir1").check()
|
||||||
assert not dest.join("bogus").check()
|
assert not dest.join("bogus").check()
|
||||||
|
|
||||||
def test_hostmanager_rsync_ignore(self, source, dest):
|
def test_hostmanager_rsyncignore(self, source, dest):
|
||||||
dir2 = source.ensure("dir1", "dir2", dir=1)
|
dir2 = source.ensure("dir1", "dir2", dir=1)
|
||||||
dir5 = source.ensure("dir5", "dir6", "bogus")
|
dir5 = source.ensure("dir5", "dir6", "bogus")
|
||||||
dirf = source.ensure("dir5", "file")
|
dirf = source.ensure("dir5", "file")
|
||||||
dir2.ensure("hello")
|
dir2.ensure("hello")
|
||||||
source.join("conftest.py").write(py.code.Source("""
|
source.join("conftest.py").write(py.code.Source("""
|
||||||
dist_rsync_ignore = ['dir1/dir2', 'dir5/dir6']
|
rsyncdirs = ['dir1', 'dir5']
|
||||||
dist_rsync_roots = ['dir1', 'dir5']
|
rsyncignore = ['dir1/dir2', 'dir5/dir6']
|
||||||
"""))
|
"""))
|
||||||
session = py.test.config._reparse([source]).initsession()
|
session = py.test.config._reparse([source]).initsession()
|
||||||
hm = HostManager(session.config,
|
hm = HostManager(session.config,
|
||||||
hosts=["localhost:" + str(dest)])
|
hosts=["popen:" + str(dest)])
|
||||||
hm.rsync_roots()
|
hm.rsync_roots()
|
||||||
assert dest.join("dir1").check()
|
assert dest.join("dir1").check()
|
||||||
assert not dest.join("dir1", "dir2").check()
|
assert not dest.join("dir1", "dir2").check()
|
||||||
assert dest.join("dir5","file").check()
|
assert dest.join("dir5","file").check()
|
||||||
assert not dest.join("dir6").check()
|
assert not dest.join("dir6").check()
|
||||||
|
|
||||||
def test_hostmanage_optimise_localhost(self, source, dest):
|
def test_hostmanage_optimise_popen(self, source, dest):
|
||||||
hosts = ["localhost"] * 3
|
hosts = ["popen"] * 3
|
||||||
source.join("conftest.py").write("dist_rsync_roots = ['a']")
|
source.join("conftest.py").write("rsyncdirs = ['a']")
|
||||||
source.ensure('a', dir=1)
|
source.ensure('a', dir=1)
|
||||||
config = py.test.config._reparse([source])
|
config = py.test.config._reparse([source])
|
||||||
hm = HostManager(config, hosts=hosts)
|
hm = HostManager(config, hosts=hosts)
|
||||||
|
@ -116,31 +118,35 @@ class TestHostManager:
|
||||||
assert gwspec.inplacelocal()
|
assert gwspec.inplacelocal()
|
||||||
assert not gwspec.joinpath
|
assert not gwspec.joinpath
|
||||||
|
|
||||||
def test_hostmanage_setup_hosts(self, source):
|
def test_hostmanage_setup_hosts_DEBUG(self, source, EventRecorder):
|
||||||
hosts = ["localhost"] * 3
|
hosts = ["popen"] * 2
|
||||||
source.join("conftest.py").write("dist_rsync_roots = ['a']")
|
source.join("conftest.py").write("rsyncdirs = ['a']")
|
||||||
source.ensure('a', dir=1)
|
source.ensure('a', dir=1)
|
||||||
config = py.test.config._reparse([source])
|
config = py.test.config._reparse([source, '--debug'])
|
||||||
|
assert config.option.debug
|
||||||
hm = HostManager(config, hosts=hosts)
|
hm = HostManager(config, hosts=hosts)
|
||||||
queue = py.std.Queue.Queue()
|
evrec = EventRecorder(config.bus, debug=True)
|
||||||
hm.setup_hosts(putevent=queue.put)
|
hm.setup_hosts(putevent=[].append)
|
||||||
for host in hm.gwmanager.spec2gateway:
|
for host in hm.gwmanager.spec2gateway:
|
||||||
eventcall = queue.get(timeout=2.0)
|
l = evrec.getnamed("trace")
|
||||||
name, args, kwargs = eventcall
|
print evrec.events
|
||||||
assert name == "hostup"
|
assert l
|
||||||
for host in hm.gwmanager.spec2gateway:
|
hm.teardown_hosts()
|
||||||
host.node.shutdown()
|
|
||||||
for host in hm.gwmanager.spec2gateway:
|
|
||||||
eventcall = queue.get(timeout=2.0)
|
|
||||||
name, args, kwargs = eventcall
|
|
||||||
print name, args, kwargs
|
|
||||||
assert name == "hostdown"
|
|
||||||
|
|
||||||
def XXXtest_ssh_rsync_samehost_twice(self):
|
def test_hostmanage_simple_ssh_test(self, testdir):
|
||||||
#XXX we have no easy way to have a temp directory remotely!
|
rp = testdir.mkdir('xyz123')
|
||||||
|
rp.ensure("__init__.py")
|
||||||
|
p = testdir.makepyfile("def test_123(): import xyz123")
|
||||||
|
result = testdir.runpytest(p, '-d', "--hosts=popen", '--rsyncdirs=' + str(rp))
|
||||||
|
assert result.ret == 0
|
||||||
|
assert result.stdout.str().find("1 passed") != -1
|
||||||
|
|
||||||
|
@py.test.mark.xfail("implement double-rsync test")
|
||||||
|
def test_ssh_rsync_samehost_twice(self):
|
||||||
option = py.test.config.option
|
option = py.test.config.option
|
||||||
if option.sshhost is None:
|
if option.sshhost is None:
|
||||||
py.test.skip("no known ssh target, use -S to set one")
|
py.test.skip("no known ssh target, use -S to set one")
|
||||||
|
|
||||||
host1 = Host("%s" % (option.sshhost, ))
|
host1 = Host("%s" % (option.sshhost, ))
|
||||||
host2 = Host("%s" % (option.sshhost, ))
|
host2 = Host("%s" % (option.sshhost, ))
|
||||||
hm = HostManager(config, hosts=[host1, host2])
|
hm = HostManager(config, hosts=[host1, host2])
|
||||||
|
@ -150,8 +156,35 @@ class TestHostManager:
|
||||||
assert 0
|
assert 0
|
||||||
|
|
||||||
|
|
||||||
def test_getconfighosts():
|
def test_getconfighosts_numprocesses():
|
||||||
config = py.test.config._reparse(['-n3'])
|
config = py.test.config._reparse(['-n3'])
|
||||||
hosts = getconfighosts(config)
|
hosts = getconfighosts(config)
|
||||||
assert len(hosts) == 3
|
assert len(hosts) == 3
|
||||||
|
|
||||||
|
def test_getconfighosts_disthosts():
|
||||||
|
config = py.test.config._reparse(['--hosts=a,b,c'])
|
||||||
|
hosts = getconfighosts(config)
|
||||||
|
assert len(hosts) == 3
|
||||||
|
assert hosts == ['a', 'b', 'c']
|
||||||
|
|
||||||
|
def test_getconfigroots(testdir):
|
||||||
|
config = testdir.parseconfig('--rsyncdirs=' + str(testdir.tmpdir))
|
||||||
|
roots = getconfigroots(config)
|
||||||
|
assert len(roots) == 1
|
||||||
|
assert roots == [testdir.tmpdir]
|
||||||
|
|
||||||
|
def test_getconfigroots_with_conftest(testdir):
|
||||||
|
testdir.chdir()
|
||||||
|
p = py.path.local()
|
||||||
|
for bn in 'x y z'.split():
|
||||||
|
p.mkdir(bn)
|
||||||
|
testdir.makeconftest("""
|
||||||
|
rsyncdirs= 'x',
|
||||||
|
""")
|
||||||
|
config = testdir.parseconfig(testdir.tmpdir, '--rsyncdirs=y,z')
|
||||||
|
roots = getconfigroots(config)
|
||||||
|
assert len(roots) == 3
|
||||||
|
assert py.path.local('y') in roots
|
||||||
|
assert py.path.local('z') in roots
|
||||||
|
assert testdir.tmpdir.join('x') in roots
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ class MySetup:
|
||||||
config = py.test.config._reparse([])
|
config = py.test.config._reparse([])
|
||||||
self.config = config
|
self.config = config
|
||||||
self.queue = py.std.Queue.Queue()
|
self.queue = py.std.Queue.Queue()
|
||||||
self.host = GatewaySpec("localhost")
|
self.host = GatewaySpec("popen")
|
||||||
self.gateway = self.host.makegateway()
|
self.gateway = self.host.makegateway()
|
||||||
self.node = MasterNode(self.host, self.gateway, self.config, putevent=self.queue.put)
|
self.node = MasterNode(self.host, self.gateway, self.config, putevent=self.queue.put)
|
||||||
assert not self.node.channel.isclosed()
|
assert not self.node.channel.isclosed()
|
||||||
|
|
|
@ -36,9 +36,6 @@ class DefaultPlugin:
|
||||||
group._addoption('-x', '--exitfirst',
|
group._addoption('-x', '--exitfirst',
|
||||||
action="store_true", dest="exitfirst", default=False,
|
action="store_true", dest="exitfirst", default=False,
|
||||||
help="exit instantly on first error or failed test."),
|
help="exit instantly on first error or failed test."),
|
||||||
group._addoption('-s', '--nocapture',
|
|
||||||
action="store_true", dest="nocapture", default=False,
|
|
||||||
help="disable catching of sys.stdout/stderr output."),
|
|
||||||
group._addoption('-k',
|
group._addoption('-k',
|
||||||
action="store", dest="keyword", default='',
|
action="store", dest="keyword", default='',
|
||||||
help="only run test items matching the given "
|
help="only run test items matching the given "
|
||||||
|
@ -47,57 +44,70 @@ class DefaultPlugin:
|
||||||
"to run all subsequent tests. ")
|
"to run all subsequent tests. ")
|
||||||
group._addoption('-l', '--showlocals',
|
group._addoption('-l', '--showlocals',
|
||||||
action="store_true", dest="showlocals", default=False,
|
action="store_true", dest="showlocals", default=False,
|
||||||
help="show locals in tracebacks (disabled by default)."),
|
help="show locals in tracebacks (disabled by default).")
|
||||||
group._addoption('--showskipsummary',
|
group._addoption('--showskipsummary',
|
||||||
action="store_true", dest="showskipsummary", default=False,
|
action="store_true", dest="showskipsummary", default=False,
|
||||||
help="always show summary of skipped tests"),
|
help="always show summary of skipped tests")
|
||||||
group._addoption('', '--pdb',
|
group._addoption('--pdb',
|
||||||
action="store_true", dest="usepdb", default=False,
|
action="store_true", dest="usepdb", default=False,
|
||||||
help="start pdb (the Python debugger) on errors."),
|
help="start pdb (the Python debugger) on errors.")
|
||||||
group._addoption('', '--tb',
|
group._addoption('--tb',
|
||||||
action="store", dest="tbstyle", default='long',
|
action="store", dest="tbstyle", default='long',
|
||||||
type="choice", choices=['long', 'short', 'no'],
|
type="choice", choices=['long', 'short', 'no'],
|
||||||
help="traceback verboseness (long/short/no)."),
|
help="traceback verboseness (long/short/no).")
|
||||||
group._addoption('', '--fulltrace',
|
group._addoption('--fulltrace',
|
||||||
action="store_true", dest="fulltrace", default=False,
|
action="store_true", dest="fulltrace", default=False,
|
||||||
help="don't cut any tracebacks (default is to cut)."),
|
help="don't cut any tracebacks (default is to cut).")
|
||||||
group._addoption('', '--nomagic',
|
group._addoption('-s', '--nocapture',
|
||||||
action="store_true", dest="nomagic", default=False,
|
action="store_true", dest="nocapture", default=False,
|
||||||
help="refrain from using magic as much as possible."),
|
help="disable catching of sys.stdout/stderr output."),
|
||||||
group._addoption('', '--traceconfig',
|
|
||||||
action="store_true", dest="traceconfig", default=False,
|
|
||||||
help="trace considerations of conftest.py files."),
|
|
||||||
group._addoption('-f', '--looponfailing',
|
|
||||||
action="store_true", dest="looponfailing", default=False,
|
|
||||||
help="loop on failing test set."),
|
|
||||||
group._addoption('', '--exec',
|
|
||||||
action="store", dest="executable", default=None,
|
|
||||||
help="python executable to run the tests with."),
|
|
||||||
group._addoption('-n', '--numprocesses', dest="numprocesses", default=0,
|
|
||||||
action="store", type="int",
|
|
||||||
help="number of local test processes."),
|
|
||||||
group._addoption('', '--debug',
|
|
||||||
action="store_true", dest="debug", default=False,
|
|
||||||
help="turn on debugging information."),
|
|
||||||
|
|
||||||
group = parser.addgroup("experimental", "experimental options")
|
|
||||||
group._addoption('-d', '--dist',
|
|
||||||
action="store_true", dest="dist", default=False,
|
|
||||||
help="ad-hoc distribute tests across machines (requires conftest settings)"),
|
|
||||||
group._addoption('-w', '--startserver',
|
|
||||||
action="store_true", dest="startserver", default=False,
|
|
||||||
help="starts local web server for displaying test progress.",
|
|
||||||
),
|
|
||||||
group._addoption('-r', '--runbrowser',
|
|
||||||
action="store_true", dest="runbrowser", default=False,
|
|
||||||
help="run browser (implies --startserver)."
|
|
||||||
),
|
|
||||||
group._addoption('--boxed',
|
group._addoption('--boxed',
|
||||||
action="store_true", dest="boxed", default=False,
|
action="store_true", dest="boxed", default=False,
|
||||||
help="box each test run in a separate process"),
|
help="box each test run in a separate process"),
|
||||||
group._addoption('--rest',
|
group._addoption('-f', '--looponfailing',
|
||||||
action='store_true', dest="restreport", default=False,
|
action="store_true", dest="looponfailing", default=False,
|
||||||
help="restructured text output reporting."),
|
help="loop on failing test set.")
|
||||||
|
|
||||||
|
group = parser.addgroup("test process debugging")
|
||||||
|
group.addoption('--collectonly',
|
||||||
|
action="store_true", dest="collectonly",
|
||||||
|
help="only collect tests, don't execute them."),
|
||||||
|
group.addoption('--traceconfig',
|
||||||
|
action="store_true", dest="traceconfig", default=False,
|
||||||
|
help="trace considerations of conftest.py files."),
|
||||||
|
group._addoption('--nomagic',
|
||||||
|
action="store_true", dest="nomagic", default=False,
|
||||||
|
help="don't use assert reinterpretation and python traceback cutting. ")
|
||||||
|
group.addoption('--debug',
|
||||||
|
action="store_true", dest="debug", default=False,
|
||||||
|
help="generate and show debugging information.")
|
||||||
|
|
||||||
|
group = parser.addgroup("xplatform", "distributed/cross platform testing")
|
||||||
|
group._addoption('-d', '--dist',
|
||||||
|
action="store_true", dest="dist", default=False,
|
||||||
|
help="ad-hoc distribute tests across machines (requires conftest settings)")
|
||||||
|
group._addoption('-n', '--numprocesses', dest="numprocesses", default=0, metavar="num",
|
||||||
|
action="store", type="int",
|
||||||
|
help="number of local test processes. conflicts with --dist.")
|
||||||
|
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('--hosts', dest="hosts", default=None, metavar="host1,host2,...",
|
||||||
|
help="comma-separated list of host specs to send tests to.")
|
||||||
|
group._addoption('--exec',
|
||||||
|
action="store", dest="executable", default=None,
|
||||||
|
help="python executable to run the tests with.")
|
||||||
|
#group._addoption('-w', '--startserver',
|
||||||
|
# action="store_true", dest="startserver", default=False,
|
||||||
|
# help="starts local web server for displaying test progress.",
|
||||||
|
# ),
|
||||||
|
#group._addoption('-r', '--runbrowser',
|
||||||
|
# action="store_true", dest="runbrowser", default=False,
|
||||||
|
# help="run browser (implies --startserver)."
|
||||||
|
# ),
|
||||||
|
#group._addoption('--rest',
|
||||||
|
# action='store_true', dest="restreport", default=False,
|
||||||
|
# help="restructured text output reporting."),
|
||||||
|
|
||||||
def pytest_configure(self, config):
|
def pytest_configure(self, config):
|
||||||
self.setsession(config)
|
self.setsession(config)
|
||||||
|
|
|
@ -155,6 +155,9 @@ class PytestPluginHooks:
|
||||||
def pyevent(self, eventname, *args, **kwargs):
|
def pyevent(self, eventname, *args, **kwargs):
|
||||||
""" called for each testing event. """
|
""" called for each testing event. """
|
||||||
|
|
||||||
|
def pyevent_trace(self, category, msg):
|
||||||
|
""" called for tracing events events. """
|
||||||
|
|
||||||
def pyevent_internalerror(self, event):
|
def pyevent_internalerror(self, event):
|
||||||
""" called for internal errors. """
|
""" called for internal errors. """
|
||||||
|
|
||||||
|
|
|
@ -248,10 +248,8 @@ class EventRecorder(object):
|
||||||
if name == "plugin_registered" and args == (self,):
|
if name == "plugin_registered" and args == (self,):
|
||||||
return
|
return
|
||||||
if self.debug:
|
if self.debug:
|
||||||
print "[event] %s: %s **%s" %(name, ", ".join(map(str, args)), kwargs,)
|
print "[event: %s]: %s **%s" %(name, ", ".join(map(str, args)), kwargs,)
|
||||||
if len(args) == 1:
|
self.events.append((name,) + tuple(args))
|
||||||
event, = args
|
|
||||||
self.events.append((name, event))
|
|
||||||
|
|
||||||
def get(self, cls):
|
def get(self, cls):
|
||||||
l = []
|
l = []
|
||||||
|
|
|
@ -3,11 +3,6 @@ import sys
|
||||||
|
|
||||||
class TerminalPlugin(object):
|
class TerminalPlugin(object):
|
||||||
""" Report a test run to a terminal. """
|
""" Report a test run to a terminal. """
|
||||||
def pytest_addoption(self, parser):
|
|
||||||
parser.addoption('--collectonly',
|
|
||||||
action="store_true", dest="collectonly",
|
|
||||||
help="only collect tests, don't execute them."),
|
|
||||||
|
|
||||||
def pytest_configure(self, config):
|
def pytest_configure(self, config):
|
||||||
if config.option.collectonly:
|
if config.option.collectonly:
|
||||||
self.reporter = CollectonlyReporter(config)
|
self.reporter = CollectonlyReporter(config)
|
||||||
|
@ -115,6 +110,11 @@ class TerminalReporter:
|
||||||
if error:
|
if error:
|
||||||
self.write_line("HostDown %s: %s" %(host, error))
|
self.write_line("HostDown %s: %s" %(host, error))
|
||||||
|
|
||||||
|
def pyevent_trace(self, category, msg):
|
||||||
|
if self.config.option.debug or \
|
||||||
|
self.config.option.traceconfig and category.find("config") != -1:
|
||||||
|
self.write_line("[%s] %s" %(category, msg))
|
||||||
|
|
||||||
def pyevent_itemstart(self, event):
|
def pyevent_itemstart(self, event):
|
||||||
if self.config.option.verbose:
|
if self.config.option.verbose:
|
||||||
info = event.item.repr_metainfo()
|
info = event.item.repr_metainfo()
|
||||||
|
@ -167,6 +167,7 @@ class TerminalReporter:
|
||||||
rev = py.__pkg__.getrev()
|
rev = py.__pkg__.getrev()
|
||||||
self.write_line("using py lib: %s <rev %s>" % (
|
self.write_line("using py lib: %s <rev %s>" % (
|
||||||
py.path.local(py.__file__).dirpath(), rev))
|
py.path.local(py.__file__).dirpath(), rev))
|
||||||
|
if self.config.option.traceconfig:
|
||||||
plugins = []
|
plugins = []
|
||||||
for x in self.config.pytestplugins._plugins:
|
for x in self.config.pytestplugins._plugins:
|
||||||
if isinstance(x, str) and x.startswith("pytest_"):
|
if isinstance(x, str) and x.startswith("pytest_"):
|
||||||
|
|
|
@ -29,9 +29,9 @@ class Session(object):
|
||||||
def fixoptions(self):
|
def fixoptions(self):
|
||||||
""" check, fix and determine conflicting options. """
|
""" check, fix and determine conflicting options. """
|
||||||
option = self.config.option
|
option = self.config.option
|
||||||
if option.runbrowser and not option.startserver:
|
#if option.runbrowser and not option.startserver:
|
||||||
#print "--runbrowser implies --startserver"
|
# #print "--runbrowser implies --startserver"
|
||||||
option.startserver = True
|
# option.startserver = True
|
||||||
# conflicting options
|
# conflicting options
|
||||||
if option.looponfailing and option.usepdb:
|
if option.looponfailing and option.usepdb:
|
||||||
raise ValueError, "--looponfailing together with --pdb not supported."
|
raise ValueError, "--looponfailing together with --pdb not supported."
|
||||||
|
|
|
@ -241,13 +241,11 @@ class TestPyTest:
|
||||||
def test_skip():
|
def test_skip():
|
||||||
py.test.skip("hello")
|
py.test.skip("hello")
|
||||||
""",
|
""",
|
||||||
conftest="""
|
|
||||||
dist_hosts = ['localhost'] * 3
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
result = testdir.runpytest(p1, '-d')
|
#result = testdir.runpytest(p1, '-d')
|
||||||
|
result = testdir.runpytest(p1, '-d', '--hosts=popen,popen,popen')
|
||||||
result.stdout.fnmatch_lines([
|
result.stdout.fnmatch_lines([
|
||||||
"HOSTUP: localhost*Python*",
|
"HOSTUP: popen*Python*",
|
||||||
#"HOSTUP: localhost*Python*",
|
#"HOSTUP: localhost*Python*",
|
||||||
#"HOSTUP: localhost*Python*",
|
#"HOSTUP: localhost*Python*",
|
||||||
"*2 failed, 1 passed, 1 skipped*",
|
"*2 failed, 1 passed, 1 skipped*",
|
||||||
|
@ -273,17 +271,14 @@ class TestPyTest:
|
||||||
import os
|
import os
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
os.kill(os.getpid(), 15)
|
os.kill(os.getpid(), 15)
|
||||||
""",
|
|
||||||
conftest="""
|
|
||||||
dist_hosts = ['localhost'] * 3
|
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
result = testdir.runpytest(p1, '-d')
|
result = testdir.runpytest(p1, '-d', '--hosts=popen,popen,popen')
|
||||||
result.stdout.fnmatch_lines([
|
result.stdout.fnmatch_lines([
|
||||||
"*localhost*Python*",
|
"*popen*Python*",
|
||||||
"*localhost*Python*",
|
"*popen*Python*",
|
||||||
"*localhost*Python*",
|
"*popen*Python*",
|
||||||
"HostDown*localhost*TERMINATED*",
|
"HostDown*TERMINATED*",
|
||||||
"*3 failed, 1 passed, 1 skipped*"
|
"*3 failed, 1 passed, 1 skipped*"
|
||||||
])
|
])
|
||||||
assert result.ret == 1
|
assert result.ret == 1
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import py
|
import py
|
||||||
|
|
||||||
|
|
||||||
class TestConfigCmdlineParsing:
|
class TestConfigCmdlineParsing:
|
||||||
def test_config_cmdline_options(self, testdir):
|
def test_config_cmdline_options(self, testdir):
|
||||||
testdir.makepyfile(conftest="""
|
testdir.makepyfile(conftest="""
|
||||||
|
@ -118,22 +119,18 @@ class TestConfigAPI:
|
||||||
config = py.test.config._reparse([str(o)])
|
config = py.test.config._reparse([str(o)])
|
||||||
assert config.getvalue('x') == 1
|
assert config.getvalue('x') == 1
|
||||||
|
|
||||||
def test_getvalue_pathlist(self, tmpdir):
|
def test_getconftest_pathlist(self, tmpdir):
|
||||||
somepath = tmpdir.join("x", "y", "z")
|
somepath = tmpdir.join("x", "y", "z")
|
||||||
p = tmpdir.join("conftest.py")
|
p = tmpdir.join("conftest.py")
|
||||||
p.write("pathlist = ['.', %r]" % str(somepath))
|
p.write("pathlist = ['.', %r]" % str(somepath))
|
||||||
config = py.test.config._reparse([p])
|
config = py.test.config._reparse([p])
|
||||||
assert config.getvalue_pathlist('notexist') is None
|
assert config.getconftest_pathlist('notexist') is None
|
||||||
pl = config.getvalue_pathlist('pathlist')
|
pl = config.getconftest_pathlist('pathlist')
|
||||||
print pl
|
print pl
|
||||||
assert len(pl) == 2
|
assert len(pl) == 2
|
||||||
assert pl[0] == tmpdir
|
assert pl[0] == tmpdir
|
||||||
assert pl[1] == somepath
|
assert pl[1] == somepath
|
||||||
|
|
||||||
config.option.mypathlist = [py.path.local()]
|
|
||||||
pl = config.getvalue_pathlist('mypathlist')
|
|
||||||
assert pl == [py.path.local()]
|
|
||||||
|
|
||||||
def test_setsessionclass_and_initsession(self, testdir):
|
def test_setsessionclass_and_initsession(self, testdir):
|
||||||
from py.__.test.config import Config
|
from py.__.test.config import Config
|
||||||
config = Config()
|
config = Config()
|
||||||
|
|
|
@ -100,7 +100,7 @@ class TestBootstrapping:
|
||||||
|
|
||||||
def test_config_sets_conftesthandle_onimport(self, testdir):
|
def test_config_sets_conftesthandle_onimport(self, testdir):
|
||||||
config = testdir.parseconfig([])
|
config = testdir.parseconfig([])
|
||||||
assert config._conftest._onimport == config.pytestplugins.consider_conftest
|
assert config._conftest._onimport == config._onimportconftest
|
||||||
|
|
||||||
def test_consider_conftest_deps(self, testdir):
|
def test_consider_conftest_deps(self, testdir):
|
||||||
mod = testdir.makepyfile("pytest_plugins='xyz'").pyimport()
|
mod = testdir.makepyfile("pytest_plugins='xyz'").pyimport()
|
||||||
|
|
Loading…
Reference in New Issue