]> git.proxmox.com Git - libgit2.git/blob - tests-clar/index/tests.c
Vector improvements and their fallout
[libgit2.git] / tests-clar / index / tests.c
1 #include "clar_libgit2.h"
2 #include "index.h"
3
4 static const size_t index_entry_count = 109;
5 static const size_t index_entry_count_2 = 1437;
6 #define TEST_INDEX_PATH cl_fixture("testrepo.git/index")
7 #define TEST_INDEX2_PATH cl_fixture("gitgit.index")
8 #define TEST_INDEXBIG_PATH cl_fixture("big.index")
9
10
11 // Suite data
12 struct test_entry {
13 size_t index;
14 char path[128];
15 git_off_t file_size;
16 git_time_t mtime;
17 };
18
19 static struct test_entry test_entries[] = {
20 {4, "Makefile", 5064, 0x4C3F7F33},
21 {62, "tests/Makefile", 2631, 0x4C3F7F33},
22 {36, "src/index.c", 10014, 0x4C43368D},
23 {6, "git.git-authors", 2709, 0x4C3F7F33},
24 {48, "src/revobject.h", 1448, 0x4C3F7FE2}
25 };
26
27 // Helpers
28 static void copy_file(const char *src, const char *dst)
29 {
30 git_buf source_buf = GIT_BUF_INIT;
31 git_file dst_fd;
32
33 cl_git_pass(git_futils_readbuffer(&source_buf, src));
34
35 dst_fd = git_futils_creat_withpath(dst, 0777, 0666); //-V536
36 if (dst_fd < 0)
37 goto cleanup;
38
39 cl_git_pass(p_write(dst_fd, source_buf.ptr, source_buf.size));
40
41 cleanup:
42 git_buf_free(&source_buf);
43 p_close(dst_fd);
44 }
45
46 static void files_are_equal(const char *a, const char *b)
47 {
48 git_buf buf_a = GIT_BUF_INIT;
49 git_buf buf_b = GIT_BUF_INIT;
50 int pass;
51
52 if (git_futils_readbuffer(&buf_a, a) < 0)
53 cl_assert(0);
54
55 if (git_futils_readbuffer(&buf_b, b) < 0) {
56 git_buf_free(&buf_a);
57 cl_assert(0);
58 }
59
60 pass = (buf_a.size == buf_b.size && !memcmp(buf_a.ptr, buf_b.ptr, buf_a.size));
61
62 git_buf_free(&buf_a);
63 git_buf_free(&buf_b);
64
65 cl_assert(pass);
66 }
67
68
69 // Fixture setup and teardown
70 void test_index_tests__initialize(void)
71 {
72 }
73
74 void test_index_tests__empty_index(void)
75 {
76 git_index *index;
77
78 cl_git_pass(git_index_open(&index, "in-memory-index"));
79 cl_assert(index->on_disk == 0);
80
81 cl_assert(git_index_entrycount(index) == 0);
82 cl_assert(index->entries.sorted);
83
84 git_index_free(index);
85 }
86
87 void test_index_tests__default_test_index(void)
88 {
89 git_index *index;
90 unsigned int i;
91 git_index_entry **entries;
92
93 cl_git_pass(git_index_open(&index, TEST_INDEX_PATH));
94 cl_assert(index->on_disk);
95
96 cl_assert(git_index_entrycount(index) == index_entry_count);
97 cl_assert(index->entries.sorted);
98
99 entries = (git_index_entry **)index->entries.contents;
100
101 for (i = 0; i < ARRAY_SIZE(test_entries); ++i) {
102 git_index_entry *e = entries[test_entries[i].index];
103
104 cl_assert_equal_s(e->path, test_entries[i].path);
105 cl_assert(e->mtime.seconds == test_entries[i].mtime);
106 cl_assert(e->file_size == test_entries[i].file_size);
107 }
108
109 git_index_free(index);
110 }
111
112 void test_index_tests__gitgit_index(void)
113 {
114 git_index *index;
115
116 cl_git_pass(git_index_open(&index, TEST_INDEX2_PATH));
117 cl_assert(index->on_disk);
118
119 cl_assert(git_index_entrycount(index) == index_entry_count_2);
120 cl_assert(index->entries.sorted);
121 cl_assert(index->tree != NULL);
122
123 git_index_free(index);
124 }
125
126 void test_index_tests__find_in_existing(void)
127 {
128 git_index *index;
129 unsigned int i;
130
131 cl_git_pass(git_index_open(&index, TEST_INDEX_PATH));
132
133 for (i = 0; i < ARRAY_SIZE(test_entries); ++i) {
134 size_t idx;
135
136 cl_assert(!git_index_find(&idx, index, test_entries[i].path));
137 cl_assert(idx == test_entries[i].index);
138 }
139
140 git_index_free(index);
141 }
142
143 void test_index_tests__find_in_empty(void)
144 {
145 git_index *index;
146 unsigned int i;
147
148 cl_git_pass(git_index_open(&index, "fake-index"));
149
150 for (i = 0; i < ARRAY_SIZE(test_entries); ++i) {
151 cl_assert(GIT_ENOTFOUND == git_index_find(NULL, index, test_entries[i].path));
152 }
153
154 git_index_free(index);
155 }
156
157 void test_index_tests__write(void)
158 {
159 git_index *index;
160
161 copy_file(TEST_INDEXBIG_PATH, "index_rewrite");
162
163 cl_git_pass(git_index_open(&index, "index_rewrite"));
164 cl_assert(index->on_disk);
165
166 cl_git_pass(git_index_write(index));
167 files_are_equal(TEST_INDEXBIG_PATH, "index_rewrite");
168
169 git_index_free(index);
170
171 p_unlink("index_rewrite");
172 }
173
174 void test_index_tests__sort0(void)
175 {
176 // sort the entires in an index
177 /*
178 * TODO: This no longer applies:
179 * index sorting in Git uses some specific changes to the way
180 * directories are sorted.
181 *
182 * We need to specificially check for this by creating a new
183 * index, adding entries in random order and then
184 * checking for consistency
185 */
186 }
187
188 void test_index_tests__sort1(void)
189 {
190 // sort the entires in an empty index
191 git_index *index;
192
193 cl_git_pass(git_index_open(&index, "fake-index"));
194
195 /* FIXME: this test is slightly dumb */
196 cl_assert(index->entries.sorted);
197
198 git_index_free(index);
199 }
200
201 static void cleanup_myrepo(void *opaque)
202 {
203 GIT_UNUSED(opaque);
204 cl_fixture_cleanup("myrepo");
205 }
206
207 void test_index_tests__add(void)
208 {
209 git_index *index;
210 git_filebuf file = GIT_FILEBUF_INIT;
211 git_repository *repo;
212 const git_index_entry *entry;
213 git_oid id1;
214
215 cl_set_cleanup(&cleanup_myrepo, NULL);
216
217 /* Intialize a new repository */
218 cl_git_pass(git_repository_init(&repo, "./myrepo", 0));
219
220 /* Ensure we're the only guy in the room */
221 cl_git_pass(git_repository_index(&index, repo));
222 cl_assert(git_index_entrycount(index) == 0);
223
224 /* Create a new file in the working directory */
225 cl_git_pass(git_futils_mkpath2file("myrepo/test.txt", 0777));
226 cl_git_pass(git_filebuf_open(&file, "myrepo/test.txt", 0));
227 cl_git_pass(git_filebuf_write(&file, "hey there\n", 10));
228 cl_git_pass(git_filebuf_commit(&file, 0666));
229
230 /* Store the expected hash of the file/blob
231 * This has been generated by executing the following
232 * $ echo "hey there" | git hash-object --stdin
233 */
234 cl_git_pass(git_oid_fromstr(&id1, "a8233120f6ad708f843d861ce2b7228ec4e3dec6"));
235
236 /* Add the new file to the index */
237 cl_git_pass(git_index_add_bypath(index, "test.txt"));
238
239 /* Wow... it worked! */
240 cl_assert(git_index_entrycount(index) == 1);
241 entry = git_index_get_byindex(index, 0);
242
243 /* And the built-in hashing mechanism worked as expected */
244 cl_assert(git_oid_cmp(&id1, &entry->oid) == 0);
245
246 /* Test access by path instead of index */
247 cl_assert((entry = git_index_get_bypath(index, "test.txt", 0)) != NULL);
248 cl_assert(git_oid_cmp(&id1, &entry->oid) == 0);
249
250 git_index_free(index);
251 git_repository_free(repo);
252 }
253
254 void test_index_tests__add_bypath_to_a_bare_repository_returns_EBAREPO(void)
255 {
256 git_repository *bare_repo;
257 git_index *index;
258
259 cl_git_pass(git_repository_open(&bare_repo, cl_fixture("testrepo.git")));
260 cl_git_pass(git_repository_index(&index, bare_repo));
261
262 cl_assert_equal_i(GIT_EBAREREPO, git_index_add_bypath(index, "test.txt"));
263
264 git_index_free(index);
265 git_repository_free(bare_repo);
266 }
267
268 /* Test that writing an invalid filename fails */
269 void test_index_tests__write_invalid_filename(void)
270 {
271 git_repository *repo;
272 git_index *index;
273 git_oid expected;
274
275 p_mkdir("read_tree", 0700);
276
277 cl_git_pass(git_repository_init(&repo, "./read_tree", 0));
278 cl_git_pass(git_repository_index(&index, repo));
279
280 cl_assert(git_index_entrycount(index) == 0);
281
282 cl_git_mkfile("./read_tree/.git/hello", NULL);
283
284 cl_git_pass(git_index_add_bypath(index, ".git/hello"));
285
286 /* write-tree */
287 cl_git_fail(git_index_write_tree(&expected, index));
288
289 git_index_free(index);
290 git_repository_free(repo);
291
292 cl_fixture_cleanup("read_tree");
293 }
294
295 void test_index_tests__remove_entry(void)
296 {
297 git_repository *repo;
298 git_index *index;
299
300 p_mkdir("index_test", 0770);
301
302 cl_git_pass(git_repository_init(&repo, "index_test", 0));
303 cl_git_pass(git_repository_index(&index, repo));
304 cl_assert(git_index_entrycount(index) == 0);
305
306 cl_git_mkfile("index_test/hello", NULL);
307 cl_git_pass(git_index_add_bypath(index, "hello"));
308 cl_git_pass(git_index_write(index));
309
310 cl_git_pass(git_index_read(index)); /* reload */
311 cl_assert(git_index_entrycount(index) == 1);
312 cl_assert(git_index_get_bypath(index, "hello", 0) != NULL);
313
314 cl_git_pass(git_index_remove(index, "hello", 0));
315 cl_git_pass(git_index_write(index));
316
317 cl_git_pass(git_index_read(index)); /* reload */
318 cl_assert(git_index_entrycount(index) == 0);
319 cl_assert(git_index_get_bypath(index, "hello", 0) == NULL);
320
321 git_index_free(index);
322 git_repository_free(repo);
323 cl_fixture_cleanup("index_test");
324 }
325
326 void test_index_tests__remove_directory(void)
327 {
328 git_repository *repo;
329 git_index *index;
330
331 p_mkdir("index_test", 0770);
332
333 cl_git_pass(git_repository_init(&repo, "index_test", 0));
334 cl_git_pass(git_repository_index(&index, repo));
335 cl_assert_equal_i(0, (int)git_index_entrycount(index));
336
337 p_mkdir("index_test/a", 0770);
338 cl_git_mkfile("index_test/a/1.txt", NULL);
339 cl_git_mkfile("index_test/a/2.txt", NULL);
340 cl_git_mkfile("index_test/a/3.txt", NULL);
341 cl_git_mkfile("index_test/b.txt", NULL);
342
343 cl_git_pass(git_index_add_bypath(index, "a/1.txt"));
344 cl_git_pass(git_index_add_bypath(index, "a/2.txt"));
345 cl_git_pass(git_index_add_bypath(index, "a/3.txt"));
346 cl_git_pass(git_index_add_bypath(index, "b.txt"));
347 cl_git_pass(git_index_write(index));
348
349 cl_git_pass(git_index_read(index)); /* reload */
350 cl_assert_equal_i(4, (int)git_index_entrycount(index));
351 cl_assert(git_index_get_bypath(index, "a/1.txt", 0) != NULL);
352 cl_assert(git_index_get_bypath(index, "a/2.txt", 0) != NULL);
353 cl_assert(git_index_get_bypath(index, "b.txt", 0) != NULL);
354
355 cl_git_pass(git_index_remove(index, "a/1.txt", 0));
356 cl_git_pass(git_index_write(index));
357
358 cl_git_pass(git_index_read(index)); /* reload */
359 cl_assert_equal_i(3, (int)git_index_entrycount(index));
360 cl_assert(git_index_get_bypath(index, "a/1.txt", 0) == NULL);
361 cl_assert(git_index_get_bypath(index, "a/2.txt", 0) != NULL);
362 cl_assert(git_index_get_bypath(index, "b.txt", 0) != NULL);
363
364 cl_git_pass(git_index_remove_directory(index, "a", 0));
365 cl_git_pass(git_index_write(index));
366
367 cl_git_pass(git_index_read(index)); /* reload */
368 cl_assert_equal_i(1, (int)git_index_entrycount(index));
369 cl_assert(git_index_get_bypath(index, "a/1.txt", 0) == NULL);
370 cl_assert(git_index_get_bypath(index, "a/2.txt", 0) == NULL);
371 cl_assert(git_index_get_bypath(index, "b.txt", 0) != NULL);
372
373 git_index_free(index);
374 git_repository_free(repo);
375 cl_fixture_cleanup("index_test");
376 }