tests: wire up reftable tests

Wire up reftable tests so that they can be executed by setting the
`CLAR_REF_FORMAT` environment variable. This only catches tests that use
`cl_git_sandbox_init()`, but that should cover most of our tests. So
this infrastructure isn't perfect, but for now it's good enough. We may
want to iterate on it in the future.
This commit is contained in:
Patrick Steinhardt
2025-07-22 13:00:37 +02:00
parent 415f3fbdb0
commit 5c6cba5142
11 changed files with 128 additions and 85 deletions

View File

@@ -172,13 +172,42 @@ static git_repository *_cl_repo = NULL;
git_repository *cl_git_sandbox_init(const char *sandbox)
{
/* Get the name of the sandbox folder which will be created */
const char *basename = cl_fixture_basename(sandbox);
const char *basename;
char *ref_format;
/* Copy the whole sandbox folder from our fixtures to our test sandbox
* area. After this it can be accessed with `./sandbox`
*/
cl_fixture_sandbox(sandbox);
/* Get the name of the sandbox folder which will be created */
basename = cl_fixture_basename(sandbox);
ref_format = cl_getenv("CLAR_REF_FORMAT");
if (!ref_format || !strcmp(ref_format, "files")) {
/*
* Copy the whole sandbox folder from our fixtures to our
* test sandbox area. After this it can be accessed with
* `./sandbox`
*/
cl_fixture_sandbox(sandbox);
} else if (!strcmp(ref_format, "reftable")) {
struct git_str reftable_sandbox = GIT_STR_INIT;
cl_git_pass(git_str_joinpath(&reftable_sandbox, "reftable", sandbox));
if (!git_fs_path_isdir(cl_fixture(reftable_sandbox.ptr))) {
git_str_dispose(&reftable_sandbox);
_cl_sandbox = NULL;
_cl_repo = NULL;
cl_fail("no seed for reftable repository");
}
/*
* Copy over the sandbox and rename it so that the basename
* matches the originally requested basename.
*/
cl_fixture_sandbox(reftable_sandbox.ptr);
git_str_dispose(&reftable_sandbox);
} else {
cl_fail("Unexpected ref format");
}
git__free(ref_format);
_cl_sandbox = sandbox;
cl_git_pass(p_chdir(basename));

View File

@@ -608,7 +608,7 @@ void test_iterator_workdir__filesystem(void)
void test_iterator_workdir__filesystem2(void)
{
git_iterator *i;
static const char *expect_base[] = {
static const char *expect_files[] = {
"heads/br2",
"heads/dir",
"heads/executable",
@@ -626,14 +626,21 @@ void test_iterator_workdir__filesystem2(void)
"tags/foo/foo/bar",
"tags/point_to_blob",
"tags/test",
NULL,
};
static const char *expect_reftable[] = {
"heads",
};
g_repo = cl_git_sandbox_init("testrepo");
cl_git_pass(git_iterator_for_filesystem(
&i, "testrepo/.git/refs", NULL));
expect_iterator_items(i, 17, expect_base, 17, expect_base);
if (cl_repo_has_ref_format(g_repo, "files"))
expect_iterator_items(i, ARRAY_SIZE(expect_files), expect_files,
ARRAY_SIZE(expect_files), expect_files);
else
expect_iterator_items(i, ARRAY_SIZE(expect_reftable), expect_reftable,
ARRAY_SIZE(expect_reftable), expect_reftable);
git_iterator_free(i);
}

View File

@@ -76,7 +76,10 @@ void test_refs_basic__longpaths(void)
/* Adding one more character gives us a path that is too long. */
cl_git_pass(git_str_putc(&refname, 'z'));
cl_git_fail(git_reference_create(&two, g_repo, refname.ptr, &id, 0, NULL));
if (cl_repo_has_ref_format(g_repo, "files"))
cl_git_fail(git_reference_create(&two, g_repo, refname.ptr, &id, 0, NULL));
else
cl_git_pass(git_reference_create(&two, g_repo, refname.ptr, &id, 0, NULL));
git_reference_free(one);
git_reference_free(two);

View File

@@ -281,7 +281,10 @@ static void test_win32_name(const char *name)
ret = git_reference_create(&new_reference, g_repo, name, &id, 0, NULL);
#ifdef GIT_WIN32
cl_assert_equal_i(GIT_EINVALIDSPEC, ret);
if (cl_repo_has_ref_format(g_repo, "files"))
cl_assert_equal_i(GIT_EINVALIDSPEC, ret);
else
cl_git_pass(ret);
#else
cl_git_pass(ret);
#endif

View File

@@ -8,10 +8,9 @@ void test_refs_foreachglob__initialize(void)
{
git_oid id;
cl_fixture_sandbox("testrepo.git");
cl_git_pass(git_repository_open(&repo, "testrepo.git"));
repo = cl_git_sandbox_init("testrepo.git");
cl_git_pass(git_oid_from_string(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1));
cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0, NULL));
}
@@ -19,11 +18,7 @@ void test_refs_foreachglob__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_cb(const char *reference_name, void *payload)

View File

@@ -27,10 +27,16 @@ void test_refs_namespaces__get_and_set(void)
void test_refs_namespaces__namespace_doesnt_show_normal_refs(void)
{
static git_strarray ref_list;
static git_strarray ref_list = { 0 };
cl_git_pass(git_repository_set_namespace(g_repo, "namespace"));
cl_git_pass(git_reference_list(&ref_list, g_repo));
cl_assert_equal_i(0, ref_list.count);
if (cl_repo_has_ref_format(g_repo, "reftable")) {
cl_git_fail(git_reference_list(&ref_list, g_repo));
} else {
cl_git_pass(git_reference_list(&ref_list, g_repo));
cl_assert_equal_i(0, ref_list.count);
}
git_strarray_dispose(&ref_list);
}

View File

@@ -285,6 +285,9 @@ void test_refs_reflog_reflog__cannot_write_a_moved_reflog(void)
git_str master_log_path = GIT_STR_INIT, moved_log_path = GIT_STR_INIT;
git_reflog *reflog;
if (!cl_repo_has_ref_format(g_repo, "files"))
cl_skip();
cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master"));
cl_git_pass(git_reflog_read(&reflog, g_repo, "refs/heads/master"));
@@ -332,8 +335,12 @@ void test_refs_reflog_reflog__write_when_explicitly_active(void)
git_reference *ref;
git_oid id;
if (!cl_repo_has_ref_format(g_repo, "files"))
cl_skip();
git_oid_from_string(&id, current_master_tip, GIT_OID_SHA1);
git_reference_ensure_log(g_repo, "refs/tags/foo");
cl_git_pass(git_reference_ensure_log(g_repo, "refs/tags/foo"));
cl_git_pass(git_reference_create(&ref, g_repo, "refs/tags/foo", &id, 1, NULL));
git_reference_free(ref);

View File

@@ -131,12 +131,12 @@ static void test_invalid_revspec(const char* invalid_spec)
void test_refs_revparse__initialize(void)
{
cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
g_repo = cl_git_sandbox_init("testrepo.git");
}
void test_refs_revparse__cleanup(void)
{
git_repository_free(g_repo);
cl_git_sandbox_cleanup();
}
void test_refs_revparse__nonexistant_object(void)
@@ -346,7 +346,8 @@ static void create_fake_stash_reference_and_reflog(git_repository *repo)
cl_git_pass(git_reference_rename(&new_master, master, "refs/fakestash", 0, NULL));
git_reference_free(master);
cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&log_path)));
if (cl_repo_has_ref_format(g_repo, "files"))
cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&log_path)));
git_str_dispose(&log_path);
git_reference_free(new_master);
@@ -354,11 +355,9 @@ static void create_fake_stash_reference_and_reflog(git_repository *repo)
void test_refs_revparse__reflog_of_a_ref_under_refs(void)
{
git_repository *repo = cl_git_sandbox_init("testrepo.git");
test_object_inrepo("refs/fakestash", NULL, g_repo);
test_object_inrepo("refs/fakestash", NULL, repo);
create_fake_stash_reference_and_reflog(repo);
create_fake_stash_reference_and_reflog(g_repo);
/*
* $ git reflog -1 refs/fakestash
@@ -373,12 +372,10 @@ void test_refs_revparse__reflog_of_a_ref_under_refs(void)
* $ git reflog -1 fakestash@{0}
* a65fedf fakestash@{0}: commit: checking in
*/
test_object_inrepo("refs/fakestash", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo);
test_object_inrepo("refs/fakestash@{0}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo);
test_object_inrepo("fakestash", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo);
test_object_inrepo("fakestash@{0}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo);
cl_git_sandbox_cleanup();
test_object_inrepo("refs/fakestash", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", g_repo);
test_object_inrepo("refs/fakestash@{0}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", g_repo);
test_object_inrepo("fakestash", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", g_repo);
test_object_inrepo("fakestash@{0}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", g_repo);
}
void test_refs_revparse__revwalk(void)
@@ -593,6 +590,7 @@ void test_refs_revparse__a_not_precise_enough_objectid_returns_EAMBIGUOUS(void)
git_index *index;
git_object *obj;
cl_git_sandbox_cleanup();
repo = cl_git_sandbox_init("testrepo");
cl_git_mkfile("testrepo/one.txt", "aabqhq\n");
@@ -613,37 +611,33 @@ void test_refs_revparse__a_not_precise_enough_objectid_returns_EAMBIGUOUS(void)
void test_refs_revparse__issue_994(void)
{
git_repository *repo;
git_reference *head, *with_at;
git_object *target;
repo = cl_git_sandbox_init("testrepo.git");
cl_assert_equal_i(GIT_ENOTFOUND,
git_revparse_single(&target, g_repo, "origin/bim_with_3d@11296"));
cl_assert_equal_i(GIT_ENOTFOUND,
git_revparse_single(&target, repo, "origin/bim_with_3d@11296"));
cl_assert_equal_i(GIT_ENOTFOUND,
git_revparse_single(&target, repo, "refs/remotes/origin/bim_with_3d@11296"));
git_revparse_single(&target, g_repo, "refs/remotes/origin/bim_with_3d@11296"));
cl_git_pass(git_repository_head(&head, repo));
cl_git_pass(git_repository_head(&head, g_repo));
cl_git_pass(git_reference_create(
&with_at,
repo,
g_repo,
"refs/remotes/origin/bim_with_3d@11296",
git_reference_target(head),
0,
NULL));
cl_git_pass(git_revparse_single(&target, repo, "origin/bim_with_3d@11296"));
cl_git_pass(git_revparse_single(&target, g_repo, "origin/bim_with_3d@11296"));
git_object_free(target);
cl_git_pass(git_revparse_single(&target, repo, "refs/remotes/origin/bim_with_3d@11296"));
cl_git_pass(git_revparse_single(&target, g_repo, "refs/remotes/origin/bim_with_3d@11296"));
git_object_free(target);
git_reference_free(with_at);
git_reference_free(head);
cl_git_sandbox_cleanup();
}
/**
@@ -660,25 +654,21 @@ void test_refs_revparse__issue_994(void)
*/
void test_refs_revparse__try_to_retrieve_branch_before_described_tag(void)
{
git_repository *repo;
git_reference *branch;
git_object *target;
char sha[GIT_OID_SHA1_HEXSIZE + 1];
repo = cl_git_sandbox_init("testrepo.git");
test_object_inrepo("blah-7-gc47800c", "c47800c7266a2be04c571c04d5a6614691ea99bd", g_repo);
test_object_inrepo("blah-7-gc47800c", "c47800c7266a2be04c571c04d5a6614691ea99bd", repo);
cl_git_pass(git_revparse_single(&target, repo, "HEAD~3"));
cl_git_pass(git_branch_create(&branch, repo, "blah-7-gc47800c", (git_commit *)target, 0));
cl_git_pass(git_revparse_single(&target, g_repo, "HEAD~3"));
cl_git_pass(git_branch_create(&branch, g_repo, "blah-7-gc47800c", (git_commit *)target, 0));
git_oid_tostr(sha, GIT_OID_SHA1_HEXSIZE + 1, git_object_id(target));
test_object_inrepo("blah-7-gc47800c", sha, repo);
test_object_inrepo("blah-7-gc47800c", sha, g_repo);
git_reference_free(branch);
git_object_free(target);
cl_git_sandbox_cleanup();
}
/**
@@ -698,26 +688,22 @@ void test_refs_revparse__try_to_retrieve_branch_before_described_tag(void)
*/
void test_refs_revparse__try_to_retrieve_sha_before_branch(void)
{
git_repository *repo;
git_reference *branch;
git_object *target;
char sha[GIT_OID_SHA1_HEXSIZE + 1];
repo = cl_git_sandbox_init("testrepo.git");
test_object_inrepo("a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", g_repo);
test_object_inrepo("a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo);
cl_git_pass(git_revparse_single(&target, repo, "HEAD~3"));
cl_git_pass(git_branch_create(&branch, repo, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", (git_commit *)target, 0));
cl_git_pass(git_revparse_single(&target, g_repo, "HEAD~3"));
cl_git_pass(git_branch_create(&branch, g_repo, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", (git_commit *)target, 0));
git_oid_tostr(sha, GIT_OID_SHA1_HEXSIZE + 1, git_object_id(target));
test_object_inrepo("a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo);
test_object_inrepo("heads/a65fedf39aefe402d3bb6e24df4d4f5fe4547750", sha, repo);
test_object_inrepo("a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", g_repo);
test_object_inrepo("heads/a65fedf39aefe402d3bb6e24df4d4f5fe4547750", sha, g_repo);
git_reference_free(branch);
git_object_free(target);
cl_git_sandbox_cleanup();
}
/**
@@ -734,45 +720,37 @@ void test_refs_revparse__try_to_retrieve_sha_before_branch(void)
*/
void test_refs_revparse__try_to_retrieve_branch_before_abbrev_sha(void)
{
git_repository *repo;
git_reference *branch;
git_object *target;
char sha[GIT_OID_SHA1_HEXSIZE + 1];
repo = cl_git_sandbox_init("testrepo.git");
test_object_inrepo("c47800", "c47800c7266a2be04c571c04d5a6614691ea99bd", g_repo);
test_object_inrepo("c47800", "c47800c7266a2be04c571c04d5a6614691ea99bd", repo);
cl_git_pass(git_revparse_single(&target, repo, "HEAD~3"));
cl_git_pass(git_branch_create(&branch, repo, "c47800", (git_commit *)target, 0));
cl_git_pass(git_revparse_single(&target, g_repo, "HEAD~3"));
cl_git_pass(git_branch_create(&branch, g_repo, "c47800", (git_commit *)target, 0));
git_oid_tostr(sha, GIT_OID_SHA1_HEXSIZE + 1, git_object_id(target));
test_object_inrepo("c47800", sha, repo);
test_object_inrepo("c47800", sha, g_repo);
git_reference_free(branch);
git_object_free(target);
cl_git_sandbox_cleanup();
}
void test_refs_revparse__at_at_end_of_refname(void)
{
git_repository *repo;
git_reference *branch;
git_object *target;
repo = cl_git_sandbox_init("testrepo.git");
cl_git_pass(git_revparse_single(&target, repo, "HEAD"));
cl_git_pass(git_branch_create(&branch, repo, "master@", (git_commit *)target, 0));
cl_git_pass(git_revparse_single(&target, g_repo, "HEAD"));
cl_git_pass(git_branch_create(&branch, g_repo, "master@", (git_commit *)target, 0));
git_object_free(target);
test_id_inrepo("master@", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", NULL, GIT_REVSPEC_SINGLE, repo);
test_id_inrepo("master@", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", NULL, GIT_REVSPEC_SINGLE, g_repo);
cl_git_fail_with(GIT_ENOTFOUND, git_revparse_single(&target, repo, "foo@"));
cl_git_fail_with(GIT_ENOTFOUND, git_revparse_single(&target, g_repo, "foo@"));
git_reference_free(branch);
cl_git_sandbox_cleanup();
}
void test_refs_revparse__range(void)

View File

@@ -15,13 +15,12 @@ void test_refs_shorthand__0(void)
{
git_repository *repo;
cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
repo = cl_git_sandbox_init("testrepo.git");
assert_shorthand(repo, "refs/heads/master", "master");
assert_shorthand(repo, "refs/tags/test", "test");
assert_shorthand(repo, "refs/remotes/test/master", "test/master");
assert_shorthand(repo, "refs/notes/fanout", "notes/fanout");
git_repository_free(repo);
cl_git_sandbox_cleanup();
}

View File

@@ -8,6 +8,8 @@ void test_refs_transactions__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
cl_git_pass(git_transaction_new(&g_tx, g_repo));
if (!cl_repo_has_ref_format(g_repo, "files"))
cl_skip();
}
void test_refs_transactions__cleanup(void)

View File

@@ -90,7 +90,7 @@ static void *create_refs(void *arg)
cl_git_thread_pass(data, git_repository_refdb(&refdb, repo));
do {
error = git_refdb_compress(refdb);
} while (error == GIT_ELOCKED);
} while (error == GIT_ELOCKED || error == GIT_EMODIFIED);
cl_git_thread_pass(data, error);
git_refdb_free(refdb);
}
@@ -136,7 +136,7 @@ static void *delete_refs(void *arg)
cl_git_thread_pass(data, git_repository_refdb(&refdb, repo));
do {
error = git_refdb_compress(refdb);
} while (error == GIT_ELOCKED);
} while (error == GIT_ELOCKED || error == GIT_EMODIFIED);
cl_git_thread_pass(data, error);
git_refdb_free(refdb);
}
@@ -162,6 +162,20 @@ void test_threads_refdb__edit_while_iterate(void)
g_repo = cl_git_sandbox_init("testrepo2");
#ifdef GIT_WIN32
/*
* On Windows we still have issues with renaming the "table.list" file
* into place. This will require a bit of a rework of how we open files
* so that they are always opened with `FILE_SHARE_DELETE`.
* Furthermore, we'll have to start using POSIX-semantics when renaming
* files.
*
* For now, we just accept that this doesn't yet work.
*/
if (cl_repo_has_ref_format(g_repo, "reftable"))
cl_skip();
#endif
cl_git_pass(git_reference_name_to_id(&head, g_repo, "HEAD"));
/* make a bunch of references */