Made EachScheduling.numnodes countable from config

This commit is contained in:
Michael Elovskikh
2017-02-14 20:19:41 +05:00
parent a2aaf9bf04
commit 6200123fac
4 changed files with 43 additions and 40 deletions

View File

@@ -52,8 +52,8 @@ class TestEachScheduling:
def test_schedule_load_simple(self, testdir): def test_schedule_load_simple(self, testdir):
node1 = MockNode() node1 = MockNode()
node2 = MockNode() node2 = MockNode()
config = testdir.parseconfig() config = testdir.parseconfig("--tx=2*popen")
sched = EachScheduling(2, config) sched = EachScheduling(config)
sched.addnode(node1) sched.addnode(node1)
sched.addnode(node2) sched.addnode(node2)
collection = ["a.py::test_1", ] collection = ["a.py::test_1", ]
@@ -75,8 +75,8 @@ class TestEachScheduling:
def test_schedule_remove_node(self, testdir): def test_schedule_remove_node(self, testdir):
node1 = MockNode() node1 = MockNode()
config = testdir.parseconfig() config = testdir.parseconfig("--tx=popen")
sched = EachScheduling(1, config) sched = EachScheduling(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
@@ -93,8 +93,8 @@ class TestEachScheduling:
class TestLoadScheduling: class TestLoadScheduling:
def test_schedule_load_simple(self, testdir): def test_schedule_load_simple(self, testdir):
config = testdir.parseconfig() config = testdir.parseconfig("--tx=2*popen")
sched = LoadScheduling(2, config) sched = LoadScheduling(config)
sched.addnode(MockNode()) sched.addnode(MockNode())
sched.addnode(MockNode()) sched.addnode(MockNode())
node1, node2 = sched.nodes node1, node2 = sched.nodes
@@ -117,8 +117,8 @@ class TestLoadScheduling:
assert sched.tests_finished() assert sched.tests_finished()
def test_schedule_batch_size(self, testdir): def test_schedule_batch_size(self, testdir):
config = testdir.parseconfig() config = testdir.parseconfig("--tx=2*popen")
sched = LoadScheduling(2, config) sched = LoadScheduling(config)
sched.addnode(MockNode()) sched.addnode(MockNode())
sched.addnode(MockNode()) sched.addnode(MockNode())
node1, node2 = sched.nodes node1, node2 = sched.nodes
@@ -144,8 +144,8 @@ class TestLoadScheduling:
assert not sched.pending assert not sched.pending
def test_schedule_fewer_tests_than_nodes(self, testdir): def test_schedule_fewer_tests_than_nodes(self, testdir):
config = testdir.parseconfig() config = testdir.parseconfig("--tx=2*popen")
sched = LoadScheduling(2, config) sched = LoadScheduling(config)
sched.addnode(MockNode()) sched.addnode(MockNode())
sched.addnode(MockNode()) sched.addnode(MockNode())
sched.addnode(MockNode()) sched.addnode(MockNode())
@@ -164,8 +164,8 @@ class TestLoadScheduling:
assert not sched.pending assert not sched.pending
def test_schedule_fewer_than_two_tests_per_node(self, testdir): def test_schedule_fewer_than_two_tests_per_node(self, testdir):
config = testdir.parseconfig() config = testdir.parseconfig("--tx=2*popen")
sched = LoadScheduling(2, config) sched = LoadScheduling(config)
sched.addnode(MockNode()) sched.addnode(MockNode())
sched.addnode(MockNode()) sched.addnode(MockNode())
sched.addnode(MockNode()) sched.addnode(MockNode())
@@ -185,8 +185,8 @@ class TestLoadScheduling:
def test_add_remove_node(self, testdir): def test_add_remove_node(self, testdir):
node = MockNode() node = MockNode()
config = testdir.parseconfig() config = testdir.parseconfig("--tx=popen")
sched = LoadScheduling(1, config) sched = LoadScheduling(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)
@@ -214,11 +214,11 @@ class TestLoadScheduling:
self.reports.append(report) self.reports.append(report)
collect_hook = CollectHook() collect_hook = CollectHook()
config = testdir.parseconfig() config = testdir.parseconfig("--tx=2*popen")
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) sched = LoadScheduling(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"])

View File

@@ -4,7 +4,7 @@ from _pytest.runner import CollectReport
import pytest import pytest
import py import py
from xdist.slavemanage import NodeManager from xdist.slavemanage import NodeManager, parse_spec_config
queue = py.builtin._tryimport('queue', 'Queue') queue = py.builtin._tryimport('queue', 'Queue')
@@ -24,8 +24,9 @@ class EachScheduling:
assigned the remaining items from the removed node. assigned the remaining items from the removed node.
""" """
def __init__(self, numnodes, config, log=None): def __init__(self, config, log=None):
self.numnodes = numnodes self.config = config
self.numnodes = len(parse_spec_config(config))
self.node2collection = {} self.node2collection = {}
self.node2pending = {} self.node2pending = {}
self._started = [] self._started = []
@@ -181,8 +182,8 @@ class LoadScheduling:
:config: Config object, used for handling hooks. :config: Config object, used for handling hooks.
""" """
def __init__(self, numnodes, config, log=None): def __init__(self, config, log=None):
self.numnodes = numnodes self.numnodes = len(parse_spec_config(config))
self.node2collection = {} self.node2collection = {}
self.node2pending = {} self.node2pending = {}
self.pending = [] self.pending = []
@@ -522,17 +523,15 @@ class DSession:
return True return True
@pytest.mark.trylast @pytest.mark.trylast
def pytest_xdist_make_scheduler(self, numnodes, config, log): def pytest_xdist_make_scheduler(self, config, log):
dist = config.getvalue("dist") dist = config.getvalue("dist")
if dist == "load": if dist == "load":
return LoadScheduling(numnodes, config, log) return LoadScheduling(config, log)
elif dist == "each": elif dist == "each":
return EachScheduling(numnodes, config, log) return EachScheduling(config, log)
def pytest_runtestloop(self): def pytest_runtestloop(self):
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,
config=self.config, config=self.config,
log=self.log log=self.log
) )

View File

@@ -48,5 +48,5 @@ def pytest_xdist_node_collection_finished(node, ids):
@pytest.mark.firstresult @pytest.mark.firstresult
def pytest_xdist_make_scheduler(numnodes, config, log): def pytest_xdist_make_scheduler(config, log):
""" return a node scheduler implementation """ """ return a node scheduler implementation """

View File

@@ -10,6 +10,22 @@ import xdist.remote
from _pytest import runner # XXX load dynamically from _pytest import runner # XXX load dynamically
def parse_spec_config(config):
xspeclist = []
for xspec in config.getvalue("tx"):
i = xspec.find("*")
try:
num = int(xspec[:i])
except ValueError:
xspeclist.append(xspec)
else:
xspeclist.extend([xspec[i + 1:]] * num)
if not xspeclist:
raise pytest.UsageError(
"MISSING test execution (tx) nodes: please specify --tx")
return xspeclist
class NodeManager(object): class NodeManager(object):
EXIT_TIMEOUT = 10 EXIT_TIMEOUT = 10
DEFAULT_IGNORES = ['.*', '*.pyc', '*.pyo', '*~'] DEFAULT_IGNORES = ['.*', '*.pyc', '*.pyo', '*~']
@@ -62,19 +78,7 @@ class NodeManager(object):
self.group.terminate(self.EXIT_TIMEOUT) self.group.terminate(self.EXIT_TIMEOUT)
def _getxspecs(self): def _getxspecs(self):
xspeclist = [] return [execnet.XSpec(x) for x in parse_spec_config(self.config)]
for xspec in self.config.getvalue("tx"):
i = xspec.find("*")
try:
num = int(xspec[:i])
except ValueError:
xspeclist.append(xspec)
else:
xspeclist.extend([xspec[i+1:]] * num)
if not xspeclist:
raise pytest.UsageError(
"MISSING test execution (tx) nodes: please specify --tx")
return [execnet.XSpec(x) for x in xspeclist]
def _getrsyncdirs(self): def _getrsyncdirs(self):
for spec in self.specs: for spec in self.specs: