Mercurial > hg
changeset 36533:1a36ef7df70a
sshpeer: support not reading and forwarding stderr
The "doublepipe" primitive as used by sshpeer will automatically read
from stderr and forward output to the local ui.
This poses problems for deterministic testing because reads may not
be consistent. For example, the server may not be done sending all
output to stderr and the client will perform different numbers of
read operations or will read from stderr and stdout at different times.
To make tests deterministic, we'll need to disable the "doublepipe"
primitive and perform stderr I/O explicitly. We add an argument to the
sshpeer constructor to disable the use of the doublepipe.
Differential Revision: https://phab.mercurial-scm.org/D2467
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Mon, 26 Feb 2018 13:12:03 -0800 |
parents | 1138e5c0fbc9 |
children | 5faeabb07cf5 |
files | mercurial/sshpeer.py |
diffstat | 1 files changed, 12 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/sshpeer.py Fri Feb 23 16:03:27 2018 -0800 +++ b/mercurial/sshpeer.py Mon Feb 26 13:12:03 2018 -0800 @@ -337,13 +337,16 @@ return protoname, caps class sshv1peer(wireproto.wirepeer): - def __init__(self, ui, url, proc, stdin, stdout, stderr, caps): + def __init__(self, ui, url, proc, stdin, stdout, stderr, caps, + autoreadstderr=True): """Create a peer from an existing SSH connection. ``proc`` is a handle on the underlying SSH process. ``stdin``, ``stdout``, and ``stderr`` are handles on the stdio pipes for that process. ``caps`` is a set of capabilities supported by the remote. + ``autoreadstderr`` denotes whether to automatically read from + stderr and to forward its output. """ self._url = url self._ui = ui @@ -353,8 +356,9 @@ # And we hook up our "doublepipe" wrapper to allow querying # stderr any time we perform I/O. - stdout = doublepipe(ui, util.bufferedinputpipe(stdout), stderr) - stdin = doublepipe(ui, stdin, stderr) + if autoreadstderr: + stdout = doublepipe(ui, util.bufferedinputpipe(stdout), stderr) + stdin = doublepipe(ui, stdin, stderr) self._pipeo = stdin self._pipei = stdout @@ -531,7 +535,7 @@ # And handshake is performed before the peer is instantiated. So # we need no custom code. -def makepeer(ui, path, proc, stdin, stdout, stderr): +def makepeer(ui, path, proc, stdin, stdout, stderr, autoreadstderr=True): """Make a peer instance from existing pipes. ``path`` and ``proc`` are stored on the eventual peer instance and may @@ -552,9 +556,11 @@ raise if protoname == wireprotoserver.SSHV1: - return sshv1peer(ui, path, proc, stdin, stdout, stderr, caps) + return sshv1peer(ui, path, proc, stdin, stdout, stderr, caps, + autoreadstderr=autoreadstderr) elif protoname == wireprotoserver.SSHV2: - return sshv2peer(ui, path, proc, stdin, stdout, stderr, caps) + return sshv2peer(ui, path, proc, stdin, stdout, stderr, caps, + autoreadstderr=autoreadstderr) else: _cleanuppipes(ui, stdout, stdin, stderr) raise error.RepoError(_('unknown version of SSH protocol: %s') %