1 #include "clar_libgit2.h"
3 #include "git2/odb_backend.h"
5 #include "loose_data.h"
6 #include "repository.h"
9 # define S_IREAD S_IRUSR
10 # define S_IWRITE S_IWUSR
13 static void write_object_files(object_data
*d
)
17 if (p_mkdir(d
->dir
, GIT_OBJECT_DIR_MODE
) < 0)
18 cl_assert(errno
== EEXIST
);
20 cl_assert((fd
= p_creat(d
->file
, S_IREAD
| S_IWRITE
)) >= 0);
21 cl_must_pass(p_write(fd
, d
->bytes
, d
->blen
));
26 static void cmp_objects(git_rawobj
*o
, object_data
*d
)
28 cl_assert(o
->type
== git_object_string2type(d
->type
));
29 cl_assert(o
->len
== d
->dlen
);
32 cl_assert(memcmp(o
->data
, d
->data
, o
->len
) == 0);
35 static void test_read_object(object_data
*data
)
42 write_object_files(data
);
44 cl_git_pass(git_odb_open(&odb
, "test-objects"));
45 cl_git_pass(git_oid_fromstr(&id
, data
->id
));
46 cl_git_pass(git_odb_read(&obj
, odb
, &id
));
48 tmp
.data
= obj
->buffer
;
49 tmp
.len
= obj
->cached
.size
;
50 tmp
.type
= obj
->cached
.type
;
52 cmp_objects(&tmp
, data
);
54 git_odb_object_free(obj
);
58 static void test_read_header(object_data
*data
)
65 write_object_files(data
);
67 cl_git_pass(git_odb_open(&odb
, "test-objects"));
68 cl_git_pass(git_oid_fromstr(&id
, data
->id
));
69 cl_git_pass(git_odb_read_header(&len
, &type
, odb
, &id
));
71 cl_assert_equal_sz(data
->dlen
, len
);
72 cl_assert_equal_i(git_object_string2type(data
->type
), type
);
77 static void test_readstream_object(object_data
*data
, size_t blocksize
)
81 git_odb_stream
*stream
;
83 char buf
[2048], *ptr
= buf
;
87 write_object_files(data
);
89 cl_git_pass(git_odb_open(&odb
, "test-objects"));
90 cl_git_pass(git_oid_fromstr(&id
, data
->id
));
91 cl_git_pass(git_odb_open_rstream(&stream
, &tmp
.len
, &tmp
.type
, odb
, &id
));
96 cl_assert((ret
= git_odb_stream_read(stream
, ptr
, blocksize
)) >= 0);
100 cl_assert(remain
>= (size_t)ret
);
105 cl_assert(remain
== 0);
109 cmp_objects(&tmp
, data
);
111 git_odb_stream_free(stream
);
115 void test_odb_loose__initialize(void)
118 cl_must_pass(p_mkdir("test-objects", GIT_OBJECT_DIR_MODE
));
121 void test_odb_loose__cleanup(void)
123 cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_FSYNC_GITDIR
, 0));
124 cl_fixture_cleanup("test-objects");
127 void test_odb_loose__exists(void)
132 write_object_files(&one
);
133 cl_git_pass(git_odb_open(&odb
, "test-objects"));
135 cl_git_pass(git_oid_fromstr(&id
, one
.id
));
136 cl_assert(git_odb_exists(odb
, &id
));
138 cl_git_pass(git_oid_fromstrp(&id
, "8b137891"));
139 cl_git_pass(git_odb_exists_prefix(&id2
, odb
, &id
, 8));
140 cl_assert_equal_i(0, git_oid_streq(&id2
, one
.id
));
142 /* Test for a missing object */
143 cl_git_pass(git_oid_fromstr(&id
, "8b137891791fe96927ad78e64b0aad7bded08baa"));
144 cl_assert(!git_odb_exists(odb
, &id
));
146 cl_git_pass(git_oid_fromstrp(&id
, "8b13789a"));
147 cl_assert_equal_i(GIT_ENOTFOUND
, git_odb_exists_prefix(&id2
, odb
, &id
, 8));
152 void test_odb_loose__simple_reads(void)
154 test_read_object(&commit
);
155 test_read_object(&tree
);
156 test_read_object(&tag
);
157 test_read_object(&zero
);
158 test_read_object(&one
);
159 test_read_object(&two
);
160 test_read_object(&some
);
163 void test_odb_loose__streaming_reads(void)
165 size_t blocksizes
[] = { 1, 2, 4, 16, 99, 1024, 123456789 };
168 for (i
= 0; i
< ARRAY_SIZE(blocksizes
); i
++) {
169 test_readstream_object(&commit
, blocksizes
[i
]);
170 test_readstream_object(&tree
, blocksizes
[i
]);
171 test_readstream_object(&tag
, blocksizes
[i
]);
172 test_readstream_object(&zero
, blocksizes
[i
]);
173 test_readstream_object(&one
, blocksizes
[i
]);
174 test_readstream_object(&two
, blocksizes
[i
]);
175 test_readstream_object(&some
, blocksizes
[i
]);
179 void test_odb_loose__read_header(void)
181 test_read_header(&commit
);
182 test_read_header(&tree
);
183 test_read_header(&tag
);
184 test_read_header(&zero
);
185 test_read_header(&one
);
186 test_read_header(&two
);
187 test_read_header(&some
);
190 static void test_write_object_permission(
191 mode_t dir_mode
, mode_t file_mode
,
192 mode_t expected_dir_mode
, mode_t expected_file_mode
)
195 git_odb_backend
*backend
;
198 mode_t mask
, os_mask
;
200 /* Windows does not return group/user bits from stat,
201 * files are never executable.
212 cl_git_pass(git_odb_new(&odb
));
213 cl_git_pass(git_odb_backend_loose(&backend
, "test-objects", -1, 0, dir_mode
, file_mode
));
214 cl_git_pass(git_odb_add_backend(odb
, backend
, 1));
215 cl_git_pass(git_odb_write(&oid
, odb
, "Test data\n", 10, GIT_OBJECT_BLOB
));
217 cl_git_pass(p_stat("test-objects/67", &statbuf
));
218 cl_assert_equal_i(statbuf
.st_mode
& os_mask
, (expected_dir_mode
& ~mask
) & os_mask
);
220 cl_git_pass(p_stat("test-objects/67/b808feb36201507a77f85e6d898f0a2836e4a5", &statbuf
));
221 cl_assert_equal_i(statbuf
.st_mode
& os_mask
, (expected_file_mode
& ~mask
) & os_mask
);
226 void test_odb_loose__permissions_standard(void)
228 test_write_object_permission(0, 0, GIT_OBJECT_DIR_MODE
, GIT_OBJECT_FILE_MODE
);
231 void test_odb_loose__permissions_readonly(void)
233 test_write_object_permission(0777, 0444, 0777, 0444);
236 void test_odb_loose__permissions_readwrite(void)
238 test_write_object_permission(0777, 0666, 0777, 0666);
241 static void write_object_to_loose_odb(int fsync
)
244 git_odb_backend
*backend
;
247 cl_git_pass(git_odb_new(&odb
));
248 cl_git_pass(git_odb_backend_loose(&backend
, "test-objects", -1, fsync
, 0777, 0666));
249 cl_git_pass(git_odb_add_backend(odb
, backend
, 1));
250 cl_git_pass(git_odb_write(&oid
, odb
, "Test data\n", 10, GIT_OBJECT_BLOB
));
254 void test_odb_loose__does_not_fsync_by_default(void)
256 write_object_to_loose_odb(0);
257 cl_assert_equal_sz(0, p_fsync__cnt
);
260 void test_odb_loose__fsync_obeys_odb_option(void)
262 write_object_to_loose_odb(1);
263 cl_assert(p_fsync__cnt
> 0);
266 void test_odb_loose__fsync_obeys_global_setting(void)
268 cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_FSYNC_GITDIR
, 1));
269 write_object_to_loose_odb(0);
270 cl_assert(p_fsync__cnt
> 0);
273 void test_odb_loose__fsync_obeys_repo_setting(void)
275 git_repository
*repo
;
279 cl_git_pass(git_repository_init(&repo
, "test-objects", 1));
280 cl_git_pass(git_repository_odb__weakptr(&odb
, repo
));
281 cl_git_pass(git_odb_write(&oid
, odb
, "No fsync here\n", 14, GIT_OBJECT_BLOB
));
282 cl_assert(p_fsync__cnt
== 0);
283 git_repository_free(repo
);
285 cl_git_pass(git_repository_open(&repo
, "test-objects"));
286 cl_repo_set_bool(repo
, "core.fsyncObjectFiles", true);
287 cl_git_pass(git_repository_odb__weakptr(&odb
, repo
));
288 cl_git_pass(git_odb_write(&oid
, odb
, "Now fsync\n", 10, GIT_OBJECT_BLOB
));
289 cl_assert(p_fsync__cnt
> 0);
290 git_repository_free(repo
);