Unified scheduler class interface
This commit is contained in:
@@ -49,10 +49,11 @@ def dumpqueue(queue):
|
|||||||
|
|
||||||
|
|
||||||
class TestEachScheduling:
|
class TestEachScheduling:
|
||||||
def test_schedule_load_simple(self):
|
def test_schedule_load_simple(self, testdir):
|
||||||
node1 = MockNode()
|
node1 = MockNode()
|
||||||
node2 = MockNode()
|
node2 = MockNode()
|
||||||
sched = EachScheduling(2)
|
config = testdir.parseconfig()
|
||||||
|
sched = EachScheduling(2, config)
|
||||||
sched.addnode(node1)
|
sched.addnode(node1)
|
||||||
sched.addnode(node2)
|
sched.addnode(node2)
|
||||||
collection = ["a.py::test_1", ]
|
collection = ["a.py::test_1", ]
|
||||||
@@ -72,9 +73,10 @@ class TestEachScheduling:
|
|||||||
sched.remove_item(node2, 0)
|
sched.remove_item(node2, 0)
|
||||||
assert sched.tests_finished()
|
assert sched.tests_finished()
|
||||||
|
|
||||||
def test_schedule_remove_node(self):
|
def test_schedule_remove_node(self, testdir):
|
||||||
node1 = MockNode()
|
node1 = MockNode()
|
||||||
sched = EachScheduling(1)
|
config = testdir.parseconfig()
|
||||||
|
sched = EachScheduling(1, config)
|
||||||
sched.addnode(node1)
|
sched.addnode(node1)
|
||||||
collection = ["a.py::test_1", ]
|
collection = ["a.py::test_1", ]
|
||||||
assert not sched.collection_is_completed
|
assert not sched.collection_is_completed
|
||||||
@@ -90,8 +92,9 @@ class TestEachScheduling:
|
|||||||
|
|
||||||
|
|
||||||
class TestLoadScheduling:
|
class TestLoadScheduling:
|
||||||
def test_schedule_load_simple(self):
|
def test_schedule_load_simple(self, testdir):
|
||||||
sched = LoadScheduling(2)
|
config = testdir.parseconfig()
|
||||||
|
sched = LoadScheduling(2, config)
|
||||||
sched.addnode(MockNode())
|
sched.addnode(MockNode())
|
||||||
sched.addnode(MockNode())
|
sched.addnode(MockNode())
|
||||||
node1, node2 = sched.nodes
|
node1, node2 = sched.nodes
|
||||||
@@ -113,8 +116,9 @@ class TestLoadScheduling:
|
|||||||
sched.remove_item(node1, node1.sent[0])
|
sched.remove_item(node1, node1.sent[0])
|
||||||
assert sched.tests_finished()
|
assert sched.tests_finished()
|
||||||
|
|
||||||
def test_init_distribute_batch_size(self):
|
def test_init_distribute_batch_size(self, testdir):
|
||||||
sched = LoadScheduling(2)
|
config = testdir.parseconfig()
|
||||||
|
sched = LoadScheduling(2, config)
|
||||||
sched.addnode(MockNode())
|
sched.addnode(MockNode())
|
||||||
sched.addnode(MockNode())
|
sched.addnode(MockNode())
|
||||||
node1, node2 = sched.nodes
|
node1, node2 = sched.nodes
|
||||||
@@ -139,8 +143,9 @@ class TestLoadScheduling:
|
|||||||
assert node1.sent == [0, 2, 4, 5]
|
assert node1.sent == [0, 2, 4, 5]
|
||||||
assert not sched.pending
|
assert not sched.pending
|
||||||
|
|
||||||
def test_init_distribute_fewer_tests_than_nodes(self):
|
def test_init_distribute_fewer_tests_than_nodes(self, testdir):
|
||||||
sched = LoadScheduling(2)
|
config = testdir.parseconfig()
|
||||||
|
sched = LoadScheduling(2, config)
|
||||||
sched.addnode(MockNode())
|
sched.addnode(MockNode())
|
||||||
sched.addnode(MockNode())
|
sched.addnode(MockNode())
|
||||||
sched.addnode(MockNode())
|
sched.addnode(MockNode())
|
||||||
@@ -158,8 +163,9 @@ class TestLoadScheduling:
|
|||||||
assert sent3 == []
|
assert sent3 == []
|
||||||
assert not sched.pending
|
assert not sched.pending
|
||||||
|
|
||||||
def test_init_distribute_fewer_than_two_tests_per_node(self):
|
def test_init_distribute_fewer_than_two_tests_per_node(self, testdir):
|
||||||
sched = LoadScheduling(2)
|
config = testdir.parseconfig()
|
||||||
|
sched = LoadScheduling(2, config)
|
||||||
sched.addnode(MockNode())
|
sched.addnode(MockNode())
|
||||||
sched.addnode(MockNode())
|
sched.addnode(MockNode())
|
||||||
sched.addnode(MockNode())
|
sched.addnode(MockNode())
|
||||||
@@ -177,9 +183,10 @@ class TestLoadScheduling:
|
|||||||
assert sent3 == [2]
|
assert sent3 == [2]
|
||||||
assert not sched.pending
|
assert not sched.pending
|
||||||
|
|
||||||
def test_add_remove_node(self):
|
def test_add_remove_node(self, testdir):
|
||||||
node = MockNode()
|
node = MockNode()
|
||||||
sched = LoadScheduling(1)
|
config = testdir.parseconfig()
|
||||||
|
sched = LoadScheduling(1, config)
|
||||||
sched.addnode(node)
|
sched.addnode(node)
|
||||||
collection = ["test_file.py::test_func"]
|
collection = ["test_file.py::test_func"]
|
||||||
sched.addnode_collection(node, collection)
|
sched.addnode_collection(node, collection)
|
||||||
@@ -211,7 +218,7 @@ class TestLoadScheduling:
|
|||||||
config.pluginmanager.register(collect_hook, "collect_hook")
|
config.pluginmanager.register(collect_hook, "collect_hook")
|
||||||
node1 = MockNode()
|
node1 = MockNode()
|
||||||
node2 = MockNode()
|
node2 = MockNode()
|
||||||
sched = LoadScheduling(2, config=config)
|
sched = LoadScheduling(2, config)
|
||||||
sched.addnode(node1)
|
sched.addnode(node1)
|
||||||
sched.addnode(node2)
|
sched.addnode(node2)
|
||||||
sched.addnode_collection(node1, ["a.py::test_1"])
|
sched.addnode_collection(node1, ["a.py::test_1"])
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class EachScheduling:
|
|||||||
assigned the remaining items from the removed node.
|
assigned the remaining items from the removed node.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, numnodes, log=None, config=None):
|
def __init__(self, numnodes, config, log=None):
|
||||||
self.numnodes = numnodes
|
self.numnodes = numnodes
|
||||||
self.node2collection = {}
|
self.node2collection = {}
|
||||||
self.node2pending = {}
|
self.node2pending = {}
|
||||||
@@ -181,7 +181,7 @@ class LoadScheduling:
|
|||||||
:config: Config object, used for handling hooks.
|
:config: Config object, used for handling hooks.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, numnodes, log=None, config=None):
|
def __init__(self, numnodes, config, log=None):
|
||||||
self.numnodes = numnodes
|
self.numnodes = numnodes
|
||||||
self.node2collection = {}
|
self.node2collection = {}
|
||||||
self.node2pending = {}
|
self.node2pending = {}
|
||||||
@@ -466,6 +466,8 @@ class DSession:
|
|||||||
self.log = py.log.Producer("dsession")
|
self.log = py.log.Producer("dsession")
|
||||||
if not config.option.debug:
|
if not config.option.debug:
|
||||||
py.log.setconsumer(self.log._keywords, None)
|
py.log.setconsumer(self.log._keywords, None)
|
||||||
|
self.nodemanager = None
|
||||||
|
self.sched = None
|
||||||
self.shuttingdown = False
|
self.shuttingdown = False
|
||||||
self.countfailures = 0
|
self.countfailures = 0
|
||||||
self.maxfail = config.getvalue("maxfail")
|
self.maxfail = config.getvalue("maxfail")
|
||||||
@@ -522,19 +524,19 @@ class DSession:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
@pytest.mark.trylast
|
@pytest.mark.trylast
|
||||||
def pytest_xdist_make_scheduler(self, numnodes, log, config):
|
def pytest_xdist_make_scheduler(self, numnodes, config, log):
|
||||||
dist = config.getvalue("dist")
|
dist = config.getvalue("dist")
|
||||||
if dist == "load":
|
if dist == "load":
|
||||||
return LoadScheduling(numnodes, log=log, config=config)
|
return LoadScheduling(numnodes, config, log)
|
||||||
elif dist == "each":
|
elif dist == "each":
|
||||||
return EachScheduling(numnodes, log=log, config=config)
|
return EachScheduling(numnodes, config, log)
|
||||||
|
|
||||||
def pytest_runtestloop(self):
|
def pytest_runtestloop(self):
|
||||||
numnodes = len(self.nodemanager.specs)
|
numnodes = len(self.nodemanager.specs)
|
||||||
self.sched = self.config.hook.pytest_xdist_make_scheduler(
|
self.sched = self.config.hook.pytest_xdist_make_scheduler(
|
||||||
numnodes=numnodes,
|
numnodes=numnodes,
|
||||||
log=self.log,
|
config=self.config,
|
||||||
config=self.config
|
log=self.log
|
||||||
)
|
)
|
||||||
assert self.sched is not None
|
assert self.sched is not None
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,5 @@ def pytest_xdist_node_collection_finished(node, ids):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.firstresult
|
@pytest.mark.firstresult
|
||||||
def pytest_xdist_make_scheduler(numnodes, log, config):
|
def pytest_xdist_make_scheduler(numnodes, config, log):
|
||||||
"""Return a node scheduler implementation, or None.
|
""" return a node scheduler implementation """
|
||||||
"""
|
|
||||||
|
|||||||
Reference in New Issue
Block a user