tests/test-stdio.py
author Manuel Jacob <me@manueljacob.de>
Fri, 17 Jul 2020 00:37:33 +0200
changeset 45147 c2c862b9b544
parent 45104 eb26a9cf7821
child 45148 a37f290a7124
permissions -rwxr-xr-x
tests: make pipes / PTYs non-inheritable in test-stdio.py A following patch requires that to test closing the receiving end of the pipe / PTYs. Even for existing tests, it might be safer to make the lifetime of the pipes / PTYs as short as possible.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
45038
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
     1
#!/usr/bin/env python
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
from __future__ import absolute_import
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
     6
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
     7
import contextlib
45068
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
     8
import errno
45038
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
     9
import os
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
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    16
from mercurial import pycompat
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
45147
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    19
if pycompat.ispy3:
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    20
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    21
    def set_noninheritable(fd):
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    22
        # On Python 3, file descriptors are non-inheritable by default.
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    23
        pass
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    24
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    25
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    26
else:
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    27
    if pycompat.iswindows:
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    28
        # unused
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    29
        set_noninheritable = None
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    30
    else:
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    31
        import fcntl
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    32
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    33
        def set_noninheritable(fd):
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    34
            old = fcntl.fcntl(fd, fcntl.F_GETFD)
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    35
            fcntl.fcntl(fd, fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    36
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    37
45078
a59aab6078eb tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45077
diff changeset
    38
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
    39
import os
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    40
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    41
from mercurial import dispatch
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    42
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
    43
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    44
dispatch.initstdio()
45044
359884685eab tests: generalize common test case code in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
    45
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
    46
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
    47
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
    48
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
    49
'''
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    50
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
    51
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
    52
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
    53
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    54
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
    55
TEST_LARGE_WRITE_CHILD_SCRIPT = r'''
45104
eb26a9cf7821 procutil: avoid use of deprecated tempfile.mktemp()
Manuel Jacob <me@manueljacob.de>
parents: 45097
diff changeset
    56
import os
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
    57
import signal
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
    58
import sys
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
    59
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
    60
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
    61
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
    62
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
    63
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
    64
dispatch.initstdio()
45097
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
    65
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
    66
with os.fdopen(
eb26a9cf7821 procutil: avoid use of deprecated tempfile.mktemp()
Manuel Jacob <me@manueljacob.de>
parents: 45097
diff changeset
    67
    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
    68
    'w',
eb26a9cf7821 procutil: avoid use of deprecated tempfile.mktemp()
Manuel Jacob <me@manueljacob.de>
parents: 45097
diff changeset
    69
) 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
    70
    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
    71
'''
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
    72
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
    73
45038
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    74
@contextlib.contextmanager
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    75
def _closing(fds):
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    76
    try:
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    77
        yield
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    78
    finally:
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    79
        for fd in fds:
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    80
            try:
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    81
                os.close(fd)
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    82
            except EnvironmentError:
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    83
                pass
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    84
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    85
45147
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    86
# 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
    87
# 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
    88
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
    89
45038
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
    90
@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
    91
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
    92
    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
    93
    # 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
    94
    # 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
    95
    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
    96
        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
    97
e9e452eafbfb tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents: 45095
diff changeset
    98
e9e452eafbfb tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents: 45095
diff changeset
    99
@contextlib.contextmanager
45038
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   100
def _pipes():
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   101
    rwpair = os.pipe()
45147
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
   102
    # Pipes are already non-inheritable on Windows.
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
   103
    if not pycompat.iswindows:
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
   104
        set_noninheritable(rwpair[0])
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
   105
        set_noninheritable(rwpair[1])
45038
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   106
    with _closing(rwpair):
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   107
        yield rwpair
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   108
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   109
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   110
@contextlib.contextmanager
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   111
def _ptys():
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   112
    if pycompat.iswindows:
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   113
        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
   114
    import pty
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   115
    import tty
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   116
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   117
    rwpair = pty.openpty()
45147
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
   118
    set_noninheritable(rwpair[0])
c2c862b9b544 tests: make pipes / PTYs non-inheritable in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45104
diff changeset
   119
    set_noninheritable(rwpair[1])
45038
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   120
    with _closing(rwpair):
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   121
        tty.setraw(rwpair[0])
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   122
        yield rwpair
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   123
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   124
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   125
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
   126
    buf = initial_buf or []
45068
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   127
    while True:
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   128
        try:
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   129
            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
   130
        except OSError as e:
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   131
            if e.errno == errno.EIO:
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   132
                # 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
   133
                # parent-facing PTY raises EIO.
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   134
                break
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   135
            raise
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   136
        if not s:
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
        buf.append(s)
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   139
    return b''.join(buf)
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   140
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   141
45044
359884685eab tests: generalize common test case code in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   142
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
   143
    def _test(
a59aab6078eb tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45077
diff changeset
   144
        self,
a59aab6078eb tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45077
diff changeset
   145
        child_script,
a59aab6078eb tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45077
diff changeset
   146
        stream,
a59aab6078eb tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45077
diff changeset
   147
        rwpair_generator,
a59aab6078eb tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45077
diff changeset
   148
        check_output,
a59aab6078eb tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45077
diff changeset
   149
        python_args=[],
45097
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   150
        post_child_check=None,
45078
a59aab6078eb tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45077
diff changeset
   151
    ):
45044
359884685eab tests: generalize common test case code in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   152
        assert stream in ('stdout', 'stderr')
359884685eab tests: generalize common test case code in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   153
        with rwpair_generator() as (stream_receiver, child_stream), open(
45038
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   154
            os.devnull, 'rb'
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   155
        ) as child_stdin:
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   156
            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
   157
                [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
   158
                stdin=child_stdin,
45044
359884685eab tests: generalize common test case code in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   159
                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
   160
                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
   161
            )
45068
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   162
            try:
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   163
                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
   164
                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
   165
                    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
   166
            except:  # re-raises
9172fd511999 tests: terminate subprocess in test-stdio.py in case of exception
Manuel Jacob <me@manueljacob.de>
parents: 45068
diff changeset
   167
                proc.terminate()
9172fd511999 tests: terminate subprocess in test-stdio.py in case of exception
Manuel Jacob <me@manueljacob.de>
parents: 45068
diff changeset
   168
                raise
45068
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   169
            finally:
8cd18aba5e6c tests: proof test-stdio.py against buffer fill-up
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   170
                retcode = proc.wait()
45038
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   171
            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
   172
            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
   173
                post_child_check()
45038
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   174
45078
a59aab6078eb tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45077
diff changeset
   175
    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
   176
        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
   177
    ):
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   178
        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
   179
            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
   180
a59aab6078eb tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45077
diff changeset
   181
        self._test(
a59aab6078eb tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45077
diff changeset
   182
            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
   183
            stream,
a59aab6078eb tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45077
diff changeset
   184
            rwpair_generator,
a59aab6078eb tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45077
diff changeset
   185
            check_output,
a59aab6078eb tests: make subprocess handling reusable for different tests in test-stdio.py
Manuel Jacob <me@manueljacob.de>
parents: 45077
diff changeset
   186
            python_args,
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
45096
e9e452eafbfb tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents: 45095
diff changeset
   189
    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
   190
        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
   191
45070
bc05c13e246f tests: make names in test-stdio.py more distinctive
Manuel Jacob <me@manueljacob.de>
parents: 45069
diff changeset
   192
    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
   193
        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
   194
45070
bc05c13e246f tests: make names in test-stdio.py more distinctive
Manuel Jacob <me@manueljacob.de>
parents: 45069
diff changeset
   195
    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
   196
        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
   197
45096
e9e452eafbfb tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents: 45095
diff changeset
   198
    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
   199
        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
   200
45070
bc05c13e246f tests: make names in test-stdio.py more distinctive
Manuel Jacob <me@manueljacob.de>
parents: 45069
diff changeset
   201
    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
   202
        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
   203
45070
bc05c13e246f tests: make names in test-stdio.py more distinctive
Manuel Jacob <me@manueljacob.de>
parents: 45069
diff changeset
   204
    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
   205
        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
   206
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   207
    if not pycompat.ispy3 and not pycompat.iswindows:
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   208
        # On Python 2 on non-Windows, we manually open stdout in line-buffered
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   209
        # mode if connected to a TTY. We should check if Python was configured
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   210
        # to use unbuffered stdout, but it's hard to do that.
45070
bc05c13e246f tests: make names in test-stdio.py more distinctive
Manuel Jacob <me@manueljacob.de>
parents: 45069
diff changeset
   211
        test_buffering_stdout_ptys_unbuffered = unittest.expectedFailure(
bc05c13e246f tests: make names in test-stdio.py more distinctive
Manuel Jacob <me@manueljacob.de>
parents: 45069
diff changeset
   212
            test_buffering_stdout_ptys_unbuffered
45038
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   213
        )
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   214
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   215
    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
   216
        if not pycompat.ispy3 and pycompat.isdarwin:
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   217
            # Python 2 doesn't always retry on EINTR, but the libc might retry.
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   218
            # So far, it was observed only on macOS that EINTR is raised at the
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   219
            # Python level. As Python 2 support will be dropped soon-ish, we
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   220
            # won't attempt to fix it.
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   221
            raise unittest.SkipTest("raises EINTR on macOS")
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   222
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   223
        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
   224
            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
   225
                # 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
   226
                # 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
   227
                # 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
   228
                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
   229
                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
   230
            else:
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   231
                # 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
   232
                # writes.
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   233
                buf = []
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   234
            self.assertEqual(
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   235
                _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
   236
            )
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   237
45097
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   238
        def post_child_check():
45104
eb26a9cf7821 procutil: avoid use of deprecated tempfile.mktemp()
Manuel Jacob <me@manueljacob.de>
parents: 45097
diff changeset
   239
            write_result_str = write_result_f.read()
45097
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   240
            if pycompat.ispy3:
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   241
                # On Python 3, we test that the correct number of bytes is
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   242
                # claimed to have been written.
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   243
                expected_write_result_str = '1048576'
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   244
            else:
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   245
                # On Python 2, we only check that the large write does not
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   246
                # crash.
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   247
                expected_write_result_str = 'None'
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   248
            self.assertEqual(write_result_str, expected_write_result_str)
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   249
45104
eb26a9cf7821 procutil: avoid use of deprecated tempfile.mktemp()
Manuel Jacob <me@manueljacob.de>
parents: 45097
diff changeset
   250
        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
   251
            self._test(
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   252
                TEST_LARGE_WRITE_CHILD_SCRIPT.format(
45104
eb26a9cf7821 procutil: avoid use of deprecated tempfile.mktemp()
Manuel Jacob <me@manueljacob.de>
parents: 45097
diff changeset
   253
                    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
   254
                ),
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   255
                stream,
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   256
                rwpair_generator,
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   257
                check_output,
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   258
                python_args,
dff208398ede tests: check that procutil.std{out,err}.write() returns correct result
Manuel Jacob <me@manueljacob.de>
parents: 45096
diff changeset
   259
                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
   260
            )
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   261
45096
e9e452eafbfb tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents: 45095
diff changeset
   262
    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
   263
        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
   264
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   265
    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
   266
        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
   267
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   268
    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
   269
        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
   270
45096
e9e452eafbfb tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents: 45095
diff changeset
   271
    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
   272
        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
   273
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   274
    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
   275
        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
   276
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   277
    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
   278
        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
   279
45096
e9e452eafbfb tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents: 45095
diff changeset
   280
    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
   281
        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
   282
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   283
    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
   284
        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
   285
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   286
    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
   287
        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
   288
45096
e9e452eafbfb tests: add tests for when stdout or stderr is connected to `os.devnull`
Manuel Jacob <me@manueljacob.de>
parents: 45095
diff changeset
   289
    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
   290
        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
   291
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   292
    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
   293
        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
   294
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45078
diff changeset
   295
    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
   296
        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
   297
45038
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   298
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   299
if __name__ == '__main__':
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   300
    import silenttestrunner
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   301
c7d109c400a4 tests: add tests for buffering behavior of mercurial.utils.procutil.stdout
Manuel Jacob <me@manueljacob.de>
parents:
diff changeset
   302
    silenttestrunner.main(__name__)