11#include "clar_libgit2.h"
22#include "mwindow.h"
33#include "global.h"
4+
45#include <git2.h>
6+ #include "git2/sys/commit.h"
7+ #include "git2/sys/mempack.h"
8+
9+ static size_t _expected_open_mwindow_files = 0 ;
10+ static size_t _original_mwindow_file_limit = 0 ;
511
612extern git_mwindow_ctl git_mwindow__mem_ctl ;
7- size_t mwindow_file_limit = 0 ;
8- size_t original_mwindow_file_limit = 0 ;
913
1014void test_pack_filelimit__initialize_tiny (void )
1115{
12- mwindow_file_limit = 1 ;
13- cl_git_pass (git_libgit2_opts (GIT_OPT_GET_MWINDOW_FILE_LIMIT , & original_mwindow_file_limit ));
14- cl_git_pass (git_libgit2_opts (GIT_OPT_SET_MWINDOW_FILE_LIMIT , mwindow_file_limit ));
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 ));
1519}
1620
1721void test_pack_filelimit__initialize_medium (void )
1822{
19- mwindow_file_limit = 100 ;
20- cl_git_pass (git_libgit2_opts (GIT_OPT_GET_MWINDOW_FILE_LIMIT , & original_mwindow_file_limit ));
21- cl_git_pass (git_libgit2_opts (GIT_OPT_SET_MWINDOW_FILE_LIMIT , mwindow_file_limit ));
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 ));
2233}
2334
2435void test_pack_filelimit__cleanup (void )
2536{
26- cl_git_pass (git_libgit2_opts (GIT_OPT_SET_MWINDOW_FILE_LIMIT , original_mwindow_file_limit ));
37+ git_buf path = GIT_BUF_INIT ;
38+ cl_git_pass (git_libgit2_opts (GIT_OPT_SET_MWINDOW_FILE_LIMIT , _original_mwindow_file_limit ));
39+
40+ cl_git_pass (git_buf_joinpath (& path , clar_sandbox_path (), "repo.git" ));
41+ cl_fixture_cleanup (path .ptr );
42+ git_buf_dispose (& path );
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+ */
50+ void create_packfile_commit (
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+ {
57+ git_buf file_contents = GIT_BUF_INIT ;
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+
70+ cl_git_pass (git_buf_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 ));
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+
85+ git_buf_dispose (& file_contents );
86+ git_treebuilder_free (treebuilder );
87+ git_packbuilder_free (packbuilder );
88+ git_signature_free (s );
2789}
2890
29- void test_pack_filelimit__open_repo_with_1025_packfiles (void )
91+ void test_pack_filelimit__open_repo_with_multiple_packfiles (void )
3092{
93+ git_buf path = GIT_BUF_INIT ;
3194 git_mwindow_ctl * ctl = & git_mwindow__mem_ctl ;
3295 git_repository * repo ;
3396 git_revwalk * walk ;
34- git_oid id ;
35- int i ;
97+ git_oid id , * parent_id = NULL ;
98+ size_t i ;
99+ const size_t commit_count = 16 ;
36100 unsigned int open_windows ;
37101
38102 /*
39- * This repository contains 1025 packfiles, each with one commit, one tree,
40- * and two blobs. The first blob (README.md) has the same content in all
41- * commits, but the second one (file.txt) has a different content in each
42- * commit.
103+ * Create a repository and populate it with 16 commits, each in its own
104+ * packfile.
43105 */
44- cl_git_pass (git_repository_open (& repo , cl_fixture ("1025.git" )));
45- cl_git_pass (git_revwalk_new (& walk , repo ));
106+ cl_git_pass (git_buf_joinpath (& path , clar_sandbox_path (), "repo.git" ));
107+ cl_git_pass (git_repository_init (& repo , path .ptr , true));
108+ for (i = 1 ; i <= commit_count ; ++ i ) {
109+ create_packfile_commit (repo , & id , parent_id , i , commit_count );
110+ parent_id = & id ;
111+ }
46112
113+ cl_git_pass (git_revwalk_new (& walk , repo ));
47114 cl_git_pass (git_revwalk_sorting (walk , GIT_SORT_TOPOLOGICAL ));
48115 cl_git_pass (git_revwalk_push_ref (walk , "refs/heads/master" ));
49116
50117 /*
51- * Walking the tree requires opening each of the 1025 packfiles. This should
52- * work in all platforms, including those where the default limit of open
53- * file descriptors is small (e.g. 256 in macOS).
118+ * Walking the repository requires eventually opening each of the packfiles.
54119 */
55120 i = 0 ;
56121 while (git_revwalk_next (& id , walk ) == 0 )
57122 ++ i ;
58- cl_assert_equal_i (1025 , i );
123+ cl_assert_equal_i (commit_count , i );
59124
60125 cl_git_pass (git_mutex_lock (& git__mwindow_mutex ));
61126 /*
@@ -65,8 +130,9 @@ void test_pack_filelimit__open_repo_with_1025_packfiles(void)
65130 open_windows = ctl -> open_windows ;
66131 cl_git_pass (git_mutex_unlock (& git__mwindow_mutex ));
67132
68- cl_assert_equal_i (mwindow_file_limit , open_windows );
133+ cl_assert_equal_i (_expected_open_mwindow_files , open_windows );
69134
135+ git_buf_dispose (& path );
70136 git_revwalk_free (walk );
71137 git_repository_free (repo );
72138}
0 commit comments