Commit 84357f1d authored by Scott Talbert's avatar Scott Talbert

New upstream version 1.22.1

parent 34fe781a
pytest-xdist 1.22.1 (2018-02-19)
================================
Bug Fixes
---------
- Fix issue when using ``loadscope`` or ``loadfile`` where tests would fail to
start if the first scope had only one test. (`#257
<https://github.com/pytest-dev/pytest-xdist/issues/257>`_)
Trivial Changes
---------------
- Change terminology used by ``pytest-xdist`` to *master* and *worker* in
arguments and messages (for example ``--max-worker-reset``). (`#234
<https://github.com/pytest-dev/pytest-xdist/issues/234>`_)
pytest-xdist 1.22.0 (2018-01-11)
================================
......
......@@ -26,13 +26,11 @@ To publish a new release ``X.Y.Z``, the steps are as follows:
#. Install ``pytest-xdist`` and dev requirements in a virtualenv::
$ pip install -e . -r dev-requirements.txt
$ pip install -e . -U -r dev-requirements.txt
#. Update ``CHANGELOG.rst`` file by running::
$ towncrier --version X.Y.Z
It might ask for confirmation to remove news fragments; answer yes.
$ towncrier --version X.Y.Z --yes
#. Commit and push the branch for review.
......
This diff is collapsed.
This diff is collapsed.
......@@ -33,4 +33,4 @@ template = "changelog/_template.rst"
[[tool.towncrier.type]]
directory = "trivial"
name = "Trivial Changes"
showcontent = false
showcontent = true
This diff is collapsed.
......@@ -203,7 +203,7 @@ class TestLoadScheduling:
def test_different_tests_collected(self, testdir):
"""
Test that LoadScheduling is reporting collection errors when
different test ids are collected by slaves.
different test ids are collected by workers.
"""
class CollectHook(object):
......
......@@ -20,10 +20,10 @@ class TestHooks:
def pytest_runtest_logreport(report):
if hasattr(report, 'node'):
if report.when == "call":
slaveid = report.node.slaveinput['slaveid']
if slaveid != report.worker_id:
workerid = report.node.workerinput['workerid']
if workerid != report.worker_id:
print("HOOK: Worker id mismatch: %s %s"
% (slaveid, report.worker_id))
% (workerid, report.worker_id))
else:
print("HOOK: %s %s"
% (report.nodeid, report.worker_id))
......@@ -41,9 +41,9 @@ class TestHooks:
"""
testdir.makeconftest("""
def pytest_xdist_node_collection_finished(node, ids):
slaveid = node.slaveinput['slaveid']
workerid = node.workerinput['workerid']
stripped_ids = [x.split('::')[1] for x in ids]
print("HOOK: %s %s" % (slaveid, ', '.join(stripped_ids)))
print("HOOK: %s %s" % (workerid, ', '.join(stripped_ids)))
""")
res = testdir.runpytest('-n2', '-s')
res.stdout.fnmatch_lines_random([
......
import py
import execnet
from xdist.slavemanage import NodeManager
from xdist.workermanage import NodeManager
def test_dist_incompatibility_messages(testdir):
......
import py
import pytest
from xdist.slavemanage import SlaveController, unserialize_report
from xdist.workermanage import WorkerController, unserialize_report
from xdist.remote import serialize_report
import execnet
import marshal
......@@ -26,7 +26,7 @@ class EventCall:
return "<EventCall %s(**%s)>" % (self.name, self.kwargs)
class SlaveSetup:
class WorkerSetup:
use_callback = False
def __init__(self, request, testdir):
......@@ -44,8 +44,8 @@ class SlaveSetup:
class DummyMananger:
specs = [0, 1]
self.slp = SlaveController(DummyMananger, self.gateway, config,
putevent)
self.slp = WorkerController(DummyMananger, self.gateway, config,
putevent)
self.request.addfinalizer(self.slp.ensure_teardown)
self.slp.setup()
......@@ -65,8 +65,8 @@ class SlaveSetup:
@pytest.fixture
def slave(request, testdir):
return SlaveSetup(request, testdir)
def worker(request, testdir):
return WorkerSetup(request, testdir)
@pytest.mark.xfail(reason='#59')
......@@ -243,107 +243,107 @@ class TestReportSerialization:
assert newrep.longrepr == str(rep.longrepr)
class TestSlaveInteractor:
def test_basic_collect_and_runtests(self, slave):
slave.testdir.makepyfile("""
class TestWorkerInteractor:
def test_basic_collect_and_runtests(self, worker):
worker.testdir.makepyfile("""
def test_func():
pass
""")
slave.setup()
ev = slave.popevent()
assert ev.name == "slaveready"
ev = slave.popevent()
worker.setup()
ev = worker.popevent()
assert ev.name == "workerready"
ev = worker.popevent()
assert ev.name == "collectionstart"
assert not ev.kwargs
ev = slave.popevent("collectionfinish")
assert ev.kwargs['topdir'] == slave.testdir.tmpdir
ev = worker.popevent("collectionfinish")
assert ev.kwargs['topdir'] == worker.testdir.tmpdir
ids = ev.kwargs['ids']
assert len(ids) == 1
slave.sendcommand("runtests", indices=list(range(len(ids))))
slave.sendcommand("shutdown")
ev = slave.popevent("logstart")
worker.sendcommand("runtests", indices=list(range(len(ids))))
worker.sendcommand("shutdown")
ev = worker.popevent("logstart")
assert ev.kwargs["nodeid"].endswith("test_func")
assert len(ev.kwargs["location"]) == 3
ev = slave.popevent("testreport") # setup
ev = slave.popevent("testreport")
ev = worker.popevent("testreport") # setup
ev = worker.popevent("testreport")
assert ev.name == "testreport"
rep = unserialize_report(ev.name, ev.kwargs['data'])
assert rep.nodeid.endswith("::test_func")
assert rep.passed
assert rep.when == "call"
ev = slave.popevent("slavefinished")
assert 'slaveoutput' in ev.kwargs
ev = worker.popevent("workerfinished")
assert 'workeroutput' in ev.kwargs
@pytest.mark.skipif(pytest.__version__ >= '3.0',
reason='skip at module level illegal in pytest 3.0')
def test_remote_collect_skip(self, slave):
slave.testdir.makepyfile("""
def test_remote_collect_skip(self, worker):
worker.testdir.makepyfile("""
import py
py.test.skip("hello")
""")
slave.setup()
ev = slave.popevent("collectionstart")
worker.setup()
ev = worker.popevent("collectionstart")
assert not ev.kwargs
ev = slave.popevent()
ev = worker.popevent()
assert ev.name == "collectreport"
ev = slave.popevent()
ev = worker.popevent()
assert ev.name == "collectreport"
rep = unserialize_report(ev.name, ev.kwargs['data'])
assert rep.skipped
ev = slave.popevent("collectionfinish")
ev = worker.popevent("collectionfinish")
assert not ev.kwargs['ids']
def test_remote_collect_fail(self, slave):
slave.testdir.makepyfile("""aasd qwe""")
slave.setup()
ev = slave.popevent("collectionstart")
def test_remote_collect_fail(self, worker):
worker.testdir.makepyfile("""aasd qwe""")
worker.setup()
ev = worker.popevent("collectionstart")
assert not ev.kwargs
ev = slave.popevent()
ev = worker.popevent()
assert ev.name == "collectreport"
ev = slave.popevent()
ev = worker.popevent()
assert ev.name == "collectreport"
rep = unserialize_report(ev.name, ev.kwargs['data'])
assert rep.failed
ev = slave.popevent("collectionfinish")
ev = worker.popevent("collectionfinish")
assert not ev.kwargs['ids']
def test_runtests_all(self, slave):
slave.testdir.makepyfile("""
def test_runtests_all(self, worker):
worker.testdir.makepyfile("""
def test_func(): pass
def test_func2(): pass
""")
slave.setup()
ev = slave.popevent()
assert ev.name == "slaveready"
ev = slave.popevent()
worker.setup()
ev = worker.popevent()
assert ev.name == "workerready"
ev = worker.popevent()
assert ev.name == "collectionstart"
assert not ev.kwargs
ev = slave.popevent("collectionfinish")
ev = worker.popevent("collectionfinish")
ids = ev.kwargs['ids']
assert len(ids) == 2
slave.sendcommand("runtests_all", )
slave.sendcommand("shutdown", )
worker.sendcommand("runtests_all", )
worker.sendcommand("shutdown", )
for func in "::test_func", "::test_func2":
for i in range(3): # setup/call/teardown
ev = slave.popevent("testreport")
ev = worker.popevent("testreport")
assert ev.name == "testreport"
rep = unserialize_report(ev.name, ev.kwargs['data'])
assert rep.nodeid.endswith(func)
ev = slave.popevent("slavefinished")
assert 'slaveoutput' in ev.kwargs
ev = worker.popevent("workerfinished")
assert 'workeroutput' in ev.kwargs
def test_happy_run_events_converted(self, testdir, slave):
def test_happy_run_events_converted(self, testdir, worker):
py.test.xfail("implement a simple test for event production")
assert not slave.use_callback
slave.testdir.makepyfile("""
assert not worker.use_callback
worker.testdir.makepyfile("""
def test_func():
pass
""")
slave.setup()
hookrec = testdir.getreportrecorder(slave.config)
for data in slave.slp.channel:
slave.slp.process_from_remote(data)
slave.slp.process_from_remote(slave.slp.ENDMARK)
worker.setup()
hookrec = testdir.getreportrecorder(worker.config)
for data in worker.slp.channel:
worker.slp.process_from_remote(data)
worker.slp.process_from_remote(worker.slp.ENDMARK)
py.std.pprint.pprint(hookrec.hookrecorder.calls)
hookrec.hookrecorder.contains([
("pytest_collectstart", "collector.fspath == aaa"),
......@@ -354,13 +354,13 @@ class TestSlaveInteractor:
("pytest_collectreport", "report.collector.fspath == bbb"),
])
def test_process_from_remote_error_handling(self, slave, capsys):
slave.use_callback = True
slave.setup()
slave.slp.process_from_remote(('<nonono>', ()))
def test_process_from_remote_error_handling(self, worker, capsys):
worker.use_callback = True
worker.setup()
worker.slp.process_from_remote(('<nonono>', ()))
out, err = capsys.readouterr()
assert 'INTERNALERROR> ValueError: unknown event: <nonono>' in out
ev = slave.popevent()
ev = worker.popevent()
assert ev.name == "errordown"
......@@ -371,5 +371,5 @@ def test_remote_env_vars(testdir):
assert os.environ['PYTEST_XDIST_WORKER'] in ('gw0', 'gw1')
assert os.environ['PYTEST_XDIST_WORKER_COUNT'] == '2'
''')
result = testdir.runpytest('-n2', '--max-slave-restart=0')
result = testdir.runpytest('-n2', '--max-worker-restart=0')
assert result.ret == 0
......@@ -2,8 +2,8 @@ import py
import pytest
import execnet
from _pytest.pytester import HookRecorder
from xdist import slavemanage, newhooks
from xdist.slavemanage import HostRSync, NodeManager
from xdist import workermanage, newhooks
from xdist.workermanage import HostRSync, NodeManager
pytest_plugins = "pytester"
......@@ -32,7 +32,7 @@ def mysetup(tmpdir):
@pytest.fixture
def slavecontroller(monkeypatch):
def workercontroller(monkeypatch):
class MockController(object):
def __init__(self, *args):
pass
......@@ -40,7 +40,7 @@ def slavecontroller(monkeypatch):
def setup(self):
pass
monkeypatch.setattr(slavemanage, 'SlaveController', MockController)
monkeypatch.setattr(workermanage, 'WorkerController', MockController)
return MockController
......@@ -57,7 +57,7 @@ class TestNodeManagerPopen:
assert spec.chdir == "abc"
def test_popen_makegateway_events(self, config, hookrecorder,
slavecontroller):
workercontroller):
hm = NodeManager(config, ["popen"] * 2)
hm.setup_nodes(None)
call = hookrecorder.popcall("pytest_xdist_setupnodes")
......@@ -72,7 +72,7 @@ class TestNodeManagerPopen:
hm.teardown_nodes()
assert not len(hm.group)
def test_popens_rsync(self, config, mysetup, slavecontroller):
def test_popens_rsync(self, config, mysetup, workercontroller):
source = mysetup.source
hm = NodeManager(config, ["popen"] * 2)
hm.setup_nodes(None)
......@@ -97,7 +97,7 @@ class TestNodeManagerPopen:
assert not len(hm.group)
assert "sys.path.insert" in gw.remote_exec.args[0]
def test_rsync_popen_with_path(self, config, mysetup, slavecontroller):
def test_rsync_popen_with_path(self, config, mysetup, workercontroller):
source, dest = mysetup.source, mysetup.dest
hm = NodeManager(config, ["popen//chdir=%s" % dest] * 1)
hm.setup_nodes(None)
......@@ -114,7 +114,7 @@ class TestNodeManagerPopen:
assert dest.join("dir1", "dir2", 'hello').check()
def test_rsync_same_popen_twice(self, config, mysetup, hookrecorder,
slavecontroller):
workercontroller):
source, dest = mysetup.source, mysetup.dest
hm = NodeManager(config, ["popen//chdir=%s" % dest] * 2)
hm.roots = []
......@@ -174,7 +174,7 @@ class TestNodeManager:
assert p.join("dir1").check()
assert p.join("dir1", "file1").check()
def test_popen_rsync_subdir(self, testdir, mysetup, slavecontroller):
def test_popen_rsync_subdir(self, testdir, mysetup, workercontroller):
source, dest = mysetup.source, mysetup.dest
dir1 = mysetup.source.mkdir("dir1")
dir2 = dir1.mkdir("dir2")
......@@ -192,7 +192,7 @@ class TestNodeManager:
assert dest.join("dir1", "dir2", 'hello').check()
nodemanager.teardown_nodes()
def test_init_rsync_roots(self, testdir, mysetup, slavecontroller):
def test_init_rsync_roots(self, testdir, mysetup, workercontroller):
source, dest = mysetup.source, mysetup.dest
dir2 = source.ensure("dir1", "dir2", dir=1)
source.ensure("dir1", "somefile", dir=1)
......@@ -209,7 +209,7 @@ class TestNodeManager:
assert not dest.join("dir1").check()
assert not dest.join("bogus").check()
def test_rsyncignore(self, testdir, mysetup, slavecontroller):
def test_rsyncignore(self, testdir, mysetup, workercontroller):
source, dest = mysetup.source, mysetup.dest
dir2 = source.ensure("dir1", "dir2", dir=1)
source.ensure("dir5", "dir6", "bogus")
......@@ -233,7 +233,7 @@ class TestNodeManager:
assert not dest.join('foo').check()
assert not dest.join('bar').check()
def test_optimise_popen(self, testdir, mysetup, slavecontroller):
def test_optimise_popen(self, testdir, mysetup, workercontroller):
source = mysetup.source
specs = ["popen"] * 3
source.join("conftest.py").write("rsyncdirs = ['a']")
......
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
version = '1.22.0'
version = '1.22.1'
This diff is collapsed.
......@@ -69,10 +69,10 @@ class RemoteControl(object):
out = py.io.TerminalWriter()
if hasattr(self, 'gateway'):
raise ValueError("already have gateway %r" % self.gateway)
self.trace("setting up slave session")
self.trace("setting up worker session")
self.gateway = self.initgateway()
self.channel = channel = self.gateway.remote_exec(
init_slave_session,
init_worker_session,
args=self.config.args,
option_dict=vars(self.config.option),
)
......@@ -134,7 +134,7 @@ def repr_pytest_looponfailinfo(failreports, rootdirs):
tr.line("### Watching: %s" % (rootdir,), bold=True)
def init_slave_session(channel, args, option_dict):
def init_worker_session(channel, args, option_dict):
import os
import sys
outchannel = channel.gateway.newchannel()
......@@ -153,11 +153,11 @@ def init_slave_session(channel, args, option_dict):
from _pytest.config import Config
config = Config.fromdictargs(option_dict, list(args))
config.args = args
from xdist.looponfail import SlaveFailSession
SlaveFailSession(config, channel).main()
from xdist.looponfail import WorkerFailSession
WorkerFailSession(config, channel).main()
class SlaveFailSession:
class WorkerFailSession:
def __init__(self, config, channel):
self.config = config
self.channel = channel
......@@ -194,11 +194,11 @@ class SlaveFailSession:
self.collection_failed = True
def main(self):
self.DEBUG("SLAVE: received configuration, waiting for command trails")
self.DEBUG("WORKER: received configuration, waiting for command trails")
try:
command = self.channel.receive()
except KeyboardInterrupt:
return # in the slave we can't do much about this
return # in the worker we can't do much about this
self.DEBUG("received", command)
self.current_command = command
self.config.hook.pytest_cmdline_main(config=self.config)
......
......@@ -26,9 +26,12 @@ def pytest_addoption(parser):
help="shortcut for '--dist=load --tx=NUM*popen', "
"you can use 'auto' here for auto detection CPUs number on "
"host system")
group.addoption('--max-slave-restart', action="store", default=None,
help="maximum number of slaves that can be restarted "
"when crashed (set to zero to disable this feature)")
group.addoption('--max-worker-restart', '--max-slave-restart', action="store", default=None,
dest="maxworkerrestart",
help="maximum number of workers that can be restarted "
"when crashed (set to zero to disable this feature)\n"
"'--max-slave-restart' option is deprecated and will be removed in "
"a future release")
group.addoption(
'--dist', metavar="distmode",
action="store", choices=['each', 'load', 'loadscope', 'loadfile', 'no'],
......@@ -129,7 +132,7 @@ def worker_id(request):
"""Return the id of the current worker ('gw0', 'gw1', etc) or 'master'
if running on the master node.
"""
if hasattr(request.config, 'slaveinput'):
return request.config.slaveinput['slaveid']
if hasattr(request.config, 'workerinput'):
return request.config.workerinput['workerid']
else:
return 'master'
......@@ -14,11 +14,11 @@ import _pytest.hookspec
import pytest
class SlaveInteractor:
class WorkerInteractor:
def __init__(self, config, channel):
self.config = config
self.slaveid = config.slaveinput.get('slaveid', "?")
self.log = py.log.Producer("slave-%s" % self.slaveid)
self.workerid = config.workerinput.get('workerid', "?")
self.log = py.log.Producer("worker-%s" % self.workerid)
if not config.option.debug:
py.log.setconsumer(self.log._keywords, None)
self.channel = channel
......@@ -34,14 +34,14 @@ class SlaveInteractor:
def pytest_sessionstart(self, session):
self.session = session
slaveinfo = getinfodict()
self.sendevent("slaveready", slaveinfo=slaveinfo)
workerinfo = getinfodict()
self.sendevent("workerready", workerinfo=workerinfo)
@pytest.hookimpl(hookwrapper=True)
def pytest_sessionfinish(self, exitstatus):
self.config.slaveoutput['exitstatus'] = exitstatus
self.config.workeroutput['exitstatus'] = exitstatus
yield
self.sendevent("slavefinished", slaveoutput=self.config.slaveoutput)
self.sendevent("workerfinished", workeroutput=self.config.workeroutput)
def pytest_collection(self, session):
self.sendevent("collectionstart")
......@@ -103,7 +103,7 @@ class SlaveInteractor:
def pytest_runtest_logreport(self, report):
data = serialize_report(report)
data["item_index"] = self.item_index
data["worker_id"] = self.slaveid
data["worker_id"] = self.workerid
assert self.session.items[self.item_index].nodeid == report.nodeid
self.sendevent("testreport", data=data)
......@@ -185,18 +185,21 @@ def remote_initconfig(option_dict, args):
if __name__ == '__channelexec__':
channel = channel # noqa
slaveinput, args, option_dict = channel.receive()
workerinput, args, option_dict = channel.receive()
importpath = os.getcwd()
sys.path.insert(0, importpath) # XXX only for remote situations
os.environ['PYTHONPATH'] = (
importpath + os.pathsep +
os.environ.get('PYTHONPATH', ''))
os.environ['PYTEST_XDIST_WORKER'] = slaveinput['slaveid']
os.environ['PYTEST_XDIST_WORKER_COUNT'] = str(slaveinput['slavecount'])
os.environ['PYTEST_XDIST_WORKER'] = workerinput['workerid']
os.environ['PYTEST_XDIST_WORKER_COUNT'] = str(workerinput['workercount'])
# os.environ['PYTHONPATH'] = importpath
import py
config = remote_initconfig(option_dict, args)
config.slaveinput = slaveinput
config.slaveoutput = {}
interactor = SlaveInteractor(config, channel)
config.workerinput = workerinput
config.workeroutput = {}
# TODO: deprecated name, backward compatibility only. Remove it in future
config.slaveinput = config.workerinput
config.slaveoutput = config.workeroutput
interactor = WorkerInteractor(config, channel)
config.hook.pytest_cmdline_main(config=config)
from py.log import Producer
from xdist.slavemanage import parse_spec_config
from xdist.workermanage import parse_spec_config
from xdist.report import report_collection_diff
......
......@@ -3,7 +3,7 @@ from itertools import cycle
from py.log import Producer
from _pytest.runner import CollectReport
from xdist.slavemanage import parse_spec_config
from xdist.workermanage import parse_spec_config
from xdist.report import report_collection_diff
......@@ -113,7 +113,7 @@ class LoadScheduling:
From now on the node will be allocated chunks of tests to
execute.
Called by the ``DSession.slave_slaveready`` hook when it
Called by the ``DSession.worker_workerready`` hook when it
successfully bootstraps a new node.
"""
assert node not in self.node2pending
......@@ -123,7 +123,7 @@ class LoadScheduling:
"""Add the collected test items from a node
The collection is stored in the ``.node2collection`` map.
Called by the ``DSession.slave_collectionfinish`` hook.
Called by the ``DSession.worker_collectionfinish`` hook.
"""
assert node in self.node2pending
if self.collection_is_completed:
......@@ -147,7 +147,7 @@ class LoadScheduling:
The duration it took to execute the item is used as a hint to
the scheduler.
This is called by the ``DSession.slave_testreport`` hook.
This is called by the ``DSession.worker_testreport`` hook.
"""
self.node2pending[node].remove(item_index)
self.check_schedule(node, duration=duration)
......@@ -187,8 +187,8 @@ class LoadScheduling:
This should be called either when the node crashed or at
shutdown time. In the former case any pending items assigned
to the node will be re-scheduled. Called by the
``DSession.slave_slavefinished`` and
``DSession.slave_errordown`` hooks.
``DSession.worker_workerfinished`` and
``DSession.worker_errordown`` hooks.
Return the item which was being executing while the node
crashed or None if the node has no more pending items.
......@@ -213,7 +213,7 @@ class LoadScheduling:
``.check_schedule()`` on all nodes so that newly added nodes
will start to be used.
This is called by the ``DSession.slave_collectionfinish`` hook
This is called by the ``DSession.worker_collectionfinish`` hook
if ``.collection_is_completed`` is True.
"""
assert self.collection_is_completed
......
......@@ -3,7 +3,7 @@ from collections import OrderedDict
from _pytest.runner import CollectReport
from py.log import Producer
from xdist.report import report_collection_diff
from xdist.slavemanage import parse_spec_config
from xdist.workermanage import parse_spec_config
class LoadScopeScheduling:
......@@ -151,7 +151,7 @@ class LoadScopeScheduling:
From now on the node will be assigned work units to be executed.
Called by the ``DSession.slave_slaveready`` hook when it successfully
Called by the ``DSession.worker_workerready`` hook when it successfully
bootstraps a new node.
"""
assert node not in self.assigned_work
......@@ -166,8 +166,8 @@ class LoadScopeScheduling:
Called by the hooks:
- ``DSession.slave_slavefinished``.
- ``DSession.slave_errordown``.
- ``DSession.worker_workerfinished``.
- ``DSession.worker_errordown``.
Return the item being executed while the node crashed or None if the
node has no more pending items.
......@@ -206,7 +206,7 @@ class LoadScopeScheduling:
Called by the hook:
- ``DSession.slave_collectionfinish``.
- ``DSession.worker_collectionfinish``.
"""
# Check that add_node() was called on the node before
......@@ -239,7 +239,7 @@ class LoadScopeScheduling:
Called by the hook:
- ``DSession.slave_testreport``.
- ``DSession.worker_testreport``.
"""
nodeid = self.registered_collections[node][item_index]
scope = self._split_scope(nodeid)
......@@ -336,7 +336,7 @@ class LoadScopeScheduling:
If ``.collection_is_completed`` is True, this is called by the hook:
- ``DSession.slave_collectionfinish``.
- ``DSession.worker_collectionfinish``.
"""
assert self.collection_is_completed
......@@ -380,6 +380,10 @@ class LoadScopeScheduling:
for node in self.nodes:
self._assign_work_unit(node)
# Ensure nodes start with at least two work units if possible (#277)
for node in self.nodes:
self._reschedule(node)
# Initial distribution sent all tests, start node shutdown
if not self.workqueue:
for node in self.nodes:
......
......@@ -68,7 +68,7 @@ class NodeManager(object):
gw = self.group.makegateway(spec)
self.config.hook.pytest_xdist_newgateway(gateway=gw)
self.rsync_roots(gw)
node = SlaveController(self, gw, self.config, putevent)
node = WorkerController(self, gw, self.config, putevent)
gw.node = node # keep the node alive
node.setup()
self.trace("started node %r" % node)
......@@ -201,7 +201,7 @@ def make_reltoroot(roots, args):
return result
class SlaveController(object):
class WorkerController(object):
ENDMARK = -1
def __init__(self, nodemanager, gateway, config, putevent):
......@@ -209,11 +209,16 @@ class SlaveController(object):
self.putevent = putevent
self.gateway = gateway
self.config = config
self.slaveinput = {'slaveid': gateway.id,
'slavecount': len(nodemanager.specs)}
self.workerinput = {'workerid': gateway.id,
'workercount': len(nodemanager.specs),
'slaveid': gateway.id,
'slavecount': len(nodemanager.specs)
}
# TODO: deprecated name, backward compatibility only. Remove it in future
self.slaveinput = self.workerinput
self._down = False
self._shutdown_sent = False