diff --git a/xdist/dsession.py b/xdist/dsession.py index 4a998c0..7f03326 100644 --- a/xdist/dsession.py +++ b/xdist/dsession.py @@ -485,17 +485,6 @@ class DSession: self.trdist = TerminalDistReporter(config) config.pluginmanager.register(self.trdist, "terminaldistreporter") - self.sched = None - dist = self.config.getvalue("dist") - if dist == "load": - self.ScheduleCls = LoadScheduling - elif dist == "each": - self.ScheduleCls = EachScheduling - else: - mod_name, cls_name = dist.rsplit('.', 1) - mod = __import__(mod_name) - self.ScheduleCls = getattr(mod, cls_name) - @property def session_finished(self): """Return True if the distributed session has finished @@ -532,11 +521,22 @@ class DSession: # prohibit collection of test items in master process return True + @pytest.hookimpl(trylast=True) + def pytest_xdist_make_scheduler(self, numnodes, log, config): + dist = config.getvalue("dist") + if dist == "load": + return LoadScheduling(numnodes, log=log, config=config) + elif dist == "each": + return EachScheduling(numnodes, log=log, config=config) + def pytest_runtestloop(self): numnodes = len(self.nodemanager.specs) + self.sched = self.config.hook.pytest_xdist_make_scheduler(numnodes=numnodes, + log=self.log, + config=self.config) + assert self.sched is not None + self.shouldstop = False - self.sched = self.ScheduleCls(numnodes, log=self.log, - config=self.config) while not self.session_finished: self.loop_once() if self.shouldstop: diff --git a/xdist/newhooks.py b/xdist/newhooks.py index d31aed8..5942f29 100644 --- a/xdist/newhooks.py +++ b/xdist/newhooks.py @@ -11,6 +11,7 @@ must be taken in plugins in case ``xdist`` is not installed. Please see: http://pytest.org/latest/writing_plugins.html#optionally-using-hooks-from-3rd-party-plugins """ +import pytest def pytest_xdist_setupnodes(config, specs): @@ -44,3 +45,9 @@ def pytest_testnodedown(node, error): def pytest_xdist_node_collection_finished(node, ids): """called by the master node when a node finishes collecting. """ + + +@pytest.hookspec(firstresult=True) +def pytest_xdist_make_scheduler(numnodes, log, config): + """Return a node scheduler implementation, or None. + """ diff --git a/xdist/plugin.py b/xdist/plugin.py index a144f20..dc721da 100644 --- a/xdist/plugin.py +++ b/xdist/plugin.py @@ -37,8 +37,6 @@ def pytest_addoption(parser): "each: send each test to each available environment.\n\n" "load: send each test to available environment.\n\n" "(default) no: run tests inprocess, don't distribute.")) - group._addoption('--dc', dest='distcustom', - help="Custom scheduler implementation") group._addoption( '--tx', dest="tx", action="append", default=[], metavar="xspec", @@ -101,8 +99,6 @@ def pytest_cmdline_main(config): config.option.tx = ['popen'] * config.option.numprocesses if config.option.distload: config.option.dist = "load" - if config.option.distcustom: - config.option.dist = config.option.distcustom val = config.getvalue if not val("collectonly"): usepdb = config.getoption('usepdb') # a core option diff --git a/xdist/remote.py b/xdist/remote.py index 31dcc19..40bbeac 100644 --- a/xdist/remote.py +++ b/xdist/remote.py @@ -131,7 +131,6 @@ def remote_initconfig(option_dict, args): config.option.usepdb = False config.option.dist = "no" config.option.distload = False - config.option.distcustom = None config.option.numprocesses = None config.args = args return config