Mercurial > hg
annotate tests/test-stdio.py @ 50072:a99dcf53eebd
dirstate-guard: remove the feature
The dirstate guard duplicated some of the logic already implemented in the
transaction (and now the changing_* context).
However the feature was incomplete, for example, living only in memory meant we
could not recover from the hardest crash. In addition this duplicated with the
transaction logic meant things could go out of sync or step on each other.
Removing the feature now that we no longer needs it seems the safest.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Thu, 16 Feb 2023 00:33:15 +0100 |
parents | 402f9f0f9387 |
children |
rev | line source |
---|---|
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__) |