mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-08 03:15:46 +00:00

There was a problem found in the Rugged test suite where the refdb_fs_backend__next function could exit too early in some very specific hashing patterns for packed refs. This ports the Rugged test to libgit2 and then fixes the bug.
174 lines
3.9 KiB
C
174 lines
3.9 KiB
C
#include "clar_libgit2.h"
|
|
#include "refs.h"
|
|
|
|
static git_repository *repo;
|
|
static git_reference *fake_remote;
|
|
|
|
void test_refs_branches_foreach__initialize(void)
|
|
{
|
|
git_oid id;
|
|
|
|
cl_fixture_sandbox("testrepo.git");
|
|
cl_git_pass(git_repository_open(&repo, "testrepo.git"));
|
|
|
|
cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
|
|
cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0));
|
|
}
|
|
|
|
void test_refs_branches_foreach__cleanup(void)
|
|
{
|
|
git_reference_free(fake_remote);
|
|
fake_remote = NULL;
|
|
|
|
git_repository_free(repo);
|
|
repo = NULL;
|
|
|
|
cl_fixture_cleanup("testrepo.git");
|
|
|
|
cl_git_sandbox_cleanup();
|
|
}
|
|
|
|
static int count_branch_list_cb(const char *branch_name, git_branch_t branch_type, void *payload)
|
|
{
|
|
int *count;
|
|
|
|
GIT_UNUSED(branch_type);
|
|
GIT_UNUSED(branch_name);
|
|
|
|
count = (int *)payload;
|
|
(*count)++;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void assert_retrieval(unsigned int flags, unsigned int expected_count)
|
|
{
|
|
int count = 0;
|
|
|
|
cl_git_pass(git_branch_foreach(repo, flags, count_branch_list_cb, &count));
|
|
|
|
cl_assert_equal_i(expected_count, count);
|
|
}
|
|
|
|
void test_refs_branches_foreach__retrieve_all_branches(void)
|
|
{
|
|
assert_retrieval(GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE, 14);
|
|
}
|
|
|
|
void test_refs_branches_foreach__retrieve_remote_branches(void)
|
|
{
|
|
assert_retrieval(GIT_BRANCH_REMOTE, 2);
|
|
}
|
|
|
|
void test_refs_branches_foreach__retrieve_local_branches(void)
|
|
{
|
|
assert_retrieval(GIT_BRANCH_LOCAL, 12);
|
|
}
|
|
|
|
struct expectations {
|
|
const char *branch_name;
|
|
int encounters;
|
|
};
|
|
|
|
static void assert_branch_has_been_found(struct expectations *findings, const char* expected_branch_name)
|
|
{
|
|
int pos = 0;
|
|
|
|
for (pos = 0; findings[pos].branch_name; ++pos) {
|
|
if (strcmp(expected_branch_name, findings[pos].branch_name) == 0) {
|
|
cl_assert_equal_i(1, findings[pos].encounters);
|
|
return;
|
|
}
|
|
}
|
|
|
|
cl_fail("expected branch not found in list.");
|
|
}
|
|
|
|
static int contains_branch_list_cb(const char *branch_name, git_branch_t branch_type, void *payload)
|
|
{
|
|
int pos = 0;
|
|
struct expectations *exp;
|
|
|
|
GIT_UNUSED(branch_type);
|
|
|
|
exp = (struct expectations *)payload;
|
|
|
|
for (pos = 0; exp[pos].branch_name; ++pos) {
|
|
if (strcmp(branch_name, exp[pos].branch_name) == 0)
|
|
exp[pos].encounters++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* $ git branch -r
|
|
* nulltoken/HEAD -> nulltoken/master
|
|
* nulltoken/master
|
|
*/
|
|
void test_refs_branches_foreach__retrieve_remote_symbolic_HEAD_when_present(void)
|
|
{
|
|
struct expectations exp[] = {
|
|
{ "nulltoken/HEAD", 0 },
|
|
{ "nulltoken/master", 0 },
|
|
{ NULL, 0 }
|
|
};
|
|
|
|
git_reference_free(fake_remote);
|
|
cl_git_pass(git_reference_symbolic_create(&fake_remote, repo, "refs/remotes/nulltoken/HEAD", "refs/remotes/nulltoken/master", 0));
|
|
|
|
assert_retrieval(GIT_BRANCH_REMOTE, 3);
|
|
|
|
cl_git_pass(git_branch_foreach(repo, GIT_BRANCH_REMOTE, contains_branch_list_cb, &exp));
|
|
|
|
assert_branch_has_been_found(exp, "nulltoken/HEAD");
|
|
assert_branch_has_been_found(exp, "nulltoken/HEAD");
|
|
}
|
|
|
|
static int branch_list_interrupt_cb(
|
|
const char *branch_name, git_branch_t branch_type, void *payload)
|
|
{
|
|
int *count;
|
|
|
|
GIT_UNUSED(branch_type);
|
|
GIT_UNUSED(branch_name);
|
|
|
|
count = (int *)payload;
|
|
(*count)++;
|
|
|
|
return (*count == 5);
|
|
}
|
|
|
|
void test_refs_branches_foreach__can_cancel(void)
|
|
{
|
|
int count = 0;
|
|
|
|
cl_assert_equal_i(GIT_EUSER,
|
|
git_branch_foreach(repo, GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE,
|
|
branch_list_interrupt_cb, &count));
|
|
|
|
cl_assert_equal_i(5, count);
|
|
}
|
|
|
|
void test_refs_branches_foreach__mix_of_packed_and_loose(void)
|
|
{
|
|
struct expectations exp[] = {
|
|
{ "master", 0 },
|
|
{ "origin/HEAD", 0 },
|
|
{ "origin/master", 0 },
|
|
{ "origin/packed", 0 },
|
|
{ NULL, 0 }
|
|
};
|
|
git_repository *r2;
|
|
|
|
r2 = cl_git_sandbox_init("testrepo2");
|
|
|
|
cl_git_pass(git_branch_foreach(r2, GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE,
|
|
contains_branch_list_cb, &exp));
|
|
|
|
assert_branch_has_been_found(exp, "master");
|
|
assert_branch_has_been_found(exp, "origin/HEAD");
|
|
assert_branch_has_been_found(exp, "origin/master");
|
|
assert_branch_has_been_found(exp, "origin/packed");
|
|
}
|