[PATCH 1 of 2] hook: forcibly flush stderr for Windows test stability

Matt Harbison mharbison72 at gmail.com
Sat Apr 11 05:57:26 UTC 2015


# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1428719419 14400
#      Fri Apr 10 22:30:19 2015 -0400
# Node ID ff700da553f4003835d45204b76be2a05e98b78c
# Parent  553dc2b094d9e1eb2f66ba8f1ec36ecb55cf9d64
hook: forcibly flush stderr for Windows test stability

There are a handful of SSH related test failures on Windows.

  --- c:/Users/Matt/Projects/hg/tests/test-bundle2-exchange.t
  +++ c:/Users/Matt/Projects/hg/tests/test-bundle2-exchange.t.err
  @@ -305,16 +305,16 @@
     remote: added 1 changesets with 1 changes to 1 files
     remote: 1 new obsolescence markers
     updating bookmark book_5fdd
  +  pre-close-tip:02de42196ebe draft book_02de
  +  postclose-tip:02de42196ebe draft book_02de
  +  txnclose hook: HG_SOURCE=push-response HG_TXNNAME=push-response
  +  ssh://user@dummy/other HG_URL=ssh://user@dummy/other
     remote: pre-close-tip:5fddd98957c8 draft book_5fdd
     remote: pushkey: lock state after "bookmarks"
     remote: lock:  free
     remote: wlock: free
     remote: postclose-tip:5fddd98957c8 draft book_5fdd
     remote: txnclose hook: (env vars truncated)
  -  pre-close-tip:02de42196ebe draft book_02de
  -  postclose-tip:02de42196ebe draft book_02de
  -  txnclose hook: HG_SOURCE=push-response HG_TXNNAME=push-response
  -  ssh://user@dummy/other HG_URL=ssh://user@dummy/other
     $ hg -R other log -G
     o  6:5fddd98957c8 draft Nicolas Dumazet <...> book_5fdd C
     |

  --- c:/Users/Matt/Projects/hg/tests/test-ssh.t
  +++ c:/Users/Matt/Projects/hg/tests/test-ssh.t.err
  @@ -438,12 +438,12 @@
     $ hg push
     pushing to ssh://user@dummy/remote
     searching for changes
  +  local stdout
     remote: adding changesets
     remote: adding manifests
     remote: adding file changes
     remote: added 1 changesets with 1 changes to 1 files
  -  remote: KABOOM
  -  local stdout
  +  remote: KABOOM\r (esc)

     $ cd ..


What is happening is that no data is available in 'sshpeer.pipee' while the
command is executing.  As the command completes, local output is printed, and
then sshpeer.cleanup() is called.  When it calls 'self.pipeo.close()', the child
process is shutdown, flushing stderr.

As an experiment, I printed a line to stdout and another to stderr instead this
flush().  The stdout data was immediately available to the hg client, and none
of the stderr data was until the child exited.  At that point, pipee has all of
the buffered data, and it is read out and printed before the pipe is closed in
sshpeer.cleanup().  This is probably a known issue, since ui.write_err()
mentions that stderr may be buffered, and also flushes stderr.

It would be nice if there was a more general fix (there is one more test that
fails), but I'm not sure what it is.  I've seen (ancient) references [1] to
setvbuf() "crashing spectacularly" on some systems if any I/O has been done
already, so it seems worth avoiding.


https://sourceware.org/ml/gdb-patches/2013-08/msg00422.html

[1] https://groups.google.com/forum/#!msg/comp.lang.python/JT8LiYzYDEY/Qg9d1HwyjScJ

diff --git a/mercurial/hook.py b/mercurial/hook.py
--- a/mercurial/hook.py
+++ b/mercurial/hook.py
@@ -200,6 +200,11 @@
                 r = _pythonhook(ui, repo, name, hname, hookfn, args, throw) or r
             else:
                 r = _exthook(ui, repo, hname, cmd, args, throw) or r
+
+            # The stderr is fully buffered on Windows when connected to a pipe.
+            # A forcible flush is required to make small stderr data in the
+            # remote side available to the client immediately.
+            sys.stderr.flush()
     finally:
         if _redirect and oldstdout >= 0:
             os.dup2(oldstdout, stdoutno)


More information about the Mercurial-devel mailing list