1 #include "clar_libgit2.h"
5 #include "git2/sys/commit.h"
6 #include "git2/sys/mempack.h"
8 static size_t expected_open_mwindow_files
= 0;
9 static size_t original_mwindow_file_limit
= 0;
11 extern git_mutex git__mwindow_mutex
;
12 extern git_mwindow_ctl git_mwindow__mem_ctl
;
14 void test_pack_filelimit__initialize_tiny(void)
16 expected_open_mwindow_files
= 1;
17 cl_git_pass(git_libgit2_opts(GIT_OPT_GET_MWINDOW_FILE_LIMIT
, &original_mwindow_file_limit
));
18 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_MWINDOW_FILE_LIMIT
, expected_open_mwindow_files
));
21 void test_pack_filelimit__initialize_medium(void)
23 expected_open_mwindow_files
= 10;
24 cl_git_pass(git_libgit2_opts(GIT_OPT_GET_MWINDOW_FILE_LIMIT
, &original_mwindow_file_limit
));
25 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_MWINDOW_FILE_LIMIT
, expected_open_mwindow_files
));
28 void test_pack_filelimit__initialize_unlimited(void)
30 expected_open_mwindow_files
= 15;
31 cl_git_pass(git_libgit2_opts(GIT_OPT_GET_MWINDOW_FILE_LIMIT
, &original_mwindow_file_limit
));
32 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_MWINDOW_FILE_LIMIT
, 0));
35 void test_pack_filelimit__cleanup(void)
37 git_str path
= GIT_STR_INIT
;
38 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_MWINDOW_FILE_LIMIT
, original_mwindow_file_limit
));
40 cl_git_pass(git_str_joinpath(&path
, clar_sandbox_path(), "repo.git"));
41 cl_fixture_cleanup(path
.ptr
);
42 git_str_dispose(&path
);
46 * Create a packfile with one commit, one tree, and two blobs. The first blob
47 * (README.md) has the same content in all commits, but the second one
48 * (file.txt) has a different content in each commit.
50 static void create_packfile_commit(
52 git_oid
*out_commit_id
,
57 git_str file_contents
= GIT_STR_INIT
;
58 git_treebuilder
*treebuilder
;
59 git_packbuilder
*packbuilder
;
61 git_oid oid
, tree_id
, commit_id
;
62 const git_oid
*parents
[] = { parent_id
};
63 size_t parent_count
= parent_id
? 1 : 0;
65 cl_git_pass(git_treebuilder_new(&treebuilder
, repo
, NULL
));
67 cl_git_pass(git_blob_create_from_buffer(&oid
, repo
, "", 0));
68 cl_git_pass(git_treebuilder_insert(NULL
, treebuilder
, "README.md", &oid
, 0100644));
70 cl_git_pass(git_str_printf(&file_contents
, "Commit %zd/%zd", commit_index
, commit_count
));
71 cl_git_pass(git_blob_create_from_buffer(&oid
, repo
, file_contents
.ptr
, file_contents
.size
));
72 cl_git_pass(git_treebuilder_insert(NULL
, treebuilder
, "file.txt", &oid
, 0100644));
74 cl_git_pass(git_treebuilder_write(&tree_id
, treebuilder
));
75 cl_git_pass(git_signature_now(&s
, "alice", "alice@example.com"));
76 cl_git_pass(git_commit_create_from_ids(&commit_id
, repo
, "refs/heads/master", s
, s
,
77 NULL
, file_contents
.ptr
, &tree_id
, parent_count
, parents
));
79 cl_git_pass(git_packbuilder_new(&packbuilder
, repo
));
80 cl_git_pass(git_packbuilder_insert_commit(packbuilder
, &commit_id
));
81 cl_git_pass(git_packbuilder_write(packbuilder
, NULL
, 0, NULL
, NULL
));
83 cl_git_pass(git_oid_cpy(out_commit_id
, &commit_id
));
85 git_str_dispose(&file_contents
);
86 git_treebuilder_free(treebuilder
);
87 git_packbuilder_free(packbuilder
);
88 git_signature_free(s
);
91 void test_pack_filelimit__open_repo_with_multiple_packfiles(void)
93 git_str path
= GIT_STR_INIT
;
94 git_mwindow_ctl
*ctl
= &git_mwindow__mem_ctl
;
97 git_oid id
, *parent_id
= NULL
;
99 const size_t commit_count
= 16;
100 unsigned int open_windows
;
103 * Create a repository and populate it with 16 commits, each in its own
106 cl_git_pass(git_str_joinpath(&path
, clar_sandbox_path(), "repo.git"));
107 cl_git_pass(git_repository_init(&repo
, path
.ptr
, true));
108 for (i
= 0; i
< commit_count
; ++i
) {
109 create_packfile_commit(repo
, &id
, parent_id
, i
+ 1, commit_count
);
113 cl_git_pass(git_revwalk_new(&walk
, repo
));
114 cl_git_pass(git_revwalk_sorting(walk
, GIT_SORT_TOPOLOGICAL
));
115 cl_git_pass(git_revwalk_push_ref(walk
, "refs/heads/master"));
117 /* Walking the repository requires eventually opening each of the packfiles. */
119 while (git_revwalk_next(&id
, walk
) == 0)
121 cl_assert_equal_i(commit_count
, i
);
123 cl_git_pass(git_mutex_lock(&git__mwindow_mutex
));
125 * Adding an assert while holding a lock will cause the whole process to
126 * deadlock. Copy the value and do the assert after releasing the lock.
128 open_windows
= ctl
->open_windows
;
129 cl_git_pass(git_mutex_unlock(&git__mwindow_mutex
));
131 cl_assert_equal_i(expected_open_mwindow_files
, open_windows
);
133 git_str_dispose(&path
);
134 git_revwalk_free(walk
);
135 git_repository_free(repo
);