From bd3c7dba8bb2f6ae0b5305b6f0f406637ce8b345 Mon Sep 17 00:00:00 2001 From: lmtierney Date: Thu, 8 Feb 2018 19:38:18 -0600 Subject: [PATCH 1/2] Ensure loadscope and loadfile work when the first scope has one work unit --- changelog/257.bugfix | 1 + testing/acceptance_test.py | 64 ++++++++++++++++++++++++++++++++++++ xdist/scheduler/loadscope.py | 4 +++ 3 files changed, 69 insertions(+) create mode 100644 changelog/257.bugfix diff --git a/changelog/257.bugfix b/changelog/257.bugfix new file mode 100644 index 0000000..6b3cde6 --- /dev/null +++ b/changelog/257.bugfix @@ -0,0 +1 @@ +Fix issue when using ``loadscope`` or ``loadfile`` where tests would fail to start if the first scope had only one test. diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 56ecc0b..2ecff57 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -888,6 +888,38 @@ class TestLoadScope: assert get_workers_and_test_count_by_prefix( 'test_a.py::TestB', result.outlines) in ({'gw0': 10}, {'gw1': 10}) + def test_module_single_start(self, testdir): + test_file1 = """ + import pytest + def test(): + pass + """ + test_file2 = """ + import pytest + def test_1(): + pass + def test_2(): + pass + """ + testdir.makepyfile( + test_a=test_file1, + test_b=test_file1, + test_c=test_file2 + ) + result = testdir.runpytest('-n2', '--dist=loadscope', '-v') + a = get_workers_and_test_count_by_prefix('test_a.py::test', + result.outlines) + b = get_workers_and_test_count_by_prefix('test_b.py::test', + result.outlines) + c1 = get_workers_and_test_count_by_prefix('test_c.py::test_1', + result.outlines) + c2 = get_workers_and_test_count_by_prefix('test_c.py::test_2', + result.outlines) + assert a in ({'gw0': 1}, {'gw1': 1}) + assert b in ({'gw0': 1}, {'gw1': 1}) + assert a.items() != b.items() + assert c1 == c2 + class TestFileScope: @@ -943,6 +975,38 @@ class TestFileScope: assert test_b_workers_and_test_count in ({'gw0': 10}, {'gw1': 0}) or \ test_b_workers_and_test_count in ({'gw0': 0}, {'gw1': 10}) + def test_module_single_start(self, testdir): + test_file1 = """ + import pytest + def test(): + pass + """ + test_file2 = """ + import pytest + def test_1(): + pass + def test_2(): + pass + """ + testdir.makepyfile( + test_a=test_file1, + test_b=test_file1, + test_c=test_file2 + ) + result = testdir.runpytest('-n2', '--dist=loadfile', '-v') + a = get_workers_and_test_count_by_prefix('test_a.py::test', + result.outlines) + b = get_workers_and_test_count_by_prefix('test_b.py::test', + result.outlines) + c1 = get_workers_and_test_count_by_prefix('test_c.py::test_1', + result.outlines) + c2 = get_workers_and_test_count_by_prefix('test_c.py::test_2', + result.outlines) + assert a in ({'gw0': 1}, {'gw1': 1}) + assert b in ({'gw0': 1}, {'gw1': 1}) + assert a.items() != b.items() + assert c1 == c2 + def parse_tests_and_workers_from_output(lines): result = [] diff --git a/xdist/scheduler/loadscope.py b/xdist/scheduler/loadscope.py index 4c51f7d..0677e3e 100644 --- a/xdist/scheduler/loadscope.py +++ b/xdist/scheduler/loadscope.py @@ -380,6 +380,10 @@ class LoadScopeScheduling: for node in self.nodes: self._assign_work_unit(node) + # Ensure nodes start with at least two work units if possible + for node in self.nodes: + self._reschedule(node) + # Initial distribution sent all tests, start node shutdown if not self.workqueue: for node in self.nodes: From 1be8a463ffe1ad06987442d210032a1dbc4af968 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Fri, 16 Feb 2018 20:13:56 -0200 Subject: [PATCH 2/2] Add docstring to tests for #277 --- testing/acceptance_test.py | 2 ++ xdist/scheduler/loadscope.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 2ecff57..697070e 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -889,6 +889,7 @@ class TestLoadScope: 'test_a.py::TestB', result.outlines) in ({'gw0': 10}, {'gw1': 10}) def test_module_single_start(self, testdir): + """Fix test suite never finishing in case all workers start with a single test (#277).""" test_file1 = """ import pytest def test(): @@ -976,6 +977,7 @@ class TestFileScope: test_b_workers_and_test_count in ({'gw0': 0}, {'gw1': 10}) def test_module_single_start(self, testdir): + """Fix test suite never finishing in case all workers start with a single test (#277).""" test_file1 = """ import pytest def test(): diff --git a/xdist/scheduler/loadscope.py b/xdist/scheduler/loadscope.py index 0677e3e..3c8381a 100644 --- a/xdist/scheduler/loadscope.py +++ b/xdist/scheduler/loadscope.py @@ -380,7 +380,7 @@ class LoadScopeScheduling: for node in self.nodes: self._assign_work_unit(node) - # Ensure nodes start with at least two work units if possible + # Ensure nodes start with at least two work units if possible (#277) for node in self.nodes: self._reschedule(node)