]>
Commit | Line | Data |
---|---|---|
0a32dca5 | 1 | #include "clar_libgit2.h" |
22a2d3d5 | 2 | #include "futils.h" |
1e60e5f4 | 3 | #include "pack.h" |
6774b107 | 4 | #include "hash.h" |
0a32dca5 MS |
5 | #include "iterator.h" |
6 | #include "vector.h" | |
bffbeebb | 7 | #include "posix.h" |
e579e0f7 | 8 | #include "hash.h" |
0a32dca5 MS |
9 | |
10 | static git_repository *_repo; | |
11 | static git_revwalk *_revwalker; | |
12 | static git_packbuilder *_packbuilder; | |
a6154f21 | 13 | static git_indexer *_indexer; |
0a32dca5 | 14 | static git_vector _commits; |
9094d30b | 15 | static int _commits_is_initialized; |
22a2d3d5 UG |
16 | static git_indexer_progress _stats; |
17 | ||
18 | extern bool git_disable_pack_keep_file_checks; | |
0a32dca5 MS |
19 | |
20 | void test_pack_packbuilder__initialize(void) | |
21 | { | |
7b51d675 | 22 | _repo = cl_git_sandbox_init("testrepo.git"); |
d7a29463 | 23 | cl_git_pass(p_chdir("testrepo.git")); |
0a32dca5 MS |
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)); | |
9094d30b | 27 | _commits_is_initialized = 1; |
7697e541 | 28 | memset(&_stats, 0, sizeof(_stats)); |
1c2c0ae2 | 29 | p_fsync__cnt = 0; |
0a32dca5 MS |
30 | } |
31 | ||
32 | void test_pack_packbuilder__cleanup(void) | |
33 | { | |
34 | git_oid *o; | |
35 | unsigned int i; | |
36 | ||
6c23704d | 37 | cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_FSYNC_GITDIR, 0)); |
22a2d3d5 | 38 | cl_git_pass(git_libgit2_opts(GIT_OPT_DISABLE_PACK_KEEP_FILE_CHECKS, false)); |
1c2c0ae2 | 39 | |
9094d30b SC |
40 | if (_commits_is_initialized) { |
41 | _commits_is_initialized = 0; | |
42 | git_vector_foreach(&_commits, i, o) { | |
43 | git__free(o); | |
44 | } | |
45 | git_vector_free(&_commits); | |
0a32dca5 | 46 | } |
9094d30b | 47 | |
0a32dca5 | 48 | git_packbuilder_free(_packbuilder); |
9094d30b SC |
49 | _packbuilder = NULL; |
50 | ||
0a32dca5 | 51 | git_revwalk_free(_revwalker); |
9094d30b SC |
52 | _revwalker = NULL; |
53 | ||
a6154f21 | 54 | git_indexer_free(_indexer); |
3dfed9cb | 55 | _indexer = NULL; |
9094d30b | 56 | |
0478b7f4 | 57 | cl_git_pass(p_chdir("..")); |
7b51d675 | 58 | cl_git_sandbox_cleanup(); |
9094d30b | 59 | _repo = NULL; |
0a32dca5 MS |
60 | } |
61 | ||
3dfed9cb | 62 | static void seed_packbuilder(void) |
0a32dca5 | 63 | { |
0a32dca5 MS |
64 | git_oid oid, *o; |
65 | unsigned int i; | |
66 | ||
67 | git_revwalk_sorting(_revwalker, GIT_SORT_TIME); | |
68 | cl_git_pass(git_revwalk_push_ref(_revwalker, "HEAD")); | |
69 | ||
70 | while (git_revwalk_next(&oid, _revwalker) == 0) { | |
ad5611d8 | 71 | o = git__malloc(sizeof(git_oid)); |
0a32dca5 MS |
72 | cl_assert(o != NULL); |
73 | git_oid_cpy(o, &oid); | |
74 | cl_git_pass(git_vector_insert(&_commits, o)); | |
75 | } | |
76 | ||
77 | git_vector_foreach(&_commits, i, o) { | |
78 | cl_git_pass(git_packbuilder_insert(_packbuilder, o, NULL)); | |
79 | } | |
80 | ||
81 | git_vector_foreach(&_commits, i, o) { | |
82 | git_object *obj; | |
ac3d33df | 83 | cl_git_pass(git_object_lookup(&obj, _repo, o, GIT_OBJECT_COMMIT)); |
0a32dca5 | 84 | cl_git_pass(git_packbuilder_insert_tree(_packbuilder, |
cfbe4be3 | 85 | git_commit_tree_id((git_commit *)obj))); |
0a32dca5 MS |
86 | git_object_free(obj); |
87 | } | |
3dfed9cb CMN |
88 | } |
89 | ||
447ae791 CMN |
90 | static int feed_indexer(void *ptr, size_t len, void *payload) |
91 | { | |
22a2d3d5 | 92 | git_indexer_progress *stats = (git_indexer_progress *)payload; |
447ae791 | 93 | |
a6154f21 | 94 | return git_indexer_append(_indexer, ptr, len, stats); |
447ae791 CMN |
95 | } |
96 | ||
3dfed9cb CMN |
97 | void test_pack_packbuilder__create_pack(void) |
98 | { | |
22a2d3d5 | 99 | git_indexer_progress stats; |
e579e0f7 | 100 | git_str buf = GIT_STR_INIT, path = GIT_STR_INIT; |
6774b107 | 101 | git_hash_ctx ctx; |
e579e0f7 MB |
102 | unsigned char hash[GIT_HASH_SHA1_SIZE]; |
103 | char hex[(GIT_HASH_SHA1_SIZE * 2) + 1]; | |
0a32dca5 | 104 | |
3dfed9cb | 105 | seed_packbuilder(); |
0a32dca5 | 106 | |
ac3d33df | 107 | cl_git_pass(git_indexer_new(&_indexer, ".", 0, NULL, NULL)); |
447ae791 | 108 | cl_git_pass(git_packbuilder_foreach(_packbuilder, feed_indexer, &stats)); |
a6154f21 | 109 | cl_git_pass(git_indexer_commit(_indexer, &stats)); |
447ae791 | 110 | |
e579e0f7 | 111 | git_str_printf(&path, "pack-%s.pack", git_indexer_name(_indexer)); |
6774b107 MS |
112 | |
113 | /* | |
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). | |
118 | * | |
83e1efbf | 119 | * $ cd tests/resources/testrepo.git |
6774b107 MS |
120 | * $ git rev-list --objects HEAD | \ |
121 | * git pack-objects -q --no-reuse-delta --threads=1 pack | |
c0e54155 | 122 | * $ sha1sum pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.pack |
6774b107 MS |
123 | * 5d410bdf97cf896f9007681b92868471d636954b |
124 | * | |
125 | */ | |
126 | ||
e579e0f7 | 127 | cl_git_pass(git_futils_readbuffer(&buf, git_str_cstr(&path))); |
6774b107 | 128 | |
e579e0f7 | 129 | cl_git_pass(git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1)); |
6774b107 | 130 | cl_git_pass(git_hash_update(&ctx, buf.ptr, buf.size)); |
e579e0f7 | 131 | cl_git_pass(git_hash_final(hash, &ctx)); |
be225be7 | 132 | git_hash_ctx_cleanup(&ctx); |
6774b107 | 133 | |
e579e0f7 MB |
134 | git_str_dispose(&path); |
135 | git_str_dispose(&buf); | |
6774b107 | 136 | |
e579e0f7 | 137 | git_hash_fmt(hex, hash, GIT_HASH_SHA1_SIZE); |
6774b107 | 138 | cl_assert_equal_s(hex, "5d410bdf97cf896f9007681b92868471d636954b"); |
0a32dca5 | 139 | } |
3dfed9cb | 140 | |
e579e0f7 | 141 | void test_pack_packbuilder__get_name(void) |
cc2447da | 142 | { |
cc2447da ET |
143 | seed_packbuilder(); |
144 | ||
22a2d3d5 | 145 | cl_git_pass(git_packbuilder_write(_packbuilder, ".", 0, NULL, NULL)); |
e579e0f7 | 146 | cl_assert_equal_s("7f5fa362c664d68ba7221259be1cbd187434b2f0", git_packbuilder_name(_packbuilder)); |
cc2447da ET |
147 | } |
148 | ||
22a2d3d5 UG |
149 | void test_pack_packbuilder__write_default_path(void) |
150 | { | |
151 | seed_packbuilder(); | |
152 | ||
153 | cl_git_pass(git_packbuilder_write(_packbuilder, NULL, 0, NULL, NULL)); | |
e579e0f7 MB |
154 | cl_assert(git_fs_path_exists("objects/pack/pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.idx")); |
155 | cl_assert(git_fs_path_exists("objects/pack/pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.pack")); | |
22a2d3d5 UG |
156 | } |
157 | ||
1e60e5f4 ET |
158 | static void test_write_pack_permission(mode_t given, mode_t expected) |
159 | { | |
160 | struct stat statbuf; | |
161 | mode_t mask, os_mask; | |
162 | ||
163 | seed_packbuilder(); | |
164 | ||
22a2d3d5 | 165 | cl_git_pass(git_packbuilder_write(_packbuilder, ".", given, NULL, NULL)); |
1e60e5f4 ET |
166 | |
167 | /* Windows does not return group/user bits from stat, | |
168 | * files are never executable. | |
169 | */ | |
170 | #ifdef GIT_WIN32 | |
171 | os_mask = 0600; | |
172 | #else | |
173 | os_mask = 0777; | |
174 | #endif | |
175 | ||
176 | mask = p_umask(0); | |
177 | p_umask(mask); | |
178 | ||
c0e54155 | 179 | cl_git_pass(p_stat("pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.idx", &statbuf)); |
1e60e5f4 ET |
180 | cl_assert_equal_i(statbuf.st_mode & os_mask, (expected & ~mask) & os_mask); |
181 | ||
c0e54155 | 182 | cl_git_pass(p_stat("pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.pack", &statbuf)); |
1e60e5f4 ET |
183 | cl_assert_equal_i(statbuf.st_mode & os_mask, (expected & ~mask) & os_mask); |
184 | } | |
185 | ||
186 | void test_pack_packbuilder__permissions_standard(void) | |
187 | { | |
188 | test_write_pack_permission(0, GIT_PACK_FILE_MODE); | |
189 | } | |
190 | ||
191 | void test_pack_packbuilder__permissions_readonly(void) | |
192 | { | |
193 | test_write_pack_permission(0444, 0444); | |
194 | } | |
195 | ||
196 | void test_pack_packbuilder__permissions_readwrite(void) | |
197 | { | |
198 | test_write_pack_permission(0666, 0666); | |
199 | } | |
200 | ||
1c2c0ae2 ET |
201 | void test_pack_packbuilder__does_not_fsync_by_default(void) |
202 | { | |
203 | seed_packbuilder(); | |
22a2d3d5 | 204 | cl_git_pass(git_packbuilder_write(_packbuilder, ".", 0666, NULL, NULL)); |
1c2c0ae2 ET |
205 | cl_assert_equal_sz(0, p_fsync__cnt); |
206 | } | |
207 | ||
1c04a96b ET |
208 | /* We fsync the packfile and index. On non-Windows, we also fsync |
209 | * the parent directories. | |
210 | */ | |
3ac05d11 | 211 | #ifdef GIT_WIN32 |
1c04a96b | 212 | static int expected_fsyncs = 2; |
3ac05d11 | 213 | #else |
1c04a96b | 214 | static int expected_fsyncs = 4; |
3ac05d11 ET |
215 | #endif |
216 | ||
1c04a96b ET |
217 | void test_pack_packbuilder__fsync_global_setting(void) |
218 | { | |
6c23704d | 219 | cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_FSYNC_GITDIR, 1)); |
1c2c0ae2 ET |
220 | p_fsync__cnt = 0; |
221 | seed_packbuilder(); | |
22a2d3d5 | 222 | cl_git_pass(git_packbuilder_write(_packbuilder, ".", 0666, NULL, NULL)); |
1c04a96b ET |
223 | cl_assert_equal_sz(expected_fsyncs, p_fsync__cnt); |
224 | } | |
225 | ||
226 | void test_pack_packbuilder__fsync_repo_setting(void) | |
227 | { | |
228 | cl_repo_set_bool(_repo, "core.fsyncObjectFiles", true); | |
229 | p_fsync__cnt = 0; | |
230 | seed_packbuilder(); | |
22a2d3d5 | 231 | cl_git_pass(git_packbuilder_write(_packbuilder, ".", 0666, NULL, NULL)); |
1c04a96b | 232 | cl_assert_equal_sz(expected_fsyncs, p_fsync__cnt); |
1c2c0ae2 ET |
233 | } |
234 | ||
3dfed9cb CMN |
235 | static int foreach_cb(void *buf, size_t len, void *payload) |
236 | { | |
a6154f21 | 237 | git_indexer *idx = (git_indexer *) payload; |
7697e541 | 238 | cl_git_pass(git_indexer_append(idx, buf, len, &_stats)); |
3dfed9cb CMN |
239 | return 0; |
240 | } | |
241 | ||
242 | void test_pack_packbuilder__foreach(void) | |
243 | { | |
a6154f21 | 244 | git_indexer *idx; |
3dfed9cb CMN |
245 | |
246 | seed_packbuilder(); | |
ac3d33df | 247 | cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL)); |
3dfed9cb | 248 | cl_git_pass(git_packbuilder_foreach(_packbuilder, foreach_cb, idx)); |
7697e541 RB |
249 | cl_git_pass(git_indexer_commit(idx, &_stats)); |
250 | git_indexer_free(idx); | |
251 | } | |
252 | ||
253 | static int foreach_cancel_cb(void *buf, size_t len, void *payload) | |
254 | { | |
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; | |
258 | } | |
259 | ||
260 | void test_pack_packbuilder__foreach_with_cancel(void) | |
261 | { | |
262 | git_indexer *idx; | |
263 | ||
264 | seed_packbuilder(); | |
ac3d33df | 265 | cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL)); |
7697e541 RB |
266 | cl_git_fail_with( |
267 | git_packbuilder_foreach(_packbuilder, foreach_cancel_cb, idx), -1111); | |
a6154f21 | 268 | git_indexer_free(idx); |
3dfed9cb | 269 | } |
22a2d3d5 UG |
270 | |
271 | void test_pack_packbuilder__keep_file_check(void) | |
272 | { | |
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); | |
276 | } |