changeset 36530:bde0bd50f368

debugcommands: allow sending of simple commands with debugwireproto Previously, we only had support for low-level "raw" operations. A goal of `hg debugwireproto` is to allow easily performing higher-level primitives, such as sending a wire protocol command and reading its response. We implement a "command" action that does just this. Currently, we only support simple commands (those without payloads). We have basic support for sending command arguments. We don't yet support sending dictionary arguments. This will be implemented later. To prove it works, we add tests to test-ssh-proto.t that send some "listkeys" commands. Note: we don't observe/report os.read() events because these may not be deterministic. We instead observe/report the read() and readline() operations on the bufferedinputpipe. These *should* be deterministic. Differential Revision: https://phab.mercurial-scm.org/D2406
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 01 Mar 2018 08:27:30 -0800
parents 33c6f8f0388d
children 097ad1079192
files mercurial/debugcommands.py tests/test-ssh-proto.t
diffstat 2 files changed, 616 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/debugcommands.py	Fri Feb 23 09:40:12 2018 -0800
+++ b/mercurial/debugcommands.py	Thu Mar 01 08:27:30 2018 -0800
@@ -2614,6 +2614,21 @@
 
     Behaves like ``raw`` except flushes output afterwards.
 
+    command <X>
+    -----------
+
+    Send a request to run a named command, whose name follows the ``command``
+    string.
+
+    Arguments to the command are defined as lines in this block. The format of
+    each line is ``<key> <value>``. e.g.::
+
+       command listkeys
+           namespace bookmarks
+
+    Values are interpreted as Python b'' literals. This allows encoding
+    special byte sequences via backslash escaping.
+
     close
     -----
 
@@ -2713,6 +2728,29 @@
                 stdin.flush()
         elif action == 'flush':
             stdin.flush()
+        elif action.startswith('command'):
+            if not peer:
+                raise error.Abort(_('cannot send commands unless peer instance '
+                                    'is available'))
+
+            command = action.split(' ', 1)[1]
+
+            args = {}
+            for line in lines:
+                # We need to allow empty values.
+                fields = line.lstrip().split(' ', 1)
+                if len(fields) == 1:
+                    key = fields[0]
+                    value = ''
+                else:
+                    key, value = fields
+
+                args[key] = util.unescapestr(value)
+
+            ui.status(_('sending %s command\n') % command)
+            res = peer._call(command, **args)
+            ui.status(_('response: %s\n') % util.escapedata(res))
+
         elif action == 'close':
             peer.close()
         elif action == 'readavailable':
--- a/tests/test-ssh-proto.t	Fri Feb 23 09:40:12 2018 -0800
+++ b/tests/test-ssh-proto.t	Thu Mar 01 08:27:30 2018 -0800
@@ -1,3 +1,23 @@
+  $ cat > hgrc-sshv2 << EOF
+  > %include $HGRCPATH
+  > [experimental]
+  > sshpeer.advertise-v2 = true
+  > sshserver.support-v2 = true
+  > EOF
+
+Helper function to run protocol tests against multiple protocol versions.
+This is easier than using #testcases because managing differences between
+protocols with inline conditional output is hard to read.
+
+  $ debugwireproto() {
+  >   commands=`cat -`
+  >   echo 'testing ssh1'
+  >   echo "${commands}" | hg --verbose debugwireproto --localssh
+  >   echo ""
+  >   echo 'testing ssh2'
+  >   echo "${commands}" | HGRCPATH=$TESTTMP/hgrc-sshv2 hg --verbose debugwireproto --localssh
+  > }
+
   $ cat >> $HGRCPATH << EOF
   > [ui]
   > ssh = $PYTHON "$TESTDIR/dummyssh"
@@ -1252,3 +1272,561 @@
   e> read(-1) -> 49:
   e>     malformed handshake protocol: missing pairs 81\n
   e>     -\n
+
+  $ cd ..
+
+Test listkeys for listing namespaces
+
+  $ hg init empty
+  $ cd empty
+  $ debugwireproto << EOF
+  > command listkeys
+  >     namespace namespaces
+  > EOF
+  testing ssh1
+  creating ssh peer from handshake results
+  i> write(104) -> None:
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 4:
+  o>     384\n
+  o> readline() -> 384:
+  o>     capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
+  o> readline() -> 2:
+  o>     1\n
+  o> readline() -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(13) -> None:
+  i>     namespace 10\n
+  i> write(10) -> None: namespaces
+  i> flush() -> None
+  o> bufferedreadline() -> 3:
+  o>     30\n
+  o> bufferedread(30) -> 30:
+  o>     bookmarks	\n
+  o>     namespaces	\n
+  o>     phases	
+  response: bookmarks	\nnamespaces	\nphases	
+  
+  testing ssh2
+  creating ssh peer from handshake results
+  i> write(171) -> None:
+  i>     upgrade * proto=exp-ssh-v2-0001\n (glob)
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 62:
+  o>     upgraded * exp-ssh-v2-0001\n (glob)
+  o> readline() -> 4:
+  o>     383\n
+  o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
+  o> read(1) -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(13) -> None:
+  i>     namespace 10\n
+  i> write(10) -> None: namespaces
+  i> flush() -> None
+  o> bufferedreadline() -> 3:
+  o>     30\n
+  o> bufferedread(30) -> 30:
+  o>     bookmarks	\n
+  o>     namespaces	\n
+  o>     phases	
+  response: bookmarks	\nnamespaces	\nphases	
+
+  $ cd ..
+
+Test listkeys for bookmarks
+
+  $ hg init bookmarkrepo
+  $ cd bookmarkrepo
+  $ echo 0 > foo
+  $ hg add foo
+  $ hg -q commit -m initial
+  $ echo 1 > foo
+  $ hg commit -m second
+
+With no bookmarks set
+
+  $ debugwireproto << EOF
+  > command listkeys
+  >     namespace bookmarks
+  > EOF
+  testing ssh1
+  creating ssh peer from handshake results
+  i> write(104) -> None:
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 4:
+  o>     384\n
+  o> readline() -> 384:
+  o>     capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
+  o> readline() -> 2:
+  o>     1\n
+  o> readline() -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(12) -> None:
+  i>     namespace 9\n
+  i> write(9) -> None: bookmarks
+  i> flush() -> None
+  o> bufferedreadline() -> 2:
+  o>     0\n
+  response: 
+  
+  testing ssh2
+  creating ssh peer from handshake results
+  i> write(171) -> None:
+  i>     upgrade * proto=exp-ssh-v2-0001\n (glob)
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 62:
+  o>     upgraded * exp-ssh-v2-0001\n (glob)
+  o> readline() -> 4:
+  o>     383\n
+  o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
+  o> read(1) -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(12) -> None:
+  i>     namespace 9\n
+  i> write(9) -> None: bookmarks
+  i> flush() -> None
+  o> bufferedreadline() -> 2:
+  o>     0\n
+  response: 
+
+With a single bookmark set
+
+  $ hg book -r 0 bookA
+  $ debugwireproto << EOF
+  > command listkeys
+  >     namespace bookmarks
+  > EOF
+  testing ssh1
+  creating ssh peer from handshake results
+  i> write(104) -> None:
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 4:
+  o>     384\n
+  o> readline() -> 384:
+  o>     capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
+  o> readline() -> 2:
+  o>     1\n
+  o> readline() -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(12) -> None:
+  i>     namespace 9\n
+  i> write(9) -> None: bookmarks
+  i> flush() -> None
+  o> bufferedreadline() -> 3:
+  o>     46\n
+  o> bufferedread(46) -> 46: bookA	68986213bd4485ea51533535e3fc9e78007a711f
+  response: bookA	68986213bd4485ea51533535e3fc9e78007a711f
+  
+  testing ssh2
+  creating ssh peer from handshake results
+  i> write(171) -> None:
+  i>     upgrade * proto=exp-ssh-v2-0001\n (glob)
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 62:
+  o>     upgraded * exp-ssh-v2-0001\n (glob)
+  o> readline() -> 4:
+  o>     383\n
+  o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
+  o> read(1) -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(12) -> None:
+  i>     namespace 9\n
+  i> write(9) -> None: bookmarks
+  i> flush() -> None
+  o> bufferedreadline() -> 3:
+  o>     46\n
+  o> bufferedread(46) -> 46: bookA	68986213bd4485ea51533535e3fc9e78007a711f
+  response: bookA	68986213bd4485ea51533535e3fc9e78007a711f
+
+With multiple bookmarks set
+
+  $ hg book -r 1 bookB
+  $ debugwireproto << EOF
+  > command listkeys
+  >     namespace bookmarks
+  > EOF
+  testing ssh1
+  creating ssh peer from handshake results
+  i> write(104) -> None:
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 4:
+  o>     384\n
+  o> readline() -> 384:
+  o>     capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
+  o> readline() -> 2:
+  o>     1\n
+  o> readline() -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(12) -> None:
+  i>     namespace 9\n
+  i> write(9) -> None: bookmarks
+  i> flush() -> None
+  o> bufferedreadline() -> 3:
+  o>     93\n
+  o> bufferedread(93) -> 93:
+  o>     bookA	68986213bd4485ea51533535e3fc9e78007a711f\n
+  o>     bookB	1880f3755e2e52e3199e0ee5638128b08642f34d
+  response: bookA	68986213bd4485ea51533535e3fc9e78007a711f\nbookB	1880f3755e2e52e3199e0ee5638128b08642f34d
+  
+  testing ssh2
+  creating ssh peer from handshake results
+  i> write(171) -> None:
+  i>     upgrade * proto=exp-ssh-v2-0001\n (glob)
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 62:
+  o>     upgraded * exp-ssh-v2-0001\n (glob)
+  o> readline() -> 4:
+  o>     383\n
+  o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
+  o> read(1) -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(12) -> None:
+  i>     namespace 9\n
+  i> write(9) -> None: bookmarks
+  i> flush() -> None
+  o> bufferedreadline() -> 3:
+  o>     93\n
+  o> bufferedread(93) -> 93:
+  o>     bookA	68986213bd4485ea51533535e3fc9e78007a711f\n
+  o>     bookB	1880f3755e2e52e3199e0ee5638128b08642f34d
+  response: bookA	68986213bd4485ea51533535e3fc9e78007a711f\nbookB	1880f3755e2e52e3199e0ee5638128b08642f34d
+
+  $ cd ..
+
+Test listkeys for phases
+
+  $ hg init phasesrepo
+  $ cd phasesrepo
+
+Phases on empty repo
+
+  $ debugwireproto << EOF
+  > command listkeys
+  >     namespace phases
+  > EOF
+  testing ssh1
+  creating ssh peer from handshake results
+  i> write(104) -> None:
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 4:
+  o>     384\n
+  o> readline() -> 384:
+  o>     capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
+  o> readline() -> 2:
+  o>     1\n
+  o> readline() -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(12) -> None:
+  i>     namespace 6\n
+  i> write(6) -> None: phases
+  i> flush() -> None
+  o> bufferedreadline() -> 3:
+  o>     15\n
+  o> bufferedread(15) -> 15: publishing	True
+  response: publishing	True
+  
+  testing ssh2
+  creating ssh peer from handshake results
+  i> write(171) -> None:
+  i>     upgrade * proto=exp-ssh-v2-0001\n (glob)
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 62:
+  o>     upgraded * exp-ssh-v2-0001\n (glob)
+  o> readline() -> 4:
+  o>     383\n
+  o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
+  o> read(1) -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(12) -> None:
+  i>     namespace 6\n
+  i> write(6) -> None: phases
+  i> flush() -> None
+  o> bufferedreadline() -> 3:
+  o>     15\n
+  o> bufferedread(15) -> 15: publishing	True
+  response: publishing	True
+
+Create some commits
+
+  $ echo 0 > foo
+  $ hg add foo
+  $ hg -q commit -m initial
+  $ hg phase --public
+  $ echo 1 > foo
+  $ hg commit -m 'head 1 commit 1'
+  $ echo 2 > foo
+  $ hg commit -m 'head 1 commit 2'
+  $ hg -q up 0
+  $ echo 1a > foo
+  $ hg commit -m 'head 2 commit 1'
+  created new head
+  $ echo 2a > foo
+  $ hg commit -m 'head 2 commit 2'
+
+Two draft heads
+
+  $ debugwireproto << EOF
+  > command listkeys
+  >     namespace phases
+  > EOF
+  testing ssh1
+  creating ssh peer from handshake results
+  i> write(104) -> None:
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 4:
+  o>     384\n
+  o> readline() -> 384:
+  o>     capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
+  o> readline() -> 2:
+  o>     1\n
+  o> readline() -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(12) -> None:
+  i>     namespace 6\n
+  i> write(6) -> None: phases
+  i> flush() -> None
+  o> bufferedreadline() -> 4:
+  o>     101\n
+  o> bufferedread(101) -> 101:
+  o>     20b8a89289d80036e6c4e87c2083e3bea1586637	1\n
+  o>     c4750011d906c18ea2f0527419cbc1a544435150	1\n
+  o>     publishing	True
+  response: 20b8a89289d80036e6c4e87c2083e3bea1586637	1\nc4750011d906c18ea2f0527419cbc1a544435150	1\npublishing	True
+  
+  testing ssh2
+  creating ssh peer from handshake results
+  i> write(171) -> None:
+  i>     upgrade * proto=exp-ssh-v2-0001\n (glob)
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 62:
+  o>     upgraded * exp-ssh-v2-0001\n (glob)
+  o> readline() -> 4:
+  o>     383\n
+  o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
+  o> read(1) -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(12) -> None:
+  i>     namespace 6\n
+  i> write(6) -> None: phases
+  i> flush() -> None
+  o> bufferedreadline() -> 4:
+  o>     101\n
+  o> bufferedread(101) -> 101:
+  o>     20b8a89289d80036e6c4e87c2083e3bea1586637	1\n
+  o>     c4750011d906c18ea2f0527419cbc1a544435150	1\n
+  o>     publishing	True
+  response: 20b8a89289d80036e6c4e87c2083e3bea1586637	1\nc4750011d906c18ea2f0527419cbc1a544435150	1\npublishing	True
+
+Single draft head
+
+  $ hg phase --public -r 2
+  $ debugwireproto << EOF
+  > command listkeys
+  >     namespace phases
+  > EOF
+  testing ssh1
+  creating ssh peer from handshake results
+  i> write(104) -> None:
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 4:
+  o>     384\n
+  o> readline() -> 384:
+  o>     capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
+  o> readline() -> 2:
+  o>     1\n
+  o> readline() -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(12) -> None:
+  i>     namespace 6\n
+  i> write(6) -> None: phases
+  i> flush() -> None
+  o> bufferedreadline() -> 3:
+  o>     58\n
+  o> bufferedread(58) -> 58:
+  o>     c4750011d906c18ea2f0527419cbc1a544435150	1\n
+  o>     publishing	True
+  response: c4750011d906c18ea2f0527419cbc1a544435150	1\npublishing	True
+  
+  testing ssh2
+  creating ssh peer from handshake results
+  i> write(171) -> None:
+  i>     upgrade * proto=exp-ssh-v2-0001\n (glob)
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 62:
+  o>     upgraded * exp-ssh-v2-0001\n (glob)
+  o> readline() -> 4:
+  o>     383\n
+  o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
+  o> read(1) -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(12) -> None:
+  i>     namespace 6\n
+  i> write(6) -> None: phases
+  i> flush() -> None
+  o> bufferedreadline() -> 3:
+  o>     58\n
+  o> bufferedread(58) -> 58:
+  o>     c4750011d906c18ea2f0527419cbc1a544435150	1\n
+  o>     publishing	True
+  response: c4750011d906c18ea2f0527419cbc1a544435150	1\npublishing	True
+
+All public heads
+
+  $ hg phase --public -r 4
+  $ debugwireproto << EOF
+  > command listkeys
+  >     namespace phases
+  > EOF
+  testing ssh1
+  creating ssh peer from handshake results
+  i> write(104) -> None:
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 4:
+  o>     384\n
+  o> readline() -> 384:
+  o>     capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
+  o> readline() -> 2:
+  o>     1\n
+  o> readline() -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(12) -> None:
+  i>     namespace 6\n
+  i> write(6) -> None: phases
+  i> flush() -> None
+  o> bufferedreadline() -> 3:
+  o>     15\n
+  o> bufferedread(15) -> 15: publishing	True
+  response: publishing	True
+  
+  testing ssh2
+  creating ssh peer from handshake results
+  i> write(171) -> None:
+  i>     upgrade * proto=exp-ssh-v2-0001\n (glob)
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 62:
+  o>     upgraded * exp-ssh-v2-0001\n (glob)
+  o> readline() -> 4:
+  o>     383\n
+  o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
+  o> read(1) -> 1:
+  o>     \n
+  sending listkeys command
+  i> write(9) -> None:
+  i>     listkeys\n
+  i> write(12) -> None:
+  i>     namespace 6\n
+  i> write(6) -> None: phases
+  i> flush() -> None
+  o> bufferedreadline() -> 3:
+  o>     15\n
+  o> bufferedread(15) -> 15: publishing	True
+  response: publishing	True