1
1
from contextlib import suppress
2
2
from pathlib import Path
3
+ import sys
4
+ import os
3
5
4
6
import execnet
5
7
from xdist .workermanage import NodeManager
6
8
7
9
import pytest
8
10
9
11
12
+ @pytest .fixture
13
+ def monkeypatch_3_cpus (monkeypatch : pytest .MonkeyPatch ):
14
+ """Make pytest-xdist believe the system has 3 CPUs"""
15
+ monkeypatch .setitem (sys .modules , "psutil" , None ) # block import
16
+ monkeypatch .delattr (os , "sched_getaffinity" , raising = False )
17
+ monkeypatch .setattr (os , "cpu_count" , lambda : 3 )
18
+
19
+
10
20
def test_dist_incompatibility_messages (pytester : pytest .Pytester ) -> None :
11
21
result = pytester .runpytest ("--pdb" , "--looponfail" )
12
22
assert result .ret != 0
@@ -41,7 +51,6 @@ def test_dist_options(pytester: pytest.Pytester) -> None:
41
51
def test_auto_detect_cpus (
42
52
pytester : pytest .Pytester , monkeypatch : pytest .MonkeyPatch
43
53
) -> None :
44
- import os
45
54
from xdist .plugin import pytest_cmdline_main as check_options
46
55
47
56
with suppress (ImportError ):
@@ -102,6 +111,20 @@ def test_auto_detect_cpus_psutil(
102
111
assert config .getoption ("numprocesses" ) == 84
103
112
104
113
114
+ def test_auto_detect_cpus_os (
115
+ pytester : pytest .Pytester , monkeypatch : pytest .MonkeyPatch , monkeypatch_3_cpus
116
+ ) -> None :
117
+ from xdist .plugin import pytest_cmdline_main as check_options
118
+
119
+ config = pytester .parseconfigure ("-nauto" )
120
+ check_options (config )
121
+ assert config .getoption ("numprocesses" ) == 3
122
+
123
+ config = pytester .parseconfigure ("-nlogical" )
124
+ check_options (config )
125
+ assert config .getoption ("numprocesses" ) == 3
126
+
127
+
105
128
def test_hook_auto_num_workers (
106
129
pytester : pytest .Pytester , monkeypatch : pytest .MonkeyPatch
107
130
) -> None :
@@ -122,6 +145,105 @@ def pytest_xdist_auto_num_workers():
122
145
assert config .getoption ("numprocesses" ) == 42
123
146
124
147
148
+ def test_hook_auto_num_workers_arg (
149
+ pytester : pytest .Pytester , monkeypatch : pytest .MonkeyPatch
150
+ ) -> None :
151
+ # config.option.numprocesses is a pytest feature,
152
+ # but we document it so let's test it.
153
+ from xdist .plugin import pytest_cmdline_main as check_options
154
+
155
+ pytester .makeconftest (
156
+ """
157
+ def pytest_xdist_auto_num_workers(config):
158
+ if config.option.numprocesses == 'auto':
159
+ return 42
160
+ if config.option.numprocesses == 'logical':
161
+ return 8
162
+ """
163
+ )
164
+ config = pytester .parseconfigure ("-nauto" )
165
+ check_options (config )
166
+ assert config .getoption ("numprocesses" ) == 42
167
+
168
+ config = pytester .parseconfigure ("-nlogical" )
169
+ check_options (config )
170
+ assert config .getoption ("numprocesses" ) == 8
171
+
172
+
173
+ def test_hook_auto_num_workers_none (
174
+ pytester : pytest .Pytester , monkeypatch : pytest .MonkeyPatch , monkeypatch_3_cpus
175
+ ) -> None :
176
+ # Returning None from a hook to skip it is pytest behavior,
177
+ # but we document it so let's test it.
178
+ from xdist .plugin import pytest_cmdline_main as check_options
179
+
180
+ pytester .makeconftest (
181
+ """
182
+ def pytest_xdist_auto_num_workers():
183
+ return None
184
+ """
185
+ )
186
+ config = pytester .parseconfigure ("-nauto" )
187
+ check_options (config )
188
+ assert config .getoption ("numprocesses" ) == 3
189
+
190
+ monkeypatch .setenv ("PYTEST_XDIST_AUTO_NUM_WORKERS" , "5" )
191
+
192
+ config = pytester .parseconfigure ("-nauto" )
193
+ check_options (config )
194
+ assert config .getoption ("numprocesses" ) == 5
195
+
196
+
197
+ def test_envvar_auto_num_workers (
198
+ pytester : pytest .Pytester , monkeypatch : pytest .MonkeyPatch
199
+ ) -> None :
200
+ from xdist .plugin import pytest_cmdline_main as check_options
201
+
202
+ monkeypatch .setenv ("PYTEST_XDIST_AUTO_NUM_WORKERS" , "7" )
203
+
204
+ config = pytester .parseconfigure ("-nauto" )
205
+ check_options (config )
206
+ assert config .getoption ("numprocesses" ) == 7
207
+
208
+ config = pytester .parseconfigure ("-nlogical" )
209
+ check_options (config )
210
+ assert config .getoption ("numprocesses" ) == 7
211
+
212
+
213
+ def test_envvar_auto_num_workers_warn (
214
+ pytester : pytest .Pytester , monkeypatch : pytest .MonkeyPatch , monkeypatch_3_cpus
215
+ ) -> None :
216
+ from xdist .plugin import pytest_cmdline_main as check_options
217
+
218
+ monkeypatch .setenv ("PYTEST_XDIST_AUTO_NUM_WORKERS" , "fourscore" )
219
+
220
+ config = pytester .parseconfigure ("-nauto" )
221
+ with pytest .warns (UserWarning ):
222
+ check_options (config )
223
+ assert config .getoption ("numprocesses" ) == 3
224
+
225
+
226
+ def test_auto_num_workers_hook_overrides_envvar (
227
+ pytester : pytest .Pytester , monkeypatch : pytest .MonkeyPatch , monkeypatch_3_cpus
228
+ ) -> None :
229
+ from xdist .plugin import pytest_cmdline_main as check_options
230
+
231
+ monkeypatch .setenv ("PYTEST_XDIST_AUTO_NUM_WORKERS" , "987" )
232
+ pytester .makeconftest (
233
+ """
234
+ def pytest_xdist_auto_num_workers():
235
+ return 2
236
+ """
237
+ )
238
+ config = pytester .parseconfigure ("-nauto" )
239
+ check_options (config )
240
+ assert config .getoption ("numprocesses" ) == 2
241
+
242
+ config = pytester .parseconfigure ("-nauto" )
243
+ check_options (config )
244
+ assert config .getoption ("numprocesses" ) == 2
245
+
246
+
125
247
def test_dsession_with_collect_only (pytester : pytest .Pytester ) -> None :
126
248
from xdist .plugin import pytest_cmdline_main as check_options
127
249
from xdist .plugin import pytest_configure as configure
0 commit comments