filelimit.c 4.48 KB
Newer Older
1
#include "clar_libgit2.h"
lhchavez committed
2
#include "mwindow.h"
3

4
#include <git2.h>
5 6 7
#include "git2/sys/commit.h"
#include "git2/sys/mempack.h"

8 9
static size_t expected_open_mwindow_files = 0;
static size_t original_mwindow_file_limit = 0;
10

11
extern git_mutex git__mwindow_mutex;
lhchavez committed
12 13 14 15
extern git_mwindow_ctl git_mwindow__mem_ctl;

void test_pack_filelimit__initialize_tiny(void)
{
16 17 18
	expected_open_mwindow_files = 1;
	cl_git_pass(git_libgit2_opts(GIT_OPT_GET_MWINDOW_FILE_LIMIT, &original_mwindow_file_limit));
	cl_git_pass(git_libgit2_opts(GIT_OPT_SET_MWINDOW_FILE_LIMIT, expected_open_mwindow_files));
lhchavez committed
19 20 21 22
}

void test_pack_filelimit__initialize_medium(void)
{
23 24 25
	expected_open_mwindow_files = 10;
	cl_git_pass(git_libgit2_opts(GIT_OPT_GET_MWINDOW_FILE_LIMIT, &original_mwindow_file_limit));
	cl_git_pass(git_libgit2_opts(GIT_OPT_SET_MWINDOW_FILE_LIMIT, expected_open_mwindow_files));
26 27 28 29
}

void test_pack_filelimit__initialize_unlimited(void)
{
30 31
	expected_open_mwindow_files = 15;
	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));
lhchavez committed
33 34 35 36
}

void test_pack_filelimit__cleanup(void)
{
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

	cl_git_pass(git_buf_joinpath(&path, clar_sandbox_path(), "repo.git"));
	cl_fixture_cleanup(path.ptr);
	git_buf_dispose(&path);
}

/*
 * Create a packfile with one commit, one tree, and two blobs. The first blob
 * (README.md) has the same content in all commits, but the second one
 * (file.txt) has a different content in each commit.
 */
void create_packfile_commit(
		git_repository *repo,
		git_oid *out_commit_id,
		git_oid *parent_id,
		size_t commit_index,
		size_t commit_count)
{
	git_buf file_contents = GIT_BUF_INIT;
	git_treebuilder *treebuilder;
	git_packbuilder *packbuilder;
	git_signature *s;
	git_oid oid, tree_id, commit_id;
	const git_oid *parents[] = { parent_id };
	size_t parent_count = parent_id ? 1 : 0;

	cl_git_pass(git_treebuilder_new(&treebuilder, repo, NULL));

	cl_git_pass(git_blob_create_from_buffer(&oid, repo, "", 0));
	cl_git_pass(git_treebuilder_insert(NULL, treebuilder, "README.md", &oid, 0100644));

	cl_git_pass(git_buf_printf(&file_contents, "Commit %zd/%zd", commit_index, commit_count));
	cl_git_pass(git_blob_create_from_buffer(&oid, repo, file_contents.ptr, file_contents.size));
	cl_git_pass(git_treebuilder_insert(NULL, treebuilder, "file.txt", &oid, 0100644));

	cl_git_pass(git_treebuilder_write(&tree_id, treebuilder));
	cl_git_pass(git_signature_now(&s, "alice", "alice@example.com"));
	cl_git_pass(git_commit_create_from_ids(&commit_id, repo, "refs/heads/master", s, s,
			NULL, file_contents.ptr, &tree_id, parent_count, parents));

	cl_git_pass(git_packbuilder_new(&packbuilder, repo));
	cl_git_pass(git_packbuilder_insert_commit(packbuilder, &commit_id));
	cl_git_pass(git_packbuilder_write(packbuilder, NULL, 0, NULL, NULL));

	cl_git_pass(git_oid_cpy(out_commit_id, &commit_id));

	git_buf_dispose(&file_contents);
	git_treebuilder_free(treebuilder);
	git_packbuilder_free(packbuilder);
	git_signature_free(s);
lhchavez committed
89 90
}

91
void test_pack_filelimit__open_repo_with_multiple_packfiles(void)
92
{
93
	git_buf path = GIT_BUF_INIT;
lhchavez committed
94
	git_mwindow_ctl *ctl = &git_mwindow__mem_ctl;
95 96
	git_repository *repo;
	git_revwalk *walk;
97 98 99
	git_oid id, *parent_id = NULL;
	size_t i;
	const size_t commit_count = 16;
lhchavez committed
100
	unsigned int open_windows;
101 102

	/*
103 104
	 * Create a repository and populate it with 16 commits, each in its own
	 * packfile.
105
	 */
106 107
	cl_git_pass(git_buf_joinpath(&path, clar_sandbox_path(), "repo.git"));
	cl_git_pass(git_repository_init(&repo, path.ptr, true));
108 109
	for (i = 0; i < commit_count; ++i) {
		create_packfile_commit(repo, &id, parent_id, i + 1, commit_count);
110 111
		parent_id = &id;
	}
112

113
	cl_git_pass(git_revwalk_new(&walk, repo));
114 115 116
	cl_git_pass(git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL));
	cl_git_pass(git_revwalk_push_ref(walk, "refs/heads/master"));

117
	/* Walking the repository requires eventually opening each of the packfiles. */
118 119 120
	i = 0;
	while (git_revwalk_next(&id, walk) == 0)
		++i;
121
	cl_assert_equal_i(commit_count, i);
122

lhchavez committed
123 124 125 126 127 128 129 130
	cl_git_pass(git_mutex_lock(&git__mwindow_mutex));
	/*
	 * Adding an assert while holding a lock will cause the whole process to
	 * deadlock. Copy the value and do the assert after releasing the lock.
	 */
	open_windows = ctl->open_windows;
	cl_git_pass(git_mutex_unlock(&git__mwindow_mutex));

131
	cl_assert_equal_i(expected_open_mwindow_files, open_windows);
lhchavez committed
132

133
	git_buf_dispose(&path);
134 135 136
	git_revwalk_free(walk);
	git_repository_free(repo);
}