D3444: tests: comprehensively test exit handling
indygreg (Gregory Szorc)
phabricator at mercurial-scm.org
Sun May 6 04:11:19 UTC 2018
indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.
REVISION SUMMARY
Rust `hg` currently has some test failures around exit handling.
This commit establishes some centralized tests around exit handling so
that we can unify the behavior of our Rust frontend and `python`.
There are some added tests that use a value other than an integer
or None for the exit code. The docs for sys.exit() say such a value
is allowed. However, Mercurial currently crashes in this case. Upcoming
commits will teach Mercurial to handle these values.
This does introduce a few Python 3 test failures. However, this test
already has a few failures. And the failures being introduced should
mostly go away with subsequent commits. So I think this is acceptable.
REPOSITORY
rHG Mercurial
REVISION DETAIL
https://phab.mercurial-scm.org/D3444
AFFECTED FILES
tests/test-dispatch.t
CHANGE DETAILS
diff --git a/tests/test-dispatch.t b/tests/test-dispatch.t
--- a/tests/test-dispatch.t
+++ b/tests/test-dispatch.t
@@ -217,3 +217,94 @@
[1]
#endif
+
+Test various exit codes and methods
+
+ $ cd $TESTTMP
+
+ $ cat >> $TESTTMP/exitmodes.py <<'EOF'
+ > from mercurial import pycompat, registrar, commands
+ > cmdtable = {}
+ > command = registrar.command(cmdtable)
+ > @command(b'exit', [], b'[MODE] [VALUE]', norepo=True)
+ > def exitmodes(ui, mode, value=None):
+ > if mode == b'returnint':
+ > return int(value)
+ > elif mode == b'returnstring':
+ > # sysstr is to make testing easier, since Python 2 and 3 will
+ > # format bytes and unicode types differently when printed.
+ > return pycompat.sysstr(value)
+ > elif mode == b'returnnone':
+ > return None
+ > elif mode == b'returnempty':
+ > return
+ > elif mode == b'systemexitint':
+ > raise SystemExit(int(value))
+ > elif mode == b'systemexitstring':
+ > raise SystemExit(pycompat.sysstr(value))
+ > elif mode == b'systemexitnoarg':
+ > raise SystemExit()
+ > elif mode == b'systemexitnone':
+ > raise SystemExit(None)
+ > elif mode == b'returndict':
+ > return {'key1': 'value1'}
+ > elif mode == b'systemexitdict':
+ > raise SystemExit({'key1': 'value1'})
+ > else:
+ > raise Exception('unknown mode: %s' % mode)
+ > EOF
+
+ $ cat >> $HGRCPATH <<'EOF'
+ > [extensions]
+ > exitmodes = $TESTTMP/exitmodes.py
+ > EOF
+
+ $ hg exit returnint 42
+ [42]
+
+ $ hg exit returnstring 'some message'
+ Traceback (most recent call last):
+ File "*/hg", line *, in <module> (glob)
+ dispatch.run()
+ File "*/mercurial/dispatch.py", line *, in run (glob)
+ sys.exit(status & 255)
+ TypeError: unsupported operand type(s) for &: 'str' and 'int'
+ [1]
+
+ $ hg exit returnnone
+
+ $ hg exit returnempty
+
+ $ hg exit returndict
+ Traceback (most recent call last):
+ File "*/hg", line *, in <module> (glob)
+ dispatch.run()
+ File "*/mercurial/dispatch.py", line *, in run (glob)
+ sys.exit(status & 255)
+ TypeError: unsupported operand type(s) for &: 'dict' and 'int'
+ [1]
+
+ $ hg exit systemexitint 42
+ [42]
+
+ $ hg exit systemexitstring 'failure message'
+ Traceback (most recent call last):
+ File "*/hg", line *, in <module> (glob)
+ dispatch.run()
+ File "*/mercurial/dispatch.py", line *, in run (glob)
+ sys.exit(status & 255)
+ TypeError: unsupported operand type(s) for &: 'str' and 'int'
+ [1]
+
+ $ hg exit systemexitnoarg
+
+ $ hg exit systemexitnone
+
+ $ hg exit systemexitdict
+ Traceback (most recent call last):
+ File "*/hg", line *, in <module> (glob)
+ dispatch.run()
+ File "*/mercurial/dispatch.py", line *, in run (glob)
+ sys.exit(status & 255)
+ TypeError: unsupported operand type(s) for &: 'dict' and 'int'
+ [1]
To: indygreg, #hg-reviewers
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list