#234 Added master/worker terminology
This commit is contained in:
@@ -196,23 +196,23 @@ class TestDistribution:
|
||||
testdir.makeconftest("""
|
||||
# This hook only called on master.
|
||||
def pytest_configure_node(node):
|
||||
node.slaveinput['a'] = 42
|
||||
node.slaveinput['b'] = 7
|
||||
node.workerinput['a'] = 42
|
||||
node.workerinput['b'] = 7
|
||||
|
||||
def pytest_configure(config):
|
||||
# this attribute is only set on slaves
|
||||
if hasattr(config, 'slaveinput'):
|
||||
a = config.slaveinput['a']
|
||||
b = config.slaveinput['b']
|
||||
# this attribute is only set on workers
|
||||
if hasattr(config, 'workerinput'):
|
||||
a = config.workerinput['a']
|
||||
b = config.workerinput['b']
|
||||
r = a + b
|
||||
config.slaveoutput['r'] = r
|
||||
config.workeroutput['r'] = r
|
||||
|
||||
# This hook only called on master.
|
||||
def pytest_testnodedown(node, error):
|
||||
node.config.calc_result = node.slaveoutput['r']
|
||||
node.config.calc_result = node.workeroutput['r']
|
||||
|
||||
def pytest_terminal_summary(terminalreporter):
|
||||
if not hasattr(terminalreporter.config, 'slaveinput'):
|
||||
if not hasattr(terminalreporter.config, 'workerinput'):
|
||||
calc_result = terminalreporter.config.calc_result
|
||||
terminalreporter._tw.sep('-',
|
||||
'calculated result is %s' % calc_result)
|
||||
@@ -232,12 +232,12 @@ class TestDistribution:
|
||||
""")
|
||||
testdir.makeconftest("""
|
||||
def pytest_sessionfinish(session):
|
||||
# on the slave
|
||||
if hasattr(session.config, 'slaveoutput'):
|
||||
session.config.slaveoutput['s2'] = 42
|
||||
# on the worker
|
||||
if hasattr(session.config, 'workeroutput'):
|
||||
session.config.workeroutput['s2'] = 42
|
||||
# on the master
|
||||
def pytest_testnodedown(node, error):
|
||||
assert node.slaveoutput['s2'] == 42
|
||||
assert node.workeroutput['s2'] == 42
|
||||
print ("s2call-finished")
|
||||
""")
|
||||
args = ["-n1", "--debug"]
|
||||
@@ -411,7 +411,7 @@ def test_teardownfails_one_function(testdir):
|
||||
def test_terminate_on_hangingnode(testdir):
|
||||
p = testdir.makeconftest("""
|
||||
def pytest_sessionfinish(session):
|
||||
if session.nodeid == "my": # running on slave
|
||||
if session.nodeid == "my": # running on worker
|
||||
import time
|
||||
time.sleep(3)
|
||||
""")
|
||||
@@ -429,15 +429,15 @@ def test_session_hooks(testdir):
|
||||
def pytest_sessionstart(session):
|
||||
sys.pytestsessionhooks = session
|
||||
def pytest_sessionfinish(session):
|
||||
if hasattr(session.config, 'slaveinput'):
|
||||
name = "slave"
|
||||
if hasattr(session.config, 'workerinput'):
|
||||
name = "worker"
|
||||
else:
|
||||
name = "master"
|
||||
f = open(name, "w")
|
||||
f.write("xy")
|
||||
f.close()
|
||||
# let's fail on the slave
|
||||
if name == "slave":
|
||||
# let's fail on the worker
|
||||
if name == "worker":
|
||||
raise ValueError(42)
|
||||
""")
|
||||
p = testdir.makepyfile("""
|
||||
@@ -453,14 +453,14 @@ def test_session_hooks(testdir):
|
||||
assert not result.ret
|
||||
d = result.parseoutcomes()
|
||||
assert d['passed'] == 1
|
||||
assert testdir.tmpdir.join("slave").check()
|
||||
assert testdir.tmpdir.join("worker").check()
|
||||
assert testdir.tmpdir.join("master").check()
|
||||
|
||||
|
||||
def test_session_testscollected(testdir):
|
||||
"""
|
||||
Make sure master node is updating the session object with the number
|
||||
of tests collected from the slaves.
|
||||
of tests collected from the workers.
|
||||
"""
|
||||
testdir.makepyfile(test_foo="""
|
||||
import pytest
|
||||
@@ -714,7 +714,7 @@ class TestNodeFailure:
|
||||
"*2 failed*2 passed*",
|
||||
])
|
||||
|
||||
def test_max_slave_restart(self, testdir):
|
||||
def test_max_worker_restart(self, testdir):
|
||||
f = testdir.makepyfile("""
|
||||
import os
|
||||
def test_a(): pass
|
||||
@@ -731,7 +731,7 @@ class TestNodeFailure:
|
||||
"*2 failed*2 passed*",
|
||||
])
|
||||
|
||||
def test_max_slave_restart_die(self, testdir):
|
||||
def test_max_worker_restart_die(self, testdir):
|
||||
f = testdir.makepyfile("""
|
||||
import os
|
||||
os._exit(1)
|
||||
|
||||
@@ -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([
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import py
|
||||
import execnet
|
||||
from xdist.slavemanage import NodeManager
|
||||
from xdist.workermanage import NodeManager
|
||||
|
||||
|
||||
def test_dist_incompatibility_messages(testdir):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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,7 +44,7 @@ class SlaveSetup:
|
||||
class DummyMananger:
|
||||
specs = [0, 1]
|
||||
|
||||
self.slp = SlaveController(DummyMananger, self.gateway, config,
|
||||
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"
|
||||
|
||||
|
||||
|
||||
@@ -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']")
|
||||
|
||||
Reference in New Issue
Block a user