]> git.proxmox.com Git - libgit2.git/blame - tests/libgit2/refs/iterator.c
Merge https://salsa.debian.org/debian/libgit2 into proxmox/bullseye
[libgit2.git] / tests / libgit2 / refs / iterator.c
CommitLineData
4def7035
CMN
1#include "clar_libgit2.h"
2#include "refs.h"
3#include "vector.h"
4
5static git_repository *repo;
6
7void test_refs_iterator__initialize(void)
8{
eae0bfdc 9 repo = cl_git_sandbox_init("testrepo.git");
4def7035
CMN
10}
11
12void test_refs_iterator__cleanup(void)
13{
eae0bfdc 14 cl_git_sandbox_cleanup();
4def7035
CMN
15}
16
17static const char *refnames[] = {
22a2d3d5 18 "refs/blobs/annotated_tag_to_blob",
4def7035
CMN
19 "refs/heads/br2",
20 "refs/heads/cannot-fetch",
21 "refs/heads/chomped",
22 "refs/heads/haacked",
23 "refs/heads/master",
24 "refs/heads/not-good",
25 "refs/heads/packed",
26 "refs/heads/packed-test",
27 "refs/heads/subtrees",
28 "refs/heads/test",
29 "refs/heads/track-local",
30 "refs/heads/trailing",
e579e0f7 31 "refs/heads/with-empty-log",
4def7035
CMN
32 "refs/notes/fanout",
33 "refs/remotes/test/master",
34 "refs/tags/annotated_tag_to_blob",
35 "refs/tags/e90810b",
36 "refs/tags/hard_tag",
37 "refs/tags/point_to_blob",
38 "refs/tags/taggerless",
39 "refs/tags/test",
40 "refs/tags/wrapped_tag",
eae0bfdc
PP
41 NULL
42};
43
44static const char *refnames_with_symlink[] = {
22a2d3d5 45 "refs/blobs/annotated_tag_to_blob",
eae0bfdc
PP
46 "refs/heads/br2",
47 "refs/heads/cannot-fetch",
48 "refs/heads/chomped",
49 "refs/heads/haacked",
50 "refs/heads/link/a",
51 "refs/heads/link/b",
52 "refs/heads/link/c",
53 "refs/heads/link/d",
54 "refs/heads/master",
55 "refs/heads/not-good",
56 "refs/heads/packed",
57 "refs/heads/packed-test",
58 "refs/heads/subtrees",
59 "refs/heads/test",
60 "refs/heads/track-local",
61 "refs/heads/trailing",
e579e0f7 62 "refs/heads/with-empty-log",
eae0bfdc
PP
63 "refs/notes/fanout",
64 "refs/remotes/test/master",
65 "refs/tags/annotated_tag_to_blob",
66 "refs/tags/e90810b",
67 "refs/tags/hard_tag",
68 "refs/tags/point_to_blob",
69 "refs/tags/taggerless",
70 "refs/tags/test",
71 "refs/tags/wrapped_tag",
72 NULL
4def7035
CMN
73};
74
56960b83
VM
75static int refcmp_cb(const void *a, const void *b)
76{
77 const git_reference *refa = (const git_reference *)a;
78 const git_reference *refb = (const git_reference *)b;
79
80 return strcmp(refa->name, refb->name);
81}
82
eae0bfdc 83static void assert_all_refnames_match(const char **expected, git_vector *names)
11bd7a03
RB
84{
85 size_t i;
86 git_reference *ref;
87
eae0bfdc 88 git_vector_sort(names);
11bd7a03 89
eae0bfdc
PP
90 git_vector_foreach(names, i, ref) {
91 cl_assert(expected[i] != NULL);
92 cl_assert_equal_s(expected[i], ref->name);
11bd7a03
RB
93 git_reference_free(ref);
94 }
eae0bfdc 95 cl_assert(expected[i] == NULL);
11bd7a03 96
eae0bfdc 97 git_vector_free(names);
11bd7a03
RB
98}
99
4def7035
CMN
100void test_refs_iterator__list(void)
101{
102 git_reference_iterator *iter;
103 git_vector output;
56960b83 104 git_reference *ref;
4def7035 105
22a2d3d5 106 cl_git_pass(git_vector_init(&output, 33, &refcmp_cb));
4def7035
CMN
107 cl_git_pass(git_reference_iterator_new(&iter, repo));
108
11bd7a03
RB
109 while (1) {
110 int error = git_reference_next(&ref, iter);
111 if (error == GIT_ITEROVER)
112 break;
113 cl_git_pass(error);
114 cl_git_pass(git_vector_insert(&output, ref));
115 }
4def7035 116
56960b83 117 git_reference_iterator_free(iter);
4def7035 118
eae0bfdc 119 assert_all_refnames_match(refnames, &output);
4def7035 120}
51fc5e89
CMN
121
122void test_refs_iterator__empty(void)
123{
124 git_reference_iterator *iter;
125 git_odb *odb;
56960b83 126 git_reference *ref;
51fc5e89
CMN
127 git_repository *empty;
128
129 cl_git_pass(git_odb_new(&odb));
130 cl_git_pass(git_repository_wrap_odb(&empty, odb));
131
132 cl_git_pass(git_reference_iterator_new(&iter, empty));
56960b83 133 cl_assert_equal_i(GIT_ITEROVER, git_reference_next(&ref, iter));
51fc5e89
CMN
134
135 git_reference_iterator_free(iter);
136 git_odb_free(odb);
137 git_repository_free(empty);
138}
11bd7a03
RB
139
140static int refs_foreach_cb(git_reference *reference, void *payload)
141{
142 git_vector *output = payload;
143 cl_git_pass(git_vector_insert(output, reference));
144 return 0;
145}
146
147void test_refs_iterator__foreach(void)
148{
149 git_vector output;
22a2d3d5 150 cl_git_pass(git_vector_init(&output, 33, &refcmp_cb));
11bd7a03 151 cl_git_pass(git_reference_foreach(repo, refs_foreach_cb, &output));
eae0bfdc
PP
152 assert_all_refnames_match(refnames, &output);
153}
154
155void test_refs_iterator__foreach_through_symlink(void)
156{
157 git_vector output;
158
159#ifdef GIT_WIN32
160 cl_skip();
161#endif
162
163 cl_git_pass(git_vector_init(&output, 32, &refcmp_cb));
164
165 cl_git_pass(p_mkdir("refs", 0777));
166 cl_git_mkfile("refs/a", "1234567890123456789012345678901234567890");
167 cl_git_mkfile("refs/b", "1234567890123456789012345678901234567890");
168 cl_git_mkfile("refs/c", "1234567890123456789012345678901234567890");
169 cl_git_mkfile("refs/d", "1234567890123456789012345678901234567890");
170
171 cl_git_pass(p_symlink("../../../refs", "testrepo.git/refs/heads/link"));
172
173 cl_git_pass(git_reference_foreach(repo, refs_foreach_cb, &output));
174 assert_all_refnames_match(refnames_with_symlink, &output);
11bd7a03
RB
175}
176
177static int refs_foreach_cancel_cb(git_reference *reference, void *payload)
178{
179 int *cancel_after = payload;
180
181 git_reference_free(reference);
182
183 if (!*cancel_after)
184 return -333;
185 (*cancel_after)--;
186 return 0;
187}
188
189void test_refs_iterator__foreach_can_cancel(void)
190{
191 int cancel_after = 3;
192 cl_git_fail_with(
193 git_reference_foreach(repo, refs_foreach_cancel_cb, &cancel_after),
194 -333);
195 cl_assert_equal_i(0, cancel_after);
196}
197
198static int refs_foreach_name_cb(const char *name, void *payload)
199{
200 git_vector *output = payload;
201 cl_git_pass(git_vector_insert(output, git__strdup(name)));
202 return 0;
203}
204
205void test_refs_iterator__foreach_name(void)
206{
207 git_vector output;
208 size_t i;
209 char *name;
210
211 cl_git_pass(git_vector_init(&output, 32, &git__strcmp_cb));
212 cl_git_pass(
213 git_reference_foreach_name(repo, refs_foreach_name_cb, &output));
214
11bd7a03
RB
215 git_vector_sort(&output);
216
217 git_vector_foreach(&output, i, name) {
eae0bfdc
PP
218 cl_assert(refnames[i] != NULL);
219 cl_assert_equal_s(refnames[i], name);
11bd7a03
RB
220 git__free(name);
221 }
222
223 git_vector_free(&output);
224}
225
226static int refs_foreach_name_cancel_cb(const char *name, void *payload)
227{
228 int *cancel_after = payload;
229 if (!*cancel_after)
230 return -333;
231 GIT_UNUSED(name);
232 (*cancel_after)--;
233 return 0;
234}
235
236void test_refs_iterator__foreach_name_can_cancel(void)
237{
238 int cancel_after = 5;
239 cl_git_fail_with(
240 git_reference_foreach_name(
241 repo, refs_foreach_name_cancel_cb, &cancel_after),
242 -333);
243 cl_assert_equal_i(0, cancel_after);
244}
4ee2543c
CMN
245
246void test_refs_iterator__concurrent_delete(void)
247{
248 git_reference_iterator *iter;
249 size_t full_count = 0, concurrent_count = 0;
250 const char *name;
251 int error;
252
eae0bfdc 253 cl_git_sandbox_cleanup();
4ee2543c
CMN
254 repo = cl_git_sandbox_init("testrepo");
255
256 cl_git_pass(git_reference_iterator_new(&iter, repo));
257 while ((error = git_reference_next_name(&name, iter)) == 0) {
258 full_count++;
259 }
260
261 git_reference_iterator_free(iter);
262 cl_assert_equal_i(GIT_ITEROVER, error);
263
264 cl_git_pass(git_reference_iterator_new(&iter, repo));
265 while ((error = git_reference_next_name(&name, iter)) == 0) {
266 cl_git_pass(git_reference_remove(repo, name));
267 concurrent_count++;
268 }
269
270 git_reference_iterator_free(iter);
271 cl_assert_equal_i(GIT_ITEROVER, error);
272
273 cl_assert_equal_i(full_count, concurrent_count);
4ee2543c 274}