]> git.ipfire.org Git - thirdparty/git.git/blob - t/t5558-clone-bundle-uri.sh
submodule-config.c: strengthen URL fsck check
[thirdparty/git.git] / t / t5558-clone-bundle-uri.sh
1 #!/bin/sh
2
3 test_description='test fetching bundles with --bundle-uri'
4
5 . ./test-lib.sh
6
7 test_expect_success 'fail to clone from non-existent file' '
8 test_when_finished rm -rf test &&
9 git clone --bundle-uri="$(pwd)/does-not-exist" . test 2>err &&
10 grep "failed to download bundle from URI" err
11 '
12
13 test_expect_success 'fail to clone from non-bundle file' '
14 test_when_finished rm -rf test &&
15 echo bogus >bogus &&
16 git clone --bundle-uri="$(pwd)/bogus" . test 2>err &&
17 grep "is not a bundle" err
18 '
19
20 test_expect_success 'create bundle' '
21 git init clone-from &&
22 git -C clone-from checkout -b topic &&
23 test_commit -C clone-from A &&
24 test_commit -C clone-from B &&
25 git -C clone-from bundle create B.bundle topic
26 '
27
28 test_expect_success 'clone with path bundle' '
29 git clone --bundle-uri="clone-from/B.bundle" \
30 clone-from clone-path &&
31 git -C clone-path rev-parse refs/bundles/topic >actual &&
32 git -C clone-from rev-parse topic >expect &&
33 test_cmp expect actual
34 '
35
36 test_expect_success 'clone with file:// bundle' '
37 git clone --bundle-uri="file://$(pwd)/clone-from/B.bundle" \
38 clone-from clone-file &&
39 git -C clone-file rev-parse refs/bundles/topic >actual &&
40 git -C clone-from rev-parse topic >expect &&
41 test_cmp expect actual
42 '
43
44 # To get interesting tests for bundle lists, we need to construct a
45 # somewhat-interesting commit history.
46 #
47 # ---------------- bundle-4
48 #
49 # 4
50 # / \
51 # ----|---|------- bundle-3
52 # | |
53 # | 3
54 # | |
55 # ----|---|------- bundle-2
56 # | |
57 # 2 |
58 # | |
59 # ----|---|------- bundle-1
60 # \ /
61 # 1
62 # |
63 # (previous commits)
64 test_expect_success 'construct incremental bundle list' '
65 (
66 cd clone-from &&
67 git checkout -b base &&
68 test_commit 1 &&
69 git checkout -b left &&
70 test_commit 2 &&
71 git checkout -b right base &&
72 test_commit 3 &&
73 git checkout -b merge left &&
74 git merge right -m "4" &&
75
76 git bundle create bundle-1.bundle base &&
77 git bundle create bundle-2.bundle base..left &&
78 git bundle create bundle-3.bundle base..right &&
79 git bundle create bundle-4.bundle merge --not left right
80 )
81 '
82
83 test_expect_success 'clone bundle list (file, no heuristic)' '
84 cat >bundle-list <<-EOF &&
85 [bundle]
86 version = 1
87 mode = all
88
89 [bundle "bundle-1"]
90 uri = file://$(pwd)/clone-from/bundle-1.bundle
91
92 [bundle "bundle-2"]
93 uri = file://$(pwd)/clone-from/bundle-2.bundle
94
95 [bundle "bundle-3"]
96 uri = file://$(pwd)/clone-from/bundle-3.bundle
97
98 [bundle "bundle-4"]
99 uri = file://$(pwd)/clone-from/bundle-4.bundle
100 EOF
101
102 git clone --bundle-uri="file://$(pwd)/bundle-list" \
103 clone-from clone-list-file 2>err &&
104 ! grep "Repository lacks these prerequisite commits" err &&
105
106 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
107 git -C clone-list-file cat-file --batch-check <oids &&
108
109 git -C clone-list-file for-each-ref --format="%(refname)" >refs &&
110 grep "refs/bundles/" refs >actual &&
111 cat >expect <<-\EOF &&
112 refs/bundles/base
113 refs/bundles/left
114 refs/bundles/merge
115 refs/bundles/right
116 EOF
117 test_cmp expect actual
118 '
119
120 test_expect_success 'clone bundle list (file, all mode, some failures)' '
121 cat >bundle-list <<-EOF &&
122 [bundle]
123 version = 1
124 mode = all
125
126 # Does not exist. Should be skipped.
127 [bundle "bundle-0"]
128 uri = file://$(pwd)/clone-from/bundle-0.bundle
129
130 [bundle "bundle-1"]
131 uri = file://$(pwd)/clone-from/bundle-1.bundle
132
133 [bundle "bundle-2"]
134 uri = file://$(pwd)/clone-from/bundle-2.bundle
135
136 # No bundle-3 means bundle-4 will not apply.
137
138 [bundle "bundle-4"]
139 uri = file://$(pwd)/clone-from/bundle-4.bundle
140
141 # Does not exist. Should be skipped.
142 [bundle "bundle-5"]
143 uri = file://$(pwd)/clone-from/bundle-5.bundle
144 EOF
145
146 GIT_TRACE2_PERF=1 \
147 git clone --bundle-uri="file://$(pwd)/bundle-list" \
148 clone-from clone-all-some 2>err &&
149 ! grep "Repository lacks these prerequisite commits" err &&
150 ! grep "fatal" err &&
151 grep "warning: failed to download bundle from URI" err &&
152
153 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
154 git -C clone-all-some cat-file --batch-check <oids &&
155
156 git -C clone-all-some for-each-ref --format="%(refname)" >refs &&
157 grep "refs/bundles/" refs >actual &&
158 cat >expect <<-\EOF &&
159 refs/bundles/base
160 refs/bundles/left
161 EOF
162 test_cmp expect actual
163 '
164
165 test_expect_success 'clone bundle list (file, all mode, all failures)' '
166 cat >bundle-list <<-EOF &&
167 [bundle]
168 version = 1
169 mode = all
170
171 # Does not exist. Should be skipped.
172 [bundle "bundle-0"]
173 uri = file://$(pwd)/clone-from/bundle-0.bundle
174
175 # Does not exist. Should be skipped.
176 [bundle "bundle-5"]
177 uri = file://$(pwd)/clone-from/bundle-5.bundle
178 EOF
179
180 git clone --bundle-uri="file://$(pwd)/bundle-list" \
181 clone-from clone-all-fail 2>err &&
182 ! grep "Repository lacks these prerequisite commits" err &&
183 ! grep "fatal" err &&
184 grep "warning: failed to download bundle from URI" err &&
185
186 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
187 git -C clone-all-fail cat-file --batch-check <oids &&
188
189 git -C clone-all-fail for-each-ref --format="%(refname)" >refs &&
190 ! grep "refs/bundles/" refs
191 '
192
193 test_expect_success 'clone bundle list (file, any mode)' '
194 cat >bundle-list <<-EOF &&
195 [bundle]
196 version = 1
197 mode = any
198
199 # Does not exist. Should be skipped.
200 [bundle "bundle-0"]
201 uri = file://$(pwd)/clone-from/bundle-0.bundle
202
203 [bundle "bundle-1"]
204 uri = file://$(pwd)/clone-from/bundle-1.bundle
205
206 # Does not exist. Should be skipped.
207 [bundle "bundle-5"]
208 uri = file://$(pwd)/clone-from/bundle-5.bundle
209 EOF
210
211 git clone --bundle-uri="file://$(pwd)/bundle-list" \
212 clone-from clone-any-file 2>err &&
213 ! grep "Repository lacks these prerequisite commits" err &&
214
215 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
216 git -C clone-any-file cat-file --batch-check <oids &&
217
218 git -C clone-any-file for-each-ref --format="%(refname)" >refs &&
219 grep "refs/bundles/" refs >actual &&
220 cat >expect <<-\EOF &&
221 refs/bundles/base
222 EOF
223 test_cmp expect actual
224 '
225
226 test_expect_success 'clone bundle list (file, any mode, all failures)' '
227 cat >bundle-list <<-EOF &&
228 [bundle]
229 version = 1
230 mode = any
231
232 # Does not exist. Should be skipped.
233 [bundle "bundle-0"]
234 uri = $HTTPD_URL/bundle-0.bundle
235
236 # Does not exist. Should be skipped.
237 [bundle "bundle-5"]
238 uri = $HTTPD_URL/bundle-5.bundle
239 EOF
240
241 git clone --bundle-uri="file://$(pwd)/bundle-list" \
242 clone-from clone-any-fail 2>err &&
243 ! grep "fatal" err &&
244 grep "warning: failed to download bundle from URI" err &&
245
246 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
247 git -C clone-any-fail cat-file --batch-check <oids &&
248
249 git -C clone-any-fail for-each-ref --format="%(refname)" >refs &&
250 ! grep "refs/bundles/" refs
251 '
252
253 #########################################################################
254 # HTTP tests begin here
255
256 . "$TEST_DIRECTORY"/lib-httpd.sh
257 start_httpd
258
259 test_expect_success 'fail to fetch from non-existent HTTP URL' '
260 test_when_finished rm -rf test &&
261 git clone --bundle-uri="$HTTPD_URL/does-not-exist" . test 2>err &&
262 grep "failed to download bundle from URI" err
263 '
264
265 test_expect_success 'fail to fetch from non-bundle HTTP URL' '
266 test_when_finished rm -rf test &&
267 echo bogus >"$HTTPD_DOCUMENT_ROOT_PATH/bogus" &&
268 git clone --bundle-uri="$HTTPD_URL/bogus" . test 2>err &&
269 grep "is not a bundle" err
270 '
271
272 test_expect_success 'clone HTTP bundle' '
273 cp clone-from/B.bundle "$HTTPD_DOCUMENT_ROOT_PATH/B.bundle" &&
274
275 git clone --no-local --mirror clone-from \
276 "$HTTPD_DOCUMENT_ROOT_PATH/fetch.git" &&
277
278 git clone --bundle-uri="$HTTPD_URL/B.bundle" \
279 "$HTTPD_URL/smart/fetch.git" clone-http &&
280 git -C clone-http rev-parse refs/bundles/topic >actual &&
281 git -C clone-from rev-parse topic >expect &&
282 test_cmp expect actual &&
283
284 test_config -C clone-http log.excludedecoration refs/bundle/
285 '
286
287 test_expect_success 'clone bundle list (HTTP, no heuristic)' '
288 test_when_finished rm -f trace*.txt &&
289
290 cp clone-from/bundle-*.bundle "$HTTPD_DOCUMENT_ROOT_PATH/" &&
291 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
292 [bundle]
293 version = 1
294 mode = all
295
296 [bundle "bundle-1"]
297 uri = $HTTPD_URL/bundle-1.bundle
298
299 [bundle "bundle-2"]
300 uri = $HTTPD_URL/bundle-2.bundle
301
302 [bundle "bundle-3"]
303 uri = $HTTPD_URL/bundle-3.bundle
304
305 [bundle "bundle-4"]
306 uri = $HTTPD_URL/bundle-4.bundle
307 EOF
308
309 GIT_TRACE2_EVENT="$(pwd)/trace-clone.txt" \
310 git clone --bundle-uri="$HTTPD_URL/bundle-list" \
311 clone-from clone-list-http 2>err &&
312 ! grep "Repository lacks these prerequisite commits" err &&
313
314 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
315 git -C clone-list-http cat-file --batch-check <oids &&
316
317 cat >expect <<-EOF &&
318 $HTTPD_URL/bundle-1.bundle
319 $HTTPD_URL/bundle-2.bundle
320 $HTTPD_URL/bundle-3.bundle
321 $HTTPD_URL/bundle-4.bundle
322 $HTTPD_URL/bundle-list
323 EOF
324
325 # Sort the list, since the order is not well-defined
326 # without a heuristic.
327 test_remote_https_urls <trace-clone.txt | sort >actual &&
328 test_cmp expect actual
329 '
330
331 test_expect_success 'clone bundle list (HTTP, any mode)' '
332 cp clone-from/bundle-*.bundle "$HTTPD_DOCUMENT_ROOT_PATH/" &&
333 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
334 [bundle]
335 version = 1
336 mode = any
337
338 # Does not exist. Should be skipped.
339 [bundle "bundle-0"]
340 uri = $HTTPD_URL/bundle-0.bundle
341
342 [bundle "bundle-1"]
343 uri = $HTTPD_URL/bundle-1.bundle
344
345 # Does not exist. Should be skipped.
346 [bundle "bundle-5"]
347 uri = $HTTPD_URL/bundle-5.bundle
348 EOF
349
350 git clone --bundle-uri="$HTTPD_URL/bundle-list" \
351 clone-from clone-any-http 2>err &&
352 ! grep "fatal" err &&
353 grep "warning: failed to download bundle from URI" err &&
354
355 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
356 git -C clone-any-http cat-file --batch-check <oids &&
357
358 git -C clone-list-file for-each-ref --format="%(refname)" >refs &&
359 grep "refs/bundles/" refs >actual &&
360 cat >expect <<-\EOF &&
361 refs/bundles/base
362 refs/bundles/left
363 refs/bundles/merge
364 refs/bundles/right
365 EOF
366 test_cmp expect actual
367 '
368
369 test_expect_success 'clone bundle list (http, creationToken)' '
370 test_when_finished rm -f trace*.txt &&
371
372 cp clone-from/bundle-*.bundle "$HTTPD_DOCUMENT_ROOT_PATH/" &&
373 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
374 [bundle]
375 version = 1
376 mode = all
377 heuristic = creationToken
378
379 [bundle "bundle-1"]
380 uri = bundle-1.bundle
381 creationToken = 1
382
383 [bundle "bundle-2"]
384 uri = bundle-2.bundle
385 creationToken = 2
386
387 [bundle "bundle-3"]
388 uri = bundle-3.bundle
389 creationToken = 3
390
391 [bundle "bundle-4"]
392 uri = bundle-4.bundle
393 creationToken = 4
394 EOF
395
396 GIT_TRACE2_EVENT="$(pwd)/trace-clone.txt" git \
397 clone --bundle-uri="$HTTPD_URL/bundle-list" \
398 "$HTTPD_URL/smart/fetch.git" clone-list-http-2 &&
399
400 git -C clone-from for-each-ref --format="%(objectname)" >oids &&
401 git -C clone-list-http-2 cat-file --batch-check <oids &&
402
403 cat >expect <<-EOF &&
404 $HTTPD_URL/bundle-list
405 $HTTPD_URL/bundle-4.bundle
406 $HTTPD_URL/bundle-3.bundle
407 $HTTPD_URL/bundle-2.bundle
408 $HTTPD_URL/bundle-1.bundle
409 EOF
410
411 test_remote_https_urls <trace-clone.txt >actual &&
412 test_cmp expect actual
413 '
414
415 test_expect_success 'clone incomplete bundle list (http, creationToken)' '
416 test_when_finished rm -f trace*.txt &&
417
418 cp clone-from/bundle-*.bundle "$HTTPD_DOCUMENT_ROOT_PATH/" &&
419 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
420 [bundle]
421 version = 1
422 mode = all
423 heuristic = creationToken
424
425 [bundle "bundle-1"]
426 uri = bundle-1.bundle
427 creationToken = 1
428 EOF
429
430 GIT_TRACE2_EVENT=$(pwd)/trace-clone.txt \
431 git clone --bundle-uri="$HTTPD_URL/bundle-list" \
432 --single-branch --branch=base --no-tags \
433 "$HTTPD_URL/smart/fetch.git" clone-token-http &&
434
435 test_cmp_config -C clone-token-http "$HTTPD_URL/bundle-list" fetch.bundleuri &&
436 test_cmp_config -C clone-token-http 1 fetch.bundlecreationtoken &&
437
438 cat >expect <<-EOF &&
439 $HTTPD_URL/bundle-list
440 $HTTPD_URL/bundle-1.bundle
441 EOF
442
443 test_remote_https_urls <trace-clone.txt >actual &&
444 test_cmp expect actual &&
445
446 # We now have only one bundle ref.
447 git -C clone-token-http for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
448 cat >expect <<-\EOF &&
449 refs/bundles/base
450 EOF
451 test_cmp expect refs &&
452
453 # Add remaining bundles, exercising the "deepening" strategy
454 # for downloading via the creationToken heurisitc.
455 cat >>"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
456 [bundle "bundle-2"]
457 uri = bundle-2.bundle
458 creationToken = 2
459
460 [bundle "bundle-3"]
461 uri = bundle-3.bundle
462 creationToken = 3
463
464 [bundle "bundle-4"]
465 uri = bundle-4.bundle
466 creationToken = 4
467 EOF
468
469 GIT_TRACE2_EVENT="$(pwd)/trace1.txt" \
470 git -C clone-token-http fetch origin --no-tags \
471 refs/heads/merge:refs/heads/merge &&
472 test_cmp_config -C clone-token-http 4 fetch.bundlecreationtoken &&
473
474 cat >expect <<-EOF &&
475 $HTTPD_URL/bundle-list
476 $HTTPD_URL/bundle-4.bundle
477 $HTTPD_URL/bundle-3.bundle
478 $HTTPD_URL/bundle-2.bundle
479 EOF
480
481 test_remote_https_urls <trace1.txt >actual &&
482 test_cmp expect actual &&
483
484 # We now have all bundle refs.
485 git -C clone-token-http for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
486
487 cat >expect <<-\EOF &&
488 refs/bundles/base
489 refs/bundles/left
490 refs/bundles/merge
491 refs/bundles/right
492 EOF
493 test_cmp expect refs
494 '
495
496 test_expect_success 'http clone with bundle.heuristic creates fetch.bundleURI' '
497 test_when_finished rm -rf fetch-http-4 trace*.txt &&
498
499 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
500 [bundle]
501 version = 1
502 mode = all
503 heuristic = creationToken
504
505 [bundle "bundle-1"]
506 uri = bundle-1.bundle
507 creationToken = 1
508 EOF
509
510 GIT_TRACE2_EVENT="$(pwd)/trace-clone.txt" \
511 git clone --single-branch --branch=base \
512 --bundle-uri="$HTTPD_URL/bundle-list" \
513 "$HTTPD_URL/smart/fetch.git" fetch-http-4 &&
514
515 test_cmp_config -C fetch-http-4 "$HTTPD_URL/bundle-list" fetch.bundleuri &&
516 test_cmp_config -C fetch-http-4 1 fetch.bundlecreationtoken &&
517
518 cat >expect <<-EOF &&
519 $HTTPD_URL/bundle-list
520 $HTTPD_URL/bundle-1.bundle
521 EOF
522
523 test_remote_https_urls <trace-clone.txt >actual &&
524 test_cmp expect actual &&
525
526 # only received base ref from bundle-1
527 git -C fetch-http-4 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
528 cat >expect <<-\EOF &&
529 refs/bundles/base
530 EOF
531 test_cmp expect refs &&
532
533 cat >>"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
534 [bundle "bundle-2"]
535 uri = bundle-2.bundle
536 creationToken = 2
537 EOF
538
539 # Fetch the objects for bundle-2 _and_ bundle-3.
540 GIT_TRACE2_EVENT="$(pwd)/trace1.txt" \
541 git -C fetch-http-4 fetch origin --no-tags \
542 refs/heads/left:refs/heads/left \
543 refs/heads/right:refs/heads/right &&
544 test_cmp_config -C fetch-http-4 2 fetch.bundlecreationtoken &&
545
546 cat >expect <<-EOF &&
547 $HTTPD_URL/bundle-list
548 $HTTPD_URL/bundle-2.bundle
549 EOF
550
551 test_remote_https_urls <trace1.txt >actual &&
552 test_cmp expect actual &&
553
554 # received left from bundle-2
555 git -C fetch-http-4 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
556 cat >expect <<-\EOF &&
557 refs/bundles/base
558 refs/bundles/left
559 EOF
560 test_cmp expect refs &&
561
562 # No-op fetch
563 GIT_TRACE2_EVENT="$(pwd)/trace1b.txt" \
564 git -C fetch-http-4 fetch origin --no-tags \
565 refs/heads/left:refs/heads/left \
566 refs/heads/right:refs/heads/right &&
567
568 cat >expect <<-EOF &&
569 $HTTPD_URL/bundle-list
570 EOF
571 test_remote_https_urls <trace1b.txt >actual &&
572 test_cmp expect actual &&
573
574 cat >>"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
575 [bundle "bundle-3"]
576 uri = bundle-3.bundle
577 creationToken = 3
578
579 [bundle "bundle-4"]
580 uri = bundle-4.bundle
581 creationToken = 4
582 EOF
583
584 # This fetch should skip bundle-3.bundle, since its objects are
585 # already local (we have the requisite commits for bundle-4.bundle).
586 GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
587 git -C fetch-http-4 fetch origin --no-tags \
588 refs/heads/merge:refs/heads/merge &&
589 test_cmp_config -C fetch-http-4 4 fetch.bundlecreationtoken &&
590
591 cat >expect <<-EOF &&
592 $HTTPD_URL/bundle-list
593 $HTTPD_URL/bundle-4.bundle
594 EOF
595
596 test_remote_https_urls <trace2.txt >actual &&
597 test_cmp expect actual &&
598
599 # received merge ref from bundle-4, but right is missing
600 # because we did not download bundle-3.
601 git -C fetch-http-4 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
602
603 cat >expect <<-\EOF &&
604 refs/bundles/base
605 refs/bundles/left
606 refs/bundles/merge
607 EOF
608 test_cmp expect refs &&
609
610 # No-op fetch
611 GIT_TRACE2_EVENT="$(pwd)/trace2b.txt" \
612 git -C fetch-http-4 fetch origin &&
613
614 cat >expect <<-EOF &&
615 $HTTPD_URL/bundle-list
616 EOF
617 test_remote_https_urls <trace2b.txt >actual &&
618 test_cmp expect actual
619 '
620
621 test_expect_success 'creationToken heuristic with failed downloads (clone)' '
622 test_when_finished rm -rf download-* trace*.txt &&
623
624 # Case 1: base bundle does not exist, nothing can unbundle
625 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
626 [bundle]
627 version = 1
628 mode = all
629 heuristic = creationToken
630
631 [bundle "bundle-1"]
632 uri = fake.bundle
633 creationToken = 1
634
635 [bundle "bundle-2"]
636 uri = bundle-2.bundle
637 creationToken = 2
638
639 [bundle "bundle-3"]
640 uri = bundle-3.bundle
641 creationToken = 3
642
643 [bundle "bundle-4"]
644 uri = bundle-4.bundle
645 creationToken = 4
646 EOF
647
648 GIT_TRACE2_EVENT="$(pwd)/trace-clone-1.txt" \
649 git clone --single-branch --branch=base \
650 --bundle-uri="$HTTPD_URL/bundle-list" \
651 "$HTTPD_URL/smart/fetch.git" download-1 &&
652
653 # Bundle failure does not set these configs.
654 test_must_fail git -C download-1 config fetch.bundleuri &&
655 test_must_fail git -C download-1 config fetch.bundlecreationtoken &&
656
657 cat >expect <<-EOF &&
658 $HTTPD_URL/bundle-list
659 $HTTPD_URL/bundle-4.bundle
660 $HTTPD_URL/bundle-3.bundle
661 $HTTPD_URL/bundle-2.bundle
662 $HTTPD_URL/fake.bundle
663 EOF
664 test_remote_https_urls <trace-clone-1.txt >actual &&
665 test_cmp expect actual &&
666
667 # All bundles failed to unbundle
668 git -C download-1 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
669 test_must_be_empty refs &&
670
671 # Case 2: middle bundle does not exist, only two bundles can unbundle
672 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
673 [bundle]
674 version = 1
675 mode = all
676 heuristic = creationToken
677
678 [bundle "bundle-1"]
679 uri = bundle-1.bundle
680 creationToken = 1
681
682 [bundle "bundle-2"]
683 uri = fake.bundle
684 creationToken = 2
685
686 [bundle "bundle-3"]
687 uri = bundle-3.bundle
688 creationToken = 3
689
690 [bundle "bundle-4"]
691 uri = bundle-4.bundle
692 creationToken = 4
693 EOF
694
695 GIT_TRACE2_EVENT="$(pwd)/trace-clone-2.txt" \
696 git clone --single-branch --branch=base \
697 --bundle-uri="$HTTPD_URL/bundle-list" \
698 "$HTTPD_URL/smart/fetch.git" download-2 &&
699
700 # Bundle failure does not set these configs.
701 test_must_fail git -C download-2 config fetch.bundleuri &&
702 test_must_fail git -C download-2 config fetch.bundlecreationtoken &&
703
704 cat >expect <<-EOF &&
705 $HTTPD_URL/bundle-list
706 $HTTPD_URL/bundle-4.bundle
707 $HTTPD_URL/bundle-3.bundle
708 $HTTPD_URL/fake.bundle
709 $HTTPD_URL/bundle-1.bundle
710 EOF
711 test_remote_https_urls <trace-clone-2.txt >actual &&
712 test_cmp expect actual &&
713
714 # bundle-1 and bundle-3 could unbundle, but bundle-4 could not
715 git -C download-2 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
716 cat >expect <<-EOF &&
717 refs/bundles/base
718 refs/bundles/right
719 EOF
720 test_cmp expect refs &&
721
722 # Case 3: top bundle does not exist, rest unbundle fine.
723 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
724 [bundle]
725 version = 1
726 mode = all
727 heuristic = creationToken
728
729 [bundle "bundle-1"]
730 uri = bundle-1.bundle
731 creationToken = 1
732
733 [bundle "bundle-2"]
734 uri = bundle-2.bundle
735 creationToken = 2
736
737 [bundle "bundle-3"]
738 uri = bundle-3.bundle
739 creationToken = 3
740
741 [bundle "bundle-4"]
742 uri = fake.bundle
743 creationToken = 4
744 EOF
745
746 GIT_TRACE2_EVENT="$(pwd)/trace-clone-3.txt" \
747 git clone --single-branch --branch=base \
748 --bundle-uri="$HTTPD_URL/bundle-list" \
749 "$HTTPD_URL/smart/fetch.git" download-3 &&
750
751 # As long as we have continguous successful downloads,
752 # we _do_ set these configs.
753 test_cmp_config -C download-3 "$HTTPD_URL/bundle-list" fetch.bundleuri &&
754 test_cmp_config -C download-3 3 fetch.bundlecreationtoken &&
755
756 cat >expect <<-EOF &&
757 $HTTPD_URL/bundle-list
758 $HTTPD_URL/fake.bundle
759 $HTTPD_URL/bundle-3.bundle
760 $HTTPD_URL/bundle-2.bundle
761 $HTTPD_URL/bundle-1.bundle
762 EOF
763 test_remote_https_urls <trace-clone-3.txt >actual &&
764 test_cmp expect actual &&
765
766 # fake.bundle did not unbundle, but the others did.
767 git -C download-3 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
768 cat >expect <<-EOF &&
769 refs/bundles/base
770 refs/bundles/left
771 refs/bundles/right
772 EOF
773 test_cmp expect refs
774 '
775
776 # Expand the bundle list to include other interesting shapes, specifically
777 # interesting for use when fetching from a previous state.
778 #
779 # ---------------- bundle-7
780 # 7
781 # _/|\_
782 # ---/--|--\------ bundle-6
783 # 5 | 6
784 # --|---|---|----- bundle-4
785 # | 4 |
786 # | / \ /
787 # --|-|---|/------ bundle-3 (the client will be caught up to this point.)
788 # \ | 3
789 # ---\|---|------- bundle-2
790 # 2 |
791 # ----|---|------- bundle-1
792 # \ /
793 # 1
794 # |
795 # (previous commits)
796 test_expect_success 'expand incremental bundle list' '
797 (
798 cd clone-from &&
799 git checkout -b lefter left &&
800 test_commit 5 &&
801 git checkout -b righter right &&
802 test_commit 6 &&
803 git checkout -b top lefter &&
804 git merge -m "7" merge righter &&
805
806 git bundle create bundle-6.bundle lefter righter --not left right &&
807 git bundle create bundle-7.bundle top --not lefter merge righter &&
808
809 cp bundle-*.bundle "$HTTPD_DOCUMENT_ROOT_PATH/"
810 ) &&
811 git -C "$HTTPD_DOCUMENT_ROOT_PATH/fetch.git" fetch origin +refs/heads/*:refs/heads/*
812 '
813
814 test_expect_success 'creationToken heuristic with failed downloads (fetch)' '
815 test_when_finished rm -rf download-* trace*.txt &&
816
817 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
818 [bundle]
819 version = 1
820 mode = all
821 heuristic = creationToken
822
823 [bundle "bundle-1"]
824 uri = bundle-1.bundle
825 creationToken = 1
826
827 [bundle "bundle-2"]
828 uri = bundle-2.bundle
829 creationToken = 2
830
831 [bundle "bundle-3"]
832 uri = bundle-3.bundle
833 creationToken = 3
834 EOF
835
836 git clone --single-branch --branch=left \
837 --bundle-uri="$HTTPD_URL/bundle-list" \
838 "$HTTPD_URL/smart/fetch.git" fetch-base &&
839 test_cmp_config -C fetch-base "$HTTPD_URL/bundle-list" fetch.bundleURI &&
840 test_cmp_config -C fetch-base 3 fetch.bundleCreationToken &&
841
842 # Case 1: all bundles exist: successful unbundling of all bundles
843 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
844 [bundle]
845 version = 1
846 mode = all
847 heuristic = creationToken
848
849 [bundle "bundle-1"]
850 uri = bundle-1.bundle
851 creationToken = 1
852
853 [bundle "bundle-2"]
854 uri = bundle-2.bundle
855 creationToken = 2
856
857 [bundle "bundle-3"]
858 uri = bundle-3.bundle
859 creationToken = 3
860
861 [bundle "bundle-4"]
862 uri = bundle-4.bundle
863 creationToken = 4
864
865 [bundle "bundle-6"]
866 uri = bundle-6.bundle
867 creationToken = 6
868
869 [bundle "bundle-7"]
870 uri = bundle-7.bundle
871 creationToken = 7
872 EOF
873
874 cp -r fetch-base fetch-1 &&
875 GIT_TRACE2_EVENT="$(pwd)/trace-fetch-1.txt" \
876 git -C fetch-1 fetch origin &&
877 test_cmp_config -C fetch-1 7 fetch.bundlecreationtoken &&
878
879 cat >expect <<-EOF &&
880 $HTTPD_URL/bundle-list
881 $HTTPD_URL/bundle-7.bundle
882 $HTTPD_URL/bundle-6.bundle
883 $HTTPD_URL/bundle-4.bundle
884 EOF
885 test_remote_https_urls <trace-fetch-1.txt >actual &&
886 test_cmp expect actual &&
887
888 # Check which bundles have unbundled by refs
889 git -C fetch-1 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
890 cat >expect <<-EOF &&
891 refs/bundles/base
892 refs/bundles/left
893 refs/bundles/lefter
894 refs/bundles/merge
895 refs/bundles/right
896 refs/bundles/righter
897 refs/bundles/top
898 EOF
899 test_cmp expect refs &&
900
901 # Case 2: middle bundle does not exist, only bundle-4 can unbundle
902 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
903 [bundle]
904 version = 1
905 mode = all
906 heuristic = creationToken
907
908 [bundle "bundle-1"]
909 uri = bundle-1.bundle
910 creationToken = 1
911
912 [bundle "bundle-2"]
913 uri = bundle-2.bundle
914 creationToken = 2
915
916 [bundle "bundle-3"]
917 uri = bundle-3.bundle
918 creationToken = 3
919
920 [bundle "bundle-4"]
921 uri = bundle-4.bundle
922 creationToken = 4
923
924 [bundle "bundle-6"]
925 uri = fake.bundle
926 creationToken = 6
927
928 [bundle "bundle-7"]
929 uri = bundle-7.bundle
930 creationToken = 7
931 EOF
932
933 cp -r fetch-base fetch-2 &&
934 GIT_TRACE2_EVENT="$(pwd)/trace-fetch-2.txt" \
935 git -C fetch-2 fetch origin &&
936
937 # Since bundle-7 fails to unbundle, do not update creation token.
938 test_cmp_config -C fetch-2 3 fetch.bundlecreationtoken &&
939
940 cat >expect <<-EOF &&
941 $HTTPD_URL/bundle-list
942 $HTTPD_URL/bundle-7.bundle
943 $HTTPD_URL/fake.bundle
944 $HTTPD_URL/bundle-4.bundle
945 EOF
946 test_remote_https_urls <trace-fetch-2.txt >actual &&
947 test_cmp expect actual &&
948
949 # Check which bundles have unbundled by refs
950 git -C fetch-2 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
951 cat >expect <<-EOF &&
952 refs/bundles/base
953 refs/bundles/left
954 refs/bundles/merge
955 refs/bundles/right
956 EOF
957 test_cmp expect refs &&
958
959 # Case 3: top bundle does not exist, rest unbundle fine.
960 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
961 [bundle]
962 version = 1
963 mode = all
964 heuristic = creationToken
965
966 [bundle "bundle-1"]
967 uri = bundle-1.bundle
968 creationToken = 1
969
970 [bundle "bundle-2"]
971 uri = bundle-2.bundle
972 creationToken = 2
973
974 [bundle "bundle-3"]
975 uri = bundle-3.bundle
976 creationToken = 3
977
978 [bundle "bundle-4"]
979 uri = bundle-4.bundle
980 creationToken = 4
981
982 [bundle "bundle-6"]
983 uri = bundle-6.bundle
984 creationToken = 6
985
986 [bundle "bundle-7"]
987 uri = fake.bundle
988 creationToken = 7
989 EOF
990
991 cp -r fetch-base fetch-3 &&
992 GIT_TRACE2_EVENT="$(pwd)/trace-fetch-3.txt" \
993 git -C fetch-3 fetch origin &&
994
995 # As long as we have continguous successful downloads,
996 # we _do_ set the maximum creation token.
997 test_cmp_config -C fetch-3 6 fetch.bundlecreationtoken &&
998
999 # NOTE: the fetch skips bundle-4 since bundle-6 successfully
1000 # unbundles itself and bundle-7 failed to download.
1001 cat >expect <<-EOF &&
1002 $HTTPD_URL/bundle-list
1003 $HTTPD_URL/fake.bundle
1004 $HTTPD_URL/bundle-6.bundle
1005 EOF
1006 test_remote_https_urls <trace-fetch-3.txt >actual &&
1007 test_cmp expect actual &&
1008
1009 # Check which bundles have unbundled by refs
1010 git -C fetch-3 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
1011 cat >expect <<-EOF &&
1012 refs/bundles/base
1013 refs/bundles/left
1014 refs/bundles/lefter
1015 refs/bundles/right
1016 refs/bundles/righter
1017 EOF
1018 test_cmp expect refs
1019 '
1020
1021 test_expect_success 'bundles are downloaded once during fetch --all' '
1022 test_when_finished rm -rf download-* trace*.txt fetch-mult &&
1023
1024 cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
1025 [bundle]
1026 version = 1
1027 mode = all
1028 heuristic = creationToken
1029
1030 [bundle "bundle-1"]
1031 uri = bundle-1.bundle
1032 creationToken = 1
1033
1034 [bundle "bundle-2"]
1035 uri = bundle-2.bundle
1036 creationToken = 2
1037
1038 [bundle "bundle-3"]
1039 uri = bundle-3.bundle
1040 creationToken = 3
1041 EOF
1042
1043 git clone --single-branch --branch=left \
1044 --bundle-uri="$HTTPD_URL/bundle-list" \
1045 "$HTTPD_URL/smart/fetch.git" fetch-mult &&
1046 git -C fetch-mult remote add dup1 "$HTTPD_URL/smart/fetch.git" &&
1047 git -C fetch-mult remote add dup2 "$HTTPD_URL/smart/fetch.git" &&
1048
1049 GIT_TRACE2_EVENT="$(pwd)/trace-mult.txt" \
1050 git -C fetch-mult fetch --all &&
1051 grep "\"child_start\".*\"git-remote-https\",\"$HTTPD_URL/bundle-list\"" \
1052 trace-mult.txt >bundle-fetches &&
1053 test_line_count = 1 bundle-fetches
1054 '
1055 # Do not add tests here unless they use the HTTP server, as they will
1056 # not run unless the HTTP dependencies exist.
1057
1058 test_done