comparison tests/test-wireproto-command-filesdata.t @ 40178:46a40bce3ae0

wireprotov2: define and implement "filesdata" command Previously, the only way to access file revision data was the "filedata" command. This command is useful to have. But, it only allowed resolving revision data for a single file. This meant that clients needed to send 1 command for each tracked path they were seeking data on. Furthermore, those commands would need to enumerate the exact file nodes they wanted data for. This approach meant that clients were sending a lot of data to remotes in order to request file data. e.g. if there were 1M file revisions, we'd need at least 20,000,000 bytes just to encode file nodes! Many clients on the internet don't have that kind of upload capacity. In order to limit the amount of data that clients must send, we'll need more efficient ways to request repository data. This commit defines and implements a new "filesdata" command. This command allows the retrieval of data for multiple files by specifying changeset revisions and optional file patterns. The command figures out what file revisions are "relevant" and sends them in bulk. The logic around choosing which file revisions to send in the case of haveparents not being set is overly simple and will over-send files. We will need more smarts here eventually. (Specifically, the client will need to tell the server which revisions it knows about.) This work is deferred until a later time. Differential Revision: https://phab.mercurial-scm.org/D4981
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 03 Oct 2018 12:54:39 -0700
parents
children abbd077965c0
comparison
equal deleted inserted replaced
40177:41e2633bcd00 40178:46a40bce3ae0
1 $ . $TESTDIR/wireprotohelpers.sh
2
3 $ hg init server
4 $ enablehttpv2 server
5 $ cd server
6 $ cat > a << EOF
7 > a0
8 > 00000000000000000000000000000000000000
9 > 11111111111111111111111111111111111111
10 > EOF
11 $ cat > b << EOF
12 > b0
13 > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
14 > bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
15 > EOF
16 $ mkdir -p dir0/child0 dir0/child1 dir1
17 $ echo c0 > dir0/c
18 $ echo d0 > dir0/d
19 $ echo e0 > dir0/child0/e
20 $ echo f0 > dir0/child1/f
21 $ hg -q commit -A -m 'commit 0'
22
23 $ echo a1 >> a
24 $ echo d1 > dir0/d
25 $ echo g0 > g
26 $ echo h0 > h
27 $ hg -q commit -A -m 'commit 1'
28 $ echo f1 > dir0/child1/f
29 $ echo i0 > dir0/i
30 $ hg -q commit -A -m 'commit 2'
31
32 $ hg -q up -r 0
33 $ echo a2 >> a
34 $ hg commit -m 'commit 3'
35 created new head
36
37 $ hg log -G -T '{rev}:{node} {desc}\n'
38 @ 3:476fbf122cd82f6726f0191ff146f67140946abc commit 3
39 |
40 | o 2:b91c03cbba3519ab149b6cd0a0afbdb5cf1b5c8a commit 2
41 | |
42 | o 1:5b0b1a23577e205ea240e39c9704e28d7697cbd8 commit 1
43 |/
44 o 0:6e875ff18c227659ad6143bb3580c65700734884 commit 0
45
46
47 $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
48 $ cat hg.pid > $DAEMON_PIDS
49
50 Missing arguments is an error
51
52 $ sendhttpv2peer << EOF
53 > command filesdata
54 > EOF
55 creating http peer for wire protocol version 2
56 sending filesdata command
57 abort: missing required arguments: revisions!
58 [255]
59
60 Bad pattern to pathfilter is rejected
61
62 $ sendhttpv2peer << EOF
63 > command filesdata
64 > revisions eval:[{
65 > b'type': b'changesetexplicit',
66 > b'nodes': [
67 > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
68 > ]}]
69 > pathfilter eval:{b'include': [b'bad:foo']}
70 > EOF
71 creating http peer for wire protocol version 2
72 sending filesdata command
73 abort: include pattern must begin with `path:` or `rootfilesin:`; got bad:foo!
74 [255]
75
76 $ sendhttpv2peer << EOF
77 > command filesdata
78 > revisions eval:[{
79 > b'type': b'changesetexplicit',
80 > b'nodes': [
81 > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
82 > ]}]
83 > pathfilter eval:{b'exclude': [b'glob:foo']}
84 > EOF
85 creating http peer for wire protocol version 2
86 sending filesdata command
87 abort: exclude pattern must begin with `path:` or `rootfilesin:`; got glob:foo!
88 [255]
89
90 Fetching a single changeset without parents fetches all files
91
92 $ sendhttpv2peer << EOF
93 > command filesdata
94 > revisions eval:[{
95 > b'type': b'changesetexplicit',
96 > b'nodes': [
97 > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
98 > ]}]
99 > EOF
100 creating http peer for wire protocol version 2
101 sending filesdata command
102 response: gen[
103 {
104 b'totalitems': 8,
105 b'totalpaths': 8
106 },
107 {
108 b'path': b'a',
109 b'totalitems': 1
110 },
111 {
112 b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
113 },
114 {
115 b'path': b'b',
116 b'totalitems': 1
117 },
118 {
119 b'node': b'\x88\xbac\xb8\xd8\xc6 :\xc6z\xc9\x98\xac\xd9\x17K\xf7\x05!\xb2'
120 },
121 {
122 b'path': b'dir0/c',
123 b'totalitems': 1
124 },
125 {
126 b'node': b'\x91DE4j\x0c\xa0b\x9b\xd4|\xeb]\xfe\x07\xe4\xd4\xcf%\x01'
127 },
128 {
129 b'path': b'dir0/child0/e',
130 b'totalitems': 1
131 },
132 {
133 b'node': b'\xbb\xbal\x06\xb3\x0fD=4\xff\x84\x1b\xc9\x85\xc4\xd0\x82|k\xe4'
134 },
135 {
136 b'path': b'dir0/child1/f',
137 b'totalitems': 1
138 },
139 {
140 b'node': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4'
141 },
142 {
143 b'path': b'dir0/d',
144 b'totalitems': 1
145 },
146 {
147 b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
148 },
149 {
150 b'path': b'g',
151 b'totalitems': 1
152 },
153 {
154 b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
155 },
156 {
157 b'path': b'h',
158 b'totalitems': 1
159 },
160 {
161 b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
162 }
163 ]
164
165 Fetching a single changeset saying parents data is available fetches just new files
166
167 $ sendhttpv2peer << EOF
168 > command filesdata
169 > revisions eval:[{
170 > b'type': b'changesetexplicit',
171 > b'nodes': [
172 > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
173 > ]}]
174 > haveparents eval:True
175 > EOF
176 creating http peer for wire protocol version 2
177 sending filesdata command
178 response: gen[
179 {
180 b'totalitems': 4,
181 b'totalpaths': 4
182 },
183 {
184 b'path': b'a',
185 b'totalitems': 1
186 },
187 {
188 b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
189 },
190 {
191 b'path': b'dir0/d',
192 b'totalitems': 1
193 },
194 {
195 b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
196 },
197 {
198 b'path': b'g',
199 b'totalitems': 1
200 },
201 {
202 b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
203 },
204 {
205 b'path': b'h',
206 b'totalitems': 1
207 },
208 {
209 b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
210 }
211 ]
212
213 A path filter for a sub-directory is honored
214
215 $ sendhttpv2peer << EOF
216 > command filesdata
217 > revisions eval:[{
218 > b'type': b'changesetexplicit',
219 > b'nodes': [
220 > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
221 > ]}]
222 > haveparents eval:True
223 > pathfilter eval:{b'include': [b'path:dir0']}
224 > EOF
225 creating http peer for wire protocol version 2
226 sending filesdata command
227 response: gen[
228 {
229 b'totalitems': 1,
230 b'totalpaths': 1
231 },
232 {
233 b'path': b'dir0/d',
234 b'totalitems': 1
235 },
236 {
237 b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
238 }
239 ]
240
241 $ sendhttpv2peer << EOF
242 > command filesdata
243 > revisions eval:[{
244 > b'type': b'changesetexplicit',
245 > b'nodes': [
246 > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
247 > ]}]
248 > haveparents eval:True
249 > pathfilter eval:{b'exclude': [b'path:a', b'path:g']}
250 > EOF
251 creating http peer for wire protocol version 2
252 sending filesdata command
253 response: gen[
254 {
255 b'totalitems': 2,
256 b'totalpaths': 2
257 },
258 {
259 b'path': b'dir0/d',
260 b'totalitems': 1
261 },
262 {
263 b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
264 },
265 {
266 b'path': b'h',
267 b'totalitems': 1
268 },
269 {
270 b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
271 }
272 ]
273
274 Requesting multiple changeset nodes without haveparents sends all data for both
275
276 $ sendhttpv2peer << EOF
277 > command filesdata
278 > revisions eval:[{
279 > b'type': b'changesetexplicit',
280 > b'nodes': [
281 > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
282 > b'\xb9\x1c\x03\xcb\xba\x35\x19\xab\x14\x9b\x6c\xd0\xa0\xaf\xbd\xb5\xcf\x1b\x5c\x8a',
283 > ]}]
284 > EOF
285 creating http peer for wire protocol version 2
286 sending filesdata command
287 response: gen[
288 {
289 b'totalitems': 10,
290 b'totalpaths': 9
291 },
292 {
293 b'path': b'a',
294 b'totalitems': 1
295 },
296 {
297 b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
298 },
299 {
300 b'path': b'b',
301 b'totalitems': 1
302 },
303 {
304 b'node': b'\x88\xbac\xb8\xd8\xc6 :\xc6z\xc9\x98\xac\xd9\x17K\xf7\x05!\xb2'
305 },
306 {
307 b'path': b'dir0/c',
308 b'totalitems': 1
309 },
310 {
311 b'node': b'\x91DE4j\x0c\xa0b\x9b\xd4|\xeb]\xfe\x07\xe4\xd4\xcf%\x01'
312 },
313 {
314 b'path': b'dir0/child0/e',
315 b'totalitems': 1
316 },
317 {
318 b'node': b'\xbb\xbal\x06\xb3\x0fD=4\xff\x84\x1b\xc9\x85\xc4\xd0\x82|k\xe4'
319 },
320 {
321 b'path': b'dir0/child1/f',
322 b'totalitems': 2
323 },
324 {
325 b'node': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4'
326 },
327 {
328 b'node': b'(\xc7v\xae\x08\xd0\xd5^\xb4\x06H\xb4\x01\xb9\x0f\xf5DH4\x8e'
329 },
330 {
331 b'path': b'dir0/d',
332 b'totalitems': 1
333 },
334 {
335 b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
336 },
337 {
338 b'path': b'dir0/i',
339 b'totalitems': 1
340 },
341 {
342 b'node': b'\xd7t\xb5\x80Jq\xfd1\xe1\xae\x05\xea\x8e2\xdd\x9b\xa3\xd8S\xd7'
343 },
344 {
345 b'path': b'g',
346 b'totalitems': 1
347 },
348 {
349 b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
350 },
351 {
352 b'path': b'h',
353 b'totalitems': 1
354 },
355 {
356 b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
357 }
358 ]
359
360 Requesting multiple changeset nodes with haveparents sends incremental data for both
361
362 $ sendhttpv2peer << EOF
363 > command filesdata
364 > revisions eval:[{
365 > b'type': b'changesetexplicit',
366 > b'nodes': [
367 > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
368 > b'\xb9\x1c\x03\xcb\xba\x35\x19\xab\x14\x9b\x6c\xd0\xa0\xaf\xbd\xb5\xcf\x1b\x5c\x8a',
369 > ]}]
370 > haveparents eval:True
371 > EOF
372 creating http peer for wire protocol version 2
373 sending filesdata command
374 response: gen[
375 {
376 b'totalitems': 6,
377 b'totalpaths': 6
378 },
379 {
380 b'path': b'a',
381 b'totalitems': 1
382 },
383 {
384 b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
385 },
386 {
387 b'path': b'dir0/child1/f',
388 b'totalitems': 1
389 },
390 {
391 b'node': b'(\xc7v\xae\x08\xd0\xd5^\xb4\x06H\xb4\x01\xb9\x0f\xf5DH4\x8e'
392 },
393 {
394 b'path': b'dir0/d',
395 b'totalitems': 1
396 },
397 {
398 b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
399 },
400 {
401 b'path': b'dir0/i',
402 b'totalitems': 1
403 },
404 {
405 b'node': b'\xd7t\xb5\x80Jq\xfd1\xe1\xae\x05\xea\x8e2\xdd\x9b\xa3\xd8S\xd7'
406 },
407 {
408 b'path': b'g',
409 b'totalitems': 1
410 },
411 {
412 b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
413 },
414 {
415 b'path': b'h',
416 b'totalitems': 1
417 },
418 {
419 b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
420 }
421 ]
422
423 Requesting parents works
424
425 $ sendhttpv2peer << EOF
426 > command filesdata
427 > revisions eval:[{
428 > b'type': b'changesetexplicit',
429 > b'nodes': [
430 > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
431 > ]}]
432 > fields eval:[b'parents']
433 > EOF
434 creating http peer for wire protocol version 2
435 sending filesdata command
436 response: gen[
437 {
438 b'totalitems': 8,
439 b'totalpaths': 8
440 },
441 {
442 b'path': b'a',
443 b'totalitems': 1
444 },
445 {
446 b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11',
447 b'parents': [
448 b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9',
449 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
450 ]
451 },
452 {
453 b'path': b'b',
454 b'totalitems': 1
455 },
456 {
457 b'node': b'\x88\xbac\xb8\xd8\xc6 :\xc6z\xc9\x98\xac\xd9\x17K\xf7\x05!\xb2',
458 b'parents': [
459 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
460 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
461 ]
462 },
463 {
464 b'path': b'dir0/c',
465 b'totalitems': 1
466 },
467 {
468 b'node': b'\x91DE4j\x0c\xa0b\x9b\xd4|\xeb]\xfe\x07\xe4\xd4\xcf%\x01',
469 b'parents': [
470 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
471 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
472 ]
473 },
474 {
475 b'path': b'dir0/child0/e',
476 b'totalitems': 1
477 },
478 {
479 b'node': b'\xbb\xbal\x06\xb3\x0fD=4\xff\x84\x1b\xc9\x85\xc4\xd0\x82|k\xe4',
480 b'parents': [
481 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
482 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
483 ]
484 },
485 {
486 b'path': b'dir0/child1/f',
487 b'totalitems': 1
488 },
489 {
490 b'node': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4',
491 b'parents': [
492 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
493 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
494 ]
495 },
496 {
497 b'path': b'dir0/d',
498 b'totalitems': 1
499 },
500 {
501 b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G',
502 b'parents': [
503 b'S\x82\x06\xdc\x97\x1eR\x15@\xd6\x84:\xbf\xe6\xd1`2\xf6\xd4&',
504 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
505 ]
506 },
507 {
508 b'path': b'g',
509 b'totalitems': 1
510 },
511 {
512 b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c',
513 b'parents': [
514 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
515 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
516 ]
517 },
518 {
519 b'path': b'h',
520 b'totalitems': 1
521 },
522 {
523 b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K',
524 b'parents': [
525 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
526 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
527 ]
528 }
529 ]
530
531 Requesting revision data works
532 (haveparents defaults to False, so fulltext is emitted)
533
534 $ sendhttpv2peer << EOF
535 > command filesdata
536 > revisions eval:[{
537 > b'type': b'changesetexplicit',
538 > b'nodes': [
539 > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
540 > ]}]
541 > fields eval:[b'revision']
542 > EOF
543 creating http peer for wire protocol version 2
544 sending filesdata command
545 response: gen[
546 {
547 b'totalitems': 8,
548 b'totalpaths': 8
549 },
550 {
551 b'path': b'a',
552 b'totalitems': 1
553 },
554 {
555 b'fieldsfollowing': [
556 [
557 b'revision',
558 84
559 ]
560 ],
561 b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
562 },
563 b'a0\n00000000000000000000000000000000000000\n11111111111111111111111111111111111111\na1\n',
564 {
565 b'path': b'b',
566 b'totalitems': 1
567 },
568 {
569 b'fieldsfollowing': [
570 [
571 b'revision',
572 81
573 ]
574 ],
575 b'node': b'\x88\xbac\xb8\xd8\xc6 :\xc6z\xc9\x98\xac\xd9\x17K\xf7\x05!\xb2'
576 },
577 b'b0\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n',
578 {
579 b'path': b'dir0/c',
580 b'totalitems': 1
581 },
582 {
583 b'fieldsfollowing': [
584 [
585 b'revision',
586 3
587 ]
588 ],
589 b'node': b'\x91DE4j\x0c\xa0b\x9b\xd4|\xeb]\xfe\x07\xe4\xd4\xcf%\x01'
590 },
591 b'c0\n',
592 {
593 b'path': b'dir0/child0/e',
594 b'totalitems': 1
595 },
596 {
597 b'fieldsfollowing': [
598 [
599 b'revision',
600 3
601 ]
602 ],
603 b'node': b'\xbb\xbal\x06\xb3\x0fD=4\xff\x84\x1b\xc9\x85\xc4\xd0\x82|k\xe4'
604 },
605 b'e0\n',
606 {
607 b'path': b'dir0/child1/f',
608 b'totalitems': 1
609 },
610 {
611 b'fieldsfollowing': [
612 [
613 b'revision',
614 3
615 ]
616 ],
617 b'node': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4'
618 },
619 b'f0\n',
620 {
621 b'path': b'dir0/d',
622 b'totalitems': 1
623 },
624 {
625 b'fieldsfollowing': [
626 [
627 b'revision',
628 3
629 ]
630 ],
631 b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
632 },
633 b'd1\n',
634 {
635 b'path': b'g',
636 b'totalitems': 1
637 },
638 {
639 b'fieldsfollowing': [
640 [
641 b'revision',
642 3
643 ]
644 ],
645 b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
646 },
647 b'g0\n',
648 {
649 b'path': b'h',
650 b'totalitems': 1
651 },
652 {
653 b'fieldsfollowing': [
654 [
655 b'revision',
656 3
657 ]
658 ],
659 b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
660 },
661 b'h0\n'
662 ]
663
664 haveparents=False should be same as above
665
666 $ sendhttpv2peer << EOF
667 > command filesdata
668 > revisions eval:[{
669 > b'type': b'changesetexplicit',
670 > b'nodes': [
671 > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
672 > ]}]
673 > fields eval:[b'revision']
674 > haveparents eval:False
675 > EOF
676 creating http peer for wire protocol version 2
677 sending filesdata command
678 response: gen[
679 {
680 b'totalitems': 8,
681 b'totalpaths': 8
682 },
683 {
684 b'path': b'a',
685 b'totalitems': 1
686 },
687 {
688 b'fieldsfollowing': [
689 [
690 b'revision',
691 84
692 ]
693 ],
694 b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
695 },
696 b'a0\n00000000000000000000000000000000000000\n11111111111111111111111111111111111111\na1\n',
697 {
698 b'path': b'b',
699 b'totalitems': 1
700 },
701 {
702 b'fieldsfollowing': [
703 [
704 b'revision',
705 81
706 ]
707 ],
708 b'node': b'\x88\xbac\xb8\xd8\xc6 :\xc6z\xc9\x98\xac\xd9\x17K\xf7\x05!\xb2'
709 },
710 b'b0\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n',
711 {
712 b'path': b'dir0/c',
713 b'totalitems': 1
714 },
715 {
716 b'fieldsfollowing': [
717 [
718 b'revision',
719 3
720 ]
721 ],
722 b'node': b'\x91DE4j\x0c\xa0b\x9b\xd4|\xeb]\xfe\x07\xe4\xd4\xcf%\x01'
723 },
724 b'c0\n',
725 {
726 b'path': b'dir0/child0/e',
727 b'totalitems': 1
728 },
729 {
730 b'fieldsfollowing': [
731 [
732 b'revision',
733 3
734 ]
735 ],
736 b'node': b'\xbb\xbal\x06\xb3\x0fD=4\xff\x84\x1b\xc9\x85\xc4\xd0\x82|k\xe4'
737 },
738 b'e0\n',
739 {
740 b'path': b'dir0/child1/f',
741 b'totalitems': 1
742 },
743 {
744 b'fieldsfollowing': [
745 [
746 b'revision',
747 3
748 ]
749 ],
750 b'node': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4'
751 },
752 b'f0\n',
753 {
754 b'path': b'dir0/d',
755 b'totalitems': 1
756 },
757 {
758 b'fieldsfollowing': [
759 [
760 b'revision',
761 3
762 ]
763 ],
764 b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
765 },
766 b'd1\n',
767 {
768 b'path': b'g',
769 b'totalitems': 1
770 },
771 {
772 b'fieldsfollowing': [
773 [
774 b'revision',
775 3
776 ]
777 ],
778 b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
779 },
780 b'g0\n',
781 {
782 b'path': b'h',
783 b'totalitems': 1
784 },
785 {
786 b'fieldsfollowing': [
787 [
788 b'revision',
789 3
790 ]
791 ],
792 b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
793 },
794 b'h0\n'
795 ]
796
797 haveparents=True should emit a delta
798
799 $ sendhttpv2peer << EOF
800 > command filesdata
801 > revisions eval:[{
802 > b'type': b'changesetexplicit',
803 > b'nodes': [
804 > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
805 > ]}]
806 > fields eval:[b'revision']
807 > haveparents eval:True
808 > EOF
809 creating http peer for wire protocol version 2
810 sending filesdata command
811 response: gen[
812 {
813 b'totalitems': 4,
814 b'totalpaths': 4
815 },
816 {
817 b'path': b'a',
818 b'totalitems': 1
819 },
820 {
821 b'deltabasenode': b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9',
822 b'fieldsfollowing': [
823 [
824 b'delta',
825 15
826 ]
827 ],
828 b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
829 },
830 b'\x00\x00\x00Q\x00\x00\x00Q\x00\x00\x00\x03a1\n',
831 {
832 b'path': b'dir0/d',
833 b'totalitems': 1
834 },
835 {
836 b'deltabasenode': b'S\x82\x06\xdc\x97\x1eR\x15@\xd6\x84:\xbf\xe6\xd1`2\xf6\xd4&',
837 b'fieldsfollowing': [
838 [
839 b'delta',
840 15
841 ]
842 ],
843 b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
844 },
845 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03d1\n',
846 {
847 b'path': b'g',
848 b'totalitems': 1
849 },
850 {
851 b'fieldsfollowing': [
852 [
853 b'revision',
854 3
855 ]
856 ],
857 b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
858 },
859 b'g0\n',
860 {
861 b'path': b'h',
862 b'totalitems': 1
863 },
864 {
865 b'fieldsfollowing': [
866 [
867 b'revision',
868 3
869 ]
870 ],
871 b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
872 },
873 b'h0\n'
874 ]
875
876 Requesting multiple revisions works
877 (first revision is a fulltext since haveparents=False by default)
878
879 $ sendhttpv2peer << EOF
880 > command filesdata
881 > revisions eval:[{
882 > b'type': b'changesetexplicit',
883 > b'nodes': [
884 > b'\x6e\x87\x5f\xf1\x8c\x22\x76\x59\xad\x61\x43\xbb\x35\x80\xc6\x57\x00\x73\x48\x84',
885 > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
886 > b'\xb9\x1c\x03\xcb\xba\x35\x19\xab\x14\x9b\x6c\xd0\xa0\xaf\xbd\xb5\xcf\x1b\x5c\x8a',
887 > ]}]
888 > fields eval:[b'revision']
889 > EOF
890 creating http peer for wire protocol version 2
891 sending filesdata command
892 response: gen[
893 {
894 b'totalitems': 12,
895 b'totalpaths': 9
896 },
897 {
898 b'path': b'a',
899 b'totalitems': 2
900 },
901 {
902 b'fieldsfollowing': [
903 [
904 b'revision',
905 81
906 ]
907 ],
908 b'node': b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9'
909 },
910 b'a0\n00000000000000000000000000000000000000\n11111111111111111111111111111111111111\n',
911 {
912 b'deltabasenode': b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9',
913 b'fieldsfollowing': [
914 [
915 b'delta',
916 15
917 ]
918 ],
919 b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
920 },
921 b'\x00\x00\x00Q\x00\x00\x00Q\x00\x00\x00\x03a1\n',
922 {
923 b'path': b'b',
924 b'totalitems': 1
925 },
926 {
927 b'fieldsfollowing': [
928 [
929 b'revision',
930 81
931 ]
932 ],
933 b'node': b'\x88\xbac\xb8\xd8\xc6 :\xc6z\xc9\x98\xac\xd9\x17K\xf7\x05!\xb2'
934 },
935 b'b0\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n',
936 {
937 b'path': b'dir0/c',
938 b'totalitems': 1
939 },
940 {
941 b'fieldsfollowing': [
942 [
943 b'revision',
944 3
945 ]
946 ],
947 b'node': b'\x91DE4j\x0c\xa0b\x9b\xd4|\xeb]\xfe\x07\xe4\xd4\xcf%\x01'
948 },
949 b'c0\n',
950 {
951 b'path': b'dir0/child0/e',
952 b'totalitems': 1
953 },
954 {
955 b'fieldsfollowing': [
956 [
957 b'revision',
958 3
959 ]
960 ],
961 b'node': b'\xbb\xbal\x06\xb3\x0fD=4\xff\x84\x1b\xc9\x85\xc4\xd0\x82|k\xe4'
962 },
963 b'e0\n',
964 {
965 b'path': b'dir0/child1/f',
966 b'totalitems': 2
967 },
968 {
969 b'fieldsfollowing': [
970 [
971 b'revision',
972 3
973 ]
974 ],
975 b'node': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4'
976 },
977 b'f0\n',
978 {
979 b'deltabasenode': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4',
980 b'fieldsfollowing': [
981 [
982 b'delta',
983 15
984 ]
985 ],
986 b'node': b'(\xc7v\xae\x08\xd0\xd5^\xb4\x06H\xb4\x01\xb9\x0f\xf5DH4\x8e'
987 },
988 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03f1\n',
989 {
990 b'path': b'dir0/d',
991 b'totalitems': 2
992 },
993 {
994 b'fieldsfollowing': [
995 [
996 b'revision',
997 3
998 ]
999 ],
1000 b'node': b'S\x82\x06\xdc\x97\x1eR\x15@\xd6\x84:\xbf\xe6\xd1`2\xf6\xd4&'
1001 },
1002 b'd0\n',
1003 {
1004 b'deltabasenode': b'S\x82\x06\xdc\x97\x1eR\x15@\xd6\x84:\xbf\xe6\xd1`2\xf6\xd4&',
1005 b'fieldsfollowing': [
1006 [
1007 b'delta',
1008 15
1009 ]
1010 ],
1011 b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
1012 },
1013 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03d1\n',
1014 {
1015 b'path': b'dir0/i',
1016 b'totalitems': 1
1017 },
1018 {
1019 b'fieldsfollowing': [
1020 [
1021 b'revision',
1022 3
1023 ]
1024 ],
1025 b'node': b'\xd7t\xb5\x80Jq\xfd1\xe1\xae\x05\xea\x8e2\xdd\x9b\xa3\xd8S\xd7'
1026 },
1027 b'i0\n',
1028 {
1029 b'path': b'g',
1030 b'totalitems': 1
1031 },
1032 {
1033 b'fieldsfollowing': [
1034 [
1035 b'revision',
1036 3
1037 ]
1038 ],
1039 b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
1040 },
1041 b'g0\n',
1042 {
1043 b'path': b'h',
1044 b'totalitems': 1
1045 },
1046 {
1047 b'fieldsfollowing': [
1048 [
1049 b'revision',
1050 3
1051 ]
1052 ],
1053 b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
1054 },
1055 b'h0\n'
1056 ]
1057
1058 $ cat error.log