annotate tests/flagprocessorext.py @ 37054:40206e227412

wireproto: define and implement protocol for issuing requests The existing HTTP and SSH wire protocols suffer from a host of flaws and shortcomings. I've been wanting to rewrite the protocol for a while now. Supporting partial clone - which will require new wire protocol commands and capabilities - and other advanced server functionality will be much easier if we start from a clean slate and don't have to be constrained by limitations of the existing wire protocol. This commit starts to introduce a new data exchange format for use over the wire protocol. The new protocol is built on top of "frames," which are atomic units of metadata + data. Frames will make it easier to implement proxies and other mechanisms that want to inspect data without having to maintain state. The existing frame metadata is very minimal and it will evolve heavily. (We will eventually support things like concurrent requests, out-of-order responses, compression, side-channels for status updates, etc. Some of these will require additions to the frame header.) Another benefit of frames is that all reads are of a fixed size. A reader works by consuming a frame header, extracting the payload length, then reading that many bytes. No lookahead, buffering, or memory reallocations are needed. The new protocol attempts to be transport agnostic. I want all that's required to use the new protocol to be a pair of unidirectional, half-duplex pipes. (Yes, we will eventually make use of full-duplex pipes, but that's for another commit.) Notably, when the SSH transport switches to this new protocol, stderr will be unused. This is by design: the lack of stderr on HTTP harms protocol behavior there. By shoehorning everything into a pair of pipes, we can have more consistent behavior across transports. We currently only define the client side parts of the new protocol, specifically the bits for requesting that a command run. This keeps the new code and feature small and somewhat easy to review. We add support to `hg debugwireproto` for writing frames into HTTP request bodies. Our tests that issue commands to the new HTTP endpoint have been updated to transmit frames. The server bits haven't been touched to consume the frames yet. This will occur in the next commit... Astute readers may notice that the command name is transmitted in both the HTTP request URL and the command request frame. This is partially a kludge from me initially implementing the frame-based protocol for SSH first. But it is also a feature: I intend to eventually support issuing multiple commands per HTTP request. This will allow us to replace the abomination that is the "batch" wire protocol command with a protocol-level mechanism for performing multi-dispatch. Because I want the frame-based protocol to be as similar as possible across transports, I'd rather we (redundantly) include the command name in the frame than differ behavior between transports that have out-of-band routing information (like HTTP) readily available. Differential Revision: https://phab.mercurial-scm.org/D2851
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 19 Mar 2018 16:49:53 -0700
parents 83246d6920f2
children 6c7a6b04b274
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
30745
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
1 # coding=UTF-8
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
2
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
3 from __future__ import absolute_import
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
4
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
5 import base64
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
6 import zlib
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
7
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
8 from mercurial import (
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
9 changegroup,
31832
77f746e5383a test-flagprocessor: use changegroup3 in bundle2
Jun Wu <quark@fb.com>
parents: 30745
diff changeset
10 exchange,
30745
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
11 extensions,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
12 filelog,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
13 revlog,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
14 util,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
15 )
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
16
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
17 # Test only: These flags are defined here only in the context of testing the
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
18 # behavior of the flag processor. The canonical way to add flags is to get in
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
19 # touch with the community and make them known in revlog.
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
20 REVIDX_NOOP = (1 << 3)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
21 REVIDX_BASE64 = (1 << 2)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
22 REVIDX_GZIP = (1 << 1)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
23 REVIDX_FAIL = 1
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
24
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
25 def validatehash(self, text):
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
26 return True
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
27
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
28 def bypass(self, text):
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
29 return False
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
30
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
31 def noopdonothing(self, text):
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
32 return (text, True)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
33
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
34 def b64encode(self, text):
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
35 return (base64.b64encode(text), False)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
36
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
37 def b64decode(self, text):
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
38 return (base64.b64decode(text), True)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
39
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
40 def gzipcompress(self, text):
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
41 return (zlib.compress(text), False)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
42
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
43 def gzipdecompress(self, text):
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
44 return (zlib.decompress(text), True)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
45
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
46 def supportedoutgoingversions(orig, repo):
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
47 versions = orig(repo)
36152
83246d6920f2 py3: use b'' for changegroup version literals
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35570
diff changeset
48 versions.discard(b'01')
83246d6920f2 py3: use b'' for changegroup version literals
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35570
diff changeset
49 versions.discard(b'02')
83246d6920f2 py3: use b'' for changegroup version literals
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35570
diff changeset
50 versions.add(b'03')
30745
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
51 return versions
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
52
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
53 def allsupportedversions(orig, ui):
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
54 versions = orig(ui)
36152
83246d6920f2 py3: use b'' for changegroup version literals
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35570
diff changeset
55 versions.add(b'03')
30745
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
56 return versions
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
57
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
58 def noopaddrevision(orig, self, text, transaction, link, p1, p2,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
59 cachedelta=None, node=None,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
60 flags=revlog.REVIDX_DEFAULT_FLAGS):
35570
3e3f4c03876b tests: add b'' to string literals where bytes are required
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31832
diff changeset
61 if b'[NOOP]' in text:
30745
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
62 flags |= REVIDX_NOOP
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
63 return orig(self, text, transaction, link, p1, p2, cachedelta=cachedelta,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
64 node=node, flags=flags)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
65
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
66 def b64addrevision(orig, self, text, transaction, link, p1, p2,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
67 cachedelta=None, node=None,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
68 flags=revlog.REVIDX_DEFAULT_FLAGS):
35570
3e3f4c03876b tests: add b'' to string literals where bytes are required
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31832
diff changeset
69 if b'[BASE64]' in text:
30745
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
70 flags |= REVIDX_BASE64
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
71 return orig(self, text, transaction, link, p1, p2, cachedelta=cachedelta,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
72 node=node, flags=flags)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
73
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
74 def gzipaddrevision(orig, self, text, transaction, link, p1, p2,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
75 cachedelta=None, node=None,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
76 flags=revlog.REVIDX_DEFAULT_FLAGS):
35570
3e3f4c03876b tests: add b'' to string literals where bytes are required
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31832
diff changeset
77 if b'[GZIP]' in text:
30745
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
78 flags |= REVIDX_GZIP
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
79 return orig(self, text, transaction, link, p1, p2, cachedelta=cachedelta,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
80 node=node, flags=flags)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
81
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
82 def failaddrevision(orig, self, text, transaction, link, p1, p2,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
83 cachedelta=None, node=None,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
84 flags=revlog.REVIDX_DEFAULT_FLAGS):
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
85 # This addrevision wrapper is meant to add a flag we will not have
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
86 # transforms registered for, ensuring we handle this error case.
35570
3e3f4c03876b tests: add b'' to string literals where bytes are required
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31832
diff changeset
87 if b'[FAIL]' in text:
30745
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
88 flags |= REVIDX_FAIL
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
89 return orig(self, text, transaction, link, p1, p2, cachedelta=cachedelta,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
90 node=node, flags=flags)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
91
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
92 def extsetup(ui):
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
93 # Enable changegroup3 for flags to be sent over the wire
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
94 wrapfunction = extensions.wrapfunction
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
95 wrapfunction(changegroup,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
96 'supportedoutgoingversions',
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
97 supportedoutgoingversions)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
98 wrapfunction(changegroup,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
99 'allsupportedversions',
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
100 allsupportedversions)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
101
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
102 # Teach revlog about our test flags
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
103 flags = [REVIDX_NOOP, REVIDX_BASE64, REVIDX_GZIP, REVIDX_FAIL]
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
104 revlog.REVIDX_KNOWN_FLAGS |= util.bitsfrom(flags)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
105 revlog.REVIDX_FLAGS_ORDER.extend(flags)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
106
31832
77f746e5383a test-flagprocessor: use changegroup3 in bundle2
Jun Wu <quark@fb.com>
parents: 30745
diff changeset
107 # Teach exchange to use changegroup 3
77f746e5383a test-flagprocessor: use changegroup3 in bundle2
Jun Wu <quark@fb.com>
parents: 30745
diff changeset
108 for k in exchange._bundlespeccgversions.keys():
36152
83246d6920f2 py3: use b'' for changegroup version literals
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35570
diff changeset
109 exchange._bundlespeccgversions[k] = b'03'
31832
77f746e5383a test-flagprocessor: use changegroup3 in bundle2
Jun Wu <quark@fb.com>
parents: 30745
diff changeset
110
30745
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
111 # Add wrappers for addrevision, responsible to set flags depending on the
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
112 # revision data contents.
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
113 wrapfunction(filelog.filelog, 'addrevision', noopaddrevision)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
114 wrapfunction(filelog.filelog, 'addrevision', b64addrevision)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
115 wrapfunction(filelog.filelog, 'addrevision', gzipaddrevision)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
116 wrapfunction(filelog.filelog, 'addrevision', failaddrevision)
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
117
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
118 # Register flag processors for each extension
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
119 revlog.addflagprocessor(
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
120 REVIDX_NOOP,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
121 (
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
122 noopdonothing,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
123 noopdonothing,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
124 validatehash,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
125 )
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
126 )
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
127 revlog.addflagprocessor(
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
128 REVIDX_BASE64,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
129 (
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
130 b64decode,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
131 b64encode,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
132 bypass,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
133 ),
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
134 )
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
135 revlog.addflagprocessor(
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
136 REVIDX_GZIP,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
137 (
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
138 gzipdecompress,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
139 gzipcompress,
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
140 bypass
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
141 )
c1b7b2285522 revlog: flag processor
Remi Chaintron <remi@fb.com>
parents:
diff changeset
142 )