Compare commits

...

8 Commits

Author SHA1 Message Date
Bruno Oliveira
bfd6029102 Release 1.24.0 2018-10-18 07:55:54 -03:00
Bruno Oliveira
3f5a8eeb7f Merge pull request #356 from pristupa/maxprocessing-option
Add --maxprocesses option to use with --numprocesses=auto
2018-10-18 07:54:02 -03:00
Bruno Oliveira
d5b61e72d4 Merge pull request #351 from cybojanek/master
Issue node shutdown on empty workload
2018-10-18 07:53:52 -03:00
Bruno Oliveira
f224c4b00e Fix CHANGELOG formatting 2018-10-17 09:19:48 -03:00
Pavel Pristupa
ddefd3f453 Call group.addoption() instead of _addoption() when parsing command-line arguments
Fix #337
2018-10-17 17:48:47 +07:00
Pavel Pristupa
5ce8a6ec1a Add maxprocesses option to limit the maximum number of workers when using numprocesses=auto
Fix #337
2018-10-17 17:08:56 +07:00
Jan Kasiak
fe06f27b8b Issue node shutdown on empty workload
Remote pytest_runtestloop requires at least 2 tests, or a test
and a shutdown command. In case of inter test locking, for
example using a file lock, the tests could deadlock, since the
shutdown command would not be enqueued, and the last test of a
worker would never finish, and would not allow another worker
to make progress.
2018-09-30 15:39:04 -04:00
Bruno Oliveira
86e2fb5a5a Merge pull request #347 from nicoddemus/release-1.23.2
Release 1.23.2
2018-09-28 07:34:43 -03:00
9 changed files with 88 additions and 1 deletions

View File

@@ -1,3 +1,18 @@
pytest-xdist 1.24.0 (2018-10-18)
================================
Features
--------
- `#337 <https://github.com/pytest-dev/pytest-xdist/issues/337>`_: New ``--maxprocesses`` command-line option that limits the maximum number of workers when using ``--numprocesses=auto``.
Bug Fixes
---------
- `#351 <https://github.com/pytest-dev/pytest-xdist/issues/351>`_: Fix scheduling deadlock in case of inter-test locking.
pytest-xdist 1.23.2 (2018-09-28)
================================

View File

@@ -1132,6 +1132,56 @@ class TestFileScope:
assert c1 == c2
class TestLocking:
_test_content = """
class TestClassName%s(object):
@classmethod
def setup_class(cls):
FILE_LOCK.acquire()
@classmethod
def teardown_class(cls):
FILE_LOCK.release()
def test_a(self):
pass
def test_b(self):
pass
def test_c(self):
pass
"""
test_file1 = """
import filelock
FILE_LOCK = filelock.FileLock("test.lock")
""" + (
(_test_content * 4) % ("A", "B", "C", "D")
)
@pytest.mark.parametrize("scope", ["each", "load", "loadscope", "loadfile", "no"])
def test_single_file(self, testdir, scope):
testdir.makepyfile(test_a=self.test_file1)
result = testdir.runpytest("-n2", "--dist=%s" % scope, "-v")
result.assert_outcomes(passed=(12 if scope != "each" else 12 * 2))
@pytest.mark.parametrize("scope", ["each", "load", "loadscope", "loadfile", "no"])
def test_multi_file(self, testdir, scope):
testdir.makepyfile(
test_a=self.test_file1,
test_b=self.test_file1,
test_c=self.test_file1,
test_d=self.test_file1,
)
result = testdir.runpytest("-n2", "--dist=%s" % scope, "-v")
result.assert_outcomes(passed=(48 if scope != "each" else 48 * 2))
def parse_tests_and_workers_from_output(lines):
result = []
for line in lines:

View File

@@ -25,6 +25,10 @@ def test_dist_options(testdir):
check_options(config)
assert config.option.dist == "load"
assert config.option.tx == ["popen"] * 2
config = testdir.parseconfigure("--numprocesses", "3", "--maxprocesses", "2")
check_options(config)
assert config.option.dist == "load"
assert config.option.tx == ["popen"] * 2
config = testdir.parseconfigure("-d")
check_options(config)
assert config.option.dist == "load"

View File

@@ -23,6 +23,7 @@ deps =
pytestmaster: git+https://github.com/pytest-dev/pytest.git@master
pytestfeatures: git+https://github.com/pytest-dev/pytest.git@features
pexpect: pexpect
filelock
platform=
pexpect: linux|darwin
commands=

View File

@@ -47,6 +47,14 @@ def pytest_addoption(parser):
"you can use 'auto' here for auto detection CPUs number on "
"host system",
)
group.addoption(
"--maxprocesses",
dest="maxprocesses",
metavar="maxprocesses",
action="store",
type=int,
help="limit the maximum number of workers to process the tests when using --numprocesses=auto",
)
group.addoption(
"--max-worker-restart",
"--max-slave-restart",
@@ -172,7 +180,10 @@ def pytest_cmdline_main(config):
if config.option.numprocesses:
if config.option.dist == "no":
config.option.dist = "load"
config.option.tx = ["popen"] * config.option.numprocesses
numprocesses = config.option.numprocesses
if config.option.maxprocesses:
numprocesses = min(numprocesses, config.option.maxprocesses)
config.option.tx = ["popen"] * numprocesses
if config.option.distload:
config.option.dist = "load"
val = config.getvalue

View File

@@ -234,6 +234,7 @@ def remote_initconfig(option_dict, args):
config.option.dist = "no"
config.option.distload = False
config.option.numprocesses = None
config.option.maxprocesses = None
config.args = args
return config

View File

@@ -126,6 +126,7 @@ class EachScheduling(object):
if not pending:
pending[:] = range(len(self.node2collection[node]))
node.send_runtest_all()
node.shutdown()
else:
node.send_runtest_some(pending)
self._started.append(node)

View File

@@ -178,6 +178,9 @@ class LoadScheduling(object):
return
num_send = items_per_node_max - len(node_pending)
self._send_tests(node, num_send)
else:
node.shutdown()
self.log("num items waiting for node:", len(self.pending))
def remove_node(self, node):

View File

@@ -306,6 +306,7 @@ class LoadScopeScheduling(object):
# Check that more work is available
if not self.workqueue:
node.shutdown()
return
self.log("Number of units waiting for node:", len(self.workqueue))