##// END OF EJS Templates
wireprotov2: implement commands as a generator of objects...
wireprotov2: implement commands as a generator of objects Previously, wire protocol version 2 inherited version 1's model of having separate types to represent the results of different wire protocol commands. As I implemented more powerful commands in future commits, I found I was using a common pattern of returning a special type to hold a generator. This meant the command function required a closure to do most of the work. That made logic flow more difficult to follow. I also noticed that many commands were effectively a sequence of objects to be CBOR encoded. I think it makes sense to define version 2 commands as generators. This way, commands can simply emit the data structures they wish to send to the client. This eliminates the need for a closure in command functions and removes encoding from the bodies of commands. As part of this commit, the handling of response objects has been moved into the serverreactor class. This puts the reactor in the driver's seat with regards to CBOR encoding and error handling. Having error handling in the function that emits frames is particularly important because exceptions in that function can lead to things getting in a bad state: I'm fairly certain that uncaught exceptions in the frame generator were causing deadlocks. I also introduced a dedicated error type for explicit error reporting in command handlers. This will be used in subsequent commits. There's still a bit of work to be done here, especially around formalizing the error handling "protocol." I've added yet another TODO to track this so we don't forget. Test output changed because we're using generators and no longer know we are at the end of the data until we hit the end of the generator. This means we can't emit the end-of-stream flag until we've exhausted the generator. Hence the introduction of 0-sized end-of-stream frames. Differential Revision: https://phab.mercurial-scm.org/D4472

File last commit:

r35722:41ef02ba default
r39595:07b58266 default
Show More
test-mq-qnew.t
321 lines | 8.2 KiB | text/troff | Tads3Lexer
Matt Mackall
tests: unify test-mq-qnew
r12466
$ catpatch() {
> cat $1 | sed -e "s/^\(# Parent \).*/\1/"
> }
$ echo "[extensions]" >> $HGRCPATH
$ echo "mq=" >> $HGRCPATH
$ runtest() {
> hg init mq
> cd mq
>
> echo a > a
> hg ci -Ama
>
> echo '% qnew should refuse bad patch names'
> hg qnew series
> hg qnew status
> hg qnew guards
Idan Kamara
mq: add '.' and '..' to list of forbidden patch names...
r14051 > hg qnew .
> hg qnew ..
Matt Mackall
tests: unify test-mq-qnew
r12466 > hg qnew .hgignore
> hg qnew .mqfoo
> hg qnew 'foo#bar'
> hg qnew 'foo:bar'
Augie Fackler
mq: ban \r and \n in patch names (issue4711)...
r25454 > hg qnew "`echo foo; echo bar`"
Yuya Nishihara
mq: reject new patch name containing leading/trailing whitespace...
r31556 > hg qnew ' foo'
> hg qnew 'foo '
Matt Mackall
tests: unify test-mq-qnew
r12466 >
> hg qinit -c
>
> echo '% qnew with name containing slash'
Martin Geisler
qnew: give better feedback when doing 'hg qnew foo/' (issue2464)
r12878 > hg qnew foo/
Matt Mackall
tests: unify test-mq-qnew
r12466 > hg qnew foo/bar.patch
Martin Geisler
qnew: distinguish between existing file and directory (issue2464)
r12879 > hg qnew foo
Matt Mackall
tests: unify test-mq-qnew
r12466 > hg qseries
> hg qpop
> hg qdelete foo/bar.patch
>
> echo '% qnew with uncommitted changes'
> echo a > somefile
> hg add somefile
> hg qnew uncommitted.patch
> hg st
> hg qseries
>
> echo '% qnew implies add'
> hg -R .hg/patches st
>
> echo '% qnew missing'
> hg qnew missing.patch missing
>
> echo '% qnew -m'
> hg qnew -m 'foo bar' mtest.patch
> catpatch .hg/patches/mtest.patch
>
> echo '% qnew twice'
> hg qnew first.patch
> hg qnew first.patch
>
> touch ../first.patch
> hg qimport ../first.patch
>
> echo '% qnew -f from a subdirectory'
> hg qpop -a
> mkdir d
> cd d
> echo b > b
> hg ci -Am t
> echo b >> b
> hg st
> hg qnew -g -f p
> catpatch ../.hg/patches/p
>
> echo '% qnew -u with no username configured'
> HGUSER= hg qnew -u blue red
> catpatch ../.hg/patches/red
>
> echo '% qnew -e -u with no username configured'
> HGUSER= hg qnew -e -u chartreuse fucsia
> catpatch ../.hg/patches/fucsia
>
> echo '% fail when trying to import a merge'
> hg init merge
> cd merge
> touch a
> hg ci -Am null
> echo a >> a
> hg ci -m a
> hg up -r 0
> echo b >> a
> hg ci -m b
> hg merge -f 1
> hg resolve --mark a
> hg qnew -f merge
>
> cd ../../..
> rm -r mq
> }
plain headers
$ echo "[mq]" >> $HGRCPATH
$ echo "plain=true" >> $HGRCPATH
$ mkdir sandbox
$ (cd sandbox ; runtest)
adding a
% qnew should refuse bad patch names
abort: "series" cannot be used as the name of a patch
abort: "status" cannot be used as the name of a patch
abort: "guards" cannot be used as the name of a patch
Idan Kamara
mq: add '.' and '..' to list of forbidden patch names...
r14051 abort: "." cannot be used as the name of a patch
abort: ".." cannot be used as the name of a patch
Idan Kamara
mq: be more explicit on invalid patch name message
r14054 abort: patch name cannot begin with ".hg"
abort: patch name cannot begin with ".mq"
Augie Fackler
mq: use %r to format illegal characters instead of manually quoting...
r25453 abort: '#' cannot be used in the name of a patch
abort: ':' cannot be used in the name of a patch
Augie Fackler
mq: ban \r and \n in patch names (issue4711)...
r25454 abort: '\n' cannot be used in the name of a patch
Yuya Nishihara
mq: reject new patch name containing leading/trailing whitespace...
r31556 abort: patch name cannot begin or end with whitespace
abort: patch name cannot begin or end with whitespace
Matt Mackall
tests: unify test-mq-qnew
r12466 % qnew with name containing slash
Matt Harbison
tests: remove (glob) annotations that were only for '\' matches...
r35394 abort: path ends in directory separator: foo/
Martin Geisler
qnew: distinguish between existing file and directory (issue2464)
r12879 abort: "foo" already exists as a directory
Matt Mackall
tests: unify test-mq-qnew
r12466 foo/bar.patch
popping foo/bar.patch
patch queue now empty
% qnew with uncommitted changes
uncommitted.patch
% qnew implies add
A .hgignore
A series
A uncommitted.patch
% qnew missing
Mads Kiilerich
tests: hide 'No such file or directory' messages...
r15521 abort: missing: * (glob)
Matt Mackall
tests: unify test-mq-qnew
r12466 % qnew -m
foo bar
% qnew twice
abort: patch "first.patch" already exists
abort: patch "first.patch" already exists
% qnew -f from a subdirectory
popping first.patch
popping mtest.patch
popping uncommitted.patch
patch queue now empty
adding d/b
M d/b
diff --git a/d/b b/d/b
--- a/d/b
+++ b/d/b
@@ -1,1 +1,2 @@
b
+b
% qnew -u with no username configured
From: blue
% qnew -e -u with no username configured
From: chartreuse
% fail when trying to import a merge
adding a
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
created new head
merging a
Siddharth Agarwal
simplemerge: move conflict warning message to filemerge...
r26614 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
Matt Mackall
tests: unify test-mq-qnew
r12466 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
Pulkit Goyal
merge: add `--abort` flag which can abort the merge...
r35722 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
Pierre-Yves David
resolve: add parenthesis around "no more unresolved files" message...
r21947 (no more unresolved files)
Matt Mackall
tests: unify test-mq-qnew
r12466 abort: cannot manage merge changesets
$ rm -r sandbox
hg headers
$ echo "plain=false" >> $HGRCPATH
$ mkdir sandbox
$ (cd sandbox ; runtest)
adding a
% qnew should refuse bad patch names
abort: "series" cannot be used as the name of a patch
abort: "status" cannot be used as the name of a patch
abort: "guards" cannot be used as the name of a patch
Idan Kamara
mq: add '.' and '..' to list of forbidden patch names...
r14051 abort: "." cannot be used as the name of a patch
abort: ".." cannot be used as the name of a patch
Idan Kamara
mq: be more explicit on invalid patch name message
r14054 abort: patch name cannot begin with ".hg"
abort: patch name cannot begin with ".mq"
Augie Fackler
mq: use %r to format illegal characters instead of manually quoting...
r25453 abort: '#' cannot be used in the name of a patch
abort: ':' cannot be used in the name of a patch
Augie Fackler
mq: ban \r and \n in patch names (issue4711)...
r25454 abort: '\n' cannot be used in the name of a patch
Yuya Nishihara
mq: reject new patch name containing leading/trailing whitespace...
r31556 abort: patch name cannot begin or end with whitespace
abort: patch name cannot begin or end with whitespace
Matt Mackall
tests: unify test-mq-qnew
r12466 % qnew with name containing slash
Matt Harbison
tests: remove (glob) annotations that were only for '\' matches...
r35394 abort: path ends in directory separator: foo/
Martin Geisler
qnew: distinguish between existing file and directory (issue2464)
r12879 abort: "foo" already exists as a directory
Matt Mackall
tests: unify test-mq-qnew
r12466 foo/bar.patch
popping foo/bar.patch
patch queue now empty
% qnew with uncommitted changes
uncommitted.patch
% qnew implies add
A .hgignore
A series
A uncommitted.patch
% qnew missing
Mads Kiilerich
tests: hide 'No such file or directory' messages...
r15521 abort: missing: * (glob)
Matt Mackall
tests: unify test-mq-qnew
r12466 % qnew -m
# HG changeset patch
# Parent
foo bar
% qnew twice
abort: patch "first.patch" already exists
abort: patch "first.patch" already exists
% qnew -f from a subdirectory
popping first.patch
popping mtest.patch
popping uncommitted.patch
patch queue now empty
adding d/b
M d/b
# HG changeset patch
# Parent
Mads Kiilerich
mq: correctly make an empty line after description in new patches...
r22519
Matt Mackall
tests: unify test-mq-qnew
r12466 diff --git a/d/b b/d/b
--- a/d/b
+++ b/d/b
@@ -1,1 +1,2 @@
b
+b
% qnew -u with no username configured
# HG changeset patch
Mads Kiilerich
mq: write headers for new HG patches in the same order as export (BC)
r22520 # User blue
Matt Mackall
tests: unify test-mq-qnew
r12466 # Parent
Mads Kiilerich
mq: correctly make an empty line after description in new patches...
r22519
Matt Mackall
tests: unify test-mq-qnew
r12466 % qnew -e -u with no username configured
# HG changeset patch
Mads Kiilerich
mq: write headers for new HG patches in the same order as export (BC)
r22520 # User chartreuse
Matt Mackall
tests: unify test-mq-qnew
r12466 # Parent
Mads Kiilerich
mq: correctly make an empty line after description in new patches...
r22519
Matt Mackall
tests: unify test-mq-qnew
r12466 % fail when trying to import a merge
adding a
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
created new head
merging a
Siddharth Agarwal
simplemerge: move conflict warning message to filemerge...
r26614 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
Matt Mackall
tests: unify test-mq-qnew
r12466 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
Pulkit Goyal
merge: add `--abort` flag which can abort the merge...
r35722 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
Pierre-Yves David
resolve: add parenthesis around "no more unresolved files" message...
r21947 (no more unresolved files)
Matt Mackall
tests: unify test-mq-qnew
r12466 abort: cannot manage merge changesets
$ rm -r sandbox
FUJIWARA Katsunori
qnew: save manually edited commit message into ".hg/last-message.txt"...
r20768
Test saving last-message.txt
$ hg init repo
$ cd repo
Sean Farley
tests: use TESTTMP instead of TESTDIR...
r20859 $ cat > $TESTTMP/commitfailure.py <<EOF
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 > from mercurial import error
FUJIWARA Katsunori
qnew: save manually edited commit message into ".hg/last-message.txt"...
r20768 > def reposetup(ui, repo):
> class commitfailure(repo.__class__):
> def commit(self, *args, **kwargs):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 > raise error.Abort('emulating unexpected abort')
FUJIWARA Katsunori
qnew: save manually edited commit message into ".hg/last-message.txt"...
r20768 > repo.__class__ = commitfailure
> EOF
FUJIWARA Katsunori
qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21234 $ cat >> .hg/hgrc <<EOF
FUJIWARA Katsunori
qnew: save manually edited commit message into ".hg/last-message.txt"...
r20768 > [extensions]
FUJIWARA Katsunori
qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21234 > # this failure occurs before editor invocation
Sean Farley
tests: use TESTTMP instead of TESTDIR...
r20859 > commitfailure = $TESTTMP/commitfailure.py
FUJIWARA Katsunori
qnew: save manually edited commit message into ".hg/last-message.txt"...
r20768 > EOF
Sean Farley
tests: use TESTTMP instead of TESTDIR...
r20859 $ cat > $TESTTMP/editor.sh << EOF
FUJIWARA Katsunori
qnew: save manually edited commit message into ".hg/last-message.txt"...
r20768 > echo "==== before editing"
> cat \$1
> echo "===="
> echo "test saving last-message.txt" >> \$1
> EOF
FUJIWARA Katsunori
qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21234 (test that editor is not invoked before transaction starting)
$ rm -f .hg/last-message.txt
$ HGEDITOR="sh $TESTTMP/editor.sh" hg qnew -e patch
abort: emulating unexpected abort
[255]
Danek Duvall
tests: cat error messages are different on Solaris
r21930 $ test -f .hg/last-message.txt
FUJIWARA Katsunori
qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21234 [1]
(test that editor is invoked and commit message is saved into
"last-message.txt")
$ cat >> .hg/hgrc <<EOF
> [extensions]
> commitfailure = !
> [hooks]
> # this failure occurs after editor invocation
> pretxncommit.unexpectedabort = false
> EOF
FUJIWARA Katsunori
qnew: save manually edited commit message into ".hg/last-message.txt"...
r20768 $ rm -f .hg/last-message.txt
FUJIWARA Katsunori
mq: use the editor gotten by "getcommiteditor()" instead of "ui.edit()" (qnew)...
r21421 $ hg status
Sean Farley
tests: use TESTTMP instead of TESTDIR...
r20859 $ HGEDITOR="sh $TESTTMP/editor.sh" hg qnew -e patch
FUJIWARA Katsunori
qnew: save manually edited commit message into ".hg/last-message.txt"...
r20768 ==== before editing
FUJIWARA Katsunori
qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21234
FUJIWARA Katsunori
mq: use the editor gotten by "getcommiteditor()" instead of "ui.edit()" (qnew)...
r21421
HG: Enter commit message. Lines beginning with 'HG:' are removed.
HG: Leave message empty to use default message.
HG: --
HG: user: test
HG: branch 'default'
HG: no files changed
FUJIWARA Katsunori
qnew: save manually edited commit message into ".hg/last-message.txt"...
r20768 ====
Laurent Charignon
localrepo: put bookmark move following commit in one transaction...
r26998 note: commit message saved in .hg/last-message.txt
FUJIWARA Katsunori
qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21234 transaction abort!
rollback completed
abort: pretxncommit.unexpectedabort hook exited with status 1
FUJIWARA Katsunori
qnew: save manually edited commit message into ".hg/last-message.txt"...
r20768 [255]
$ cat .hg/last-message.txt
FUJIWARA Katsunori
qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21234
FUJIWARA Katsunori
mq: use the editor gotten by "getcommiteditor()" instead of "ui.edit()" (qnew)...
r21421
FUJIWARA Katsunori
qnew: save manually edited commit message into ".hg/last-message.txt"...
r20768 test saving last-message.txt
FUJIWARA Katsunori
qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21234 $ cat >> .hg/hgrc <<EOF
> [hooks]
> pretxncommit.unexpectedabort =
> EOF