author | Pierre-Yves David <pierre-yves.david@octobus.net> |
Wed, 21 Feb 2024 14:42:13 +0100 | |
changeset 51417 | e0d329491709 |
parent 49297 | 402f9f0f9387 |
permissions | -rwxr-xr-x |
47500
23f5ed6dbcb1
run-tests: stop writing a `python3` symlink pointing to python2
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45830
diff
changeset
|
1 |
#!/usr/bin/env python |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
2 |
""" |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
3 |
Tests the buffering behavior of stdio streams in `mercurial.utils.procutil`. |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
4 |
""" |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
5 |
|
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
6 |
import contextlib |
45068
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
7 |
import errno |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
8 |
import os |
48870
df56e6bd37f6
py3: use pickle directly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
47500
diff
changeset
|
9 |
import pickle |
45095
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
10 |
import signal |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
11 |
import subprocess |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
12 |
import sys |
45097
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
13 |
import tempfile |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
14 |
import unittest |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
15 |
|
45148
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
16 |
from mercurial import pycompat, util |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
17 |
|
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
18 |
|
45078
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
19 |
TEST_BUFFERING_CHILD_SCRIPT = r''' |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
20 |
import os |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
21 |
|
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
22 |
from mercurial import dispatch |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
23 |
from mercurial.utils import procutil |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
24 |
|
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
25 |
dispatch.initstdio() |
45044
359884685eab
tests: generalize common test case code in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45043
diff
changeset
|
26 |
procutil.{stream}.write(b'aaa') |
359884685eab
tests: generalize common test case code in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45043
diff
changeset
|
27 |
os.write(procutil.{stream}.fileno(), b'[written aaa]') |
359884685eab
tests: generalize common test case code in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45043
diff
changeset
|
28 |
procutil.{stream}.write(b'bbb\n') |
359884685eab
tests: generalize common test case code in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45043
diff
changeset
|
29 |
os.write(procutil.{stream}.fileno(), b'[written bbb\\n]') |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
30 |
''' |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
31 |
UNBUFFERED = b'aaa[written aaa]bbb\n[written bbb\\n]' |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
32 |
LINE_BUFFERED = b'[written aaa]aaabbb\n[written bbb\\n]' |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
33 |
FULLY_BUFFERED = b'[written aaa][written bbb\\n]aaabbb\n' |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
34 |
|
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
35 |
|
45095
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
36 |
TEST_LARGE_WRITE_CHILD_SCRIPT = r''' |
45104
eb26a9cf7821
procutil: avoid use of deprecated tempfile.mktemp()
Manuel Jacob <me@manueljacob.de>
parents:
45097
diff
changeset
|
37 |
import os |
45095
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
38 |
import signal |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
39 |
import sys |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
40 |
|
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
41 |
from mercurial import dispatch |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
42 |
from mercurial.utils import procutil |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
43 |
|
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
44 |
signal.signal(signal.SIGINT, lambda *x: None) |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
45 |
dispatch.initstdio() |
45097
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
46 |
write_result = procutil.{stream}.write(b'x' * 1048576) |
45104
eb26a9cf7821
procutil: avoid use of deprecated tempfile.mktemp()
Manuel Jacob <me@manueljacob.de>
parents:
45097
diff
changeset
|
47 |
with os.fdopen( |
eb26a9cf7821
procutil: avoid use of deprecated tempfile.mktemp()
Manuel Jacob <me@manueljacob.de>
parents:
45097
diff
changeset
|
48 |
os.open({write_result_fn!r}, os.O_WRONLY | getattr(os, 'O_TEMPORARY', 0)), |
eb26a9cf7821
procutil: avoid use of deprecated tempfile.mktemp()
Manuel Jacob <me@manueljacob.de>
parents:
45097
diff
changeset
|
49 |
'w', |
eb26a9cf7821
procutil: avoid use of deprecated tempfile.mktemp()
Manuel Jacob <me@manueljacob.de>
parents:
45097
diff
changeset
|
50 |
) as write_result_f: |
45097
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
51 |
write_result_f.write(str(write_result)) |
45095
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
52 |
''' |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
53 |
|
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
54 |
|
45148
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
55 |
TEST_BROKEN_PIPE_CHILD_SCRIPT = r''' |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
56 |
import os |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
57 |
import pickle |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
58 |
|
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
59 |
from mercurial import dispatch |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
60 |
from mercurial.utils import procutil |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
61 |
|
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
62 |
dispatch.initstdio() |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
63 |
procutil.stdin.read(1) # wait until parent process closed pipe |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
64 |
try: |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
65 |
procutil.{stream}.write(b'test') |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
66 |
procutil.{stream}.flush() |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
67 |
except EnvironmentError as e: |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
68 |
with os.fdopen( |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
69 |
os.open( |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
70 |
{err_fn!r}, |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
71 |
os.O_WRONLY |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
72 |
| getattr(os, 'O_BINARY', 0) |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
73 |
| getattr(os, 'O_TEMPORARY', 0), |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
74 |
), |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
75 |
'wb', |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
76 |
) as err_f: |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
77 |
pickle.dump(e, err_f) |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
78 |
# Exit early to suppress further broken pipe errors at interpreter shutdown. |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
79 |
os._exit(0) |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
80 |
''' |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
81 |
|
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
82 |
|
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
83 |
@contextlib.contextmanager |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
84 |
def _closing(fds): |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
85 |
try: |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
86 |
yield |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
87 |
finally: |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
88 |
for fd in fds: |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
89 |
try: |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
90 |
os.close(fd) |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
91 |
except EnvironmentError: |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
92 |
pass |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
93 |
|
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
94 |
|
45147
c2c862b9b544
tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45104
diff
changeset
|
95 |
# In the following, we set the FDs non-inheritable mainly to make it possible |
c2c862b9b544
tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45104
diff
changeset
|
96 |
# for tests to close the receiving end of the pipe / PTYs. |
c2c862b9b544
tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45104
diff
changeset
|
97 |
|
c2c862b9b544
tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45104
diff
changeset
|
98 |
|
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
99 |
@contextlib.contextmanager |
45096
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
100 |
def _devnull(): |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
101 |
devnull = os.open(os.devnull, os.O_WRONLY) |
45147
c2c862b9b544
tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45104
diff
changeset
|
102 |
# We don't have a receiving end, so it's not worth the effort on Python 2 |
c2c862b9b544
tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45104
diff
changeset
|
103 |
# on Windows to make the FD non-inheritable. |
45096
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
104 |
with _closing([devnull]): |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
105 |
yield (None, devnull) |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
106 |
|
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
107 |
|
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
108 |
@contextlib.contextmanager |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
109 |
def _pipes(): |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
110 |
rwpair = os.pipe() |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
111 |
with _closing(rwpair): |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
112 |
yield rwpair |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
113 |
|
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
114 |
|
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
115 |
@contextlib.contextmanager |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
116 |
def _ptys(): |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
117 |
if pycompat.iswindows: |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
118 |
raise unittest.SkipTest("PTYs are not supported on Windows") |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
119 |
import pty |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
120 |
import tty |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
121 |
|
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
122 |
rwpair = pty.openpty() |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
123 |
with _closing(rwpair): |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
124 |
tty.setraw(rwpair[0]) |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
125 |
yield rwpair |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
126 |
|
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
127 |
|
45095
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
128 |
def _readall(fd, buffer_size, initial_buf=None): |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
129 |
buf = initial_buf or [] |
45068
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
130 |
while True: |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
131 |
try: |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
132 |
s = os.read(fd, buffer_size) |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
133 |
except OSError as e: |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
134 |
if e.errno == errno.EIO: |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
135 |
# If the child-facing PTY got closed, reading from the |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
136 |
# parent-facing PTY raises EIO. |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
137 |
break |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
138 |
raise |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
139 |
if not s: |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
140 |
break |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
141 |
buf.append(s) |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
142 |
return b''.join(buf) |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
143 |
|
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
144 |
|
45044
359884685eab
tests: generalize common test case code in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45043
diff
changeset
|
145 |
class TestStdio(unittest.TestCase): |
45078
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
146 |
def _test( |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
147 |
self, |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
148 |
child_script, |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
149 |
stream, |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
150 |
rwpair_generator, |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
151 |
check_output, |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
152 |
python_args=[], |
45097
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
153 |
post_child_check=None, |
45148
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
154 |
stdin_generator=None, |
45078
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
155 |
): |
45044
359884685eab
tests: generalize common test case code in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45043
diff
changeset
|
156 |
assert stream in ('stdout', 'stderr') |
45148
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
157 |
if stdin_generator is None: |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
158 |
stdin_generator = open(os.devnull, 'rb') |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
159 |
with rwpair_generator() as ( |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
160 |
stream_receiver, |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
161 |
child_stream, |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
162 |
), stdin_generator as child_stdin: |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
163 |
proc = subprocess.Popen( |
45078
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
164 |
[sys.executable] + python_args + ['-c', child_script], |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
165 |
stdin=child_stdin, |
45044
359884685eab
tests: generalize common test case code in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45043
diff
changeset
|
166 |
stdout=child_stream if stream == 'stdout' else None, |
359884685eab
tests: generalize common test case code in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45043
diff
changeset
|
167 |
stderr=child_stream if stream == 'stderr' else None, |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
168 |
) |
45068
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
169 |
try: |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
170 |
os.close(child_stream) |
45096
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
171 |
if stream_receiver is not None: |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
172 |
check_output(stream_receiver, proc) |
45069
9172fd511999
tests: terminate subprocess in test-stdio.py in case of exception
Manuel Jacob <me@manueljacob.de>
parents:
45068
diff
changeset
|
173 |
except: # re-raises |
9172fd511999
tests: terminate subprocess in test-stdio.py in case of exception
Manuel Jacob <me@manueljacob.de>
parents:
45068
diff
changeset
|
174 |
proc.terminate() |
9172fd511999
tests: terminate subprocess in test-stdio.py in case of exception
Manuel Jacob <me@manueljacob.de>
parents:
45068
diff
changeset
|
175 |
raise |
45068
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
176 |
finally: |
8cd18aba5e6c
tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents:
45045
diff
changeset
|
177 |
retcode = proc.wait() |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
178 |
self.assertEqual(retcode, 0) |
45097
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
179 |
if post_child_check is not None: |
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
180 |
post_child_check() |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
181 |
|
45078
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
182 |
def _test_buffering( |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
183 |
self, stream, rwpair_generator, expected_output, python_args=[] |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
184 |
): |
45095
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
185 |
def check_output(stream_receiver, proc): |
45078
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
186 |
self.assertEqual(_readall(stream_receiver, 1024), expected_output) |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
187 |
|
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
188 |
self._test( |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
189 |
TEST_BUFFERING_CHILD_SCRIPT.format(stream=stream), |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
190 |
stream, |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
191 |
rwpair_generator, |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
192 |
check_output, |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
193 |
python_args, |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
194 |
) |
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
195 |
|
45096
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
196 |
def test_buffering_stdout_devnull(self): |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
197 |
self._test_buffering('stdout', _devnull, None) |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
198 |
|
45070
bc05c13e246f
tests: make names in test-stdio.py more distinctive
Manuel Jacob <me@manueljacob.de>
parents:
45069
diff
changeset
|
199 |
def test_buffering_stdout_pipes(self): |
45078
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
200 |
self._test_buffering('stdout', _pipes, FULLY_BUFFERED) |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
201 |
|
45070
bc05c13e246f
tests: make names in test-stdio.py more distinctive
Manuel Jacob <me@manueljacob.de>
parents:
45069
diff
changeset
|
202 |
def test_buffering_stdout_ptys(self): |
45078
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
203 |
self._test_buffering('stdout', _ptys, LINE_BUFFERED) |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
204 |
|
45096
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
205 |
def test_buffering_stdout_devnull_unbuffered(self): |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
206 |
self._test_buffering('stdout', _devnull, None, python_args=['-u']) |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
207 |
|
45070
bc05c13e246f
tests: make names in test-stdio.py more distinctive
Manuel Jacob <me@manueljacob.de>
parents:
45069
diff
changeset
|
208 |
def test_buffering_stdout_pipes_unbuffered(self): |
45078
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
209 |
self._test_buffering('stdout', _pipes, UNBUFFERED, python_args=['-u']) |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
210 |
|
45070
bc05c13e246f
tests: make names in test-stdio.py more distinctive
Manuel Jacob <me@manueljacob.de>
parents:
45069
diff
changeset
|
211 |
def test_buffering_stdout_ptys_unbuffered(self): |
45078
a59aab6078eb
tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
45077
diff
changeset
|
212 |
self._test_buffering('stdout', _ptys, UNBUFFERED, python_args=['-u']) |
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
213 |
|
45095
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
214 |
def _test_large_write(self, stream, rwpair_generator, python_args=[]): |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
215 |
def check_output(stream_receiver, proc): |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
216 |
if not pycompat.iswindows: |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
217 |
# On Unix, we can provoke a partial write() by interrupting it |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
218 |
# by a signal handler as soon as a bit of data was written. |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
219 |
# We test that write() is called until all data is written. |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
220 |
buf = [os.read(stream_receiver, 1)] |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
221 |
proc.send_signal(signal.SIGINT) |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
222 |
else: |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
223 |
# On Windows, there doesn't seem to be a way to cause partial |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
224 |
# writes. |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
225 |
buf = [] |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
226 |
self.assertEqual( |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
227 |
_readall(stream_receiver, 131072, buf), b'x' * 1048576 |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
228 |
) |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
229 |
|
45097
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
230 |
def post_child_check(): |
49297
402f9f0f9387
tests: remove Python 2 special cases in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents:
49296
diff
changeset
|
231 |
self.assertEqual(write_result_f.read(), '1048576') |
45097
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
232 |
|
45104
eb26a9cf7821
procutil: avoid use of deprecated tempfile.mktemp()
Manuel Jacob <me@manueljacob.de>
parents:
45097
diff
changeset
|
233 |
with tempfile.NamedTemporaryFile('r') as write_result_f: |
45097
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
234 |
self._test( |
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
235 |
TEST_LARGE_WRITE_CHILD_SCRIPT.format( |
45104
eb26a9cf7821
procutil: avoid use of deprecated tempfile.mktemp()
Manuel Jacob <me@manueljacob.de>
parents:
45097
diff
changeset
|
236 |
stream=stream, write_result_fn=write_result_f.name |
45097
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
237 |
), |
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
238 |
stream, |
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
239 |
rwpair_generator, |
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
240 |
check_output, |
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
241 |
python_args, |
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
242 |
post_child_check=post_child_check, |
dff208398ede
tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents:
45096
diff
changeset
|
243 |
) |
45095
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
244 |
|
45096
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
245 |
def test_large_write_stdout_devnull(self): |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
246 |
self._test_large_write('stdout', _devnull) |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
247 |
|
45095
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
248 |
def test_large_write_stdout_pipes(self): |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
249 |
self._test_large_write('stdout', _pipes) |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
250 |
|
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
251 |
def test_large_write_stdout_ptys(self): |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
252 |
self._test_large_write('stdout', _ptys) |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
253 |
|
45096
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
254 |
def test_large_write_stdout_devnull_unbuffered(self): |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
255 |
self._test_large_write('stdout', _devnull, python_args=['-u']) |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
256 |
|
45095
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
257 |
def test_large_write_stdout_pipes_unbuffered(self): |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
258 |
self._test_large_write('stdout', _pipes, python_args=['-u']) |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
259 |
|
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
260 |
def test_large_write_stdout_ptys_unbuffered(self): |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
261 |
self._test_large_write('stdout', _ptys, python_args=['-u']) |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
262 |
|
45096
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
263 |
def test_large_write_stderr_devnull(self): |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
264 |
self._test_large_write('stderr', _devnull) |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
265 |
|
45095
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
266 |
def test_large_write_stderr_pipes(self): |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
267 |
self._test_large_write('stderr', _pipes) |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
268 |
|
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
269 |
def test_large_write_stderr_ptys(self): |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
270 |
self._test_large_write('stderr', _ptys) |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
271 |
|
45096
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
272 |
def test_large_write_stderr_devnull_unbuffered(self): |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
273 |
self._test_large_write('stderr', _devnull, python_args=['-u']) |
e9e452eafbfb
tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents:
45095
diff
changeset
|
274 |
|
45095
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
275 |
def test_large_write_stderr_pipes_unbuffered(self): |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
276 |
self._test_large_write('stderr', _pipes, python_args=['-u']) |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
277 |
|
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
278 |
def test_large_write_stderr_ptys_unbuffered(self): |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
279 |
self._test_large_write('stderr', _ptys, python_args=['-u']) |
8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents:
45078
diff
changeset
|
280 |
|
45148
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
281 |
def _test_broken_pipe(self, stream): |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
282 |
assert stream in ('stdout', 'stderr') |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
283 |
|
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
284 |
def check_output(stream_receiver, proc): |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
285 |
os.close(stream_receiver) |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
286 |
proc.stdin.write(b'x') |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
287 |
proc.stdin.close() |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
288 |
|
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
289 |
def post_child_check(): |
48870
df56e6bd37f6
py3: use pickle directly
Gregory Szorc <gregory.szorc@gmail.com>
parents:
47500
diff
changeset
|
290 |
err = pickle.load(err_f) |
45148
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
291 |
self.assertEqual(err.errno, errno.EPIPE) |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
292 |
self.assertEqual(err.strerror, "Broken pipe") |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
293 |
|
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
294 |
with tempfile.NamedTemporaryFile('rb') as err_f: |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
295 |
self._test( |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
296 |
TEST_BROKEN_PIPE_CHILD_SCRIPT.format( |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
297 |
stream=stream, err_fn=err_f.name |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
298 |
), |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
299 |
stream, |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
300 |
_pipes, |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
301 |
check_output, |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
302 |
post_child_check=post_child_check, |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
303 |
stdin_generator=util.nullcontextmanager(subprocess.PIPE), |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
304 |
) |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
305 |
|
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
306 |
def test_broken_pipe_stdout(self): |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
307 |
self._test_broken_pipe('stdout') |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
308 |
|
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
309 |
def test_broken_pipe_stderr(self): |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
310 |
self._test_broken_pipe('stderr') |
a37f290a7124
windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents:
45147
diff
changeset
|
311 |
|
45038
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
312 |
|
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
313 |
if __name__ == '__main__': |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
314 |
import silenttestrunner |
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
315 |
|
c7d109c400a4
tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff
changeset
|
316 |
silenttestrunner.main(__name__) |