1 #include "clar_libgit2.h"
10 static git_repository
*_repo
;
11 static git_revwalk
*_revwalker
;
12 static git_packbuilder
*_packbuilder
;
13 static git_indexer
*_indexer
;
14 static git_vector _commits
;
15 static int _commits_is_initialized
;
16 static git_indexer_progress _stats
;
18 extern bool git_disable_pack_keep_file_checks
;
20 void test_pack_packbuilder__initialize(void)
22 _repo
= cl_git_sandbox_init("testrepo.git");
23 cl_git_pass(p_chdir("testrepo.git"));
24 cl_git_pass(git_revwalk_new(&_revwalker
, _repo
));
25 cl_git_pass(git_packbuilder_new(&_packbuilder
, _repo
));
26 cl_git_pass(git_vector_init(&_commits
, 0, NULL
));
27 _commits_is_initialized
= 1;
28 memset(&_stats
, 0, sizeof(_stats
));
32 void test_pack_packbuilder__cleanup(void)
37 cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_FSYNC_GITDIR
, 0));
38 cl_git_pass(git_libgit2_opts(GIT_OPT_DISABLE_PACK_KEEP_FILE_CHECKS
, false));
40 if (_commits_is_initialized
) {
41 _commits_is_initialized
= 0;
42 git_vector_foreach(&_commits
, i
, o
) {
45 git_vector_free(&_commits
);
48 git_packbuilder_free(_packbuilder
);
51 git_revwalk_free(_revwalker
);
54 git_indexer_free(_indexer
);
57 cl_git_pass(p_chdir(".."));
58 cl_git_sandbox_cleanup();
62 static void seed_packbuilder(void)
67 git_revwalk_sorting(_revwalker
, GIT_SORT_TIME
);
68 cl_git_pass(git_revwalk_push_ref(_revwalker
, "HEAD"));
70 while (git_revwalk_next(&oid
, _revwalker
) == 0) {
71 o
= git__malloc(GIT_OID_RAWSZ
);
74 cl_git_pass(git_vector_insert(&_commits
, o
));
77 git_vector_foreach(&_commits
, i
, o
) {
78 cl_git_pass(git_packbuilder_insert(_packbuilder
, o
, NULL
));
81 git_vector_foreach(&_commits
, i
, o
) {
83 cl_git_pass(git_object_lookup(&obj
, _repo
, o
, GIT_OBJECT_COMMIT
));
84 cl_git_pass(git_packbuilder_insert_tree(_packbuilder
,
85 git_commit_tree_id((git_commit
*)obj
)));
90 static int feed_indexer(void *ptr
, size_t len
, void *payload
)
92 git_indexer_progress
*stats
= (git_indexer_progress
*)payload
;
94 return git_indexer_append(_indexer
, ptr
, len
, stats
);
97 void test_pack_packbuilder__create_pack(void)
99 git_indexer_progress stats
;
100 git_str buf
= GIT_STR_INIT
, path
= GIT_STR_INIT
;
102 unsigned char hash
[GIT_HASH_SHA1_SIZE
];
103 char hex
[(GIT_HASH_SHA1_SIZE
* 2) + 1];
107 cl_git_pass(git_indexer_new(&_indexer
, ".", 0, NULL
, NULL
));
108 cl_git_pass(git_packbuilder_foreach(_packbuilder
, feed_indexer
, &stats
));
109 cl_git_pass(git_indexer_commit(_indexer
, &stats
));
111 git_str_printf(&path
, "pack-%s.pack", git_indexer_name(_indexer
));
114 * By default, packfiles are created with only one thread.
115 * Therefore we can predict the object ordering and make sure
116 * we create exactly the same pack as git.git does when *not*
117 * reusing existing deltas (as libgit2).
119 * $ cd tests/resources/testrepo.git
120 * $ git rev-list --objects HEAD | \
121 * git pack-objects -q --no-reuse-delta --threads=1 pack
122 * $ sha1sum pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.pack
123 * 5d410bdf97cf896f9007681b92868471d636954b
127 cl_git_pass(git_futils_readbuffer(&buf
, git_str_cstr(&path
)));
129 cl_git_pass(git_hash_ctx_init(&ctx
, GIT_HASH_ALGORITHM_SHA1
));
130 cl_git_pass(git_hash_update(&ctx
, buf
.ptr
, buf
.size
));
131 cl_git_pass(git_hash_final(hash
, &ctx
));
132 git_hash_ctx_cleanup(&ctx
);
134 git_str_dispose(&path
);
135 git_str_dispose(&buf
);
137 git_hash_fmt(hex
, hash
, GIT_HASH_SHA1_SIZE
);
138 cl_assert_equal_s(hex
, "5d410bdf97cf896f9007681b92868471d636954b");
141 void test_pack_packbuilder__get_name(void)
145 cl_git_pass(git_packbuilder_write(_packbuilder
, ".", 0, NULL
, NULL
));
146 cl_assert_equal_s("7f5fa362c664d68ba7221259be1cbd187434b2f0", git_packbuilder_name(_packbuilder
));
149 void test_pack_packbuilder__write_default_path(void)
153 cl_git_pass(git_packbuilder_write(_packbuilder
, NULL
, 0, NULL
, NULL
));
154 cl_assert(git_fs_path_exists("objects/pack/pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.idx"));
155 cl_assert(git_fs_path_exists("objects/pack/pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.pack"));
158 static void test_write_pack_permission(mode_t given
, mode_t expected
)
161 mode_t mask
, os_mask
;
165 cl_git_pass(git_packbuilder_write(_packbuilder
, ".", given
, NULL
, NULL
));
167 /* Windows does not return group/user bits from stat,
168 * files are never executable.
179 cl_git_pass(p_stat("pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.idx", &statbuf
));
180 cl_assert_equal_i(statbuf
.st_mode
& os_mask
, (expected
& ~mask
) & os_mask
);
182 cl_git_pass(p_stat("pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.pack", &statbuf
));
183 cl_assert_equal_i(statbuf
.st_mode
& os_mask
, (expected
& ~mask
) & os_mask
);
186 void test_pack_packbuilder__permissions_standard(void)
188 test_write_pack_permission(0, GIT_PACK_FILE_MODE
);
191 void test_pack_packbuilder__permissions_readonly(void)
193 test_write_pack_permission(0444, 0444);
196 void test_pack_packbuilder__permissions_readwrite(void)
198 test_write_pack_permission(0666, 0666);
201 void test_pack_packbuilder__does_not_fsync_by_default(void)
204 cl_git_pass(git_packbuilder_write(_packbuilder
, ".", 0666, NULL
, NULL
));
205 cl_assert_equal_sz(0, p_fsync__cnt
);
208 /* We fsync the packfile and index. On non-Windows, we also fsync
209 * the parent directories.
212 static int expected_fsyncs
= 2;
214 static int expected_fsyncs
= 4;
217 void test_pack_packbuilder__fsync_global_setting(void)
219 cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_FSYNC_GITDIR
, 1));
222 cl_git_pass(git_packbuilder_write(_packbuilder
, ".", 0666, NULL
, NULL
));
223 cl_assert_equal_sz(expected_fsyncs
, p_fsync__cnt
);
226 void test_pack_packbuilder__fsync_repo_setting(void)
228 cl_repo_set_bool(_repo
, "core.fsyncObjectFiles", true);
231 cl_git_pass(git_packbuilder_write(_packbuilder
, ".", 0666, NULL
, NULL
));
232 cl_assert_equal_sz(expected_fsyncs
, p_fsync__cnt
);
235 static int foreach_cb(void *buf
, size_t len
, void *payload
)
237 git_indexer
*idx
= (git_indexer
*) payload
;
238 cl_git_pass(git_indexer_append(idx
, buf
, len
, &_stats
));
242 void test_pack_packbuilder__foreach(void)
247 cl_git_pass(git_indexer_new(&idx
, ".", 0, NULL
, NULL
));
248 cl_git_pass(git_packbuilder_foreach(_packbuilder
, foreach_cb
, idx
));
249 cl_git_pass(git_indexer_commit(idx
, &_stats
));
250 git_indexer_free(idx
);
253 static int foreach_cancel_cb(void *buf
, size_t len
, void *payload
)
255 git_indexer
*idx
= (git_indexer
*)payload
;
256 cl_git_pass(git_indexer_append(idx
, buf
, len
, &_stats
));
257 return (_stats
.total_objects
> 2) ? -1111 : 0;
260 void test_pack_packbuilder__foreach_with_cancel(void)
265 cl_git_pass(git_indexer_new(&idx
, ".", 0, NULL
, NULL
));
267 git_packbuilder_foreach(_packbuilder
, foreach_cancel_cb
, idx
), -1111);
268 git_indexer_free(idx
);
271 void test_pack_packbuilder__keep_file_check(void)
273 assert(!git_disable_pack_keep_file_checks
);
274 cl_git_pass(git_libgit2_opts(GIT_OPT_DISABLE_PACK_KEEP_FILE_CHECKS
, true));
275 assert(git_disable_pack_keep_file_checks
);