# HG changeset patch
# User Gregory Szorc <gregory.sz...@gmail.com>
# Date 1502741560 25200
#      Mon Aug 14 13:12:40 2017 -0700
# Branch stable
# Node ID 0a33f202bca4ee7ea126e7638bb74b5d58775858
# Parent  7686cbb0ba4138c56d038d8d82ccc052bf9b60d7
tests: demonstrate that I/O error can lead to orphaned transaction (issue5658)

ui._write(), ui._write_err(), and ui.flush() all trap IOError and
re-raise as error.StdioError. If a caller doesn't catch StdioError
when writing to stdio, it could bubble all the way to dispatch.

This commit adds tests for I/O failures around transaction rollback.

It shows that an uncaught StdioError for printing "transaction abort!" can
lead to an abandonded transaction.

StdioError for hook output, however, it properly dealt with.

And errors during "rollback completed" can also result in wonkiness.

diff --git a/tests/test-rollback.t b/tests/test-rollback.t
--- a/tests/test-rollback.t
+++ b/tests/test-rollback.t
@@ -210,3 +210,99 @@ rollback disabled by config
   abort: rollback is disabled because it is unsafe
   (see `hg help -v rollback` for information)
   [255]
+
+  $ cd ..
+
+I/O errors on stdio are handled properly (issue5658)
+
+  $ cat > badui.py << EOF
+  > import errno
+  > from mercurial.i18n import _
+  > from mercurial import (
+  >     error,
+  >     ui as uimod,
+  > )
+  > 
+  > def txnabort(ui, repo, **kwargs):
+  >     ui.warn('warn during abort\n')
+  > 
+  > def uisetup(ui):
+  >     class badui(ui.__class__):
+  >         def write_err(self, *args, **opts):
+  >             errors = set(self.configlist('ui', 'ioerrors', []))
+  >             txnabort = _('transaction abort!\n') in args
+  >             txnaborthook = 'warn during abort\n' in args
+  >             txnrollback = _('rollback completed\n') in args
+  > 
+  >             if txnabort and 'txnabort' in errors:
+  >                 raise error.StdioError(IOError(errno.EPIPE, 'simulated 
epipe'))
+  >             if txnaborthook and 'txnaborthook' in errors:
+  >                 raise error.StdioError(IOError(errno.EBADF, 'simulated 
ebadf'))
+  >             if txnrollback and 'txnrollback' in errors:
+  >                 raise error.StdioError(IOError(errno.EIO, 'simulated eio'))
+  > 
+  >             return super(badui, self).write_err(*args, **opts)
+  >     ui.__class__ = badui
+  > 
+  > def reposetup(ui, repo):
+  >     ui.setconfig('hooks', 'txnabort.badui', txnabort, 'badui')
+  > EOF
+
+  $ cat >> $HGRCPATH << EOF
+  > [extensions]
+  > badui = $TESTTMP/badui.py
+  > EOF
+
+An I/O error writing "transaction abort" should still result in rollback
+
+  $ hg init ioerror-abort
+  $ cd ioerror-abort
+
+  $ echo 0 > foo
+  $ hg -q commit -A -m initial
+
+  $ echo 1 > foo
+  $ hg --config ui.ioerrors=txnabort --config hooks.pretxncommit=false commit 
-m 'error during abort message'
+  *: DeprecationWarning: use lock.release instead of del lock (glob)
+    return -1
+  [255]
+
+  $ hg commit -m 'commit 1'
+  abort: abandoned transaction found!
+  (run 'hg recover' to clean up transaction)
+  [255]
+
+  $ cd ..
+
+An I/O error during transaction abort callback should still result in rollback
+
+  $ hg init ioerror-abortcallback
+  $ cd ioerror-abortcallback
+
+  $ echo 0 > foo
+  $ hg -q commit -A -m initial
+
+  $ echo 1 > foo
+  $ hg --config ui.ioerrors=txnaborthook --config hooks.pretxncommit=false 
commit -m 'error during abort'
+  transaction abort!
+  error: txnabort.badui hook raised an exception: [Errno 9] simulated ebadf
+  (run with --traceback for stack trace)
+  rollback completed
+  abort: pretxncommit hook exited with status 1
+  [255]
+
+An I/O error writing "rollback completed" should still result in rollback
+
+  $ hg --config ui.ioerrors=txnrollback --config hooks.pretxncommit=false 
commit -m 'error during rollback message'
+  transaction abort!
+  warn during abort
+  rollback failed - please run hg recover
+  abort: pretxncommit hook exited with status 1
+  [255]
+
+  $ hg verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  1 files, 1 changesets, 1 total revisions
_______________________________________________
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Reply via email to