Skip to content

Commit f1060be

Browse files
committed
test(subprocess): SubprocessCommand
1 parent a42c011 commit f1060be

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

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

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

0 commit comments

Comments
 (0)