]>
Commit | Line | Data |
---|---|---|
22a2d3d5 UG |
1 | #include "clar_libgit2.h" |
2 | #include "mwindow.h" | |
22a2d3d5 UG |
3 | |
4 | #include <git2.h> | |
5 | #include "git2/sys/commit.h" | |
6 | #include "git2/sys/mempack.h" | |
7 | ||
8 | static size_t expected_open_mwindow_files = 0; | |
9 | static size_t original_mwindow_file_limit = 0; | |
10 | ||
c25aa7cd | 11 | extern git_mutex git__mwindow_mutex; |
22a2d3d5 UG |
12 | extern git_mwindow_ctl git_mwindow__mem_ctl; |
13 | ||
14 | void test_pack_filelimit__initialize_tiny(void) | |
15 | { | |
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)); | |
19 | } | |
20 | ||
21 | void test_pack_filelimit__initialize_medium(void) | |
22 | { | |
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)); | |
26 | } | |
27 | ||
28 | void test_pack_filelimit__initialize_unlimited(void) | |
29 | { | |
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)); | |
33 | } | |
34 | ||
35 | void test_pack_filelimit__cleanup(void) | |
36 | { | |
e579e0f7 | 37 | git_str path = GIT_STR_INIT; |
22a2d3d5 UG |
38 | cl_git_pass(git_libgit2_opts(GIT_OPT_SET_MWINDOW_FILE_LIMIT, original_mwindow_file_limit)); |
39 | ||
e579e0f7 | 40 | cl_git_pass(git_str_joinpath(&path, clar_sandbox_path(), "repo.git")); |
22a2d3d5 | 41 | cl_fixture_cleanup(path.ptr); |
e579e0f7 | 42 | git_str_dispose(&path); |
22a2d3d5 UG |
43 | } |
44 | ||
45 | /* | |
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. | |
49 | */ | |
e579e0f7 | 50 | static void create_packfile_commit( |
22a2d3d5 UG |
51 | git_repository *repo, |
52 | git_oid *out_commit_id, | |
53 | git_oid *parent_id, | |
54 | size_t commit_index, | |
55 | size_t commit_count) | |
56 | { | |
e579e0f7 | 57 | git_str file_contents = GIT_STR_INIT; |
22a2d3d5 UG |
58 | git_treebuilder *treebuilder; |
59 | git_packbuilder *packbuilder; | |
60 | git_signature *s; | |
61 | git_oid oid, tree_id, commit_id; | |
62 | const git_oid *parents[] = { parent_id }; | |
63 | size_t parent_count = parent_id ? 1 : 0; | |
64 | ||
65 | cl_git_pass(git_treebuilder_new(&treebuilder, repo, NULL)); | |
66 | ||
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)); | |
69 | ||
e579e0f7 | 70 | cl_git_pass(git_str_printf(&file_contents, "Commit %zd/%zd", commit_index, commit_count)); |
22a2d3d5 UG |
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)); | |
73 | ||
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)); | |
78 | ||
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)); | |
82 | ||
83 | cl_git_pass(git_oid_cpy(out_commit_id, &commit_id)); | |
84 | ||
e579e0f7 | 85 | git_str_dispose(&file_contents); |
22a2d3d5 UG |
86 | git_treebuilder_free(treebuilder); |
87 | git_packbuilder_free(packbuilder); | |
88 | git_signature_free(s); | |
89 | } | |
90 | ||
91 | void test_pack_filelimit__open_repo_with_multiple_packfiles(void) | |
92 | { | |
e579e0f7 | 93 | git_str path = GIT_STR_INIT; |
22a2d3d5 UG |
94 | git_mwindow_ctl *ctl = &git_mwindow__mem_ctl; |
95 | git_repository *repo; | |
96 | git_revwalk *walk; | |
97 | git_oid id, *parent_id = NULL; | |
98 | size_t i; | |
99 | const size_t commit_count = 16; | |
100 | unsigned int open_windows; | |
101 | ||
102 | /* | |
103 | * Create a repository and populate it with 16 commits, each in its own | |
104 | * packfile. | |
105 | */ | |
e579e0f7 | 106 | cl_git_pass(git_str_joinpath(&path, clar_sandbox_path(), "repo.git")); |
22a2d3d5 UG |
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); | |
110 | parent_id = &id; | |
111 | } | |
112 | ||
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")); | |
116 | ||
117 | /* Walking the repository requires eventually opening each of the packfiles. */ | |
118 | i = 0; | |
119 | while (git_revwalk_next(&id, walk) == 0) | |
120 | ++i; | |
121 | cl_assert_equal_i(commit_count, i); | |
122 | ||
123 | cl_git_pass(git_mutex_lock(&git__mwindow_mutex)); | |
124 | /* | |
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. | |
127 | */ | |
128 | open_windows = ctl->open_windows; | |
129 | cl_git_pass(git_mutex_unlock(&git__mwindow_mutex)); | |
130 | ||
131 | cl_assert_equal_i(expected_open_mwindow_files, open_windows); | |
132 | ||
e579e0f7 | 133 | git_str_dispose(&path); |
22a2d3d5 UG |
134 | git_revwalk_free(walk); |
135 | git_repository_free(repo); | |
136 | } |