| #include "clar_libgit2.h" |
| #include "index.h" |
| |
| static git_repository *g_repo = NULL; |
| |
| void test_index_version__cleanup(void) |
| { |
| cl_git_sandbox_cleanup(); |
| g_repo = NULL; |
| } |
| |
| void test_index_version__can_read_v4(void) |
| { |
| const char *paths[] = { |
| "file.tx", "file.txt", "file.txz", "foo", "zzz", |
| }; |
| git_index *index; |
| size_t i; |
| |
| g_repo = cl_git_sandbox_init("indexv4"); |
| |
| cl_git_pass(git_repository_index(&index, g_repo)); |
| cl_assert_equal_sz(git_index_entrycount(index), 5); |
| |
| for (i = 0; i < ARRAY_SIZE(paths); i++) { |
| const git_index_entry *entry = |
| git_index_get_bypath(index, paths[i], GIT_INDEX_STAGE_NORMAL); |
| |
| cl_assert(entry != NULL); |
| } |
| |
| git_index_free(index); |
| } |
| |
| void test_index_version__can_write_v4(void) |
| { |
| const char *paths[] = { |
| "foo", |
| "foox", |
| "foobar", |
| "foobal", |
| "x", |
| "xz", |
| "xyzzyx" |
| }; |
| git_index_entry entry; |
| git_index *index; |
| size_t i; |
| |
| g_repo = cl_git_sandbox_init("empty_standard_repo"); |
| cl_git_pass(git_repository_index(&index, g_repo)); |
| cl_git_pass(git_index_set_version(index, 4)); |
| |
| for (i = 0; i < ARRAY_SIZE(paths); i++) { |
| memset(&entry, 0, sizeof(entry)); |
| entry.path = paths[i]; |
| entry.mode = GIT_FILEMODE_BLOB; |
| cl_git_pass(git_index_add_frombuffer(index, &entry, paths[i], |
| strlen(paths[i]) + 1)); |
| } |
| cl_assert_equal_sz(git_index_entrycount(index), ARRAY_SIZE(paths)); |
| |
| cl_git_pass(git_index_write(index)); |
| git_index_free(index); |
| |
| cl_git_pass(git_repository_index(&index, g_repo)); |
| cl_assert(git_index_version(index) == 4); |
| |
| for (i = 0; i < ARRAY_SIZE(paths); i++) { |
| const git_index_entry *e; |
| |
| cl_assert(e = git_index_get_bypath(index, paths[i], 0)); |
| cl_assert_equal_s(paths[i], e->path); |
| } |
| |
| git_index_free(index); |
| } |
| |
| void test_index_version__v4_uses_path_compression(void) |
| { |
| git_index_entry entry; |
| git_index *index; |
| char path[250], buf[1]; |
| struct stat st; |
| char i, j; |
| |
| memset(path, 'a', sizeof(path)); |
| memset(buf, 'a', sizeof(buf)); |
| |
| memset(&entry, 0, sizeof(entry)); |
| entry.path = path; |
| entry.mode = GIT_FILEMODE_BLOB; |
| |
| g_repo = cl_git_sandbox_init("indexv4"); |
| cl_git_pass(git_repository_index(&index, g_repo)); |
| |
| /* write 676 paths of 250 bytes length */ |
| for (i = 'a'; i <= 'z'; i++) { |
| for (j = 'a'; j < 'z'; j++) { |
| path[ARRAY_SIZE(path) - 3] = i; |
| path[ARRAY_SIZE(path) - 2] = j; |
| path[ARRAY_SIZE(path) - 1] = '\0'; |
| cl_git_pass(git_index_add_frombuffer(index, &entry, buf, sizeof(buf))); |
| } |
| } |
| |
| cl_git_pass(git_index_write(index)); |
| cl_git_pass(p_stat(git_index_path(index), &st)); |
| |
| /* |
| * Without path compression, the written paths would at |
| * least take |
| * |
| * (entries * pathlen) = len |
| * (676 * 250) = 169000 |
| * |
| * bytes. As index v4 uses suffix-compression and our |
| * written paths only differ in the last two entries, |
| * this number will be much smaller, e.g. |
| * |
| * (1 * pathlen) + (675 * 2) = len |
| * 676 + 1350 = 2026 |
| * |
| * bytes. |
| * |
| * Note that the above calculations do not include |
| * additional metadata of the index, e.g. OIDs or |
| * index extensions. Including those we get an index |
| * of approx. 200kB without compression and 40kB with |
| * compression. As this is a lot smaller than without |
| * compression, we can verify that path compression is |
| * used. |
| */ |
| cl_assert_(st.st_size < 75000, "path compression not enabled"); |
| |
| git_index_free(index); |
| } |