1 #include "clar_libgit2.h"
9 static git_repository
*_repo
;
10 static git_revwalk
*_revwalker
;
11 static git_packbuilder
*_packbuilder
;
12 static git_indexer
*_indexer
;
13 static git_vector _commits
;
14 static int _commits_is_initialized
;
15 static git_transfer_progress _stats
;
17 void test_pack_packbuilder__initialize(void)
19 _repo
= cl_git_sandbox_init("testrepo.git");
20 cl_git_pass(p_chdir("testrepo.git"));
21 cl_git_pass(git_revwalk_new(&_revwalker
, _repo
));
22 cl_git_pass(git_packbuilder_new(&_packbuilder
, _repo
));
23 cl_git_pass(git_vector_init(&_commits
, 0, NULL
));
24 _commits_is_initialized
= 1;
25 memset(&_stats
, 0, sizeof(_stats
));
29 void test_pack_packbuilder__cleanup(void)
34 cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_FSYNC_GITDIR
, 0));
36 if (_commits_is_initialized
) {
37 _commits_is_initialized
= 0;
38 git_vector_foreach(&_commits
, i
, o
) {
41 git_vector_free(&_commits
);
44 git_packbuilder_free(_packbuilder
);
47 git_revwalk_free(_revwalker
);
50 git_indexer_free(_indexer
);
53 cl_git_pass(p_chdir(".."));
54 cl_git_sandbox_cleanup();
58 static void seed_packbuilder(void)
63 git_revwalk_sorting(_revwalker
, GIT_SORT_TIME
);
64 cl_git_pass(git_revwalk_push_ref(_revwalker
, "HEAD"));
66 while (git_revwalk_next(&oid
, _revwalker
) == 0) {
67 o
= git__malloc(GIT_OID_RAWSZ
);
70 cl_git_pass(git_vector_insert(&_commits
, o
));
73 git_vector_foreach(&_commits
, i
, o
) {
74 cl_git_pass(git_packbuilder_insert(_packbuilder
, o
, NULL
));
77 git_vector_foreach(&_commits
, i
, o
) {
79 cl_git_pass(git_object_lookup(&obj
, _repo
, o
, GIT_OBJECT_COMMIT
));
80 cl_git_pass(git_packbuilder_insert_tree(_packbuilder
,
81 git_commit_tree_id((git_commit
*)obj
)));
86 static int feed_indexer(void *ptr
, size_t len
, void *payload
)
88 git_transfer_progress
*stats
= (git_transfer_progress
*)payload
;
90 return git_indexer_append(_indexer
, ptr
, len
, stats
);
93 void test_pack_packbuilder__create_pack(void)
95 git_transfer_progress stats
;
96 git_buf buf
= GIT_BUF_INIT
, path
= GIT_BUF_INIT
;
99 char hex
[GIT_OID_HEXSZ
+1]; hex
[GIT_OID_HEXSZ
] = '\0';
103 cl_git_pass(git_indexer_new(&_indexer
, ".", 0, NULL
, NULL
));
104 cl_git_pass(git_packbuilder_foreach(_packbuilder
, feed_indexer
, &stats
));
105 cl_git_pass(git_indexer_commit(_indexer
, &stats
));
107 git_oid_fmt(hex
, git_indexer_hash(_indexer
));
108 git_buf_printf(&path
, "pack-%s.pack", hex
);
111 * By default, packfiles are created with only one thread.
112 * Therefore we can predict the object ordering and make sure
113 * we create exactly the same pack as git.git does when *not*
114 * reusing existing deltas (as libgit2).
116 * $ cd tests/resources/testrepo.git
117 * $ git rev-list --objects HEAD | \
118 * git pack-objects -q --no-reuse-delta --threads=1 pack
119 * $ sha1sum pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.pack
120 * 5d410bdf97cf896f9007681b92868471d636954b
124 cl_git_pass(git_futils_readbuffer(&buf
, git_buf_cstr(&path
)));
126 cl_git_pass(git_hash_ctx_init(&ctx
));
127 cl_git_pass(git_hash_update(&ctx
, buf
.ptr
, buf
.size
));
128 cl_git_pass(git_hash_final(&hash
, &ctx
));
129 git_hash_ctx_cleanup(&ctx
);
131 git_buf_dispose(&path
);
132 git_buf_dispose(&buf
);
134 git_oid_fmt(hex
, &hash
);
136 cl_assert_equal_s(hex
, "5d410bdf97cf896f9007681b92868471d636954b");
139 void test_pack_packbuilder__get_hash(void)
141 char hex
[GIT_OID_HEXSZ
+1]; hex
[GIT_OID_HEXSZ
] = '\0';
145 git_packbuilder_write(_packbuilder
, ".", 0, NULL
, NULL
);
146 git_oid_fmt(hex
, git_packbuilder_hash(_packbuilder
));
148 cl_assert_equal_s(hex
, "7f5fa362c664d68ba7221259be1cbd187434b2f0");
151 static void test_write_pack_permission(mode_t given
, mode_t expected
)
154 mode_t mask
, os_mask
;
158 git_packbuilder_write(_packbuilder
, ".", given
, NULL
, NULL
);
160 /* Windows does not return group/user bits from stat,
161 * files are never executable.
172 cl_git_pass(p_stat("pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.idx", &statbuf
));
173 cl_assert_equal_i(statbuf
.st_mode
& os_mask
, (expected
& ~mask
) & os_mask
);
175 cl_git_pass(p_stat("pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.pack", &statbuf
));
176 cl_assert_equal_i(statbuf
.st_mode
& os_mask
, (expected
& ~mask
) & os_mask
);
179 void test_pack_packbuilder__permissions_standard(void)
181 test_write_pack_permission(0, GIT_PACK_FILE_MODE
);
184 void test_pack_packbuilder__permissions_readonly(void)
186 test_write_pack_permission(0444, 0444);
189 void test_pack_packbuilder__permissions_readwrite(void)
191 test_write_pack_permission(0666, 0666);
194 void test_pack_packbuilder__does_not_fsync_by_default(void)
197 git_packbuilder_write(_packbuilder
, ".", 0666, NULL
, NULL
);
198 cl_assert_equal_sz(0, p_fsync__cnt
);
201 /* We fsync the packfile and index. On non-Windows, we also fsync
202 * the parent directories.
205 static int expected_fsyncs
= 2;
207 static int expected_fsyncs
= 4;
210 void test_pack_packbuilder__fsync_global_setting(void)
212 cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_FSYNC_GITDIR
, 1));
215 git_packbuilder_write(_packbuilder
, ".", 0666, NULL
, NULL
);
216 cl_assert_equal_sz(expected_fsyncs
, p_fsync__cnt
);
219 void test_pack_packbuilder__fsync_repo_setting(void)
221 cl_repo_set_bool(_repo
, "core.fsyncObjectFiles", true);
224 git_packbuilder_write(_packbuilder
, ".", 0666, NULL
, NULL
);
225 cl_assert_equal_sz(expected_fsyncs
, p_fsync__cnt
);
228 static int foreach_cb(void *buf
, size_t len
, void *payload
)
230 git_indexer
*idx
= (git_indexer
*) payload
;
231 cl_git_pass(git_indexer_append(idx
, buf
, len
, &_stats
));
235 void test_pack_packbuilder__foreach(void)
240 cl_git_pass(git_indexer_new(&idx
, ".", 0, NULL
, NULL
));
241 cl_git_pass(git_packbuilder_foreach(_packbuilder
, foreach_cb
, idx
));
242 cl_git_pass(git_indexer_commit(idx
, &_stats
));
243 git_indexer_free(idx
);
246 static int foreach_cancel_cb(void *buf
, size_t len
, void *payload
)
248 git_indexer
*idx
= (git_indexer
*)payload
;
249 cl_git_pass(git_indexer_append(idx
, buf
, len
, &_stats
));
250 return (_stats
.total_objects
> 2) ? -1111 : 0;
253 void test_pack_packbuilder__foreach_with_cancel(void)
258 cl_git_pass(git_indexer_new(&idx
, ".", 0, NULL
, NULL
));
260 git_packbuilder_foreach(_packbuilder
, foreach_cancel_cb
, idx
), -1111);
261 git_indexer_free(idx
);