view tests/test-mq-qnew.t @ 36367:043e77f3be09

sshpeer: return framed file object when needed Currently, wireproto.wirepeer has a default implementation of _submitbatch() and sshv1peer has a very similar implementation. The main difference is that sshv1peer is aware of the total amount of bytes it can read whereas the default implementation reads the stream until no more data is returned. The default implementation works for HTTP, since there is a known end to HTTP responses (either Content-Length or 0 sized chunk). This commit teaches sshv1peer to use our just-introduced "cappedreader" class for wrapping a file object to limit the number of bytes that can be read. We do this by introducing an argument to specify whether the response is framed. If set, we returned a cappedreader instance instead of the raw pipe. _call() always has framed responses. So we set this argument unconditionally and then .read() the entirety of the result. Strictly speaking, we don't need to use cappedreader in this case and can inline frame decoding/read logic. But I like when things are consistent. The overhead should be negligible. _callstream() and _callcompressable() are special: whether framing is used depends on the specific command. So, we define a set of commands that have framed response. It currently only contains "batch." As a result of this change, the one-off implementation of _submitbatch() in sshv1peer can be removed since it is now safe to .read() the response's file object until end of stream. cappedreader takes care of not overrunning the frame. Differential Revision: https://phab.mercurial-scm.org/D2380
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 21 Feb 2018 08:35:48 -0800
parents 41ef02ba329b
children 57c462db87fd
line wrap: on
line source


  $ 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
  >     hg qnew .
  >     hg qnew ..
  >     hg qnew .hgignore
  >     hg qnew .mqfoo
  >     hg qnew 'foo#bar'
  >     hg qnew 'foo:bar'
  >     hg qnew "`echo foo; echo bar`"
  >     hg qnew ' foo'
  >     hg qnew 'foo '
  > 
  >     hg qinit -c
  > 
  >     echo '% qnew with name containing slash'
  >     hg qnew foo/
  >     hg qnew foo/bar.patch
  >     hg qnew foo
  >     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
  abort: "." cannot be used as the name of a patch
  abort: ".." cannot be used as the name of a patch
  abort: patch name cannot begin with ".hg"
  abort: patch name cannot begin with ".mq"
  abort: '#' cannot be used in the name of a patch
  abort: ':' cannot be used in the name of a patch
  abort: '\n' cannot be used in the name of a patch
  abort: patch name cannot begin or end with whitespace
  abort: patch name cannot begin or end with whitespace
  % qnew with name containing slash
  abort: path ends in directory separator: foo/
  abort: "foo" already exists as a directory
  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
  abort: missing: * (glob)
  % 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
  warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
  use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
  (no more unresolved files)
  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
  abort: "." cannot be used as the name of a patch
  abort: ".." cannot be used as the name of a patch
  abort: patch name cannot begin with ".hg"
  abort: patch name cannot begin with ".mq"
  abort: '#' cannot be used in the name of a patch
  abort: ':' cannot be used in the name of a patch
  abort: '\n' cannot be used in the name of a patch
  abort: patch name cannot begin or end with whitespace
  abort: patch name cannot begin or end with whitespace
  % qnew with name containing slash
  abort: path ends in directory separator: foo/
  abort: "foo" already exists as a directory
  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
  abort: missing: * (glob)
  % 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 
  
  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
  # User blue
  # Parent 
  
  % qnew -e -u with no username configured
  # HG changeset patch
  # User chartreuse
  # Parent 
  
  % 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
  warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
  use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
  (no more unresolved files)
  abort: cannot manage merge changesets
  $ rm -r sandbox

Test saving last-message.txt

  $ hg init repo
  $ cd repo

  $ cat > $TESTTMP/commitfailure.py <<EOF
  > from mercurial import error
  > def reposetup(ui, repo):
  >     class commitfailure(repo.__class__):
  >         def commit(self, *args, **kwargs):
  >             raise error.Abort('emulating unexpected abort')
  >     repo.__class__ = commitfailure
  > EOF
  $ cat >> .hg/hgrc <<EOF
  > [extensions]
  > # this failure occurs before editor invocation
  > commitfailure = $TESTTMP/commitfailure.py
  > EOF

  $ cat > $TESTTMP/editor.sh << EOF
  > echo "==== before editing"
  > cat \$1
  > echo "===="
  > echo "test saving last-message.txt" >> \$1
  > EOF

(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]
  $ test -f .hg/last-message.txt
  [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

  $ rm -f .hg/last-message.txt
  $ hg status
  $ HGEDITOR="sh $TESTTMP/editor.sh" hg qnew -e patch
  ==== before editing
  
  
  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
  ====
  note: commit message saved in .hg/last-message.txt
  transaction abort!
  rollback completed
  abort: pretxncommit.unexpectedabort hook exited with status 1
  [255]
  $ cat .hg/last-message.txt
  
  
  test saving last-message.txt

  $ cat >> .hg/hgrc <<EOF
  > [hooks]
  > pretxncommit.unexpectedabort =
  > EOF