test-reach: test can_all_from_reach_with_flags

The can_all_from_reach_with_flags method is used by ok_to_give_up in upload-pack.c to see if we have done enough negotiation during a fetch. This method is intentionally created to preserve state between calls to assist with stateful negotiation, such as over SSH. To make this method testable, add a new can_all_from_reach method that does the initial setup and final tear-down. We will later use this method in production code. Call the method from 'test-tool reach' for now. Since this is a many-to-many reachability query, add a new type of input to the 'test-tool reach' input format. Lines "Y:<committish>" create a list of commits to be the reachability targets from the commits in the 'X' list. In the context of fetch negotiation, the 'X' commits are the 'want' commits and the 'Y' commits are the 'have' commits. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Jul 20, 2018 at 16:33 UTC 1792bc125069e3e5b59f0158e259335a07aa7cf5
4 files changed +102 -2
commit-reach.c
+47
@@ -595,3 +595,50 @@ int can_all_from_reach_with_flag(struct object_array *from,
595 }
596 return 1;
597 }
598 +
599 +int can_all_from_reach(struct commit_list *from, struct commit_list *to,
600 + int cutoff_by_min_date)
601 +{
602 + struct object_array from_objs = OBJECT_ARRAY_INIT;
603 + time_t min_commit_date = cutoff_by_min_date ? from->item->date : 0;
604 + struct commit_list *from_iter = from, *to_iter = to;
605 + int result;
606 +
607 + while (from_iter) {
608 + add_object_array(&from_iter->item->object, NULL, &from_objs);
609 +
610 + if (!parse_commit(from_iter->item)) {
611 + if (from_iter->item->date < min_commit_date)
612 + min_commit_date = from_iter->item->date;
613 + }
614 +
615 + from_iter = from_iter->next;
616 + }
617 +
618 + while (to_iter) {
619 + if (!parse_commit(to_iter->item)) {
620 + if (to_iter->item->date < min_commit_date)
621 + min_commit_date = to_iter->item->date;
622 + }
623 +
624 + to_iter->item->object.flags |= PARENT2;
625 +
626 + to_iter = to_iter->next;
627 + }
628 +
629 + result = can_all_from_reach_with_flag(&from_objs, PARENT2, PARENT1,
630 + min_commit_date);
631 +
632 + while (from) {
633 + clear_commit_marks(from->item, PARENT1);
634 + from = from->next;
635 + }
636 +
637 + while (to) {
638 + clear_commit_marks(to->item, PARENT2);
639 + to = to->next;
640 + }
641 +
642 + object_array_clear(&from_objs);
643 + return result;
644 +}
commit-reach.h
+2
@@ -72,5 +72,7 @@ int can_all_from_reach_with_flag(struct object_array *from,
72 unsigned int with_flag,
73 unsigned int assign_flag,
74 time_t min_commit_date);
75 +int can_all_from_reach(struct commit_list *from, struct commit_list *to,
76 + int commit_date_cutoff);
77
78 #endif
t/helper/test-reach.c
+8 -2
@@ -29,7 +29,7 @@ int cmd__reach(int ac, const char **av)
29 {
30 struct object_id oid_A, oid_B;
31 struct commit *A, *B;
32 - struct commit_list *X;
32 + struct commit_list *X, *Y;
33 struct commit **X_array;
34 int X_nr, X_alloc;
35 struct strbuf buf = STRBUF_INIT;
@@ -41,7 +41,7 @@ int cmd__reach(int ac, const char **av)
41 exit(1);
42
43 A = B = NULL;
44 - X = NULL;
44 + X = Y = NULL;
45 X_nr = 0;
46 X_alloc = 16;
47 ALLOC_ARRAY(X_array, X_alloc);
@@ -86,6 +86,10 @@ int cmd__reach(int ac, const char **av)
86 X_array[X_nr++] = c;
87 break;
88
89 + case 'Y':
90 + commit_list_insert(c, &Y);
91 + break;
92 +
93 default:
94 die("unexpected start of line: %c", buf.buf[0]);
95 }
@@ -106,6 +110,8 @@ int cmd__reach(int ac, const char **av)
110 struct commit_list *list = reduce_heads(X);
111 printf("%s(X):\n", av[1]);
112 print_sorted_commit_ids(list);
113 + } else if (!strcmp(av[1], "can_all_from_reach")) {
114 + printf("%s(X,Y):%d\n", av[1], can_all_from_reach(X, Y, 1));
115 }
116
117 exit(0);
t/t6600-test-reach.sh
+45
@@ -160,4 +160,49 @@ test_expect_success 'reduce_heads' '
160 test_three_modes reduce_heads
161 '
162
163 +test_expect_success 'can_all_from_reach:hit' '
164 + cat >input <<-\EOF &&
165 + X:commit-2-10
166 + X:commit-3-9
167 + X:commit-4-8
168 + X:commit-5-7
169 + X:commit-6-6
170 + X:commit-7-5
171 + X:commit-8-4
172 + X:commit-9-3
173 + Y:commit-1-9
174 + Y:commit-2-8
175 + Y:commit-3-7
176 + Y:commit-4-6
177 + Y:commit-5-5
178 + Y:commit-6-4
179 + Y:commit-7-3
180 + Y:commit-8-1
181 + EOF
182 + echo "can_all_from_reach(X,Y):1" >expect &&
183 + test_three_modes can_all_from_reach
184 +'
185 +
186 +test_expect_success 'can_all_from_reach:miss' '
187 + cat >input <<-\EOF &&
188 + X:commit-2-10
189 + X:commit-3-9
190 + X:commit-4-8
191 + X:commit-5-7
192 + X:commit-6-6
193 + X:commit-7-5
194 + X:commit-8-4
195 + X:commit-9-3
196 + Y:commit-1-9
197 + Y:commit-2-8
198 + Y:commit-3-7
199 + Y:commit-4-6
200 + Y:commit-5-5
201 + Y:commit-6-4
202 + Y:commit-8-5
203 + EOF
204 + echo "can_all_from_reach(X,Y):0" >expect &&
205 + test_three_modes can_all_from_reach
206 +'
207 +
208 test_done