indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Callers of established wire protocol commands expect the
  response from that command to be decoded into a data structure.
  It's not very useful if callers get back a stream of bytes and
  don't know how they should be interpreted - especially since that
  stream of bytes varies by wire protocol and even the transport
  within that protocol version.
  
  This commit establishes decoding functions for various command
  responses so callers of those commands get the response type
  they expect.
  
  In theory, this should make the version 2 HTTP peer usable for
  various operations. But I haven't tested to confirm.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D3381

AFFECTED FILES
  mercurial/wireprotov2peer.py
  tests/test-wireproto-command-branchmap.t
  tests/test-wireproto-command-heads.t
  tests/test-wireproto-command-known.t
  tests/test-wireproto-command-listkeys.t
  tests/test-wireproto-command-lookup.t
  tests/test-wireproto-command-pushkey.t

CHANGE DETAILS

diff --git a/tests/test-wireproto-command-pushkey.t 
b/tests/test-wireproto-command-pushkey.t
--- a/tests/test-wireproto-command-pushkey.t
+++ b/tests/test-wireproto-command-pushkey.t
@@ -53,7 +53,7 @@
   received frame(size=*; request=1; stream=2; streamflags=stream-begin; 
type=bytes-response; flags=eos|cbor) (glob)
   s>     0\r\n
   s>     \r\n
-  response: [True]
+  response: True
 
   $ sendhttpv2peer << EOF
   > command listkeys
@@ -84,6 +84,6 @@
   received frame(size=45; request=1; stream=2; streamflags=stream-begin; 
type=bytes-response; flags=eos|cbor)
   s>     0\r\n
   s>     \r\n
-  response: [{b'@': b'426bada5c67598ca65036d57d9e4b64b0c1ce7a0'}]
+  response: {b'@': b'426bada5c67598ca65036d57d9e4b64b0c1ce7a0'}
 
   $ cat error.log
diff --git a/tests/test-wireproto-command-lookup.t 
b/tests/test-wireproto-command-lookup.t
--- a/tests/test-wireproto-command-lookup.t
+++ b/tests/test-wireproto-command-lookup.t
@@ -50,6 +50,6 @@
   received frame(size=*; request=1; stream=2; streamflags=stream-begin; 
type=bytes-response; flags=eos|cbor) (glob)
   s>     0\r\n
   s>     \r\n
-  response: [b'Bk\xad\xa5\xc6u\x98\xcae\x03mW\xd9\xe4\xb6K\x0c\x1c\xe7\xa0']
+  response: b'Bk\xad\xa5\xc6u\x98\xcae\x03mW\xd9\xe4\xb6K\x0c\x1c\xe7\xa0'
 
   $ cat error.log
diff --git a/tests/test-wireproto-command-listkeys.t 
b/tests/test-wireproto-command-listkeys.t
--- a/tests/test-wireproto-command-listkeys.t
+++ b/tests/test-wireproto-command-listkeys.t
@@ -54,7 +54,7 @@
   received frame(size=32; request=1; stream=2; streamflags=stream-begin; 
type=bytes-response; flags=eos|cbor)
   s>     0\r\n
   s>     \r\n
-  response: [{b'bookmarks': b'', b'namespaces': b'', b'phases': b''}]
+  response: {b'bookmarks': b'', b'namespaces': b'', b'phases': b''}
 
 Request for phases works
 
@@ -87,7 +87,7 @@
   received frame(size=61; request=1; stream=2; streamflags=stream-begin; 
type=bytes-response; flags=eos|cbor)
   s>     0\r\n
   s>     \r\n
-  response: [{b'be0ef73c17ade3fc89dc41701eb9fc3a91b58282': b'1', 
b'publishing': b'True'}]
+  response: {b'be0ef73c17ade3fc89dc41701eb9fc3a91b58282': b'1', b'publishing': 
b'True'}
 
 Request for bookmarks works
 
@@ -120,6 +120,6 @@
   received frame(size=45; request=1; stream=2; streamflags=stream-begin; 
type=bytes-response; flags=eos|cbor)
   s>     0\r\n
   s>     \r\n
-  response: [{b'@': b'26805aba1e600a82e93661149f2313866a221a7b'}]
+  response: {b'@': b'26805aba1e600a82e93661149f2313866a221a7b'}
 
   $ cat error.log
diff --git a/tests/test-wireproto-command-known.t 
b/tests/test-wireproto-command-known.t
--- a/tests/test-wireproto-command-known.t
+++ b/tests/test-wireproto-command-known.t
@@ -50,7 +50,7 @@
   received frame(size=1; request=1; stream=2; streamflags=stream-begin; 
type=bytes-response; flags=eos|cbor)
   s>     0\r\n
   s>     \r\n
-  response: [b'']
+  response: []
 
 Single known node works
 
@@ -83,7 +83,7 @@
   received frame(size=2; request=1; stream=2; streamflags=stream-begin; 
type=bytes-response; flags=eos|cbor)
   s>     0\r\n
   s>     \r\n
-  response: [b'1']
+  response: [True]
 
 Multiple nodes works
 
@@ -116,6 +116,6 @@
   received frame(size=4; request=1; stream=2; streamflags=stream-begin; 
type=bytes-response; flags=eos|cbor)
   s>     0\r\n
   s>     \r\n
-  response: [b'101']
+  response: [True, False, True]
 
   $ cat error.log
diff --git a/tests/test-wireproto-command-heads.t 
b/tests/test-wireproto-command-heads.t
--- a/tests/test-wireproto-command-heads.t
+++ b/tests/test-wireproto-command-heads.t
@@ -58,7 +58,7 @@
   received frame(size=64; request=1; stream=2; streamflags=stream-begin; 
type=bytes-response; flags=eos|cbor)
   s>     0\r\n
   s>     \r\n
-  response: 
[[b'\x1dok\x91\xd4J\xab\xa6\xd5\xe5\x80\xbc0\xa9\x94\x850\xdb\xe0\x0b', 
b'\xaeI.6\xb0\xc83\x9f\xfa\xf3(\xd0\x0b\x85\xb4R]\xe1\x16^', 
b')Dm-\xc5A\x9c_\x97Dz\x8b\xc0b\xe4\xcc2\x8b\xf2A']]
+  response: 
[b'\x1dok\x91\xd4J\xab\xa6\xd5\xe5\x80\xbc0\xa9\x94\x850\xdb\xe0\x0b', 
b'\xaeI.6\xb0\xc83\x9f\xfa\xf3(\xd0\x0b\x85\xb4R]\xe1\x16^', 
b')Dm-\xc5A\x9c_\x97Dz\x8b\xc0b\xe4\xcc2\x8b\xf2A']
 
 Requesting just the public heads works
 
@@ -91,6 +91,6 @@
   received frame(size=22; request=1; stream=2; streamflags=stream-begin; 
type=bytes-response; flags=eos|cbor)
   s>     0\r\n
   s>     \r\n
-  response: [[b'x\xd2\xdc\xa46\xb2\xf5\xb1\x88\xac&~)\xb8\x1e\x07&m8\xfc']]
+  response: [b'x\xd2\xdc\xa46\xb2\xf5\xb1\x88\xac&~)\xb8\x1e\x07&m8\xfc']
 
   $ cat error.log
diff --git a/tests/test-wireproto-command-branchmap.t 
b/tests/test-wireproto-command-branchmap.t
--- a/tests/test-wireproto-command-branchmap.t
+++ b/tests/test-wireproto-command-branchmap.t
@@ -67,6 +67,6 @@
   received frame(size=112; request=1; stream=2; streamflags=stream-begin; 
type=bytes-response; flags=eos|cbor)
   s>     0\r\n
   s>     \r\n
-  response: [{b'branch1': 
[b'\xb5\xfa\xac\xdf\xd2c7h\xcb1R3l\xc0\x953\x81&f\x88'], b'branch2': 
[b'"Aa\xc7X\x9a\xa4\x8f\xa8:H\xfe\xff^\x95\xb5j\xe3\'\xfc'], b'default': 
[b'&\x80Z\xba\x1e`\n\x82\xe96a\x14\x9f#\x13\x86j"\x1a{', 
b'\xbe\x0e\xf7<\x17\xad\xe3\xfc\x89\xdcAp\x1e\xb9\xfc:\x91\xb5\x82\x82']}]
+  response: {b'branch1': 
[b'\xb5\xfa\xac\xdf\xd2c7h\xcb1R3l\xc0\x953\x81&f\x88'], b'branch2': 
[b'"Aa\xc7X\x9a\xa4\x8f\xa8:H\xfe\xff^\x95\xb5j\xe3\'\xfc'], b'default': 
[b'&\x80Z\xba\x1e`\n\x82\xe96a\x14\x9f#\x13\x86j"\x1a{', 
b'\xbe\x0e\xf7<\x17\xad\xe3\xfc\x89\xdcAp\x1e\xb9\xfc:\x91\xb5\x82\x82']}
 
   $ cat error.log
diff --git a/mercurial/wireprotov2peer.py b/mercurial/wireprotov2peer.py
--- a/mercurial/wireprotov2peer.py
+++ b/mercurial/wireprotov2peer.py
@@ -12,6 +12,7 @@
     cbor,
 )
 from . import (
+    encoding,
     error,
     util,
     wireprotoframing,
@@ -127,11 +128,52 @@
                 response.cbor = True
 
             if meta['eos']:
-                self._futures[frame.requestid].set_result(response)
+                # If the command has a decoder, resolve the future to the
+                # decoded value. Otherwise resolve to the rich response object.
+                decoder = COMMAND_DECODERS.get(response.command)
+
+                result = decoder(response) if decoder else response
+
+                self._futures[frame.requestid].set_result(result)
 
                 del self._requests[frame.requestid]
                 del self._futures[frame.requestid]
 
         else:
             raise error.ProgrammingError(
                 'unhandled action from clientreactor: %s' % action)
+
+def decodebranchmap(resp):
+    # Response should be a single CBOR map of branch name to array of nodes.
+    bm = next(resp.cborobjects())
+
+    return {encoding.tolocal(k): v for k, v in bm.items()}
+
+def decodeheads(resp):
+    # Array of node bytestrings.
+    return next(resp.cborobjects())
+
+def decodeknown(resp):
+    # Bytestring where each byte is a 0 or 1.
+    raw = next(resp.cborobjects())
+
+    return [True if c == '1' else False for c in raw]
+
+def decodelistkeys(resp):
+    # Map with bytestring keys and values.
+    return next(resp.cborobjects())
+
+def decodelookup(resp):
+    return next(resp.cborobjects())
+
+def decodepushkey(resp):
+    return next(resp.cborobjects())
+
+COMMAND_DECODERS = {
+    'branchmap': decodebranchmap,
+    'heads': decodeheads,
+    'known': decodeknown,
+    'listkeys': decodelistkeys,
+    'lookup': decodelookup,
+    'pushkey': decodepushkey,
+}



To: indygreg, #hg-reviewers
Cc: mercurial-devel
_______________________________________________
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Reply via email to