{"thread":{"id":"61911","subject":"[GSoC][PATCH 0/6] t: port reftable/stack_test.c to the unit testing framework","startedAt":"2024-08-06T14:20:43Z","lastAt":"2024-09-09T11:42:11Z","messageCount":72,"participants":["Chandra Pratap","Eric Sunshine","Junio C Hamano","Patrick Steinhardt"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"500202","messageId":"20240806142020.4615-1-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":null,"subject":"[GSoC][PATCH 0/6] t: port reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-06T14:13:36Z","receivedAt":"2024-08-06T14:20:43Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"The reftable library comes with self tests, which are exercised\nas part of the usual end-to-end tests and are designed to\nobserve the end-user visible effects of Git commands. What it\nexercises, however, is a better match for the unit-testing\nframework, merged at 8bf6fbd0 (Merge branch 'js/doc-unit-tests',\n2023-12-09), which is designed to observe how low level\nimplementation details, at the level of sequences of individual\nfunction calls, behave.\n\nHence, port reftable/stack_test.c to the unit testing framework and\nimprove upon the ported test. The first patch in the series moves\nthe test to the unit testing framework, and the rest of the patches\nimprove upon the ported test.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n\n---\nCI/PR: https://github.com/gitgitgadget/git/pull/1762\n\nChandra Pratap(6):\nt: move reftable/stack_test.c to the unit testing framework\nt: harmonize t-reftable-stack.c with coding guidelines\nt-reftable-stack: use Git's tempfile API instead of mkstemp()\nt-reftable-stack: use reftable_ref_record_equal() to compare ref records\nt-reftable-stack: add test for non-default compaction factor\nt-reftable-stack: add test for stack iterators\n\nMakefile                                                 |   2 +-\nreftable/reftable-tests.h                                |   1 -\nt/helper/test-reftable.c                                 |   1 -\nreftable/stack_test.c => t/unit-tests/t-reftable-stack.c | 600 +++++++++++++++++++--------------\n4 files changed, 355 insertions(+), 249 deletions(-)\n"},{"id":"500203","messageId":"20240806142020.4615-2-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240806142020.4615-1-chandrapratap3519@gmail.com","subject":"[PATCH 1/6] t: move reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-06T14:13:37Z","receivedAt":"2024-08-06T14:20:48Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"reftable/stack_test.c exercises the functions defined in\nreftable/stack.{c, h}. Migrate reftable/stack_test.c to the\nunit testing framework. Migration involves refactoring the tests\nto use the unit testing framework instead of reftable's test\nframework and renaming the tests to be in-line with unit-tests'\nstandards.\n\nSince some of the tests use set_test_hash() defined by\nreftable/test_framework.{c, h} but these files are not\n'#included' in the test file, copy this function in the\nported test file.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n Makefile                                      |   2 +-\n reftable/reftable-tests.h                     |   1 -\n t/helper/test-reftable.c                      |   1 -\n .../unit-tests/t-reftable-stack.c             | 350 +++++++++---------\n 4 files changed, 175 insertions(+), 179 deletions(-)\n rename reftable/stack_test.c => t/unit-tests/t-reftable-stack.c (77%)\n\ndiff --git a/Makefile b/Makefile\nindex 3863e60b66..464a17e11a 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1342,6 +1342,7 @@ UNIT_TEST_PROGRAMS += t-prio-queue\n UNIT_TEST_PROGRAMS += t-reftable-basics\n UNIT_TEST_PROGRAMS += t-reftable-merged\n UNIT_TEST_PROGRAMS += t-reftable-record\n+UNIT_TEST_PROGRAMS += t-reftable-stack\n UNIT_TEST_PROGRAMS += t-strbuf\n UNIT_TEST_PROGRAMS += t-strcmp-offset\n UNIT_TEST_PROGRAMS += t-strvec\n@@ -2683,7 +2684,6 @@ REFTABLE_TEST_OBJS += reftable/block_test.o\n REFTABLE_TEST_OBJS += reftable/dump.o\n REFTABLE_TEST_OBJS += reftable/pq_test.o\n REFTABLE_TEST_OBJS += reftable/readwrite_test.o\n-REFTABLE_TEST_OBJS += reftable/stack_test.o\n REFTABLE_TEST_OBJS += reftable/test_framework.o\n REFTABLE_TEST_OBJS += reftable/tree_test.o\n \ndiff --git a/reftable/reftable-tests.h b/reftable/reftable-tests.h\nindex d5e03dcc1b..28fe1be72e 100644\n--- a/reftable/reftable-tests.h\n+++ b/reftable/reftable-tests.h\n@@ -14,7 +14,6 @@ int block_test_main(int argc, const char **argv);\n int pq_test_main(int argc, const char **argv);\n int record_test_main(int argc, const char **argv);\n int readwrite_test_main(int argc, const char **argv);\n-int stack_test_main(int argc, const char **argv);\n int tree_test_main(int argc, const char **argv);\n int reftable_dump_main(int argc, char *const *argv);\n \ndiff --git a/t/helper/test-reftable.c b/t/helper/test-reftable.c\nindex 9d378427da..f35db442ae 100644\n--- a/t/helper/test-reftable.c\n+++ b/t/helper/test-reftable.c\n@@ -9,7 +9,6 @@ int cmd__reftable(int argc, const char **argv)\n \ttree_test_main(argc, argv);\n \tpq_test_main(argc, argv);\n \treadwrite_test_main(argc, argv);\n-\tstack_test_main(argc, argv);\n \treturn 0;\n }\n \ndiff --git a/reftable/stack_test.c b/t/unit-tests/t-reftable-stack.c\nsimilarity index 77%\nrename from reftable/stack_test.c\nrename to t/unit-tests/t-reftable-stack.c\nindex e3c11e6a6e..c578659017 100644\n--- a/reftable/stack_test.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -6,19 +6,11 @@ license that can be found in the LICENSE file or at\n https://developers.google.com/open-source/licenses/bsd\n */\n \n-#include \"stack.h\"\n-\n-#include \"system.h\"\n-\n-#include \"reftable-reader.h\"\n-#include \"merged.h\"\n-#include \"basics.h\"\n-#include \"record.h\"\n-#include \"test_framework.h\"\n-#include \"reftable-tests.h\"\n-#include \"reader.h\"\n-\n-#include <sys/types.h>\n+#include \"test-lib.h\"\n+#include \"reftable/merged.h\"\n+#include \"reftable/reader.h\"\n+#include \"reftable/reftable-error.h\"\n+#include \"reftable/stack.h\"\n #include <dirent.h>\n \n static void clear_dir(const char *dirname)\n@@ -29,6 +21,11 @@ static void clear_dir(const char *dirname)\n \tstrbuf_release(&path);\n }\n \n+static void set_test_hash(uint8_t *p, int i)\n+{\n+\tmemset(p, (uint8_t)i, hash_size(GIT_SHA1_FORMAT_ID));\n+}\n+\n static int count_dir_entries(const char *dirname)\n {\n \tDIR *dir = opendir(dirname);\n@@ -72,11 +69,11 @@ static char *get_tmp_template(int linenumber)\n static char *get_tmp_dir(int linenumber)\n {\n \tchar *dir = get_tmp_template(linenumber);\n-\tEXPECT(mkdtemp(dir));\n+\tcheck(mkdtemp(dir) != NULL);\n \treturn dir;\n }\n \n-static void test_read_file(void)\n+static void t_read_file(void)\n {\n \tchar *fn = get_tmp_template(__LINE__);\n \tint fd = mkstemp(fn);\n@@ -86,17 +83,17 @@ static void test_read_file(void)\n \tconst char *want[] = { \"line1\", \"line2\", \"line3\" };\n \tint i = 0;\n \n-\tEXPECT(fd > 0);\n+\tcheck_int(fd, >, 0);\n \tn = write_in_full(fd, out, strlen(out));\n-\tEXPECT(n == strlen(out));\n+\tcheck_int(n, ==, strlen(out));\n \terr = close(fd);\n-\tEXPECT(err >= 0);\n+\tcheck_int(err, >=, 0);\n \n \terr = read_lines(fn, &names);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; names[i]; i++) {\n-\t\tEXPECT(0 == strcmp(want[i], names[i]));\n+\t\tcheck_str(want[i], names[i]);\n \t}\n \tfree_names(names);\n \t(void) remove(fn);\n@@ -122,7 +119,7 @@ static int write_test_log(struct reftable_writer *wr, void *arg)\n \treturn reftable_writer_add_log(wr, wla->log);\n }\n \n-static void test_reftable_stack_add_one(void)\n+static void t_reftable_stack_add_one(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct strbuf scratch = STRBUF_INIT;\n@@ -141,29 +138,29 @@ static void test_reftable_stack_add_one(void)\n \tstruct reftable_ref_record dest = { NULL };\n \tstruct stat stat_result = { 0 };\n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(\"master\", dest.value.symref));\n-\tEXPECT(st->readers_len > 0);\n+\tcheck(!err);\n+\tcheck_str(\"master\", dest.value.symref);\n+\tcheck_int(st->readers_len, >, 0);\n \n \tprintf(\"testing print functionality:\\n\");\n \terr = reftable_stack_print_directory(dir, GIT_SHA1_FORMAT_ID);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_print_directory(dir, GIT_SHA256_FORMAT_ID);\n-\tEXPECT(err == REFTABLE_FORMAT_ERROR);\n+\tcheck_int(err, ==, REFTABLE_FORMAT_ERROR);\n \n #ifndef GIT_WINDOWS_NATIVE\n \tstrbuf_addstr(&scratch, dir);\n \tstrbuf_addstr(&scratch, \"/tables.list\");\n \terr = stat(scratch.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n \n \tstrbuf_reset(&scratch);\n \tstrbuf_addstr(&scratch, dir);\n@@ -171,8 +168,8 @@ static void test_reftable_stack_add_one(void)\n \t/* do not try at home; not an external API for reftable. */\n \tstrbuf_addstr(&scratch, st->readers[0]->name);\n \terr = stat(scratch.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n #else\n \t(void) stat_result;\n #endif\n@@ -184,7 +181,7 @@ static void test_reftable_stack_add_one(void)\n \tumask(mask);\n }\n \n-static void test_reftable_stack_uptodate(void)\n+static void t_reftable_stack_uptodate(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL;\n@@ -210,28 +207,28 @@ static void test_reftable_stack_uptodate(void)\n \t   by creating two stacks for the same directory.\n \t */\n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st1, &write_test_ref, &ref1);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n-\tEXPECT(err == REFTABLE_OUTDATED_ERROR);\n+\tcheck_int(err, ==, REFTABLE_OUTDATED_ERROR);\n \n \terr = reftable_stack_reload(st2);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_transaction_api(void)\n+static void t_reftable_stack_transaction_api(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -248,32 +245,32 @@ static void test_reftable_stack_transaction_api(void)\n \tstruct reftable_ref_record dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_addition_destroy(add);\n \n \terr = reftable_stack_new_addition(&add, st);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_addition_add(add, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_addition_commit(add);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_addition_destroy(add);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(REFTABLE_REF_SYMREF == dest.value_type);\n-\tEXPECT(0 == strcmp(\"master\", dest.value.symref));\n+\tcheck(!err);\n+\tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n+\tcheck_str(\"master\", dest.value.symref);\n \n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n+static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = {0};\n@@ -282,7 +279,7 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \tint i, n = 20, err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n@@ -303,13 +300,13 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\tst->opts.disable_auto_compact = i != n;\n \n \t\terr = reftable_stack_new_addition(&add, st);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_addition_add(add, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_addition_commit(add);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\treftable_addition_destroy(add);\n \n@@ -319,16 +316,16 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\t * all tables in the stack.\n \t\t */\n \t\tif (i != n)\n-\t\t\tEXPECT(st->merged->stack_len == i + 1);\n+\t\t\tcheck_int(st->merged->stack_len, ==, i + 1);\n \t\telse\n-\t\t\tEXPECT(st->merged->stack_len == 1);\n+\t\t\tcheck_int(st->merged->stack_len, ==, 1);\n \t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n+static void t_reftable_stack_auto_compaction_fails_gracefully(void)\n {\n \tstruct reftable_ref_record ref = {\n \t\t.refname = (char *) \"refs/heads/master\",\n@@ -343,13 +340,13 @@ static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->merged->stack_len == 1);\n-\tEXPECT(st->stats.attempts == 0);\n-\tEXPECT(st->stats.failures == 0);\n+\tcheck(!err);\n+\tcheck_int(st->merged->stack_len, ==, 1);\n+\tcheck_int(st->stats.attempts, ==, 0);\n+\tcheck_int(st->stats.failures, ==, 0);\n \n \t/*\n \t * Lock the newly written table such that it cannot be compacted.\n@@ -361,10 +358,10 @@ static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n \n \tref.update_index = 2;\n \terr = reftable_stack_add(st, write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->merged->stack_len == 2);\n-\tEXPECT(st->stats.attempts == 1);\n-\tEXPECT(st->stats.failures == 1);\n+\tcheck(!err);\n+\tcheck_int(st->merged->stack_len, ==, 2);\n+\tcheck_int(st->stats.attempts, ==, 1);\n+\tcheck_int(st->stats.failures, ==, 1);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&table_path);\n@@ -376,7 +373,7 @@ static int write_error(struct reftable_writer *wr, void *arg)\n \treturn *((int *)arg);\n }\n \n-static void test_reftable_stack_update_index_check(void)\n+static void t_reftable_stack_update_index_check(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -396,18 +393,18 @@ static void test_reftable_stack_update_index_check(void)\n \t};\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref1);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref2);\n-\tEXPECT(err == REFTABLE_API_ERROR);\n+\tcheck_int(err, ==, REFTABLE_API_ERROR);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_lock_failure(void)\n+static void t_reftable_stack_lock_failure(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -415,17 +412,17 @@ static void test_reftable_stack_lock_failure(void)\n \tint err, i;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \tfor (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) {\n \t\terr = reftable_stack_add(st, &write_error, &i);\n-\t\tEXPECT(err == i);\n+\t\tcheck_int(err, ==, i);\n \t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_add(void)\n+static void t_reftable_stack_add(void)\n {\n \tint i = 0;\n \tint err = 0;\n@@ -443,7 +440,7 @@ static void test_reftable_stack_add(void)\n \tint N = ARRAY_SIZE(refs);\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar buf[256];\n@@ -462,7 +459,7 @@ static void test_reftable_stack_add(void)\n \n \tfor (i = 0; i < N; i++) {\n \t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tfor (i = 0; i < N; i++) {\n@@ -471,18 +468,18 @@ static void test_reftable_stack_add(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tstruct reftable_ref_record dest = { NULL };\n \n \t\tint err = reftable_stack_read_ref(st, refs[i].refname, &dest);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(reftable_ref_record_equal(&dest, refs + i,\n+\t\tcheck(!err);\n+\t\tcheck(reftable_ref_record_equal(&dest, refs + i,\n \t\t\t\t\t\t GIT_SHA1_RAWSZ));\n \t\treftable_ref_record_release(&dest);\n \t}\n@@ -490,8 +487,8 @@ static void test_reftable_stack_add(void)\n \tfor (i = 0; i < N; i++) {\n \t\tstruct reftable_log_record dest = { NULL };\n \t\tint err = reftable_stack_read_log(st, refs[i].refname, &dest);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(reftable_log_record_equal(&dest, logs + i,\n+\t\tcheck(!err);\n+\t\tcheck(reftable_log_record_equal(&dest, logs + i,\n \t\t\t\t\t\t GIT_SHA1_RAWSZ));\n \t\treftable_log_record_release(&dest);\n \t}\n@@ -500,8 +497,8 @@ static void test_reftable_stack_add(void)\n \tstrbuf_addstr(&path, dir);\n \tstrbuf_addstr(&path, \"/tables.list\");\n \terr = stat(path.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n \n \tstrbuf_reset(&path);\n \tstrbuf_addstr(&path, dir);\n@@ -509,8 +506,8 @@ static void test_reftable_stack_add(void)\n \t/* do not try at home; not an external API for reftable. */\n \tstrbuf_addstr(&path, st->readers[0]->name);\n \terr = stat(path.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n #else\n \t(void) stat_result;\n #endif\n@@ -525,7 +522,7 @@ static void test_reftable_stack_add(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_log_normalize(void)\n+static void t_reftable_stack_log_normalize(void)\n {\n \tint err = 0;\n \tstruct reftable_write_options opts = {\n@@ -553,27 +550,27 @@ static void test_reftable_stack_log_normalize(void)\n \t};\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tinput.value.update.message = (char *) \"one\\ntwo\";\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT(err == REFTABLE_API_ERROR);\n+\tcheck_int(err, ==, REFTABLE_API_ERROR);\n \n \tinput.value.update.message = (char *) \"one\";\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, input.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(dest.value.update.message, \"one\\n\"));\n+\tcheck(!err);\n+\tcheck_str(dest.value.update.message, \"one\\n\");\n \n \tinput.value.update.message = (char *) \"two\\n\";\n \targ.update_index = 2;\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \terr = reftable_stack_read_log(st, input.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(dest.value.update.message, \"two\\n\"));\n+\tcheck(!err);\n+\tcheck_str(dest.value.update.message, \"two\\n\");\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n@@ -581,7 +578,7 @@ static void test_reftable_stack_log_normalize(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_tombstone(void)\n+static void t_reftable_stack_tombstone(void)\n {\n \tint i = 0;\n \tchar *dir = get_tmp_dir(__LINE__);\n@@ -595,7 +592,7 @@ static void test_reftable_stack_tombstone(void)\n \tstruct reftable_log_record log_dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* even entries add the refs, odd entries delete them. */\n \tfor (i = 0; i < N; i++) {\n@@ -619,7 +616,7 @@ static void test_reftable_stack_tombstone(void)\n \t}\n \tfor (i = 0; i < N; i++) {\n \t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tfor (i = 0; i < N; i++) {\n@@ -628,25 +625,25 @@ static void test_reftable_stack_tombstone(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_read_ref(st, \"branch\", &dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_ref_record_release(&dest);\n \n \terr = reftable_stack_read_log(st, \"branch\", &log_dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_log_record_release(&log_dest);\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, \"branch\", &dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, \"branch\", &log_dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_ref_record_release(&dest);\n \treftable_log_record_release(&log_dest);\n \n@@ -659,7 +656,7 @@ static void test_reftable_stack_tombstone(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_hash_id(void)\n+static void t_reftable_stack_hash_id(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -679,47 +676,47 @@ static void test_reftable_stack_hash_id(void)\n \tstruct reftable_ref_record dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* can't read it with the wrong hash ID. */\n \terr = reftable_new_stack(&st32, dir, &opts32);\n-\tEXPECT(err == REFTABLE_FORMAT_ERROR);\n+\tcheck_int(err, ==, REFTABLE_FORMAT_ERROR);\n \n \t/* check that we can read it back with default opts too. */\n \terr = reftable_new_stack(&st_default, dir, &opts_default);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st_default, \"master\", &dest);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n-\tEXPECT(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n \treftable_stack_destroy(st_default);\n \tclear_dir(dir);\n }\n \n-static void test_suggest_compaction_segment(void)\n+static void t_suggest_compaction_segment(void)\n {\n \tuint64_t sizes[] = { 512, 64, 17, 16, 9, 9, 9, 16, 2, 16 };\n \tstruct segment min =\n \t\tsuggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);\n-\tEXPECT(min.start == 1);\n-\tEXPECT(min.end == 10);\n+\tcheck_int(min.start, ==, 1);\n+\tcheck_int(min.end, ==, 10);\n }\n \n-static void test_suggest_compaction_segment_nothing(void)\n+static void t_suggest_compaction_segment_nothing(void)\n {\n \tuint64_t sizes[] = { 64, 32, 16, 8, 4, 2 };\n \tstruct segment result =\n \t\tsuggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);\n-\tEXPECT(result.start == result.end);\n+\tcheck_int(result.start, ==, result.end);\n }\n \n-static void test_reflog_expire(void)\n+static void t_reflog_expire(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -734,7 +731,7 @@ static void test_reflog_expire(void)\n \tstruct reftable_log_record log = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 1; i <= N; i++) {\n \t\tchar buf[256];\n@@ -754,30 +751,30 @@ static void test_reflog_expire(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st, &expiry);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, logs[9].refname, &log);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, logs[11].refname, &log);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \texpiry.min_update_index = 15;\n \terr = reftable_stack_compact_all(st, &expiry);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, logs[14].refname, &log);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, logs[16].refname, &log);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n@@ -794,7 +791,7 @@ static int write_nothing(struct reftable_writer *wr, void *arg)\n \treturn 0;\n }\n \n-static void test_empty_add(void)\n+static void t_empty_add(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -803,13 +800,13 @@ static void test_empty_add(void)\n \tstruct reftable_stack *st2 = NULL;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_nothing, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \tclear_dir(dir);\n \treftable_stack_destroy(st);\n \treftable_stack_destroy(st2);\n@@ -825,7 +822,7 @@ static int fastlog2(uint64_t sz)\n \treturn l - 1;\n }\n \n-static void test_reftable_stack_auto_compaction(void)\n+static void t_reftable_stack_auto_compaction(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -836,7 +833,7 @@ static void test_reftable_stack_auto_compaction(void)\n \tint N = 100;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar name[100];\n@@ -849,21 +846,21 @@ static void test_reftable_stack_auto_compaction(void)\n \t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_stack_auto_compact(st);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(i < 3 || st->merged->stack_len < 2 * fastlog2(i));\n+\t\tcheck(!err);\n+\t\tcheck(i < 3 || st->merged->stack_len < 2 * fastlog2(i));\n \t}\n \n-\tEXPECT(reftable_stack_compaction_stats(st)->entries_written <\n-\t       (uint64_t)(N * fastlog2(N)));\n+\tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n+\t\t (uint64_t)(N * fastlog2(N)));\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_add_performs_auto_compaction(void)\n+static void t_reftable_stack_add_performs_auto_compaction(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -872,7 +869,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \tint err, i, n = 20;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n@@ -893,7 +890,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \t\tref.refname = refname.buf;\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\t/*\n \t\t * The stack length should grow continuously for all runs where\n@@ -901,9 +898,9 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \t\t * all tables in the stack.\n \t\t */\n \t\tif (i != n)\n-\t\t\tEXPECT(st->merged->stack_len == i + 1);\n+\t\t\tcheck_int(st->merged->stack_len, ==, i + 1);\n \t\telse\n-\t\t\tEXPECT(st->merged->stack_len == 1);\n+\t\t\tcheck_int(st->merged->stack_len, ==, 1);\n \t}\n \n \treftable_stack_destroy(st);\n@@ -911,7 +908,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_compaction_concurrent(void)\n+static void t_reftable_stack_compaction_concurrent(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL;\n@@ -920,7 +917,7 @@ static void test_reftable_stack_compaction_concurrent(void)\n \tint N = 3;\n \n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar name[100];\n@@ -933,19 +930,19 @@ static void test_reftable_stack_compaction_concurrent(void)\n \t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n \n \t\terr = reftable_stack_add(st1, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st1, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n \n-\tEXPECT(count_dir_entries(dir) == 2);\n+\tcheck_int(count_dir_entries(dir), ==, 2);\n \tclear_dir(dir);\n }\n \n@@ -960,7 +957,7 @@ static void unclean_stack_close(struct reftable_stack *st)\n \tFREE_AND_NULL(st->readers);\n }\n \n-static void test_reftable_stack_compaction_concurrent_clean(void)\n+static void t_reftable_stack_compaction_concurrent_clean(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL, *st3 = NULL;\n@@ -969,7 +966,7 @@ static void test_reftable_stack_compaction_concurrent_clean(void)\n \tint N = 3;\n \n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar name[100];\n@@ -982,24 +979,24 @@ static void test_reftable_stack_compaction_concurrent_clean(void)\n \t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n \n \t\terr = reftable_stack_add(st1, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st1, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tunclean_stack_close(st1);\n \tunclean_stack_close(st2);\n \n \terr = reftable_new_stack(&st3, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_clean(st3);\n-\tEXPECT_ERR(err);\n-\tEXPECT(count_dir_entries(dir) == 2);\n+\tcheck(!err);\n+\tcheck_int(count_dir_entries(dir), ==, 2);\n \n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n@@ -1008,27 +1005,28 @@ static void test_reftable_stack_compaction_concurrent_clean(void)\n \tclear_dir(dir);\n }\n \n-int stack_test_main(int argc, const char *argv[])\n+int cmd_main(int argc, const char *argv[])\n {\n-\tRUN_TEST(test_empty_add);\n-\tRUN_TEST(test_read_file);\n-\tRUN_TEST(test_reflog_expire);\n-\tRUN_TEST(test_reftable_stack_add);\n-\tRUN_TEST(test_reftable_stack_add_one);\n-\tRUN_TEST(test_reftable_stack_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_add_performs_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_compaction_concurrent);\n-\tRUN_TEST(test_reftable_stack_compaction_concurrent_clean);\n-\tRUN_TEST(test_reftable_stack_hash_id);\n-\tRUN_TEST(test_reftable_stack_lock_failure);\n-\tRUN_TEST(test_reftable_stack_log_normalize);\n-\tRUN_TEST(test_reftable_stack_tombstone);\n-\tRUN_TEST(test_reftable_stack_transaction_api);\n-\tRUN_TEST(test_reftable_stack_transaction_api_performs_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_auto_compaction_fails_gracefully);\n-\tRUN_TEST(test_reftable_stack_update_index_check);\n-\tRUN_TEST(test_reftable_stack_uptodate);\n-\tRUN_TEST(test_suggest_compaction_segment);\n-\tRUN_TEST(test_suggest_compaction_segment_nothing);\n-\treturn 0;\n+\tTEST(t_empty_add(), \"empty addition to stack\");\n+\tTEST(t_read_file(), \"read_lines works\");\n+\tTEST(t_reflog_expire(), \"expire reflog entries\");\n+\tTEST(t_reftable_stack_add(), \"add multiple refs and logs to stack\");\n+\tTEST(t_reftable_stack_add_one(), \"add a single ref record to stack\");\n+\tTEST(t_reftable_stack_add_performs_auto_compaction(), \"addition to stack triggers auto-compaction\");\n+\tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_fails_gracefully(), \"failure on auto-compaction\");\n+\tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n+\tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n+\tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n+\tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n+\tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n+\tTEST(t_reftable_stack_tombstone(), \"'tombstone' refs in stack\");\n+\tTEST(t_reftable_stack_transaction_api(), \"update transaction to stack\");\n+\tTEST(t_reftable_stack_transaction_api_performs_auto_compaction(), \"update transaction triggers auto-compaction\");\n+\tTEST(t_reftable_stack_update_index_check(), \"update transactions with equal update indices\");\n+\tTEST(t_reftable_stack_uptodate(), \"stack must be reloaded before ref update\");\n+\tTEST(t_suggest_compaction_segment(), \"suggest_compaction_segment with basic input\");\n+\tTEST(t_suggest_compaction_segment_nothing(), \"suggest_compaction_segment with pre-compacted input\");\n+\n+\treturn test_done();\n }\n-- \n2.45.GIT\n\n"},{"id":"500204","messageId":"20240806142020.4615-3-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240806142020.4615-1-chandrapratap3519@gmail.com","subject":"[PATCH 2/6] t: harmonize t-reftable-stack.c with coding guidelines","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-06T14:13:38Z","receivedAt":"2024-08-06T14:20:51Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"Harmonize the newly ported test unit-tests/t-reftable-stack.c\nwith the following guidelines:\n- Single line 'for' statements must omit curly braces.\n- Structs must be 0-initialized with '= { 0 }' instead of '= { NULL }'.\n- Array sizes and indices should preferably be of type 'size_t'and\n  not 'int'.\n- Function pointers should be passed as 'func' and not '&func'.\n\nWhile at it, remove initialization for those variables that are\nre-used multiple times, like loop variables.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 128 +++++++++++++++-----------------\n 1 file changed, 61 insertions(+), 67 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex c578659017..e033feb8ee 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -81,7 +81,6 @@ static void t_read_file(void)\n \tint n, err;\n \tchar **names = NULL;\n \tconst char *want[] = { \"line1\", \"line2\", \"line3\" };\n-\tint i = 0;\n \n \tcheck_int(fd, >, 0);\n \tn = write_in_full(fd, out, strlen(out));\n@@ -92,9 +91,8 @@ static void t_read_file(void)\n \terr = read_lines(fn, &names);\n \tcheck(!err);\n \n-\tfor (i = 0; names[i]; i++) {\n+\tfor (size_t i = 0; names[i]; i++)\n \t\tcheck_str(want[i], names[i]);\n-\t}\n \tfree_names(names);\n \t(void) remove(fn);\n }\n@@ -135,12 +133,12 @@ static void t_reftable_stack_add_one(void)\n \t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t.value.symref = (char *) \"master\",\n \t};\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \tstruct stat stat_result = { 0 };\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\terr = reftable_stack_add(st, write_test_ref, &ref);\n \tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n@@ -212,16 +210,16 @@ static void t_reftable_stack_uptodate(void)\n \terr = reftable_new_stack(&st2, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st1, &write_test_ref, &ref1);\n+\terr = reftable_stack_add(st1, write_test_ref, &ref1);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st2, write_test_ref, &ref2);\n \tcheck_int(err, ==, REFTABLE_OUTDATED_ERROR);\n \n \terr = reftable_stack_reload(st2);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st2, write_test_ref, &ref2);\n \tcheck(!err);\n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n@@ -242,7 +240,7 @@ static void t_reftable_stack_transaction_api(void)\n \t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t.value.symref = (char *) \"master\",\n \t};\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -252,7 +250,7 @@ static void t_reftable_stack_transaction_api(void)\n \terr = reftable_stack_new_addition(&add, st);\n \tcheck(!err);\n \n-\terr = reftable_addition_add(add, &write_test_ref, &ref);\n+\terr = reftable_addition_add(add, write_test_ref, &ref);\n \tcheck(!err);\n \n \terr = reftable_addition_commit(add);\n@@ -276,7 +274,8 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \tstruct reftable_write_options opts = {0};\n \tstruct reftable_addition *add = NULL;\n \tstruct reftable_stack *st = NULL;\n-\tint i, n = 20, err;\n+\tsize_t i, n = 20;\n+\tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -289,7 +288,7 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\t};\n \t\tchar name[100];\n \n-\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = name;\n \n \t\t/*\n@@ -302,7 +301,7 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\terr = reftable_stack_new_addition(&add, st);\n \t\tcheck(!err);\n \n-\t\terr = reftable_addition_add(add, &write_test_ref, &ref);\n+\t\terr = reftable_addition_add(add, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\terr = reftable_addition_commit(add);\n@@ -395,10 +394,10 @@ static void t_reftable_stack_update_index_check(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref1);\n+\terr = reftable_stack_add(st, write_test_ref, &ref1);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st, write_test_ref, &ref2);\n \tcheck_int(err, ==, REFTABLE_API_ERROR);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n@@ -414,7 +413,7 @@ static void t_reftable_stack_lock_failure(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \tfor (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) {\n-\t\terr = reftable_stack_add(st, &write_error, &i);\n+\t\terr = reftable_stack_add(st, write_error, &i);\n \t\tcheck_int(err, ==, i);\n \t}\n \n@@ -424,8 +423,7 @@ static void t_reftable_stack_lock_failure(void)\n \n static void t_reftable_stack_add(void)\n {\n-\tint i = 0;\n-\tint err = 0;\n+\tint err;\n \tstruct reftable_write_options opts = {\n \t\t.exact_log_message = 1,\n \t\t.default_permissions = 0660,\n@@ -433,18 +431,18 @@ static void t_reftable_stack_add(void)\n \t};\n \tstruct reftable_stack *st = NULL;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tstruct reftable_ref_record refs[2] = { { NULL } };\n-\tstruct reftable_log_record logs[2] = { { NULL } };\n+\tstruct reftable_ref_record refs[2] = { { 0 } };\n+\tstruct reftable_log_record logs[2] = { { 0 } };\n \tstruct strbuf path = STRBUF_INIT;\n \tstruct stat stat_result;\n-\tint N = ARRAY_SIZE(refs);\n+\tsize_t N = ARRAY_SIZE(refs), i;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar buf[256];\n-\t\tsnprintf(buf, sizeof(buf), \"branch%02d\", i);\n+\t\tsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n \t\trefs[i].refname = xstrdup(buf);\n \t\trefs[i].update_index = i + 1;\n \t\trefs[i].value_type = REFTABLE_REF_VAL1;\n@@ -458,7 +456,7 @@ static void t_reftable_stack_add(void)\n \t}\n \n \tfor (i = 0; i < N; i++) {\n-\t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n+\t\tint err = reftable_stack_add(st, write_test_ref, &refs[i]);\n \t\tcheck(!err);\n \t}\n \n@@ -467,7 +465,7 @@ static void t_reftable_stack_add(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -475,7 +473,7 @@ static void t_reftable_stack_add(void)\n \tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n-\t\tstruct reftable_ref_record dest = { NULL };\n+\t\tstruct reftable_ref_record dest = { 0 };\n \n \t\tint err = reftable_stack_read_ref(st, refs[i].refname, &dest);\n \t\tcheck(!err);\n@@ -485,7 +483,7 @@ static void t_reftable_stack_add(void)\n \t}\n \n \tfor (i = 0; i < N; i++) {\n-\t\tstruct reftable_log_record dest = { NULL };\n+\t\tstruct reftable_log_record dest = { 0 };\n \t\tint err = reftable_stack_read_log(st, refs[i].refname, &dest);\n \t\tcheck(!err);\n \t\tcheck(reftable_log_record_equal(&dest, logs + i,\n@@ -524,7 +522,7 @@ static void t_reftable_stack_add(void)\n \n static void t_reftable_stack_log_normalize(void)\n {\n-\tint err = 0;\n+\tint err;\n \tstruct reftable_write_options opts = {\n \t\t0,\n \t};\n@@ -553,11 +551,11 @@ static void t_reftable_stack_log_normalize(void)\n \tcheck(!err);\n \n \tinput.value.update.message = (char *) \"one\\ntwo\";\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck_int(err, ==, REFTABLE_API_ERROR);\n \n \tinput.value.update.message = (char *) \"one\";\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck(!err);\n \n \terr = reftable_stack_read_log(st, input.refname, &dest);\n@@ -566,7 +564,7 @@ static void t_reftable_stack_log_normalize(void)\n \n \tinput.value.update.message = (char *) \"two\\n\";\n \targ.update_index = 2;\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck(!err);\n \terr = reftable_stack_read_log(st, input.refname, &dest);\n \tcheck(!err);\n@@ -580,16 +578,15 @@ static void t_reftable_stack_log_normalize(void)\n \n static void t_reftable_stack_tombstone(void)\n {\n-\tint i = 0;\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n \tint err;\n-\tstruct reftable_ref_record refs[2] = { { NULL } };\n-\tstruct reftable_log_record logs[2] = { { NULL } };\n-\tint N = ARRAY_SIZE(refs);\n-\tstruct reftable_ref_record dest = { NULL };\n-\tstruct reftable_log_record log_dest = { NULL };\n+\tstruct reftable_ref_record refs[2] = { { 0 } };\n+\tstruct reftable_log_record logs[2] = { { 0 } };\n+\tsize_t N = ARRAY_SIZE(refs), i;\n+\tstruct reftable_ref_record dest = { 0 };\n+\tstruct reftable_log_record log_dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -615,7 +612,7 @@ static void t_reftable_stack_tombstone(void)\n \t\t}\n \t}\n \tfor (i = 0; i < N; i++) {\n-\t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n+\t\tint err = reftable_stack_add(st, write_test_ref, &refs[i]);\n \t\tcheck(!err);\n \t}\n \n@@ -624,7 +621,7 @@ static void t_reftable_stack_tombstone(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -673,12 +670,12 @@ static void t_reftable_stack_hash_id(void)\n \tstruct reftable_stack *st32 = NULL;\n \tstruct reftable_write_options opts_default = { 0 };\n \tstruct reftable_stack *st_default = NULL;\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\terr = reftable_stack_add(st, write_test_ref, &ref);\n \tcheck(!err);\n \n \t/* can't read it with the wrong hash ID. */\n@@ -721,21 +718,20 @@ static void t_reflog_expire(void)\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n-\tstruct reftable_log_record logs[20] = { { NULL } };\n-\tint N = ARRAY_SIZE(logs) - 1;\n-\tint i = 0;\n+\tstruct reftable_log_record logs[20] = { { 0 } };\n+\tsize_t N = ARRAY_SIZE(logs) - 1, i;\n \tint err;\n \tstruct reftable_log_expiry_config expiry = {\n \t\t.time = 10,\n \t};\n-\tstruct reftable_log_record log = { NULL };\n+\tstruct reftable_log_record log = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n \tfor (i = 1; i <= N; i++) {\n \t\tchar buf[256];\n-\t\tsnprintf(buf, sizeof(buf), \"branch%02d\", i);\n+\t\tsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n \n \t\tlogs[i].refname = xstrdup(buf);\n \t\tlogs[i].update_index = i;\n@@ -750,7 +746,7 @@ static void t_reflog_expire(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -778,9 +774,8 @@ static void t_reflog_expire(void)\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n-\tfor (i = 0; i <= N; i++) {\n+\tfor (i = 0; i <= N; i++)\n \t\treftable_log_record_release(&logs[i]);\n-\t}\n \tclear_dir(dir);\n \treftable_log_record_release(&log);\n }\n@@ -802,7 +797,7 @@ static void t_empty_add(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_nothing, NULL);\n+\terr = reftable_stack_add(st, write_nothing, NULL);\n \tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n@@ -829,8 +824,8 @@ static void t_reftable_stack_auto_compaction(void)\n \t};\n \tstruct reftable_stack *st = NULL;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tint err, i;\n-\tint N = 100;\n+\tint err;\n+\tsize_t N = 100, i;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -843,9 +838,9 @@ static void t_reftable_stack_auto_compaction(void)\n \t\t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t\t.value.symref = (char *) \"master\",\n \t\t};\n-\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n \n-\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\terr = reftable_stack_add(st, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\terr = reftable_stack_auto_compact(st);\n@@ -866,7 +861,8 @@ static void t_reftable_stack_add_performs_auto_compaction(void)\n \tstruct reftable_stack *st = NULL;\n \tstruct strbuf refname = STRBUF_INIT;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tint err, i, n = 20;\n+\tint err;\n+\tsize_t i, n = 20;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -886,10 +882,10 @@ static void t_reftable_stack_add_performs_auto_compaction(void)\n \t\tst->opts.disable_auto_compact = i != n;\n \n \t\tstrbuf_reset(&refname);\n-\t\tstrbuf_addf(&refname, \"branch-%04d\", i);\n+\t\tstrbuf_addf(&refname, \"branch-%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = refname.buf;\n \n-\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\terr = reftable_stack_add(st, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\t/*\n@@ -913,8 +909,8 @@ static void t_reftable_stack_compaction_concurrent(void)\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tint err, i;\n-\tint N = 3;\n+\tint err;\n+\tsize_t N = 3, i;\n \n \terr = reftable_new_stack(&st1, dir, &opts);\n \tcheck(!err);\n@@ -927,9 +923,9 @@ static void t_reftable_stack_compaction_concurrent(void)\n \t\t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t\t.value.symref = (char *) \"master\",\n \t\t};\n-\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n \n-\t\terr = reftable_stack_add(st1, &write_test_ref, &ref);\n+\t\terr = reftable_stack_add(st1, write_test_ref, &ref);\n \t\tcheck(!err);\n \t}\n \n@@ -949,10 +945,8 @@ static void t_reftable_stack_compaction_concurrent(void)\n static void unclean_stack_close(struct reftable_stack *st)\n {\n \t/* break abstraction boundary to simulate unclean shutdown. */\n-\tint i = 0;\n-\tfor (; i < st->readers_len; i++) {\n+\tfor (size_t i = 0; i < st->readers_len; i++)\n \t\treftable_reader_free(st->readers[i]);\n-\t}\n \tst->readers_len = 0;\n \tFREE_AND_NULL(st->readers);\n }\n@@ -962,8 +956,8 @@ static void t_reftable_stack_compaction_concurrent_clean(void)\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL, *st3 = NULL;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tint err, i;\n-\tint N = 3;\n+\tint err;\n+\tsize_t N = 3, i;\n \n \terr = reftable_new_stack(&st1, dir, &opts);\n \tcheck(!err);\n@@ -976,9 +970,9 @@ static void t_reftable_stack_compaction_concurrent_clean(void)\n \t\t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t\t.value.symref = (char *) \"master\",\n \t\t};\n-\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n \n-\t\terr = reftable_stack_add(st1, &write_test_ref, &ref);\n+\t\terr = reftable_stack_add(st1, write_test_ref, &ref);\n \t\tcheck(!err);\n \t}\n \n-- \n2.45.GIT\n\n"},{"id":"500205","messageId":"20240806142020.4615-4-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240806142020.4615-1-chandrapratap3519@gmail.com","subject":"[PATCH 3/6] t-reftable-stack: use Git's tempfile API instead of mkstemp()","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-06T14:13:39Z","receivedAt":"2024-08-06T14:20:53Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"Git's tempfile API defined by $GIT_DIR/tempfile.{c, h} provides\na unified interface for tempfile operations. Since reftable/stack.c\nuses this API for all its tempfile needs instead of raw functions\nlike mkstemp(), make the ported stack test strictly use Git's\ntempfile API as well.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex e033feb8ee..14909b127e 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -76,7 +76,8 @@ static char *get_tmp_dir(int linenumber)\n static void t_read_file(void)\n {\n \tchar *fn = get_tmp_template(__LINE__);\n-\tint fd = mkstemp(fn);\n+\tstruct tempfile *tmp = mks_tempfile(fn);\n+\tint fd = get_tempfile_fd(tmp);\n \tchar out[1024] = \"line1\\n\\nline2\\nline3\";\n \tint n, err;\n \tchar **names = NULL;\n@@ -95,6 +96,7 @@ static void t_read_file(void)\n \t\tcheck_str(want[i], names[i]);\n \tfree_names(names);\n \t(void) remove(fn);\n+\tdelete_tempfile(&tmp);\n }\n \n static int write_test_ref(struct reftable_writer *wr, void *arg)\n-- \n2.45.GIT\n\n"},{"id":"500206","messageId":"20240806142020.4615-5-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240806142020.4615-1-chandrapratap3519@gmail.com","subject":"[PATCH 4/6] t-reftable-stack: use reftable_ref_record_equal() to compare ref records","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-06T14:13:40Z","receivedAt":"2024-08-06T14:20:56Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"In the current stack tests, ref records are compared for equality\nby sometimes using the dedicated function for ref-record comparison,\nreftable_ref_record_equal(), and sometimes by explicity comparing\ncontents of the ref records.\n\nReplace the latter instances of ref-record comparison with the\nformer to maintain uniformity throughout the test file.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 5 ++---\n 1 file changed, 2 insertions(+), 3 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 14909b127e..0c15e654e8 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -145,7 +145,7 @@ static void t_reftable_stack_add_one(void)\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n \tcheck(!err);\n-\tcheck_str(\"master\", dest.value.symref);\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \tcheck_int(st->readers_len, >, 0);\n \n \tprintf(\"testing print functionality:\\n\");\n@@ -262,8 +262,7 @@ static void t_reftable_stack_transaction_api(void)\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n \tcheck(!err);\n-\tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n-\tcheck_str(\"master\", dest.value.symref);\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n-- \n2.45.GIT\n\n"},{"id":"500207","messageId":"20240806142020.4615-6-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240806142020.4615-1-chandrapratap3519@gmail.com","subject":"[PATCH 5/6] t-reftable-stack: add test for non-default compaction factor","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-06T14:13:41Z","receivedAt":"2024-08-06T14:20:59Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"In a recent codebase update (commit ae8e378430, merge branch\n'ps/reftable-write-options', 2024/05/13) the geometric factor used\nin auto-compaction of reftable tables was made configurable. Add\na test to verify the functionality introduced by this update.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 41 +++++++++++++++++++++++++++++----\n 1 file changed, 37 insertions(+), 4 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 0c15e654e8..5228872450 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -808,12 +808,12 @@ static void t_empty_add(void)\n \treftable_stack_destroy(st2);\n }\n \n-static int fastlog2(uint64_t sz)\n+static int fastlogN(uint64_t sz, uint64_t N)\n {\n \tint l = 0;\n \tif (sz == 0)\n \t\treturn 0;\n-\tfor (; sz; sz /= 2)\n+\tfor (; sz; sz /= N)\n \t\tl++;\n \treturn l - 1;\n }\n@@ -846,11 +846,43 @@ static void t_reftable_stack_auto_compaction(void)\n \n \t\terr = reftable_stack_auto_compact(st);\n \t\tcheck(!err);\n-\t\tcheck(i < 3 || st->merged->stack_len < 2 * fastlog2(i));\n+\t\tcheck(i < 2 || st->merged->stack_len < 2 * fastlogN(i, 2));\n \t}\n \n \tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n-\t\t (uint64_t)(N * fastlog2(N)));\n+\t\t (uint64_t)(N * fastlogN(N, 2)));\n+\n+\treftable_stack_destroy(st);\n+\tclear_dir(dir);\n+}\n+\n+static void t_reftable_stack_auto_compaction_factor(void)\n+{\n+\tstruct reftable_write_options opts = {\n+\t\t.auto_compaction_factor = 5,\n+\t};\n+\tstruct reftable_stack *st = NULL;\n+\tchar *dir = get_tmp_dir(__LINE__);\n+\tint err;\n+\tsize_t N = 100;\n+\n+\terr = reftable_new_stack(&st, dir, &opts);\n+\tcheck(!err);\n+\n+\tfor (size_t i = 0; i < N; i++) {\n+\t\tchar name[20];\n+\t\tstruct reftable_ref_record ref = {\n+\t\t\t.refname = name,\n+\t\t\t.update_index = reftable_stack_next_update_index(st),\n+\t\t\t.value_type = REFTABLE_REF_VAL1,\n+\t\t};\n+\t\txsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n+\n+\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\tcheck(!err);\n+\n+\t\tcheck(i < 5 || st->merged->stack_len < 5 * fastlogN(i, 5));\n+\t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n@@ -1009,6 +1041,7 @@ int cmd_main(int argc, const char *argv[])\n \tTEST(t_reftable_stack_add_one(), \"add a single ref record to stack\");\n \tTEST(t_reftable_stack_add_performs_auto_compaction(), \"addition to stack triggers auto-compaction\");\n \tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_factor(), \"auto-compaction with non-default geometric factor\");\n \tTEST(t_reftable_stack_auto_compaction_fails_gracefully(), \"failure on auto-compaction\");\n \tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n \tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n-- \n2.45.GIT\n\n"},{"id":"500208","messageId":"20240806142020.4615-7-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240806142020.4615-1-chandrapratap3519@gmail.com","subject":"[PATCH 6/6] t-reftable-stack: add test for stack iterators","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-06T14:13:42Z","receivedAt":"2024-08-06T14:21:02Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"reftable_stack_init_ref_iterator and reftable_stack_init_log_iterator\nas defined by reftable/stack.{c, h} initialize a stack iterator to\niterate over the ref and log records in a reftable stack respectively.\nSince these functions are not exercised by any of the existing tests,\nadd a test for them.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 82 +++++++++++++++++++++++++++++++++\n 1 file changed, 82 insertions(+)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 5228872450..1ec8e4afc0 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -521,6 +521,87 @@ static void t_reftable_stack_add(void)\n \tclear_dir(dir);\n }\n \n+static void t_reftable_stack_iterator(void)\n+{\n+\tstruct reftable_write_options opts = { 0 };\n+\tstruct reftable_stack *st = NULL;\n+\tchar *dir = get_tmp_dir(__LINE__);\n+\tstruct reftable_ref_record refs[10] = { { 0 } };\n+\tstruct reftable_log_record logs[10] = { { 0 } };\n+\tstruct reftable_iterator it = { 0 };\n+\tsize_t N = ARRAY_SIZE(refs), i;\n+\tint err;\n+\n+\terr = reftable_new_stack(&st, dir, &opts);\n+\tcheck(!err);\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\tchar buf[20];\n+\t\txsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n+\t\trefs[i].refname = xstrdup(buf);\n+\t\trefs[i].update_index = i + 1;\n+\t\trefs[i].value_type = REFTABLE_REF_VAL1;\n+\t\tset_test_hash(refs[i].value.val1, i);\n+\n+\t\tlogs[i].refname = xstrdup(buf);\n+\t\tlogs[i].update_index = i + 1;\n+\t\tlogs[i].value_type = REFTABLE_LOG_UPDATE;\n+\t\tlogs[i].value.update.email = xstrdup(\"johndoe@invalid\");\n+\t\tlogs[i].value.update.message = xstrdup(\"commit\\n\");\n+\t\tset_test_hash(logs[i].value.update.new_hash, i);\n+\t}\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\terr = reftable_stack_add(st, &write_test_ref, &refs[i]);\n+\t\tcheck(!err);\n+\t}\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\tstruct write_log_arg arg = {\n+\t\t\t.log = &logs[i],\n+\t\t\t.update_index = reftable_stack_next_update_index(st),\n+\t\t};\n+\t\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tcheck(!err);\n+\t}\n+\n+\treftable_stack_init_ref_iterator(st, &it);\n+\treftable_iterator_seek_ref(&it, refs[0].refname);\n+\tfor (i = 0; ; i++) {\n+\t\tstruct reftable_ref_record ref = { 0 };\n+\t\terr = reftable_iterator_next_ref(&it, &ref);\n+\t\tif (err > 0)\n+\t\t\tbreak;\n+\t\tcheck(!err);\n+\t\tcheck(reftable_ref_record_equal(&ref, &refs[i], GIT_SHA1_RAWSZ));\n+\t\treftable_ref_record_release(&ref);\n+\t}\n+\tcheck_int(i, ==, N);\n+\n+\treftable_iterator_destroy(&it);\n+\n+\treftable_stack_init_log_iterator(st, &it);\n+\treftable_iterator_seek_log(&it, logs[0].refname);\n+\tfor (i = 0; ; i++) {\n+\t\tstruct reftable_log_record log = { 0 };\n+\t\terr = reftable_iterator_next_log(&it, &log);\n+\t\tif (err > 0)\n+\t\t\tbreak;\n+\t\tcheck(!err);\n+\t\tcheck(reftable_log_record_equal(&log, &logs[i], GIT_SHA1_RAWSZ));\n+\t\treftable_log_record_release(&log);\n+\t}\n+\tcheck_int(i, ==, N);\n+\n+\treftable_stack_destroy(st);\n+\treftable_iterator_destroy(&it);\n+\tfor (i = 0; i < N; i++) {\n+\t\treftable_ref_record_release(&refs[i]);\n+\t\treftable_log_record_release(&logs[i]);\n+\t}\n+\tclear_dir(dir);\n+}\n+\n static void t_reftable_stack_log_normalize(void)\n {\n \tint err;\n@@ -1046,6 +1127,7 @@ int cmd_main(int argc, const char *argv[])\n \tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n \tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n \tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n+\tTEST(t_reftable_stack_iterator(), \"log and ref iterator for reftable stack\");\n \tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n \tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n \tTEST(t_reftable_stack_tombstone(), \"'tombstone' refs in stack\");\n-- \n2.45.GIT\n\n"},{"id":"500244","messageId":"CAPig+cTLzdUf9D-u4YWURPb-ymGM9xgi6Ckc_wQGgORDmMHP-A@mail.gmail.com","threadId":"61911","inReplyTo":"20240806142020.4615-3-chandrapratap3519@gmail.com","subject":"Re: [PATCH 2/6] t: harmonize t-reftable-stack.c with coding guidelines","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2024-08-06T18:20:15Z","receivedAt":"2024-08-06T18:20:27Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Tue, Aug 6, 2024 at 10:21 AM Chandra Pratap\n<chandrapratap3519@gmail.com> wrote:\n> Harmonize the newly ported test unit-tests/t-reftable-stack.c\n> with the following guidelines:\n> - Single line 'for' statements must omit curly braces.\n> - Structs must be 0-initialized with '= { 0 }' instead of '= { NULL }'.\n> - Array sizes and indices should preferably be of type 'size_t'and\n\ns/'size_t'and'/'size_t' and/\n\n>   not 'int'.\n> - Function pointers should be passed as 'func' and not '&func'.\n>\n> While at it, remove initialization for those variables that are\n> re-used multiple times, like loop variables.\n>\n> Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n"},{"id":"500252","messageId":"xmqqed71s7yf.fsf@gitster.g","threadId":"61911","inReplyTo":"20240806142020.4615-1-chandrapratap3519@gmail.com","subject":"Re: [GSoC][PATCH 0/6] t: port reftable/stack_test.c to the unit testing framework","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-08-06T20:38:16Z","receivedAt":"2024-08-06T20:38:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Chandra Pratap <chandrapratap3519@gmail.com> writes:\n\n> The reftable library comes with self tests, which are exercised\n> as part of the usual end-to-end tests and are designed to\n> observe the end-user visible effects of Git commands. What it\n> exercises, however, is a better match for the unit-testing\n> framework, merged at 8bf6fbd0 (Merge branch 'js/doc-unit-tests',\n> 2023-12-09), which is designed to observe how low level\n> implementation details, at the level of sequences of individual\n> function calls, behave.\n>\n> Hence, port reftable/stack_test.c to the unit testing framework and\n> improve upon the ported test. The first patch in the series moves\n> the test to the unit testing framework, and the rest of the patches\n> improve upon the ported test.\n\nHowever, reftable/stack_test.c currently is a moving target because\nthere is an in-flight topic that improves the table compaction and\nthat topic wants to add more tests there.  So let's wait until the\ndust from the other topic settles before doing the first step of\nthis topic to move the file to t/unit-tests/ hiearchy.\n\nThanks.\n\n> Mentored-by: Patrick Steinhardt <ps@pks.im>\n> Mentored-by: Christian Couder <chriscool@tuxfamily.org>\n> Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n>\n> ---\n> CI/PR: https://github.com/gitgitgadget/git/pull/1762\n>\n> Chandra Pratap(6):\n> t: move reftable/stack_test.c to the unit testing framework\n> t: harmonize t-reftable-stack.c with coding guidelines\n> t-reftable-stack: use Git's tempfile API instead of mkstemp()\n> t-reftable-stack: use reftable_ref_record_equal() to compare ref records\n> t-reftable-stack: add test for non-default compaction factor\n> t-reftable-stack: add test for stack iterators\n>\n> Makefile                                                 |   2 +-\n> reftable/reftable-tests.h                                |   1 -\n> t/helper/test-reftable.c                                 |   1 -\n> reftable/stack_test.c => t/unit-tests/t-reftable-stack.c | 600 +++++++++++++++++++--------------\n> 4 files changed, 355 insertions(+), 249 deletions(-)\n"},{"id":"500253","messageId":"xmqq7ccts7j3.fsf@gitster.g","threadId":"61911","inReplyTo":"20240806142020.4615-4-chandrapratap3519@gmail.com","subject":"Re: [PATCH 3/6] t-reftable-stack: use Git's tempfile API instead of mkstemp()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-08-06T20:47:28Z","receivedAt":"2024-08-06T20:47:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Chandra Pratap <chandrapratap3519@gmail.com> writes:\n\n> Git's tempfile API defined by $GIT_DIR/tempfile.{c, h} provides\n\nYou are using the syntax of (some) shells to express \"repeat the\nstring with 'c' and 'h' appended\" here, so drop SP after the comma.\n"},{"id":"500261","messageId":"ZrME3EXwf2qDfTew@tanuki","threadId":"61911","inReplyTo":"20240806142020.4615-5-chandrapratap3519@gmail.com","subject":"Re: [PATCH 4/6] t-reftable-stack: use reftable_ref_record_equal() to compare ref records","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-08-07T05:23:40Z","receivedAt":"2024-08-07T05:23:47Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Aug 06, 2024 at 07:43:40PM +0530, Chandra Pratap wrote:\n> diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\n> index 14909b127e..0c15e654e8 100644\n> --- a/t/unit-tests/t-reftable-stack.c\n> +++ b/t/unit-tests/t-reftable-stack.c\n> @@ -145,7 +145,7 @@ static void t_reftable_stack_add_one(void)\n>  \n>  \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n>  \tcheck(!err);\n> -\tcheck_str(\"master\", dest.value.symref);\n> +\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n>  \tcheck_int(st->readers_len, >, 0);\n\nI think the change itself is sensible as long as we have tests that\nverify that `reftable_ref_record_equal()` itself behaves as expected. I\ndon't think we have such tests anywhere though, uncovering a test gap.\n\nPatrick\n"},{"id":"500262","messageId":"ZrME4jcdSmK3rUTh@tanuki","threadId":"61911","inReplyTo":"20240806142020.4615-3-chandrapratap3519@gmail.com","subject":"Re: [PATCH 2/6] t: harmonize t-reftable-stack.c with coding guidelines","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-08-07T05:23:46Z","receivedAt":"2024-08-07T05:23:52Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Aug 06, 2024 at 07:43:38PM +0530, Chandra Pratap wrote:\n> @@ -433,18 +431,18 @@ static void t_reftable_stack_add(void)\n>  \t};\n>  \tstruct reftable_stack *st = NULL;\n>  \tchar *dir = get_tmp_dir(__LINE__);\n> -\tstruct reftable_ref_record refs[2] = { { NULL } };\n> -\tstruct reftable_log_record logs[2] = { { NULL } };\n> +\tstruct reftable_ref_record refs[2] = { { 0 } };\n> +\tstruct reftable_log_record logs[2] = { { 0 } };\n\nThese should simply be `{ 0 }`, here and in a few other places further\ndown.\n\nPatrick\n"},{"id":"500263","messageId":"ZrME6CR7eX_Fj0DQ@tanuki","threadId":"61911","inReplyTo":"20240806142020.4615-4-chandrapratap3519@gmail.com","subject":"Re: [PATCH 3/6] t-reftable-stack: use Git's tempfile API instead of mkstemp()","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-08-07T05:23:52Z","receivedAt":"2024-08-07T05:23:56Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Aug 06, 2024 at 07:43:39PM +0530, Chandra Pratap wrote:\n> Git's tempfile API defined by $GIT_DIR/tempfile.{c, h} provides\n> a unified interface for tempfile operations. Since reftable/stack.c\n> uses this API for all its tempfile needs instead of raw functions\n> like mkstemp(), make the ported stack test strictly use Git's\n> tempfile API as well.\n> \n> Mentored-by: Patrick Steinhardt <ps@pks.im>\n> Mentored-by: Christian Couder <chriscool@tuxfamily.org>\n> Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n> ---\n>  t/unit-tests/t-reftable-stack.c | 4 +++-\n>  1 file changed, 3 insertions(+), 1 deletion(-)\n> \n> diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\n> index e033feb8ee..14909b127e 100644\n> --- a/t/unit-tests/t-reftable-stack.c\n> +++ b/t/unit-tests/t-reftable-stack.c\n> @@ -76,7 +76,8 @@ static char *get_tmp_dir(int linenumber)\n>  static void t_read_file(void)\n>  {\n>  \tchar *fn = get_tmp_template(__LINE__);\n> -\tint fd = mkstemp(fn);\n> +\tstruct tempfile *tmp = mks_tempfile(fn);\n> +\tint fd = get_tempfile_fd(tmp);\n>  \tchar out[1024] = \"line1\\n\\nline2\\nline3\";\n>  \tint n, err;\n>  \tchar **names = NULL;\n> @@ -95,6 +96,7 @@ static void t_read_file(void)\n>  \t\tcheck_str(want[i], names[i]);\n>  \tfree_names(names);\n>  \t(void) remove(fn);\n> +\tdelete_tempfile(&tmp);\n>  }\n\nI'm a bit torn whether this is a good idea because we are using a higher\nlevel interface that doesn't have unit tests itself. As I see it, both\nlow-level primitives and anything that is already verified via another\nset of unit tests can be used when writing unit tests. But as far as I\nknow, the tempfile interface does not yet have any.\n\nMaybe I'm being overthinking this though.\n\nIdeally, we wouldn't have to care about the underlying issue at all,\nnamely cleanup of the temporary file. This is something that the clar\nbrings to us for free: it can create temporary directories that it also\nknows to clean up automatically once done.\n\nPatrick\n"},{"id":"500264","messageId":"ZrME7SDUslFm4FqS@tanuki","threadId":"61911","inReplyTo":"20240806142020.4615-7-chandrapratap3519@gmail.com","subject":"Re: [PATCH 6/6] t-reftable-stack: add test for stack iterators","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-08-07T05:23:57Z","receivedAt":"2024-08-07T05:24:01Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Aug 06, 2024 at 07:43:42PM +0530, Chandra Pratap wrote:\n> reftable_stack_init_ref_iterator and reftable_stack_init_log_iterator\n> as defined by reftable/stack.{c, h} initialize a stack iterator to\n\nSame remark here that Junio posted on a preceding catch, please drop the\nspace in `stack.{c,h}`.\n\n> @@ -521,6 +521,87 @@ static void t_reftable_stack_add(void)\n>  \tclear_dir(dir);\n>  }\n>  \n> +static void t_reftable_stack_iterator(void)\n> +{\n> +\tstruct reftable_write_options opts = { 0 };\n> +\tstruct reftable_stack *st = NULL;\n> +\tchar *dir = get_tmp_dir(__LINE__);\n> +\tstruct reftable_ref_record refs[10] = { { 0 } };\n> +\tstruct reftable_log_record logs[10] = { { 0 } };\n\nAgain, these should be initialized with `= { 0 }`.\n\n> +\tstruct reftable_iterator it = { 0 };\n> +\tsize_t N = ARRAY_SIZE(refs), i;\n> +\tint err;\n> +\n> +\terr = reftable_new_stack(&st, dir, &opts);\n> +\tcheck(!err);\n> +\n> +\tfor (i = 0; i < N; i++) {\n> +\t\tchar buf[20];\n> +\t\txsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n> +\t\trefs[i].refname = xstrdup(buf);\n\nThis can be simplified to a single call to `xstrfmt()`.\n\nPatrick\n"},{"id":"500311","messageId":"CA+J6zkTr1m7WSpE3-GSCkhQhaTsG3Kvzuh-z5SPnK8qXvsg3qA@mail.gmail.com","threadId":"61911","inReplyTo":"xmqqed71s7yf.fsf@gitster.g","subject":"Re: [GSoC][PATCH 0/6] t: port reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-07T13:01:41Z","receivedAt":"2024-08-07T13:02:14Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"On Wed, 7 Aug 2024 at 02:08, Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Chandra Pratap <chandrapratap3519@gmail.com> writes:\n>\n> > The reftable library comes with self tests, which are exercised\n> > as part of the usual end-to-end tests and are designed to\n> > observe the end-user visible effects of Git commands. What it\n> > exercises, however, is a better match for the unit-testing\n> > framework, merged at 8bf6fbd0 (Merge branch 'js/doc-unit-tests',\n> > 2023-12-09), which is designed to observe how low level\n> > implementation details, at the level of sequences of individual\n> > function calls, behave.\n> >\n> > Hence, port reftable/stack_test.c to the unit testing framework and\n> > improve upon the ported test. The first patch in the series moves\n> > the test to the unit testing framework, and the rest of the patches\n> > improve upon the ported test.\n>\n> However, reftable/stack_test.c currently is a moving target because\n> there is an in-flight topic that improves the table compaction and\n> that topic wants to add more tests there.  So let's wait until the\n> dust from the other topic settles before doing the first step of\n> this topic to move the file to t/unit-tests/ hiearchy.\n>\n> Thanks.\n>\n\nOh okay, I will focus on the other tests in the meantime.\n\n--snip--\n"},{"id":"500330","messageId":"CA+J6zkTSBsrTZf2xyec-RaiqP3vJqvJmhVuW8GusbV-ia8CQ=A@mail.gmail.com","threadId":"61911","inReplyTo":"ZrME3EXwf2qDfTew@tanuki","subject":"Re: [PATCH 4/6] t-reftable-stack: use reftable_ref_record_equal() to compare ref records","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-07T14:42:58Z","receivedAt":"2024-08-07T14:43:26Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"On Wed, 7 Aug 2024 at 14:11, Patrick Steinhardt <ps@pks.im> wrote:\n>\n> On Tue, Aug 06, 2024 at 07:43:40PM +0530, Chandra Pratap wrote:\n> > diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\n> > index 14909b127e..0c15e654e8 100644\n> > --- a/t/unit-tests/t-reftable-stack.c\n> > +++ b/t/unit-tests/t-reftable-stack.c\n> > @@ -145,7 +145,7 @@ static void t_reftable_stack_add_one(void)\n> >\n> >       err = reftable_stack_read_ref(st, ref.refname, &dest);\n> >       check(!err);\n> > -     check_str(\"master\", dest.value.symref);\n> > +     check(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n> >       check_int(st->readers_len, >, 0);\n>\n> I think the change itself is sensible as long as we have tests that\n> verify that `reftable_ref_record_equal()` itself behaves as expected. I\n> don't think we have such tests anywhere though, uncovering a test gap.\n\nWe _do_ test reftable_record_equal (which is a wrapper for\nreftable_ref_record_equal in the case of ref records) in the\nrecently ported t-reftable-record test. Here is the test exercising\nthis function in unit-tests/t-reftable-record.c:\n\nstatic void t_reftable_ref_record_comparison(void)\n{\n  struct reftable_record in[3] = {\n    {\n      .type = BLOCK_TYPE_REF,\n      .u.ref.refname = (char *) \"refs/heads/master\",\n      .u.ref.value_type = REFTABLE_REF_VAL1,\n    },\n    {\n      .type = BLOCK_TYPE_REF,\n      .u.ref.refname = (char *) \"refs/heads/master\",\n      .u.ref.value_type = REFTABLE_REF_DELETION,\n    },\n    {\n      .type = BLOCK_TYPE_REF,\n      .u.ref.refname = (char *) \"HEAD\",\n      .u.ref.value_type = REFTABLE_REF_SYMREF,\n      .u.ref.value.symref = (char *) \"refs/heads/master\",\n    },\n  };\n\n  check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));\n  check(!reftable_record_cmp(&in[0], &in[1]));\n\n  check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ));\n  check_int(reftable_record_cmp(&in[1], &in[2]), >, 0);\n\n  in[1].u.ref.value_type = in[0].u.ref.value_type;\n  check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));\n  check(!reftable_record_cmp(&in[0], &in[1]));\n}\n"},{"id":"500383","messageId":"ZrREaGKQmriAfnIV@tanuki","threadId":"61911","inReplyTo":"CA+J6zkTSBsrTZf2xyec-RaiqP3vJqvJmhVuW8GusbV-ia8CQ=A@mail.gmail.com","subject":"Re: [PATCH 4/6] t-reftable-stack: use reftable_ref_record_equal() to compare ref records","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-08-08T04:07:04Z","receivedAt":"2024-08-08T04:07:11Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Wed, Aug 07, 2024 at 08:12:58PM +0530, Chandra Pratap wrote:\n> On Wed, 7 Aug 2024 at 14:11, Patrick Steinhardt <ps@pks.im> wrote:\n> >\n> > On Tue, Aug 06, 2024 at 07:43:40PM +0530, Chandra Pratap wrote:\n> > > diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\n> > > index 14909b127e..0c15e654e8 100644\n> > > --- a/t/unit-tests/t-reftable-stack.c\n> > > +++ b/t/unit-tests/t-reftable-stack.c\n> > > @@ -145,7 +145,7 @@ static void t_reftable_stack_add_one(void)\n> > >\n> > >       err = reftable_stack_read_ref(st, ref.refname, &dest);\n> > >       check(!err);\n> > > -     check_str(\"master\", dest.value.symref);\n> > > +     check(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n> > >       check_int(st->readers_len, >, 0);\n> >\n> > I think the change itself is sensible as long as we have tests that\n> > verify that `reftable_ref_record_equal()` itself behaves as expected. I\n> > don't think we have such tests anywhere though, uncovering a test gap.\n> \n> We _do_ test reftable_record_equal (which is a wrapper for\n> reftable_ref_record_equal in the case of ref records) in the\n> recently ported t-reftable-record test. Here is the test exercising\n> this function in unit-tests/t-reftable-record.c:\n\nAh, great, never mind then! I didn't see this test because we are\nusing `reftable_ref_record_equal()` here, whereas the test uses\n`reftable_record_equal()`. But the latter uses the former for ref\nrecords, so that's fine.\n\nPatrick\n"},{"id":"501582","messageId":"20240823120514.11070-1-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240806142020.4615-1-chandrapratap3519@gmail.com","subject":"[GSoC][PATCH v2 0/6] t: port reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-23T11:48:45Z","receivedAt":"2024-08-23T12:05:56Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"The reftable library comes with self tests, which are exercised\nas part of the usual end-to-end tests and are designed to\nobserve the end-user visible effects of Git commands. What it\nexercises, however, is a better match for the unit-testing\nframework, merged at 8bf6fbd0 (Merge branch 'js/doc-unit-tests',\n2023-12-09), which is designed to observe how low level\nimplementation details, at the level of sequences of individual\nfunction calls, behave.\n\nHence, port reftable/stack_test.c to the unit testing framework and\nimprove upon the ported test. The first patch in the series moves\nthe test to the unit testing framework, and the rest of the patches\nimprove upon the ported test.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n\n---\nChanges in v2:\n- Rebase the branch on top of latest 'master', this ensures that\n  updates to reftable/stack_test.c are included in the ported test.\n- Fix a typo in the commit message patch 2.\n- Use ' = { 0 }' to 0-initialize arrays of structs instead\n  of ' = { { 0 } }' in patch 2.\n- use 'xstrfmt()' instead of a char buffer and 'xstrdup()' in the\n  new test in patch 6.\n\nCI/PR: https://github.com/gitgitgadget/git/pull/1762\n\nChandra Pratap(6):\nt: move reftable/stack_test.c to the unit testing framework\nt: harmonize t-reftable-stack.c with coding guidelines\nt-reftable-stack: use Git's tempfile API instead of mkstemp()\nt-reftable-stack: use reftable_ref_record_equal() to compare ref records\nt-reftable-stack: add test for non-default compaction factor\nt-reftable-stack: add test for stack iterators\n\nMakefile                                                 |   2 +-\nreftable/reftable-tests.h                                |   1 -\nt/helper/test-reftable.c                                 |   1 -\nreftable/stack_test.c => t/unit-tests/t-reftable-stack.c | 611 +++++++++++++++++++--------------\n4 files changed, 360 insertions(+), 255 deletions(-)\n\nRange-diff against v1:\n<rebase commits>\n  1:  bd595290dc ! 167:  b401ef765a t: move reftable/stack_test.c to the unit testing framework\n    @@ Commit message\n         Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n\n      ## Makefile ##\n    -@@ Makefile: UNIT_TEST_PROGRAMS += t-prio-queue\n    - UNIT_TEST_PROGRAMS += t-reftable-basics\n    +@@ Makefile: UNIT_TEST_PROGRAMS += t-reftable-basics\n      UNIT_TEST_PROGRAMS += t-reftable-merged\n    + UNIT_TEST_PROGRAMS += t-reftable-pq\n      UNIT_TEST_PROGRAMS += t-reftable-record\n     +UNIT_TEST_PROGRAMS += t-reftable-stack\n    + UNIT_TEST_PROGRAMS += t-reftable-tree\n      UNIT_TEST_PROGRAMS += t-strbuf\n      UNIT_TEST_PROGRAMS += t-strcmp-offset\n    - UNIT_TEST_PROGRAMS += t-strvec\n    -@@ Makefile: REFTABLE_TEST_OBJS += reftable/block_test.o\n    +@@ Makefile: REFTABLE_OBJS += reftable/writer.o\n    + REFTABLE_TEST_OBJS += reftable/block_test.o\n      REFTABLE_TEST_OBJS += reftable/dump.o\n    - REFTABLE_TEST_OBJS += reftable/pq_test.o\n      REFTABLE_TEST_OBJS += reftable/readwrite_test.o\n     -REFTABLE_TEST_OBJS += reftable/stack_test.o\n      REFTABLE_TEST_OBJS += reftable/test_framework.o\n    - REFTABLE_TEST_OBJS += reftable/tree_test.o\n\n    + TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))\n\n      ## reftable/reftable-tests.h ##\n    -@@ reftable/reftable-tests.h: int block_test_main(int argc, const char **argv);\n    - int pq_test_main(int argc, const char **argv);\n    +@@ reftable/reftable-tests.h: int basics_test_main(int argc, const char **argv);\n    + int block_test_main(int argc, const char **argv);\n      int record_test_main(int argc, const char **argv);\n      int readwrite_test_main(int argc, const char **argv);\n     -int stack_test_main(int argc, const char **argv);\n    - int tree_test_main(int argc, const char **argv);\n      int reftable_dump_main(int argc, char *const *argv);\n\n    + #endif\n\n      ## t/helper/test-reftable.c ##\n     @@ t/helper/test-reftable.c: int cmd__reftable(int argc, const char **argv)\n    - \ttree_test_main(argc, argv);\n    - \tpq_test_main(argc, argv);\n    + \t/* test from simple to complex. */\n    + \tblock_test_main(argc, argv);\n      \treadwrite_test_main(argc, argv);\n     -\tstack_test_main(argc, argv);\n      \treturn 0;\n    @@ t/unit-tests/t-reftable-stack.c: license that can be found in the LICENSE file o\n     +#include \"reftable/stack.h\"\n      #include <dirent.h>\n\n    - static void clear_dir(const char *dirname)\n    -@@ t/unit-tests/t-reftable-stack.c: static void clear_dir(const char *dirname)\n    - \tstrbuf_release(&path);\n    - }\n    -\n     +static void set_test_hash(uint8_t *p, int i)\n     +{\n     +\tmemset(p, (uint8_t)i, hash_size(GIT_SHA1_FORMAT_ID));\n     +}\n     +\n    - static int count_dir_entries(const char *dirname)\n    + static void clear_dir(const char *dirname)\n      {\n    - \tDIR *dir = opendir(dirname);\n    + \tstruct strbuf path = STRBUF_INIT;\n     @@ t/unit-tests/t-reftable-stack.c: static char *get_tmp_template(int linenumber)\n      static char *get_tmp_dir(int linenumber)\n      {\n    @@ t/unit-tests/t-reftable-stack.c: static void test_read_file(void)\n      \t}\n      \tfree_names(names);\n      \t(void) remove(fn);\n    +@@ t/unit-tests/t-reftable-stack.c: static void write_n_ref_tables(struct reftable_stack *st,\n    + \t\tset_test_hash(ref.value.val1, i);\n    +\n    + \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n    +-\t\tEXPECT_ERR(err);\n    ++\t\tcheck(!err);\n    + \t}\n    +\n    + \tst->opts.disable_auto_compact = disable_auto_compact;\n     @@ t/unit-tests/t-reftable-stack.c: static int write_test_log(struct reftable_writer *wr, void *arg)\n      \treturn reftable_writer_add_log(wr, wla->log);\n      }\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_auto_compaction\n      \t}\n\n     -\tEXPECT(reftable_stack_compaction_stats(st)->entries_written <\n    --\t       (uint64_t)(N * fastlog2(N)));\n     +\tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n    -+\t\t (uint64_t)(N * fastlog2(N)));\n    + \t       (uint64_t)(N * fastlog2(N)));\n    +\n    + \treftable_stack_destroy(st);\n    + \tclear_dir(dir);\n    + }\n    +\n    +-static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n    ++static void t_reftable_stack_auto_compaction_with_locked_tables(void)\n    + {\n    + \tstruct reftable_write_options opts = {\n    + \t\t.disable_auto_compact = 1,\n    +@@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n    + \tint err;\n    +\n    + \terr = reftable_new_stack(&st, dir, &opts);\n    +-\tEXPECT_ERR(err);\n    ++\tcheck(!err);\n    +\n    + \twrite_n_ref_tables(st, 5);\n    +-\tEXPECT(st->merged->stack_len == 5);\n    ++\tcheck_int(st->merged->stack_len, ==, 5);\n    +\n    + \t/*\n    + \t * Given that all tables we have written should be roughly the same\n    +@@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n    + \t * only compact the newest two tables.\n    + \t */\n    + \terr = reftable_stack_auto_compact(st);\n    +-\tEXPECT_ERR(err);\n    +-\tEXPECT(st->stats.failures == 0);\n    +-\tEXPECT(st->merged->stack_len == 4);\n    ++\tcheck(!err);\n    ++\tcheck_int(st->stats.failures, ==, 0);\n    ++\tcheck_int(st->merged->stack_len, ==, 4);\n\n      \treftable_stack_destroy(st);\n    + \tstrbuf_release(&buf);\n      \tclear_dir(dir);\n      }\n\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_add_performs_au\n      \tclear_dir(dir);\n      }\n\n    +-static void test_reftable_stack_compaction_with_locked_tables(void)\n    ++static void t_reftable_stack_compaction_with_locked_tables(void)\n    + {\n    + \tstruct reftable_write_options opts = {\n    + \t\t.disable_auto_compact = 1,\n    +@@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_compaction_with_locked_tables(void)\n    + \tint err;\n    +\n    + \terr = reftable_new_stack(&st, dir, &opts);\n    +-\tEXPECT_ERR(err);\n    ++\tcheck(!err);\n    +\n    + \twrite_n_ref_tables(st, 3);\n    +-\tEXPECT(st->merged->stack_len == 3);\n    ++\tcheck_int(st->merged->stack_len, ==, 3);\n    +\n    + \t/* Lock one of the tables that we're about to compact. */\n    + \tstrbuf_reset(&buf);\n    +@@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_compaction_with_locked_tables(void)\n    + \t * compact all tables.\n    + \t */\n    + \terr = reftable_stack_compact_all(st, NULL);\n    +-\tEXPECT(err == REFTABLE_LOCK_ERROR);\n    +-\tEXPECT(st->stats.failures == 1);\n    +-\tEXPECT(st->merged->stack_len == 3);\n    ++\tcheck_int(err, ==, REFTABLE_LOCK_ERROR);\n    ++\tcheck_int(st->stats.failures, ==, 1);\n    ++\tcheck_int(st->merged->stack_len, ==, 3);\n    +\n    + \treftable_stack_destroy(st);\n    + \tstrbuf_release(&buf);\n    + \tclear_dir(dir);\n    + }\n    +\n     -static void test_reftable_stack_compaction_concurrent(void)\n     +static void t_reftable_stack_compaction_concurrent(void)\n      {\n      \tstruct reftable_write_options opts = { 0 };\n      \tstruct reftable_stack *st1 = NULL, *st2 = NULL;\n     @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_compaction_concurrent(void)\n    - \tint N = 3;\n    + \tint err;\n\n      \terr = reftable_new_stack(&st1, dir, &opts);\n     -\tEXPECT_ERR(err);\n     +\tcheck(!err);\n    -\n    - \tfor (i = 0; i < N; i++) {\n    - \t\tchar name[100];\n    -@@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_compaction_concurrent(void)\n    - \t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n    -\n    - \t\terr = reftable_stack_add(st1, &write_test_ref, &ref);\n    --\t\tEXPECT_ERR(err);\n    -+\t\tcheck(!err);\n    - \t}\n    + \twrite_n_ref_tables(st1, 3);\n\n      \terr = reftable_new_stack(&st2, dir, &opts);\n     -\tEXPECT_ERR(err);\n    @@ t/unit-tests/t-reftable-stack.c: static void unclean_stack_close(struct reftable\n      \tstruct reftable_write_options opts = { 0 };\n      \tstruct reftable_stack *st1 = NULL, *st2 = NULL, *st3 = NULL;\n     @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_compaction_concurrent_clean(void)\n    - \tint N = 3;\n    + \tint err;\n\n      \terr = reftable_new_stack(&st1, dir, &opts);\n     -\tEXPECT_ERR(err);\n     +\tcheck(!err);\n    -\n    - \tfor (i = 0; i < N; i++) {\n    - \t\tchar name[100];\n    -@@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_compaction_concurrent_clean(void)\n    - \t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n    -\n    - \t\terr = reftable_stack_add(st1, &write_test_ref, &ref);\n    --\t\tEXPECT_ERR(err);\n    -+\t\tcheck(!err);\n    - \t}\n    + \twrite_n_ref_tables(st1, 3);\n\n      \terr = reftable_new_stack(&st2, dir, &opts);\n     -\tEXPECT_ERR(err);\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_compaction_conc\n     -\tRUN_TEST(test_reftable_stack_add);\n     -\tRUN_TEST(test_reftable_stack_add_one);\n     -\tRUN_TEST(test_reftable_stack_auto_compaction);\n    +-\tRUN_TEST(test_reftable_stack_auto_compaction_with_locked_tables);\n     -\tRUN_TEST(test_reftable_stack_add_performs_auto_compaction);\n     -\tRUN_TEST(test_reftable_stack_compaction_concurrent);\n     -\tRUN_TEST(test_reftable_stack_compaction_concurrent_clean);\n    +-\tRUN_TEST(test_reftable_stack_compaction_with_locked_tables);\n     -\tRUN_TEST(test_reftable_stack_hash_id);\n     -\tRUN_TEST(test_reftable_stack_lock_failure);\n     -\tRUN_TEST(test_reftable_stack_log_normalize);\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_compaction_conc\n     +\tTEST(t_reftable_stack_add_performs_auto_compaction(), \"addition to stack triggers auto-compaction\");\n     +\tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n     +\tTEST(t_reftable_stack_auto_compaction_fails_gracefully(), \"failure on auto-compaction\");\n    ++\tTEST(t_reftable_stack_auto_compaction_with_locked_tables(), \"auto compaction with locked tables\");\n     +\tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n     +\tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n    ++\tTEST(t_reftable_stack_compaction_with_locked_tables(), \"compaction with locked tables\");\n     +\tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n     +\tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n     +\tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n  2:  64d91d89a5 ! 168:  e1704047cb t: harmonize t-reftable-stack.c with coding guidelines\n    @@ Commit message\n         with the following guidelines:\n         - Single line 'for' statements must omit curly braces.\n         - Structs must be 0-initialized with '= { 0 }' instead of '= { NULL }'.\n    -    - Array sizes and indices should preferably be of type 'size_t'and\n    +    - Array sizes and indices should preferably be of type 'size_t' and\n           not 'int'.\n         - Function pointers should be passed as 'func' and not '&func'.\n\n    @@ t/unit-tests/t-reftable-stack.c: static void t_read_file(void)\n      \tfree_names(names);\n      \t(void) remove(fn);\n      }\n    +@@ t/unit-tests/t-reftable-stack.c: static void write_n_ref_tables(struct reftable_stack *st,\n    + \t\t\t.value_type = REFTABLE_REF_VAL1,\n    + \t\t};\n    +\n    +-\t\tstrbuf_addf(&buf, \"refs/heads/branch-%04u\", (unsigned) i);\n    ++\t\tstrbuf_addf(&buf, \"refs/heads/branch-%04\"PRIuMAX, (uintmax_t)i);\n    + \t\tref.refname = buf.buf;\n    + \t\tset_test_hash(ref.value.val1, i);\n    +\n     @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add_one(void)\n      \t\t.value_type = REFTABLE_REF_SYMREF,\n      \t\t.value.symref = (char *) \"master\",\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_transaction_api_pe\n      \tstruct reftable_addition *add = NULL;\n      \tstruct reftable_stack *st = NULL;\n     -\tint i, n = 20, err;\n    -+\tsize_t i, n = 20;\n    ++\tsize_t n = 20;\n     +\tint err;\n\n      \terr = reftable_new_stack(&st, dir, &opts);\n      \tcheck(!err);\n    +\n    +-\tfor (i = 0; i <= n; i++) {\n    ++\tfor (size_t i = 0; i <= n; i++) {\n    + \t\tstruct reftable_ref_record ref = {\n    + \t\t\t.update_index = reftable_stack_next_update_index(st),\n    + \t\t\t.value_type = REFTABLE_REF_SYMREF,\n     @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n      \t\t};\n      \t\tchar name[100];\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_transaction_api_pe\n      \t\tcheck(!err);\n\n      \t\terr = reftable_addition_commit(add);\n    +@@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_auto_compaction_fails_gracefully(void)\n    + \t\t.value_type = REFTABLE_REF_VAL1,\n    + \t\t.value.val1 = {0x01},\n    + \t};\n    +-\tstruct reftable_write_options opts = {0};\n    ++\tstruct reftable_write_options opts = { 0 };\n    + \tstruct reftable_stack *st;\n    + \tstruct strbuf table_path = STRBUF_INIT;\n    + \tchar *dir = get_tmp_dir(__LINE__);\n     @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_update_index_check(void)\n      \terr = reftable_new_stack(&st, dir, &opts);\n      \tcheck(!err);\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_lock_failure(void)\n      static void t_reftable_stack_add(void)\n      {\n     -\tint i = 0;\n    --\tint err = 0;\n    -+\tint err;\n    + \tint err = 0;\n      \tstruct reftable_write_options opts = {\n      \t\t.exact_log_message = 1,\n    - \t\t.default_permissions = 0660,\n     @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add(void)\n      \t};\n      \tstruct reftable_stack *st = NULL;\n      \tchar *dir = get_tmp_dir(__LINE__);\n     -\tstruct reftable_ref_record refs[2] = { { NULL } };\n     -\tstruct reftable_log_record logs[2] = { { NULL } };\n    -+\tstruct reftable_ref_record refs[2] = { { 0 } };\n    -+\tstruct reftable_log_record logs[2] = { { 0 } };\n    ++\tstruct reftable_ref_record refs[2] = { 0 };\n    ++\tstruct reftable_log_record logs[2] = { 0 };\n      \tstruct strbuf path = STRBUF_INIT;\n      \tstruct stat stat_result;\n     -\tint N = ARRAY_SIZE(refs);\n    -+\tsize_t N = ARRAY_SIZE(refs), i;\n    ++\tsize_t i, N = ARRAY_SIZE(refs);\n\n      \terr = reftable_new_stack(&st, dir, &opts);\n      \tcheck(!err);\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add(void)\n      \t\tint err = reftable_stack_read_log(st, refs[i].refname, &dest);\n      \t\tcheck(!err);\n      \t\tcheck(reftable_log_record_equal(&dest, logs + i,\n    -@@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add(void)\n    -\n    - static void t_reftable_stack_log_normalize(void)\n    - {\n    --\tint err = 0;\n    -+\tint err;\n    - \tstruct reftable_write_options opts = {\n    - \t\t0,\n    - \t};\n     @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_log_normalize(void)\n      \tcheck(!err);\n\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_log_normalize(void\n     -\tint N = ARRAY_SIZE(refs);\n     -\tstruct reftable_ref_record dest = { NULL };\n     -\tstruct reftable_log_record log_dest = { NULL };\n    -+\tstruct reftable_ref_record refs[2] = { { 0 } };\n    -+\tstruct reftable_log_record logs[2] = { { 0 } };\n    -+\tsize_t N = ARRAY_SIZE(refs), i;\n    ++\tstruct reftable_ref_record refs[2] = { 0 };\n    ++\tstruct reftable_log_record logs[2] = { 0 };\n    ++\tsize_t i, N = ARRAY_SIZE(refs);\n     +\tstruct reftable_ref_record dest = { 0 };\n     +\tstruct reftable_log_record log_dest = { 0 };\n\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reflog_expire(void)\n     -\tstruct reftable_log_record logs[20] = { { NULL } };\n     -\tint N = ARRAY_SIZE(logs) - 1;\n     -\tint i = 0;\n    -+\tstruct reftable_log_record logs[20] = { { 0 } };\n    -+\tsize_t N = ARRAY_SIZE(logs) - 1, i;\n    ++\tstruct reftable_log_record logs[20] = { 0 };\n    ++\tsize_t i, N = ARRAY_SIZE(logs) - 1;\n      \tint err;\n      \tstruct reftable_log_expiry_config expiry = {\n      \t\t.time = 10,\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_auto_compaction(vo\n     -\tint err, i;\n     -\tint N = 100;\n     +\tint err;\n    -+\tsize_t N = 100, i;\n    ++\tsize_t i, N = 100;\n\n      \terr = reftable_new_stack(&st, dir, &opts);\n      \tcheck(!err);\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add_performs_auto_\n      \t\tcheck(!err);\n\n      \t\t/*\n    -@@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_compaction_concurrent(void)\n    - \tstruct reftable_write_options opts = { 0 };\n    - \tstruct reftable_stack *st1 = NULL, *st2 = NULL;\n    - \tchar *dir = get_tmp_dir(__LINE__);\n    --\tint err, i;\n    --\tint N = 3;\n    -+\tint err;\n    -+\tsize_t N = 3, i;\n    -\n    - \terr = reftable_new_stack(&st1, dir, &opts);\n    - \tcheck(!err);\n    -@@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_compaction_concurrent(void)\n    - \t\t\t.value_type = REFTABLE_REF_SYMREF,\n    - \t\t\t.value.symref = (char *) \"master\",\n    - \t\t};\n    --\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n    -+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n    -\n    --\t\terr = reftable_stack_add(st1, &write_test_ref, &ref);\n    -+\t\terr = reftable_stack_add(st1, write_test_ref, &ref);\n    - \t\tcheck(!err);\n    - \t}\n    -\n     @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_compaction_concurrent(void)\n      static void unclean_stack_close(struct reftable_stack *st)\n      {\n      \t/* break abstraction boundary to simulate unclean shutdown. */\n     -\tint i = 0;\n     -\tfor (; i < st->readers_len; i++) {\n    -+\tfor (size_t i = 0; i < st->readers_len; i++)\n    ++\tfor (int i = 0; i < st->readers_len; i++)\n      \t\treftable_reader_free(st->readers[i]);\n     -\t}\n      \tst->readers_len = 0;\n      \tFREE_AND_NULL(st->readers);\n      }\n    -@@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_compaction_concurrent_clean(void)\n    - \tstruct reftable_write_options opts = { 0 };\n    - \tstruct reftable_stack *st1 = NULL, *st2 = NULL, *st3 = NULL;\n    - \tchar *dir = get_tmp_dir(__LINE__);\n    --\tint err, i;\n    --\tint N = 3;\n    -+\tint err;\n    -+\tsize_t N = 3, i;\n    -\n    - \terr = reftable_new_stack(&st1, dir, &opts);\n    - \tcheck(!err);\n    -@@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_compaction_concurrent_clean(void)\n    - \t\t\t.value_type = REFTABLE_REF_SYMREF,\n    - \t\t\t.value.symref = (char *) \"master\",\n    - \t\t};\n    --\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n    -+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n    -\n    --\t\terr = reftable_stack_add(st1, &write_test_ref, &ref);\n    -+\t\terr = reftable_stack_add(st1, write_test_ref, &ref);\n    - \t\tcheck(!err);\n    - \t}\n    -\n  3:  4e769b826f ! 169:  792a7b1e62 t-reftable-stack: use Git's tempfile API instead of mkstemp()\n    @@ Metadata\n      ## Commit message ##\n         t-reftable-stack: use Git's tempfile API instead of mkstemp()\n\n    -    Git's tempfile API defined by $GIT_DIR/tempfile.{c, h} provides\n    +    Git's tempfile API defined by $GIT_DIR/tempfile.{c,h} provides\n         a unified interface for tempfile operations. Since reftable/stack.c\n         uses this API for all its tempfile needs instead of raw functions\n         like mkstemp(), make the ported stack test strictly use Git's\n  4:  8277e711af ! 170:  d771dc74af t-reftable-stack: use reftable_ref_record_equal() to compare ref records\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add_one(void)\n\n      \tprintf(\"testing print functionality:\\n\");\n     @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_transaction_api(void)\n    -\n      \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n      \tcheck(!err);\n    --\tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n    + \tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n     -\tcheck_str(\"master\", dest.value.symref);\n     +\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n\n  5:  9528f910ce ! 171:  c38a96cd4e t-reftable-stack: add test for non-default compaction factor\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_auto_compaction(vo\n      \t}\n\n      \tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n    --\t\t (uint64_t)(N * fastlog2(N)));\n    -+\t\t (uint64_t)(N * fastlogN(N, 2)));\n    +-\t       (uint64_t)(N * fastlog2(N)));\n    ++\t       (uint64_t)(N * fastlogN(N, 2)));\n     +\n     +\treftable_stack_destroy(st);\n     +\tclear_dir(dir);\n    @@ t/unit-tests/t-reftable-stack.c: int cmd_main(int argc, const char *argv[])\n      \tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n     +\tTEST(t_reftable_stack_auto_compaction_factor(), \"auto-compaction with non-default geometric factor\");\n      \tTEST(t_reftable_stack_auto_compaction_fails_gracefully(), \"failure on auto-compaction\");\n    + \tTEST(t_reftable_stack_auto_compaction_with_locked_tables(), \"auto compaction with locked tables\");\n      \tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n    - \tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n  6:  bd997a27d7 ! 172:  ea5267ca22 t-reftable-stack: add test for stack iterators\n    @@ Commit message\n         t-reftable-stack: add test for stack iterators\n\n         reftable_stack_init_ref_iterator and reftable_stack_init_log_iterator\n    -    as defined by reftable/stack.{c, h} initialize a stack iterator to\n    +    as defined by reftable/stack.{c,h} initialize a stack iterator to\n         iterate over the ref and log records in a reftable stack respectively.\n         Since these functions are not exercised by any of the existing tests,\n         add a test for them.\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add(void)\n     +\tstruct reftable_write_options opts = { 0 };\n     +\tstruct reftable_stack *st = NULL;\n     +\tchar *dir = get_tmp_dir(__LINE__);\n    -+\tstruct reftable_ref_record refs[10] = { { 0 } };\n    -+\tstruct reftable_log_record logs[10] = { { 0 } };\n    ++\tstruct reftable_ref_record refs[10] = { 0 };\n    ++\tstruct reftable_log_record logs[10] = { 0 };\n     +\tstruct reftable_iterator it = { 0 };\n     +\tsize_t N = ARRAY_SIZE(refs), i;\n     +\tint err;\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add(void)\n     +\tcheck(!err);\n     +\n     +\tfor (i = 0; i < N; i++) {\n    -+\t\tchar buf[20];\n    -+\t\txsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n    -+\t\trefs[i].refname = xstrdup(buf);\n    ++\t\trefs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n     +\t\trefs[i].update_index = i + 1;\n     +\t\trefs[i].value_type = REFTABLE_REF_VAL1;\n     +\t\tset_test_hash(refs[i].value.val1, i);\n     +\n    -+\t\tlogs[i].refname = xstrdup(buf);\n    ++\t\tlogs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n     +\t\tlogs[i].update_index = i + 1;\n     +\t\tlogs[i].value_type = REFTABLE_LOG_UPDATE;\n     +\t\tlogs[i].value.update.email = xstrdup(\"johndoe@invalid\");\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add(void)\n     +\n      static void t_reftable_stack_log_normalize(void)\n      {\n    - \tint err;\n    + \tint err = 0;\n     @@ t/unit-tests/t-reftable-stack.c: int cmd_main(int argc, const char *argv[])\n    - \tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n      \tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n    + \tTEST(t_reftable_stack_compaction_with_locked_tables(), \"compaction with locked tables\");\n      \tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n     +\tTEST(t_reftable_stack_iterator(), \"log and ref iterator for reftable stack\");\n      \tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n\n"},{"id":"501583","messageId":"20240823120514.11070-2-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240823120514.11070-1-chandrapratap3519@gmail.com","subject":"[PATCH v2 1/6] t: move reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-23T11:48:46Z","receivedAt":"2024-08-23T12:05:58Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"reftable/stack_test.c exercises the functions defined in\nreftable/stack.{c, h}. Migrate reftable/stack_test.c to the\nunit testing framework. Migration involves refactoring the tests\nto use the unit testing framework instead of reftable's test\nframework and renaming the tests to be in-line with unit-tests'\nstandards.\n\nSince some of the tests use set_test_hash() defined by\nreftable/test_framework.{c, h} but these files are not\n'#included' in the test file, copy this function in the\nported test file.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n Makefile                                      |   2 +-\n reftable/reftable-tests.h                     |   1 -\n t/helper/test-reftable.c                      |   1 -\n .../unit-tests/t-reftable-stack.c             | 374 +++++++++---------\n 4 files changed, 187 insertions(+), 191 deletions(-)\n rename reftable/stack_test.c => t/unit-tests/t-reftable-stack.c (77%)\n\ndiff --git a/Makefile b/Makefile\nindex a87e18b317..a63b3d8381 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1344,6 +1344,7 @@ UNIT_TEST_PROGRAMS += t-reftable-basics\n UNIT_TEST_PROGRAMS += t-reftable-merged\n UNIT_TEST_PROGRAMS += t-reftable-pq\n UNIT_TEST_PROGRAMS += t-reftable-record\n+UNIT_TEST_PROGRAMS += t-reftable-stack\n UNIT_TEST_PROGRAMS += t-reftable-tree\n UNIT_TEST_PROGRAMS += t-strbuf\n UNIT_TEST_PROGRAMS += t-strcmp-offset\n@@ -2685,7 +2686,6 @@ REFTABLE_OBJS += reftable/writer.o\n REFTABLE_TEST_OBJS += reftable/block_test.o\n REFTABLE_TEST_OBJS += reftable/dump.o\n REFTABLE_TEST_OBJS += reftable/readwrite_test.o\n-REFTABLE_TEST_OBJS += reftable/stack_test.o\n REFTABLE_TEST_OBJS += reftable/test_framework.o\n \n TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))\ndiff --git a/reftable/reftable-tests.h b/reftable/reftable-tests.h\nindex 4b666810af..2ed2aa7a86 100644\n--- a/reftable/reftable-tests.h\n+++ b/reftable/reftable-tests.h\n@@ -13,7 +13,6 @@ int basics_test_main(int argc, const char **argv);\n int block_test_main(int argc, const char **argv);\n int record_test_main(int argc, const char **argv);\n int readwrite_test_main(int argc, const char **argv);\n-int stack_test_main(int argc, const char **argv);\n int reftable_dump_main(int argc, char *const *argv);\n \n #endif\ndiff --git a/t/helper/test-reftable.c b/t/helper/test-reftable.c\nindex 623cf3f0f5..8a817ca9d9 100644\n--- a/t/helper/test-reftable.c\n+++ b/t/helper/test-reftable.c\n@@ -7,7 +7,6 @@ int cmd__reftable(int argc, const char **argv)\n \t/* test from simple to complex. */\n \tblock_test_main(argc, argv);\n \treadwrite_test_main(argc, argv);\n-\tstack_test_main(argc, argv);\n \treturn 0;\n }\n \ndiff --git a/reftable/stack_test.c b/t/unit-tests/t-reftable-stack.c\nsimilarity index 77%\nrename from reftable/stack_test.c\nrename to t/unit-tests/t-reftable-stack.c\nindex 8c36590ff0..cae86b4b91 100644\n--- a/reftable/stack_test.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -6,21 +6,18 @@ license that can be found in the LICENSE file or at\n https://developers.google.com/open-source/licenses/bsd\n */\n \n-#include \"stack.h\"\n-\n-#include \"system.h\"\n-\n-#include \"reftable-reader.h\"\n-#include \"merged.h\"\n-#include \"basics.h\"\n-#include \"record.h\"\n-#include \"test_framework.h\"\n-#include \"reftable-tests.h\"\n-#include \"reader.h\"\n-\n-#include <sys/types.h>\n+#include \"test-lib.h\"\n+#include \"reftable/merged.h\"\n+#include \"reftable/reader.h\"\n+#include \"reftable/reftable-error.h\"\n+#include \"reftable/stack.h\"\n #include <dirent.h>\n \n+static void set_test_hash(uint8_t *p, int i)\n+{\n+\tmemset(p, (uint8_t)i, hash_size(GIT_SHA1_FORMAT_ID));\n+}\n+\n static void clear_dir(const char *dirname)\n {\n \tstruct strbuf path = STRBUF_INIT;\n@@ -72,11 +69,11 @@ static char *get_tmp_template(int linenumber)\n static char *get_tmp_dir(int linenumber)\n {\n \tchar *dir = get_tmp_template(linenumber);\n-\tEXPECT(mkdtemp(dir));\n+\tcheck(mkdtemp(dir) != NULL);\n \treturn dir;\n }\n \n-static void test_read_file(void)\n+static void t_read_file(void)\n {\n \tchar *fn = get_tmp_template(__LINE__);\n \tint fd = mkstemp(fn);\n@@ -86,17 +83,17 @@ static void test_read_file(void)\n \tconst char *want[] = { \"line1\", \"line2\", \"line3\" };\n \tint i = 0;\n \n-\tEXPECT(fd > 0);\n+\tcheck_int(fd, >, 0);\n \tn = write_in_full(fd, out, strlen(out));\n-\tEXPECT(n == strlen(out));\n+\tcheck_int(n, ==, strlen(out));\n \terr = close(fd);\n-\tEXPECT(err >= 0);\n+\tcheck_int(err, >=, 0);\n \n \terr = read_lines(fn, &names);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; names[i]; i++) {\n-\t\tEXPECT(0 == strcmp(want[i], names[i]));\n+\t\tcheck_str(want[i], names[i]);\n \t}\n \tfree_names(names);\n \t(void) remove(fn);\n@@ -130,7 +127,7 @@ static void write_n_ref_tables(struct reftable_stack *st,\n \t\tset_test_hash(ref.value.val1, i);\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tst->opts.disable_auto_compact = disable_auto_compact;\n@@ -150,7 +147,7 @@ static int write_test_log(struct reftable_writer *wr, void *arg)\n \treturn reftable_writer_add_log(wr, wla->log);\n }\n \n-static void test_reftable_stack_add_one(void)\n+static void t_reftable_stack_add_one(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct strbuf scratch = STRBUF_INIT;\n@@ -169,29 +166,29 @@ static void test_reftable_stack_add_one(void)\n \tstruct reftable_ref_record dest = { NULL };\n \tstruct stat stat_result = { 0 };\n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(\"master\", dest.value.symref));\n-\tEXPECT(st->readers_len > 0);\n+\tcheck(!err);\n+\tcheck_str(\"master\", dest.value.symref);\n+\tcheck_int(st->readers_len, >, 0);\n \n \tprintf(\"testing print functionality:\\n\");\n \terr = reftable_stack_print_directory(dir, GIT_SHA1_FORMAT_ID);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_print_directory(dir, GIT_SHA256_FORMAT_ID);\n-\tEXPECT(err == REFTABLE_FORMAT_ERROR);\n+\tcheck_int(err, ==, REFTABLE_FORMAT_ERROR);\n \n #ifndef GIT_WINDOWS_NATIVE\n \tstrbuf_addstr(&scratch, dir);\n \tstrbuf_addstr(&scratch, \"/tables.list\");\n \terr = stat(scratch.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n \n \tstrbuf_reset(&scratch);\n \tstrbuf_addstr(&scratch, dir);\n@@ -199,8 +196,8 @@ static void test_reftable_stack_add_one(void)\n \t/* do not try at home; not an external API for reftable. */\n \tstrbuf_addstr(&scratch, st->readers[0]->name);\n \terr = stat(scratch.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n #else\n \t(void) stat_result;\n #endif\n@@ -212,7 +209,7 @@ static void test_reftable_stack_add_one(void)\n \tumask(mask);\n }\n \n-static void test_reftable_stack_uptodate(void)\n+static void t_reftable_stack_uptodate(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL;\n@@ -238,28 +235,28 @@ static void test_reftable_stack_uptodate(void)\n \t   by creating two stacks for the same directory.\n \t */\n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st1, &write_test_ref, &ref1);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n-\tEXPECT(err == REFTABLE_OUTDATED_ERROR);\n+\tcheck_int(err, ==, REFTABLE_OUTDATED_ERROR);\n \n \terr = reftable_stack_reload(st2);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_transaction_api(void)\n+static void t_reftable_stack_transaction_api(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -276,32 +273,32 @@ static void test_reftable_stack_transaction_api(void)\n \tstruct reftable_ref_record dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_addition_destroy(add);\n \n \terr = reftable_stack_new_addition(&add, st);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_addition_add(add, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_addition_commit(add);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_addition_destroy(add);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(REFTABLE_REF_SYMREF == dest.value_type);\n-\tEXPECT(0 == strcmp(\"master\", dest.value.symref));\n+\tcheck(!err);\n+\tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n+\tcheck_str(\"master\", dest.value.symref);\n \n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n+static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = {0};\n@@ -310,7 +307,7 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \tint i, n = 20, err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n@@ -331,13 +328,13 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\tst->opts.disable_auto_compact = i != n;\n \n \t\terr = reftable_stack_new_addition(&add, st);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_addition_add(add, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_addition_commit(add);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\treftable_addition_destroy(add);\n \n@@ -347,16 +344,16 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\t * all tables in the stack.\n \t\t */\n \t\tif (i != n)\n-\t\t\tEXPECT(st->merged->stack_len == i + 1);\n+\t\t\tcheck_int(st->merged->stack_len, ==, i + 1);\n \t\telse\n-\t\t\tEXPECT(st->merged->stack_len == 1);\n+\t\t\tcheck_int(st->merged->stack_len, ==, 1);\n \t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n+static void t_reftable_stack_auto_compaction_fails_gracefully(void)\n {\n \tstruct reftable_ref_record ref = {\n \t\t.refname = (char *) \"refs/heads/master\",\n@@ -371,13 +368,13 @@ static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->merged->stack_len == 1);\n-\tEXPECT(st->stats.attempts == 0);\n-\tEXPECT(st->stats.failures == 0);\n+\tcheck(!err);\n+\tcheck_int(st->merged->stack_len, ==, 1);\n+\tcheck_int(st->stats.attempts, ==, 0);\n+\tcheck_int(st->stats.failures, ==, 0);\n \n \t/*\n \t * Lock the newly written table such that it cannot be compacted.\n@@ -389,10 +386,10 @@ static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n \n \tref.update_index = 2;\n \terr = reftable_stack_add(st, write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->merged->stack_len == 2);\n-\tEXPECT(st->stats.attempts == 1);\n-\tEXPECT(st->stats.failures == 1);\n+\tcheck(!err);\n+\tcheck_int(st->merged->stack_len, ==, 2);\n+\tcheck_int(st->stats.attempts, ==, 1);\n+\tcheck_int(st->stats.failures, ==, 1);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&table_path);\n@@ -404,7 +401,7 @@ static int write_error(struct reftable_writer *wr, void *arg)\n \treturn *((int *)arg);\n }\n \n-static void test_reftable_stack_update_index_check(void)\n+static void t_reftable_stack_update_index_check(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -424,18 +421,18 @@ static void test_reftable_stack_update_index_check(void)\n \t};\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref1);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref2);\n-\tEXPECT(err == REFTABLE_API_ERROR);\n+\tcheck_int(err, ==, REFTABLE_API_ERROR);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_lock_failure(void)\n+static void t_reftable_stack_lock_failure(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -443,17 +440,17 @@ static void test_reftable_stack_lock_failure(void)\n \tint err, i;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \tfor (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) {\n \t\terr = reftable_stack_add(st, &write_error, &i);\n-\t\tEXPECT(err == i);\n+\t\tcheck_int(err, ==, i);\n \t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_add(void)\n+static void t_reftable_stack_add(void)\n {\n \tint i = 0;\n \tint err = 0;\n@@ -471,7 +468,7 @@ static void test_reftable_stack_add(void)\n \tint N = ARRAY_SIZE(refs);\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar buf[256];\n@@ -490,7 +487,7 @@ static void test_reftable_stack_add(void)\n \n \tfor (i = 0; i < N; i++) {\n \t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tfor (i = 0; i < N; i++) {\n@@ -499,18 +496,18 @@ static void test_reftable_stack_add(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tstruct reftable_ref_record dest = { NULL };\n \n \t\tint err = reftable_stack_read_ref(st, refs[i].refname, &dest);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(reftable_ref_record_equal(&dest, refs + i,\n+\t\tcheck(!err);\n+\t\tcheck(reftable_ref_record_equal(&dest, refs + i,\n \t\t\t\t\t\t GIT_SHA1_RAWSZ));\n \t\treftable_ref_record_release(&dest);\n \t}\n@@ -518,8 +515,8 @@ static void test_reftable_stack_add(void)\n \tfor (i = 0; i < N; i++) {\n \t\tstruct reftable_log_record dest = { NULL };\n \t\tint err = reftable_stack_read_log(st, refs[i].refname, &dest);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(reftable_log_record_equal(&dest, logs + i,\n+\t\tcheck(!err);\n+\t\tcheck(reftable_log_record_equal(&dest, logs + i,\n \t\t\t\t\t\t GIT_SHA1_RAWSZ));\n \t\treftable_log_record_release(&dest);\n \t}\n@@ -528,8 +525,8 @@ static void test_reftable_stack_add(void)\n \tstrbuf_addstr(&path, dir);\n \tstrbuf_addstr(&path, \"/tables.list\");\n \terr = stat(path.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n \n \tstrbuf_reset(&path);\n \tstrbuf_addstr(&path, dir);\n@@ -537,8 +534,8 @@ static void test_reftable_stack_add(void)\n \t/* do not try at home; not an external API for reftable. */\n \tstrbuf_addstr(&path, st->readers[0]->name);\n \terr = stat(path.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n #else\n \t(void) stat_result;\n #endif\n@@ -553,7 +550,7 @@ static void test_reftable_stack_add(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_log_normalize(void)\n+static void t_reftable_stack_log_normalize(void)\n {\n \tint err = 0;\n \tstruct reftable_write_options opts = {\n@@ -581,27 +578,27 @@ static void test_reftable_stack_log_normalize(void)\n \t};\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tinput.value.update.message = (char *) \"one\\ntwo\";\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT(err == REFTABLE_API_ERROR);\n+\tcheck_int(err, ==, REFTABLE_API_ERROR);\n \n \tinput.value.update.message = (char *) \"one\";\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, input.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(dest.value.update.message, \"one\\n\"));\n+\tcheck(!err);\n+\tcheck_str(dest.value.update.message, \"one\\n\");\n \n \tinput.value.update.message = (char *) \"two\\n\";\n \targ.update_index = 2;\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \terr = reftable_stack_read_log(st, input.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(dest.value.update.message, \"two\\n\"));\n+\tcheck(!err);\n+\tcheck_str(dest.value.update.message, \"two\\n\");\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n@@ -609,7 +606,7 @@ static void test_reftable_stack_log_normalize(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_tombstone(void)\n+static void t_reftable_stack_tombstone(void)\n {\n \tint i = 0;\n \tchar *dir = get_tmp_dir(__LINE__);\n@@ -623,7 +620,7 @@ static void test_reftable_stack_tombstone(void)\n \tstruct reftable_log_record log_dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* even entries add the refs, odd entries delete them. */\n \tfor (i = 0; i < N; i++) {\n@@ -647,7 +644,7 @@ static void test_reftable_stack_tombstone(void)\n \t}\n \tfor (i = 0; i < N; i++) {\n \t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tfor (i = 0; i < N; i++) {\n@@ -656,25 +653,25 @@ static void test_reftable_stack_tombstone(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_read_ref(st, \"branch\", &dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_ref_record_release(&dest);\n \n \terr = reftable_stack_read_log(st, \"branch\", &log_dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_log_record_release(&log_dest);\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, \"branch\", &dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, \"branch\", &log_dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_ref_record_release(&dest);\n \treftable_log_record_release(&log_dest);\n \n@@ -687,7 +684,7 @@ static void test_reftable_stack_tombstone(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_hash_id(void)\n+static void t_reftable_stack_hash_id(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -707,47 +704,47 @@ static void test_reftable_stack_hash_id(void)\n \tstruct reftable_ref_record dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* can't read it with the wrong hash ID. */\n \terr = reftable_new_stack(&st32, dir, &opts32);\n-\tEXPECT(err == REFTABLE_FORMAT_ERROR);\n+\tcheck_int(err, ==, REFTABLE_FORMAT_ERROR);\n \n \t/* check that we can read it back with default opts too. */\n \terr = reftable_new_stack(&st_default, dir, &opts_default);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st_default, \"master\", &dest);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n-\tEXPECT(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n \treftable_stack_destroy(st_default);\n \tclear_dir(dir);\n }\n \n-static void test_suggest_compaction_segment(void)\n+static void t_suggest_compaction_segment(void)\n {\n \tuint64_t sizes[] = { 512, 64, 17, 16, 9, 9, 9, 16, 2, 16 };\n \tstruct segment min =\n \t\tsuggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);\n-\tEXPECT(min.start == 1);\n-\tEXPECT(min.end == 10);\n+\tcheck_int(min.start, ==, 1);\n+\tcheck_int(min.end, ==, 10);\n }\n \n-static void test_suggest_compaction_segment_nothing(void)\n+static void t_suggest_compaction_segment_nothing(void)\n {\n \tuint64_t sizes[] = { 64, 32, 16, 8, 4, 2 };\n \tstruct segment result =\n \t\tsuggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);\n-\tEXPECT(result.start == result.end);\n+\tcheck_int(result.start, ==, result.end);\n }\n \n-static void test_reflog_expire(void)\n+static void t_reflog_expire(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -762,7 +759,7 @@ static void test_reflog_expire(void)\n \tstruct reftable_log_record log = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 1; i <= N; i++) {\n \t\tchar buf[256];\n@@ -782,30 +779,30 @@ static void test_reflog_expire(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st, &expiry);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, logs[9].refname, &log);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, logs[11].refname, &log);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \texpiry.min_update_index = 15;\n \terr = reftable_stack_compact_all(st, &expiry);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, logs[14].refname, &log);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, logs[16].refname, &log);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n@@ -822,7 +819,7 @@ static int write_nothing(struct reftable_writer *wr, void *arg)\n \treturn 0;\n }\n \n-static void test_empty_add(void)\n+static void t_empty_add(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -831,13 +828,13 @@ static void test_empty_add(void)\n \tstruct reftable_stack *st2 = NULL;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_nothing, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \tclear_dir(dir);\n \treftable_stack_destroy(st);\n \treftable_stack_destroy(st2);\n@@ -853,7 +850,7 @@ static int fastlog2(uint64_t sz)\n \treturn l - 1;\n }\n \n-static void test_reftable_stack_auto_compaction(void)\n+static void t_reftable_stack_auto_compaction(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -864,7 +861,7 @@ static void test_reftable_stack_auto_compaction(void)\n \tint N = 100;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar name[100];\n@@ -877,21 +874,21 @@ static void test_reftable_stack_auto_compaction(void)\n \t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_stack_auto_compact(st);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(i < 3 || st->merged->stack_len < 2 * fastlog2(i));\n+\t\tcheck(!err);\n+\t\tcheck(i < 3 || st->merged->stack_len < 2 * fastlog2(i));\n \t}\n \n-\tEXPECT(reftable_stack_compaction_stats(st)->entries_written <\n+\tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n \t       (uint64_t)(N * fastlog2(N)));\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n+static void t_reftable_stack_auto_compaction_with_locked_tables(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -902,10 +899,10 @@ static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \twrite_n_ref_tables(st, 5);\n-\tEXPECT(st->merged->stack_len == 5);\n+\tcheck_int(st->merged->stack_len, ==, 5);\n \n \t/*\n \t * Given that all tables we have written should be roughly the same\n@@ -923,16 +920,16 @@ static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n \t * only compact the newest two tables.\n \t */\n \terr = reftable_stack_auto_compact(st);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->stats.failures == 0);\n-\tEXPECT(st->merged->stack_len == 4);\n+\tcheck(!err);\n+\tcheck_int(st->stats.failures, ==, 0);\n+\tcheck_int(st->merged->stack_len, ==, 4);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&buf);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_add_performs_auto_compaction(void)\n+static void t_reftable_stack_add_performs_auto_compaction(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -941,7 +938,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \tint err, i, n = 20;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n@@ -962,7 +959,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \t\tref.refname = refname.buf;\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\t/*\n \t\t * The stack length should grow continuously for all runs where\n@@ -970,9 +967,9 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \t\t * all tables in the stack.\n \t\t */\n \t\tif (i != n)\n-\t\t\tEXPECT(st->merged->stack_len == i + 1);\n+\t\t\tcheck_int(st->merged->stack_len, ==, i + 1);\n \t\telse\n-\t\t\tEXPECT(st->merged->stack_len == 1);\n+\t\t\tcheck_int(st->merged->stack_len, ==, 1);\n \t}\n \n \treftable_stack_destroy(st);\n@@ -980,7 +977,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_compaction_with_locked_tables(void)\n+static void t_reftable_stack_compaction_with_locked_tables(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -991,10 +988,10 @@ static void test_reftable_stack_compaction_with_locked_tables(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \twrite_n_ref_tables(st, 3);\n-\tEXPECT(st->merged->stack_len == 3);\n+\tcheck_int(st->merged->stack_len, ==, 3);\n \n \t/* Lock one of the tables that we're about to compact. */\n \tstrbuf_reset(&buf);\n@@ -1006,16 +1003,16 @@ static void test_reftable_stack_compaction_with_locked_tables(void)\n \t * compact all tables.\n \t */\n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT(err == REFTABLE_LOCK_ERROR);\n-\tEXPECT(st->stats.failures == 1);\n-\tEXPECT(st->merged->stack_len == 3);\n+\tcheck_int(err, ==, REFTABLE_LOCK_ERROR);\n+\tcheck_int(st->stats.failures, ==, 1);\n+\tcheck_int(st->merged->stack_len, ==, 3);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&buf);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_compaction_concurrent(void)\n+static void t_reftable_stack_compaction_concurrent(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL;\n@@ -1023,19 +1020,19 @@ static void test_reftable_stack_compaction_concurrent(void)\n \tint err;\n \n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st1, 3);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st1, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n \n-\tEXPECT(count_dir_entries(dir) == 2);\n+\tcheck_int(count_dir_entries(dir), ==, 2);\n \tclear_dir(dir);\n }\n \n@@ -1050,7 +1047,7 @@ static void unclean_stack_close(struct reftable_stack *st)\n \tFREE_AND_NULL(st->readers);\n }\n \n-static void test_reftable_stack_compaction_concurrent_clean(void)\n+static void t_reftable_stack_compaction_concurrent_clean(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL, *st3 = NULL;\n@@ -1058,24 +1055,24 @@ static void test_reftable_stack_compaction_concurrent_clean(void)\n \tint err;\n \n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st1, 3);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st1, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tunclean_stack_close(st1);\n \tunclean_stack_close(st2);\n \n \terr = reftable_new_stack(&st3, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_clean(st3);\n-\tEXPECT_ERR(err);\n-\tEXPECT(count_dir_entries(dir) == 2);\n+\tcheck(!err);\n+\tcheck_int(count_dir_entries(dir), ==, 2);\n \n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n@@ -1084,29 +1081,30 @@ static void test_reftable_stack_compaction_concurrent_clean(void)\n \tclear_dir(dir);\n }\n \n-int stack_test_main(int argc, const char *argv[])\n+int cmd_main(int argc, const char *argv[])\n {\n-\tRUN_TEST(test_empty_add);\n-\tRUN_TEST(test_read_file);\n-\tRUN_TEST(test_reflog_expire);\n-\tRUN_TEST(test_reftable_stack_add);\n-\tRUN_TEST(test_reftable_stack_add_one);\n-\tRUN_TEST(test_reftable_stack_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_auto_compaction_with_locked_tables);\n-\tRUN_TEST(test_reftable_stack_add_performs_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_compaction_concurrent);\n-\tRUN_TEST(test_reftable_stack_compaction_concurrent_clean);\n-\tRUN_TEST(test_reftable_stack_compaction_with_locked_tables);\n-\tRUN_TEST(test_reftable_stack_hash_id);\n-\tRUN_TEST(test_reftable_stack_lock_failure);\n-\tRUN_TEST(test_reftable_stack_log_normalize);\n-\tRUN_TEST(test_reftable_stack_tombstone);\n-\tRUN_TEST(test_reftable_stack_transaction_api);\n-\tRUN_TEST(test_reftable_stack_transaction_api_performs_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_auto_compaction_fails_gracefully);\n-\tRUN_TEST(test_reftable_stack_update_index_check);\n-\tRUN_TEST(test_reftable_stack_uptodate);\n-\tRUN_TEST(test_suggest_compaction_segment);\n-\tRUN_TEST(test_suggest_compaction_segment_nothing);\n-\treturn 0;\n+\tTEST(t_empty_add(), \"empty addition to stack\");\n+\tTEST(t_read_file(), \"read_lines works\");\n+\tTEST(t_reflog_expire(), \"expire reflog entries\");\n+\tTEST(t_reftable_stack_add(), \"add multiple refs and logs to stack\");\n+\tTEST(t_reftable_stack_add_one(), \"add a single ref record to stack\");\n+\tTEST(t_reftable_stack_add_performs_auto_compaction(), \"addition to stack triggers auto-compaction\");\n+\tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_fails_gracefully(), \"failure on auto-compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_with_locked_tables(), \"auto compaction with locked tables\");\n+\tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n+\tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n+\tTEST(t_reftable_stack_compaction_with_locked_tables(), \"compaction with locked tables\");\n+\tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n+\tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n+\tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n+\tTEST(t_reftable_stack_tombstone(), \"'tombstone' refs in stack\");\n+\tTEST(t_reftable_stack_transaction_api(), \"update transaction to stack\");\n+\tTEST(t_reftable_stack_transaction_api_performs_auto_compaction(), \"update transaction triggers auto-compaction\");\n+\tTEST(t_reftable_stack_update_index_check(), \"update transactions with equal update indices\");\n+\tTEST(t_reftable_stack_uptodate(), \"stack must be reloaded before ref update\");\n+\tTEST(t_suggest_compaction_segment(), \"suggest_compaction_segment with basic input\");\n+\tTEST(t_suggest_compaction_segment_nothing(), \"suggest_compaction_segment with pre-compacted input\");\n+\n+\treturn test_done();\n }\n-- \n2.45.GIT\n\n"},{"id":"501584","messageId":"20240823120514.11070-3-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240823120514.11070-1-chandrapratap3519@gmail.com","subject":"[PATCH v2 2/6] t: harmonize t-reftable-stack.c with coding guidelines","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-23T11:48:47Z","receivedAt":"2024-08-23T12:06:01Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"Harmonize the newly ported test unit-tests/t-reftable-stack.c\nwith the following guidelines:\n- Single line 'for' statements must omit curly braces.\n- Structs must be 0-initialized with '= { 0 }' instead of '= { NULL }'.\n- Array sizes and indices should preferably be of type 'size_t' and\n  not 'int'.\n- Function pointers should be passed as 'func' and not '&func'.\n\nWhile at it, remove initialization for those variables that are\nre-used multiple times, like loop variables.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 114 +++++++++++++++-----------------\n 1 file changed, 54 insertions(+), 60 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex cae86b4b91..c0acd7502c 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -81,7 +81,6 @@ static void t_read_file(void)\n \tint n, err;\n \tchar **names = NULL;\n \tconst char *want[] = { \"line1\", \"line2\", \"line3\" };\n-\tint i = 0;\n \n \tcheck_int(fd, >, 0);\n \tn = write_in_full(fd, out, strlen(out));\n@@ -92,9 +91,8 @@ static void t_read_file(void)\n \terr = read_lines(fn, &names);\n \tcheck(!err);\n \n-\tfor (i = 0; names[i]; i++) {\n+\tfor (size_t i = 0; names[i]; i++)\n \t\tcheck_str(want[i], names[i]);\n-\t}\n \tfree_names(names);\n \t(void) remove(fn);\n }\n@@ -122,7 +120,7 @@ static void write_n_ref_tables(struct reftable_stack *st,\n \t\t\t.value_type = REFTABLE_REF_VAL1,\n \t\t};\n \n-\t\tstrbuf_addf(&buf, \"refs/heads/branch-%04u\", (unsigned) i);\n+\t\tstrbuf_addf(&buf, \"refs/heads/branch-%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = buf.buf;\n \t\tset_test_hash(ref.value.val1, i);\n \n@@ -163,12 +161,12 @@ static void t_reftable_stack_add_one(void)\n \t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t.value.symref = (char *) \"master\",\n \t};\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \tstruct stat stat_result = { 0 };\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\terr = reftable_stack_add(st, write_test_ref, &ref);\n \tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n@@ -240,16 +238,16 @@ static void t_reftable_stack_uptodate(void)\n \terr = reftable_new_stack(&st2, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st1, &write_test_ref, &ref1);\n+\terr = reftable_stack_add(st1, write_test_ref, &ref1);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st2, write_test_ref, &ref2);\n \tcheck_int(err, ==, REFTABLE_OUTDATED_ERROR);\n \n \terr = reftable_stack_reload(st2);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st2, write_test_ref, &ref2);\n \tcheck(!err);\n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n@@ -270,7 +268,7 @@ static void t_reftable_stack_transaction_api(void)\n \t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t.value.symref = (char *) \"master\",\n \t};\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -280,7 +278,7 @@ static void t_reftable_stack_transaction_api(void)\n \terr = reftable_stack_new_addition(&add, st);\n \tcheck(!err);\n \n-\terr = reftable_addition_add(add, &write_test_ref, &ref);\n+\terr = reftable_addition_add(add, write_test_ref, &ref);\n \tcheck(!err);\n \n \terr = reftable_addition_commit(add);\n@@ -304,12 +302,13 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \tstruct reftable_write_options opts = {0};\n \tstruct reftable_addition *add = NULL;\n \tstruct reftable_stack *st = NULL;\n-\tint i, n = 20, err;\n+\tsize_t n = 20;\n+\tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\tfor (i = 0; i <= n; i++) {\n+\tfor (size_t i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t\t.value_type = REFTABLE_REF_SYMREF,\n@@ -317,7 +316,7 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\t};\n \t\tchar name[100];\n \n-\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = name;\n \n \t\t/*\n@@ -330,7 +329,7 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\terr = reftable_stack_new_addition(&add, st);\n \t\tcheck(!err);\n \n-\t\terr = reftable_addition_add(add, &write_test_ref, &ref);\n+\t\terr = reftable_addition_add(add, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\terr = reftable_addition_commit(add);\n@@ -361,7 +360,7 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void)\n \t\t.value_type = REFTABLE_REF_VAL1,\n \t\t.value.val1 = {0x01},\n \t};\n-\tstruct reftable_write_options opts = {0};\n+\tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st;\n \tstruct strbuf table_path = STRBUF_INIT;\n \tchar *dir = get_tmp_dir(__LINE__);\n@@ -423,10 +422,10 @@ static void t_reftable_stack_update_index_check(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref1);\n+\terr = reftable_stack_add(st, write_test_ref, &ref1);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st, write_test_ref, &ref2);\n \tcheck_int(err, ==, REFTABLE_API_ERROR);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n@@ -442,7 +441,7 @@ static void t_reftable_stack_lock_failure(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \tfor (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) {\n-\t\terr = reftable_stack_add(st, &write_error, &i);\n+\t\terr = reftable_stack_add(st, write_error, &i);\n \t\tcheck_int(err, ==, i);\n \t}\n \n@@ -452,7 +451,6 @@ static void t_reftable_stack_lock_failure(void)\n \n static void t_reftable_stack_add(void)\n {\n-\tint i = 0;\n \tint err = 0;\n \tstruct reftable_write_options opts = {\n \t\t.exact_log_message = 1,\n@@ -461,18 +459,18 @@ static void t_reftable_stack_add(void)\n \t};\n \tstruct reftable_stack *st = NULL;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tstruct reftable_ref_record refs[2] = { { NULL } };\n-\tstruct reftable_log_record logs[2] = { { NULL } };\n+\tstruct reftable_ref_record refs[2] = { 0 };\n+\tstruct reftable_log_record logs[2] = { 0 };\n \tstruct strbuf path = STRBUF_INIT;\n \tstruct stat stat_result;\n-\tint N = ARRAY_SIZE(refs);\n+\tsize_t i, N = ARRAY_SIZE(refs);\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar buf[256];\n-\t\tsnprintf(buf, sizeof(buf), \"branch%02d\", i);\n+\t\tsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n \t\trefs[i].refname = xstrdup(buf);\n \t\trefs[i].update_index = i + 1;\n \t\trefs[i].value_type = REFTABLE_REF_VAL1;\n@@ -486,7 +484,7 @@ static void t_reftable_stack_add(void)\n \t}\n \n \tfor (i = 0; i < N; i++) {\n-\t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n+\t\tint err = reftable_stack_add(st, write_test_ref, &refs[i]);\n \t\tcheck(!err);\n \t}\n \n@@ -495,7 +493,7 @@ static void t_reftable_stack_add(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -503,7 +501,7 @@ static void t_reftable_stack_add(void)\n \tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n-\t\tstruct reftable_ref_record dest = { NULL };\n+\t\tstruct reftable_ref_record dest = { 0 };\n \n \t\tint err = reftable_stack_read_ref(st, refs[i].refname, &dest);\n \t\tcheck(!err);\n@@ -513,7 +511,7 @@ static void t_reftable_stack_add(void)\n \t}\n \n \tfor (i = 0; i < N; i++) {\n-\t\tstruct reftable_log_record dest = { NULL };\n+\t\tstruct reftable_log_record dest = { 0 };\n \t\tint err = reftable_stack_read_log(st, refs[i].refname, &dest);\n \t\tcheck(!err);\n \t\tcheck(reftable_log_record_equal(&dest, logs + i,\n@@ -581,11 +579,11 @@ static void t_reftable_stack_log_normalize(void)\n \tcheck(!err);\n \n \tinput.value.update.message = (char *) \"one\\ntwo\";\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck_int(err, ==, REFTABLE_API_ERROR);\n \n \tinput.value.update.message = (char *) \"one\";\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck(!err);\n \n \terr = reftable_stack_read_log(st, input.refname, &dest);\n@@ -594,7 +592,7 @@ static void t_reftable_stack_log_normalize(void)\n \n \tinput.value.update.message = (char *) \"two\\n\";\n \targ.update_index = 2;\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck(!err);\n \terr = reftable_stack_read_log(st, input.refname, &dest);\n \tcheck(!err);\n@@ -608,16 +606,15 @@ static void t_reftable_stack_log_normalize(void)\n \n static void t_reftable_stack_tombstone(void)\n {\n-\tint i = 0;\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n \tint err;\n-\tstruct reftable_ref_record refs[2] = { { NULL } };\n-\tstruct reftable_log_record logs[2] = { { NULL } };\n-\tint N = ARRAY_SIZE(refs);\n-\tstruct reftable_ref_record dest = { NULL };\n-\tstruct reftable_log_record log_dest = { NULL };\n+\tstruct reftable_ref_record refs[2] = { 0 };\n+\tstruct reftable_log_record logs[2] = { 0 };\n+\tsize_t i, N = ARRAY_SIZE(refs);\n+\tstruct reftable_ref_record dest = { 0 };\n+\tstruct reftable_log_record log_dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -643,7 +640,7 @@ static void t_reftable_stack_tombstone(void)\n \t\t}\n \t}\n \tfor (i = 0; i < N; i++) {\n-\t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n+\t\tint err = reftable_stack_add(st, write_test_ref, &refs[i]);\n \t\tcheck(!err);\n \t}\n \n@@ -652,7 +649,7 @@ static void t_reftable_stack_tombstone(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -701,12 +698,12 @@ static void t_reftable_stack_hash_id(void)\n \tstruct reftable_stack *st32 = NULL;\n \tstruct reftable_write_options opts_default = { 0 };\n \tstruct reftable_stack *st_default = NULL;\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\terr = reftable_stack_add(st, write_test_ref, &ref);\n \tcheck(!err);\n \n \t/* can't read it with the wrong hash ID. */\n@@ -749,21 +746,20 @@ static void t_reflog_expire(void)\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n-\tstruct reftable_log_record logs[20] = { { NULL } };\n-\tint N = ARRAY_SIZE(logs) - 1;\n-\tint i = 0;\n+\tstruct reftable_log_record logs[20] = { 0 };\n+\tsize_t i, N = ARRAY_SIZE(logs) - 1;\n \tint err;\n \tstruct reftable_log_expiry_config expiry = {\n \t\t.time = 10,\n \t};\n-\tstruct reftable_log_record log = { NULL };\n+\tstruct reftable_log_record log = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n \tfor (i = 1; i <= N; i++) {\n \t\tchar buf[256];\n-\t\tsnprintf(buf, sizeof(buf), \"branch%02d\", i);\n+\t\tsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n \n \t\tlogs[i].refname = xstrdup(buf);\n \t\tlogs[i].update_index = i;\n@@ -778,7 +774,7 @@ static void t_reflog_expire(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -806,9 +802,8 @@ static void t_reflog_expire(void)\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n-\tfor (i = 0; i <= N; i++) {\n+\tfor (i = 0; i <= N; i++)\n \t\treftable_log_record_release(&logs[i]);\n-\t}\n \tclear_dir(dir);\n \treftable_log_record_release(&log);\n }\n@@ -830,7 +825,7 @@ static void t_empty_add(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_nothing, NULL);\n+\terr = reftable_stack_add(st, write_nothing, NULL);\n \tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n@@ -857,8 +852,8 @@ static void t_reftable_stack_auto_compaction(void)\n \t};\n \tstruct reftable_stack *st = NULL;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tint err, i;\n-\tint N = 100;\n+\tint err;\n+\tsize_t i, N = 100;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -871,9 +866,9 @@ static void t_reftable_stack_auto_compaction(void)\n \t\t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t\t.value.symref = (char *) \"master\",\n \t\t};\n-\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n \n-\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\terr = reftable_stack_add(st, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\terr = reftable_stack_auto_compact(st);\n@@ -935,7 +930,8 @@ static void t_reftable_stack_add_performs_auto_compaction(void)\n \tstruct reftable_stack *st = NULL;\n \tstruct strbuf refname = STRBUF_INIT;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tint err, i, n = 20;\n+\tint err;\n+\tsize_t i, n = 20;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -955,10 +951,10 @@ static void t_reftable_stack_add_performs_auto_compaction(void)\n \t\tst->opts.disable_auto_compact = i != n;\n \n \t\tstrbuf_reset(&refname);\n-\t\tstrbuf_addf(&refname, \"branch-%04d\", i);\n+\t\tstrbuf_addf(&refname, \"branch-%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = refname.buf;\n \n-\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\terr = reftable_stack_add(st, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\t/*\n@@ -1039,10 +1035,8 @@ static void t_reftable_stack_compaction_concurrent(void)\n static void unclean_stack_close(struct reftable_stack *st)\n {\n \t/* break abstraction boundary to simulate unclean shutdown. */\n-\tint i = 0;\n-\tfor (; i < st->readers_len; i++) {\n+\tfor (int i = 0; i < st->readers_len; i++)\n \t\treftable_reader_free(st->readers[i]);\n-\t}\n \tst->readers_len = 0;\n \tFREE_AND_NULL(st->readers);\n }\n-- \n2.45.GIT\n\n"},{"id":"501585","messageId":"20240823120514.11070-4-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240823120514.11070-1-chandrapratap3519@gmail.com","subject":"[PATCH v2 3/6] t-reftable-stack: use Git's tempfile API instead of mkstemp()","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-23T11:48:48Z","receivedAt":"2024-08-23T12:06:04Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"Git's tempfile API defined by $GIT_DIR/tempfile.{c,h} provides\na unified interface for tempfile operations. Since reftable/stack.c\nuses this API for all its tempfile needs instead of raw functions\nlike mkstemp(), make the ported stack test strictly use Git's\ntempfile API as well.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex c0acd7502c..917d059fca 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -76,7 +76,8 @@ static char *get_tmp_dir(int linenumber)\n static void t_read_file(void)\n {\n \tchar *fn = get_tmp_template(__LINE__);\n-\tint fd = mkstemp(fn);\n+\tstruct tempfile *tmp = mks_tempfile(fn);\n+\tint fd = get_tempfile_fd(tmp);\n \tchar out[1024] = \"line1\\n\\nline2\\nline3\";\n \tint n, err;\n \tchar **names = NULL;\n@@ -95,6 +96,7 @@ static void t_read_file(void)\n \t\tcheck_str(want[i], names[i]);\n \tfree_names(names);\n \t(void) remove(fn);\n+\tdelete_tempfile(&tmp);\n }\n \n static int write_test_ref(struct reftable_writer *wr, void *arg)\n-- \n2.45.GIT\n\n"},{"id":"501586","messageId":"20240823120514.11070-5-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240823120514.11070-1-chandrapratap3519@gmail.com","subject":"[PATCH v2 4/6] t-reftable-stack: use reftable_ref_record_equal() to compare ref records","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-23T11:48:49Z","receivedAt":"2024-08-23T12:06:07Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"In the current stack tests, ref records are compared for equality\nby sometimes using the dedicated function for ref-record comparison,\nreftable_ref_record_equal(), and sometimes by explicity comparing\ncontents of the ref records.\n\nReplace the latter instances of ref-record comparison with the\nformer to maintain uniformity throughout the test file.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 917d059fca..7c76aa67fb 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -173,7 +173,7 @@ static void t_reftable_stack_add_one(void)\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n \tcheck(!err);\n-\tcheck_str(\"master\", dest.value.symref);\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \tcheck_int(st->readers_len, >, 0);\n \n \tprintf(\"testing print functionality:\\n\");\n@@ -291,7 +291,7 @@ static void t_reftable_stack_transaction_api(void)\n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n \tcheck(!err);\n \tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n-\tcheck_str(\"master\", dest.value.symref);\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n-- \n2.45.GIT\n\n"},{"id":"501587","messageId":"20240823120514.11070-6-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240823120514.11070-1-chandrapratap3519@gmail.com","subject":"[PATCH v2 5/6] t-reftable-stack: add test for non-default compaction factor","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-23T11:48:50Z","receivedAt":"2024-08-23T12:06:10Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"In a recent codebase update (commit ae8e378430, merge branch\n'ps/reftable-write-options', 2024/05/13) the geometric factor used\nin auto-compaction of reftable tables was made configurable. Add\na test to verify the functionality introduced by this update.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 41 +++++++++++++++++++++++++++++----\n 1 file changed, 37 insertions(+), 4 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 7c76aa67fb..51339a9939 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -837,12 +837,12 @@ static void t_empty_add(void)\n \treftable_stack_destroy(st2);\n }\n \n-static int fastlog2(uint64_t sz)\n+static int fastlogN(uint64_t sz, uint64_t N)\n {\n \tint l = 0;\n \tif (sz == 0)\n \t\treturn 0;\n-\tfor (; sz; sz /= 2)\n+\tfor (; sz; sz /= N)\n \t\tl++;\n \treturn l - 1;\n }\n@@ -875,11 +875,43 @@ static void t_reftable_stack_auto_compaction(void)\n \n \t\terr = reftable_stack_auto_compact(st);\n \t\tcheck(!err);\n-\t\tcheck(i < 3 || st->merged->stack_len < 2 * fastlog2(i));\n+\t\tcheck(i < 2 || st->merged->stack_len < 2 * fastlogN(i, 2));\n \t}\n \n \tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n-\t       (uint64_t)(N * fastlog2(N)));\n+\t       (uint64_t)(N * fastlogN(N, 2)));\n+\n+\treftable_stack_destroy(st);\n+\tclear_dir(dir);\n+}\n+\n+static void t_reftable_stack_auto_compaction_factor(void)\n+{\n+\tstruct reftable_write_options opts = {\n+\t\t.auto_compaction_factor = 5,\n+\t};\n+\tstruct reftable_stack *st = NULL;\n+\tchar *dir = get_tmp_dir(__LINE__);\n+\tint err;\n+\tsize_t N = 100;\n+\n+\terr = reftable_new_stack(&st, dir, &opts);\n+\tcheck(!err);\n+\n+\tfor (size_t i = 0; i < N; i++) {\n+\t\tchar name[20];\n+\t\tstruct reftable_ref_record ref = {\n+\t\t\t.refname = name,\n+\t\t\t.update_index = reftable_stack_next_update_index(st),\n+\t\t\t.value_type = REFTABLE_REF_VAL1,\n+\t\t};\n+\t\txsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n+\n+\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\tcheck(!err);\n+\n+\t\tcheck(i < 5 || st->merged->stack_len < 5 * fastlogN(i, 5));\n+\t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n@@ -1086,6 +1118,7 @@ int cmd_main(int argc, const char *argv[])\n \tTEST(t_reftable_stack_add_one(), \"add a single ref record to stack\");\n \tTEST(t_reftable_stack_add_performs_auto_compaction(), \"addition to stack triggers auto-compaction\");\n \tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_factor(), \"auto-compaction with non-default geometric factor\");\n \tTEST(t_reftable_stack_auto_compaction_fails_gracefully(), \"failure on auto-compaction\");\n \tTEST(t_reftable_stack_auto_compaction_with_locked_tables(), \"auto compaction with locked tables\");\n \tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n-- \n2.45.GIT\n\n"},{"id":"501588","messageId":"20240823120514.11070-7-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240823120514.11070-1-chandrapratap3519@gmail.com","subject":"[PATCH v2 6/6] t-reftable-stack: add test for stack iterators","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-23T11:48:51Z","receivedAt":"2024-08-23T12:06:12Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"reftable_stack_init_ref_iterator and reftable_stack_init_log_iterator\nas defined by reftable/stack.{c,h} initialize a stack iterator to\niterate over the ref and log records in a reftable stack respectively.\nSince these functions are not exercised by any of the existing tests,\nadd a test for them.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 80 +++++++++++++++++++++++++++++++++\n 1 file changed, 80 insertions(+)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 51339a9939..5b1ecacd70 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -550,6 +550,85 @@ static void t_reftable_stack_add(void)\n \tclear_dir(dir);\n }\n \n+static void t_reftable_stack_iterator(void)\n+{\n+\tstruct reftable_write_options opts = { 0 };\n+\tstruct reftable_stack *st = NULL;\n+\tchar *dir = get_tmp_dir(__LINE__);\n+\tstruct reftable_ref_record refs[10] = { 0 };\n+\tstruct reftable_log_record logs[10] = { 0 };\n+\tstruct reftable_iterator it = { 0 };\n+\tsize_t N = ARRAY_SIZE(refs), i;\n+\tint err;\n+\n+\terr = reftable_new_stack(&st, dir, &opts);\n+\tcheck(!err);\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\trefs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n+\t\trefs[i].update_index = i + 1;\n+\t\trefs[i].value_type = REFTABLE_REF_VAL1;\n+\t\tset_test_hash(refs[i].value.val1, i);\n+\n+\t\tlogs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n+\t\tlogs[i].update_index = i + 1;\n+\t\tlogs[i].value_type = REFTABLE_LOG_UPDATE;\n+\t\tlogs[i].value.update.email = xstrdup(\"johndoe@invalid\");\n+\t\tlogs[i].value.update.message = xstrdup(\"commit\\n\");\n+\t\tset_test_hash(logs[i].value.update.new_hash, i);\n+\t}\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\terr = reftable_stack_add(st, &write_test_ref, &refs[i]);\n+\t\tcheck(!err);\n+\t}\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\tstruct write_log_arg arg = {\n+\t\t\t.log = &logs[i],\n+\t\t\t.update_index = reftable_stack_next_update_index(st),\n+\t\t};\n+\t\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tcheck(!err);\n+\t}\n+\n+\treftable_stack_init_ref_iterator(st, &it);\n+\treftable_iterator_seek_ref(&it, refs[0].refname);\n+\tfor (i = 0; ; i++) {\n+\t\tstruct reftable_ref_record ref = { 0 };\n+\t\terr = reftable_iterator_next_ref(&it, &ref);\n+\t\tif (err > 0)\n+\t\t\tbreak;\n+\t\tcheck(!err);\n+\t\tcheck(reftable_ref_record_equal(&ref, &refs[i], GIT_SHA1_RAWSZ));\n+\t\treftable_ref_record_release(&ref);\n+\t}\n+\tcheck_int(i, ==, N);\n+\n+\treftable_iterator_destroy(&it);\n+\n+\treftable_stack_init_log_iterator(st, &it);\n+\treftable_iterator_seek_log(&it, logs[0].refname);\n+\tfor (i = 0; ; i++) {\n+\t\tstruct reftable_log_record log = { 0 };\n+\t\terr = reftable_iterator_next_log(&it, &log);\n+\t\tif (err > 0)\n+\t\t\tbreak;\n+\t\tcheck(!err);\n+\t\tcheck(reftable_log_record_equal(&log, &logs[i], GIT_SHA1_RAWSZ));\n+\t\treftable_log_record_release(&log);\n+\t}\n+\tcheck_int(i, ==, N);\n+\n+\treftable_stack_destroy(st);\n+\treftable_iterator_destroy(&it);\n+\tfor (i = 0; i < N; i++) {\n+\t\treftable_ref_record_release(&refs[i]);\n+\t\treftable_log_record_release(&logs[i]);\n+\t}\n+\tclear_dir(dir);\n+}\n+\n static void t_reftable_stack_log_normalize(void)\n {\n \tint err = 0;\n@@ -1125,6 +1204,7 @@ int cmd_main(int argc, const char *argv[])\n \tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n \tTEST(t_reftable_stack_compaction_with_locked_tables(), \"compaction with locked tables\");\n \tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n+\tTEST(t_reftable_stack_iterator(), \"log and ref iterator for reftable stack\");\n \tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n \tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n \tTEST(t_reftable_stack_tombstone(), \"'tombstone' refs in stack\");\n-- \n2.45.GIT\n\n"},{"id":"501639","messageId":"ZswjDAOBzj5gwlxO@tanuki","threadId":"61911","inReplyTo":"20240823120514.11070-3-chandrapratap3519@gmail.com","subject":"Re: [PATCH v2 2/6] t: harmonize t-reftable-stack.c with coding guidelines","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-08-26T06:39:08Z","receivedAt":"2024-08-26T06:39:14Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Fri, Aug 23, 2024 at 05:18:47PM +0530, Chandra Pratap wrote:\n> @@ -1039,10 +1035,8 @@ static void t_reftable_stack_compaction_concurrent(void)\n>  static void unclean_stack_close(struct reftable_stack *st)\n>  {\n>  \t/* break abstraction boundary to simulate unclean shutdown. */\n> -\tint i = 0;\n> -\tfor (; i < st->readers_len; i++) {\n> +\tfor (int i = 0; i < st->readers_len; i++)\n\nNit: this should likely be `size_t i`. Not worth a reroll on its own\nthough.\n\nPatrick\n"},{"id":"501640","messageId":"ZswjDx5RHvH905zw@tanuki","threadId":"61911","inReplyTo":"20240823120514.11070-7-chandrapratap3519@gmail.com","subject":"Re: [PATCH v2 6/6] t-reftable-stack: add test for stack iterators","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-08-26T06:39:11Z","receivedAt":"2024-08-26T06:39:15Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Fri, Aug 23, 2024 at 05:18:51PM +0530, Chandra Pratap wrote:\n> diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\n> index 51339a9939..5b1ecacd70 100644\n> --- a/t/unit-tests/t-reftable-stack.c\n> +++ b/t/unit-tests/t-reftable-stack.c\n> @@ -550,6 +550,85 @@ static void t_reftable_stack_add(void)\n>  \tclear_dir(dir);\n>  }\n>  \n> +static void t_reftable_stack_iterator(void)\n> +{\n> +\tstruct reftable_write_options opts = { 0 };\n> +\tstruct reftable_stack *st = NULL;\n> +\tchar *dir = get_tmp_dir(__LINE__);\n> +\tstruct reftable_ref_record refs[10] = { 0 };\n> +\tstruct reftable_log_record logs[10] = { 0 };\n> +\tstruct reftable_iterator it = { 0 };\n> +\tsize_t N = ARRAY_SIZE(refs), i;\n> +\tint err;\n> +\n> +\terr = reftable_new_stack(&st, dir, &opts);\n> +\tcheck(!err);\n> +\n> +\tfor (i = 0; i < N; i++) {\n> +\t\trefs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n> +\t\trefs[i].update_index = i + 1;\n> +\t\trefs[i].value_type = REFTABLE_REF_VAL1;\n> +\t\tset_test_hash(refs[i].value.val1, i);\n> +\n> +\t\tlogs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n> +\t\tlogs[i].update_index = i + 1;\n> +\t\tlogs[i].value_type = REFTABLE_LOG_UPDATE;\n> +\t\tlogs[i].value.update.email = xstrdup(\"johndoe@invalid\");\n> +\t\tlogs[i].value.update.message = xstrdup(\"commit\\n\");\n> +\t\tset_test_hash(logs[i].value.update.new_hash, i);\n> +\t}\n> +\n> +\tfor (i = 0; i < N; i++) {\n> +\t\terr = reftable_stack_add(st, &write_test_ref, &refs[i]);\n> +\t\tcheck(!err);\n> +\t}\n\nNit: you re-add the ampersands before the function pointers here, which\nbasically reintroduces the pattern you got rid of in the second patch.\n\nPatrick\n"},{"id":"501683","messageId":"20240826173627.4525-1-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240823120514.11070-1-chandrapratap3519@gmail.com","subject":"[GSoC][PATCH v3 0/6] t: port reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-26T17:29:40Z","receivedAt":"2024-08-26T17:37:02Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"The reftable library comes with self tests, which are exercised\nas part of the usual end-to-end tests and are designed to\nobserve the end-user visible effects of Git commands. What it\nexercises, however, is a better match for the unit-testing\nframework, merged at 8bf6fbd0 (Merge branch 'js/doc-unit-tests',\n2023-12-09), which is designed to observe how low level\nimplementation details, at the level of sequences of individual\nfunction calls, behave.\n\nHence, port reftable/stack_test.c to the unit testing framework and\nimprove upon the ported test. The first patch in the series moves\nthe test to the unit testing framework, and the rest of the patches\nimprove upon the ported test.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n\n---\nChanges in v2:\n- Use 'size_t' as array index instead of 'int' in a test that is\n  modified in patch 2.\n- Fix a coding style violation in the newly introduced test in\n  patch 6.\n\nCI/PR: https://github.com/gitgitgadget/git/pull/1762\n\nChandra Pratap(6):\nt: move reftable/stack_test.c to the unit testing framework\nt: harmonize t-reftable-stack.c with coding guidelines\nt-reftable-stack: use Git's tempfile API instead of mkstemp()\nt-reftable-stack: use reftable_ref_record_equal() to compare ref records\nt-reftable-stack: add test for non-default compaction factor\nt-reftable-stack: add test for stack iterators\n\nMakefile                                                 |   2 +-\nreftable/reftable-tests.h                                |   1 -\nt/helper/test-reftable.c                                 |   1 -\nreftable/stack_test.c => t/unit-tests/t-reftable-stack.c | 611 +++++++++++++++++++--------------\n4 files changed, 360 insertions(+), 255 deletions(-)\n\nRange-diff against v2:\n1:  e172ceefd7 ! 1:  838ccc63a7 t: harmonize t-reftable-stack.c with coding guidelines\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_compaction_concurr\n      \t/* break abstraction boundary to simulate unclean shutdown. */\n     -\tint i = 0;\n     -\tfor (; i < st->readers_len; i++) {\n    -+\tfor (int i = 0; i < st->readers_len; i++)\n    ++\tfor (size_t i = 0; i < st->readers_len; i++)\n      \t\treftable_reader_free(st->readers[i]);\n     -\t}\n      \tst->readers_len = 0;\n2:  73b94aaa6a = 2:  2a151c299c t-reftable-stack: use Git's tempfile API instead of mkstemp()\n3:  b6f0363656 = 3:  fb5073da2c t-reftable-stack: use reftable_ref_record_equal() to compare ref records\n4:  35c09e6054 = 4:  028fa6f70b t-reftable-stack: add test for non-default compaction factor\n5:  3163c2af7d ! 5:  fa0d358e65 t-reftable-stack: add test for stack iterators\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add(void)\n     +\t}\n     +\n     +\tfor (i = 0; i < N; i++) {\n    -+\t\terr = reftable_stack_add(st, &write_test_ref, &refs[i]);\n    ++\t\terr = reftable_stack_add(st, write_test_ref, &refs[i]);\n     +\t\tcheck(!err);\n     +\t}\n     +\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add(void)\n     +\t\t\t.log = &logs[i],\n     +\t\t\t.update_index = reftable_stack_next_update_index(st),\n     +\t\t};\n    -+\t\terr = reftable_stack_add(st, &write_test_log, &arg);\n    ++\t\terr = reftable_stack_add(st, write_test_log, &arg);\n     +\t\tcheck(!err);\n     +\t}\n     +\n"},{"id":"501684","messageId":"20240826173627.4525-2-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240826173627.4525-1-chandrapratap3519@gmail.com","subject":"[PATCH v3 1/6] t: move reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-26T17:29:41Z","receivedAt":"2024-08-26T17:37:05Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"reftable/stack_test.c exercises the functions defined in\nreftable/stack.{c, h}. Migrate reftable/stack_test.c to the\nunit testing framework. Migration involves refactoring the tests\nto use the unit testing framework instead of reftable's test\nframework and renaming the tests to be in-line with unit-tests'\nstandards.\n\nSince some of the tests use set_test_hash() defined by\nreftable/test_framework.{c, h} but these files are not\n'#included' in the test file, copy this function in the\nported test file.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n Makefile                                      |   2 +-\n reftable/reftable-tests.h                     |   1 -\n t/helper/test-reftable.c                      |   1 -\n .../unit-tests/t-reftable-stack.c             | 374 +++++++++---------\n 4 files changed, 187 insertions(+), 191 deletions(-)\n rename reftable/stack_test.c => t/unit-tests/t-reftable-stack.c (77%)\n\ndiff --git a/Makefile b/Makefile\nindex a87e18b317..a63b3d8381 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1344,6 +1344,7 @@ UNIT_TEST_PROGRAMS += t-reftable-basics\n UNIT_TEST_PROGRAMS += t-reftable-merged\n UNIT_TEST_PROGRAMS += t-reftable-pq\n UNIT_TEST_PROGRAMS += t-reftable-record\n+UNIT_TEST_PROGRAMS += t-reftable-stack\n UNIT_TEST_PROGRAMS += t-reftable-tree\n UNIT_TEST_PROGRAMS += t-strbuf\n UNIT_TEST_PROGRAMS += t-strcmp-offset\n@@ -2685,7 +2686,6 @@ REFTABLE_OBJS += reftable/writer.o\n REFTABLE_TEST_OBJS += reftable/block_test.o\n REFTABLE_TEST_OBJS += reftable/dump.o\n REFTABLE_TEST_OBJS += reftable/readwrite_test.o\n-REFTABLE_TEST_OBJS += reftable/stack_test.o\n REFTABLE_TEST_OBJS += reftable/test_framework.o\n \n TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))\ndiff --git a/reftable/reftable-tests.h b/reftable/reftable-tests.h\nindex 4b666810af..2ed2aa7a86 100644\n--- a/reftable/reftable-tests.h\n+++ b/reftable/reftable-tests.h\n@@ -13,7 +13,6 @@ int basics_test_main(int argc, const char **argv);\n int block_test_main(int argc, const char **argv);\n int record_test_main(int argc, const char **argv);\n int readwrite_test_main(int argc, const char **argv);\n-int stack_test_main(int argc, const char **argv);\n int reftable_dump_main(int argc, char *const *argv);\n \n #endif\ndiff --git a/t/helper/test-reftable.c b/t/helper/test-reftable.c\nindex 623cf3f0f5..8a817ca9d9 100644\n--- a/t/helper/test-reftable.c\n+++ b/t/helper/test-reftable.c\n@@ -7,7 +7,6 @@ int cmd__reftable(int argc, const char **argv)\n \t/* test from simple to complex. */\n \tblock_test_main(argc, argv);\n \treadwrite_test_main(argc, argv);\n-\tstack_test_main(argc, argv);\n \treturn 0;\n }\n \ndiff --git a/reftable/stack_test.c b/t/unit-tests/t-reftable-stack.c\nsimilarity index 77%\nrename from reftable/stack_test.c\nrename to t/unit-tests/t-reftable-stack.c\nindex 8c36590ff0..cae86b4b91 100644\n--- a/reftable/stack_test.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -6,21 +6,18 @@ license that can be found in the LICENSE file or at\n https://developers.google.com/open-source/licenses/bsd\n */\n \n-#include \"stack.h\"\n-\n-#include \"system.h\"\n-\n-#include \"reftable-reader.h\"\n-#include \"merged.h\"\n-#include \"basics.h\"\n-#include \"record.h\"\n-#include \"test_framework.h\"\n-#include \"reftable-tests.h\"\n-#include \"reader.h\"\n-\n-#include <sys/types.h>\n+#include \"test-lib.h\"\n+#include \"reftable/merged.h\"\n+#include \"reftable/reader.h\"\n+#include \"reftable/reftable-error.h\"\n+#include \"reftable/stack.h\"\n #include <dirent.h>\n \n+static void set_test_hash(uint8_t *p, int i)\n+{\n+\tmemset(p, (uint8_t)i, hash_size(GIT_SHA1_FORMAT_ID));\n+}\n+\n static void clear_dir(const char *dirname)\n {\n \tstruct strbuf path = STRBUF_INIT;\n@@ -72,11 +69,11 @@ static char *get_tmp_template(int linenumber)\n static char *get_tmp_dir(int linenumber)\n {\n \tchar *dir = get_tmp_template(linenumber);\n-\tEXPECT(mkdtemp(dir));\n+\tcheck(mkdtemp(dir) != NULL);\n \treturn dir;\n }\n \n-static void test_read_file(void)\n+static void t_read_file(void)\n {\n \tchar *fn = get_tmp_template(__LINE__);\n \tint fd = mkstemp(fn);\n@@ -86,17 +83,17 @@ static void test_read_file(void)\n \tconst char *want[] = { \"line1\", \"line2\", \"line3\" };\n \tint i = 0;\n \n-\tEXPECT(fd > 0);\n+\tcheck_int(fd, >, 0);\n \tn = write_in_full(fd, out, strlen(out));\n-\tEXPECT(n == strlen(out));\n+\tcheck_int(n, ==, strlen(out));\n \terr = close(fd);\n-\tEXPECT(err >= 0);\n+\tcheck_int(err, >=, 0);\n \n \terr = read_lines(fn, &names);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; names[i]; i++) {\n-\t\tEXPECT(0 == strcmp(want[i], names[i]));\n+\t\tcheck_str(want[i], names[i]);\n \t}\n \tfree_names(names);\n \t(void) remove(fn);\n@@ -130,7 +127,7 @@ static void write_n_ref_tables(struct reftable_stack *st,\n \t\tset_test_hash(ref.value.val1, i);\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tst->opts.disable_auto_compact = disable_auto_compact;\n@@ -150,7 +147,7 @@ static int write_test_log(struct reftable_writer *wr, void *arg)\n \treturn reftable_writer_add_log(wr, wla->log);\n }\n \n-static void test_reftable_stack_add_one(void)\n+static void t_reftable_stack_add_one(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct strbuf scratch = STRBUF_INIT;\n@@ -169,29 +166,29 @@ static void test_reftable_stack_add_one(void)\n \tstruct reftable_ref_record dest = { NULL };\n \tstruct stat stat_result = { 0 };\n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(\"master\", dest.value.symref));\n-\tEXPECT(st->readers_len > 0);\n+\tcheck(!err);\n+\tcheck_str(\"master\", dest.value.symref);\n+\tcheck_int(st->readers_len, >, 0);\n \n \tprintf(\"testing print functionality:\\n\");\n \terr = reftable_stack_print_directory(dir, GIT_SHA1_FORMAT_ID);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_print_directory(dir, GIT_SHA256_FORMAT_ID);\n-\tEXPECT(err == REFTABLE_FORMAT_ERROR);\n+\tcheck_int(err, ==, REFTABLE_FORMAT_ERROR);\n \n #ifndef GIT_WINDOWS_NATIVE\n \tstrbuf_addstr(&scratch, dir);\n \tstrbuf_addstr(&scratch, \"/tables.list\");\n \terr = stat(scratch.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n \n \tstrbuf_reset(&scratch);\n \tstrbuf_addstr(&scratch, dir);\n@@ -199,8 +196,8 @@ static void test_reftable_stack_add_one(void)\n \t/* do not try at home; not an external API for reftable. */\n \tstrbuf_addstr(&scratch, st->readers[0]->name);\n \terr = stat(scratch.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n #else\n \t(void) stat_result;\n #endif\n@@ -212,7 +209,7 @@ static void test_reftable_stack_add_one(void)\n \tumask(mask);\n }\n \n-static void test_reftable_stack_uptodate(void)\n+static void t_reftable_stack_uptodate(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL;\n@@ -238,28 +235,28 @@ static void test_reftable_stack_uptodate(void)\n \t   by creating two stacks for the same directory.\n \t */\n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st1, &write_test_ref, &ref1);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n-\tEXPECT(err == REFTABLE_OUTDATED_ERROR);\n+\tcheck_int(err, ==, REFTABLE_OUTDATED_ERROR);\n \n \terr = reftable_stack_reload(st2);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_transaction_api(void)\n+static void t_reftable_stack_transaction_api(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -276,32 +273,32 @@ static void test_reftable_stack_transaction_api(void)\n \tstruct reftable_ref_record dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_addition_destroy(add);\n \n \terr = reftable_stack_new_addition(&add, st);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_addition_add(add, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_addition_commit(add);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_addition_destroy(add);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(REFTABLE_REF_SYMREF == dest.value_type);\n-\tEXPECT(0 == strcmp(\"master\", dest.value.symref));\n+\tcheck(!err);\n+\tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n+\tcheck_str(\"master\", dest.value.symref);\n \n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n+static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = {0};\n@@ -310,7 +307,7 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \tint i, n = 20, err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n@@ -331,13 +328,13 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\tst->opts.disable_auto_compact = i != n;\n \n \t\terr = reftable_stack_new_addition(&add, st);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_addition_add(add, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_addition_commit(add);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\treftable_addition_destroy(add);\n \n@@ -347,16 +344,16 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\t * all tables in the stack.\n \t\t */\n \t\tif (i != n)\n-\t\t\tEXPECT(st->merged->stack_len == i + 1);\n+\t\t\tcheck_int(st->merged->stack_len, ==, i + 1);\n \t\telse\n-\t\t\tEXPECT(st->merged->stack_len == 1);\n+\t\t\tcheck_int(st->merged->stack_len, ==, 1);\n \t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n+static void t_reftable_stack_auto_compaction_fails_gracefully(void)\n {\n \tstruct reftable_ref_record ref = {\n \t\t.refname = (char *) \"refs/heads/master\",\n@@ -371,13 +368,13 @@ static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->merged->stack_len == 1);\n-\tEXPECT(st->stats.attempts == 0);\n-\tEXPECT(st->stats.failures == 0);\n+\tcheck(!err);\n+\tcheck_int(st->merged->stack_len, ==, 1);\n+\tcheck_int(st->stats.attempts, ==, 0);\n+\tcheck_int(st->stats.failures, ==, 0);\n \n \t/*\n \t * Lock the newly written table such that it cannot be compacted.\n@@ -389,10 +386,10 @@ static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n \n \tref.update_index = 2;\n \terr = reftable_stack_add(st, write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->merged->stack_len == 2);\n-\tEXPECT(st->stats.attempts == 1);\n-\tEXPECT(st->stats.failures == 1);\n+\tcheck(!err);\n+\tcheck_int(st->merged->stack_len, ==, 2);\n+\tcheck_int(st->stats.attempts, ==, 1);\n+\tcheck_int(st->stats.failures, ==, 1);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&table_path);\n@@ -404,7 +401,7 @@ static int write_error(struct reftable_writer *wr, void *arg)\n \treturn *((int *)arg);\n }\n \n-static void test_reftable_stack_update_index_check(void)\n+static void t_reftable_stack_update_index_check(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -424,18 +421,18 @@ static void test_reftable_stack_update_index_check(void)\n \t};\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref1);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref2);\n-\tEXPECT(err == REFTABLE_API_ERROR);\n+\tcheck_int(err, ==, REFTABLE_API_ERROR);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_lock_failure(void)\n+static void t_reftable_stack_lock_failure(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -443,17 +440,17 @@ static void test_reftable_stack_lock_failure(void)\n \tint err, i;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \tfor (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) {\n \t\terr = reftable_stack_add(st, &write_error, &i);\n-\t\tEXPECT(err == i);\n+\t\tcheck_int(err, ==, i);\n \t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_add(void)\n+static void t_reftable_stack_add(void)\n {\n \tint i = 0;\n \tint err = 0;\n@@ -471,7 +468,7 @@ static void test_reftable_stack_add(void)\n \tint N = ARRAY_SIZE(refs);\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar buf[256];\n@@ -490,7 +487,7 @@ static void test_reftable_stack_add(void)\n \n \tfor (i = 0; i < N; i++) {\n \t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tfor (i = 0; i < N; i++) {\n@@ -499,18 +496,18 @@ static void test_reftable_stack_add(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tstruct reftable_ref_record dest = { NULL };\n \n \t\tint err = reftable_stack_read_ref(st, refs[i].refname, &dest);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(reftable_ref_record_equal(&dest, refs + i,\n+\t\tcheck(!err);\n+\t\tcheck(reftable_ref_record_equal(&dest, refs + i,\n \t\t\t\t\t\t GIT_SHA1_RAWSZ));\n \t\treftable_ref_record_release(&dest);\n \t}\n@@ -518,8 +515,8 @@ static void test_reftable_stack_add(void)\n \tfor (i = 0; i < N; i++) {\n \t\tstruct reftable_log_record dest = { NULL };\n \t\tint err = reftable_stack_read_log(st, refs[i].refname, &dest);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(reftable_log_record_equal(&dest, logs + i,\n+\t\tcheck(!err);\n+\t\tcheck(reftable_log_record_equal(&dest, logs + i,\n \t\t\t\t\t\t GIT_SHA1_RAWSZ));\n \t\treftable_log_record_release(&dest);\n \t}\n@@ -528,8 +525,8 @@ static void test_reftable_stack_add(void)\n \tstrbuf_addstr(&path, dir);\n \tstrbuf_addstr(&path, \"/tables.list\");\n \terr = stat(path.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n \n \tstrbuf_reset(&path);\n \tstrbuf_addstr(&path, dir);\n@@ -537,8 +534,8 @@ static void test_reftable_stack_add(void)\n \t/* do not try at home; not an external API for reftable. */\n \tstrbuf_addstr(&path, st->readers[0]->name);\n \terr = stat(path.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n #else\n \t(void) stat_result;\n #endif\n@@ -553,7 +550,7 @@ static void test_reftable_stack_add(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_log_normalize(void)\n+static void t_reftable_stack_log_normalize(void)\n {\n \tint err = 0;\n \tstruct reftable_write_options opts = {\n@@ -581,27 +578,27 @@ static void test_reftable_stack_log_normalize(void)\n \t};\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tinput.value.update.message = (char *) \"one\\ntwo\";\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT(err == REFTABLE_API_ERROR);\n+\tcheck_int(err, ==, REFTABLE_API_ERROR);\n \n \tinput.value.update.message = (char *) \"one\";\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, input.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(dest.value.update.message, \"one\\n\"));\n+\tcheck(!err);\n+\tcheck_str(dest.value.update.message, \"one\\n\");\n \n \tinput.value.update.message = (char *) \"two\\n\";\n \targ.update_index = 2;\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \terr = reftable_stack_read_log(st, input.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(dest.value.update.message, \"two\\n\"));\n+\tcheck(!err);\n+\tcheck_str(dest.value.update.message, \"two\\n\");\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n@@ -609,7 +606,7 @@ static void test_reftable_stack_log_normalize(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_tombstone(void)\n+static void t_reftable_stack_tombstone(void)\n {\n \tint i = 0;\n \tchar *dir = get_tmp_dir(__LINE__);\n@@ -623,7 +620,7 @@ static void test_reftable_stack_tombstone(void)\n \tstruct reftable_log_record log_dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* even entries add the refs, odd entries delete them. */\n \tfor (i = 0; i < N; i++) {\n@@ -647,7 +644,7 @@ static void test_reftable_stack_tombstone(void)\n \t}\n \tfor (i = 0; i < N; i++) {\n \t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tfor (i = 0; i < N; i++) {\n@@ -656,25 +653,25 @@ static void test_reftable_stack_tombstone(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_read_ref(st, \"branch\", &dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_ref_record_release(&dest);\n \n \terr = reftable_stack_read_log(st, \"branch\", &log_dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_log_record_release(&log_dest);\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, \"branch\", &dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, \"branch\", &log_dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_ref_record_release(&dest);\n \treftable_log_record_release(&log_dest);\n \n@@ -687,7 +684,7 @@ static void test_reftable_stack_tombstone(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_hash_id(void)\n+static void t_reftable_stack_hash_id(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -707,47 +704,47 @@ static void test_reftable_stack_hash_id(void)\n \tstruct reftable_ref_record dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* can't read it with the wrong hash ID. */\n \terr = reftable_new_stack(&st32, dir, &opts32);\n-\tEXPECT(err == REFTABLE_FORMAT_ERROR);\n+\tcheck_int(err, ==, REFTABLE_FORMAT_ERROR);\n \n \t/* check that we can read it back with default opts too. */\n \terr = reftable_new_stack(&st_default, dir, &opts_default);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st_default, \"master\", &dest);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n-\tEXPECT(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n \treftable_stack_destroy(st_default);\n \tclear_dir(dir);\n }\n \n-static void test_suggest_compaction_segment(void)\n+static void t_suggest_compaction_segment(void)\n {\n \tuint64_t sizes[] = { 512, 64, 17, 16, 9, 9, 9, 16, 2, 16 };\n \tstruct segment min =\n \t\tsuggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);\n-\tEXPECT(min.start == 1);\n-\tEXPECT(min.end == 10);\n+\tcheck_int(min.start, ==, 1);\n+\tcheck_int(min.end, ==, 10);\n }\n \n-static void test_suggest_compaction_segment_nothing(void)\n+static void t_suggest_compaction_segment_nothing(void)\n {\n \tuint64_t sizes[] = { 64, 32, 16, 8, 4, 2 };\n \tstruct segment result =\n \t\tsuggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);\n-\tEXPECT(result.start == result.end);\n+\tcheck_int(result.start, ==, result.end);\n }\n \n-static void test_reflog_expire(void)\n+static void t_reflog_expire(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -762,7 +759,7 @@ static void test_reflog_expire(void)\n \tstruct reftable_log_record log = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 1; i <= N; i++) {\n \t\tchar buf[256];\n@@ -782,30 +779,30 @@ static void test_reflog_expire(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st, &expiry);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, logs[9].refname, &log);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, logs[11].refname, &log);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \texpiry.min_update_index = 15;\n \terr = reftable_stack_compact_all(st, &expiry);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, logs[14].refname, &log);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, logs[16].refname, &log);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n@@ -822,7 +819,7 @@ static int write_nothing(struct reftable_writer *wr, void *arg)\n \treturn 0;\n }\n \n-static void test_empty_add(void)\n+static void t_empty_add(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -831,13 +828,13 @@ static void test_empty_add(void)\n \tstruct reftable_stack *st2 = NULL;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_nothing, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \tclear_dir(dir);\n \treftable_stack_destroy(st);\n \treftable_stack_destroy(st2);\n@@ -853,7 +850,7 @@ static int fastlog2(uint64_t sz)\n \treturn l - 1;\n }\n \n-static void test_reftable_stack_auto_compaction(void)\n+static void t_reftable_stack_auto_compaction(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -864,7 +861,7 @@ static void test_reftable_stack_auto_compaction(void)\n \tint N = 100;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar name[100];\n@@ -877,21 +874,21 @@ static void test_reftable_stack_auto_compaction(void)\n \t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_stack_auto_compact(st);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(i < 3 || st->merged->stack_len < 2 * fastlog2(i));\n+\t\tcheck(!err);\n+\t\tcheck(i < 3 || st->merged->stack_len < 2 * fastlog2(i));\n \t}\n \n-\tEXPECT(reftable_stack_compaction_stats(st)->entries_written <\n+\tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n \t       (uint64_t)(N * fastlog2(N)));\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n+static void t_reftable_stack_auto_compaction_with_locked_tables(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -902,10 +899,10 @@ static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \twrite_n_ref_tables(st, 5);\n-\tEXPECT(st->merged->stack_len == 5);\n+\tcheck_int(st->merged->stack_len, ==, 5);\n \n \t/*\n \t * Given that all tables we have written should be roughly the same\n@@ -923,16 +920,16 @@ static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n \t * only compact the newest two tables.\n \t */\n \terr = reftable_stack_auto_compact(st);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->stats.failures == 0);\n-\tEXPECT(st->merged->stack_len == 4);\n+\tcheck(!err);\n+\tcheck_int(st->stats.failures, ==, 0);\n+\tcheck_int(st->merged->stack_len, ==, 4);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&buf);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_add_performs_auto_compaction(void)\n+static void t_reftable_stack_add_performs_auto_compaction(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -941,7 +938,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \tint err, i, n = 20;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n@@ -962,7 +959,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \t\tref.refname = refname.buf;\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\t/*\n \t\t * The stack length should grow continuously for all runs where\n@@ -970,9 +967,9 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \t\t * all tables in the stack.\n \t\t */\n \t\tif (i != n)\n-\t\t\tEXPECT(st->merged->stack_len == i + 1);\n+\t\t\tcheck_int(st->merged->stack_len, ==, i + 1);\n \t\telse\n-\t\t\tEXPECT(st->merged->stack_len == 1);\n+\t\t\tcheck_int(st->merged->stack_len, ==, 1);\n \t}\n \n \treftable_stack_destroy(st);\n@@ -980,7 +977,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_compaction_with_locked_tables(void)\n+static void t_reftable_stack_compaction_with_locked_tables(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -991,10 +988,10 @@ static void test_reftable_stack_compaction_with_locked_tables(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \twrite_n_ref_tables(st, 3);\n-\tEXPECT(st->merged->stack_len == 3);\n+\tcheck_int(st->merged->stack_len, ==, 3);\n \n \t/* Lock one of the tables that we're about to compact. */\n \tstrbuf_reset(&buf);\n@@ -1006,16 +1003,16 @@ static void test_reftable_stack_compaction_with_locked_tables(void)\n \t * compact all tables.\n \t */\n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT(err == REFTABLE_LOCK_ERROR);\n-\tEXPECT(st->stats.failures == 1);\n-\tEXPECT(st->merged->stack_len == 3);\n+\tcheck_int(err, ==, REFTABLE_LOCK_ERROR);\n+\tcheck_int(st->stats.failures, ==, 1);\n+\tcheck_int(st->merged->stack_len, ==, 3);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&buf);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_compaction_concurrent(void)\n+static void t_reftable_stack_compaction_concurrent(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL;\n@@ -1023,19 +1020,19 @@ static void test_reftable_stack_compaction_concurrent(void)\n \tint err;\n \n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st1, 3);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st1, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n \n-\tEXPECT(count_dir_entries(dir) == 2);\n+\tcheck_int(count_dir_entries(dir), ==, 2);\n \tclear_dir(dir);\n }\n \n@@ -1050,7 +1047,7 @@ static void unclean_stack_close(struct reftable_stack *st)\n \tFREE_AND_NULL(st->readers);\n }\n \n-static void test_reftable_stack_compaction_concurrent_clean(void)\n+static void t_reftable_stack_compaction_concurrent_clean(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL, *st3 = NULL;\n@@ -1058,24 +1055,24 @@ static void test_reftable_stack_compaction_concurrent_clean(void)\n \tint err;\n \n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st1, 3);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st1, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tunclean_stack_close(st1);\n \tunclean_stack_close(st2);\n \n \terr = reftable_new_stack(&st3, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_clean(st3);\n-\tEXPECT_ERR(err);\n-\tEXPECT(count_dir_entries(dir) == 2);\n+\tcheck(!err);\n+\tcheck_int(count_dir_entries(dir), ==, 2);\n \n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n@@ -1084,29 +1081,30 @@ static void test_reftable_stack_compaction_concurrent_clean(void)\n \tclear_dir(dir);\n }\n \n-int stack_test_main(int argc, const char *argv[])\n+int cmd_main(int argc, const char *argv[])\n {\n-\tRUN_TEST(test_empty_add);\n-\tRUN_TEST(test_read_file);\n-\tRUN_TEST(test_reflog_expire);\n-\tRUN_TEST(test_reftable_stack_add);\n-\tRUN_TEST(test_reftable_stack_add_one);\n-\tRUN_TEST(test_reftable_stack_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_auto_compaction_with_locked_tables);\n-\tRUN_TEST(test_reftable_stack_add_performs_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_compaction_concurrent);\n-\tRUN_TEST(test_reftable_stack_compaction_concurrent_clean);\n-\tRUN_TEST(test_reftable_stack_compaction_with_locked_tables);\n-\tRUN_TEST(test_reftable_stack_hash_id);\n-\tRUN_TEST(test_reftable_stack_lock_failure);\n-\tRUN_TEST(test_reftable_stack_log_normalize);\n-\tRUN_TEST(test_reftable_stack_tombstone);\n-\tRUN_TEST(test_reftable_stack_transaction_api);\n-\tRUN_TEST(test_reftable_stack_transaction_api_performs_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_auto_compaction_fails_gracefully);\n-\tRUN_TEST(test_reftable_stack_update_index_check);\n-\tRUN_TEST(test_reftable_stack_uptodate);\n-\tRUN_TEST(test_suggest_compaction_segment);\n-\tRUN_TEST(test_suggest_compaction_segment_nothing);\n-\treturn 0;\n+\tTEST(t_empty_add(), \"empty addition to stack\");\n+\tTEST(t_read_file(), \"read_lines works\");\n+\tTEST(t_reflog_expire(), \"expire reflog entries\");\n+\tTEST(t_reftable_stack_add(), \"add multiple refs and logs to stack\");\n+\tTEST(t_reftable_stack_add_one(), \"add a single ref record to stack\");\n+\tTEST(t_reftable_stack_add_performs_auto_compaction(), \"addition to stack triggers auto-compaction\");\n+\tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_fails_gracefully(), \"failure on auto-compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_with_locked_tables(), \"auto compaction with locked tables\");\n+\tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n+\tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n+\tTEST(t_reftable_stack_compaction_with_locked_tables(), \"compaction with locked tables\");\n+\tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n+\tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n+\tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n+\tTEST(t_reftable_stack_tombstone(), \"'tombstone' refs in stack\");\n+\tTEST(t_reftable_stack_transaction_api(), \"update transaction to stack\");\n+\tTEST(t_reftable_stack_transaction_api_performs_auto_compaction(), \"update transaction triggers auto-compaction\");\n+\tTEST(t_reftable_stack_update_index_check(), \"update transactions with equal update indices\");\n+\tTEST(t_reftable_stack_uptodate(), \"stack must be reloaded before ref update\");\n+\tTEST(t_suggest_compaction_segment(), \"suggest_compaction_segment with basic input\");\n+\tTEST(t_suggest_compaction_segment_nothing(), \"suggest_compaction_segment with pre-compacted input\");\n+\n+\treturn test_done();\n }\n-- \n2.45.GIT\n\n"},{"id":"501685","messageId":"20240826173627.4525-3-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240826173627.4525-1-chandrapratap3519@gmail.com","subject":"[PATCH v3 2/6] t: harmonize t-reftable-stack.c with coding guidelines","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-26T17:29:42Z","receivedAt":"2024-08-26T17:37:08Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"Harmonize the newly ported test unit-tests/t-reftable-stack.c\nwith the following guidelines:\n- Single line 'for' statements must omit curly braces.\n- Structs must be 0-initialized with '= { 0 }' instead of '= { NULL }'.\n- Array sizes and indices should preferably be of type 'size_t' and\n  not 'int'.\n- Function pointers should be passed as 'func' and not '&func'.\n\nWhile at it, remove initialization for those variables that are\nre-used multiple times, like loop variables.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 114 +++++++++++++++-----------------\n 1 file changed, 54 insertions(+), 60 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex cae86b4b91..3ae7478fbf 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -81,7 +81,6 @@ static void t_read_file(void)\n \tint n, err;\n \tchar **names = NULL;\n \tconst char *want[] = { \"line1\", \"line2\", \"line3\" };\n-\tint i = 0;\n \n \tcheck_int(fd, >, 0);\n \tn = write_in_full(fd, out, strlen(out));\n@@ -92,9 +91,8 @@ static void t_read_file(void)\n \terr = read_lines(fn, &names);\n \tcheck(!err);\n \n-\tfor (i = 0; names[i]; i++) {\n+\tfor (size_t i = 0; names[i]; i++)\n \t\tcheck_str(want[i], names[i]);\n-\t}\n \tfree_names(names);\n \t(void) remove(fn);\n }\n@@ -122,7 +120,7 @@ static void write_n_ref_tables(struct reftable_stack *st,\n \t\t\t.value_type = REFTABLE_REF_VAL1,\n \t\t};\n \n-\t\tstrbuf_addf(&buf, \"refs/heads/branch-%04u\", (unsigned) i);\n+\t\tstrbuf_addf(&buf, \"refs/heads/branch-%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = buf.buf;\n \t\tset_test_hash(ref.value.val1, i);\n \n@@ -163,12 +161,12 @@ static void t_reftable_stack_add_one(void)\n \t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t.value.symref = (char *) \"master\",\n \t};\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \tstruct stat stat_result = { 0 };\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\terr = reftable_stack_add(st, write_test_ref, &ref);\n \tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n@@ -240,16 +238,16 @@ static void t_reftable_stack_uptodate(void)\n \terr = reftable_new_stack(&st2, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st1, &write_test_ref, &ref1);\n+\terr = reftable_stack_add(st1, write_test_ref, &ref1);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st2, write_test_ref, &ref2);\n \tcheck_int(err, ==, REFTABLE_OUTDATED_ERROR);\n \n \terr = reftable_stack_reload(st2);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st2, write_test_ref, &ref2);\n \tcheck(!err);\n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n@@ -270,7 +268,7 @@ static void t_reftable_stack_transaction_api(void)\n \t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t.value.symref = (char *) \"master\",\n \t};\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -280,7 +278,7 @@ static void t_reftable_stack_transaction_api(void)\n \terr = reftable_stack_new_addition(&add, st);\n \tcheck(!err);\n \n-\terr = reftable_addition_add(add, &write_test_ref, &ref);\n+\terr = reftable_addition_add(add, write_test_ref, &ref);\n \tcheck(!err);\n \n \terr = reftable_addition_commit(add);\n@@ -304,12 +302,13 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \tstruct reftable_write_options opts = {0};\n \tstruct reftable_addition *add = NULL;\n \tstruct reftable_stack *st = NULL;\n-\tint i, n = 20, err;\n+\tsize_t n = 20;\n+\tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\tfor (i = 0; i <= n; i++) {\n+\tfor (size_t i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t\t.value_type = REFTABLE_REF_SYMREF,\n@@ -317,7 +316,7 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\t};\n \t\tchar name[100];\n \n-\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = name;\n \n \t\t/*\n@@ -330,7 +329,7 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\terr = reftable_stack_new_addition(&add, st);\n \t\tcheck(!err);\n \n-\t\terr = reftable_addition_add(add, &write_test_ref, &ref);\n+\t\terr = reftable_addition_add(add, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\terr = reftable_addition_commit(add);\n@@ -361,7 +360,7 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void)\n \t\t.value_type = REFTABLE_REF_VAL1,\n \t\t.value.val1 = {0x01},\n \t};\n-\tstruct reftable_write_options opts = {0};\n+\tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st;\n \tstruct strbuf table_path = STRBUF_INIT;\n \tchar *dir = get_tmp_dir(__LINE__);\n@@ -423,10 +422,10 @@ static void t_reftable_stack_update_index_check(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref1);\n+\terr = reftable_stack_add(st, write_test_ref, &ref1);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st, write_test_ref, &ref2);\n \tcheck_int(err, ==, REFTABLE_API_ERROR);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n@@ -442,7 +441,7 @@ static void t_reftable_stack_lock_failure(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \tfor (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) {\n-\t\terr = reftable_stack_add(st, &write_error, &i);\n+\t\terr = reftable_stack_add(st, write_error, &i);\n \t\tcheck_int(err, ==, i);\n \t}\n \n@@ -452,7 +451,6 @@ static void t_reftable_stack_lock_failure(void)\n \n static void t_reftable_stack_add(void)\n {\n-\tint i = 0;\n \tint err = 0;\n \tstruct reftable_write_options opts = {\n \t\t.exact_log_message = 1,\n@@ -461,18 +459,18 @@ static void t_reftable_stack_add(void)\n \t};\n \tstruct reftable_stack *st = NULL;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tstruct reftable_ref_record refs[2] = { { NULL } };\n-\tstruct reftable_log_record logs[2] = { { NULL } };\n+\tstruct reftable_ref_record refs[2] = { 0 };\n+\tstruct reftable_log_record logs[2] = { 0 };\n \tstruct strbuf path = STRBUF_INIT;\n \tstruct stat stat_result;\n-\tint N = ARRAY_SIZE(refs);\n+\tsize_t i, N = ARRAY_SIZE(refs);\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar buf[256];\n-\t\tsnprintf(buf, sizeof(buf), \"branch%02d\", i);\n+\t\tsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n \t\trefs[i].refname = xstrdup(buf);\n \t\trefs[i].update_index = i + 1;\n \t\trefs[i].value_type = REFTABLE_REF_VAL1;\n@@ -486,7 +484,7 @@ static void t_reftable_stack_add(void)\n \t}\n \n \tfor (i = 0; i < N; i++) {\n-\t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n+\t\tint err = reftable_stack_add(st, write_test_ref, &refs[i]);\n \t\tcheck(!err);\n \t}\n \n@@ -495,7 +493,7 @@ static void t_reftable_stack_add(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -503,7 +501,7 @@ static void t_reftable_stack_add(void)\n \tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n-\t\tstruct reftable_ref_record dest = { NULL };\n+\t\tstruct reftable_ref_record dest = { 0 };\n \n \t\tint err = reftable_stack_read_ref(st, refs[i].refname, &dest);\n \t\tcheck(!err);\n@@ -513,7 +511,7 @@ static void t_reftable_stack_add(void)\n \t}\n \n \tfor (i = 0; i < N; i++) {\n-\t\tstruct reftable_log_record dest = { NULL };\n+\t\tstruct reftable_log_record dest = { 0 };\n \t\tint err = reftable_stack_read_log(st, refs[i].refname, &dest);\n \t\tcheck(!err);\n \t\tcheck(reftable_log_record_equal(&dest, logs + i,\n@@ -581,11 +579,11 @@ static void t_reftable_stack_log_normalize(void)\n \tcheck(!err);\n \n \tinput.value.update.message = (char *) \"one\\ntwo\";\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck_int(err, ==, REFTABLE_API_ERROR);\n \n \tinput.value.update.message = (char *) \"one\";\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck(!err);\n \n \terr = reftable_stack_read_log(st, input.refname, &dest);\n@@ -594,7 +592,7 @@ static void t_reftable_stack_log_normalize(void)\n \n \tinput.value.update.message = (char *) \"two\\n\";\n \targ.update_index = 2;\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck(!err);\n \terr = reftable_stack_read_log(st, input.refname, &dest);\n \tcheck(!err);\n@@ -608,16 +606,15 @@ static void t_reftable_stack_log_normalize(void)\n \n static void t_reftable_stack_tombstone(void)\n {\n-\tint i = 0;\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n \tint err;\n-\tstruct reftable_ref_record refs[2] = { { NULL } };\n-\tstruct reftable_log_record logs[2] = { { NULL } };\n-\tint N = ARRAY_SIZE(refs);\n-\tstruct reftable_ref_record dest = { NULL };\n-\tstruct reftable_log_record log_dest = { NULL };\n+\tstruct reftable_ref_record refs[2] = { 0 };\n+\tstruct reftable_log_record logs[2] = { 0 };\n+\tsize_t i, N = ARRAY_SIZE(refs);\n+\tstruct reftable_ref_record dest = { 0 };\n+\tstruct reftable_log_record log_dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -643,7 +640,7 @@ static void t_reftable_stack_tombstone(void)\n \t\t}\n \t}\n \tfor (i = 0; i < N; i++) {\n-\t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n+\t\tint err = reftable_stack_add(st, write_test_ref, &refs[i]);\n \t\tcheck(!err);\n \t}\n \n@@ -652,7 +649,7 @@ static void t_reftable_stack_tombstone(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -701,12 +698,12 @@ static void t_reftable_stack_hash_id(void)\n \tstruct reftable_stack *st32 = NULL;\n \tstruct reftable_write_options opts_default = { 0 };\n \tstruct reftable_stack *st_default = NULL;\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\terr = reftable_stack_add(st, write_test_ref, &ref);\n \tcheck(!err);\n \n \t/* can't read it with the wrong hash ID. */\n@@ -749,21 +746,20 @@ static void t_reflog_expire(void)\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n-\tstruct reftable_log_record logs[20] = { { NULL } };\n-\tint N = ARRAY_SIZE(logs) - 1;\n-\tint i = 0;\n+\tstruct reftable_log_record logs[20] = { 0 };\n+\tsize_t i, N = ARRAY_SIZE(logs) - 1;\n \tint err;\n \tstruct reftable_log_expiry_config expiry = {\n \t\t.time = 10,\n \t};\n-\tstruct reftable_log_record log = { NULL };\n+\tstruct reftable_log_record log = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n \tfor (i = 1; i <= N; i++) {\n \t\tchar buf[256];\n-\t\tsnprintf(buf, sizeof(buf), \"branch%02d\", i);\n+\t\tsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n \n \t\tlogs[i].refname = xstrdup(buf);\n \t\tlogs[i].update_index = i;\n@@ -778,7 +774,7 @@ static void t_reflog_expire(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -806,9 +802,8 @@ static void t_reflog_expire(void)\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n-\tfor (i = 0; i <= N; i++) {\n+\tfor (i = 0; i <= N; i++)\n \t\treftable_log_record_release(&logs[i]);\n-\t}\n \tclear_dir(dir);\n \treftable_log_record_release(&log);\n }\n@@ -830,7 +825,7 @@ static void t_empty_add(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_nothing, NULL);\n+\terr = reftable_stack_add(st, write_nothing, NULL);\n \tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n@@ -857,8 +852,8 @@ static void t_reftable_stack_auto_compaction(void)\n \t};\n \tstruct reftable_stack *st = NULL;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tint err, i;\n-\tint N = 100;\n+\tint err;\n+\tsize_t i, N = 100;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -871,9 +866,9 @@ static void t_reftable_stack_auto_compaction(void)\n \t\t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t\t.value.symref = (char *) \"master\",\n \t\t};\n-\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n \n-\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\terr = reftable_stack_add(st, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\terr = reftable_stack_auto_compact(st);\n@@ -935,7 +930,8 @@ static void t_reftable_stack_add_performs_auto_compaction(void)\n \tstruct reftable_stack *st = NULL;\n \tstruct strbuf refname = STRBUF_INIT;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tint err, i, n = 20;\n+\tint err;\n+\tsize_t i, n = 20;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -955,10 +951,10 @@ static void t_reftable_stack_add_performs_auto_compaction(void)\n \t\tst->opts.disable_auto_compact = i != n;\n \n \t\tstrbuf_reset(&refname);\n-\t\tstrbuf_addf(&refname, \"branch-%04d\", i);\n+\t\tstrbuf_addf(&refname, \"branch-%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = refname.buf;\n \n-\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\terr = reftable_stack_add(st, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\t/*\n@@ -1039,10 +1035,8 @@ static void t_reftable_stack_compaction_concurrent(void)\n static void unclean_stack_close(struct reftable_stack *st)\n {\n \t/* break abstraction boundary to simulate unclean shutdown. */\n-\tint i = 0;\n-\tfor (; i < st->readers_len; i++) {\n+\tfor (size_t i = 0; i < st->readers_len; i++)\n \t\treftable_reader_free(st->readers[i]);\n-\t}\n \tst->readers_len = 0;\n \tFREE_AND_NULL(st->readers);\n }\n-- \n2.45.GIT\n\n"},{"id":"501686","messageId":"20240826173627.4525-4-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240826173627.4525-1-chandrapratap3519@gmail.com","subject":"[PATCH v3 3/6] t-reftable-stack: use Git's tempfile API instead of mkstemp()","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-26T17:29:43Z","receivedAt":"2024-08-26T17:37:10Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"Git's tempfile API defined by $GIT_DIR/tempfile.{c,h} provides\na unified interface for tempfile operations. Since reftable/stack.c\nuses this API for all its tempfile needs instead of raw functions\nlike mkstemp(), make the ported stack test strictly use Git's\ntempfile API as well.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 3ae7478fbf..5cb79ad8fd 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -76,7 +76,8 @@ static char *get_tmp_dir(int linenumber)\n static void t_read_file(void)\n {\n \tchar *fn = get_tmp_template(__LINE__);\n-\tint fd = mkstemp(fn);\n+\tstruct tempfile *tmp = mks_tempfile(fn);\n+\tint fd = get_tempfile_fd(tmp);\n \tchar out[1024] = \"line1\\n\\nline2\\nline3\";\n \tint n, err;\n \tchar **names = NULL;\n@@ -95,6 +96,7 @@ static void t_read_file(void)\n \t\tcheck_str(want[i], names[i]);\n \tfree_names(names);\n \t(void) remove(fn);\n+\tdelete_tempfile(&tmp);\n }\n \n static int write_test_ref(struct reftable_writer *wr, void *arg)\n-- \n2.45.GIT\n\n"},{"id":"501687","messageId":"20240826173627.4525-5-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240826173627.4525-1-chandrapratap3519@gmail.com","subject":"[PATCH v3 4/6] t-reftable-stack: use reftable_ref_record_equal() to compare ref records","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-26T17:29:44Z","receivedAt":"2024-08-26T17:37:13Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"In the current stack tests, ref records are compared for equality\nby sometimes using the dedicated function for ref-record comparison,\nreftable_ref_record_equal(), and sometimes by explicity comparing\ncontents of the ref records.\n\nReplace the latter instances of ref-record comparison with the\nformer to maintain uniformity throughout the test file.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 5cb79ad8fd..4c694329e8 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -173,7 +173,7 @@ static void t_reftable_stack_add_one(void)\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n \tcheck(!err);\n-\tcheck_str(\"master\", dest.value.symref);\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \tcheck_int(st->readers_len, >, 0);\n \n \tprintf(\"testing print functionality:\\n\");\n@@ -291,7 +291,7 @@ static void t_reftable_stack_transaction_api(void)\n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n \tcheck(!err);\n \tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n-\tcheck_str(\"master\", dest.value.symref);\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n-- \n2.45.GIT\n\n"},{"id":"501688","messageId":"20240826173627.4525-6-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240826173627.4525-1-chandrapratap3519@gmail.com","subject":"[PATCH v3 5/6] t-reftable-stack: add test for non-default compaction factor","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-26T17:29:45Z","receivedAt":"2024-08-26T17:37:15Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"In a recent codebase update (commit ae8e378430, merge branch\n'ps/reftable-write-options', 2024/05/13) the geometric factor used\nin auto-compaction of reftable tables was made configurable. Add\na test to verify the functionality introduced by this update.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 41 +++++++++++++++++++++++++++++----\n 1 file changed, 37 insertions(+), 4 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 4c694329e8..e8c137529e 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -837,12 +837,12 @@ static void t_empty_add(void)\n \treftable_stack_destroy(st2);\n }\n \n-static int fastlog2(uint64_t sz)\n+static int fastlogN(uint64_t sz, uint64_t N)\n {\n \tint l = 0;\n \tif (sz == 0)\n \t\treturn 0;\n-\tfor (; sz; sz /= 2)\n+\tfor (; sz; sz /= N)\n \t\tl++;\n \treturn l - 1;\n }\n@@ -875,11 +875,43 @@ static void t_reftable_stack_auto_compaction(void)\n \n \t\terr = reftable_stack_auto_compact(st);\n \t\tcheck(!err);\n-\t\tcheck(i < 3 || st->merged->stack_len < 2 * fastlog2(i));\n+\t\tcheck(i < 2 || st->merged->stack_len < 2 * fastlogN(i, 2));\n \t}\n \n \tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n-\t       (uint64_t)(N * fastlog2(N)));\n+\t       (uint64_t)(N * fastlogN(N, 2)));\n+\n+\treftable_stack_destroy(st);\n+\tclear_dir(dir);\n+}\n+\n+static void t_reftable_stack_auto_compaction_factor(void)\n+{\n+\tstruct reftable_write_options opts = {\n+\t\t.auto_compaction_factor = 5,\n+\t};\n+\tstruct reftable_stack *st = NULL;\n+\tchar *dir = get_tmp_dir(__LINE__);\n+\tint err;\n+\tsize_t N = 100;\n+\n+\terr = reftable_new_stack(&st, dir, &opts);\n+\tcheck(!err);\n+\n+\tfor (size_t i = 0; i < N; i++) {\n+\t\tchar name[20];\n+\t\tstruct reftable_ref_record ref = {\n+\t\t\t.refname = name,\n+\t\t\t.update_index = reftable_stack_next_update_index(st),\n+\t\t\t.value_type = REFTABLE_REF_VAL1,\n+\t\t};\n+\t\txsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n+\n+\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\tcheck(!err);\n+\n+\t\tcheck(i < 5 || st->merged->stack_len < 5 * fastlogN(i, 5));\n+\t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n@@ -1086,6 +1118,7 @@ int cmd_main(int argc, const char *argv[])\n \tTEST(t_reftable_stack_add_one(), \"add a single ref record to stack\");\n \tTEST(t_reftable_stack_add_performs_auto_compaction(), \"addition to stack triggers auto-compaction\");\n \tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_factor(), \"auto-compaction with non-default geometric factor\");\n \tTEST(t_reftable_stack_auto_compaction_fails_gracefully(), \"failure on auto-compaction\");\n \tTEST(t_reftable_stack_auto_compaction_with_locked_tables(), \"auto compaction with locked tables\");\n \tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n-- \n2.45.GIT\n\n"},{"id":"501689","messageId":"20240826173627.4525-7-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240826173627.4525-1-chandrapratap3519@gmail.com","subject":"[PATCH v3 6/6] t-reftable-stack: add test for stack iterators","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-26T17:29:46Z","receivedAt":"2024-08-26T17:37:18Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"reftable_stack_init_ref_iterator and reftable_stack_init_log_iterator\nas defined by reftable/stack.{c,h} initialize a stack iterator to\niterate over the ref and log records in a reftable stack respectively.\nSince these functions are not exercised by any of the existing tests,\nadd a test for them.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 80 +++++++++++++++++++++++++++++++++\n 1 file changed, 80 insertions(+)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex e8c137529e..112d954afd 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -550,6 +550,85 @@ static void t_reftable_stack_add(void)\n \tclear_dir(dir);\n }\n \n+static void t_reftable_stack_iterator(void)\n+{\n+\tstruct reftable_write_options opts = { 0 };\n+\tstruct reftable_stack *st = NULL;\n+\tchar *dir = get_tmp_dir(__LINE__);\n+\tstruct reftable_ref_record refs[10] = { 0 };\n+\tstruct reftable_log_record logs[10] = { 0 };\n+\tstruct reftable_iterator it = { 0 };\n+\tsize_t N = ARRAY_SIZE(refs), i;\n+\tint err;\n+\n+\terr = reftable_new_stack(&st, dir, &opts);\n+\tcheck(!err);\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\trefs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n+\t\trefs[i].update_index = i + 1;\n+\t\trefs[i].value_type = REFTABLE_REF_VAL1;\n+\t\tset_test_hash(refs[i].value.val1, i);\n+\n+\t\tlogs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n+\t\tlogs[i].update_index = i + 1;\n+\t\tlogs[i].value_type = REFTABLE_LOG_UPDATE;\n+\t\tlogs[i].value.update.email = xstrdup(\"johndoe@invalid\");\n+\t\tlogs[i].value.update.message = xstrdup(\"commit\\n\");\n+\t\tset_test_hash(logs[i].value.update.new_hash, i);\n+\t}\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\terr = reftable_stack_add(st, write_test_ref, &refs[i]);\n+\t\tcheck(!err);\n+\t}\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\tstruct write_log_arg arg = {\n+\t\t\t.log = &logs[i],\n+\t\t\t.update_index = reftable_stack_next_update_index(st),\n+\t\t};\n+\t\terr = reftable_stack_add(st, write_test_log, &arg);\n+\t\tcheck(!err);\n+\t}\n+\n+\treftable_stack_init_ref_iterator(st, &it);\n+\treftable_iterator_seek_ref(&it, refs[0].refname);\n+\tfor (i = 0; ; i++) {\n+\t\tstruct reftable_ref_record ref = { 0 };\n+\t\terr = reftable_iterator_next_ref(&it, &ref);\n+\t\tif (err > 0)\n+\t\t\tbreak;\n+\t\tcheck(!err);\n+\t\tcheck(reftable_ref_record_equal(&ref, &refs[i], GIT_SHA1_RAWSZ));\n+\t\treftable_ref_record_release(&ref);\n+\t}\n+\tcheck_int(i, ==, N);\n+\n+\treftable_iterator_destroy(&it);\n+\n+\treftable_stack_init_log_iterator(st, &it);\n+\treftable_iterator_seek_log(&it, logs[0].refname);\n+\tfor (i = 0; ; i++) {\n+\t\tstruct reftable_log_record log = { 0 };\n+\t\terr = reftable_iterator_next_log(&it, &log);\n+\t\tif (err > 0)\n+\t\t\tbreak;\n+\t\tcheck(!err);\n+\t\tcheck(reftable_log_record_equal(&log, &logs[i], GIT_SHA1_RAWSZ));\n+\t\treftable_log_record_release(&log);\n+\t}\n+\tcheck_int(i, ==, N);\n+\n+\treftable_stack_destroy(st);\n+\treftable_iterator_destroy(&it);\n+\tfor (i = 0; i < N; i++) {\n+\t\treftable_ref_record_release(&refs[i]);\n+\t\treftable_log_record_release(&logs[i]);\n+\t}\n+\tclear_dir(dir);\n+}\n+\n static void t_reftable_stack_log_normalize(void)\n {\n \tint err = 0;\n@@ -1125,6 +1204,7 @@ int cmd_main(int argc, const char *argv[])\n \tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n \tTEST(t_reftable_stack_compaction_with_locked_tables(), \"compaction with locked tables\");\n \tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n+\tTEST(t_reftable_stack_iterator(), \"log and ref iterator for reftable stack\");\n \tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n \tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n \tTEST(t_reftable_stack_tombstone(), \"'tombstone' refs in stack\");\n-- \n2.45.GIT\n\n"},{"id":"501690","messageId":"xmqqcylvjhtt.fsf@gitster.g","threadId":"61911","inReplyTo":"20240826173627.4525-1-chandrapratap3519@gmail.com","subject":"Re: [GSoC][PATCH v3 0/6] t: port reftable/stack_test.c to the unit testing framework","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-08-26T17:48:46Z","receivedAt":"2024-08-26T17:48:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Chandra Pratap <chandrapratap3519@gmail.com> writes:\n\n> Changes in v2:\n> - Use 'size_t' as array index instead of 'int' in a test that is\n>   modified in patch 2.\n> - Fix a coding style violation in the newly introduced test in\n>   patch 6.\n\nIf I recall correctly, the first iteration conflicted too badly with\nother topics in flight, and kept out of 'seen' so far.  Have you\ntested this series, not just standalone, but see how well it works\ntogether with other topics by creating trial merges of it into\n'next' and 'seen'?\n\nIt some other topics that conflict with what you do in this topic\nhave advanced (or better yet, graduated to 'master'), it may not be\na bad idea to consider rebasing the topic to more recent 'master',\npossibly merging other topics into it first.\n\nThanks.\n\n"},{"id":"501692","messageId":"CA+J6zkQKc=NmBnuih9Y+2oMjQtVOhKxJ_RfOLGxvWxcBbMH+kA@mail.gmail.com","threadId":"61911","inReplyTo":"xmqqcylvjhtt.fsf@gitster.g","subject":"Re: [GSoC][PATCH v3 0/6] t: port reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-08-26T18:34:06Z","receivedAt":"2024-08-26T18:34:34Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"On Mon, 26 Aug 2024 at 23:18, Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Chandra Pratap <chandrapratap3519@gmail.com> writes:\n>\n> > Changes in v2:\n> > - Use 'size_t' as array index instead of 'int' in a test that is\n> >   modified in patch 2.\n> > - Fix a coding style violation in the newly introduced test in\n> >   patch 6.\n>\n> If I recall correctly, the first iteration conflicted too badly with\n> other topics in flight, and kept out of 'seen' so far.\n\nYeah, I remember Patrick was working on some other patch\nseries involving 'reftable/stack_test.c' which caused conflicts\nwith this series. I _did_ make sure to rebase this series on top\nof that one.\n\n> Have you tested this series, not just standalone, but see how well\n> it works together with other topics by creating trial merges of it into\n> 'next' and 'seen'?\n\nI did notice some small Makefile conflicts with the latest 'master'\non the GitHub CI, but other than that, no, I haven't checked the\npatch against 'next' or 'seen'.\n\n> It some other topics that conflict with what you do in this topic\n> have advanced (or better yet, graduated to 'master'), it may not be\n> a bad idea to consider rebasing the topic to more recent 'master',\n> possibly merging other topics into it first.\n\nI generally make sure to rebase my patches on top of the latest\nmaster before sending them to the mailing list. I'll add 'next' and\n'seen' to my checklist as well.\n"},{"id":"501695","messageId":"xmqqwmk3hzly.fsf@gitster.g","threadId":"61911","inReplyTo":"CA+J6zkQKc=NmBnuih9Y+2oMjQtVOhKxJ_RfOLGxvWxcBbMH+kA@mail.gmail.com","subject":"Re: [GSoC][PATCH v3 0/6] t: port reftable/stack_test.c to the unit testing framework","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-08-26T19:07:37Z","receivedAt":"2024-08-26T19:07:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Chandra Pratap <chandrapratap3519@gmail.com> writes:\n\n> I generally make sure to rebase my patches on top of the latest\n> master before sending them to the mailing list.\n\nThis is generally considered a bad practice.  You shouldn't rebase\nunless there is a compelling reason (e.g., API you rely on\ndisappeared and you need to reimplement your change differently, you\nrewrote some code based on an old version, but the code you touched\nhave been enhanced so you'd need to rewrite the new part).\n\nOn the other hand, you should realize that every topic first is\nqueued to 'seen' and only after it proves that it plays well with\nother topics in flight, it is considered to advance to 'next'.  So\nif you conflict with other topics that makes you conflict when\nmerged to either 'next' or 'seen', you'd be better off creating a\nmore suitable base than 'master' and then build on top of it.\n\nAn effective way to do so is to mimick how topics like\n\n  https://lore.kernel.org/git/cover.1724308389.git.ps@pks.im/\n\nare built.  This one says:\n\n    This patch series continues to build on top of 25673b1c47 (The third\n    batch, 2024-08-07) with Junio's ps/reftable-stack-compaction at\n    f234df07f6 (reftable/stack: handle locked tables during auto-compaction,\n    2024-08-08) merged into it.\n\nin its cover letter, allowing anybody to reconstruct the base with\n\n    $ git checkout -b ps/reftable-drop-generic 25673b1c47\n    $ git merge f234df07f6\n\nbefore running \"git am\" to apply the series on top.  Because it\n_depends_ on ps/reftable-stack-compaction, the resulting topic\ncannot be merged to anywhere without dragging the base topic with\nit, so such a dependency needs to be already fairly stable (e.g.,\nhave been thoroughly reviewed and merged to 'next'), but then the\ntopic will have less chance to conflict when merged to 'next' and\n'seen'.\n\nThanks.\n"},{"id":"501696","messageId":"xmqqo75fhyqb.fsf@gitster.g","threadId":"61911","inReplyTo":"xmqqwmk3hzly.fsf@gitster.g","subject":"Re: [GSoC][PATCH v3 0/6] t: port reftable/stack_test.c to the unit testing framework","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-08-26T19:26:36Z","receivedAt":"2024-08-26T19:26:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> On the other hand, you should realize that every topic first is\n> queued to 'seen' and only after it proves that it plays well with\n> other topics in flight, it is considered to advance to 'next'.  So\n> if you conflict with other topics that makes you conflict when\n> merged to either 'next' or 'seen', you'd be better off creating a\n> more suitable base than 'master' and then build on top of it.\n\n$ git log --first-parent --oneline \\\n  cp/unit-test-reftable-stack..next -- reftable/stack_test.c\n\ntells me that Patrick's \"concurrent compaction\" and \"drop generic\"\nare the big two topics that touch reftable/stack_test.c file that\nyou are removing.  As the former already depends on the latter,\nit may make sense to \n\n    $ git checkout -b cp/unit-test-reftable-stack master\n    $ git merge ps/reftable-concurrent-compaction\n\nto prepare the base, and then rebuild these patches on top of it.\nThere is another topic jk/mark-unused-parameters that touches the\nsame file, but the conflict it causes is trivial.\n\nIn any case, the cover letter is a good place to describe how you\nprepared such a custom base (as opposed to \"the patches in this\ntopic apply cleanly to any recent tip of 'master', as the topic\ntouches a relatively dormant calm area of the code base\", in which\ncase you do not say anything).\n\nThanks.\n\n"},{"id":"502139","messageId":"20240904150132.11567-1-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240826173627.4525-1-chandrapratap3519@gmail.com","subject":"[GSoC][PATCH v4 0/6] t: port reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-04T14:38:00Z","receivedAt":"2024-09-04T15:01:56Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"The reftable library comes with self tests, which are exercised\nas part of the usual end-to-end tests and are designed to\nobserve the end-user visible effects of Git commands. What it\nexercises, however, is a better match for the unit-testing\nframework, merged at 8bf6fbd0 (Merge branch 'js/doc-unit-tests',\n2023-12-09), which is designed to observe how low level\nimplementation details, at the level of sequences of individual\nfunction calls, behave.\n\nHence, port reftable/stack_test.c to the unit testing framework and\nimprove upon the ported test. The first patch in the series moves\nthe test to the unit testing framework, and the rest of the patches\nimprove upon the ported test.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n\n---\nChanges in v4:\n- v3 of this patch series had conflicts with 85da2a2ab6 (Merge branch\n  'ps/reftable-concurrent-compaction') and e49d2472d2 (Merge branch\n  'ps/reftable-drop-generic').\n\n  These branches have since graduated to 'master', so this version\n  rebases the commits on top of the latest 'master'. The resulting\n  branch has been tested to have no conflicts with 'next' and\n  trivial ones with 'seen'.\n\nCI/PR: https://github.com/gitgitgadget/git/pull/1762\n\nChandra Pratap(6):\nt: move reftable/stack_test.c to the unit testing framework\nt: harmonize t-reftable-stack.c with coding guidelines\nt-reftable-stack: use Git's tempfile API instead of mkstemp()\nt-reftable-stack: use reftable_ref_record_equal() to compare ref records\nt-reftable-stack: add test for non-default compaction factor\nt-reftable-stack: add test for stack iterators\n\nMakefile                                                 |   2 +-\nreftable/reftable-tests.h                                |   1 -\nt/helper/test-reftable.c                                 |   1 -\nreftable/stack_test.c => t/unit-tests/t-reftable-stack.c | 611 +++++++++++++++++++--------------\n4 files changed, 360 insertions(+), 255 deletions(-)\n\nRange-diff against v3:\n<rebase commits>\n  1:  d094b8f94d ! 184:  cdfb49f5d5 t: move reftable/stack_test.c to the unit testing framework\n    @@ Commit message\n         Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n\n      ## Makefile ##\n    -@@ Makefile: UNIT_TEST_PROGRAMS += t-reftable-basics\n    - UNIT_TEST_PROGRAMS += t-reftable-merged\n    +@@ Makefile: UNIT_TEST_PROGRAMS += t-reftable-merged\n      UNIT_TEST_PROGRAMS += t-reftable-pq\n    + UNIT_TEST_PROGRAMS += t-reftable-readwrite\n      UNIT_TEST_PROGRAMS += t-reftable-record\n     +UNIT_TEST_PROGRAMS += t-reftable-stack\n      UNIT_TEST_PROGRAMS += t-reftable-tree\n      UNIT_TEST_PROGRAMS += t-strbuf\n      UNIT_TEST_PROGRAMS += t-strcmp-offset\n    -@@ Makefile: REFTABLE_OBJS += reftable/writer.o\n    - REFTABLE_TEST_OBJS += reftable/block_test.o\n    - REFTABLE_TEST_OBJS += reftable/dump.o\n    - REFTABLE_TEST_OBJS += reftable/readwrite_test.o\n    +@@ Makefile: REFTABLE_OBJS += reftable/stack.o\n    + REFTABLE_OBJS += reftable/tree.o\n    + REFTABLE_OBJS += reftable/writer.o\n    +\n     -REFTABLE_TEST_OBJS += reftable/stack_test.o\n      REFTABLE_TEST_OBJS += reftable/test_framework.o\n\n      TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))\n\n      ## reftable/reftable-tests.h ##\n    -@@ reftable/reftable-tests.h: int basics_test_main(int argc, const char **argv);\n    - int block_test_main(int argc, const char **argv);\n    - int record_test_main(int argc, const char **argv);\n    - int readwrite_test_main(int argc, const char **argv);\n    +@@ reftable/reftable-tests.h: license that can be found in the LICENSE file or at\n    + #ifndef REFTABLE_TESTS_H\n    + #define REFTABLE_TESTS_H\n    +\n     -int stack_test_main(int argc, const char **argv);\n    - int reftable_dump_main(int argc, char *const *argv);\n\n      #endif\n\n      ## t/helper/test-reftable.c ##\n    -@@ t/helper/test-reftable.c: int cmd__reftable(int argc, const char **argv)\n    +@@\n    + int cmd__reftable(int argc, const char **argv)\n    + {\n      \t/* test from simple to complex. */\n    - \tblock_test_main(argc, argv);\n    - \treadwrite_test_main(argc, argv);\n     -\tstack_test_main(argc, argv);\n      \treturn 0;\n      }\n    @@ t/unit-tests/t-reftable-stack.c: license that can be found in the LICENSE file o\n     -\n     -#include \"system.h\"\n     -\n    +-#include \"copy.h\"\n     -#include \"reftable-reader.h\"\n     -#include \"merged.h\"\n     -#include \"basics.h\"\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_add_one(void)\n     +\tcheck_str(\"master\", dest.value.symref);\n     +\tcheck_int(st->readers_len, >, 0);\n\n    - \tprintf(\"testing print functionality:\\n\");\n    - \terr = reftable_stack_print_directory(dir, GIT_SHA1_FORMAT_ID);\n    --\tEXPECT_ERR(err);\n    -+\tcheck(!err);\n    -\n    - \terr = reftable_stack_print_directory(dir, GIT_SHA256_FORMAT_ID);\n    --\tEXPECT(err == REFTABLE_FORMAT_ERROR);\n    -+\tcheck_int(err, ==, REFTABLE_FORMAT_ERROR);\n    -\n      #ifndef GIT_WINDOWS_NATIVE\n      \tstrbuf_addstr(&scratch, dir);\n      \tstrbuf_addstr(&scratch, \"/tables.list\");\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_transaction_api\n      \t\t * all tables in the stack.\n      \t\t */\n      \t\tif (i != n)\n    --\t\t\tEXPECT(st->merged->stack_len == i + 1);\n    -+\t\t\tcheck_int(st->merged->stack_len, ==, i + 1);\n    +-\t\t\tEXPECT(st->merged->readers_len == i + 1);\n    ++\t\t\tcheck_int(st->merged->readers_len, ==, i + 1);\n      \t\telse\n    --\t\t\tEXPECT(st->merged->stack_len == 1);\n    -+\t\t\tcheck_int(st->merged->stack_len, ==, 1);\n    +-\t\t\tEXPECT(st->merged->readers_len == 1);\n    ++\t\t\tcheck_int(st->merged->readers_len, ==, 1);\n      \t}\n\n      \treftable_stack_destroy(st);\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_auto_compaction\n\n      \terr = reftable_stack_add(st, write_test_ref, &ref);\n     -\tEXPECT_ERR(err);\n    --\tEXPECT(st->merged->stack_len == 1);\n    +-\tEXPECT(st->merged->readers_len == 1);\n     -\tEXPECT(st->stats.attempts == 0);\n     -\tEXPECT(st->stats.failures == 0);\n     +\tcheck(!err);\n    -+\tcheck_int(st->merged->stack_len, ==, 1);\n    ++\tcheck_int(st->merged->readers_len, ==, 1);\n     +\tcheck_int(st->stats.attempts, ==, 0);\n     +\tcheck_int(st->stats.failures, ==, 0);\n\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_auto_compaction\n      \tref.update_index = 2;\n      \terr = reftable_stack_add(st, write_test_ref, &ref);\n     -\tEXPECT_ERR(err);\n    --\tEXPECT(st->merged->stack_len == 2);\n    +-\tEXPECT(st->merged->readers_len == 2);\n     -\tEXPECT(st->stats.attempts == 1);\n     -\tEXPECT(st->stats.failures == 1);\n     +\tcheck(!err);\n    -+\tcheck_int(st->merged->stack_len, ==, 2);\n    ++\tcheck_int(st->merged->readers_len, ==, 2);\n     +\tcheck_int(st->stats.attempts, ==, 1);\n     +\tcheck_int(st->stats.failures, ==, 1);\n\n      \treftable_stack_destroy(st);\n      \tstrbuf_release(&table_path);\n    -@@ t/unit-tests/t-reftable-stack.c: static int write_error(struct reftable_writer *wr, void *arg)\n    +@@ t/unit-tests/t-reftable-stack.c: static int write_error(struct reftable_writer *wr UNUSED, void *arg)\n      \treturn *((int *)arg);\n      }\n\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reflog_expire(void)\n\n      \t/* cleanup */\n      \treftable_stack_destroy(st);\n    -@@ t/unit-tests/t-reftable-stack.c: static int write_nothing(struct reftable_writer *wr, void *arg)\n    +@@ t/unit-tests/t-reftable-stack.c: static int write_nothing(struct reftable_writer *wr, void *arg UNUSED)\n      \treturn 0;\n      }\n\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_auto_compaction\n\n      \t\terr = reftable_stack_auto_compact(st);\n     -\t\tEXPECT_ERR(err);\n    --\t\tEXPECT(i < 3 || st->merged->stack_len < 2 * fastlog2(i));\n    +-\t\tEXPECT(i < 3 || st->merged->readers_len < 2 * fastlog2(i));\n     +\t\tcheck(!err);\n    -+\t\tcheck(i < 3 || st->merged->stack_len < 2 * fastlog2(i));\n    ++\t\tcheck(i < 3 || st->merged->readers_len < 2 * fastlog2(i));\n      \t}\n\n     -\tEXPECT(reftable_stack_compaction_stats(st)->entries_written <\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_auto_compaction\n     +\tcheck(!err);\n\n      \twrite_n_ref_tables(st, 5);\n    --\tEXPECT(st->merged->stack_len == 5);\n    -+\tcheck_int(st->merged->stack_len, ==, 5);\n    +-\tEXPECT(st->merged->readers_len == 5);\n    ++\tcheck_int(st->merged->readers_len, ==, 5);\n\n      \t/*\n      \t * Given that all tables we have written should be roughly the same\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_auto_compaction\n      \terr = reftable_stack_auto_compact(st);\n     -\tEXPECT_ERR(err);\n     -\tEXPECT(st->stats.failures == 0);\n    --\tEXPECT(st->merged->stack_len == 4);\n    +-\tEXPECT(st->merged->readers_len == 4);\n     +\tcheck(!err);\n     +\tcheck_int(st->stats.failures, ==, 0);\n    -+\tcheck_int(st->merged->stack_len, ==, 4);\n    ++\tcheck_int(st->merged->readers_len, ==, 4);\n\n      \treftable_stack_destroy(st);\n      \tstrbuf_release(&buf);\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_add_performs_au\n      \t\t * all tables in the stack.\n      \t\t */\n      \t\tif (i != n)\n    --\t\t\tEXPECT(st->merged->stack_len == i + 1);\n    -+\t\t\tcheck_int(st->merged->stack_len, ==, i + 1);\n    +-\t\t\tEXPECT(st->merged->readers_len == i + 1);\n    ++\t\t\tcheck_int(st->merged->readers_len, ==, i + 1);\n      \t\telse\n    --\t\t\tEXPECT(st->merged->stack_len == 1);\n    -+\t\t\tcheck_int(st->merged->stack_len, ==, 1);\n    +-\t\t\tEXPECT(st->merged->readers_len == 1);\n    ++\t\t\tcheck_int(st->merged->readers_len, ==, 1);\n      \t}\n\n      \treftable_stack_destroy(st);\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_compaction_with\n     +\tcheck(!err);\n\n      \twrite_n_ref_tables(st, 3);\n    --\tEXPECT(st->merged->stack_len == 3);\n    -+\tcheck_int(st->merged->stack_len, ==, 3);\n    +-\tEXPECT(st->merged->readers_len == 3);\n    ++\tcheck_int(st->merged->readers_len, ==, 3);\n\n      \t/* Lock one of the tables that we're about to compact. */\n      \tstrbuf_reset(&buf);\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_compaction_with\n      \terr = reftable_stack_compact_all(st, NULL);\n     -\tEXPECT(err == REFTABLE_LOCK_ERROR);\n     -\tEXPECT(st->stats.failures == 1);\n    --\tEXPECT(st->merged->stack_len == 3);\n    +-\tEXPECT(st->merged->readers_len == 3);\n     +\tcheck_int(err, ==, REFTABLE_LOCK_ERROR);\n     +\tcheck_int(st->stats.failures, ==, 1);\n    -+\tcheck_int(st->merged->stack_len, ==, 3);\n    ++\tcheck_int(st->merged->readers_len, ==, 3);\n\n      \treftable_stack_destroy(st);\n      \tstrbuf_release(&buf);\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_compaction_conc\n      \tclear_dir(dir);\n      }\n\n    --int stack_test_main(int argc, const char *argv[])\n    -+int cmd_main(int argc, const char *argv[])\n    +-static void test_reftable_stack_read_across_reload(void)\n    ++static void t_reftable_stack_read_across_reload(void)\n    + {\n    + \tstruct reftable_write_options opts = { 0 };\n    + \tstruct reftable_stack *st1 = NULL, *st2 = NULL;\n    +@@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_read_across_reload(void)\n    +\n    + \t/* Create a first stack and set up an iterator for it. */\n    + \terr = reftable_new_stack(&st1, dir, &opts);\n    +-\tEXPECT_ERR(err);\n    ++\tcheck(!err);\n    + \twrite_n_ref_tables(st1, 2);\n    +-\tEXPECT(st1->merged->readers_len == 2);\n    ++\tcheck_int(st1->merged->readers_len, ==, 2);\n    + \treftable_stack_init_ref_iterator(st1, &it);\n    + \terr = reftable_iterator_seek_ref(&it, \"\");\n    +-\tEXPECT_ERR(err);\n    ++\tcheck(!err);\n    +\n    + \t/* Set up a second stack for the same directory and compact it. */\n    + \terr = reftable_new_stack(&st2, dir, &opts);\n    +-\tEXPECT_ERR(err);\n    +-\tEXPECT(st2->merged->readers_len == 2);\n    ++\tcheck(!err);\n    ++\tcheck_int(st2->merged->readers_len, ==, 2);\n    + \terr = reftable_stack_compact_all(st2, NULL);\n    +-\tEXPECT_ERR(err);\n    +-\tEXPECT(st2->merged->readers_len == 1);\n    ++\tcheck(!err);\n    ++\tcheck_int(st2->merged->readers_len, ==, 1);\n    +\n    + \t/*\n    + \t * Verify that we can continue to use the old iterator even after we\n    + \t * have reloaded its stack.\n    + \t */\n    + \terr = reftable_stack_reload(st1);\n    +-\tEXPECT_ERR(err);\n    +-\tEXPECT(st1->merged->readers_len == 1);\n    ++\tcheck(!err);\n    ++\tcheck_int(st1->merged->readers_len, ==, 1);\n    + \terr = reftable_iterator_next_ref(&it, &rec);\n    +-\tEXPECT_ERR(err);\n    +-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0000\"));\n    ++\tcheck(!err);\n    ++\tcheck_str(rec.refname, \"refs/heads/branch-0000\");\n    + \terr = reftable_iterator_next_ref(&it, &rec);\n    +-\tEXPECT_ERR(err);\n    +-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0001\"));\n    ++\tcheck(!err);\n    ++\tcheck_str(rec.refname, \"refs/heads/branch-0001\");\n    + \terr = reftable_iterator_next_ref(&it, &rec);\n    +-\tEXPECT(err > 0);\n    ++\tcheck_int(err, >, 0);\n    +\n    + \treftable_ref_record_release(&rec);\n    + \treftable_iterator_destroy(&it);\n    +@@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_read_across_reload(void)\n    + \tclear_dir(dir);\n    + }\n    +\n    +-static void test_reftable_stack_reload_with_missing_table(void)\n    ++static void t_reftable_stack_reload_with_missing_table(void)\n    + {\n    + \tstruct reftable_write_options opts = { 0 };\n    + \tstruct reftable_stack *st = NULL;\n    +@@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_reload_with_missing_table(void)\n    +\n    + \t/* Create a first stack and set up an iterator for it. */\n    + \terr = reftable_new_stack(&st, dir, &opts);\n    +-\tEXPECT_ERR(err);\n    ++\tcheck(!err);\n    + \twrite_n_ref_tables(st, 2);\n    +-\tEXPECT(st->merged->readers_len == 2);\n    ++\tcheck_int(st->merged->readers_len, ==, 2);\n    + \treftable_stack_init_ref_iterator(st, &it);\n    + \terr = reftable_iterator_seek_ref(&it, \"\");\n    +-\tEXPECT_ERR(err);\n    ++\tcheck(!err);\n    +\n    + \t/*\n    + \t * Update the tables.list file with some garbage data, while reusing\n    +@@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_reload_with_missing_table(void)\n    + \tstrbuf_addf(&table_path, \"%s.lock\", st->list_file);\n    + \twrite_file_buf(table_path.buf, content.buf, content.len);\n    + \terr = rename(table_path.buf, st->list_file);\n    +-\tEXPECT_ERR(err);\n    ++\tcheck(!err);\n    +\n    + \terr = reftable_stack_reload(st);\n    +-\tEXPECT(err == -4);\n    +-\tEXPECT(st->merged->readers_len == 2);\n    ++\tcheck_int(err, ==, -4);\n    ++\tcheck_int(st->merged->readers_len, ==, 2);\n    +\n    + \t/*\n    + \t * Even though the reload has failed, we should be able to continue\n    + \t * using the iterator.\n    + \t*/\n    + \terr = reftable_iterator_next_ref(&it, &rec);\n    +-\tEXPECT_ERR(err);\n    +-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0000\"));\n    ++\tcheck(!err);\n    ++\tcheck_str(rec.refname, \"refs/heads/branch-0000\");\n    + \terr = reftable_iterator_next_ref(&it, &rec);\n    +-\tEXPECT_ERR(err);\n    +-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0001\"));\n    ++\tcheck(!err);\n    ++\tcheck_str(rec.refname, \"refs/heads/branch-0001\");\n    + \terr = reftable_iterator_next_ref(&it, &rec);\n    +-\tEXPECT(err > 0);\n    ++\tcheck_int(err, >, 0);\n    +\n    + \treftable_ref_record_release(&rec);\n    + \treftable_iterator_destroy(&it);\n    +@@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_reload_with_missing_table(void)\n    + \tclear_dir(dir);\n    + }\n    +\n    +-int stack_test_main(int argc UNUSED, const char *argv[] UNUSED)\n    ++int cmd_main(int argc UNUSED, const char *argv[] UNUSED)\n      {\n     -\tRUN_TEST(test_empty_add);\n     -\tRUN_TEST(test_read_file);\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_compaction_conc\n     -\tRUN_TEST(test_reftable_stack_auto_compaction_fails_gracefully);\n     -\tRUN_TEST(test_reftable_stack_update_index_check);\n     -\tRUN_TEST(test_reftable_stack_uptodate);\n    +-\tRUN_TEST(test_reftable_stack_read_across_reload);\n    +-\tRUN_TEST(test_reftable_stack_reload_with_missing_table);\n     -\tRUN_TEST(test_suggest_compaction_segment);\n     -\tRUN_TEST(test_suggest_compaction_segment_nothing);\n     -\treturn 0;\n    @@ t/unit-tests/t-reftable-stack.c: static void test_reftable_stack_compaction_conc\n     +\tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n     +\tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n     +\tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n    ++\tTEST(t_reftable_stack_read_across_reload(), \"reading stack works across reloads\");\n    ++\tTEST(t_reftable_stack_reload_with_missing_table(), \"reading stack with garbage tables\");\n     +\tTEST(t_reftable_stack_tombstone(), \"'tombstone' refs in stack\");\n     +\tTEST(t_reftable_stack_transaction_api(), \"update transaction to stack\");\n     +\tTEST(t_reftable_stack_transaction_api_performs_auto_compaction(), \"update transaction triggers auto-compaction\");\n  2:  838ccc63a7 ! 185:  e37be61cbe t: harmonize t-reftable-stack.c with coding guidelines\n    @@ t/unit-tests/t-reftable-stack.c: static void t_read_file(void)\n      \t(void) remove(fn);\n      }\n     @@ t/unit-tests/t-reftable-stack.c: static void write_n_ref_tables(struct reftable_stack *st,\n    - \t\t\t.value_type = REFTABLE_REF_VAL1,\n      \t\t};\n\n    + \t\tstrbuf_reset(&buf);\n     -\t\tstrbuf_addf(&buf, \"refs/heads/branch-%04u\", (unsigned) i);\n     +\t\tstrbuf_addf(&buf, \"refs/heads/branch-%04\"PRIuMAX, (uintmax_t)i);\n      \t\tref.refname = buf.buf;\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add_performs_auto_\n      \t\tcheck(!err);\n\n      \t\t/*\n    -@@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_compaction_concurrent(void)\n    - static void unclean_stack_close(struct reftable_stack *st)\n    - {\n    - \t/* break abstraction boundary to simulate unclean shutdown. */\n    --\tint i = 0;\n    --\tfor (; i < st->readers_len; i++) {\n    -+\tfor (size_t i = 0; i < st->readers_len; i++)\n    - \t\treftable_reader_free(st->readers[i]);\n    --\t}\n    - \tst->readers_len = 0;\n    - \tFREE_AND_NULL(st->readers);\n    - }\n  3:  2a151c299c = 186:  449b9e5e26 t-reftable-stack: use Git's tempfile API instead of mkstemp()\n  4:  fb5073da2c ! 187:  a4f1a8e93a t-reftable-stack: use reftable_ref_record_equal() to compare ref records\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add_one(void)\n     +\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n      \tcheck_int(st->readers_len, >, 0);\n\n    - \tprintf(\"testing print functionality:\\n\");\n    + #ifndef GIT_WINDOWS_NATIVE\n     @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_transaction_api(void)\n      \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n      \tcheck(!err);\n  5:  028fa6f70b ! 188:  b5dce8c505 t-reftable-stack: add test for non-default compaction factor\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_auto_compaction(vo\n\n      \t\terr = reftable_stack_auto_compact(st);\n      \t\tcheck(!err);\n    --\t\tcheck(i < 3 || st->merged->stack_len < 2 * fastlog2(i));\n    -+\t\tcheck(i < 2 || st->merged->stack_len < 2 * fastlogN(i, 2));\n    +-\t\tcheck(i < 3 || st->merged->readers_len < 2 * fastlog2(i));\n    ++\t\tcheck(i < 2 || st->merged->readers_len < 2 * fastlogN(i, 2));\n      \t}\n\n      \tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_auto_compaction(vo\n     +\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n     +\t\tcheck(!err);\n     +\n    -+\t\tcheck(i < 5 || st->merged->stack_len < 5 * fastlogN(i, 5));\n    ++\t\tcheck(i < 5 || st->merged->readers_len < 5 * fastlogN(i, 5));\n     +\t}\n\n      \treftable_stack_destroy(st);\n      \tclear_dir(dir);\n    -@@ t/unit-tests/t-reftable-stack.c: int cmd_main(int argc, const char *argv[])\n    +@@ t/unit-tests/t-reftable-stack.c: int cmd_main(int argc UNUSED, const char *argv[] UNUSED)\n      \tTEST(t_reftable_stack_add_one(), \"add a single ref record to stack\");\n      \tTEST(t_reftable_stack_add_performs_auto_compaction(), \"addition to stack triggers auto-compaction\");\n      \tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n  6:  fa0d358e65 ! 189:  8081831ce6 t-reftable-stack: add test for stack iterators\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add(void)\n      static void t_reftable_stack_log_normalize(void)\n      {\n      \tint err = 0;\n    -@@ t/unit-tests/t-reftable-stack.c: int cmd_main(int argc, const char *argv[])\n    +@@ t/unit-tests/t-reftable-stack.c: int cmd_main(int argc UNUSED, const char *argv[] UNUSED)\n      \tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n      \tTEST(t_reftable_stack_compaction_with_locked_tables(), \"compaction with locked tables\");\n      \tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n     +\tTEST(t_reftable_stack_iterator(), \"log and ref iterator for reftable stack\");\n      \tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n      \tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n    - \tTEST(t_reftable_stack_tombstone(), \"'tombstone' refs in stack\");\n    + \tTEST(t_reftable_stack_read_across_reload(), \"reading stack works across reloads\");\n\n"},{"id":"502140","messageId":"20240904150132.11567-2-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240904150132.11567-1-chandrapratap3519@gmail.com","subject":"[PATCH v4 1/6] t: move reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-04T14:38:01Z","receivedAt":"2024-09-04T15:01:59Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"reftable/stack_test.c exercises the functions defined in\nreftable/stack.{c, h}. Migrate reftable/stack_test.c to the\nunit testing framework. Migration involves refactoring the tests\nto use the unit testing framework instead of reftable's test\nframework and renaming the tests to be in-line with unit-tests'\nstandards.\n\nSince some of the tests use set_test_hash() defined by\nreftable/test_framework.{c, h} but these files are not\n'#included' in the test file, copy this function in the\nported test file.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n Makefile                                      |   2 +-\n reftable/reftable-tests.h                     |   1 -\n t/helper/test-reftable.c                      |   1 -\n .../unit-tests/t-reftable-stack.c             | 429 +++++++++---------\n 4 files changed, 214 insertions(+), 219 deletions(-)\n rename reftable/stack_test.c => t/unit-tests/t-reftable-stack.c (76%)\n\ndiff --git a/Makefile b/Makefile\nindex 91f65d7dc5..1cbc2d61ae 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1349,6 +1349,7 @@ UNIT_TEST_PROGRAMS += t-reftable-merged\n UNIT_TEST_PROGRAMS += t-reftable-pq\n UNIT_TEST_PROGRAMS += t-reftable-readwrite\n UNIT_TEST_PROGRAMS += t-reftable-record\n+UNIT_TEST_PROGRAMS += t-reftable-stack\n UNIT_TEST_PROGRAMS += t-reftable-tree\n UNIT_TEST_PROGRAMS += t-strbuf\n UNIT_TEST_PROGRAMS += t-strcmp-offset\n@@ -2691,7 +2692,6 @@ REFTABLE_OBJS += reftable/stack.o\n REFTABLE_OBJS += reftable/tree.o\n REFTABLE_OBJS += reftable/writer.o\n \n-REFTABLE_TEST_OBJS += reftable/stack_test.o\n REFTABLE_TEST_OBJS += reftable/test_framework.o\n \n TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))\ndiff --git a/reftable/reftable-tests.h b/reftable/reftable-tests.h\nindex 5d725c69c7..05f8d2d5bc 100644\n--- a/reftable/reftable-tests.h\n+++ b/reftable/reftable-tests.h\n@@ -9,6 +9,5 @@ license that can be found in the LICENSE file or at\n #ifndef REFTABLE_TESTS_H\n #define REFTABLE_TESTS_H\n \n-int stack_test_main(int argc, const char **argv);\n \n #endif\ndiff --git a/t/helper/test-reftable.c b/t/helper/test-reftable.c\nindex ce5a94fbd3..d27d7ee798 100644\n--- a/t/helper/test-reftable.c\n+++ b/t/helper/test-reftable.c\n@@ -12,7 +12,6 @@\n int cmd__reftable(int argc, const char **argv)\n {\n \t/* test from simple to complex. */\n-\tstack_test_main(argc, argv);\n \treturn 0;\n }\n \ndiff --git a/reftable/stack_test.c b/t/unit-tests/t-reftable-stack.c\nsimilarity index 76%\nrename from reftable/stack_test.c\nrename to t/unit-tests/t-reftable-stack.c\nindex 89cb2be19f..de28fac466 100644\n--- a/reftable/stack_test.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -6,22 +6,18 @@ license that can be found in the LICENSE file or at\n https://developers.google.com/open-source/licenses/bsd\n */\n \n-#include \"stack.h\"\n-\n-#include \"system.h\"\n-\n-#include \"copy.h\"\n-#include \"reftable-reader.h\"\n-#include \"merged.h\"\n-#include \"basics.h\"\n-#include \"record.h\"\n-#include \"test_framework.h\"\n-#include \"reftable-tests.h\"\n-#include \"reader.h\"\n-\n-#include <sys/types.h>\n+#include \"test-lib.h\"\n+#include \"reftable/merged.h\"\n+#include \"reftable/reader.h\"\n+#include \"reftable/reftable-error.h\"\n+#include \"reftable/stack.h\"\n #include <dirent.h>\n \n+static void set_test_hash(uint8_t *p, int i)\n+{\n+\tmemset(p, (uint8_t)i, hash_size(GIT_SHA1_FORMAT_ID));\n+}\n+\n static void clear_dir(const char *dirname)\n {\n \tstruct strbuf path = STRBUF_INIT;\n@@ -73,11 +69,11 @@ static char *get_tmp_template(int linenumber)\n static char *get_tmp_dir(int linenumber)\n {\n \tchar *dir = get_tmp_template(linenumber);\n-\tEXPECT(mkdtemp(dir));\n+\tcheck(mkdtemp(dir) != NULL);\n \treturn dir;\n }\n \n-static void test_read_file(void)\n+static void t_read_file(void)\n {\n \tchar *fn = get_tmp_template(__LINE__);\n \tint fd = mkstemp(fn);\n@@ -87,17 +83,17 @@ static void test_read_file(void)\n \tconst char *want[] = { \"line1\", \"line2\", \"line3\" };\n \tint i = 0;\n \n-\tEXPECT(fd > 0);\n+\tcheck_int(fd, >, 0);\n \tn = write_in_full(fd, out, strlen(out));\n-\tEXPECT(n == strlen(out));\n+\tcheck_int(n, ==, strlen(out));\n \terr = close(fd);\n-\tEXPECT(err >= 0);\n+\tcheck_int(err, >=, 0);\n \n \terr = read_lines(fn, &names);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; names[i]; i++) {\n-\t\tEXPECT(0 == strcmp(want[i], names[i]));\n+\t\tcheck_str(want[i], names[i]);\n \t}\n \tfree_names(names);\n \t(void) remove(fn);\n@@ -132,7 +128,7 @@ static void write_n_ref_tables(struct reftable_stack *st,\n \t\tset_test_hash(ref.value.val1, i);\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tst->opts.disable_auto_compact = disable_auto_compact;\n@@ -152,7 +148,7 @@ static int write_test_log(struct reftable_writer *wr, void *arg)\n \treturn reftable_writer_add_log(wr, wla->log);\n }\n \n-static void test_reftable_stack_add_one(void)\n+static void t_reftable_stack_add_one(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct strbuf scratch = STRBUF_INIT;\n@@ -171,22 +167,22 @@ static void test_reftable_stack_add_one(void)\n \tstruct reftable_ref_record dest = { NULL };\n \tstruct stat stat_result = { 0 };\n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(\"master\", dest.value.symref));\n-\tEXPECT(st->readers_len > 0);\n+\tcheck(!err);\n+\tcheck_str(\"master\", dest.value.symref);\n+\tcheck_int(st->readers_len, >, 0);\n \n #ifndef GIT_WINDOWS_NATIVE\n \tstrbuf_addstr(&scratch, dir);\n \tstrbuf_addstr(&scratch, \"/tables.list\");\n \terr = stat(scratch.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n \n \tstrbuf_reset(&scratch);\n \tstrbuf_addstr(&scratch, dir);\n@@ -194,8 +190,8 @@ static void test_reftable_stack_add_one(void)\n \t/* do not try at home; not an external API for reftable. */\n \tstrbuf_addstr(&scratch, st->readers[0]->name);\n \terr = stat(scratch.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n #else\n \t(void) stat_result;\n #endif\n@@ -207,7 +203,7 @@ static void test_reftable_stack_add_one(void)\n \tumask(mask);\n }\n \n-static void test_reftable_stack_uptodate(void)\n+static void t_reftable_stack_uptodate(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL;\n@@ -233,28 +229,28 @@ static void test_reftable_stack_uptodate(void)\n \t   by creating two stacks for the same directory.\n \t */\n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st1, &write_test_ref, &ref1);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n-\tEXPECT(err == REFTABLE_OUTDATED_ERROR);\n+\tcheck_int(err, ==, REFTABLE_OUTDATED_ERROR);\n \n \terr = reftable_stack_reload(st2);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_transaction_api(void)\n+static void t_reftable_stack_transaction_api(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -271,32 +267,32 @@ static void test_reftable_stack_transaction_api(void)\n \tstruct reftable_ref_record dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_addition_destroy(add);\n \n \terr = reftable_stack_new_addition(&add, st);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_addition_add(add, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_addition_commit(add);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_addition_destroy(add);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(REFTABLE_REF_SYMREF == dest.value_type);\n-\tEXPECT(0 == strcmp(\"master\", dest.value.symref));\n+\tcheck(!err);\n+\tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n+\tcheck_str(\"master\", dest.value.symref);\n \n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n+static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = {0};\n@@ -305,7 +301,7 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \tint i, n = 20, err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n@@ -326,13 +322,13 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\tst->opts.disable_auto_compact = i != n;\n \n \t\terr = reftable_stack_new_addition(&add, st);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_addition_add(add, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_addition_commit(add);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\treftable_addition_destroy(add);\n \n@@ -342,16 +338,16 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\t * all tables in the stack.\n \t\t */\n \t\tif (i != n)\n-\t\t\tEXPECT(st->merged->readers_len == i + 1);\n+\t\t\tcheck_int(st->merged->readers_len, ==, i + 1);\n \t\telse\n-\t\t\tEXPECT(st->merged->readers_len == 1);\n+\t\t\tcheck_int(st->merged->readers_len, ==, 1);\n \t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n+static void t_reftable_stack_auto_compaction_fails_gracefully(void)\n {\n \tstruct reftable_ref_record ref = {\n \t\t.refname = (char *) \"refs/heads/master\",\n@@ -366,13 +362,13 @@ static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->merged->readers_len == 1);\n-\tEXPECT(st->stats.attempts == 0);\n-\tEXPECT(st->stats.failures == 0);\n+\tcheck(!err);\n+\tcheck_int(st->merged->readers_len, ==, 1);\n+\tcheck_int(st->stats.attempts, ==, 0);\n+\tcheck_int(st->stats.failures, ==, 0);\n \n \t/*\n \t * Lock the newly written table such that it cannot be compacted.\n@@ -384,10 +380,10 @@ static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n \n \tref.update_index = 2;\n \terr = reftable_stack_add(st, write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->merged->readers_len == 2);\n-\tEXPECT(st->stats.attempts == 1);\n-\tEXPECT(st->stats.failures == 1);\n+\tcheck(!err);\n+\tcheck_int(st->merged->readers_len, ==, 2);\n+\tcheck_int(st->stats.attempts, ==, 1);\n+\tcheck_int(st->stats.failures, ==, 1);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&table_path);\n@@ -399,7 +395,7 @@ static int write_error(struct reftable_writer *wr UNUSED, void *arg)\n \treturn *((int *)arg);\n }\n \n-static void test_reftable_stack_update_index_check(void)\n+static void t_reftable_stack_update_index_check(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -419,18 +415,18 @@ static void test_reftable_stack_update_index_check(void)\n \t};\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref1);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref2);\n-\tEXPECT(err == REFTABLE_API_ERROR);\n+\tcheck_int(err, ==, REFTABLE_API_ERROR);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_lock_failure(void)\n+static void t_reftable_stack_lock_failure(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -438,17 +434,17 @@ static void test_reftable_stack_lock_failure(void)\n \tint err, i;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \tfor (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) {\n \t\terr = reftable_stack_add(st, &write_error, &i);\n-\t\tEXPECT(err == i);\n+\t\tcheck_int(err, ==, i);\n \t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_add(void)\n+static void t_reftable_stack_add(void)\n {\n \tint i = 0;\n \tint err = 0;\n@@ -466,7 +462,7 @@ static void test_reftable_stack_add(void)\n \tint N = ARRAY_SIZE(refs);\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar buf[256];\n@@ -485,7 +481,7 @@ static void test_reftable_stack_add(void)\n \n \tfor (i = 0; i < N; i++) {\n \t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tfor (i = 0; i < N; i++) {\n@@ -494,18 +490,18 @@ static void test_reftable_stack_add(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tstruct reftable_ref_record dest = { NULL };\n \n \t\tint err = reftable_stack_read_ref(st, refs[i].refname, &dest);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(reftable_ref_record_equal(&dest, refs + i,\n+\t\tcheck(!err);\n+\t\tcheck(reftable_ref_record_equal(&dest, refs + i,\n \t\t\t\t\t\t GIT_SHA1_RAWSZ));\n \t\treftable_ref_record_release(&dest);\n \t}\n@@ -513,8 +509,8 @@ static void test_reftable_stack_add(void)\n \tfor (i = 0; i < N; i++) {\n \t\tstruct reftable_log_record dest = { NULL };\n \t\tint err = reftable_stack_read_log(st, refs[i].refname, &dest);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(reftable_log_record_equal(&dest, logs + i,\n+\t\tcheck(!err);\n+\t\tcheck(reftable_log_record_equal(&dest, logs + i,\n \t\t\t\t\t\t GIT_SHA1_RAWSZ));\n \t\treftable_log_record_release(&dest);\n \t}\n@@ -523,8 +519,8 @@ static void test_reftable_stack_add(void)\n \tstrbuf_addstr(&path, dir);\n \tstrbuf_addstr(&path, \"/tables.list\");\n \terr = stat(path.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n \n \tstrbuf_reset(&path);\n \tstrbuf_addstr(&path, dir);\n@@ -532,8 +528,8 @@ static void test_reftable_stack_add(void)\n \t/* do not try at home; not an external API for reftable. */\n \tstrbuf_addstr(&path, st->readers[0]->name);\n \terr = stat(path.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n #else\n \t(void) stat_result;\n #endif\n@@ -548,7 +544,7 @@ static void test_reftable_stack_add(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_log_normalize(void)\n+static void t_reftable_stack_log_normalize(void)\n {\n \tint err = 0;\n \tstruct reftable_write_options opts = {\n@@ -576,27 +572,27 @@ static void test_reftable_stack_log_normalize(void)\n \t};\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tinput.value.update.message = (char *) \"one\\ntwo\";\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT(err == REFTABLE_API_ERROR);\n+\tcheck_int(err, ==, REFTABLE_API_ERROR);\n \n \tinput.value.update.message = (char *) \"one\";\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, input.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(dest.value.update.message, \"one\\n\"));\n+\tcheck(!err);\n+\tcheck_str(dest.value.update.message, \"one\\n\");\n \n \tinput.value.update.message = (char *) \"two\\n\";\n \targ.update_index = 2;\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \terr = reftable_stack_read_log(st, input.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(dest.value.update.message, \"two\\n\"));\n+\tcheck(!err);\n+\tcheck_str(dest.value.update.message, \"two\\n\");\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n@@ -604,7 +600,7 @@ static void test_reftable_stack_log_normalize(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_tombstone(void)\n+static void t_reftable_stack_tombstone(void)\n {\n \tint i = 0;\n \tchar *dir = get_tmp_dir(__LINE__);\n@@ -618,7 +614,7 @@ static void test_reftable_stack_tombstone(void)\n \tstruct reftable_log_record log_dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* even entries add the refs, odd entries delete them. */\n \tfor (i = 0; i < N; i++) {\n@@ -642,7 +638,7 @@ static void test_reftable_stack_tombstone(void)\n \t}\n \tfor (i = 0; i < N; i++) {\n \t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tfor (i = 0; i < N; i++) {\n@@ -651,25 +647,25 @@ static void test_reftable_stack_tombstone(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_read_ref(st, \"branch\", &dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_ref_record_release(&dest);\n \n \terr = reftable_stack_read_log(st, \"branch\", &log_dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_log_record_release(&log_dest);\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, \"branch\", &dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, \"branch\", &log_dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_ref_record_release(&dest);\n \treftable_log_record_release(&log_dest);\n \n@@ -682,7 +678,7 @@ static void test_reftable_stack_tombstone(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_hash_id(void)\n+static void t_reftable_stack_hash_id(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -702,47 +698,47 @@ static void test_reftable_stack_hash_id(void)\n \tstruct reftable_ref_record dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* can't read it with the wrong hash ID. */\n \terr = reftable_new_stack(&st32, dir, &opts32);\n-\tEXPECT(err == REFTABLE_FORMAT_ERROR);\n+\tcheck_int(err, ==, REFTABLE_FORMAT_ERROR);\n \n \t/* check that we can read it back with default opts too. */\n \terr = reftable_new_stack(&st_default, dir, &opts_default);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st_default, \"master\", &dest);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n-\tEXPECT(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n \treftable_stack_destroy(st_default);\n \tclear_dir(dir);\n }\n \n-static void test_suggest_compaction_segment(void)\n+static void t_suggest_compaction_segment(void)\n {\n \tuint64_t sizes[] = { 512, 64, 17, 16, 9, 9, 9, 16, 2, 16 };\n \tstruct segment min =\n \t\tsuggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);\n-\tEXPECT(min.start == 1);\n-\tEXPECT(min.end == 10);\n+\tcheck_int(min.start, ==, 1);\n+\tcheck_int(min.end, ==, 10);\n }\n \n-static void test_suggest_compaction_segment_nothing(void)\n+static void t_suggest_compaction_segment_nothing(void)\n {\n \tuint64_t sizes[] = { 64, 32, 16, 8, 4, 2 };\n \tstruct segment result =\n \t\tsuggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);\n-\tEXPECT(result.start == result.end);\n+\tcheck_int(result.start, ==, result.end);\n }\n \n-static void test_reflog_expire(void)\n+static void t_reflog_expire(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -757,7 +753,7 @@ static void test_reflog_expire(void)\n \tstruct reftable_log_record log = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 1; i <= N; i++) {\n \t\tchar buf[256];\n@@ -777,30 +773,30 @@ static void test_reflog_expire(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st, &expiry);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, logs[9].refname, &log);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, logs[11].refname, &log);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \texpiry.min_update_index = 15;\n \terr = reftable_stack_compact_all(st, &expiry);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, logs[14].refname, &log);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, logs[16].refname, &log);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n@@ -817,7 +813,7 @@ static int write_nothing(struct reftable_writer *wr, void *arg UNUSED)\n \treturn 0;\n }\n \n-static void test_empty_add(void)\n+static void t_empty_add(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -826,13 +822,13 @@ static void test_empty_add(void)\n \tstruct reftable_stack *st2 = NULL;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_nothing, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \tclear_dir(dir);\n \treftable_stack_destroy(st);\n \treftable_stack_destroy(st2);\n@@ -848,7 +844,7 @@ static int fastlog2(uint64_t sz)\n \treturn l - 1;\n }\n \n-static void test_reftable_stack_auto_compaction(void)\n+static void t_reftable_stack_auto_compaction(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -859,7 +855,7 @@ static void test_reftable_stack_auto_compaction(void)\n \tint N = 100;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar name[100];\n@@ -872,21 +868,21 @@ static void test_reftable_stack_auto_compaction(void)\n \t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_stack_auto_compact(st);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(i < 3 || st->merged->readers_len < 2 * fastlog2(i));\n+\t\tcheck(!err);\n+\t\tcheck(i < 3 || st->merged->readers_len < 2 * fastlog2(i));\n \t}\n \n-\tEXPECT(reftable_stack_compaction_stats(st)->entries_written <\n+\tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n \t       (uint64_t)(N * fastlog2(N)));\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n+static void t_reftable_stack_auto_compaction_with_locked_tables(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -897,10 +893,10 @@ static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \twrite_n_ref_tables(st, 5);\n-\tEXPECT(st->merged->readers_len == 5);\n+\tcheck_int(st->merged->readers_len, ==, 5);\n \n \t/*\n \t * Given that all tables we have written should be roughly the same\n@@ -918,16 +914,16 @@ static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n \t * only compact the newest two tables.\n \t */\n \terr = reftable_stack_auto_compact(st);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->stats.failures == 0);\n-\tEXPECT(st->merged->readers_len == 4);\n+\tcheck(!err);\n+\tcheck_int(st->stats.failures, ==, 0);\n+\tcheck_int(st->merged->readers_len, ==, 4);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&buf);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_add_performs_auto_compaction(void)\n+static void t_reftable_stack_add_performs_auto_compaction(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -936,7 +932,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \tint err, i, n = 20;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n@@ -957,7 +953,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \t\tref.refname = refname.buf;\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\t/*\n \t\t * The stack length should grow continuously for all runs where\n@@ -965,9 +961,9 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \t\t * all tables in the stack.\n \t\t */\n \t\tif (i != n)\n-\t\t\tEXPECT(st->merged->readers_len == i + 1);\n+\t\t\tcheck_int(st->merged->readers_len, ==, i + 1);\n \t\telse\n-\t\t\tEXPECT(st->merged->readers_len == 1);\n+\t\t\tcheck_int(st->merged->readers_len, ==, 1);\n \t}\n \n \treftable_stack_destroy(st);\n@@ -975,7 +971,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_compaction_with_locked_tables(void)\n+static void t_reftable_stack_compaction_with_locked_tables(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -986,10 +982,10 @@ static void test_reftable_stack_compaction_with_locked_tables(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \twrite_n_ref_tables(st, 3);\n-\tEXPECT(st->merged->readers_len == 3);\n+\tcheck_int(st->merged->readers_len, ==, 3);\n \n \t/* Lock one of the tables that we're about to compact. */\n \tstrbuf_reset(&buf);\n@@ -1001,16 +997,16 @@ static void test_reftable_stack_compaction_with_locked_tables(void)\n \t * compact all tables.\n \t */\n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT(err == REFTABLE_LOCK_ERROR);\n-\tEXPECT(st->stats.failures == 1);\n-\tEXPECT(st->merged->readers_len == 3);\n+\tcheck_int(err, ==, REFTABLE_LOCK_ERROR);\n+\tcheck_int(st->stats.failures, ==, 1);\n+\tcheck_int(st->merged->readers_len, ==, 3);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&buf);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_compaction_concurrent(void)\n+static void t_reftable_stack_compaction_concurrent(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL;\n@@ -1018,19 +1014,19 @@ static void test_reftable_stack_compaction_concurrent(void)\n \tint err;\n \n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st1, 3);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st1, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n \n-\tEXPECT(count_dir_entries(dir) == 2);\n+\tcheck_int(count_dir_entries(dir), ==, 2);\n \tclear_dir(dir);\n }\n \n@@ -1043,7 +1039,7 @@ static void unclean_stack_close(struct reftable_stack *st)\n \tFREE_AND_NULL(st->readers);\n }\n \n-static void test_reftable_stack_compaction_concurrent_clean(void)\n+static void t_reftable_stack_compaction_concurrent_clean(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL, *st3 = NULL;\n@@ -1051,24 +1047,24 @@ static void test_reftable_stack_compaction_concurrent_clean(void)\n \tint err;\n \n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st1, 3);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st1, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tunclean_stack_close(st1);\n \tunclean_stack_close(st2);\n \n \terr = reftable_new_stack(&st3, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_clean(st3);\n-\tEXPECT_ERR(err);\n-\tEXPECT(count_dir_entries(dir) == 2);\n+\tcheck(!err);\n+\tcheck_int(count_dir_entries(dir), ==, 2);\n \n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n@@ -1077,7 +1073,7 @@ static void test_reftable_stack_compaction_concurrent_clean(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_read_across_reload(void)\n+static void t_reftable_stack_read_across_reload(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL;\n@@ -1088,36 +1084,36 @@ static void test_reftable_stack_read_across_reload(void)\n \n \t/* Create a first stack and set up an iterator for it. */\n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st1, 2);\n-\tEXPECT(st1->merged->readers_len == 2);\n+\tcheck_int(st1->merged->readers_len, ==, 2);\n \treftable_stack_init_ref_iterator(st1, &it);\n \terr = reftable_iterator_seek_ref(&it, \"\");\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* Set up a second stack for the same directory and compact it. */\n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st2->merged->readers_len == 2);\n+\tcheck(!err);\n+\tcheck_int(st2->merged->readers_len, ==, 2);\n \terr = reftable_stack_compact_all(st2, NULL);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st2->merged->readers_len == 1);\n+\tcheck(!err);\n+\tcheck_int(st2->merged->readers_len, ==, 1);\n \n \t/*\n \t * Verify that we can continue to use the old iterator even after we\n \t * have reloaded its stack.\n \t */\n \terr = reftable_stack_reload(st1);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st1->merged->readers_len == 1);\n+\tcheck(!err);\n+\tcheck_int(st1->merged->readers_len, ==, 1);\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT_ERR(err);\n-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0000\"));\n+\tcheck(!err);\n+\tcheck_str(rec.refname, \"refs/heads/branch-0000\");\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT_ERR(err);\n-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0001\"));\n+\tcheck(!err);\n+\tcheck_str(rec.refname, \"refs/heads/branch-0001\");\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT(err > 0);\n+\tcheck_int(err, >, 0);\n \n \treftable_ref_record_release(&rec);\n \treftable_iterator_destroy(&it);\n@@ -1126,7 +1122,7 @@ static void test_reftable_stack_read_across_reload(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_reload_with_missing_table(void)\n+static void t_reftable_stack_reload_with_missing_table(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -1138,12 +1134,12 @@ static void test_reftable_stack_reload_with_missing_table(void)\n \n \t/* Create a first stack and set up an iterator for it. */\n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st, 2);\n-\tEXPECT(st->merged->readers_len == 2);\n+\tcheck_int(st->merged->readers_len, ==, 2);\n \treftable_stack_init_ref_iterator(st, &it);\n \terr = reftable_iterator_seek_ref(&it, \"\");\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/*\n \t * Update the tables.list file with some garbage data, while reusing\n@@ -1156,24 +1152,24 @@ static void test_reftable_stack_reload_with_missing_table(void)\n \tstrbuf_addf(&table_path, \"%s.lock\", st->list_file);\n \twrite_file_buf(table_path.buf, content.buf, content.len);\n \terr = rename(table_path.buf, st->list_file);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_reload(st);\n-\tEXPECT(err == -4);\n-\tEXPECT(st->merged->readers_len == 2);\n+\tcheck_int(err, ==, -4);\n+\tcheck_int(st->merged->readers_len, ==, 2);\n \n \t/*\n \t * Even though the reload has failed, we should be able to continue\n \t * using the iterator.\n \t*/\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT_ERR(err);\n-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0000\"));\n+\tcheck(!err);\n+\tcheck_str(rec.refname, \"refs/heads/branch-0000\");\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT_ERR(err);\n-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0001\"));\n+\tcheck(!err);\n+\tcheck_str(rec.refname, \"refs/heads/branch-0001\");\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT(err > 0);\n+\tcheck_int(err, >, 0);\n \n \treftable_ref_record_release(&rec);\n \treftable_iterator_destroy(&it);\n@@ -1183,31 +1179,32 @@ static void test_reftable_stack_reload_with_missing_table(void)\n \tclear_dir(dir);\n }\n \n-int stack_test_main(int argc UNUSED, const char *argv[] UNUSED)\n+int cmd_main(int argc UNUSED, const char *argv[] UNUSED)\n {\n-\tRUN_TEST(test_empty_add);\n-\tRUN_TEST(test_read_file);\n-\tRUN_TEST(test_reflog_expire);\n-\tRUN_TEST(test_reftable_stack_add);\n-\tRUN_TEST(test_reftable_stack_add_one);\n-\tRUN_TEST(test_reftable_stack_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_auto_compaction_with_locked_tables);\n-\tRUN_TEST(test_reftable_stack_add_performs_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_compaction_concurrent);\n-\tRUN_TEST(test_reftable_stack_compaction_concurrent_clean);\n-\tRUN_TEST(test_reftable_stack_compaction_with_locked_tables);\n-\tRUN_TEST(test_reftable_stack_hash_id);\n-\tRUN_TEST(test_reftable_stack_lock_failure);\n-\tRUN_TEST(test_reftable_stack_log_normalize);\n-\tRUN_TEST(test_reftable_stack_tombstone);\n-\tRUN_TEST(test_reftable_stack_transaction_api);\n-\tRUN_TEST(test_reftable_stack_transaction_api_performs_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_auto_compaction_fails_gracefully);\n-\tRUN_TEST(test_reftable_stack_update_index_check);\n-\tRUN_TEST(test_reftable_stack_uptodate);\n-\tRUN_TEST(test_reftable_stack_read_across_reload);\n-\tRUN_TEST(test_reftable_stack_reload_with_missing_table);\n-\tRUN_TEST(test_suggest_compaction_segment);\n-\tRUN_TEST(test_suggest_compaction_segment_nothing);\n-\treturn 0;\n+\tTEST(t_empty_add(), \"empty addition to stack\");\n+\tTEST(t_read_file(), \"read_lines works\");\n+\tTEST(t_reflog_expire(), \"expire reflog entries\");\n+\tTEST(t_reftable_stack_add(), \"add multiple refs and logs to stack\");\n+\tTEST(t_reftable_stack_add_one(), \"add a single ref record to stack\");\n+\tTEST(t_reftable_stack_add_performs_auto_compaction(), \"addition to stack triggers auto-compaction\");\n+\tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_fails_gracefully(), \"failure on auto-compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_with_locked_tables(), \"auto compaction with locked tables\");\n+\tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n+\tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n+\tTEST(t_reftable_stack_compaction_with_locked_tables(), \"compaction with locked tables\");\n+\tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n+\tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n+\tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n+\tTEST(t_reftable_stack_read_across_reload(), \"stack iterators work across reloads\");\n+\tTEST(t_reftable_stack_reload_with_missing_table(), \"stack iteration with garbage tables\");\n+\tTEST(t_reftable_stack_tombstone(), \"'tombstone' refs in stack\");\n+\tTEST(t_reftable_stack_transaction_api(), \"update transaction to stack\");\n+\tTEST(t_reftable_stack_transaction_api_performs_auto_compaction(), \"update transaction triggers auto-compaction\");\n+\tTEST(t_reftable_stack_update_index_check(), \"update transactions with equal update indices\");\n+\tTEST(t_reftable_stack_uptodate(), \"stack must be reloaded before ref update\");\n+\tTEST(t_suggest_compaction_segment(), \"suggest_compaction_segment with basic input\");\n+\tTEST(t_suggest_compaction_segment_nothing(), \"suggest_compaction_segment with pre-compacted input\");\n+\n+\treturn test_done();\n }\n-- \n2.45.GIT\n\n"},{"id":"502141","messageId":"20240904150132.11567-3-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240904150132.11567-1-chandrapratap3519@gmail.com","subject":"[PATCH v4 2/6] t: harmonize t-reftable-stack.c with coding guidelines","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-04T14:38:02Z","receivedAt":"2024-09-04T15:02:01Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"Harmonize the newly ported test unit-tests/t-reftable-stack.c\nwith the following guidelines:\n- Single line 'for' statements must omit curly braces.\n- Structs must be 0-initialized with '= { 0 }' instead of '= { NULL }'.\n- Array sizes and indices should preferably be of type 'size_t' and\n  not 'int'.\n- Function pointers should be passed as 'func' and not '&func'.\n\nWhile at it, remove initialization for those variables that are\nre-used multiple times, like loop variables.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 110 +++++++++++++++-----------------\n 1 file changed, 53 insertions(+), 57 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex de28fac466..c74660a1e2 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -81,7 +81,6 @@ static void t_read_file(void)\n \tint n, err;\n \tchar **names = NULL;\n \tconst char *want[] = { \"line1\", \"line2\", \"line3\" };\n-\tint i = 0;\n \n \tcheck_int(fd, >, 0);\n \tn = write_in_full(fd, out, strlen(out));\n@@ -92,9 +91,8 @@ static void t_read_file(void)\n \terr = read_lines(fn, &names);\n \tcheck(!err);\n \n-\tfor (i = 0; names[i]; i++) {\n+\tfor (size_t i = 0; names[i]; i++)\n \t\tcheck_str(want[i], names[i]);\n-\t}\n \tfree_names(names);\n \t(void) remove(fn);\n }\n@@ -123,7 +121,7 @@ static void write_n_ref_tables(struct reftable_stack *st,\n \t\t};\n \n \t\tstrbuf_reset(&buf);\n-\t\tstrbuf_addf(&buf, \"refs/heads/branch-%04u\", (unsigned) i);\n+\t\tstrbuf_addf(&buf, \"refs/heads/branch-%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = buf.buf;\n \t\tset_test_hash(ref.value.val1, i);\n \n@@ -164,12 +162,12 @@ static void t_reftable_stack_add_one(void)\n \t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t.value.symref = (char *) \"master\",\n \t};\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \tstruct stat stat_result = { 0 };\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\terr = reftable_stack_add(st, write_test_ref, &ref);\n \tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n@@ -234,16 +232,16 @@ static void t_reftable_stack_uptodate(void)\n \terr = reftable_new_stack(&st2, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st1, &write_test_ref, &ref1);\n+\terr = reftable_stack_add(st1, write_test_ref, &ref1);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st2, write_test_ref, &ref2);\n \tcheck_int(err, ==, REFTABLE_OUTDATED_ERROR);\n \n \terr = reftable_stack_reload(st2);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st2, write_test_ref, &ref2);\n \tcheck(!err);\n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n@@ -264,7 +262,7 @@ static void t_reftable_stack_transaction_api(void)\n \t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t.value.symref = (char *) \"master\",\n \t};\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -274,7 +272,7 @@ static void t_reftable_stack_transaction_api(void)\n \terr = reftable_stack_new_addition(&add, st);\n \tcheck(!err);\n \n-\terr = reftable_addition_add(add, &write_test_ref, &ref);\n+\terr = reftable_addition_add(add, write_test_ref, &ref);\n \tcheck(!err);\n \n \terr = reftable_addition_commit(add);\n@@ -298,12 +296,13 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \tstruct reftable_write_options opts = {0};\n \tstruct reftable_addition *add = NULL;\n \tstruct reftable_stack *st = NULL;\n-\tint i, n = 20, err;\n+\tsize_t n = 20;\n+\tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\tfor (i = 0; i <= n; i++) {\n+\tfor (size_t i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t\t.value_type = REFTABLE_REF_SYMREF,\n@@ -311,7 +310,7 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\t};\n \t\tchar name[100];\n \n-\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = name;\n \n \t\t/*\n@@ -324,7 +323,7 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\terr = reftable_stack_new_addition(&add, st);\n \t\tcheck(!err);\n \n-\t\terr = reftable_addition_add(add, &write_test_ref, &ref);\n+\t\terr = reftable_addition_add(add, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\terr = reftable_addition_commit(add);\n@@ -355,7 +354,7 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void)\n \t\t.value_type = REFTABLE_REF_VAL1,\n \t\t.value.val1 = {0x01},\n \t};\n-\tstruct reftable_write_options opts = {0};\n+\tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st;\n \tstruct strbuf table_path = STRBUF_INIT;\n \tchar *dir = get_tmp_dir(__LINE__);\n@@ -417,10 +416,10 @@ static void t_reftable_stack_update_index_check(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref1);\n+\terr = reftable_stack_add(st, write_test_ref, &ref1);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st, write_test_ref, &ref2);\n \tcheck_int(err, ==, REFTABLE_API_ERROR);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n@@ -436,7 +435,7 @@ static void t_reftable_stack_lock_failure(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \tfor (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) {\n-\t\terr = reftable_stack_add(st, &write_error, &i);\n+\t\terr = reftable_stack_add(st, write_error, &i);\n \t\tcheck_int(err, ==, i);\n \t}\n \n@@ -446,7 +445,6 @@ static void t_reftable_stack_lock_failure(void)\n \n static void t_reftable_stack_add(void)\n {\n-\tint i = 0;\n \tint err = 0;\n \tstruct reftable_write_options opts = {\n \t\t.exact_log_message = 1,\n@@ -455,18 +453,18 @@ static void t_reftable_stack_add(void)\n \t};\n \tstruct reftable_stack *st = NULL;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tstruct reftable_ref_record refs[2] = { { NULL } };\n-\tstruct reftable_log_record logs[2] = { { NULL } };\n+\tstruct reftable_ref_record refs[2] = { 0 };\n+\tstruct reftable_log_record logs[2] = { 0 };\n \tstruct strbuf path = STRBUF_INIT;\n \tstruct stat stat_result;\n-\tint N = ARRAY_SIZE(refs);\n+\tsize_t i, N = ARRAY_SIZE(refs);\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar buf[256];\n-\t\tsnprintf(buf, sizeof(buf), \"branch%02d\", i);\n+\t\tsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n \t\trefs[i].refname = xstrdup(buf);\n \t\trefs[i].update_index = i + 1;\n \t\trefs[i].value_type = REFTABLE_REF_VAL1;\n@@ -480,7 +478,7 @@ static void t_reftable_stack_add(void)\n \t}\n \n \tfor (i = 0; i < N; i++) {\n-\t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n+\t\tint err = reftable_stack_add(st, write_test_ref, &refs[i]);\n \t\tcheck(!err);\n \t}\n \n@@ -489,7 +487,7 @@ static void t_reftable_stack_add(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -497,7 +495,7 @@ static void t_reftable_stack_add(void)\n \tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n-\t\tstruct reftable_ref_record dest = { NULL };\n+\t\tstruct reftable_ref_record dest = { 0 };\n \n \t\tint err = reftable_stack_read_ref(st, refs[i].refname, &dest);\n \t\tcheck(!err);\n@@ -507,7 +505,7 @@ static void t_reftable_stack_add(void)\n \t}\n \n \tfor (i = 0; i < N; i++) {\n-\t\tstruct reftable_log_record dest = { NULL };\n+\t\tstruct reftable_log_record dest = { 0 };\n \t\tint err = reftable_stack_read_log(st, refs[i].refname, &dest);\n \t\tcheck(!err);\n \t\tcheck(reftable_log_record_equal(&dest, logs + i,\n@@ -575,11 +573,11 @@ static void t_reftable_stack_log_normalize(void)\n \tcheck(!err);\n \n \tinput.value.update.message = (char *) \"one\\ntwo\";\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck_int(err, ==, REFTABLE_API_ERROR);\n \n \tinput.value.update.message = (char *) \"one\";\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck(!err);\n \n \terr = reftable_stack_read_log(st, input.refname, &dest);\n@@ -588,7 +586,7 @@ static void t_reftable_stack_log_normalize(void)\n \n \tinput.value.update.message = (char *) \"two\\n\";\n \targ.update_index = 2;\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck(!err);\n \terr = reftable_stack_read_log(st, input.refname, &dest);\n \tcheck(!err);\n@@ -602,16 +600,15 @@ static void t_reftable_stack_log_normalize(void)\n \n static void t_reftable_stack_tombstone(void)\n {\n-\tint i = 0;\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n \tint err;\n-\tstruct reftable_ref_record refs[2] = { { NULL } };\n-\tstruct reftable_log_record logs[2] = { { NULL } };\n-\tint N = ARRAY_SIZE(refs);\n-\tstruct reftable_ref_record dest = { NULL };\n-\tstruct reftable_log_record log_dest = { NULL };\n+\tstruct reftable_ref_record refs[2] = { 0 };\n+\tstruct reftable_log_record logs[2] = { 0 };\n+\tsize_t i, N = ARRAY_SIZE(refs);\n+\tstruct reftable_ref_record dest = { 0 };\n+\tstruct reftable_log_record log_dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -637,7 +634,7 @@ static void t_reftable_stack_tombstone(void)\n \t\t}\n \t}\n \tfor (i = 0; i < N; i++) {\n-\t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n+\t\tint err = reftable_stack_add(st, write_test_ref, &refs[i]);\n \t\tcheck(!err);\n \t}\n \n@@ -646,7 +643,7 @@ static void t_reftable_stack_tombstone(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -695,12 +692,12 @@ static void t_reftable_stack_hash_id(void)\n \tstruct reftable_stack *st32 = NULL;\n \tstruct reftable_write_options opts_default = { 0 };\n \tstruct reftable_stack *st_default = NULL;\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\terr = reftable_stack_add(st, write_test_ref, &ref);\n \tcheck(!err);\n \n \t/* can't read it with the wrong hash ID. */\n@@ -743,21 +740,20 @@ static void t_reflog_expire(void)\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n-\tstruct reftable_log_record logs[20] = { { NULL } };\n-\tint N = ARRAY_SIZE(logs) - 1;\n-\tint i = 0;\n+\tstruct reftable_log_record logs[20] = { 0 };\n+\tsize_t i, N = ARRAY_SIZE(logs) - 1;\n \tint err;\n \tstruct reftable_log_expiry_config expiry = {\n \t\t.time = 10,\n \t};\n-\tstruct reftable_log_record log = { NULL };\n+\tstruct reftable_log_record log = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n \tfor (i = 1; i <= N; i++) {\n \t\tchar buf[256];\n-\t\tsnprintf(buf, sizeof(buf), \"branch%02d\", i);\n+\t\tsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n \n \t\tlogs[i].refname = xstrdup(buf);\n \t\tlogs[i].update_index = i;\n@@ -772,7 +768,7 @@ static void t_reflog_expire(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -800,9 +796,8 @@ static void t_reflog_expire(void)\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n-\tfor (i = 0; i <= N; i++) {\n+\tfor (i = 0; i <= N; i++)\n \t\treftable_log_record_release(&logs[i]);\n-\t}\n \tclear_dir(dir);\n \treftable_log_record_release(&log);\n }\n@@ -824,7 +819,7 @@ static void t_empty_add(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_nothing, NULL);\n+\terr = reftable_stack_add(st, write_nothing, NULL);\n \tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n@@ -851,8 +846,8 @@ static void t_reftable_stack_auto_compaction(void)\n \t};\n \tstruct reftable_stack *st = NULL;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tint err, i;\n-\tint N = 100;\n+\tint err;\n+\tsize_t i, N = 100;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -865,9 +860,9 @@ static void t_reftable_stack_auto_compaction(void)\n \t\t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t\t.value.symref = (char *) \"master\",\n \t\t};\n-\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n \n-\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\terr = reftable_stack_add(st, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\terr = reftable_stack_auto_compact(st);\n@@ -929,7 +924,8 @@ static void t_reftable_stack_add_performs_auto_compaction(void)\n \tstruct reftable_stack *st = NULL;\n \tstruct strbuf refname = STRBUF_INIT;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tint err, i, n = 20;\n+\tint err;\n+\tsize_t i, n = 20;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -949,10 +945,10 @@ static void t_reftable_stack_add_performs_auto_compaction(void)\n \t\tst->opts.disable_auto_compact = i != n;\n \n \t\tstrbuf_reset(&refname);\n-\t\tstrbuf_addf(&refname, \"branch-%04d\", i);\n+\t\tstrbuf_addf(&refname, \"branch-%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = refname.buf;\n \n-\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\terr = reftable_stack_add(st, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\t/*\n-- \n2.45.GIT\n\n"},{"id":"502142","messageId":"20240904150132.11567-4-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240904150132.11567-1-chandrapratap3519@gmail.com","subject":"[PATCH v4 3/6] t-reftable-stack: use Git's tempfile API instead of mkstemp()","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-04T14:38:03Z","receivedAt":"2024-09-04T15:02:04Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"Git's tempfile API defined by $GIT_DIR/tempfile.{c,h} provides\na unified interface for tempfile operations. Since reftable/stack.c\nuses this API for all its tempfile needs instead of raw functions\nlike mkstemp(), make the ported stack test strictly use Git's\ntempfile API as well.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex c74660a1e2..8047e25c48 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -76,7 +76,8 @@ static char *get_tmp_dir(int linenumber)\n static void t_read_file(void)\n {\n \tchar *fn = get_tmp_template(__LINE__);\n-\tint fd = mkstemp(fn);\n+\tstruct tempfile *tmp = mks_tempfile(fn);\n+\tint fd = get_tempfile_fd(tmp);\n \tchar out[1024] = \"line1\\n\\nline2\\nline3\";\n \tint n, err;\n \tchar **names = NULL;\n@@ -95,6 +96,7 @@ static void t_read_file(void)\n \t\tcheck_str(want[i], names[i]);\n \tfree_names(names);\n \t(void) remove(fn);\n+\tdelete_tempfile(&tmp);\n }\n \n static int write_test_ref(struct reftable_writer *wr, void *arg)\n-- \n2.45.GIT\n\n"},{"id":"502143","messageId":"20240904150132.11567-5-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240904150132.11567-1-chandrapratap3519@gmail.com","subject":"[PATCH v4 4/6] t-reftable-stack: use reftable_ref_record_equal() to compare ref records","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-04T14:38:04Z","receivedAt":"2024-09-04T15:02:07Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"In the current stack tests, ref records are compared for equality\nby sometimes using the dedicated function for ref-record comparison,\nreftable_ref_record_equal(), and sometimes by explicity comparing\ncontents of the ref records.\n\nReplace the latter instances of ref-record comparison with the\nformer to maintain uniformity throughout the test file.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 8047e25c48..4f2ef1a8cc 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -174,7 +174,7 @@ static void t_reftable_stack_add_one(void)\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n \tcheck(!err);\n-\tcheck_str(\"master\", dest.value.symref);\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \tcheck_int(st->readers_len, >, 0);\n \n #ifndef GIT_WINDOWS_NATIVE\n@@ -285,7 +285,7 @@ static void t_reftable_stack_transaction_api(void)\n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n \tcheck(!err);\n \tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n-\tcheck_str(\"master\", dest.value.symref);\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n-- \n2.45.GIT\n\n"},{"id":"502144","messageId":"20240904150132.11567-6-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240904150132.11567-1-chandrapratap3519@gmail.com","subject":"[PATCH v4 5/6] t-reftable-stack: add test for non-default compaction factor","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-04T14:38:05Z","receivedAt":"2024-09-04T15:02:09Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"In a recent codebase update (commit ae8e378430, merge branch\n'ps/reftable-write-options', 2024/05/13) the geometric factor used\nin auto-compaction of reftable tables was made configurable. Add\na test to verify the functionality introduced by this update.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 41 +++++++++++++++++++++++++++++----\n 1 file changed, 37 insertions(+), 4 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 4f2ef1a8cc..4acf07ab0c 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -831,12 +831,12 @@ static void t_empty_add(void)\n \treftable_stack_destroy(st2);\n }\n \n-static int fastlog2(uint64_t sz)\n+static int fastlogN(uint64_t sz, uint64_t N)\n {\n \tint l = 0;\n \tif (sz == 0)\n \t\treturn 0;\n-\tfor (; sz; sz /= 2)\n+\tfor (; sz; sz /= N)\n \t\tl++;\n \treturn l - 1;\n }\n@@ -869,11 +869,43 @@ static void t_reftable_stack_auto_compaction(void)\n \n \t\terr = reftable_stack_auto_compact(st);\n \t\tcheck(!err);\n-\t\tcheck(i < 3 || st->merged->readers_len < 2 * fastlog2(i));\n+\t\tcheck(i < 2 || st->merged->readers_len < 2 * fastlogN(i, 2));\n \t}\n \n \tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n-\t       (uint64_t)(N * fastlog2(N)));\n+\t       (uint64_t)(N * fastlogN(N, 2)));\n+\n+\treftable_stack_destroy(st);\n+\tclear_dir(dir);\n+}\n+\n+static void t_reftable_stack_auto_compaction_factor(void)\n+{\n+\tstruct reftable_write_options opts = {\n+\t\t.auto_compaction_factor = 5,\n+\t};\n+\tstruct reftable_stack *st = NULL;\n+\tchar *dir = get_tmp_dir(__LINE__);\n+\tint err;\n+\tsize_t N = 100;\n+\n+\terr = reftable_new_stack(&st, dir, &opts);\n+\tcheck(!err);\n+\n+\tfor (size_t i = 0; i < N; i++) {\n+\t\tchar name[20];\n+\t\tstruct reftable_ref_record ref = {\n+\t\t\t.refname = name,\n+\t\t\t.update_index = reftable_stack_next_update_index(st),\n+\t\t\t.value_type = REFTABLE_REF_VAL1,\n+\t\t};\n+\t\txsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n+\n+\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\tcheck(!err);\n+\n+\t\tcheck(i < 5 || st->merged->readers_len < 5 * fastlogN(i, 5));\n+\t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n@@ -1186,6 +1218,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)\n \tTEST(t_reftable_stack_add_one(), \"add a single ref record to stack\");\n \tTEST(t_reftable_stack_add_performs_auto_compaction(), \"addition to stack triggers auto-compaction\");\n \tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_factor(), \"auto-compaction with non-default geometric factor\");\n \tTEST(t_reftable_stack_auto_compaction_fails_gracefully(), \"failure on auto-compaction\");\n \tTEST(t_reftable_stack_auto_compaction_with_locked_tables(), \"auto compaction with locked tables\");\n \tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n-- \n2.45.GIT\n\n"},{"id":"502145","messageId":"20240904150132.11567-7-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240904150132.11567-1-chandrapratap3519@gmail.com","subject":"[PATCH v4 6/6] t-reftable-stack: add test for stack iterators","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-04T14:38:06Z","receivedAt":"2024-09-04T15:02:12Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"reftable_stack_init_ref_iterator and reftable_stack_init_log_iterator\nas defined by reftable/stack.{c,h} initialize a stack iterator to\niterate over the ref and log records in a reftable stack respectively.\nSince these functions are not exercised by any of the existing tests,\nadd a test for them.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 80 +++++++++++++++++++++++++++++++++\n 1 file changed, 80 insertions(+)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 4acf07ab0c..e209652031 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -544,6 +544,85 @@ static void t_reftable_stack_add(void)\n \tclear_dir(dir);\n }\n \n+static void t_reftable_stack_iterator(void)\n+{\n+\tstruct reftable_write_options opts = { 0 };\n+\tstruct reftable_stack *st = NULL;\n+\tchar *dir = get_tmp_dir(__LINE__);\n+\tstruct reftable_ref_record refs[10] = { 0 };\n+\tstruct reftable_log_record logs[10] = { 0 };\n+\tstruct reftable_iterator it = { 0 };\n+\tsize_t N = ARRAY_SIZE(refs), i;\n+\tint err;\n+\n+\terr = reftable_new_stack(&st, dir, &opts);\n+\tcheck(!err);\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\trefs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n+\t\trefs[i].update_index = i + 1;\n+\t\trefs[i].value_type = REFTABLE_REF_VAL1;\n+\t\tset_test_hash(refs[i].value.val1, i);\n+\n+\t\tlogs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n+\t\tlogs[i].update_index = i + 1;\n+\t\tlogs[i].value_type = REFTABLE_LOG_UPDATE;\n+\t\tlogs[i].value.update.email = xstrdup(\"johndoe@invalid\");\n+\t\tlogs[i].value.update.message = xstrdup(\"commit\\n\");\n+\t\tset_test_hash(logs[i].value.update.new_hash, i);\n+\t}\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\terr = reftable_stack_add(st, write_test_ref, &refs[i]);\n+\t\tcheck(!err);\n+\t}\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\tstruct write_log_arg arg = {\n+\t\t\t.log = &logs[i],\n+\t\t\t.update_index = reftable_stack_next_update_index(st),\n+\t\t};\n+\t\terr = reftable_stack_add(st, write_test_log, &arg);\n+\t\tcheck(!err);\n+\t}\n+\n+\treftable_stack_init_ref_iterator(st, &it);\n+\treftable_iterator_seek_ref(&it, refs[0].refname);\n+\tfor (i = 0; ; i++) {\n+\t\tstruct reftable_ref_record ref = { 0 };\n+\t\terr = reftable_iterator_next_ref(&it, &ref);\n+\t\tif (err > 0)\n+\t\t\tbreak;\n+\t\tcheck(!err);\n+\t\tcheck(reftable_ref_record_equal(&ref, &refs[i], GIT_SHA1_RAWSZ));\n+\t\treftable_ref_record_release(&ref);\n+\t}\n+\tcheck_int(i, ==, N);\n+\n+\treftable_iterator_destroy(&it);\n+\n+\treftable_stack_init_log_iterator(st, &it);\n+\treftable_iterator_seek_log(&it, logs[0].refname);\n+\tfor (i = 0; ; i++) {\n+\t\tstruct reftable_log_record log = { 0 };\n+\t\terr = reftable_iterator_next_log(&it, &log);\n+\t\tif (err > 0)\n+\t\t\tbreak;\n+\t\tcheck(!err);\n+\t\tcheck(reftable_log_record_equal(&log, &logs[i], GIT_SHA1_RAWSZ));\n+\t\treftable_log_record_release(&log);\n+\t}\n+\tcheck_int(i, ==, N);\n+\n+\treftable_stack_destroy(st);\n+\treftable_iterator_destroy(&it);\n+\tfor (i = 0; i < N; i++) {\n+\t\treftable_ref_record_release(&refs[i]);\n+\t\treftable_log_record_release(&logs[i]);\n+\t}\n+\tclear_dir(dir);\n+}\n+\n static void t_reftable_stack_log_normalize(void)\n {\n \tint err = 0;\n@@ -1225,6 +1304,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)\n \tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n \tTEST(t_reftable_stack_compaction_with_locked_tables(), \"compaction with locked tables\");\n \tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n+\tTEST(t_reftable_stack_iterator(), \"log and ref iterator for reftable stack\");\n \tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n \tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n \tTEST(t_reftable_stack_read_across_reload(), \"stack iterators work across reloads\");\n-- \n2.45.GIT\n\n"},{"id":"502155","messageId":"xmqqmskn9w3o.fsf@gitster.g","threadId":"61911","inReplyTo":"20240904150132.11567-2-chandrapratap3519@gmail.com","subject":"Re: [PATCH v4 1/6] t: move reftable/stack_test.c to the unit testing framework","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-09-04T17:17:47Z","receivedAt":"2024-09-04T17:17:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Chandra Pratap <chandrapratap3519@gmail.com> writes:\n\n>  int cmd__reftable(int argc, const char **argv)\n>  {\n>  \t/* test from simple to complex. */\n> -\tstack_test_main(argc, argv);\n>  \treturn 0;\n>  }\n\nThis makes cmd__reftable() a no-op.\n\nEven though you cannot remove t/helpter/test-reftable.c, as it\ncontains the implementation for \"test-tool dump-reftable\", we should\nat least be able to do something like this.\n\n--- >8 ---\nSubject: [PATCH 7/6] t: clean up leftover reftable test cruft\n\nWith migration of the tests of the reftable to the unit-tests\nframework, \"test-tool reftable\" has become an expensive no-op.\n\nRetire everything that uses \"test-tool reftable\", and everything\nthat is used to implement it.\n\nWhile at it, make the cmds[] list alphabetically sorted again by\nmoving the entry for \"dump-reftable\".\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/helper/test-reftable.c     |  6 ------\n t/helper/test-tool.c         |  3 +--\n t/helper/test-tool.h         |  1 -\n t/t0032-reftable-unittest.sh | 16 ----------------\n 4 files changed, 1 insertion(+), 25 deletions(-)\n\ndiff --git c/t/helper/test-reftable.c w/t/helper/test-reftable.c\nindex d27d7ee798..e62298c6a4 100644\n--- c/t/helper/test-reftable.c\n+++ w/t/helper/test-reftable.c\n@@ -9,12 +9,6 @@\n #include \"reftable/reftable-tests.h\"\n #include \"test-tool.h\"\n \n-int cmd__reftable(int argc, const char **argv)\n-{\n-\t/* test from simple to complex. */\n-\treturn 0;\n-}\n-\n static void print_help(void)\n {\n \tprintf(\"usage: dump [-st] arg\\n\\n\"\ndiff --git c/t/helper/test-tool.c w/t/helper/test-tool.c\nindex f8a67df7de..252fa5de63 100644\n--- c/t/helper/test-tool.c\n+++ w/t/helper/test-tool.c\n@@ -26,6 +26,7 @@ static struct test_cmd cmds[] = {\n \t{ \"drop-caches\", cmd__drop_caches },\n \t{ \"dump-cache-tree\", cmd__dump_cache_tree },\n \t{ \"dump-fsmonitor\", cmd__dump_fsmonitor },\n+\t{ \"dump-reftable\", cmd__dump_reftable },\n \t{ \"dump-split-index\", cmd__dump_split_index },\n \t{ \"dump-untracked-cache\", cmd__dump_untracked_cache },\n \t{ \"env-helper\", cmd__env_helper },\n@@ -61,9 +62,7 @@ static struct test_cmd cmds[] = {\n \t{ \"read-graph\", cmd__read_graph },\n \t{ \"read-midx\", cmd__read_midx },\n \t{ \"ref-store\", cmd__ref_store },\n-\t{ \"reftable\", cmd__reftable },\n \t{ \"rot13-filter\", cmd__rot13_filter },\n-\t{ \"dump-reftable\", cmd__dump_reftable },\n \t{ \"regex\", cmd__regex },\n \t{ \"repository\", cmd__repository },\n \t{ \"revision-walking\", cmd__revision_walking },\ndiff --git c/t/helper/test-tool.h w/t/helper/test-tool.h\nindex e74bc0ffd4..84291318cb 100644\n--- c/t/helper/test-tool.h\n+++ w/t/helper/test-tool.h\n@@ -55,7 +55,6 @@ int cmd__read_graph(int argc, const char **argv);\n int cmd__read_midx(int argc, const char **argv);\n int cmd__ref_store(int argc, const char **argv);\n int cmd__rot13_filter(int argc, const char **argv);\n-int cmd__reftable(int argc, const char **argv);\n int cmd__regex(int argc, const char **argv);\n int cmd__repository(int argc, const char **argv);\n int cmd__revision_walking(int argc, const char **argv);\ndiff --git c/t/t0032-reftable-unittest.sh w/t/t0032-reftable-unittest.sh\ndeleted file mode 100755\nindex 471cb37ac2..0000000000\n--- c/t/t0032-reftable-unittest.sh\n+++ /dev/null\n@@ -1,16 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright (c) 2020 Google LLC\n-#\n-\n-test_description='reftable unittests'\n-\n-TEST_PASSES_SANITIZE_LEAK=true\n-. ./test-lib.sh\n-\n-test_expect_success 'unittests' '\n-\tTMPDIR=$(pwd) && export TMPDIR &&\n-\ttest-tool reftable\n-'\n-\n-test_done\n"},{"id":"502194","messageId":"ZtlacTtiEgPCRzTi@pks.im","threadId":"61911","inReplyTo":"20240904150132.11567-4-chandrapratap3519@gmail.com","subject":"Re: [PATCH v4 3/6] t-reftable-stack: use Git's tempfile API instead of mkstemp()","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-09-05T07:14:57Z","receivedAt":"2024-09-05T07:15:03Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Wed, Sep 04, 2024 at 08:08:03PM +0530, Chandra Pratap wrote:\n> Git's tempfile API defined by $GIT_DIR/tempfile.{c,h} provides\n> a unified interface for tempfile operations. Since reftable/stack.c\n> uses this API for all its tempfile needs instead of raw functions\n> like mkstemp(), make the ported stack test strictly use Git's\n> tempfile API as well.\n\nI don't quite think that this is sufficient motivation. The real benefit\nis that we know to clean up the tempfile in case the test fails because\nit gets registered and pruned via a signal handler.\n\nPatrick\n\n> Mentored-by: Patrick Steinhardt <ps@pks.im>\n> Mentored-by: Christian Couder <chriscool@tuxfamily.org>\n> Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n> ---\n>  t/unit-tests/t-reftable-stack.c | 4 +++-\n>  1 file changed, 3 insertions(+), 1 deletion(-)\n> \n> diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\n> index c74660a1e2..8047e25c48 100644\n> --- a/t/unit-tests/t-reftable-stack.c\n> +++ b/t/unit-tests/t-reftable-stack.c\n> @@ -76,7 +76,8 @@ static char *get_tmp_dir(int linenumber)\n>  static void t_read_file(void)\n>  {\n>  \tchar *fn = get_tmp_template(__LINE__);\n> -\tint fd = mkstemp(fn);\n> +\tstruct tempfile *tmp = mks_tempfile(fn);\n> +\tint fd = get_tempfile_fd(tmp);\n>  \tchar out[1024] = \"line1\\n\\nline2\\nline3\";\n>  \tint n, err;\n>  \tchar **names = NULL;\n> @@ -95,6 +96,7 @@ static void t_read_file(void)\n>  \t\tcheck_str(want[i], names[i]);\n>  \tfree_names(names);\n>  \t(void) remove(fn);\n> +\tdelete_tempfile(&tmp);\n>  }\n>  \n>  static int write_test_ref(struct reftable_writer *wr, void *arg)\n> -- \n> 2.45.GIT\n> \n"},{"id":"502195","messageId":"Ztladu-lhTbg1fXj@pks.im","threadId":"61911","inReplyTo":"20240904150132.11567-5-chandrapratap3519@gmail.com","subject":"Re: [PATCH v4 4/6] t-reftable-stack: use reftable_ref_record_equal() to compare ref records","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-09-05T07:15:02Z","receivedAt":"2024-09-05T07:15:05Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Wed, Sep 04, 2024 at 08:08:04PM +0530, Chandra Pratap wrote:\n> In the current stack tests, ref records are compared for equality\n> by sometimes using the dedicated function for ref-record comparison,\n> reftable_ref_record_equal(), and sometimes by explicity comparing\n> contents of the ref records.\n> \n> Replace the latter instances of ref-record comparison with the\n> former to maintain uniformity throughout the test file.\n\nIt's not really about uniformity in my opinion. It's rather that the\nfunction is a lot more thorough than only comparing the refname, which I\nthink is the real win here.\n\nPatrick\n\n> Mentored-by: Patrick Steinhardt <ps@pks.im>\n> Mentored-by: Christian Couder <chriscool@tuxfamily.org>\n> Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n> ---\n>  t/unit-tests/t-reftable-stack.c | 4 ++--\n>  1 file changed, 2 insertions(+), 2 deletions(-)\n> \n> diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\n> index 8047e25c48..4f2ef1a8cc 100644\n> --- a/t/unit-tests/t-reftable-stack.c\n> +++ b/t/unit-tests/t-reftable-stack.c\n> @@ -174,7 +174,7 @@ static void t_reftable_stack_add_one(void)\n>  \n>  \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n>  \tcheck(!err);\n> -\tcheck_str(\"master\", dest.value.symref);\n> +\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n>  \tcheck_int(st->readers_len, >, 0);\n>  \n>  #ifndef GIT_WINDOWS_NATIVE\n> @@ -285,7 +285,7 @@ static void t_reftable_stack_transaction_api(void)\n>  \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n>  \tcheck(!err);\n>  \tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n> -\tcheck_str(\"master\", dest.value.symref);\n> +\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n>  \n>  \treftable_ref_record_release(&dest);\n>  \treftable_stack_destroy(st);\n> -- \n> 2.45.GIT\n> \n"},{"id":"502196","messageId":"ZtlaeQ-SqrCPP_SA@pks.im","threadId":"61911","inReplyTo":"20240904150132.11567-7-chandrapratap3519@gmail.com","subject":"Re: [PATCH v4 6/6] t-reftable-stack: add test for stack iterators","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-09-05T07:15:05Z","receivedAt":"2024-09-05T07:15:08Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Wed, Sep 04, 2024 at 08:08:06PM +0530, Chandra Pratap wrote:\n> reftable_stack_init_ref_iterator and reftable_stack_init_log_iterator\n> as defined by reftable/stack.{c,h} initialize a stack iterator to\n> iterate over the ref and log records in a reftable stack respectively.\n> Since these functions are not exercised by any of the existing tests,\n> add a test for them.\n> \n> Mentored-by: Patrick Steinhardt <ps@pks.im>\n> Mentored-by: Christian Couder <chriscool@tuxfamily.org>\n> Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n> ---\n>  t/unit-tests/t-reftable-stack.c | 80 +++++++++++++++++++++++++++++++++\n>  1 file changed, 80 insertions(+)\n> \n> diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\n> index 4acf07ab0c..e209652031 100644\n> --- a/t/unit-tests/t-reftable-stack.c\n> +++ b/t/unit-tests/t-reftable-stack.c\n> @@ -544,6 +544,85 @@ static void t_reftable_stack_add(void)\n>  \tclear_dir(dir);\n>  }\n>  \n> +static void t_reftable_stack_iterator(void)\n> +{\n> +\tstruct reftable_write_options opts = { 0 };\n> +\tstruct reftable_stack *st = NULL;\n> +\tchar *dir = get_tmp_dir(__LINE__);\n> +\tstruct reftable_ref_record refs[10] = { 0 };\n> +\tstruct reftable_log_record logs[10] = { 0 };\n> +\tstruct reftable_iterator it = { 0 };\n> +\tsize_t N = ARRAY_SIZE(refs), i;\n> +\tint err;\n> +\n> +\terr = reftable_new_stack(&st, dir, &opts);\n> +\tcheck(!err);\n> +\n> +\tfor (i = 0; i < N; i++) {\n> +\t\trefs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n> +\t\trefs[i].update_index = i + 1;\n> +\t\trefs[i].value_type = REFTABLE_REF_VAL1;\n> +\t\tset_test_hash(refs[i].value.val1, i);\n> +\n> +\t\tlogs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n> +\t\tlogs[i].update_index = i + 1;\n> +\t\tlogs[i].value_type = REFTABLE_LOG_UPDATE;\n> +\t\tlogs[i].value.update.email = xstrdup(\"johndoe@invalid\");\n> +\t\tlogs[i].value.update.message = xstrdup(\"commit\\n\");\n> +\t\tset_test_hash(logs[i].value.update.new_hash, i);\n> +\t}\n> +\n> +\tfor (i = 0; i < N; i++) {\n> +\t\terr = reftable_stack_add(st, write_test_ref, &refs[i]);\n> +\t\tcheck(!err);\n> +\t}\n> +\n> +\tfor (i = 0; i < N; i++) {\n> +\t\tstruct write_log_arg arg = {\n> +\t\t\t.log = &logs[i],\n> +\t\t\t.update_index = reftable_stack_next_update_index(st),\n> +\t\t};\n\nNit: Let's add a newline between the variable declarations and the code,\nboth here and in the other loops further down.\n\nPatrick\n"},{"id":"502197","messageId":"ZtlafDnM-geVUTQ9@pks.im","threadId":"61911","inReplyTo":"xmqqmskn9w3o.fsf@gitster.g","subject":"Re: [PATCH v4 1/6] t: move reftable/stack_test.c to the unit testing framework","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-09-05T07:15:08Z","receivedAt":"2024-09-05T07:15:14Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Wed, Sep 04, 2024 at 10:17:47AM -0700, Junio C Hamano wrote:\n> Chandra Pratap <chandrapratap3519@gmail.com> writes:\n> \n> >  int cmd__reftable(int argc, const char **argv)\n> >  {\n> >  \t/* test from simple to complex. */\n> > -\tstack_test_main(argc, argv);\n> >  \treturn 0;\n> >  }\n> \n> This makes cmd__reftable() a no-op.\n> \n> Even though you cannot remove t/helpter/test-reftable.c, as it\n> contains the implementation for \"test-tool dump-reftable\", we should\n> at least be able to do something like this.\n\nIn addition to Junio's patch you can also remove\n\"reftable/reftable-tests.h\".\n\nPatrick\n"},{"id":"502240","messageId":"CA+J6zkR35jgmCuWniqDBBcTOW68V3Kzn1x8Yc5PZLHxO_cPtaA@mail.gmail.com","threadId":"61911","inReplyTo":"ZtlafDnM-geVUTQ9@pks.im","subject":"Re: [PATCH v4 1/6] t: move reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-05T14:45:53Z","receivedAt":"2024-09-05T14:46:20Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"On Thu, 5 Sept 2024 at 12:45, Patrick Steinhardt <ps@pks.im> wrote:\n>\n> On Wed, Sep 04, 2024 at 10:17:47AM -0700, Junio C Hamano wrote:\n> > Chandra Pratap <chandrapratap3519@gmail.com> writes:\n> >\n> > >  int cmd__reftable(int argc, const char **argv)\n> > >  {\n> > >     /* test from simple to complex. */\n> > > -   stack_test_main(argc, argv);\n> > >     return 0;\n> > >  }\n> >\n> > This makes cmd__reftable() a no-op.\n> >\n> > Even though you cannot remove t/helpter/test-reftable.c, as it\n> > contains the implementation for \"test-tool dump-reftable\", we should\n> > at least be able to do something like this.\n>\n> In addition to Junio's patch you can also remove\n> \"reftable/reftable-tests.h\".\n\nShould we get rid of reftable/test_framework.{c, h} as well?\n"},{"id":"502242","messageId":"ZtnHoNYbBh0Gkqza@pks.im","threadId":"61911","inReplyTo":"CA+J6zkR35jgmCuWniqDBBcTOW68V3Kzn1x8Yc5PZLHxO_cPtaA@mail.gmail.com","subject":"Re: [PATCH v4 1/6] t: move reftable/stack_test.c to the unit testing framework","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-09-05T15:00:48Z","receivedAt":"2024-09-05T15:00:56Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Sep 05, 2024 at 08:15:53PM +0530, Chandra Pratap wrote:\n> On Thu, 5 Sept 2024 at 12:45, Patrick Steinhardt <ps@pks.im> wrote:\n> >\n> > On Wed, Sep 04, 2024 at 10:17:47AM -0700, Junio C Hamano wrote:\n> > > Chandra Pratap <chandrapratap3519@gmail.com> writes:\n> > >\n> > > >  int cmd__reftable(int argc, const char **argv)\n> > > >  {\n> > > >     /* test from simple to complex. */\n> > > > -   stack_test_main(argc, argv);\n> > > >     return 0;\n> > > >  }\n> > >\n> > > This makes cmd__reftable() a no-op.\n> > >\n> > > Even though you cannot remove t/helpter/test-reftable.c, as it\n> > > contains the implementation for \"test-tool dump-reftable\", we should\n> > > at least be able to do something like this.\n> >\n> > In addition to Junio's patch you can also remove\n> > \"reftable/reftable-tests.h\".\n> \n> Should we get rid of reftable/test_framework.{c, h} as well?\n\nAh, yeah. If it's not needed anymore we should remove it. I have a patch\nseries pending anyway where I deduplicate some of the functionality that\nwe have in multiple reftable tests now.\n\nPatrick\n"},{"id":"502278","messageId":"xmqqseue0wnu.fsf@gitster.g","threadId":"61911","inReplyTo":"ZtnHoNYbBh0Gkqza@pks.im","subject":"Re: [PATCH v4 1/6] t: move reftable/stack_test.c to the unit testing framework","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-09-05T18:42:45Z","receivedAt":"2024-09-05T18:42:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> On Thu, Sep 05, 2024 at 08:15:53PM +0530, Chandra Pratap wrote:\n>\n>> Should we get rid of reftable/test_framework.{c, h} as well?\n>\n> Ah, yeah. If it's not needed anymore we should remove it. I have a patch\n> series pending anyway where I deduplicate some of the functionality that\n> we have in multiple reftable tests now.\n\nIt is unclear if you are saying that Chandra should do the removal\nas part of an updated version of this series, or you'll do the\nremoval with refactoring in a separate series and Chandra shouldn't\nworry about it for now.\n\nAfter reading your message three times, I am leaning to take it as\nthe latter.\n\nThanks.\n"},{"id":"502305","messageId":"Ztqa-5HwvkEeWb4H@pks.im","threadId":"61911","inReplyTo":"xmqqseue0wnu.fsf@gitster.g","subject":"Re: [PATCH v4 1/6] t: move reftable/stack_test.c to the unit testing framework","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-09-06T06:02:44Z","receivedAt":"2024-09-06T06:02:50Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Sep 05, 2024 at 11:42:45AM -0700, Junio C Hamano wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> > On Thu, Sep 05, 2024 at 08:15:53PM +0530, Chandra Pratap wrote:\n> >\n> >> Should we get rid of reftable/test_framework.{c, h} as well?\n> >\n> > Ah, yeah. If it's not needed anymore we should remove it. I have a patch\n> > series pending anyway where I deduplicate some of the functionality that\n> > we have in multiple reftable tests now.\n> \n> It is unclear if you are saying that Chandra should do the removal\n> as part of an updated version of this series, or you'll do the\n> removal with refactoring in a separate series and Chandra shouldn't\n> worry about it for now.\n> \n> After reading your message three times, I am leaning to take it as\n> the latter.\n\nAh, sorry for being unclear.\n\nThe test framework used to contain some functions that were reused\nacross different reftable tests. During the migration we have instead\ncopied the necessary helpers into each of the migrated tests and thus\nhave a bit of duplication there, which was the right choice during the\nmigration to not have all migrations depend on each other. But now that\nwe are done we should deduplicate them again, and I have a patch series\npending that introduces `t/unit-tests/lib-reftable.c` that deduplicates\nsome of the functions again.\n\nSo my intention was to say that this is safe to remove as part of the\nseries we have here, and we do not have to worry about the current\nduplication we have.\n\nPatrick\n"},{"id":"502321","messageId":"20240906113746.8903-1-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240904150132.11567-1-chandrapratap3519@gmail.com","subject":"[GSoC][PATCH v5 0/7] t: port reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-06T11:29:09Z","receivedAt":"2024-09-06T11:44:59Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"The reftable library comes with self tests, which are exercised\nas part of the usual end-to-end tests and are designed to\nobserve the end-user visible effects of Git commands. What it\nexercises, however, is a better match for the unit-testing\nframework, merged at 8bf6fbd0 (Merge branch 'js/doc-unit-tests',\n2023-12-09), which is designed to observe how low level\nimplementation details, at the level of sequences of individual\nfunction calls, behave.\n\nHence, port reftable/stack_test.c to the unit testing framework and\nimprove upon the ported test. The first patch in the series moves\nthe test to the unit testing framework, and the rest of the patches\nimprove upon the ported test.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n\n---\nChanges in v5:\n- Edit the commit messages in patches 3 and 4 to reflect the changes\n  and the motivation behind those changes better.\n- Add newlines after variable declarations in patch 6.\n- Introduce patch 7 which removes leftover cruft from the previous\n  reftable testing scheme.\n\nCI/PR: https://github.com/gitgitgadget/git/pull/1762\n\nChandra Pratap(7):\nt: move reftable/stack_test.c to the unit testing framework\nt: harmonize t-reftable-stack.c with coding guidelines\nt-reftable-stack: use Git's tempfile API instead of mkstemp()\nt-reftable-stack: use reftable_ref_record_equal() to compare ref records\nt-reftable-stack: add test for non-default compaction factor\nt-reftable-stack: add test for stack iterators\nt: clean up leftover reftable test cruft\n\nMakefile                                           |   4 +-\nreftable/reftable-tests.h                          |  14 -\nreftable/test_framework.c                          |  27 -\nreftable/test_framework.h                          |  61 --\nt/helper/test-reftable.c                           |   8 -\nt/helper/test-tool.c                               |   3 +-\nt/helper/test-tool.h                               |   1 -\nt/t0032-reftable-unittest.sh                       |  16 -\n.../unit-tests/t-reftable-stack.c                  | 665 ++++++++++++---------\n9 files changed, 390 insertions(+), 409 deletions(-)\n\nRange-diff against v4:\n1:  eae681f53d ! 1:  ca4b00feef t-reftable-stack: use Git's tempfile API instead of mkstemp()\n    @@ Commit message\n         like mkstemp(), make the ported stack test strictly use Git's\n         tempfile API as well.\n\n    +    A bigger benefit is the fact that we know to clean up the tempfile\n    +    in case the test fails because it gets registered and pruned via a\n    +    signal handler.\n    +\n         Mentored-by: Patrick Steinhardt <ps@pks.im>\n         Mentored-by: Christian Couder <chriscool@tuxfamily.org>\n         Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n2:  19b2f41003 ! 2:  3e723667dd t-reftable-stack: use reftable_ref_record_equal() to compare ref records\n    @@ Commit message\n         reftable_ref_record_equal(), and sometimes by explicity comparing\n         contents of the ref records.\n\n    -    Replace the latter instances of ref-record comparison with the\n    -    former to maintain uniformity throughout the test file.\n    +    The latter method is undesired because there can exist unequal ref\n    +    records with the some of the contents being equal. Replace the latter\n    +    instances of ref-record comparison with the former. This has the\n    +    added benefit of preserving uniformity throughout the test file.\n\n         Mentored-by: Patrick Steinhardt <ps@pks.im>\n         Mentored-by: Christian Couder <chriscool@tuxfamily.org>\n3:  ffdfba6b98 = 3:  7526550c92 t-reftable-stack: add test for non-default compaction factor\n4:  ca447664e7 ! 4:  05e4b7e715 t-reftable-stack: add test for stack iterators\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add(void)\n     +\t\t\t.log = &logs[i],\n     +\t\t\t.update_index = reftable_stack_next_update_index(st),\n     +\t\t};\n    ++\n     +\t\terr = reftable_stack_add(st, write_test_log, &arg);\n     +\t\tcheck(!err);\n     +\t}\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add(void)\n     +\treftable_iterator_seek_ref(&it, refs[0].refname);\n     +\tfor (i = 0; ; i++) {\n     +\t\tstruct reftable_ref_record ref = { 0 };\n    ++\n     +\t\terr = reftable_iterator_next_ref(&it, &ref);\n     +\t\tif (err > 0)\n     +\t\t\tbreak;\n    @@ t/unit-tests/t-reftable-stack.c: static void t_reftable_stack_add(void)\n     +\treftable_iterator_seek_log(&it, logs[0].refname);\n     +\tfor (i = 0; ; i++) {\n     +\t\tstruct reftable_log_record log = { 0 };\n    ++\n     +\t\terr = reftable_iterator_next_log(&it, &log);\n     +\t\tif (err > 0)\n     +\t\t\tbreak;\n-:  ---------- > 5:  43c1a522fb t: clean up leftover reftable test cruft\n\n"},{"id":"502322","messageId":"20240906113746.8903-2-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240906113746.8903-1-chandrapratap3519@gmail.com","subject":"[PATCH v5 1/7] t: move reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-06T11:29:10Z","receivedAt":"2024-09-06T11:45:02Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"reftable/stack_test.c exercises the functions defined in\nreftable/stack.{c, h}. Migrate reftable/stack_test.c to the\nunit testing framework. Migration involves refactoring the tests\nto use the unit testing framework instead of reftable's test\nframework and renaming the tests to be in-line with unit-tests'\nstandards.\n\nSince some of the tests use set_test_hash() defined by\nreftable/test_framework.{c, h} but these files are not\n'#included' in the test file, copy this function in the\nported test file.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n Makefile                                      |   2 +-\n reftable/reftable-tests.h                     |   1 -\n t/helper/test-reftable.c                      |   1 -\n .../unit-tests/t-reftable-stack.c             | 429 +++++++++---------\n 4 files changed, 214 insertions(+), 219 deletions(-)\n rename reftable/stack_test.c => t/unit-tests/t-reftable-stack.c (76%)\n\ndiff --git a/Makefile b/Makefile\nindex 91f65d7dc5..1cbc2d61ae 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1349,6 +1349,7 @@ UNIT_TEST_PROGRAMS += t-reftable-merged\n UNIT_TEST_PROGRAMS += t-reftable-pq\n UNIT_TEST_PROGRAMS += t-reftable-readwrite\n UNIT_TEST_PROGRAMS += t-reftable-record\n+UNIT_TEST_PROGRAMS += t-reftable-stack\n UNIT_TEST_PROGRAMS += t-reftable-tree\n UNIT_TEST_PROGRAMS += t-strbuf\n UNIT_TEST_PROGRAMS += t-strcmp-offset\n@@ -2691,7 +2692,6 @@ REFTABLE_OBJS += reftable/stack.o\n REFTABLE_OBJS += reftable/tree.o\n REFTABLE_OBJS += reftable/writer.o\n \n-REFTABLE_TEST_OBJS += reftable/stack_test.o\n REFTABLE_TEST_OBJS += reftable/test_framework.o\n \n TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))\ndiff --git a/reftable/reftable-tests.h b/reftable/reftable-tests.h\nindex 5d725c69c7..05f8d2d5bc 100644\n--- a/reftable/reftable-tests.h\n+++ b/reftable/reftable-tests.h\n@@ -9,6 +9,5 @@ license that can be found in the LICENSE file or at\n #ifndef REFTABLE_TESTS_H\n #define REFTABLE_TESTS_H\n \n-int stack_test_main(int argc, const char **argv);\n \n #endif\ndiff --git a/t/helper/test-reftable.c b/t/helper/test-reftable.c\nindex ce5a94fbd3..d27d7ee798 100644\n--- a/t/helper/test-reftable.c\n+++ b/t/helper/test-reftable.c\n@@ -12,7 +12,6 @@\n int cmd__reftable(int argc, const char **argv)\n {\n \t/* test from simple to complex. */\n-\tstack_test_main(argc, argv);\n \treturn 0;\n }\n \ndiff --git a/reftable/stack_test.c b/t/unit-tests/t-reftable-stack.c\nsimilarity index 76%\nrename from reftable/stack_test.c\nrename to t/unit-tests/t-reftable-stack.c\nindex 89cb2be19f..de28fac466 100644\n--- a/reftable/stack_test.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -6,22 +6,18 @@ license that can be found in the LICENSE file or at\n https://developers.google.com/open-source/licenses/bsd\n */\n \n-#include \"stack.h\"\n-\n-#include \"system.h\"\n-\n-#include \"copy.h\"\n-#include \"reftable-reader.h\"\n-#include \"merged.h\"\n-#include \"basics.h\"\n-#include \"record.h\"\n-#include \"test_framework.h\"\n-#include \"reftable-tests.h\"\n-#include \"reader.h\"\n-\n-#include <sys/types.h>\n+#include \"test-lib.h\"\n+#include \"reftable/merged.h\"\n+#include \"reftable/reader.h\"\n+#include \"reftable/reftable-error.h\"\n+#include \"reftable/stack.h\"\n #include <dirent.h>\n \n+static void set_test_hash(uint8_t *p, int i)\n+{\n+\tmemset(p, (uint8_t)i, hash_size(GIT_SHA1_FORMAT_ID));\n+}\n+\n static void clear_dir(const char *dirname)\n {\n \tstruct strbuf path = STRBUF_INIT;\n@@ -73,11 +69,11 @@ static char *get_tmp_template(int linenumber)\n static char *get_tmp_dir(int linenumber)\n {\n \tchar *dir = get_tmp_template(linenumber);\n-\tEXPECT(mkdtemp(dir));\n+\tcheck(mkdtemp(dir) != NULL);\n \treturn dir;\n }\n \n-static void test_read_file(void)\n+static void t_read_file(void)\n {\n \tchar *fn = get_tmp_template(__LINE__);\n \tint fd = mkstemp(fn);\n@@ -87,17 +83,17 @@ static void test_read_file(void)\n \tconst char *want[] = { \"line1\", \"line2\", \"line3\" };\n \tint i = 0;\n \n-\tEXPECT(fd > 0);\n+\tcheck_int(fd, >, 0);\n \tn = write_in_full(fd, out, strlen(out));\n-\tEXPECT(n == strlen(out));\n+\tcheck_int(n, ==, strlen(out));\n \terr = close(fd);\n-\tEXPECT(err >= 0);\n+\tcheck_int(err, >=, 0);\n \n \terr = read_lines(fn, &names);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; names[i]; i++) {\n-\t\tEXPECT(0 == strcmp(want[i], names[i]));\n+\t\tcheck_str(want[i], names[i]);\n \t}\n \tfree_names(names);\n \t(void) remove(fn);\n@@ -132,7 +128,7 @@ static void write_n_ref_tables(struct reftable_stack *st,\n \t\tset_test_hash(ref.value.val1, i);\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tst->opts.disable_auto_compact = disable_auto_compact;\n@@ -152,7 +148,7 @@ static int write_test_log(struct reftable_writer *wr, void *arg)\n \treturn reftable_writer_add_log(wr, wla->log);\n }\n \n-static void test_reftable_stack_add_one(void)\n+static void t_reftable_stack_add_one(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct strbuf scratch = STRBUF_INIT;\n@@ -171,22 +167,22 @@ static void test_reftable_stack_add_one(void)\n \tstruct reftable_ref_record dest = { NULL };\n \tstruct stat stat_result = { 0 };\n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(\"master\", dest.value.symref));\n-\tEXPECT(st->readers_len > 0);\n+\tcheck(!err);\n+\tcheck_str(\"master\", dest.value.symref);\n+\tcheck_int(st->readers_len, >, 0);\n \n #ifndef GIT_WINDOWS_NATIVE\n \tstrbuf_addstr(&scratch, dir);\n \tstrbuf_addstr(&scratch, \"/tables.list\");\n \terr = stat(scratch.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n \n \tstrbuf_reset(&scratch);\n \tstrbuf_addstr(&scratch, dir);\n@@ -194,8 +190,8 @@ static void test_reftable_stack_add_one(void)\n \t/* do not try at home; not an external API for reftable. */\n \tstrbuf_addstr(&scratch, st->readers[0]->name);\n \terr = stat(scratch.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n #else\n \t(void) stat_result;\n #endif\n@@ -207,7 +203,7 @@ static void test_reftable_stack_add_one(void)\n \tumask(mask);\n }\n \n-static void test_reftable_stack_uptodate(void)\n+static void t_reftable_stack_uptodate(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL;\n@@ -233,28 +229,28 @@ static void test_reftable_stack_uptodate(void)\n \t   by creating two stacks for the same directory.\n \t */\n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st1, &write_test_ref, &ref1);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n-\tEXPECT(err == REFTABLE_OUTDATED_ERROR);\n+\tcheck_int(err, ==, REFTABLE_OUTDATED_ERROR);\n \n \terr = reftable_stack_reload(st2);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_transaction_api(void)\n+static void t_reftable_stack_transaction_api(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -271,32 +267,32 @@ static void test_reftable_stack_transaction_api(void)\n \tstruct reftable_ref_record dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_addition_destroy(add);\n \n \terr = reftable_stack_new_addition(&add, st);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_addition_add(add, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_addition_commit(add);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_addition_destroy(add);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(REFTABLE_REF_SYMREF == dest.value_type);\n-\tEXPECT(0 == strcmp(\"master\", dest.value.symref));\n+\tcheck(!err);\n+\tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n+\tcheck_str(\"master\", dest.value.symref);\n \n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n+static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = {0};\n@@ -305,7 +301,7 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \tint i, n = 20, err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n@@ -326,13 +322,13 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\tst->opts.disable_auto_compact = i != n;\n \n \t\terr = reftable_stack_new_addition(&add, st);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_addition_add(add, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_addition_commit(add);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\treftable_addition_destroy(add);\n \n@@ -342,16 +338,16 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\t * all tables in the stack.\n \t\t */\n \t\tif (i != n)\n-\t\t\tEXPECT(st->merged->readers_len == i + 1);\n+\t\t\tcheck_int(st->merged->readers_len, ==, i + 1);\n \t\telse\n-\t\t\tEXPECT(st->merged->readers_len == 1);\n+\t\t\tcheck_int(st->merged->readers_len, ==, 1);\n \t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n+static void t_reftable_stack_auto_compaction_fails_gracefully(void)\n {\n \tstruct reftable_ref_record ref = {\n \t\t.refname = (char *) \"refs/heads/master\",\n@@ -366,13 +362,13 @@ static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->merged->readers_len == 1);\n-\tEXPECT(st->stats.attempts == 0);\n-\tEXPECT(st->stats.failures == 0);\n+\tcheck(!err);\n+\tcheck_int(st->merged->readers_len, ==, 1);\n+\tcheck_int(st->stats.attempts, ==, 0);\n+\tcheck_int(st->stats.failures, ==, 0);\n \n \t/*\n \t * Lock the newly written table such that it cannot be compacted.\n@@ -384,10 +380,10 @@ static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n \n \tref.update_index = 2;\n \terr = reftable_stack_add(st, write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->merged->readers_len == 2);\n-\tEXPECT(st->stats.attempts == 1);\n-\tEXPECT(st->stats.failures == 1);\n+\tcheck(!err);\n+\tcheck_int(st->merged->readers_len, ==, 2);\n+\tcheck_int(st->stats.attempts, ==, 1);\n+\tcheck_int(st->stats.failures, ==, 1);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&table_path);\n@@ -399,7 +395,7 @@ static int write_error(struct reftable_writer *wr UNUSED, void *arg)\n \treturn *((int *)arg);\n }\n \n-static void test_reftable_stack_update_index_check(void)\n+static void t_reftable_stack_update_index_check(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -419,18 +415,18 @@ static void test_reftable_stack_update_index_check(void)\n \t};\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref1);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref2);\n-\tEXPECT(err == REFTABLE_API_ERROR);\n+\tcheck_int(err, ==, REFTABLE_API_ERROR);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_lock_failure(void)\n+static void t_reftable_stack_lock_failure(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -438,17 +434,17 @@ static void test_reftable_stack_lock_failure(void)\n \tint err, i;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \tfor (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) {\n \t\terr = reftable_stack_add(st, &write_error, &i);\n-\t\tEXPECT(err == i);\n+\t\tcheck_int(err, ==, i);\n \t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_add(void)\n+static void t_reftable_stack_add(void)\n {\n \tint i = 0;\n \tint err = 0;\n@@ -466,7 +462,7 @@ static void test_reftable_stack_add(void)\n \tint N = ARRAY_SIZE(refs);\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar buf[256];\n@@ -485,7 +481,7 @@ static void test_reftable_stack_add(void)\n \n \tfor (i = 0; i < N; i++) {\n \t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tfor (i = 0; i < N; i++) {\n@@ -494,18 +490,18 @@ static void test_reftable_stack_add(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tstruct reftable_ref_record dest = { NULL };\n \n \t\tint err = reftable_stack_read_ref(st, refs[i].refname, &dest);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(reftable_ref_record_equal(&dest, refs + i,\n+\t\tcheck(!err);\n+\t\tcheck(reftable_ref_record_equal(&dest, refs + i,\n \t\t\t\t\t\t GIT_SHA1_RAWSZ));\n \t\treftable_ref_record_release(&dest);\n \t}\n@@ -513,8 +509,8 @@ static void test_reftable_stack_add(void)\n \tfor (i = 0; i < N; i++) {\n \t\tstruct reftable_log_record dest = { NULL };\n \t\tint err = reftable_stack_read_log(st, refs[i].refname, &dest);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(reftable_log_record_equal(&dest, logs + i,\n+\t\tcheck(!err);\n+\t\tcheck(reftable_log_record_equal(&dest, logs + i,\n \t\t\t\t\t\t GIT_SHA1_RAWSZ));\n \t\treftable_log_record_release(&dest);\n \t}\n@@ -523,8 +519,8 @@ static void test_reftable_stack_add(void)\n \tstrbuf_addstr(&path, dir);\n \tstrbuf_addstr(&path, \"/tables.list\");\n \terr = stat(path.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n \n \tstrbuf_reset(&path);\n \tstrbuf_addstr(&path, dir);\n@@ -532,8 +528,8 @@ static void test_reftable_stack_add(void)\n \t/* do not try at home; not an external API for reftable. */\n \tstrbuf_addstr(&path, st->readers[0]->name);\n \terr = stat(path.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n #else\n \t(void) stat_result;\n #endif\n@@ -548,7 +544,7 @@ static void test_reftable_stack_add(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_log_normalize(void)\n+static void t_reftable_stack_log_normalize(void)\n {\n \tint err = 0;\n \tstruct reftable_write_options opts = {\n@@ -576,27 +572,27 @@ static void test_reftable_stack_log_normalize(void)\n \t};\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tinput.value.update.message = (char *) \"one\\ntwo\";\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT(err == REFTABLE_API_ERROR);\n+\tcheck_int(err, ==, REFTABLE_API_ERROR);\n \n \tinput.value.update.message = (char *) \"one\";\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, input.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(dest.value.update.message, \"one\\n\"));\n+\tcheck(!err);\n+\tcheck_str(dest.value.update.message, \"one\\n\");\n \n \tinput.value.update.message = (char *) \"two\\n\";\n \targ.update_index = 2;\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \terr = reftable_stack_read_log(st, input.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(dest.value.update.message, \"two\\n\"));\n+\tcheck(!err);\n+\tcheck_str(dest.value.update.message, \"two\\n\");\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n@@ -604,7 +600,7 @@ static void test_reftable_stack_log_normalize(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_tombstone(void)\n+static void t_reftable_stack_tombstone(void)\n {\n \tint i = 0;\n \tchar *dir = get_tmp_dir(__LINE__);\n@@ -618,7 +614,7 @@ static void test_reftable_stack_tombstone(void)\n \tstruct reftable_log_record log_dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* even entries add the refs, odd entries delete them. */\n \tfor (i = 0; i < N; i++) {\n@@ -642,7 +638,7 @@ static void test_reftable_stack_tombstone(void)\n \t}\n \tfor (i = 0; i < N; i++) {\n \t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tfor (i = 0; i < N; i++) {\n@@ -651,25 +647,25 @@ static void test_reftable_stack_tombstone(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_read_ref(st, \"branch\", &dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_ref_record_release(&dest);\n \n \terr = reftable_stack_read_log(st, \"branch\", &log_dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_log_record_release(&log_dest);\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, \"branch\", &dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, \"branch\", &log_dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_ref_record_release(&dest);\n \treftable_log_record_release(&log_dest);\n \n@@ -682,7 +678,7 @@ static void test_reftable_stack_tombstone(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_hash_id(void)\n+static void t_reftable_stack_hash_id(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -702,47 +698,47 @@ static void test_reftable_stack_hash_id(void)\n \tstruct reftable_ref_record dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* can't read it with the wrong hash ID. */\n \terr = reftable_new_stack(&st32, dir, &opts32);\n-\tEXPECT(err == REFTABLE_FORMAT_ERROR);\n+\tcheck_int(err, ==, REFTABLE_FORMAT_ERROR);\n \n \t/* check that we can read it back with default opts too. */\n \terr = reftable_new_stack(&st_default, dir, &opts_default);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st_default, \"master\", &dest);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n-\tEXPECT(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n \treftable_stack_destroy(st_default);\n \tclear_dir(dir);\n }\n \n-static void test_suggest_compaction_segment(void)\n+static void t_suggest_compaction_segment(void)\n {\n \tuint64_t sizes[] = { 512, 64, 17, 16, 9, 9, 9, 16, 2, 16 };\n \tstruct segment min =\n \t\tsuggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);\n-\tEXPECT(min.start == 1);\n-\tEXPECT(min.end == 10);\n+\tcheck_int(min.start, ==, 1);\n+\tcheck_int(min.end, ==, 10);\n }\n \n-static void test_suggest_compaction_segment_nothing(void)\n+static void t_suggest_compaction_segment_nothing(void)\n {\n \tuint64_t sizes[] = { 64, 32, 16, 8, 4, 2 };\n \tstruct segment result =\n \t\tsuggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);\n-\tEXPECT(result.start == result.end);\n+\tcheck_int(result.start, ==, result.end);\n }\n \n-static void test_reflog_expire(void)\n+static void t_reflog_expire(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -757,7 +753,7 @@ static void test_reflog_expire(void)\n \tstruct reftable_log_record log = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 1; i <= N; i++) {\n \t\tchar buf[256];\n@@ -777,30 +773,30 @@ static void test_reflog_expire(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st, &expiry);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, logs[9].refname, &log);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, logs[11].refname, &log);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \texpiry.min_update_index = 15;\n \terr = reftable_stack_compact_all(st, &expiry);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, logs[14].refname, &log);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, logs[16].refname, &log);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n@@ -817,7 +813,7 @@ static int write_nothing(struct reftable_writer *wr, void *arg UNUSED)\n \treturn 0;\n }\n \n-static void test_empty_add(void)\n+static void t_empty_add(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -826,13 +822,13 @@ static void test_empty_add(void)\n \tstruct reftable_stack *st2 = NULL;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_nothing, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \tclear_dir(dir);\n \treftable_stack_destroy(st);\n \treftable_stack_destroy(st2);\n@@ -848,7 +844,7 @@ static int fastlog2(uint64_t sz)\n \treturn l - 1;\n }\n \n-static void test_reftable_stack_auto_compaction(void)\n+static void t_reftable_stack_auto_compaction(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -859,7 +855,7 @@ static void test_reftable_stack_auto_compaction(void)\n \tint N = 100;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar name[100];\n@@ -872,21 +868,21 @@ static void test_reftable_stack_auto_compaction(void)\n \t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_stack_auto_compact(st);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(i < 3 || st->merged->readers_len < 2 * fastlog2(i));\n+\t\tcheck(!err);\n+\t\tcheck(i < 3 || st->merged->readers_len < 2 * fastlog2(i));\n \t}\n \n-\tEXPECT(reftable_stack_compaction_stats(st)->entries_written <\n+\tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n \t       (uint64_t)(N * fastlog2(N)));\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n+static void t_reftable_stack_auto_compaction_with_locked_tables(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -897,10 +893,10 @@ static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \twrite_n_ref_tables(st, 5);\n-\tEXPECT(st->merged->readers_len == 5);\n+\tcheck_int(st->merged->readers_len, ==, 5);\n \n \t/*\n \t * Given that all tables we have written should be roughly the same\n@@ -918,16 +914,16 @@ static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n \t * only compact the newest two tables.\n \t */\n \terr = reftable_stack_auto_compact(st);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->stats.failures == 0);\n-\tEXPECT(st->merged->readers_len == 4);\n+\tcheck(!err);\n+\tcheck_int(st->stats.failures, ==, 0);\n+\tcheck_int(st->merged->readers_len, ==, 4);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&buf);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_add_performs_auto_compaction(void)\n+static void t_reftable_stack_add_performs_auto_compaction(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -936,7 +932,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \tint err, i, n = 20;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n@@ -957,7 +953,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \t\tref.refname = refname.buf;\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\t/*\n \t\t * The stack length should grow continuously for all runs where\n@@ -965,9 +961,9 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \t\t * all tables in the stack.\n \t\t */\n \t\tif (i != n)\n-\t\t\tEXPECT(st->merged->readers_len == i + 1);\n+\t\t\tcheck_int(st->merged->readers_len, ==, i + 1);\n \t\telse\n-\t\t\tEXPECT(st->merged->readers_len == 1);\n+\t\t\tcheck_int(st->merged->readers_len, ==, 1);\n \t}\n \n \treftable_stack_destroy(st);\n@@ -975,7 +971,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_compaction_with_locked_tables(void)\n+static void t_reftable_stack_compaction_with_locked_tables(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -986,10 +982,10 @@ static void test_reftable_stack_compaction_with_locked_tables(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \twrite_n_ref_tables(st, 3);\n-\tEXPECT(st->merged->readers_len == 3);\n+\tcheck_int(st->merged->readers_len, ==, 3);\n \n \t/* Lock one of the tables that we're about to compact. */\n \tstrbuf_reset(&buf);\n@@ -1001,16 +997,16 @@ static void test_reftable_stack_compaction_with_locked_tables(void)\n \t * compact all tables.\n \t */\n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT(err == REFTABLE_LOCK_ERROR);\n-\tEXPECT(st->stats.failures == 1);\n-\tEXPECT(st->merged->readers_len == 3);\n+\tcheck_int(err, ==, REFTABLE_LOCK_ERROR);\n+\tcheck_int(st->stats.failures, ==, 1);\n+\tcheck_int(st->merged->readers_len, ==, 3);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&buf);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_compaction_concurrent(void)\n+static void t_reftable_stack_compaction_concurrent(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL;\n@@ -1018,19 +1014,19 @@ static void test_reftable_stack_compaction_concurrent(void)\n \tint err;\n \n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st1, 3);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st1, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n \n-\tEXPECT(count_dir_entries(dir) == 2);\n+\tcheck_int(count_dir_entries(dir), ==, 2);\n \tclear_dir(dir);\n }\n \n@@ -1043,7 +1039,7 @@ static void unclean_stack_close(struct reftable_stack *st)\n \tFREE_AND_NULL(st->readers);\n }\n \n-static void test_reftable_stack_compaction_concurrent_clean(void)\n+static void t_reftable_stack_compaction_concurrent_clean(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL, *st3 = NULL;\n@@ -1051,24 +1047,24 @@ static void test_reftable_stack_compaction_concurrent_clean(void)\n \tint err;\n \n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st1, 3);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st1, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tunclean_stack_close(st1);\n \tunclean_stack_close(st2);\n \n \terr = reftable_new_stack(&st3, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_clean(st3);\n-\tEXPECT_ERR(err);\n-\tEXPECT(count_dir_entries(dir) == 2);\n+\tcheck(!err);\n+\tcheck_int(count_dir_entries(dir), ==, 2);\n \n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n@@ -1077,7 +1073,7 @@ static void test_reftable_stack_compaction_concurrent_clean(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_read_across_reload(void)\n+static void t_reftable_stack_read_across_reload(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL;\n@@ -1088,36 +1084,36 @@ static void test_reftable_stack_read_across_reload(void)\n \n \t/* Create a first stack and set up an iterator for it. */\n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st1, 2);\n-\tEXPECT(st1->merged->readers_len == 2);\n+\tcheck_int(st1->merged->readers_len, ==, 2);\n \treftable_stack_init_ref_iterator(st1, &it);\n \terr = reftable_iterator_seek_ref(&it, \"\");\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* Set up a second stack for the same directory and compact it. */\n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st2->merged->readers_len == 2);\n+\tcheck(!err);\n+\tcheck_int(st2->merged->readers_len, ==, 2);\n \terr = reftable_stack_compact_all(st2, NULL);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st2->merged->readers_len == 1);\n+\tcheck(!err);\n+\tcheck_int(st2->merged->readers_len, ==, 1);\n \n \t/*\n \t * Verify that we can continue to use the old iterator even after we\n \t * have reloaded its stack.\n \t */\n \terr = reftable_stack_reload(st1);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st1->merged->readers_len == 1);\n+\tcheck(!err);\n+\tcheck_int(st1->merged->readers_len, ==, 1);\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT_ERR(err);\n-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0000\"));\n+\tcheck(!err);\n+\tcheck_str(rec.refname, \"refs/heads/branch-0000\");\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT_ERR(err);\n-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0001\"));\n+\tcheck(!err);\n+\tcheck_str(rec.refname, \"refs/heads/branch-0001\");\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT(err > 0);\n+\tcheck_int(err, >, 0);\n \n \treftable_ref_record_release(&rec);\n \treftable_iterator_destroy(&it);\n@@ -1126,7 +1122,7 @@ static void test_reftable_stack_read_across_reload(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_reload_with_missing_table(void)\n+static void t_reftable_stack_reload_with_missing_table(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -1138,12 +1134,12 @@ static void test_reftable_stack_reload_with_missing_table(void)\n \n \t/* Create a first stack and set up an iterator for it. */\n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st, 2);\n-\tEXPECT(st->merged->readers_len == 2);\n+\tcheck_int(st->merged->readers_len, ==, 2);\n \treftable_stack_init_ref_iterator(st, &it);\n \terr = reftable_iterator_seek_ref(&it, \"\");\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/*\n \t * Update the tables.list file with some garbage data, while reusing\n@@ -1156,24 +1152,24 @@ static void test_reftable_stack_reload_with_missing_table(void)\n \tstrbuf_addf(&table_path, \"%s.lock\", st->list_file);\n \twrite_file_buf(table_path.buf, content.buf, content.len);\n \terr = rename(table_path.buf, st->list_file);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_reload(st);\n-\tEXPECT(err == -4);\n-\tEXPECT(st->merged->readers_len == 2);\n+\tcheck_int(err, ==, -4);\n+\tcheck_int(st->merged->readers_len, ==, 2);\n \n \t/*\n \t * Even though the reload has failed, we should be able to continue\n \t * using the iterator.\n \t*/\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT_ERR(err);\n-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0000\"));\n+\tcheck(!err);\n+\tcheck_str(rec.refname, \"refs/heads/branch-0000\");\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT_ERR(err);\n-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0001\"));\n+\tcheck(!err);\n+\tcheck_str(rec.refname, \"refs/heads/branch-0001\");\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT(err > 0);\n+\tcheck_int(err, >, 0);\n \n \treftable_ref_record_release(&rec);\n \treftable_iterator_destroy(&it);\n@@ -1183,31 +1179,32 @@ static void test_reftable_stack_reload_with_missing_table(void)\n \tclear_dir(dir);\n }\n \n-int stack_test_main(int argc UNUSED, const char *argv[] UNUSED)\n+int cmd_main(int argc UNUSED, const char *argv[] UNUSED)\n {\n-\tRUN_TEST(test_empty_add);\n-\tRUN_TEST(test_read_file);\n-\tRUN_TEST(test_reflog_expire);\n-\tRUN_TEST(test_reftable_stack_add);\n-\tRUN_TEST(test_reftable_stack_add_one);\n-\tRUN_TEST(test_reftable_stack_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_auto_compaction_with_locked_tables);\n-\tRUN_TEST(test_reftable_stack_add_performs_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_compaction_concurrent);\n-\tRUN_TEST(test_reftable_stack_compaction_concurrent_clean);\n-\tRUN_TEST(test_reftable_stack_compaction_with_locked_tables);\n-\tRUN_TEST(test_reftable_stack_hash_id);\n-\tRUN_TEST(test_reftable_stack_lock_failure);\n-\tRUN_TEST(test_reftable_stack_log_normalize);\n-\tRUN_TEST(test_reftable_stack_tombstone);\n-\tRUN_TEST(test_reftable_stack_transaction_api);\n-\tRUN_TEST(test_reftable_stack_transaction_api_performs_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_auto_compaction_fails_gracefully);\n-\tRUN_TEST(test_reftable_stack_update_index_check);\n-\tRUN_TEST(test_reftable_stack_uptodate);\n-\tRUN_TEST(test_reftable_stack_read_across_reload);\n-\tRUN_TEST(test_reftable_stack_reload_with_missing_table);\n-\tRUN_TEST(test_suggest_compaction_segment);\n-\tRUN_TEST(test_suggest_compaction_segment_nothing);\n-\treturn 0;\n+\tTEST(t_empty_add(), \"empty addition to stack\");\n+\tTEST(t_read_file(), \"read_lines works\");\n+\tTEST(t_reflog_expire(), \"expire reflog entries\");\n+\tTEST(t_reftable_stack_add(), \"add multiple refs and logs to stack\");\n+\tTEST(t_reftable_stack_add_one(), \"add a single ref record to stack\");\n+\tTEST(t_reftable_stack_add_performs_auto_compaction(), \"addition to stack triggers auto-compaction\");\n+\tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_fails_gracefully(), \"failure on auto-compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_with_locked_tables(), \"auto compaction with locked tables\");\n+\tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n+\tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n+\tTEST(t_reftable_stack_compaction_with_locked_tables(), \"compaction with locked tables\");\n+\tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n+\tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n+\tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n+\tTEST(t_reftable_stack_read_across_reload(), \"stack iterators work across reloads\");\n+\tTEST(t_reftable_stack_reload_with_missing_table(), \"stack iteration with garbage tables\");\n+\tTEST(t_reftable_stack_tombstone(), \"'tombstone' refs in stack\");\n+\tTEST(t_reftable_stack_transaction_api(), \"update transaction to stack\");\n+\tTEST(t_reftable_stack_transaction_api_performs_auto_compaction(), \"update transaction triggers auto-compaction\");\n+\tTEST(t_reftable_stack_update_index_check(), \"update transactions with equal update indices\");\n+\tTEST(t_reftable_stack_uptodate(), \"stack must be reloaded before ref update\");\n+\tTEST(t_suggest_compaction_segment(), \"suggest_compaction_segment with basic input\");\n+\tTEST(t_suggest_compaction_segment_nothing(), \"suggest_compaction_segment with pre-compacted input\");\n+\n+\treturn test_done();\n }\n-- \n2.45.GIT\n\n"},{"id":"502323","messageId":"20240906113746.8903-3-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240906113746.8903-1-chandrapratap3519@gmail.com","subject":"[PATCH v5 2/7] t: harmonize t-reftable-stack.c with coding guidelines","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-06T11:29:11Z","receivedAt":"2024-09-06T11:45:05Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"Harmonize the newly ported test unit-tests/t-reftable-stack.c\nwith the following guidelines:\n- Single line 'for' statements must omit curly braces.\n- Structs must be 0-initialized with '= { 0 }' instead of '= { NULL }'.\n- Array sizes and indices should preferably be of type 'size_t' and\n  not 'int'.\n- Function pointers should be passed as 'func' and not '&func'.\n\nWhile at it, remove initialization for those variables that are\nre-used multiple times, like loop variables.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 110 +++++++++++++++-----------------\n 1 file changed, 53 insertions(+), 57 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex de28fac466..c74660a1e2 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -81,7 +81,6 @@ static void t_read_file(void)\n \tint n, err;\n \tchar **names = NULL;\n \tconst char *want[] = { \"line1\", \"line2\", \"line3\" };\n-\tint i = 0;\n \n \tcheck_int(fd, >, 0);\n \tn = write_in_full(fd, out, strlen(out));\n@@ -92,9 +91,8 @@ static void t_read_file(void)\n \terr = read_lines(fn, &names);\n \tcheck(!err);\n \n-\tfor (i = 0; names[i]; i++) {\n+\tfor (size_t i = 0; names[i]; i++)\n \t\tcheck_str(want[i], names[i]);\n-\t}\n \tfree_names(names);\n \t(void) remove(fn);\n }\n@@ -123,7 +121,7 @@ static void write_n_ref_tables(struct reftable_stack *st,\n \t\t};\n \n \t\tstrbuf_reset(&buf);\n-\t\tstrbuf_addf(&buf, \"refs/heads/branch-%04u\", (unsigned) i);\n+\t\tstrbuf_addf(&buf, \"refs/heads/branch-%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = buf.buf;\n \t\tset_test_hash(ref.value.val1, i);\n \n@@ -164,12 +162,12 @@ static void t_reftable_stack_add_one(void)\n \t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t.value.symref = (char *) \"master\",\n \t};\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \tstruct stat stat_result = { 0 };\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\terr = reftable_stack_add(st, write_test_ref, &ref);\n \tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n@@ -234,16 +232,16 @@ static void t_reftable_stack_uptodate(void)\n \terr = reftable_new_stack(&st2, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st1, &write_test_ref, &ref1);\n+\terr = reftable_stack_add(st1, write_test_ref, &ref1);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st2, write_test_ref, &ref2);\n \tcheck_int(err, ==, REFTABLE_OUTDATED_ERROR);\n \n \terr = reftable_stack_reload(st2);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st2, write_test_ref, &ref2);\n \tcheck(!err);\n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n@@ -264,7 +262,7 @@ static void t_reftable_stack_transaction_api(void)\n \t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t.value.symref = (char *) \"master\",\n \t};\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -274,7 +272,7 @@ static void t_reftable_stack_transaction_api(void)\n \terr = reftable_stack_new_addition(&add, st);\n \tcheck(!err);\n \n-\terr = reftable_addition_add(add, &write_test_ref, &ref);\n+\terr = reftable_addition_add(add, write_test_ref, &ref);\n \tcheck(!err);\n \n \terr = reftable_addition_commit(add);\n@@ -298,12 +296,13 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \tstruct reftable_write_options opts = {0};\n \tstruct reftable_addition *add = NULL;\n \tstruct reftable_stack *st = NULL;\n-\tint i, n = 20, err;\n+\tsize_t n = 20;\n+\tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\tfor (i = 0; i <= n; i++) {\n+\tfor (size_t i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t\t.value_type = REFTABLE_REF_SYMREF,\n@@ -311,7 +310,7 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\t};\n \t\tchar name[100];\n \n-\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = name;\n \n \t\t/*\n@@ -324,7 +323,7 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\terr = reftable_stack_new_addition(&add, st);\n \t\tcheck(!err);\n \n-\t\terr = reftable_addition_add(add, &write_test_ref, &ref);\n+\t\terr = reftable_addition_add(add, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\terr = reftable_addition_commit(add);\n@@ -355,7 +354,7 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void)\n \t\t.value_type = REFTABLE_REF_VAL1,\n \t\t.value.val1 = {0x01},\n \t};\n-\tstruct reftable_write_options opts = {0};\n+\tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st;\n \tstruct strbuf table_path = STRBUF_INIT;\n \tchar *dir = get_tmp_dir(__LINE__);\n@@ -417,10 +416,10 @@ static void t_reftable_stack_update_index_check(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref1);\n+\terr = reftable_stack_add(st, write_test_ref, &ref1);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st, write_test_ref, &ref2);\n \tcheck_int(err, ==, REFTABLE_API_ERROR);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n@@ -436,7 +435,7 @@ static void t_reftable_stack_lock_failure(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \tfor (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) {\n-\t\terr = reftable_stack_add(st, &write_error, &i);\n+\t\terr = reftable_stack_add(st, write_error, &i);\n \t\tcheck_int(err, ==, i);\n \t}\n \n@@ -446,7 +445,6 @@ static void t_reftable_stack_lock_failure(void)\n \n static void t_reftable_stack_add(void)\n {\n-\tint i = 0;\n \tint err = 0;\n \tstruct reftable_write_options opts = {\n \t\t.exact_log_message = 1,\n@@ -455,18 +453,18 @@ static void t_reftable_stack_add(void)\n \t};\n \tstruct reftable_stack *st = NULL;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tstruct reftable_ref_record refs[2] = { { NULL } };\n-\tstruct reftable_log_record logs[2] = { { NULL } };\n+\tstruct reftable_ref_record refs[2] = { 0 };\n+\tstruct reftable_log_record logs[2] = { 0 };\n \tstruct strbuf path = STRBUF_INIT;\n \tstruct stat stat_result;\n-\tint N = ARRAY_SIZE(refs);\n+\tsize_t i, N = ARRAY_SIZE(refs);\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar buf[256];\n-\t\tsnprintf(buf, sizeof(buf), \"branch%02d\", i);\n+\t\tsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n \t\trefs[i].refname = xstrdup(buf);\n \t\trefs[i].update_index = i + 1;\n \t\trefs[i].value_type = REFTABLE_REF_VAL1;\n@@ -480,7 +478,7 @@ static void t_reftable_stack_add(void)\n \t}\n \n \tfor (i = 0; i < N; i++) {\n-\t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n+\t\tint err = reftable_stack_add(st, write_test_ref, &refs[i]);\n \t\tcheck(!err);\n \t}\n \n@@ -489,7 +487,7 @@ static void t_reftable_stack_add(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -497,7 +495,7 @@ static void t_reftable_stack_add(void)\n \tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n-\t\tstruct reftable_ref_record dest = { NULL };\n+\t\tstruct reftable_ref_record dest = { 0 };\n \n \t\tint err = reftable_stack_read_ref(st, refs[i].refname, &dest);\n \t\tcheck(!err);\n@@ -507,7 +505,7 @@ static void t_reftable_stack_add(void)\n \t}\n \n \tfor (i = 0; i < N; i++) {\n-\t\tstruct reftable_log_record dest = { NULL };\n+\t\tstruct reftable_log_record dest = { 0 };\n \t\tint err = reftable_stack_read_log(st, refs[i].refname, &dest);\n \t\tcheck(!err);\n \t\tcheck(reftable_log_record_equal(&dest, logs + i,\n@@ -575,11 +573,11 @@ static void t_reftable_stack_log_normalize(void)\n \tcheck(!err);\n \n \tinput.value.update.message = (char *) \"one\\ntwo\";\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck_int(err, ==, REFTABLE_API_ERROR);\n \n \tinput.value.update.message = (char *) \"one\";\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck(!err);\n \n \terr = reftable_stack_read_log(st, input.refname, &dest);\n@@ -588,7 +586,7 @@ static void t_reftable_stack_log_normalize(void)\n \n \tinput.value.update.message = (char *) \"two\\n\";\n \targ.update_index = 2;\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck(!err);\n \terr = reftable_stack_read_log(st, input.refname, &dest);\n \tcheck(!err);\n@@ -602,16 +600,15 @@ static void t_reftable_stack_log_normalize(void)\n \n static void t_reftable_stack_tombstone(void)\n {\n-\tint i = 0;\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n \tint err;\n-\tstruct reftable_ref_record refs[2] = { { NULL } };\n-\tstruct reftable_log_record logs[2] = { { NULL } };\n-\tint N = ARRAY_SIZE(refs);\n-\tstruct reftable_ref_record dest = { NULL };\n-\tstruct reftable_log_record log_dest = { NULL };\n+\tstruct reftable_ref_record refs[2] = { 0 };\n+\tstruct reftable_log_record logs[2] = { 0 };\n+\tsize_t i, N = ARRAY_SIZE(refs);\n+\tstruct reftable_ref_record dest = { 0 };\n+\tstruct reftable_log_record log_dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -637,7 +634,7 @@ static void t_reftable_stack_tombstone(void)\n \t\t}\n \t}\n \tfor (i = 0; i < N; i++) {\n-\t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n+\t\tint err = reftable_stack_add(st, write_test_ref, &refs[i]);\n \t\tcheck(!err);\n \t}\n \n@@ -646,7 +643,7 @@ static void t_reftable_stack_tombstone(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -695,12 +692,12 @@ static void t_reftable_stack_hash_id(void)\n \tstruct reftable_stack *st32 = NULL;\n \tstruct reftable_write_options opts_default = { 0 };\n \tstruct reftable_stack *st_default = NULL;\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\terr = reftable_stack_add(st, write_test_ref, &ref);\n \tcheck(!err);\n \n \t/* can't read it with the wrong hash ID. */\n@@ -743,21 +740,20 @@ static void t_reflog_expire(void)\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n-\tstruct reftable_log_record logs[20] = { { NULL } };\n-\tint N = ARRAY_SIZE(logs) - 1;\n-\tint i = 0;\n+\tstruct reftable_log_record logs[20] = { 0 };\n+\tsize_t i, N = ARRAY_SIZE(logs) - 1;\n \tint err;\n \tstruct reftable_log_expiry_config expiry = {\n \t\t.time = 10,\n \t};\n-\tstruct reftable_log_record log = { NULL };\n+\tstruct reftable_log_record log = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n \tfor (i = 1; i <= N; i++) {\n \t\tchar buf[256];\n-\t\tsnprintf(buf, sizeof(buf), \"branch%02d\", i);\n+\t\tsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n \n \t\tlogs[i].refname = xstrdup(buf);\n \t\tlogs[i].update_index = i;\n@@ -772,7 +768,7 @@ static void t_reflog_expire(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -800,9 +796,8 @@ static void t_reflog_expire(void)\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n-\tfor (i = 0; i <= N; i++) {\n+\tfor (i = 0; i <= N; i++)\n \t\treftable_log_record_release(&logs[i]);\n-\t}\n \tclear_dir(dir);\n \treftable_log_record_release(&log);\n }\n@@ -824,7 +819,7 @@ static void t_empty_add(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_nothing, NULL);\n+\terr = reftable_stack_add(st, write_nothing, NULL);\n \tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n@@ -851,8 +846,8 @@ static void t_reftable_stack_auto_compaction(void)\n \t};\n \tstruct reftable_stack *st = NULL;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tint err, i;\n-\tint N = 100;\n+\tint err;\n+\tsize_t i, N = 100;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -865,9 +860,9 @@ static void t_reftable_stack_auto_compaction(void)\n \t\t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t\t.value.symref = (char *) \"master\",\n \t\t};\n-\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n \n-\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\terr = reftable_stack_add(st, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\terr = reftable_stack_auto_compact(st);\n@@ -929,7 +924,8 @@ static void t_reftable_stack_add_performs_auto_compaction(void)\n \tstruct reftable_stack *st = NULL;\n \tstruct strbuf refname = STRBUF_INIT;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tint err, i, n = 20;\n+\tint err;\n+\tsize_t i, n = 20;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -949,10 +945,10 @@ static void t_reftable_stack_add_performs_auto_compaction(void)\n \t\tst->opts.disable_auto_compact = i != n;\n \n \t\tstrbuf_reset(&refname);\n-\t\tstrbuf_addf(&refname, \"branch-%04d\", i);\n+\t\tstrbuf_addf(&refname, \"branch-%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = refname.buf;\n \n-\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\terr = reftable_stack_add(st, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\t/*\n-- \n2.45.GIT\n\n"},{"id":"502324","messageId":"20240906113746.8903-4-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240906113746.8903-1-chandrapratap3519@gmail.com","subject":"[PATCH v5 3/7] t-reftable-stack: use Git's tempfile API instead of mkstemp()","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-06T11:29:12Z","receivedAt":"2024-09-06T11:45:08Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"Git's tempfile API defined by $GIT_DIR/tempfile.{c,h} provides\na unified interface for tempfile operations. Since reftable/stack.c\nuses this API for all its tempfile needs instead of raw functions\nlike mkstemp(), make the ported stack test strictly use Git's\ntempfile API as well.\n\nA bigger benefit is the fact that we know to clean up the tempfile\nin case the test fails because it gets registered and pruned via a\nsignal handler.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex c74660a1e2..8047e25c48 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -76,7 +76,8 @@ static char *get_tmp_dir(int linenumber)\n static void t_read_file(void)\n {\n \tchar *fn = get_tmp_template(__LINE__);\n-\tint fd = mkstemp(fn);\n+\tstruct tempfile *tmp = mks_tempfile(fn);\n+\tint fd = get_tempfile_fd(tmp);\n \tchar out[1024] = \"line1\\n\\nline2\\nline3\";\n \tint n, err;\n \tchar **names = NULL;\n@@ -95,6 +96,7 @@ static void t_read_file(void)\n \t\tcheck_str(want[i], names[i]);\n \tfree_names(names);\n \t(void) remove(fn);\n+\tdelete_tempfile(&tmp);\n }\n \n static int write_test_ref(struct reftable_writer *wr, void *arg)\n-- \n2.45.GIT\n\n"},{"id":"502325","messageId":"20240906113746.8903-5-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240906113746.8903-1-chandrapratap3519@gmail.com","subject":"[PATCH v5 4/7] t-reftable-stack: use reftable_ref_record_equal() to compare ref records","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-06T11:29:13Z","receivedAt":"2024-09-06T11:45:11Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"In the current stack tests, ref records are compared for equality\nby sometimes using the dedicated function for ref-record comparison,\nreftable_ref_record_equal(), and sometimes by explicity comparing\ncontents of the ref records.\n\nThe latter method is undesired because there can exist unequal ref\nrecords with the some of the contents being equal. Replace the latter\ninstances of ref-record comparison with the former. This has the\nadded benefit of preserving uniformity throughout the test file.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 8047e25c48..4f2ef1a8cc 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -174,7 +174,7 @@ static void t_reftable_stack_add_one(void)\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n \tcheck(!err);\n-\tcheck_str(\"master\", dest.value.symref);\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \tcheck_int(st->readers_len, >, 0);\n \n #ifndef GIT_WINDOWS_NATIVE\n@@ -285,7 +285,7 @@ static void t_reftable_stack_transaction_api(void)\n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n \tcheck(!err);\n \tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n-\tcheck_str(\"master\", dest.value.symref);\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n-- \n2.45.GIT\n\n"},{"id":"502326","messageId":"20240906113746.8903-6-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240906113746.8903-1-chandrapratap3519@gmail.com","subject":"[PATCH v5 5/7] t-reftable-stack: add test for non-default compaction factor","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-06T11:29:14Z","receivedAt":"2024-09-06T11:45:13Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"In a recent codebase update (commit ae8e378430, merge branch\n'ps/reftable-write-options', 2024/05/13) the geometric factor used\nin auto-compaction of reftable tables was made configurable. Add\na test to verify the functionality introduced by this update.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 41 +++++++++++++++++++++++++++++----\n 1 file changed, 37 insertions(+), 4 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 4f2ef1a8cc..4acf07ab0c 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -831,12 +831,12 @@ static void t_empty_add(void)\n \treftable_stack_destroy(st2);\n }\n \n-static int fastlog2(uint64_t sz)\n+static int fastlogN(uint64_t sz, uint64_t N)\n {\n \tint l = 0;\n \tif (sz == 0)\n \t\treturn 0;\n-\tfor (; sz; sz /= 2)\n+\tfor (; sz; sz /= N)\n \t\tl++;\n \treturn l - 1;\n }\n@@ -869,11 +869,43 @@ static void t_reftable_stack_auto_compaction(void)\n \n \t\terr = reftable_stack_auto_compact(st);\n \t\tcheck(!err);\n-\t\tcheck(i < 3 || st->merged->readers_len < 2 * fastlog2(i));\n+\t\tcheck(i < 2 || st->merged->readers_len < 2 * fastlogN(i, 2));\n \t}\n \n \tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n-\t       (uint64_t)(N * fastlog2(N)));\n+\t       (uint64_t)(N * fastlogN(N, 2)));\n+\n+\treftable_stack_destroy(st);\n+\tclear_dir(dir);\n+}\n+\n+static void t_reftable_stack_auto_compaction_factor(void)\n+{\n+\tstruct reftable_write_options opts = {\n+\t\t.auto_compaction_factor = 5,\n+\t};\n+\tstruct reftable_stack *st = NULL;\n+\tchar *dir = get_tmp_dir(__LINE__);\n+\tint err;\n+\tsize_t N = 100;\n+\n+\terr = reftable_new_stack(&st, dir, &opts);\n+\tcheck(!err);\n+\n+\tfor (size_t i = 0; i < N; i++) {\n+\t\tchar name[20];\n+\t\tstruct reftable_ref_record ref = {\n+\t\t\t.refname = name,\n+\t\t\t.update_index = reftable_stack_next_update_index(st),\n+\t\t\t.value_type = REFTABLE_REF_VAL1,\n+\t\t};\n+\t\txsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n+\n+\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\tcheck(!err);\n+\n+\t\tcheck(i < 5 || st->merged->readers_len < 5 * fastlogN(i, 5));\n+\t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n@@ -1186,6 +1218,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)\n \tTEST(t_reftable_stack_add_one(), \"add a single ref record to stack\");\n \tTEST(t_reftable_stack_add_performs_auto_compaction(), \"addition to stack triggers auto-compaction\");\n \tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_factor(), \"auto-compaction with non-default geometric factor\");\n \tTEST(t_reftable_stack_auto_compaction_fails_gracefully(), \"failure on auto-compaction\");\n \tTEST(t_reftable_stack_auto_compaction_with_locked_tables(), \"auto compaction with locked tables\");\n \tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n-- \n2.45.GIT\n\n"},{"id":"502327","messageId":"20240906113746.8903-7-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240906113746.8903-1-chandrapratap3519@gmail.com","subject":"[PATCH v5 6/7] t-reftable-stack: add test for stack iterators","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-06T11:29:15Z","receivedAt":"2024-09-06T11:45:16Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"reftable_stack_init_ref_iterator and reftable_stack_init_log_iterator\nas defined by reftable/stack.{c,h} initialize a stack iterator to\niterate over the ref and log records in a reftable stack respectively.\nSince these functions are not exercised by any of the existing tests,\nadd a test for them.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 83 +++++++++++++++++++++++++++++++++\n 1 file changed, 83 insertions(+)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 4acf07ab0c..d62a9c1bed 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -544,6 +544,88 @@ static void t_reftable_stack_add(void)\n \tclear_dir(dir);\n }\n \n+static void t_reftable_stack_iterator(void)\n+{\n+\tstruct reftable_write_options opts = { 0 };\n+\tstruct reftable_stack *st = NULL;\n+\tchar *dir = get_tmp_dir(__LINE__);\n+\tstruct reftable_ref_record refs[10] = { 0 };\n+\tstruct reftable_log_record logs[10] = { 0 };\n+\tstruct reftable_iterator it = { 0 };\n+\tsize_t N = ARRAY_SIZE(refs), i;\n+\tint err;\n+\n+\terr = reftable_new_stack(&st, dir, &opts);\n+\tcheck(!err);\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\trefs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n+\t\trefs[i].update_index = i + 1;\n+\t\trefs[i].value_type = REFTABLE_REF_VAL1;\n+\t\tset_test_hash(refs[i].value.val1, i);\n+\n+\t\tlogs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n+\t\tlogs[i].update_index = i + 1;\n+\t\tlogs[i].value_type = REFTABLE_LOG_UPDATE;\n+\t\tlogs[i].value.update.email = xstrdup(\"johndoe@invalid\");\n+\t\tlogs[i].value.update.message = xstrdup(\"commit\\n\");\n+\t\tset_test_hash(logs[i].value.update.new_hash, i);\n+\t}\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\terr = reftable_stack_add(st, write_test_ref, &refs[i]);\n+\t\tcheck(!err);\n+\t}\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\tstruct write_log_arg arg = {\n+\t\t\t.log = &logs[i],\n+\t\t\t.update_index = reftable_stack_next_update_index(st),\n+\t\t};\n+\n+\t\terr = reftable_stack_add(st, write_test_log, &arg);\n+\t\tcheck(!err);\n+\t}\n+\n+\treftable_stack_init_ref_iterator(st, &it);\n+\treftable_iterator_seek_ref(&it, refs[0].refname);\n+\tfor (i = 0; ; i++) {\n+\t\tstruct reftable_ref_record ref = { 0 };\n+\n+\t\terr = reftable_iterator_next_ref(&it, &ref);\n+\t\tif (err > 0)\n+\t\t\tbreak;\n+\t\tcheck(!err);\n+\t\tcheck(reftable_ref_record_equal(&ref, &refs[i], GIT_SHA1_RAWSZ));\n+\t\treftable_ref_record_release(&ref);\n+\t}\n+\tcheck_int(i, ==, N);\n+\n+\treftable_iterator_destroy(&it);\n+\n+\treftable_stack_init_log_iterator(st, &it);\n+\treftable_iterator_seek_log(&it, logs[0].refname);\n+\tfor (i = 0; ; i++) {\n+\t\tstruct reftable_log_record log = { 0 };\n+\n+\t\terr = reftable_iterator_next_log(&it, &log);\n+\t\tif (err > 0)\n+\t\t\tbreak;\n+\t\tcheck(!err);\n+\t\tcheck(reftable_log_record_equal(&log, &logs[i], GIT_SHA1_RAWSZ));\n+\t\treftable_log_record_release(&log);\n+\t}\n+\tcheck_int(i, ==, N);\n+\n+\treftable_stack_destroy(st);\n+\treftable_iterator_destroy(&it);\n+\tfor (i = 0; i < N; i++) {\n+\t\treftable_ref_record_release(&refs[i]);\n+\t\treftable_log_record_release(&logs[i]);\n+\t}\n+\tclear_dir(dir);\n+}\n+\n static void t_reftable_stack_log_normalize(void)\n {\n \tint err = 0;\n@@ -1225,6 +1307,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)\n \tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n \tTEST(t_reftable_stack_compaction_with_locked_tables(), \"compaction with locked tables\");\n \tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n+\tTEST(t_reftable_stack_iterator(), \"log and ref iterator for reftable stack\");\n \tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n \tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n \tTEST(t_reftable_stack_read_across_reload(), \"stack iterators work across reloads\");\n-- \n2.45.GIT\n\n"},{"id":"502328","messageId":"20240906113746.8903-8-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240906113746.8903-1-chandrapratap3519@gmail.com","subject":"[PATCH v5 7/7] t: clean up leftover reftable test cruft","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-06T11:29:16Z","receivedAt":"2024-09-06T11:45:19Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"From: Junio C Hamano <gitster@pobox.com>\n\nWith the migration of reftable tests to the unit-tests framework,\n\"test-tool reftable\" becomes a no-op.\n\nGet rid of everything that uses \"test-tool reftable\" alongside\neverything that is used to implement it.\n\nWhile at it, alphabetically sort the cmds[] list in\nhelper/test-tool.c by moving the entry for \"dump-reftable\".\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n Makefile                     |  2 --\n reftable/reftable-tests.h    | 13 --------\n reftable/test_framework.c    | 27 ----------------\n reftable/test_framework.h    | 61 ------------------------------------\n t/helper/test-reftable.c     |  7 -----\n t/helper/test-tool.c         |  3 +-\n t/helper/test-tool.h         |  1 -\n t/t0032-reftable-unittest.sh | 16 ----------\n 8 files changed, 1 insertion(+), 129 deletions(-)\n delete mode 100644 reftable/reftable-tests.h\n delete mode 100644 reftable/test_framework.c\n delete mode 100644 reftable/test_framework.h\n delete mode 100755 t/t0032-reftable-unittest.sh\n\ndiff --git a/Makefile b/Makefile\nindex 1cbc2d61ae..64ccb1433f 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2692,8 +2692,6 @@ REFTABLE_OBJS += reftable/stack.o\n REFTABLE_OBJS += reftable/tree.o\n REFTABLE_OBJS += reftable/writer.o\n \n-REFTABLE_TEST_OBJS += reftable/test_framework.o\n-\n TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))\n \n .PHONY: test-objs\ndiff --git a/reftable/reftable-tests.h b/reftable/reftable-tests.h\ndeleted file mode 100644\nindex 05f8d2d5bc..0000000000\n--- a/reftable/reftable-tests.h\n+++ /dev/null\n@@ -1,13 +0,0 @@\n-/*\n-Copyright 2020 Google LLC\n-\n-Use of this source code is governed by a BSD-style\n-license that can be found in the LICENSE file or at\n-https://developers.google.com/open-source/licenses/bsd\n-*/\n-\n-#ifndef REFTABLE_TESTS_H\n-#define REFTABLE_TESTS_H\n-\n-\n-#endif\ndiff --git a/reftable/test_framework.c b/reftable/test_framework.c\ndeleted file mode 100644\nindex a07fec5d84..0000000000\n--- a/reftable/test_framework.c\n+++ /dev/null\n@@ -1,27 +0,0 @@\n-/*\n-Copyright 2020 Google LLC\n-\n-Use of this source code is governed by a BSD-style\n-license that can be found in the LICENSE file or at\n-https://developers.google.com/open-source/licenses/bsd\n-*/\n-\n-#include \"system.h\"\n-#include \"test_framework.h\"\n-\n-\n-void set_test_hash(uint8_t *p, int i)\n-{\n-\tmemset(p, (uint8_t)i, hash_size(GIT_SHA1_FORMAT_ID));\n-}\n-\n-ssize_t strbuf_add_void(void *b, const void *data, size_t sz)\n-{\n-\tstrbuf_add(b, data, sz);\n-\treturn sz;\n-}\n-\n-int noop_flush(void *arg UNUSED)\n-{\n-\treturn 0;\n-}\ndiff --git a/reftable/test_framework.h b/reftable/test_framework.h\ndeleted file mode 100644\nindex 687390f9c2..0000000000\n--- a/reftable/test_framework.h\n+++ /dev/null\n@@ -1,61 +0,0 @@\n-/*\n-Copyright 2020 Google LLC\n-\n-Use of this source code is governed by a BSD-style\n-license that can be found in the LICENSE file or at\n-https://developers.google.com/open-source/licenses/bsd\n-*/\n-\n-#ifndef TEST_FRAMEWORK_H\n-#define TEST_FRAMEWORK_H\n-\n-#include \"system.h\"\n-#include \"reftable-error.h\"\n-\n-#define EXPECT_ERR(c)                                                          \\\n-\tdo {                                                                   \\\n-\t\tif (c != 0) {                                                  \\\n-\t\t\tfflush(stderr);                                        \\\n-\t\t\tfflush(stdout);                                        \\\n-\t\t\tfprintf(stderr, \"%s: %d: error == %d (%s), want 0\\n\",  \\\n-\t\t\t\t__FILE__, __LINE__, c, reftable_error_str(c)); \\\n-\t\t\tabort();                                               \\\n-\t\t}                                                              \\\n-\t} while (0)\n-\n-#define EXPECT_STREQ(a, b)                                                       \\\n-\tdo {                                                                     \\\n-\t\tif (strcmp(a, b)) {                                              \\\n-\t\t\tfflush(stderr);                                          \\\n-\t\t\tfflush(stdout);                                          \\\n-\t\t\tfprintf(stderr, \"%s:%d: %s (%s) != %s (%s)\\n\", __FILE__, \\\n-\t\t\t\t__LINE__, #a, a, #b, b);                         \\\n-\t\t\tabort();                                                 \\\n-\t\t}                                                                \\\n-\t} while (0)\n-\n-#define EXPECT(c)                                                                  \\\n-\tdo {                                                                       \\\n-\t\tif (!(c)) {                                                        \\\n-\t\t\tfflush(stderr);                                            \\\n-\t\t\tfflush(stdout);                                            \\\n-\t\t\tfprintf(stderr, \"%s: %d: failed assertion %s\\n\", __FILE__, \\\n-\t\t\t\t__LINE__, #c);                                     \\\n-\t\t\tabort();                                                   \\\n-\t\t}                                                                  \\\n-\t} while (0)\n-\n-#define RUN_TEST(f)                          \\\n-\tfprintf(stderr, \"running %s\\n\", #f); \\\n-\tfflush(stderr);                      \\\n-\tf();\n-\n-void set_test_hash(uint8_t *p, int i);\n-\n-/* Like strbuf_add, but suitable for passing to reftable_new_writer\n- */\n-ssize_t strbuf_add_void(void *b, const void *data, size_t sz);\n-\n-int noop_flush(void *);\n-\n-#endif\ndiff --git a/t/helper/test-reftable.c b/t/helper/test-reftable.c\nindex d27d7ee798..29d4e9a755 100644\n--- a/t/helper/test-reftable.c\n+++ b/t/helper/test-reftable.c\n@@ -6,15 +6,8 @@\n #include \"reftable/reftable-merged.h\"\n #include \"reftable/reftable-reader.h\"\n #include \"reftable/reftable-stack.h\"\n-#include \"reftable/reftable-tests.h\"\n #include \"test-tool.h\"\n \n-int cmd__reftable(int argc, const char **argv)\n-{\n-\t/* test from simple to complex. */\n-\treturn 0;\n-}\n-\n static void print_help(void)\n {\n \tprintf(\"usage: dump [-st] arg\\n\\n\"\ndiff --git a/t/helper/test-tool.c b/t/helper/test-tool.c\nindex f8a67df7de..252fa5de63 100644\n--- a/t/helper/test-tool.c\n+++ b/t/helper/test-tool.c\n@@ -26,6 +26,7 @@ static struct test_cmd cmds[] = {\n \t{ \"drop-caches\", cmd__drop_caches },\n \t{ \"dump-cache-tree\", cmd__dump_cache_tree },\n \t{ \"dump-fsmonitor\", cmd__dump_fsmonitor },\n+\t{ \"dump-reftable\", cmd__dump_reftable },\n \t{ \"dump-split-index\", cmd__dump_split_index },\n \t{ \"dump-untracked-cache\", cmd__dump_untracked_cache },\n \t{ \"env-helper\", cmd__env_helper },\n@@ -61,9 +62,7 @@ static struct test_cmd cmds[] = {\n \t{ \"read-graph\", cmd__read_graph },\n \t{ \"read-midx\", cmd__read_midx },\n \t{ \"ref-store\", cmd__ref_store },\n-\t{ \"reftable\", cmd__reftable },\n \t{ \"rot13-filter\", cmd__rot13_filter },\n-\t{ \"dump-reftable\", cmd__dump_reftable },\n \t{ \"regex\", cmd__regex },\n \t{ \"repository\", cmd__repository },\n \t{ \"revision-walking\", cmd__revision_walking },\ndiff --git a/t/helper/test-tool.h b/t/helper/test-tool.h\nindex e74bc0ffd4..84291318cb 100644\n--- a/t/helper/test-tool.h\n+++ b/t/helper/test-tool.h\n@@ -55,7 +55,6 @@ int cmd__read_graph(int argc, const char **argv);\n int cmd__read_midx(int argc, const char **argv);\n int cmd__ref_store(int argc, const char **argv);\n int cmd__rot13_filter(int argc, const char **argv);\n-int cmd__reftable(int argc, const char **argv);\n int cmd__regex(int argc, const char **argv);\n int cmd__repository(int argc, const char **argv);\n int cmd__revision_walking(int argc, const char **argv);\ndiff --git a/t/t0032-reftable-unittest.sh b/t/t0032-reftable-unittest.sh\ndeleted file mode 100755\nindex 471cb37ac2..0000000000\n--- a/t/t0032-reftable-unittest.sh\n+++ /dev/null\n@@ -1,16 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright (c) 2020 Google LLC\n-#\n-\n-test_description='reftable unittests'\n-\n-TEST_PASSES_SANITIZE_LEAK=true\n-. ./test-lib.sh\n-\n-test_expect_success 'unittests' '\n-\tTMPDIR=$(pwd) && export TMPDIR &&\n-\ttest-tool reftable\n-'\n-\n-test_done\n-- \n2.45.GIT\n\n"},{"id":"502340","messageId":"xmqqo750wxee.fsf@gitster.g","threadId":"61911","inReplyTo":"20240906113746.8903-1-chandrapratap3519@gmail.com","subject":"Re: [GSoC][PATCH v5 0/7] t: port reftable/stack_test.c to the unit testing framework","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-09-06T16:38:01Z","receivedAt":"2024-09-06T16:38:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Chandra Pratap <chandrapratap3519@gmail.com> writes:\n\n> Changes in v5:\n> - Edit the commit messages in patches 3 and 4 to reflect the changes\n>   and the motivation behind those changes better.\n> - Add newlines after variable declarations in patch 6.\n> - Introduce patch 7 which removes leftover cruft from the previous\n>   reftable testing scheme.\n\nHmph, the end-result looks good to me, but the structure of the\nseries is a bit curious.  I didn't expect there will be a separate\nstep for removal.  Shouldn't these \"leftover cruft\" be removed *in*\nthe same step that they become cruft (which I am assuming is when\nreftable/stack_test.c and all references to it gets removed in an\nearly part of the series)?\n\nOther than that, looking good.\n\nThanks.\n"},{"id":"502383","messageId":"xmqq4j6suyha.fsf@gitster.g","threadId":"61911","inReplyTo":"xmqqo750wxee.fsf@gitster.g","subject":"Re: [GSoC][PATCH v5 0/7] t: port reftable/stack_test.c to the unit testing framework","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-09-06T23:57:37Z","receivedAt":"2024-09-06T23:57:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Chandra Pratap <chandrapratap3519@gmail.com> writes:\n>\n>> Changes in v5:\n>> - Edit the commit messages in patches 3 and 4 to reflect the changes\n>>   and the motivation behind those changes better.\n>> - Add newlines after variable declarations in patch 6.\n>> - Introduce patch 7 which removes leftover cruft from the previous\n>>   reftable testing scheme.\n>\n> Hmph, the end-result looks good to me, but the structure of the\n> series is a bit curious.  I didn't expect there will be a separate\n> step for removal.  Shouldn't these \"leftover cruft\" be removed *in*\n> the same step that they become cruft (which I am assuming is when\n> reftable/stack_test.c and all references to it gets removed in an\n> early part of the series)?\n>\n> Other than that, looking good.\n>\n> Thanks.\n\nThere is another issue.\n\nIt is unique to this among the reftable/*_test topics, simply\nbecause this one happens to be the last and needs to clean up a bit\nmore.\n\nApparently, GNU \"ar\" can be invoked without any .o object files and\nhappily creates an empty archive, but on BSD may not be that may be\nthe case.  macOS CI jobs seem to be hard failing due to this.\n\nYou'd need to squeeze in the following, in addition to [7/7], to\nearlier patch(es).\n\nThanks.\n\n Makefile | 8 ++------\n 1 file changed, 2 insertions(+), 6 deletions(-)\n\ndiff --git c/Makefile w/Makefile\nindex 64ccb1433f..bdea061971 100644\n--- c/Makefile\n+++ w/Makefile\n@@ -912,7 +912,6 @@ TEST_SHELL_PATH = $(SHELL_PATH)\n LIB_FILE = libgit.a\n XDIFF_LIB = xdiff/lib.a\n REFTABLE_LIB = reftable/libreftable.a\n-REFTABLE_TEST_LIB = reftable/libreftable_test.a\n \n GENERATED_H += command-list.h\n GENERATED_H += config-list.h\n@@ -2866,9 +2865,6 @@ $(XDIFF_LIB): $(XDIFF_OBJS)\n $(REFTABLE_LIB): $(REFTABLE_OBJS)\n \t$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^\n \n-$(REFTABLE_TEST_LIB): $(REFTABLE_TEST_OBJS)\n-\t$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^\n-\n export DEFAULT_EDITOR DEFAULT_PAGER\n \n Documentation/GIT-EXCLUDED-PROGRAMS: FORCE\n@@ -3248,7 +3244,7 @@ perf: all\n \n t/helper/test-tool$X: $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS)) $(UNIT_TEST_DIR)/test-lib.o\n \n-t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) $(REFTABLE_TEST_LIB)\n+t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS)\n \t$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS)\n \n check-sha1:: t/helper/test-tool$X\n@@ -3709,7 +3705,7 @@ clean: profile-clean coverage-clean cocciclean\n \t$(RM) git.res\n \t$(RM) $(OBJECTS)\n \t$(RM) headless-git.o\n-\t$(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(REFTABLE_TEST_LIB)\n+\t$(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB)\n \t$(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS)\n \t$(RM) $(TEST_PROGRAMS)\n \t$(RM) $(FUZZ_PROGRAMS)\n"},{"id":"502398","messageId":"20240908041632.4948-1-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240906113746.8903-1-chandrapratap3519@gmail.com","subject":"[GSoC][PATCH v6 0/6] t: port reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-08T04:05:55Z","receivedAt":"2024-09-08T04:18:06Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"The reftable library comes with self tests, which are exercised\nas part of the usual end-to-end tests and are designed to\nobserve the end-user visible effects of Git commands. What it\nexercises, however, is a better match for the unit-testing\nframework, merged at 8bf6fbd0 (Merge branch 'js/doc-unit-tests',\n2023-12-09), which is designed to observe how low level\nimplementation details, at the level of sequences of individual\nfunction calls, behave.\n\nHence, port reftable/stack_test.c to the unit testing framework and\nimprove upon the ported test. The first patch in the series moves\nthe test to the unit testing framework, and the rest of the patches\nimprove upon the ported test.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n\n---\nChanges in v6:\n- Fix the Makefile changes in patch 7 of the previous series that\n  broke the OSX CI.\n- Squash patch 7 of the previous series into patch 1.\n\nCI/PR: https://github.com/gitgitgadget/git/pull/1762\n\nChandra Pratap(6):\nt: move reftable/stack_test.c to the unit testing framework\nt: harmonize t-reftable-stack.c with coding guidelines\nt-reftable-stack: use Git's tempfile API instead of mkstemp()\nt-reftable-stack: use reftable_ref_record_equal() to compare ref records\nt-reftable-stack: add test for non-default compaction factor\nt-reftable-stack: add test for stack iterators\n\nMakefile                                           |  12 +-\nreftable/reftable-tests.h                          |  14 -\nreftable/test_framework.c                          |  27 -\nreftable/test_framework.h                          |  61 --\nt/helper/test-reftable.c                           |   8 -\nt/helper/test-tool.c                               |   3 +-\nt/helper/test-tool.h                               |   1 -\nt/t0032-reftable-unittest.sh                       |  16 -\n.../unit-tests/t-reftable-stack.c                  | 665 ++++++++++++---------\n9 files changed, 392 insertions(+), 415 deletions(-)\n\nRange-diff against v5:\n1:  e9af30d14a ! 1:  fa549a875a t: move reftable/stack_test.c to the unit testing framework\n    @@ Commit message\n         '#included' in the test file, copy this function in the\n         ported test file.\n\n    +    With the migration of stack test to the unit-tests framework,\n    +    \"test-tool reftable\" becomes a no-op. Hence, get rid of everything\n    +    that uses \"test-tool reftable\" alongside everything that is used\n    +    to implement it.\n    +\n    +    While at it, alphabetically sort the cmds[] list in\n    +    helper/test-tool.c by moving the entry for \"dump-reftable\".\n    +\n         Mentored-by: Patrick Steinhardt <ps@pks.im>\n         Mentored-by: Christian Couder <chriscool@tuxfamily.org>\n         Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n\n      ## Makefile ##\n    +@@ Makefile: TEST_SHELL_PATH = $(SHELL_PATH)\n    + LIB_FILE = libgit.a\n    + XDIFF_LIB = xdiff/lib.a\n    + REFTABLE_LIB = reftable/libreftable.a\n    +-REFTABLE_TEST_LIB = reftable/libreftable_test.a\n    +\n    + GENERATED_H += command-list.h\n    + GENERATED_H += config-list.h\n     @@ Makefile: UNIT_TEST_PROGRAMS += t-reftable-merged\n      UNIT_TEST_PROGRAMS += t-reftable-pq\n      UNIT_TEST_PROGRAMS += t-reftable-readwrite\n    @@ Makefile: REFTABLE_OBJS += reftable/stack.o\n      REFTABLE_OBJS += reftable/writer.o\n\n     -REFTABLE_TEST_OBJS += reftable/stack_test.o\n    - REFTABLE_TEST_OBJS += reftable/test_framework.o\n    -\n    +-REFTABLE_TEST_OBJS += reftable/test_framework.o\n    +-\n      TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))\n    -\n    - ## reftable/reftable-tests.h ##\n    -@@ reftable/reftable-tests.h: license that can be found in the LICENSE file or at\n    - #ifndef REFTABLE_TESTS_H\n    - #define REFTABLE_TESTS_H\n\n    --int stack_test_main(int argc, const char **argv);\n    + .PHONY: test-objs\n    +@@ Makefile: $(XDIFF_LIB): $(XDIFF_OBJS)\n    + $(REFTABLE_LIB): $(REFTABLE_OBJS)\n    + \t$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^\n\n    - #endif\n    +-$(REFTABLE_TEST_LIB): $(REFTABLE_TEST_OBJS)\n    +-\t$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^\n    +-\n    + export DEFAULT_EDITOR DEFAULT_PAGER\n    +\n    + Documentation/GIT-EXCLUDED-PROGRAMS: FORCE\n    +@@ Makefile: perf: all\n    +\n    + t/helper/test-tool$X: $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS)) $(UNIT_TEST_DIR)/test-lib.o\n    +\n    +-t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) $(REFTABLE_TEST_LIB)\n    ++t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS)\n    + \t$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS)\n    +\n    + check-sha1:: t/helper/test-tool$X\n    +@@ Makefile: clean: profile-clean coverage-clean cocciclean\n    + \t$(RM) git.res\n    + \t$(RM) $(OBJECTS)\n    + \t$(RM) headless-git.o\n    +-\t$(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(REFTABLE_TEST_LIB)\n    ++\t$(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB)\n    + \t$(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS)\n    + \t$(RM) $(TEST_PROGRAMS)\n    + \t$(RM) $(FUZZ_PROGRAMS)\n    +\n    + ## reftable/reftable-tests.h (deleted) ##\n    +@@\n    +-/*\n    +-Copyright 2020 Google LLC\n    +-\n    +-Use of this source code is governed by a BSD-style\n    +-license that can be found in the LICENSE file or at\n    +-https://developers.google.com/open-source/licenses/bsd\n    +-*/\n    +-\n    +-#ifndef REFTABLE_TESTS_H\n    +-#define REFTABLE_TESTS_H\n    +-\n    +-int stack_test_main(int argc, const char **argv);\n    +-\n    +-#endif\n    +\n    + ## reftable/test_framework.c (deleted) ##\n    +@@\n    +-/*\n    +-Copyright 2020 Google LLC\n    +-\n    +-Use of this source code is governed by a BSD-style\n    +-license that can be found in the LICENSE file or at\n    +-https://developers.google.com/open-source/licenses/bsd\n    +-*/\n    +-\n    +-#include \"system.h\"\n    +-#include \"test_framework.h\"\n    +-\n    +-\n    +-void set_test_hash(uint8_t *p, int i)\n    +-{\n    +-\tmemset(p, (uint8_t)i, hash_size(GIT_SHA1_FORMAT_ID));\n    +-}\n    +-\n    +-ssize_t strbuf_add_void(void *b, const void *data, size_t sz)\n    +-{\n    +-\tstrbuf_add(b, data, sz);\n    +-\treturn sz;\n    +-}\n    +-\n    +-int noop_flush(void *arg UNUSED)\n    +-{\n    +-\treturn 0;\n    +-}\n    +\n    + ## reftable/test_framework.h (deleted) ##\n    +@@\n    +-/*\n    +-Copyright 2020 Google LLC\n    +-\n    +-Use of this source code is governed by a BSD-style\n    +-license that can be found in the LICENSE file or at\n    +-https://developers.google.com/open-source/licenses/bsd\n    +-*/\n    +-\n    +-#ifndef TEST_FRAMEWORK_H\n    +-#define TEST_FRAMEWORK_H\n    +-\n    +-#include \"system.h\"\n    +-#include \"reftable-error.h\"\n    +-\n    +-#define EXPECT_ERR(c)                                                          \\\n    +-\tdo {                                                                   \\\n    +-\t\tif (c != 0) {                                                  \\\n    +-\t\t\tfflush(stderr);                                        \\\n    +-\t\t\tfflush(stdout);                                        \\\n    +-\t\t\tfprintf(stderr, \"%s: %d: error == %d (%s), want 0\\n\",  \\\n    +-\t\t\t\t__FILE__, __LINE__, c, reftable_error_str(c)); \\\n    +-\t\t\tabort();                                               \\\n    +-\t\t}                                                              \\\n    +-\t} while (0)\n    +-\n    +-#define EXPECT_STREQ(a, b)                                                       \\\n    +-\tdo {                                                                     \\\n    +-\t\tif (strcmp(a, b)) {                                              \\\n    +-\t\t\tfflush(stderr);                                          \\\n    +-\t\t\tfflush(stdout);                                          \\\n    +-\t\t\tfprintf(stderr, \"%s:%d: %s (%s) != %s (%s)\\n\", __FILE__, \\\n    +-\t\t\t\t__LINE__, #a, a, #b, b);                         \\\n    +-\t\t\tabort();                                                 \\\n    +-\t\t}                                                                \\\n    +-\t} while (0)\n    +-\n    +-#define EXPECT(c)                                                                  \\\n    +-\tdo {                                                                       \\\n    +-\t\tif (!(c)) {                                                        \\\n    +-\t\t\tfflush(stderr);                                            \\\n    +-\t\t\tfflush(stdout);                                            \\\n    +-\t\t\tfprintf(stderr, \"%s: %d: failed assertion %s\\n\", __FILE__, \\\n    +-\t\t\t\t__LINE__, #c);                                     \\\n    +-\t\t\tabort();                                                   \\\n    +-\t\t}                                                                  \\\n    +-\t} while (0)\n    +-\n    +-#define RUN_TEST(f)                          \\\n    +-\tfprintf(stderr, \"running %s\\n\", #f); \\\n    +-\tfflush(stderr);                      \\\n    +-\tf();\n    +-\n    +-void set_test_hash(uint8_t *p, int i);\n    +-\n    +-/* Like strbuf_add, but suitable for passing to reftable_new_writer\n    +- */\n    +-ssize_t strbuf_add_void(void *b, const void *data, size_t sz);\n    +-\n    +-int noop_flush(void *);\n    +-\n    +-#endif\n\n      ## t/helper/test-reftable.c ##\n     @@\n    - int cmd__reftable(int argc, const char **argv)\n    - {\n    - \t/* test from simple to complex. */\n    + #include \"reftable/reftable-merged.h\"\n    + #include \"reftable/reftable-reader.h\"\n    + #include \"reftable/reftable-stack.h\"\n    +-#include \"reftable/reftable-tests.h\"\n    + #include \"test-tool.h\"\n    +\n    +-int cmd__reftable(int argc, const char **argv)\n    +-{\n    +-\t/* test from simple to complex. */\n     -\tstack_test_main(argc, argv);\n    - \treturn 0;\n    - }\n    -\n    +-\treturn 0;\n    +-}\n    +-\n    + static void print_help(void)\n    + {\n    + \tprintf(\"usage: dump [-st] arg\\n\\n\"\n    +\n    + ## t/helper/test-tool.c ##\n    +@@ t/helper/test-tool.c: static struct test_cmd cmds[] = {\n    + \t{ \"drop-caches\", cmd__drop_caches },\n    + \t{ \"dump-cache-tree\", cmd__dump_cache_tree },\n    + \t{ \"dump-fsmonitor\", cmd__dump_fsmonitor },\n    ++\t{ \"dump-reftable\", cmd__dump_reftable },\n    + \t{ \"dump-split-index\", cmd__dump_split_index },\n    + \t{ \"dump-untracked-cache\", cmd__dump_untracked_cache },\n    + \t{ \"env-helper\", cmd__env_helper },\n    +@@ t/helper/test-tool.c: static struct test_cmd cmds[] = {\n    + \t{ \"read-graph\", cmd__read_graph },\n    + \t{ \"read-midx\", cmd__read_midx },\n    + \t{ \"ref-store\", cmd__ref_store },\n    +-\t{ \"reftable\", cmd__reftable },\n    + \t{ \"rot13-filter\", cmd__rot13_filter },\n    +-\t{ \"dump-reftable\", cmd__dump_reftable },\n    + \t{ \"regex\", cmd__regex },\n    + \t{ \"repository\", cmd__repository },\n    + \t{ \"revision-walking\", cmd__revision_walking },\n    +\n    + ## t/helper/test-tool.h ##\n    +@@ t/helper/test-tool.h: int cmd__read_graph(int argc, const char **argv);\n    + int cmd__read_midx(int argc, const char **argv);\n    + int cmd__ref_store(int argc, const char **argv);\n    + int cmd__rot13_filter(int argc, const char **argv);\n    +-int cmd__reftable(int argc, const char **argv);\n    + int cmd__regex(int argc, const char **argv);\n    + int cmd__repository(int argc, const char **argv);\n    + int cmd__revision_walking(int argc, const char **argv);\n    +\n    + ## t/t0032-reftable-unittest.sh (deleted) ##\n    +@@\n    +-#!/bin/sh\n    +-#\n    +-# Copyright (c) 2020 Google LLC\n    +-#\n    +-\n    +-test_description='reftable unittests'\n    +-\n    +-TEST_PASSES_SANITIZE_LEAK=true\n    +-. ./test-lib.sh\n    +-\n    +-test_expect_success 'unittests' '\n    +-\tTMPDIR=$(pwd) && export TMPDIR &&\n    +-\ttest-tool reftable\n    +-'\n    +-\n    +-test_done\n\n      ## reftable/stack_test.c => t/unit-tests/t-reftable-stack.c ##\n     @@ t/unit-tests/t-reftable-stack.c: license that can be found in the LICENSE file or at\n2:  8e8e09bd5b = 2:  1fd91e7a12 t: harmonize t-reftable-stack.c with coding guidelines\n3:  ca4b00feef = 3:  8a7132500a t-reftable-stack: use Git's tempfile API instead of mkstemp()\n4:  3e723667dd = 4:  786f7c2874 t-reftable-stack: use reftable_ref_record_equal() to compare ref records\n5:  7526550c92 = 5:  388f1129d8 t-reftable-stack: add test for non-default compaction factor\n6:  05e4b7e715 = 6:  5468c9853f t-reftable-stack: add test for stack iterators\n7:  560d3c76e0 < -:  ---------- t: clean up leftover reftable test cruft\n\n"},{"id":"502399","messageId":"20240908041632.4948-2-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240908041632.4948-1-chandrapratap3519@gmail.com","subject":"[PATCH v6 1/6] t: move reftable/stack_test.c to the unit testing framework","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-08T04:05:56Z","receivedAt":"2024-09-08T04:18:09Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"reftable/stack_test.c exercises the functions defined in\nreftable/stack.{c, h}. Migrate reftable/stack_test.c to the\nunit testing framework. Migration involves refactoring the tests\nto use the unit testing framework instead of reftable's test\nframework and renaming the tests to be in-line with unit-tests'\nstandards.\n\nSince some of the tests use set_test_hash() defined by\nreftable/test_framework.{c, h} but these files are not\n'#included' in the test file, copy this function in the\nported test file.\n\nWith the migration of stack test to the unit-tests framework,\n\"test-tool reftable\" becomes a no-op. Hence, get rid of everything\nthat uses \"test-tool reftable\" alongside everything that is used\nto implement it.\n\nWhile at it, alphabetically sort the cmds[] list in\nhelper/test-tool.c by moving the entry for \"dump-reftable\".\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n Makefile                                      |  12 +-\n reftable/reftable-tests.h                     |  14 -\n reftable/test_framework.c                     |  27 --\n reftable/test_framework.h                     |  61 ---\n t/helper/test-reftable.c                      |   8 -\n t/helper/test-tool.c                          |   3 +-\n t/helper/test-tool.h                          |   1 -\n t/t0032-reftable-unittest.sh                  |  16 -\n .../unit-tests/t-reftable-stack.c             | 429 +++++++++---------\n 9 files changed, 217 insertions(+), 354 deletions(-)\n delete mode 100644 reftable/reftable-tests.h\n delete mode 100644 reftable/test_framework.c\n delete mode 100644 reftable/test_framework.h\n delete mode 100755 t/t0032-reftable-unittest.sh\n rename reftable/stack_test.c => t/unit-tests/t-reftable-stack.c (76%)\n\ndiff --git a/Makefile b/Makefile\nindex 91f65d7dc5..bdea061971 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -912,7 +912,6 @@ TEST_SHELL_PATH = $(SHELL_PATH)\n LIB_FILE = libgit.a\n XDIFF_LIB = xdiff/lib.a\n REFTABLE_LIB = reftable/libreftable.a\n-REFTABLE_TEST_LIB = reftable/libreftable_test.a\n \n GENERATED_H += command-list.h\n GENERATED_H += config-list.h\n@@ -1349,6 +1348,7 @@ UNIT_TEST_PROGRAMS += t-reftable-merged\n UNIT_TEST_PROGRAMS += t-reftable-pq\n UNIT_TEST_PROGRAMS += t-reftable-readwrite\n UNIT_TEST_PROGRAMS += t-reftable-record\n+UNIT_TEST_PROGRAMS += t-reftable-stack\n UNIT_TEST_PROGRAMS += t-reftable-tree\n UNIT_TEST_PROGRAMS += t-strbuf\n UNIT_TEST_PROGRAMS += t-strcmp-offset\n@@ -2691,9 +2691,6 @@ REFTABLE_OBJS += reftable/stack.o\n REFTABLE_OBJS += reftable/tree.o\n REFTABLE_OBJS += reftable/writer.o\n \n-REFTABLE_TEST_OBJS += reftable/stack_test.o\n-REFTABLE_TEST_OBJS += reftable/test_framework.o\n-\n TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))\n \n .PHONY: test-objs\n@@ -2868,9 +2865,6 @@ $(XDIFF_LIB): $(XDIFF_OBJS)\n $(REFTABLE_LIB): $(REFTABLE_OBJS)\n \t$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^\n \n-$(REFTABLE_TEST_LIB): $(REFTABLE_TEST_OBJS)\n-\t$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^\n-\n export DEFAULT_EDITOR DEFAULT_PAGER\n \n Documentation/GIT-EXCLUDED-PROGRAMS: FORCE\n@@ -3250,7 +3244,7 @@ perf: all\n \n t/helper/test-tool$X: $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS)) $(UNIT_TEST_DIR)/test-lib.o\n \n-t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) $(REFTABLE_TEST_LIB)\n+t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS)\n \t$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS)\n \n check-sha1:: t/helper/test-tool$X\n@@ -3711,7 +3705,7 @@ clean: profile-clean coverage-clean cocciclean\n \t$(RM) git.res\n \t$(RM) $(OBJECTS)\n \t$(RM) headless-git.o\n-\t$(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(REFTABLE_TEST_LIB)\n+\t$(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB)\n \t$(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS)\n \t$(RM) $(TEST_PROGRAMS)\n \t$(RM) $(FUZZ_PROGRAMS)\ndiff --git a/reftable/reftable-tests.h b/reftable/reftable-tests.h\ndeleted file mode 100644\nindex 5d725c69c7..0000000000\n--- a/reftable/reftable-tests.h\n+++ /dev/null\n@@ -1,14 +0,0 @@\n-/*\n-Copyright 2020 Google LLC\n-\n-Use of this source code is governed by a BSD-style\n-license that can be found in the LICENSE file or at\n-https://developers.google.com/open-source/licenses/bsd\n-*/\n-\n-#ifndef REFTABLE_TESTS_H\n-#define REFTABLE_TESTS_H\n-\n-int stack_test_main(int argc, const char **argv);\n-\n-#endif\ndiff --git a/reftable/test_framework.c b/reftable/test_framework.c\ndeleted file mode 100644\nindex a07fec5d84..0000000000\n--- a/reftable/test_framework.c\n+++ /dev/null\n@@ -1,27 +0,0 @@\n-/*\n-Copyright 2020 Google LLC\n-\n-Use of this source code is governed by a BSD-style\n-license that can be found in the LICENSE file or at\n-https://developers.google.com/open-source/licenses/bsd\n-*/\n-\n-#include \"system.h\"\n-#include \"test_framework.h\"\n-\n-\n-void set_test_hash(uint8_t *p, int i)\n-{\n-\tmemset(p, (uint8_t)i, hash_size(GIT_SHA1_FORMAT_ID));\n-}\n-\n-ssize_t strbuf_add_void(void *b, const void *data, size_t sz)\n-{\n-\tstrbuf_add(b, data, sz);\n-\treturn sz;\n-}\n-\n-int noop_flush(void *arg UNUSED)\n-{\n-\treturn 0;\n-}\ndiff --git a/reftable/test_framework.h b/reftable/test_framework.h\ndeleted file mode 100644\nindex 687390f9c2..0000000000\n--- a/reftable/test_framework.h\n+++ /dev/null\n@@ -1,61 +0,0 @@\n-/*\n-Copyright 2020 Google LLC\n-\n-Use of this source code is governed by a BSD-style\n-license that can be found in the LICENSE file or at\n-https://developers.google.com/open-source/licenses/bsd\n-*/\n-\n-#ifndef TEST_FRAMEWORK_H\n-#define TEST_FRAMEWORK_H\n-\n-#include \"system.h\"\n-#include \"reftable-error.h\"\n-\n-#define EXPECT_ERR(c)                                                          \\\n-\tdo {                                                                   \\\n-\t\tif (c != 0) {                                                  \\\n-\t\t\tfflush(stderr);                                        \\\n-\t\t\tfflush(stdout);                                        \\\n-\t\t\tfprintf(stderr, \"%s: %d: error == %d (%s), want 0\\n\",  \\\n-\t\t\t\t__FILE__, __LINE__, c, reftable_error_str(c)); \\\n-\t\t\tabort();                                               \\\n-\t\t}                                                              \\\n-\t} while (0)\n-\n-#define EXPECT_STREQ(a, b)                                                       \\\n-\tdo {                                                                     \\\n-\t\tif (strcmp(a, b)) {                                              \\\n-\t\t\tfflush(stderr);                                          \\\n-\t\t\tfflush(stdout);                                          \\\n-\t\t\tfprintf(stderr, \"%s:%d: %s (%s) != %s (%s)\\n\", __FILE__, \\\n-\t\t\t\t__LINE__, #a, a, #b, b);                         \\\n-\t\t\tabort();                                                 \\\n-\t\t}                                                                \\\n-\t} while (0)\n-\n-#define EXPECT(c)                                                                  \\\n-\tdo {                                                                       \\\n-\t\tif (!(c)) {                                                        \\\n-\t\t\tfflush(stderr);                                            \\\n-\t\t\tfflush(stdout);                                            \\\n-\t\t\tfprintf(stderr, \"%s: %d: failed assertion %s\\n\", __FILE__, \\\n-\t\t\t\t__LINE__, #c);                                     \\\n-\t\t\tabort();                                                   \\\n-\t\t}                                                                  \\\n-\t} while (0)\n-\n-#define RUN_TEST(f)                          \\\n-\tfprintf(stderr, \"running %s\\n\", #f); \\\n-\tfflush(stderr);                      \\\n-\tf();\n-\n-void set_test_hash(uint8_t *p, int i);\n-\n-/* Like strbuf_add, but suitable for passing to reftable_new_writer\n- */\n-ssize_t strbuf_add_void(void *b, const void *data, size_t sz);\n-\n-int noop_flush(void *);\n-\n-#endif\ndiff --git a/t/helper/test-reftable.c b/t/helper/test-reftable.c\nindex ce5a94fbd3..29d4e9a755 100644\n--- a/t/helper/test-reftable.c\n+++ b/t/helper/test-reftable.c\n@@ -6,16 +6,8 @@\n #include \"reftable/reftable-merged.h\"\n #include \"reftable/reftable-reader.h\"\n #include \"reftable/reftable-stack.h\"\n-#include \"reftable/reftable-tests.h\"\n #include \"test-tool.h\"\n \n-int cmd__reftable(int argc, const char **argv)\n-{\n-\t/* test from simple to complex. */\n-\tstack_test_main(argc, argv);\n-\treturn 0;\n-}\n-\n static void print_help(void)\n {\n \tprintf(\"usage: dump [-st] arg\\n\\n\"\ndiff --git a/t/helper/test-tool.c b/t/helper/test-tool.c\nindex f8a67df7de..252fa5de63 100644\n--- a/t/helper/test-tool.c\n+++ b/t/helper/test-tool.c\n@@ -26,6 +26,7 @@ static struct test_cmd cmds[] = {\n \t{ \"drop-caches\", cmd__drop_caches },\n \t{ \"dump-cache-tree\", cmd__dump_cache_tree },\n \t{ \"dump-fsmonitor\", cmd__dump_fsmonitor },\n+\t{ \"dump-reftable\", cmd__dump_reftable },\n \t{ \"dump-split-index\", cmd__dump_split_index },\n \t{ \"dump-untracked-cache\", cmd__dump_untracked_cache },\n \t{ \"env-helper\", cmd__env_helper },\n@@ -61,9 +62,7 @@ static struct test_cmd cmds[] = {\n \t{ \"read-graph\", cmd__read_graph },\n \t{ \"read-midx\", cmd__read_midx },\n \t{ \"ref-store\", cmd__ref_store },\n-\t{ \"reftable\", cmd__reftable },\n \t{ \"rot13-filter\", cmd__rot13_filter },\n-\t{ \"dump-reftable\", cmd__dump_reftable },\n \t{ \"regex\", cmd__regex },\n \t{ \"repository\", cmd__repository },\n \t{ \"revision-walking\", cmd__revision_walking },\ndiff --git a/t/helper/test-tool.h b/t/helper/test-tool.h\nindex e74bc0ffd4..84291318cb 100644\n--- a/t/helper/test-tool.h\n+++ b/t/helper/test-tool.h\n@@ -55,7 +55,6 @@ int cmd__read_graph(int argc, const char **argv);\n int cmd__read_midx(int argc, const char **argv);\n int cmd__ref_store(int argc, const char **argv);\n int cmd__rot13_filter(int argc, const char **argv);\n-int cmd__reftable(int argc, const char **argv);\n int cmd__regex(int argc, const char **argv);\n int cmd__repository(int argc, const char **argv);\n int cmd__revision_walking(int argc, const char **argv);\ndiff --git a/t/t0032-reftable-unittest.sh b/t/t0032-reftable-unittest.sh\ndeleted file mode 100755\nindex 471cb37ac2..0000000000\n--- a/t/t0032-reftable-unittest.sh\n+++ /dev/null\n@@ -1,16 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright (c) 2020 Google LLC\n-#\n-\n-test_description='reftable unittests'\n-\n-TEST_PASSES_SANITIZE_LEAK=true\n-. ./test-lib.sh\n-\n-test_expect_success 'unittests' '\n-\tTMPDIR=$(pwd) && export TMPDIR &&\n-\ttest-tool reftable\n-'\n-\n-test_done\ndiff --git a/reftable/stack_test.c b/t/unit-tests/t-reftable-stack.c\nsimilarity index 76%\nrename from reftable/stack_test.c\nrename to t/unit-tests/t-reftable-stack.c\nindex 89cb2be19f..de28fac466 100644\n--- a/reftable/stack_test.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -6,22 +6,18 @@ license that can be found in the LICENSE file or at\n https://developers.google.com/open-source/licenses/bsd\n */\n \n-#include \"stack.h\"\n-\n-#include \"system.h\"\n-\n-#include \"copy.h\"\n-#include \"reftable-reader.h\"\n-#include \"merged.h\"\n-#include \"basics.h\"\n-#include \"record.h\"\n-#include \"test_framework.h\"\n-#include \"reftable-tests.h\"\n-#include \"reader.h\"\n-\n-#include <sys/types.h>\n+#include \"test-lib.h\"\n+#include \"reftable/merged.h\"\n+#include \"reftable/reader.h\"\n+#include \"reftable/reftable-error.h\"\n+#include \"reftable/stack.h\"\n #include <dirent.h>\n \n+static void set_test_hash(uint8_t *p, int i)\n+{\n+\tmemset(p, (uint8_t)i, hash_size(GIT_SHA1_FORMAT_ID));\n+}\n+\n static void clear_dir(const char *dirname)\n {\n \tstruct strbuf path = STRBUF_INIT;\n@@ -73,11 +69,11 @@ static char *get_tmp_template(int linenumber)\n static char *get_tmp_dir(int linenumber)\n {\n \tchar *dir = get_tmp_template(linenumber);\n-\tEXPECT(mkdtemp(dir));\n+\tcheck(mkdtemp(dir) != NULL);\n \treturn dir;\n }\n \n-static void test_read_file(void)\n+static void t_read_file(void)\n {\n \tchar *fn = get_tmp_template(__LINE__);\n \tint fd = mkstemp(fn);\n@@ -87,17 +83,17 @@ static void test_read_file(void)\n \tconst char *want[] = { \"line1\", \"line2\", \"line3\" };\n \tint i = 0;\n \n-\tEXPECT(fd > 0);\n+\tcheck_int(fd, >, 0);\n \tn = write_in_full(fd, out, strlen(out));\n-\tEXPECT(n == strlen(out));\n+\tcheck_int(n, ==, strlen(out));\n \terr = close(fd);\n-\tEXPECT(err >= 0);\n+\tcheck_int(err, >=, 0);\n \n \terr = read_lines(fn, &names);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; names[i]; i++) {\n-\t\tEXPECT(0 == strcmp(want[i], names[i]));\n+\t\tcheck_str(want[i], names[i]);\n \t}\n \tfree_names(names);\n \t(void) remove(fn);\n@@ -132,7 +128,7 @@ static void write_n_ref_tables(struct reftable_stack *st,\n \t\tset_test_hash(ref.value.val1, i);\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tst->opts.disable_auto_compact = disable_auto_compact;\n@@ -152,7 +148,7 @@ static int write_test_log(struct reftable_writer *wr, void *arg)\n \treturn reftable_writer_add_log(wr, wla->log);\n }\n \n-static void test_reftable_stack_add_one(void)\n+static void t_reftable_stack_add_one(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct strbuf scratch = STRBUF_INIT;\n@@ -171,22 +167,22 @@ static void test_reftable_stack_add_one(void)\n \tstruct reftable_ref_record dest = { NULL };\n \tstruct stat stat_result = { 0 };\n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(\"master\", dest.value.symref));\n-\tEXPECT(st->readers_len > 0);\n+\tcheck(!err);\n+\tcheck_str(\"master\", dest.value.symref);\n+\tcheck_int(st->readers_len, >, 0);\n \n #ifndef GIT_WINDOWS_NATIVE\n \tstrbuf_addstr(&scratch, dir);\n \tstrbuf_addstr(&scratch, \"/tables.list\");\n \terr = stat(scratch.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n \n \tstrbuf_reset(&scratch);\n \tstrbuf_addstr(&scratch, dir);\n@@ -194,8 +190,8 @@ static void test_reftable_stack_add_one(void)\n \t/* do not try at home; not an external API for reftable. */\n \tstrbuf_addstr(&scratch, st->readers[0]->name);\n \terr = stat(scratch.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n #else\n \t(void) stat_result;\n #endif\n@@ -207,7 +203,7 @@ static void test_reftable_stack_add_one(void)\n \tumask(mask);\n }\n \n-static void test_reftable_stack_uptodate(void)\n+static void t_reftable_stack_uptodate(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL;\n@@ -233,28 +229,28 @@ static void test_reftable_stack_uptodate(void)\n \t   by creating two stacks for the same directory.\n \t */\n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st1, &write_test_ref, &ref1);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n-\tEXPECT(err == REFTABLE_OUTDATED_ERROR);\n+\tcheck_int(err, ==, REFTABLE_OUTDATED_ERROR);\n \n \terr = reftable_stack_reload(st2);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_transaction_api(void)\n+static void t_reftable_stack_transaction_api(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -271,32 +267,32 @@ static void test_reftable_stack_transaction_api(void)\n \tstruct reftable_ref_record dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_addition_destroy(add);\n \n \terr = reftable_stack_new_addition(&add, st);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_addition_add(add, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_addition_commit(add);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_addition_destroy(add);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(REFTABLE_REF_SYMREF == dest.value_type);\n-\tEXPECT(0 == strcmp(\"master\", dest.value.symref));\n+\tcheck(!err);\n+\tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n+\tcheck_str(\"master\", dest.value.symref);\n \n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n+static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = {0};\n@@ -305,7 +301,7 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \tint i, n = 20, err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n@@ -326,13 +322,13 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\tst->opts.disable_auto_compact = i != n;\n \n \t\terr = reftable_stack_new_addition(&add, st);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_addition_add(add, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_addition_commit(add);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\treftable_addition_destroy(add);\n \n@@ -342,16 +338,16 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\t * all tables in the stack.\n \t\t */\n \t\tif (i != n)\n-\t\t\tEXPECT(st->merged->readers_len == i + 1);\n+\t\t\tcheck_int(st->merged->readers_len, ==, i + 1);\n \t\telse\n-\t\t\tEXPECT(st->merged->readers_len == 1);\n+\t\t\tcheck_int(st->merged->readers_len, ==, 1);\n \t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n+static void t_reftable_stack_auto_compaction_fails_gracefully(void)\n {\n \tstruct reftable_ref_record ref = {\n \t\t.refname = (char *) \"refs/heads/master\",\n@@ -366,13 +362,13 @@ static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->merged->readers_len == 1);\n-\tEXPECT(st->stats.attempts == 0);\n-\tEXPECT(st->stats.failures == 0);\n+\tcheck(!err);\n+\tcheck_int(st->merged->readers_len, ==, 1);\n+\tcheck_int(st->stats.attempts, ==, 0);\n+\tcheck_int(st->stats.failures, ==, 0);\n \n \t/*\n \t * Lock the newly written table such that it cannot be compacted.\n@@ -384,10 +380,10 @@ static void test_reftable_stack_auto_compaction_fails_gracefully(void)\n \n \tref.update_index = 2;\n \terr = reftable_stack_add(st, write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->merged->readers_len == 2);\n-\tEXPECT(st->stats.attempts == 1);\n-\tEXPECT(st->stats.failures == 1);\n+\tcheck(!err);\n+\tcheck_int(st->merged->readers_len, ==, 2);\n+\tcheck_int(st->stats.attempts, ==, 1);\n+\tcheck_int(st->stats.failures, ==, 1);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&table_path);\n@@ -399,7 +395,7 @@ static int write_error(struct reftable_writer *wr UNUSED, void *arg)\n \treturn *((int *)arg);\n }\n \n-static void test_reftable_stack_update_index_check(void)\n+static void t_reftable_stack_update_index_check(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -419,18 +415,18 @@ static void test_reftable_stack_update_index_check(void)\n \t};\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref1);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref2);\n-\tEXPECT(err == REFTABLE_API_ERROR);\n+\tcheck_int(err, ==, REFTABLE_API_ERROR);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_lock_failure(void)\n+static void t_reftable_stack_lock_failure(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -438,17 +434,17 @@ static void test_reftable_stack_lock_failure(void)\n \tint err, i;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \tfor (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) {\n \t\terr = reftable_stack_add(st, &write_error, &i);\n-\t\tEXPECT(err == i);\n+\t\tcheck_int(err, ==, i);\n \t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_add(void)\n+static void t_reftable_stack_add(void)\n {\n \tint i = 0;\n \tint err = 0;\n@@ -466,7 +462,7 @@ static void test_reftable_stack_add(void)\n \tint N = ARRAY_SIZE(refs);\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar buf[256];\n@@ -485,7 +481,7 @@ static void test_reftable_stack_add(void)\n \n \tfor (i = 0; i < N; i++) {\n \t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tfor (i = 0; i < N; i++) {\n@@ -494,18 +490,18 @@ static void test_reftable_stack_add(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tstruct reftable_ref_record dest = { NULL };\n \n \t\tint err = reftable_stack_read_ref(st, refs[i].refname, &dest);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(reftable_ref_record_equal(&dest, refs + i,\n+\t\tcheck(!err);\n+\t\tcheck(reftable_ref_record_equal(&dest, refs + i,\n \t\t\t\t\t\t GIT_SHA1_RAWSZ));\n \t\treftable_ref_record_release(&dest);\n \t}\n@@ -513,8 +509,8 @@ static void test_reftable_stack_add(void)\n \tfor (i = 0; i < N; i++) {\n \t\tstruct reftable_log_record dest = { NULL };\n \t\tint err = reftable_stack_read_log(st, refs[i].refname, &dest);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(reftable_log_record_equal(&dest, logs + i,\n+\t\tcheck(!err);\n+\t\tcheck(reftable_log_record_equal(&dest, logs + i,\n \t\t\t\t\t\t GIT_SHA1_RAWSZ));\n \t\treftable_log_record_release(&dest);\n \t}\n@@ -523,8 +519,8 @@ static void test_reftable_stack_add(void)\n \tstrbuf_addstr(&path, dir);\n \tstrbuf_addstr(&path, \"/tables.list\");\n \terr = stat(path.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n \n \tstrbuf_reset(&path);\n \tstrbuf_addstr(&path, dir);\n@@ -532,8 +528,8 @@ static void test_reftable_stack_add(void)\n \t/* do not try at home; not an external API for reftable. */\n \tstrbuf_addstr(&path, st->readers[0]->name);\n \terr = stat(path.buf, &stat_result);\n-\tEXPECT(!err);\n-\tEXPECT((stat_result.st_mode & 0777) == opts.default_permissions);\n+\tcheck(!err);\n+\tcheck_int((stat_result.st_mode & 0777), ==, opts.default_permissions);\n #else\n \t(void) stat_result;\n #endif\n@@ -548,7 +544,7 @@ static void test_reftable_stack_add(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_log_normalize(void)\n+static void t_reftable_stack_log_normalize(void)\n {\n \tint err = 0;\n \tstruct reftable_write_options opts = {\n@@ -576,27 +572,27 @@ static void test_reftable_stack_log_normalize(void)\n \t};\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tinput.value.update.message = (char *) \"one\\ntwo\";\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT(err == REFTABLE_API_ERROR);\n+\tcheck_int(err, ==, REFTABLE_API_ERROR);\n \n \tinput.value.update.message = (char *) \"one\";\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, input.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(dest.value.update.message, \"one\\n\"));\n+\tcheck(!err);\n+\tcheck_str(dest.value.update.message, \"one\\n\");\n \n \tinput.value.update.message = (char *) \"two\\n\";\n \targ.update_index = 2;\n \terr = reftable_stack_add(st, &write_test_log, &arg);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \terr = reftable_stack_read_log(st, input.refname, &dest);\n-\tEXPECT_ERR(err);\n-\tEXPECT(0 == strcmp(dest.value.update.message, \"two\\n\"));\n+\tcheck(!err);\n+\tcheck_str(dest.value.update.message, \"two\\n\");\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n@@ -604,7 +600,7 @@ static void test_reftable_stack_log_normalize(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_tombstone(void)\n+static void t_reftable_stack_tombstone(void)\n {\n \tint i = 0;\n \tchar *dir = get_tmp_dir(__LINE__);\n@@ -618,7 +614,7 @@ static void test_reftable_stack_tombstone(void)\n \tstruct reftable_log_record log_dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* even entries add the refs, odd entries delete them. */\n \tfor (i = 0; i < N; i++) {\n@@ -642,7 +638,7 @@ static void test_reftable_stack_tombstone(void)\n \t}\n \tfor (i = 0; i < N; i++) {\n \t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \tfor (i = 0; i < N; i++) {\n@@ -651,25 +647,25 @@ static void test_reftable_stack_tombstone(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_read_ref(st, \"branch\", &dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_ref_record_release(&dest);\n \n \terr = reftable_stack_read_log(st, \"branch\", &log_dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_log_record_release(&log_dest);\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, \"branch\", &dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, \"branch\", &log_dest);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \treftable_ref_record_release(&dest);\n \treftable_log_record_release(&log_dest);\n \n@@ -682,7 +678,7 @@ static void test_reftable_stack_tombstone(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_hash_id(void)\n+static void t_reftable_stack_hash_id(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -702,47 +698,47 @@ static void test_reftable_stack_hash_id(void)\n \tstruct reftable_ref_record dest = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* can't read it with the wrong hash ID. */\n \terr = reftable_new_stack(&st32, dir, &opts32);\n-\tEXPECT(err == REFTABLE_FORMAT_ERROR);\n+\tcheck_int(err, ==, REFTABLE_FORMAT_ERROR);\n \n \t/* check that we can read it back with default opts too. */\n \terr = reftable_new_stack(&st_default, dir, &opts_default);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_ref(st_default, \"master\", &dest);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n-\tEXPECT(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n \treftable_stack_destroy(st_default);\n \tclear_dir(dir);\n }\n \n-static void test_suggest_compaction_segment(void)\n+static void t_suggest_compaction_segment(void)\n {\n \tuint64_t sizes[] = { 512, 64, 17, 16, 9, 9, 9, 16, 2, 16 };\n \tstruct segment min =\n \t\tsuggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);\n-\tEXPECT(min.start == 1);\n-\tEXPECT(min.end == 10);\n+\tcheck_int(min.start, ==, 1);\n+\tcheck_int(min.end, ==, 10);\n }\n \n-static void test_suggest_compaction_segment_nothing(void)\n+static void t_suggest_compaction_segment_nothing(void)\n {\n \tuint64_t sizes[] = { 64, 32, 16, 8, 4, 2 };\n \tstruct segment result =\n \t\tsuggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);\n-\tEXPECT(result.start == result.end);\n+\tcheck_int(result.start, ==, result.end);\n }\n \n-static void test_reflog_expire(void)\n+static void t_reflog_expire(void)\n {\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n@@ -757,7 +753,7 @@ static void test_reflog_expire(void)\n \tstruct reftable_log_record log = { NULL };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 1; i <= N; i++) {\n \t\tchar buf[256];\n@@ -777,30 +773,30 @@ static void test_reflog_expire(void)\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n \t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \t}\n \n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st, &expiry);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, logs[9].refname, &log);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, logs[11].refname, &log);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \texpiry.min_update_index = 15;\n \terr = reftable_stack_compact_all(st, &expiry);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_read_log(st, logs[14].refname, &log);\n-\tEXPECT(err == 1);\n+\tcheck_int(err, ==, 1);\n \n \terr = reftable_stack_read_log(st, logs[16].refname, &log);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n@@ -817,7 +813,7 @@ static int write_nothing(struct reftable_writer *wr, void *arg UNUSED)\n \treturn 0;\n }\n \n-static void test_empty_add(void)\n+static void t_empty_add(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -826,13 +822,13 @@ static void test_empty_add(void)\n \tstruct reftable_stack *st2 = NULL;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_add(st, &write_nothing, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \tclear_dir(dir);\n \treftable_stack_destroy(st);\n \treftable_stack_destroy(st2);\n@@ -848,7 +844,7 @@ static int fastlog2(uint64_t sz)\n \treturn l - 1;\n }\n \n-static void test_reftable_stack_auto_compaction(void)\n+static void t_reftable_stack_auto_compaction(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -859,7 +855,7 @@ static void test_reftable_stack_auto_compaction(void)\n \tint N = 100;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar name[100];\n@@ -872,21 +868,21 @@ static void test_reftable_stack_auto_compaction(void)\n \t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\terr = reftable_stack_auto_compact(st);\n-\t\tEXPECT_ERR(err);\n-\t\tEXPECT(i < 3 || st->merged->readers_len < 2 * fastlog2(i));\n+\t\tcheck(!err);\n+\t\tcheck(i < 3 || st->merged->readers_len < 2 * fastlog2(i));\n \t}\n \n-\tEXPECT(reftable_stack_compaction_stats(st)->entries_written <\n+\tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n \t       (uint64_t)(N * fastlog2(N)));\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n+static void t_reftable_stack_auto_compaction_with_locked_tables(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -897,10 +893,10 @@ static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \twrite_n_ref_tables(st, 5);\n-\tEXPECT(st->merged->readers_len == 5);\n+\tcheck_int(st->merged->readers_len, ==, 5);\n \n \t/*\n \t * Given that all tables we have written should be roughly the same\n@@ -918,16 +914,16 @@ static void test_reftable_stack_auto_compaction_with_locked_tables(void)\n \t * only compact the newest two tables.\n \t */\n \terr = reftable_stack_auto_compact(st);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st->stats.failures == 0);\n-\tEXPECT(st->merged->readers_len == 4);\n+\tcheck(!err);\n+\tcheck_int(st->stats.failures, ==, 0);\n+\tcheck_int(st->merged->readers_len, ==, 4);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&buf);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_add_performs_auto_compaction(void)\n+static void t_reftable_stack_add_performs_auto_compaction(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -936,7 +932,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \tint err, i, n = 20;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tfor (i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n@@ -957,7 +953,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \t\tref.refname = refname.buf;\n \n \t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n-\t\tEXPECT_ERR(err);\n+\t\tcheck(!err);\n \n \t\t/*\n \t\t * The stack length should grow continuously for all runs where\n@@ -965,9 +961,9 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \t\t * all tables in the stack.\n \t\t */\n \t\tif (i != n)\n-\t\t\tEXPECT(st->merged->readers_len == i + 1);\n+\t\t\tcheck_int(st->merged->readers_len, ==, i + 1);\n \t\telse\n-\t\t\tEXPECT(st->merged->readers_len == 1);\n+\t\t\tcheck_int(st->merged->readers_len, ==, 1);\n \t}\n \n \treftable_stack_destroy(st);\n@@ -975,7 +971,7 @@ static void test_reftable_stack_add_performs_auto_compaction(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_compaction_with_locked_tables(void)\n+static void t_reftable_stack_compaction_with_locked_tables(void)\n {\n \tstruct reftable_write_options opts = {\n \t\t.disable_auto_compact = 1,\n@@ -986,10 +982,10 @@ static void test_reftable_stack_compaction_with_locked_tables(void)\n \tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \twrite_n_ref_tables(st, 3);\n-\tEXPECT(st->merged->readers_len == 3);\n+\tcheck_int(st->merged->readers_len, ==, 3);\n \n \t/* Lock one of the tables that we're about to compact. */\n \tstrbuf_reset(&buf);\n@@ -1001,16 +997,16 @@ static void test_reftable_stack_compaction_with_locked_tables(void)\n \t * compact all tables.\n \t */\n \terr = reftable_stack_compact_all(st, NULL);\n-\tEXPECT(err == REFTABLE_LOCK_ERROR);\n-\tEXPECT(st->stats.failures == 1);\n-\tEXPECT(st->merged->readers_len == 3);\n+\tcheck_int(err, ==, REFTABLE_LOCK_ERROR);\n+\tcheck_int(st->stats.failures, ==, 1);\n+\tcheck_int(st->merged->readers_len, ==, 3);\n \n \treftable_stack_destroy(st);\n \tstrbuf_release(&buf);\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_compaction_concurrent(void)\n+static void t_reftable_stack_compaction_concurrent(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL;\n@@ -1018,19 +1014,19 @@ static void test_reftable_stack_compaction_concurrent(void)\n \tint err;\n \n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st1, 3);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st1, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n \n-\tEXPECT(count_dir_entries(dir) == 2);\n+\tcheck_int(count_dir_entries(dir), ==, 2);\n \tclear_dir(dir);\n }\n \n@@ -1043,7 +1039,7 @@ static void unclean_stack_close(struct reftable_stack *st)\n \tFREE_AND_NULL(st->readers);\n }\n \n-static void test_reftable_stack_compaction_concurrent_clean(void)\n+static void t_reftable_stack_compaction_concurrent_clean(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL, *st3 = NULL;\n@@ -1051,24 +1047,24 @@ static void test_reftable_stack_compaction_concurrent_clean(void)\n \tint err;\n \n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st1, 3);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_compact_all(st1, NULL);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \tunclean_stack_close(st1);\n \tunclean_stack_close(st2);\n \n \terr = reftable_new_stack(&st3, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_clean(st3);\n-\tEXPECT_ERR(err);\n-\tEXPECT(count_dir_entries(dir) == 2);\n+\tcheck(!err);\n+\tcheck_int(count_dir_entries(dir), ==, 2);\n \n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n@@ -1077,7 +1073,7 @@ static void test_reftable_stack_compaction_concurrent_clean(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_read_across_reload(void)\n+static void t_reftable_stack_read_across_reload(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st1 = NULL, *st2 = NULL;\n@@ -1088,36 +1084,36 @@ static void test_reftable_stack_read_across_reload(void)\n \n \t/* Create a first stack and set up an iterator for it. */\n \terr = reftable_new_stack(&st1, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st1, 2);\n-\tEXPECT(st1->merged->readers_len == 2);\n+\tcheck_int(st1->merged->readers_len, ==, 2);\n \treftable_stack_init_ref_iterator(st1, &it);\n \terr = reftable_iterator_seek_ref(&it, \"\");\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/* Set up a second stack for the same directory and compact it. */\n \terr = reftable_new_stack(&st2, dir, &opts);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st2->merged->readers_len == 2);\n+\tcheck(!err);\n+\tcheck_int(st2->merged->readers_len, ==, 2);\n \terr = reftable_stack_compact_all(st2, NULL);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st2->merged->readers_len == 1);\n+\tcheck(!err);\n+\tcheck_int(st2->merged->readers_len, ==, 1);\n \n \t/*\n \t * Verify that we can continue to use the old iterator even after we\n \t * have reloaded its stack.\n \t */\n \terr = reftable_stack_reload(st1);\n-\tEXPECT_ERR(err);\n-\tEXPECT(st1->merged->readers_len == 1);\n+\tcheck(!err);\n+\tcheck_int(st1->merged->readers_len, ==, 1);\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT_ERR(err);\n-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0000\"));\n+\tcheck(!err);\n+\tcheck_str(rec.refname, \"refs/heads/branch-0000\");\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT_ERR(err);\n-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0001\"));\n+\tcheck(!err);\n+\tcheck_str(rec.refname, \"refs/heads/branch-0001\");\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT(err > 0);\n+\tcheck_int(err, >, 0);\n \n \treftable_ref_record_release(&rec);\n \treftable_iterator_destroy(&it);\n@@ -1126,7 +1122,7 @@ static void test_reftable_stack_read_across_reload(void)\n \tclear_dir(dir);\n }\n \n-static void test_reftable_stack_reload_with_missing_table(void)\n+static void t_reftable_stack_reload_with_missing_table(void)\n {\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n@@ -1138,12 +1134,12 @@ static void test_reftable_stack_reload_with_missing_table(void)\n \n \t/* Create a first stack and set up an iterator for it. */\n \terr = reftable_new_stack(&st, dir, &opts);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \twrite_n_ref_tables(st, 2);\n-\tEXPECT(st->merged->readers_len == 2);\n+\tcheck_int(st->merged->readers_len, ==, 2);\n \treftable_stack_init_ref_iterator(st, &it);\n \terr = reftable_iterator_seek_ref(&it, \"\");\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \t/*\n \t * Update the tables.list file with some garbage data, while reusing\n@@ -1156,24 +1152,24 @@ static void test_reftable_stack_reload_with_missing_table(void)\n \tstrbuf_addf(&table_path, \"%s.lock\", st->list_file);\n \twrite_file_buf(table_path.buf, content.buf, content.len);\n \terr = rename(table_path.buf, st->list_file);\n-\tEXPECT_ERR(err);\n+\tcheck(!err);\n \n \terr = reftable_stack_reload(st);\n-\tEXPECT(err == -4);\n-\tEXPECT(st->merged->readers_len == 2);\n+\tcheck_int(err, ==, -4);\n+\tcheck_int(st->merged->readers_len, ==, 2);\n \n \t/*\n \t * Even though the reload has failed, we should be able to continue\n \t * using the iterator.\n \t*/\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT_ERR(err);\n-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0000\"));\n+\tcheck(!err);\n+\tcheck_str(rec.refname, \"refs/heads/branch-0000\");\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT_ERR(err);\n-\tEXPECT(!strcmp(rec.refname, \"refs/heads/branch-0001\"));\n+\tcheck(!err);\n+\tcheck_str(rec.refname, \"refs/heads/branch-0001\");\n \terr = reftable_iterator_next_ref(&it, &rec);\n-\tEXPECT(err > 0);\n+\tcheck_int(err, >, 0);\n \n \treftable_ref_record_release(&rec);\n \treftable_iterator_destroy(&it);\n@@ -1183,31 +1179,32 @@ static void test_reftable_stack_reload_with_missing_table(void)\n \tclear_dir(dir);\n }\n \n-int stack_test_main(int argc UNUSED, const char *argv[] UNUSED)\n+int cmd_main(int argc UNUSED, const char *argv[] UNUSED)\n {\n-\tRUN_TEST(test_empty_add);\n-\tRUN_TEST(test_read_file);\n-\tRUN_TEST(test_reflog_expire);\n-\tRUN_TEST(test_reftable_stack_add);\n-\tRUN_TEST(test_reftable_stack_add_one);\n-\tRUN_TEST(test_reftable_stack_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_auto_compaction_with_locked_tables);\n-\tRUN_TEST(test_reftable_stack_add_performs_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_compaction_concurrent);\n-\tRUN_TEST(test_reftable_stack_compaction_concurrent_clean);\n-\tRUN_TEST(test_reftable_stack_compaction_with_locked_tables);\n-\tRUN_TEST(test_reftable_stack_hash_id);\n-\tRUN_TEST(test_reftable_stack_lock_failure);\n-\tRUN_TEST(test_reftable_stack_log_normalize);\n-\tRUN_TEST(test_reftable_stack_tombstone);\n-\tRUN_TEST(test_reftable_stack_transaction_api);\n-\tRUN_TEST(test_reftable_stack_transaction_api_performs_auto_compaction);\n-\tRUN_TEST(test_reftable_stack_auto_compaction_fails_gracefully);\n-\tRUN_TEST(test_reftable_stack_update_index_check);\n-\tRUN_TEST(test_reftable_stack_uptodate);\n-\tRUN_TEST(test_reftable_stack_read_across_reload);\n-\tRUN_TEST(test_reftable_stack_reload_with_missing_table);\n-\tRUN_TEST(test_suggest_compaction_segment);\n-\tRUN_TEST(test_suggest_compaction_segment_nothing);\n-\treturn 0;\n+\tTEST(t_empty_add(), \"empty addition to stack\");\n+\tTEST(t_read_file(), \"read_lines works\");\n+\tTEST(t_reflog_expire(), \"expire reflog entries\");\n+\tTEST(t_reftable_stack_add(), \"add multiple refs and logs to stack\");\n+\tTEST(t_reftable_stack_add_one(), \"add a single ref record to stack\");\n+\tTEST(t_reftable_stack_add_performs_auto_compaction(), \"addition to stack triggers auto-compaction\");\n+\tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_fails_gracefully(), \"failure on auto-compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_with_locked_tables(), \"auto compaction with locked tables\");\n+\tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n+\tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n+\tTEST(t_reftable_stack_compaction_with_locked_tables(), \"compaction with locked tables\");\n+\tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n+\tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n+\tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n+\tTEST(t_reftable_stack_read_across_reload(), \"stack iterators work across reloads\");\n+\tTEST(t_reftable_stack_reload_with_missing_table(), \"stack iteration with garbage tables\");\n+\tTEST(t_reftable_stack_tombstone(), \"'tombstone' refs in stack\");\n+\tTEST(t_reftable_stack_transaction_api(), \"update transaction to stack\");\n+\tTEST(t_reftable_stack_transaction_api_performs_auto_compaction(), \"update transaction triggers auto-compaction\");\n+\tTEST(t_reftable_stack_update_index_check(), \"update transactions with equal update indices\");\n+\tTEST(t_reftable_stack_uptodate(), \"stack must be reloaded before ref update\");\n+\tTEST(t_suggest_compaction_segment(), \"suggest_compaction_segment with basic input\");\n+\tTEST(t_suggest_compaction_segment_nothing(), \"suggest_compaction_segment with pre-compacted input\");\n+\n+\treturn test_done();\n }\n-- \n2.45.GIT\n\n"},{"id":"502400","messageId":"20240908041632.4948-3-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240908041632.4948-1-chandrapratap3519@gmail.com","subject":"[PATCH v6 2/6] t: harmonize t-reftable-stack.c with coding guidelines","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-08T04:05:57Z","receivedAt":"2024-09-08T04:18:12Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"Harmonize the newly ported test unit-tests/t-reftable-stack.c\nwith the following guidelines:\n- Single line 'for' statements must omit curly braces.\n- Structs must be 0-initialized with '= { 0 }' instead of '= { NULL }'.\n- Array sizes and indices should preferably be of type 'size_t' and\n  not 'int'.\n- Function pointers should be passed as 'func' and not '&func'.\n\nWhile at it, remove initialization for those variables that are\nre-used multiple times, like loop variables.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 110 +++++++++++++++-----------------\n 1 file changed, 53 insertions(+), 57 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex de28fac466..c74660a1e2 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -81,7 +81,6 @@ static void t_read_file(void)\n \tint n, err;\n \tchar **names = NULL;\n \tconst char *want[] = { \"line1\", \"line2\", \"line3\" };\n-\tint i = 0;\n \n \tcheck_int(fd, >, 0);\n \tn = write_in_full(fd, out, strlen(out));\n@@ -92,9 +91,8 @@ static void t_read_file(void)\n \terr = read_lines(fn, &names);\n \tcheck(!err);\n \n-\tfor (i = 0; names[i]; i++) {\n+\tfor (size_t i = 0; names[i]; i++)\n \t\tcheck_str(want[i], names[i]);\n-\t}\n \tfree_names(names);\n \t(void) remove(fn);\n }\n@@ -123,7 +121,7 @@ static void write_n_ref_tables(struct reftable_stack *st,\n \t\t};\n \n \t\tstrbuf_reset(&buf);\n-\t\tstrbuf_addf(&buf, \"refs/heads/branch-%04u\", (unsigned) i);\n+\t\tstrbuf_addf(&buf, \"refs/heads/branch-%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = buf.buf;\n \t\tset_test_hash(ref.value.val1, i);\n \n@@ -164,12 +162,12 @@ static void t_reftable_stack_add_one(void)\n \t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t.value.symref = (char *) \"master\",\n \t};\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \tstruct stat stat_result = { 0 };\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\terr = reftable_stack_add(st, write_test_ref, &ref);\n \tcheck(!err);\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n@@ -234,16 +232,16 @@ static void t_reftable_stack_uptodate(void)\n \terr = reftable_new_stack(&st2, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st1, &write_test_ref, &ref1);\n+\terr = reftable_stack_add(st1, write_test_ref, &ref1);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st2, write_test_ref, &ref2);\n \tcheck_int(err, ==, REFTABLE_OUTDATED_ERROR);\n \n \terr = reftable_stack_reload(st2);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st2, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st2, write_test_ref, &ref2);\n \tcheck(!err);\n \treftable_stack_destroy(st1);\n \treftable_stack_destroy(st2);\n@@ -264,7 +262,7 @@ static void t_reftable_stack_transaction_api(void)\n \t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t.value.symref = (char *) \"master\",\n \t};\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -274,7 +272,7 @@ static void t_reftable_stack_transaction_api(void)\n \terr = reftable_stack_new_addition(&add, st);\n \tcheck(!err);\n \n-\terr = reftable_addition_add(add, &write_test_ref, &ref);\n+\terr = reftable_addition_add(add, write_test_ref, &ref);\n \tcheck(!err);\n \n \terr = reftable_addition_commit(add);\n@@ -298,12 +296,13 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \tstruct reftable_write_options opts = {0};\n \tstruct reftable_addition *add = NULL;\n \tstruct reftable_stack *st = NULL;\n-\tint i, n = 20, err;\n+\tsize_t n = 20;\n+\tint err;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\tfor (i = 0; i <= n; i++) {\n+\tfor (size_t i = 0; i <= n; i++) {\n \t\tstruct reftable_ref_record ref = {\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t\t.value_type = REFTABLE_REF_SYMREF,\n@@ -311,7 +310,7 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\t};\n \t\tchar name[100];\n \n-\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = name;\n \n \t\t/*\n@@ -324,7 +323,7 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)\n \t\terr = reftable_stack_new_addition(&add, st);\n \t\tcheck(!err);\n \n-\t\terr = reftable_addition_add(add, &write_test_ref, &ref);\n+\t\terr = reftable_addition_add(add, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\terr = reftable_addition_commit(add);\n@@ -355,7 +354,7 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void)\n \t\t.value_type = REFTABLE_REF_VAL1,\n \t\t.value.val1 = {0x01},\n \t};\n-\tstruct reftable_write_options opts = {0};\n+\tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st;\n \tstruct strbuf table_path = STRBUF_INIT;\n \tchar *dir = get_tmp_dir(__LINE__);\n@@ -417,10 +416,10 @@ static void t_reftable_stack_update_index_check(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref1);\n+\terr = reftable_stack_add(st, write_test_ref, &ref1);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref2);\n+\terr = reftable_stack_add(st, write_test_ref, &ref2);\n \tcheck_int(err, ==, REFTABLE_API_ERROR);\n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n@@ -436,7 +435,7 @@ static void t_reftable_stack_lock_failure(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \tfor (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) {\n-\t\terr = reftable_stack_add(st, &write_error, &i);\n+\t\terr = reftable_stack_add(st, write_error, &i);\n \t\tcheck_int(err, ==, i);\n \t}\n \n@@ -446,7 +445,6 @@ static void t_reftable_stack_lock_failure(void)\n \n static void t_reftable_stack_add(void)\n {\n-\tint i = 0;\n \tint err = 0;\n \tstruct reftable_write_options opts = {\n \t\t.exact_log_message = 1,\n@@ -455,18 +453,18 @@ static void t_reftable_stack_add(void)\n \t};\n \tstruct reftable_stack *st = NULL;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tstruct reftable_ref_record refs[2] = { { NULL } };\n-\tstruct reftable_log_record logs[2] = { { NULL } };\n+\tstruct reftable_ref_record refs[2] = { 0 };\n+\tstruct reftable_log_record logs[2] = { 0 };\n \tstruct strbuf path = STRBUF_INIT;\n \tstruct stat stat_result;\n-\tint N = ARRAY_SIZE(refs);\n+\tsize_t i, N = ARRAY_SIZE(refs);\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n \t\tchar buf[256];\n-\t\tsnprintf(buf, sizeof(buf), \"branch%02d\", i);\n+\t\tsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n \t\trefs[i].refname = xstrdup(buf);\n \t\trefs[i].update_index = i + 1;\n \t\trefs[i].value_type = REFTABLE_REF_VAL1;\n@@ -480,7 +478,7 @@ static void t_reftable_stack_add(void)\n \t}\n \n \tfor (i = 0; i < N; i++) {\n-\t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n+\t\tint err = reftable_stack_add(st, write_test_ref, &refs[i]);\n \t\tcheck(!err);\n \t}\n \n@@ -489,7 +487,7 @@ static void t_reftable_stack_add(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -497,7 +495,7 @@ static void t_reftable_stack_add(void)\n \tcheck(!err);\n \n \tfor (i = 0; i < N; i++) {\n-\t\tstruct reftable_ref_record dest = { NULL };\n+\t\tstruct reftable_ref_record dest = { 0 };\n \n \t\tint err = reftable_stack_read_ref(st, refs[i].refname, &dest);\n \t\tcheck(!err);\n@@ -507,7 +505,7 @@ static void t_reftable_stack_add(void)\n \t}\n \n \tfor (i = 0; i < N; i++) {\n-\t\tstruct reftable_log_record dest = { NULL };\n+\t\tstruct reftable_log_record dest = { 0 };\n \t\tint err = reftable_stack_read_log(st, refs[i].refname, &dest);\n \t\tcheck(!err);\n \t\tcheck(reftable_log_record_equal(&dest, logs + i,\n@@ -575,11 +573,11 @@ static void t_reftable_stack_log_normalize(void)\n \tcheck(!err);\n \n \tinput.value.update.message = (char *) \"one\\ntwo\";\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck_int(err, ==, REFTABLE_API_ERROR);\n \n \tinput.value.update.message = (char *) \"one\";\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck(!err);\n \n \terr = reftable_stack_read_log(st, input.refname, &dest);\n@@ -588,7 +586,7 @@ static void t_reftable_stack_log_normalize(void)\n \n \tinput.value.update.message = (char *) \"two\\n\";\n \targ.update_index = 2;\n-\terr = reftable_stack_add(st, &write_test_log, &arg);\n+\terr = reftable_stack_add(st, write_test_log, &arg);\n \tcheck(!err);\n \terr = reftable_stack_read_log(st, input.refname, &dest);\n \tcheck(!err);\n@@ -602,16 +600,15 @@ static void t_reftable_stack_log_normalize(void)\n \n static void t_reftable_stack_tombstone(void)\n {\n-\tint i = 0;\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n \tint err;\n-\tstruct reftable_ref_record refs[2] = { { NULL } };\n-\tstruct reftable_log_record logs[2] = { { NULL } };\n-\tint N = ARRAY_SIZE(refs);\n-\tstruct reftable_ref_record dest = { NULL };\n-\tstruct reftable_log_record log_dest = { NULL };\n+\tstruct reftable_ref_record refs[2] = { 0 };\n+\tstruct reftable_log_record logs[2] = { 0 };\n+\tsize_t i, N = ARRAY_SIZE(refs);\n+\tstruct reftable_ref_record dest = { 0 };\n+\tstruct reftable_log_record log_dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -637,7 +634,7 @@ static void t_reftable_stack_tombstone(void)\n \t\t}\n \t}\n \tfor (i = 0; i < N; i++) {\n-\t\tint err = reftable_stack_add(st, &write_test_ref, &refs[i]);\n+\t\tint err = reftable_stack_add(st, write_test_ref, &refs[i]);\n \t\tcheck(!err);\n \t}\n \n@@ -646,7 +643,7 @@ static void t_reftable_stack_tombstone(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -695,12 +692,12 @@ static void t_reftable_stack_hash_id(void)\n \tstruct reftable_stack *st32 = NULL;\n \tstruct reftable_write_options opts_default = { 0 };\n \tstruct reftable_stack *st_default = NULL;\n-\tstruct reftable_ref_record dest = { NULL };\n+\tstruct reftable_ref_record dest = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\terr = reftable_stack_add(st, write_test_ref, &ref);\n \tcheck(!err);\n \n \t/* can't read it with the wrong hash ID. */\n@@ -743,21 +740,20 @@ static void t_reflog_expire(void)\n \tchar *dir = get_tmp_dir(__LINE__);\n \tstruct reftable_write_options opts = { 0 };\n \tstruct reftable_stack *st = NULL;\n-\tstruct reftable_log_record logs[20] = { { NULL } };\n-\tint N = ARRAY_SIZE(logs) - 1;\n-\tint i = 0;\n+\tstruct reftable_log_record logs[20] = { 0 };\n+\tsize_t i, N = ARRAY_SIZE(logs) - 1;\n \tint err;\n \tstruct reftable_log_expiry_config expiry = {\n \t\t.time = 10,\n \t};\n-\tstruct reftable_log_record log = { NULL };\n+\tstruct reftable_log_record log = { 0 };\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n \tfor (i = 1; i <= N; i++) {\n \t\tchar buf[256];\n-\t\tsnprintf(buf, sizeof(buf), \"branch%02d\", i);\n+\t\tsnprintf(buf, sizeof(buf), \"branch%02\"PRIuMAX, (uintmax_t)i);\n \n \t\tlogs[i].refname = xstrdup(buf);\n \t\tlogs[i].update_index = i;\n@@ -772,7 +768,7 @@ static void t_reflog_expire(void)\n \t\t\t.log = &logs[i],\n \t\t\t.update_index = reftable_stack_next_update_index(st),\n \t\t};\n-\t\tint err = reftable_stack_add(st, &write_test_log, &arg);\n+\t\tint err = reftable_stack_add(st, write_test_log, &arg);\n \t\tcheck(!err);\n \t}\n \n@@ -800,9 +796,8 @@ static void t_reflog_expire(void)\n \n \t/* cleanup */\n \treftable_stack_destroy(st);\n-\tfor (i = 0; i <= N; i++) {\n+\tfor (i = 0; i <= N; i++)\n \t\treftable_log_record_release(&logs[i]);\n-\t}\n \tclear_dir(dir);\n \treftable_log_record_release(&log);\n }\n@@ -824,7 +819,7 @@ static void t_empty_add(void)\n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n \n-\terr = reftable_stack_add(st, &write_nothing, NULL);\n+\terr = reftable_stack_add(st, write_nothing, NULL);\n \tcheck(!err);\n \n \terr = reftable_new_stack(&st2, dir, &opts);\n@@ -851,8 +846,8 @@ static void t_reftable_stack_auto_compaction(void)\n \t};\n \tstruct reftable_stack *st = NULL;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tint err, i;\n-\tint N = 100;\n+\tint err;\n+\tsize_t i, N = 100;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -865,9 +860,9 @@ static void t_reftable_stack_auto_compaction(void)\n \t\t\t.value_type = REFTABLE_REF_SYMREF,\n \t\t\t.value.symref = (char *) \"master\",\n \t\t};\n-\t\tsnprintf(name, sizeof(name), \"branch%04d\", i);\n+\t\tsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n \n-\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\terr = reftable_stack_add(st, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\terr = reftable_stack_auto_compact(st);\n@@ -929,7 +924,8 @@ static void t_reftable_stack_add_performs_auto_compaction(void)\n \tstruct reftable_stack *st = NULL;\n \tstruct strbuf refname = STRBUF_INIT;\n \tchar *dir = get_tmp_dir(__LINE__);\n-\tint err, i, n = 20;\n+\tint err;\n+\tsize_t i, n = 20;\n \n \terr = reftable_new_stack(&st, dir, &opts);\n \tcheck(!err);\n@@ -949,10 +945,10 @@ static void t_reftable_stack_add_performs_auto_compaction(void)\n \t\tst->opts.disable_auto_compact = i != n;\n \n \t\tstrbuf_reset(&refname);\n-\t\tstrbuf_addf(&refname, \"branch-%04d\", i);\n+\t\tstrbuf_addf(&refname, \"branch-%04\"PRIuMAX, (uintmax_t)i);\n \t\tref.refname = refname.buf;\n \n-\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\terr = reftable_stack_add(st, write_test_ref, &ref);\n \t\tcheck(!err);\n \n \t\t/*\n-- \n2.45.GIT\n\n"},{"id":"502401","messageId":"20240908041632.4948-4-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240908041632.4948-1-chandrapratap3519@gmail.com","subject":"[PATCH v6 3/6] t-reftable-stack: use Git's tempfile API instead of mkstemp()","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-08T04:05:58Z","receivedAt":"2024-09-08T04:18:16Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"Git's tempfile API defined by $GIT_DIR/tempfile.{c,h} provides\na unified interface for tempfile operations. Since reftable/stack.c\nuses this API for all its tempfile needs instead of raw functions\nlike mkstemp(), make the ported stack test strictly use Git's\ntempfile API as well.\n\nA bigger benefit is the fact that we know to clean up the tempfile\nin case the test fails because it gets registered and pruned via a\nsignal handler.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex c74660a1e2..8047e25c48 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -76,7 +76,8 @@ static char *get_tmp_dir(int linenumber)\n static void t_read_file(void)\n {\n \tchar *fn = get_tmp_template(__LINE__);\n-\tint fd = mkstemp(fn);\n+\tstruct tempfile *tmp = mks_tempfile(fn);\n+\tint fd = get_tempfile_fd(tmp);\n \tchar out[1024] = \"line1\\n\\nline2\\nline3\";\n \tint n, err;\n \tchar **names = NULL;\n@@ -95,6 +96,7 @@ static void t_read_file(void)\n \t\tcheck_str(want[i], names[i]);\n \tfree_names(names);\n \t(void) remove(fn);\n+\tdelete_tempfile(&tmp);\n }\n \n static int write_test_ref(struct reftable_writer *wr, void *arg)\n-- \n2.45.GIT\n\n"},{"id":"502402","messageId":"20240908041632.4948-5-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240908041632.4948-1-chandrapratap3519@gmail.com","subject":"[PATCH v6 4/6] t-reftable-stack: use reftable_ref_record_equal() to compare ref records","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-08T04:05:59Z","receivedAt":"2024-09-08T04:18:19Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"In the current stack tests, ref records are compared for equality\nby sometimes using the dedicated function for ref-record comparison,\nreftable_ref_record_equal(), and sometimes by explicity comparing\ncontents of the ref records.\n\nThe latter method is undesired because there can exist unequal ref\nrecords with the some of the contents being equal. Replace the latter\ninstances of ref-record comparison with the former. This has the\nadded benefit of preserving uniformity throughout the test file.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 8047e25c48..4f2ef1a8cc 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -174,7 +174,7 @@ static void t_reftable_stack_add_one(void)\n \n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n \tcheck(!err);\n-\tcheck_str(\"master\", dest.value.symref);\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \tcheck_int(st->readers_len, >, 0);\n \n #ifndef GIT_WINDOWS_NATIVE\n@@ -285,7 +285,7 @@ static void t_reftable_stack_transaction_api(void)\n \terr = reftable_stack_read_ref(st, ref.refname, &dest);\n \tcheck(!err);\n \tcheck_int(REFTABLE_REF_SYMREF, ==, dest.value_type);\n-\tcheck_str(\"master\", dest.value.symref);\n+\tcheck(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));\n \n \treftable_ref_record_release(&dest);\n \treftable_stack_destroy(st);\n-- \n2.45.GIT\n\n"},{"id":"502403","messageId":"20240908041632.4948-6-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240908041632.4948-1-chandrapratap3519@gmail.com","subject":"[PATCH v6 5/6] t-reftable-stack: add test for non-default compaction factor","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-08T04:06:00Z","receivedAt":"2024-09-08T04:18:21Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"In a recent codebase update (commit ae8e378430, merge branch\n'ps/reftable-write-options', 2024/05/13) the geometric factor used\nin auto-compaction of reftable tables was made configurable. Add\na test to verify the functionality introduced by this update.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 41 +++++++++++++++++++++++++++++----\n 1 file changed, 37 insertions(+), 4 deletions(-)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 4f2ef1a8cc..4acf07ab0c 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -831,12 +831,12 @@ static void t_empty_add(void)\n \treftable_stack_destroy(st2);\n }\n \n-static int fastlog2(uint64_t sz)\n+static int fastlogN(uint64_t sz, uint64_t N)\n {\n \tint l = 0;\n \tif (sz == 0)\n \t\treturn 0;\n-\tfor (; sz; sz /= 2)\n+\tfor (; sz; sz /= N)\n \t\tl++;\n \treturn l - 1;\n }\n@@ -869,11 +869,43 @@ static void t_reftable_stack_auto_compaction(void)\n \n \t\terr = reftable_stack_auto_compact(st);\n \t\tcheck(!err);\n-\t\tcheck(i < 3 || st->merged->readers_len < 2 * fastlog2(i));\n+\t\tcheck(i < 2 || st->merged->readers_len < 2 * fastlogN(i, 2));\n \t}\n \n \tcheck_int(reftable_stack_compaction_stats(st)->entries_written, <,\n-\t       (uint64_t)(N * fastlog2(N)));\n+\t       (uint64_t)(N * fastlogN(N, 2)));\n+\n+\treftable_stack_destroy(st);\n+\tclear_dir(dir);\n+}\n+\n+static void t_reftable_stack_auto_compaction_factor(void)\n+{\n+\tstruct reftable_write_options opts = {\n+\t\t.auto_compaction_factor = 5,\n+\t};\n+\tstruct reftable_stack *st = NULL;\n+\tchar *dir = get_tmp_dir(__LINE__);\n+\tint err;\n+\tsize_t N = 100;\n+\n+\terr = reftable_new_stack(&st, dir, &opts);\n+\tcheck(!err);\n+\n+\tfor (size_t i = 0; i < N; i++) {\n+\t\tchar name[20];\n+\t\tstruct reftable_ref_record ref = {\n+\t\t\t.refname = name,\n+\t\t\t.update_index = reftable_stack_next_update_index(st),\n+\t\t\t.value_type = REFTABLE_REF_VAL1,\n+\t\t};\n+\t\txsnprintf(name, sizeof(name), \"branch%04\"PRIuMAX, (uintmax_t)i);\n+\n+\t\terr = reftable_stack_add(st, &write_test_ref, &ref);\n+\t\tcheck(!err);\n+\n+\t\tcheck(i < 5 || st->merged->readers_len < 5 * fastlogN(i, 5));\n+\t}\n \n \treftable_stack_destroy(st);\n \tclear_dir(dir);\n@@ -1186,6 +1218,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)\n \tTEST(t_reftable_stack_add_one(), \"add a single ref record to stack\");\n \tTEST(t_reftable_stack_add_performs_auto_compaction(), \"addition to stack triggers auto-compaction\");\n \tTEST(t_reftable_stack_auto_compaction(), \"stack must form geometric sequence after compaction\");\n+\tTEST(t_reftable_stack_auto_compaction_factor(), \"auto-compaction with non-default geometric factor\");\n \tTEST(t_reftable_stack_auto_compaction_fails_gracefully(), \"failure on auto-compaction\");\n \tTEST(t_reftable_stack_auto_compaction_with_locked_tables(), \"auto compaction with locked tables\");\n \tTEST(t_reftable_stack_compaction_concurrent(), \"compaction with concurrent stack\");\n-- \n2.45.GIT\n\n"},{"id":"502404","messageId":"20240908041632.4948-7-chandrapratap3519@gmail.com","threadId":"61911","inReplyTo":"20240908041632.4948-1-chandrapratap3519@gmail.com","subject":"[PATCH v6 6/6] t-reftable-stack: add test for stack iterators","fromName":"Chandra Pratap","fromEmail":"chandrapratap3519@gmail.com","sentAt":"2024-09-08T04:06:01Z","receivedAt":"2024-09-08T04:18:24Z","isPatch":true,"sender":{"key":"chandrapratap3519@gmail.com","avatar":null},"body":"reftable_stack_init_ref_iterator and reftable_stack_init_log_iterator\nas defined by reftable/stack.{c,h} initialize a stack iterator to\niterate over the ref and log records in a reftable stack respectively.\nSince these functions are not exercised by any of the existing tests,\nadd a test for them.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n---\n t/unit-tests/t-reftable-stack.c | 83 +++++++++++++++++++++++++++++++++\n 1 file changed, 83 insertions(+)\n\ndiff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c\nindex 4acf07ab0c..d62a9c1bed 100644\n--- a/t/unit-tests/t-reftable-stack.c\n+++ b/t/unit-tests/t-reftable-stack.c\n@@ -544,6 +544,88 @@ static void t_reftable_stack_add(void)\n \tclear_dir(dir);\n }\n \n+static void t_reftable_stack_iterator(void)\n+{\n+\tstruct reftable_write_options opts = { 0 };\n+\tstruct reftable_stack *st = NULL;\n+\tchar *dir = get_tmp_dir(__LINE__);\n+\tstruct reftable_ref_record refs[10] = { 0 };\n+\tstruct reftable_log_record logs[10] = { 0 };\n+\tstruct reftable_iterator it = { 0 };\n+\tsize_t N = ARRAY_SIZE(refs), i;\n+\tint err;\n+\n+\terr = reftable_new_stack(&st, dir, &opts);\n+\tcheck(!err);\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\trefs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n+\t\trefs[i].update_index = i + 1;\n+\t\trefs[i].value_type = REFTABLE_REF_VAL1;\n+\t\tset_test_hash(refs[i].value.val1, i);\n+\n+\t\tlogs[i].refname = xstrfmt(\"branch%02\"PRIuMAX, (uintmax_t)i);\n+\t\tlogs[i].update_index = i + 1;\n+\t\tlogs[i].value_type = REFTABLE_LOG_UPDATE;\n+\t\tlogs[i].value.update.email = xstrdup(\"johndoe@invalid\");\n+\t\tlogs[i].value.update.message = xstrdup(\"commit\\n\");\n+\t\tset_test_hash(logs[i].value.update.new_hash, i);\n+\t}\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\terr = reftable_stack_add(st, write_test_ref, &refs[i]);\n+\t\tcheck(!err);\n+\t}\n+\n+\tfor (i = 0; i < N; i++) {\n+\t\tstruct write_log_arg arg = {\n+\t\t\t.log = &logs[i],\n+\t\t\t.update_index = reftable_stack_next_update_index(st),\n+\t\t};\n+\n+\t\terr = reftable_stack_add(st, write_test_log, &arg);\n+\t\tcheck(!err);\n+\t}\n+\n+\treftable_stack_init_ref_iterator(st, &it);\n+\treftable_iterator_seek_ref(&it, refs[0].refname);\n+\tfor (i = 0; ; i++) {\n+\t\tstruct reftable_ref_record ref = { 0 };\n+\n+\t\terr = reftable_iterator_next_ref(&it, &ref);\n+\t\tif (err > 0)\n+\t\t\tbreak;\n+\t\tcheck(!err);\n+\t\tcheck(reftable_ref_record_equal(&ref, &refs[i], GIT_SHA1_RAWSZ));\n+\t\treftable_ref_record_release(&ref);\n+\t}\n+\tcheck_int(i, ==, N);\n+\n+\treftable_iterator_destroy(&it);\n+\n+\treftable_stack_init_log_iterator(st, &it);\n+\treftable_iterator_seek_log(&it, logs[0].refname);\n+\tfor (i = 0; ; i++) {\n+\t\tstruct reftable_log_record log = { 0 };\n+\n+\t\terr = reftable_iterator_next_log(&it, &log);\n+\t\tif (err > 0)\n+\t\t\tbreak;\n+\t\tcheck(!err);\n+\t\tcheck(reftable_log_record_equal(&log, &logs[i], GIT_SHA1_RAWSZ));\n+\t\treftable_log_record_release(&log);\n+\t}\n+\tcheck_int(i, ==, N);\n+\n+\treftable_stack_destroy(st);\n+\treftable_iterator_destroy(&it);\n+\tfor (i = 0; i < N; i++) {\n+\t\treftable_ref_record_release(&refs[i]);\n+\t\treftable_log_record_release(&logs[i]);\n+\t}\n+\tclear_dir(dir);\n+}\n+\n static void t_reftable_stack_log_normalize(void)\n {\n \tint err = 0;\n@@ -1225,6 +1307,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)\n \tTEST(t_reftable_stack_compaction_concurrent_clean(), \"compaction with unclean stack shutdown\");\n \tTEST(t_reftable_stack_compaction_with_locked_tables(), \"compaction with locked tables\");\n \tTEST(t_reftable_stack_hash_id(), \"read stack with wrong hash ID\");\n+\tTEST(t_reftable_stack_iterator(), \"log and ref iterator for reftable stack\");\n \tTEST(t_reftable_stack_lock_failure(), \"stack addition with lockfile failure\");\n \tTEST(t_reftable_stack_log_normalize(), \"log messages should be normalized\");\n \tTEST(t_reftable_stack_read_across_reload(), \"stack iterators work across reloads\");\n-- \n2.45.GIT\n\n"},{"id":"502439","messageId":"Zt7fDSjqqKMW2lKG@pks.im","threadId":"61911","inReplyTo":"20240908041632.4948-5-chandrapratap3519@gmail.com","subject":"Re: [PATCH v6 4/6] t-reftable-stack: use reftable_ref_record_equal() to compare ref records","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-09-09T11:42:05Z","receivedAt":"2024-09-09T11:42:09Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Sun, Sep 08, 2024 at 09:35:59AM +0530, Chandra Pratap wrote:\n> In the current stack tests, ref records are compared for equality\n> by sometimes using the dedicated function for ref-record comparison,\n> reftable_ref_record_equal(), and sometimes by explicity comparing\n> contents of the ref records.\n> \n> The latter method is undesired because there can exist unequal ref\n> records with the some of the contents being equal. Replace the latter\n\ns/the some/some\n\nNot worth a reroll, just pointing it out in case you end up rerolling\ndue to other issues.\n\nPatrick\n"},{"id":"502440","messageId":"Zt7fEKfqQdN-Mj_T@pks.im","threadId":"61911","inReplyTo":"20240908041632.4948-1-chandrapratap3519@gmail.com","subject":"Re: [GSoC][PATCH v6 0/6] t: port reftable/stack_test.c to the unit testing framework","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-09-09T11:42:08Z","receivedAt":"2024-09-09T11:42:11Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Sun, Sep 08, 2024 at 09:35:55AM +0530, Chandra Pratap wrote:\n> The reftable library comes with self tests, which are exercised\n> as part of the usual end-to-end tests and are designed to\n> observe the end-user visible effects of Git commands. What it\n> exercises, however, is a better match for the unit-testing\n> framework, merged at 8bf6fbd0 (Merge branch 'js/doc-unit-tests',\n> 2023-12-09), which is designed to observe how low level\n> implementation details, at the level of sequences of individual\n> function calls, behave.\n> \n> Hence, port reftable/stack_test.c to the unit testing framework and\n> improve upon the ported test. The first patch in the series moves\n> the test to the unit testing framework, and the rest of the patches\n> improve upon the ported test.\n> \n> Mentored-by: Patrick Steinhardt <ps@pks.im>\n> Mentored-by: Christian Couder <chriscool@tuxfamily.org>\n> Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com>\n\nThanks, this version looks good to me.\n\nPatrick\n"}]}