127 lines
4.2 KiB
Python
127 lines
4.2 KiB
Python
import py
|
|
import sys, os
|
|
from py.__.test.dsession.txnode import MasterNode
|
|
from py.__.execnet.gwmanage import GatewayManager
|
|
|
|
|
|
class NodeManager(object):
|
|
def __init__(self, config, specs=None):
|
|
self.config = config
|
|
if specs is None:
|
|
specs = getxspecs(self.config)
|
|
self.roots = getconfigroots(config)
|
|
self.gwmanager = GatewayManager(specs)
|
|
self.nodes = []
|
|
|
|
def trace(self, msg):
|
|
self.config.bus.notify("trace", "nodemanage", msg)
|
|
|
|
def trace_nodestatus(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_each(withchannel=True):
|
|
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):
|
|
""" make sure that all remote gateways
|
|
have the same set of roots in their
|
|
current directory.
|
|
"""
|
|
self.makegateways()
|
|
options = {
|
|
'ignores': self.config_getignores(),
|
|
'verbose': self.config.option.verbose,
|
|
}
|
|
if self.roots:
|
|
# send each rsync root
|
|
for root in self.roots:
|
|
self.gwmanager.rsync(root, **options)
|
|
else:
|
|
XXX # do we want to care for situations without explicit rsyncdirs?
|
|
# we transfer our topdir as the root
|
|
self.gwmanager.rsync(self.config.topdir, **options)
|
|
# and cd into it
|
|
self.gwmanager.multi_chdir(self.config.topdir.basename, inplacelocal=False)
|
|
|
|
def makegateways(self):
|
|
# we change to the topdir sot that
|
|
# PopenGateways will have their cwd
|
|
# such that unpickling configs will
|
|
# pick it up as the right topdir
|
|
# (for other gateways this chdir is irrelevant)
|
|
old = self.config.topdir.chdir()
|
|
try:
|
|
self.gwmanager.makegateways()
|
|
finally:
|
|
old.chdir()
|
|
self.trace_nodestatus()
|
|
|
|
|
|
def setup_nodes(self, putevent):
|
|
self.rsync_roots()
|
|
nice = self.config.getvalue("dist_nicelevel")
|
|
if nice != 0:
|
|
self.gwmanager.multi_exec("""
|
|
import os
|
|
if hasattr(os, 'nice'):
|
|
os.nice(%r)
|
|
""" % nice).waitclose()
|
|
|
|
self.trace_nodestatus()
|
|
multigw = self.gwmanager.getgateways(inplacelocal=False, remote=True)
|
|
multigw.remote_exec("""
|
|
import os, sys
|
|
sys.path.insert(0, os.getcwd())
|
|
""").waitclose()
|
|
|
|
for gateway in self.gwmanager.gateways:
|
|
node = MasterNode(gateway, self.config, putevent)
|
|
self.nodes.append(node)
|
|
|
|
def teardown_nodes(self):
|
|
# 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
|