Skip to content

Commit ea15171

Browse files
committed
test(subprocess): SubprocessCommand
1 parent 722cfa2 commit ea15171

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

tests/_internal/subprocess/test_SubprocessCommand.py

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import pathlib
22
import subprocess
3+
import sys
4+
import textwrap
35
from typing import Any
6+
from unittest import mock
47

58
import pytest
69

@@ -137,3 +140,157 @@ def test_run(tmp_path: pathlib.Path, args: list, kwargs: dict, run_kwargs: dict)
137140
response = cmd.run(**run_kwargs)
138141

139142
assert response.returncode == 0
143+
144+
145+
@pytest.mark.parametrize(
146+
"args,kwargs,run_kwargs",
147+
[
148+
[
149+
["ls"],
150+
{},
151+
{},
152+
],
153+
[[["ls", "-l"]], {}, {}],
154+
[[["ls", "-al"]], {}, {"stdout": subprocess.DEVNULL}],
155+
],
156+
ids=idfn,
157+
)
158+
@mock.patch("subprocess.Popen")
159+
def test_Popen_mock(
160+
mock_subprocess_popen,
161+
tmp_path: pathlib.Path,
162+
args: list,
163+
kwargs: dict,
164+
run_kwargs: dict,
165+
capsys: pytest.LogCaptureFixture,
166+
):
167+
process_mock = mock.Mock()
168+
attrs = {"communicate.return_value": ("output", "error"), "returncode": 1}
169+
process_mock.configure_mock(**attrs)
170+
mock_subprocess_popen.return_value = process_mock
171+
cmd = SubprocessCommand(*args, cwd=tmp_path, **kwargs)
172+
response = cmd.Popen(**run_kwargs)
173+
174+
assert response.returncode == 1
175+
176+
177+
@pytest.mark.parametrize(
178+
"args,kwargs,run_kwargs",
179+
[
180+
[[["git", "pull", "--progress"]], {}, {}],
181+
],
182+
ids=idfn,
183+
)
184+
@mock.patch("subprocess.Popen")
185+
def test_Popen_git_mock(
186+
mock_subprocess_popen,
187+
tmp_path: pathlib.Path,
188+
args: list,
189+
kwargs: dict,
190+
run_kwargs: dict,
191+
capsys: pytest.LogCaptureFixture,
192+
):
193+
process_mock = mock.Mock()
194+
attrs = {"communicate.return_value": ("output", "error"), "returncode": 1}
195+
process_mock.configure_mock(**attrs)
196+
mock_subprocess_popen.return_value = process_mock
197+
cmd = SubprocessCommand(*args, cwd=tmp_path, **kwargs)
198+
response = cmd.Popen(**run_kwargs)
199+
200+
stdout, stderr = response.communicate()
201+
202+
assert response.returncode == 1
203+
assert stdout == "output"
204+
assert stderr == "error"
205+
206+
207+
CODE = (
208+
textwrap.dedent(
209+
r"""
210+
import sys
211+
import time
212+
size = 10
213+
for i in range(10):
214+
time.sleep(.01)
215+
sys.stderr.write(
216+
'[' + "#" * i + "." * (size-i) + ']' + f' {i}/{size}' + '\n'
217+
)
218+
sys.stderr.flush()
219+
"""
220+
)
221+
.strip("\n")
222+
.lstrip()
223+
)
224+
225+
226+
def test_Popen_stderr(
227+
tmp_path: pathlib.Path,
228+
capsys: pytest.LogCaptureFixture,
229+
):
230+
cmd = SubprocessCommand(
231+
[
232+
sys.executable,
233+
"-c",
234+
CODE,
235+
],
236+
stdout=subprocess.PIPE,
237+
stderr=subprocess.PIPE,
238+
cwd=tmp_path,
239+
)
240+
response = cmd.Popen()
241+
while response.poll() is None:
242+
stdout, stderr = response.communicate()
243+
244+
assert stdout != "output"
245+
assert stderr != "1"
246+
assert response.returncode == 0
247+
248+
249+
def test_CaptureStderrMixin(
250+
tmp_path: pathlib.Path,
251+
capsys: pytest.LogCaptureFixture,
252+
):
253+
cmd = SubprocessCommand(
254+
[
255+
sys.executable,
256+
"-c",
257+
CODE,
258+
],
259+
stdout=subprocess.PIPE,
260+
stderr=subprocess.PIPE,
261+
cwd=tmp_path,
262+
)
263+
response = cmd.Popen()
264+
while response.poll() is None:
265+
line = response.stderr.readline().decode("utf-8").strip()
266+
if line:
267+
assert line.startswith("[")
268+
assert response.returncode == 0
269+
270+
271+
def test_CaptureStderrMixin_error(
272+
tmp_path: pathlib.Path,
273+
capsys: pytest.LogCaptureFixture,
274+
):
275+
cmd = SubprocessCommand(
276+
[
277+
sys.executable,
278+
"-c",
279+
CODE
280+
+ textwrap.dedent(
281+
"""
282+
sys.exit("FATAL")
283+
"""
284+
),
285+
],
286+
stdout=subprocess.PIPE,
287+
stderr=subprocess.PIPE,
288+
cwd=tmp_path,
289+
)
290+
response = cmd.Popen()
291+
while response.poll() is None:
292+
line = response.stderr.readline().decode("utf-8").strip()
293+
if line:
294+
assert line.startswith("[") or line == "FATAL"
295+
296+
assert response.returncode == 1

0 commit comments

Comments
 (0)