From 546cc0d64e3df8a012d785c6b423d03e16bfc0c5 Mon Sep 17 00:00:00 2001 From: Chandra Pratap Date: Wed, 21 Aug 2024 18:00:51 +0530 Subject: [PATCH 01/12] t: move reftable/block_test.c to the unit testing framework reftable/block_test.c exercises the functions defined in reftable/block.{c, h}. Migrate reftable/block_test.c to the unit testing framework. Migration involves refactoring the tests to use the unit testing framework instead of reftable's test framework and renaming the tests to follow the unit-tests' naming conventions. Mentored-by: Patrick Steinhardt Mentored-by: Christian Couder Signed-off-by: Chandra Pratap Signed-off-by: Junio C Hamano --- Makefile | 2 +- reftable/reftable-tests.h | 1 - t/helper/test-reftable.c | 1 - .../unit-tests/t-reftable-block.c | 45 +++++++++---------- 4 files changed, 22 insertions(+), 27 deletions(-) rename reftable/block_test.c => t/unit-tests/t-reftable-block.c (76%) diff --git a/Makefile b/Makefile index a87e18b317..4c94bc718f 100644 --- a/Makefile +++ b/Makefile @@ -1341,6 +1341,7 @@ UNIT_TEST_PROGRAMS += t-oidmap UNIT_TEST_PROGRAMS += t-oidtree UNIT_TEST_PROGRAMS += t-prio-queue UNIT_TEST_PROGRAMS += t-reftable-basics +UNIT_TEST_PROGRAMS += t-reftable-block UNIT_TEST_PROGRAMS += t-reftable-merged UNIT_TEST_PROGRAMS += t-reftable-pq UNIT_TEST_PROGRAMS += t-reftable-record @@ -2682,7 +2683,6 @@ REFTABLE_OBJS += reftable/stack.o REFTABLE_OBJS += reftable/tree.o REFTABLE_OBJS += reftable/writer.o -REFTABLE_TEST_OBJS += reftable/block_test.o REFTABLE_TEST_OBJS += reftable/dump.o REFTABLE_TEST_OBJS += reftable/readwrite_test.o REFTABLE_TEST_OBJS += reftable/stack_test.o diff --git a/reftable/reftable-tests.h b/reftable/reftable-tests.h index 4b666810af..3d9118b91b 100644 --- a/reftable/reftable-tests.h +++ b/reftable/reftable-tests.h @@ -10,7 +10,6 @@ https://developers.google.com/open-source/licenses/bsd #define REFTABLE_TESTS_H int basics_test_main(int argc, const char **argv); -int block_test_main(int argc, const char **argv); int record_test_main(int argc, const char **argv); int readwrite_test_main(int argc, const char **argv); int stack_test_main(int argc, const char **argv); diff --git a/t/helper/test-reftable.c b/t/helper/test-reftable.c index 623cf3f0f5..7bdd18430b 100644 --- a/t/helper/test-reftable.c +++ b/t/helper/test-reftable.c @@ -5,7 +5,6 @@ int cmd__reftable(int argc, const char **argv) { /* test from simple to complex. */ - block_test_main(argc, argv); readwrite_test_main(argc, argv); stack_test_main(argc, argv); return 0; diff --git a/reftable/block_test.c b/t/unit-tests/t-reftable-block.c similarity index 76% rename from reftable/block_test.c rename to t/unit-tests/t-reftable-block.c index 90aecd5a7c..f2b9a8a6f4 100644 --- a/reftable/block_test.c +++ b/t/unit-tests/t-reftable-block.c @@ -6,17 +6,13 @@ license that can be found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd */ -#include "block.h" +#include "test-lib.h" +#include "reftable/block.h" +#include "reftable/blocksource.h" +#include "reftable/constants.h" +#include "reftable/reftable-error.h" -#include "system.h" -#include "blocksource.h" -#include "basics.h" -#include "constants.h" -#include "record.h" -#include "test_framework.h" -#include "reftable-tests.h" - -static void test_block_read_write(void) +static void t_block_read_write(void) { const int header_off = 21; /* random */ char *names[30]; @@ -45,7 +41,7 @@ static void test_block_read_write(void) rec.u.ref.refname = (char *) ""; rec.u.ref.value_type = REFTABLE_REF_DELETION; n = block_writer_add(&bw, &rec); - EXPECT(n == REFTABLE_API_ERROR); + check_int(n, ==, REFTABLE_API_ERROR); for (i = 0; i < N; i++) { char name[100]; @@ -59,11 +55,11 @@ static void test_block_read_write(void) n = block_writer_add(&bw, &rec); rec.u.ref.refname = NULL; rec.u.ref.value_type = REFTABLE_REF_DELETION; - EXPECT(n == 0); + check_int(n, ==, 0); } n = block_writer_finish(&bw); - EXPECT(n > 0); + check_int(n, >, 0); block_writer_release(&bw); @@ -73,11 +69,11 @@ static void test_block_read_write(void) while (1) { int r = block_iter_next(&it, &rec); - EXPECT(r >= 0); + check_int(r, >=, 0); if (r > 0) { break; } - EXPECT_STREQ(names[j], rec.u.ref.refname); + check_str(names[j], rec.u.ref.refname); j++; } @@ -90,20 +86,20 @@ static void test_block_read_write(void) strbuf_addstr(&want, names[i]); n = block_iter_seek_key(&it, &br, &want); - EXPECT(n == 0); + check_int(n, ==, 0); n = block_iter_next(&it, &rec); - EXPECT(n == 0); + check_int(n, ==, 0); - EXPECT_STREQ(names[i], rec.u.ref.refname); + check_str(names[i], rec.u.ref.refname); want.len--; n = block_iter_seek_key(&it, &br, &want); - EXPECT(n == 0); + check_int(n, ==, 0); n = block_iter_next(&it, &rec); - EXPECT(n == 0); - EXPECT_STREQ(names[10 * (i / 10)], rec.u.ref.refname); + check_int(n, ==, 0); + check_str(names[10 * (i / 10)], rec.u.ref.refname); block_iter_close(&it); } @@ -116,8 +112,9 @@ static void test_block_read_write(void) } } -int block_test_main(int argc, const char *argv[]) +int cmd_main(int argc, const char *argv[]) { - RUN_TEST(test_block_read_write); - return 0; + TEST(t_block_read_write(), "read-write operations on blocks work"); + + return test_done(); } From 6853b931bd04d534c7e09073ab39f8192f0dd34e Mon Sep 17 00:00:00 2001 From: Chandra Pratap Date: Wed, 21 Aug 2024 18:00:52 +0530 Subject: [PATCH 02/12] t: harmonize t-reftable-block.c with coding guidelines Harmonize the newly ported test unit-tests/t-reftable-block.c with the following guidelines: - Single line 'for' statements must omit curly braces. - Structs must be 0-initialized with '= { 0 }' instead of '= { NULL }'. - Array sizes and indices should preferably be of type 'size_t'and not 'int'. - Return code variable should preferably be named 'ret', not 'n'. Mentored-by: Patrick Steinhardt Mentored-by: Christian Couder Signed-off-by: Chandra Pratap Signed-off-by: Junio C Hamano --- t/unit-tests/t-reftable-block.c | 52 ++++++++++++++++----------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c index f2b9a8a6f4..b1b238ac2a 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/t-reftable-block.c @@ -16,20 +16,20 @@ static void t_block_read_write(void) { const int header_off = 21; /* random */ char *names[30]; - const int N = ARRAY_SIZE(names); - const int block_size = 1024; - struct reftable_block block = { NULL }; + const size_t N = ARRAY_SIZE(names); + const size_t block_size = 1024; + struct reftable_block block = { 0 }; struct block_writer bw = { .last_key = STRBUF_INIT, }; struct reftable_record rec = { .type = BLOCK_TYPE_REF, }; - int i = 0; - int n; + size_t i = 0; + int ret; struct block_reader br = { 0 }; struct block_iter it = BLOCK_ITER_INIT; - int j = 0; + size_t j = 0; struct strbuf want = STRBUF_INIT; REFTABLE_CALLOC_ARRAY(block.data, block_size); @@ -40,26 +40,26 @@ static void t_block_read_write(void) rec.u.ref.refname = (char *) ""; rec.u.ref.value_type = REFTABLE_REF_DELETION; - n = block_writer_add(&bw, &rec); - check_int(n, ==, REFTABLE_API_ERROR); + ret = block_writer_add(&bw, &rec); + check_int(ret, ==, REFTABLE_API_ERROR); for (i = 0; i < N; i++) { char name[100]; - snprintf(name, sizeof(name), "branch%02d", i); + snprintf(name, sizeof(name), "branch%02"PRIuMAX, (uintmax_t)i); rec.u.ref.refname = name; rec.u.ref.value_type = REFTABLE_REF_VAL1; memset(rec.u.ref.value.val1, i, GIT_SHA1_RAWSZ); names[i] = xstrdup(name); - n = block_writer_add(&bw, &rec); + ret = block_writer_add(&bw, &rec); rec.u.ref.refname = NULL; rec.u.ref.value_type = REFTABLE_REF_DELETION; - check_int(n, ==, 0); + check_int(ret, ==, 0); } - n = block_writer_finish(&bw); - check_int(n, >, 0); + ret = block_writer_finish(&bw); + check_int(ret, >, 0); block_writer_release(&bw); @@ -68,9 +68,10 @@ static void t_block_read_write(void) block_iter_seek_start(&it, &br); while (1) { - int r = block_iter_next(&it, &rec); - check_int(r, >=, 0); - if (r > 0) { + ret = block_iter_next(&it, &rec); + check_int(ret, >=, 0); + if (ret > 0) { + check_int(i, ==, N); break; } check_str(names[j], rec.u.ref.refname); @@ -85,20 +86,20 @@ static void t_block_read_write(void) strbuf_reset(&want); strbuf_addstr(&want, names[i]); - n = block_iter_seek_key(&it, &br, &want); - check_int(n, ==, 0); + ret = block_iter_seek_key(&it, &br, &want); + check_int(ret, ==, 0); - n = block_iter_next(&it, &rec); - check_int(n, ==, 0); + ret = block_iter_next(&it, &rec); + check_int(ret, ==, 0); check_str(names[i], rec.u.ref.refname); want.len--; - n = block_iter_seek_key(&it, &br, &want); - check_int(n, ==, 0); + ret = block_iter_seek_key(&it, &br, &want); + check_int(ret, ==, 0); - n = block_iter_next(&it, &rec); - check_int(n, ==, 0); + ret = block_iter_next(&it, &rec); + check_int(ret, ==, 0); check_str(names[10 * (i / 10)], rec.u.ref.refname); block_iter_close(&it); @@ -107,9 +108,8 @@ static void t_block_read_write(void) reftable_record_release(&rec); reftable_block_done(&br.block); strbuf_release(&want); - for (i = 0; i < N; i++) { + for (i = 0; i < N; i++) reftable_free(names[i]); - } } int cmd_main(int argc, const char *argv[]) From 353672f9f894294d10c85f082f53d591f438e209 Mon Sep 17 00:00:00 2001 From: Chandra Pratap Date: Wed, 21 Aug 2024 18:00:53 +0530 Subject: [PATCH 03/12] t-reftable-block: release used block reader Used block readers must be released using block_reader_release() to prevent the occurence of a memory leak. Make test_block_read_write() conform to this statement. Mentored-by: Patrick Steinhardt Mentored-by: Christian Couder Signed-off-by: Chandra Pratap Signed-off-by: Junio C Hamano --- t/unit-tests/t-reftable-block.c | 1 + 1 file changed, 1 insertion(+) diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c index b1b238ac2a..eafe1fdee9 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/t-reftable-block.c @@ -105,6 +105,7 @@ static void t_block_read_write(void) block_iter_close(&it); } + block_reader_release(&br); reftable_record_release(&rec); reftable_block_done(&br.block); strbuf_release(&want); From e638e9c8f3c3e7173e53d50d6d2b06a5f8f02ed8 Mon Sep 17 00:00:00 2001 From: Chandra Pratap Date: Wed, 21 Aug 2024 18:00:54 +0530 Subject: [PATCH 04/12] t-reftable-block: use reftable_record_equal() instead of check_str() In the current testing setup, operations like read and write for reftable blocks as defined by reftable/block.{c, h} are verified by comparing only the keys of input and output reftable records. This is not ideal because there can exist inequal reftable records with the same key. Use the dedicated function for record comparison, reftable_record_equal(), instead of key-based comparison. Mentored-by: Patrick Steinhardt Mentored-by: Christian Couder Signed-off-by: Chandra Pratap Signed-off-by: Junio C Hamano --- t/unit-tests/t-reftable-block.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c index eafe1fdee9..b106d3c1e4 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/t-reftable-block.c @@ -15,8 +15,8 @@ https://developers.google.com/open-source/licenses/bsd static void t_block_read_write(void) { const int header_off = 21; /* random */ - char *names[30]; - const size_t N = ARRAY_SIZE(names); + struct reftable_record recs[30]; + const size_t N = ARRAY_SIZE(recs); const size_t block_size = 1024; struct reftable_block block = { 0 }; struct block_writer bw = { @@ -47,11 +47,11 @@ static void t_block_read_write(void) char name[100]; snprintf(name, sizeof(name), "branch%02"PRIuMAX, (uintmax_t)i); - rec.u.ref.refname = name; + rec.u.ref.refname = xstrdup(name); rec.u.ref.value_type = REFTABLE_REF_VAL1; memset(rec.u.ref.value.val1, i, GIT_SHA1_RAWSZ); - names[i] = xstrdup(name); + recs[i] = rec; ret = block_writer_add(&bw, &rec); rec.u.ref.refname = NULL; rec.u.ref.value_type = REFTABLE_REF_DELETION; @@ -74,7 +74,7 @@ static void t_block_read_write(void) check_int(i, ==, N); break; } - check_str(names[j], rec.u.ref.refname); + check(reftable_record_equal(&recs[j], &rec, GIT_SHA1_RAWSZ)); j++; } @@ -84,7 +84,7 @@ static void t_block_read_write(void) for (i = 0; i < N; i++) { struct block_iter it = BLOCK_ITER_INIT; strbuf_reset(&want); - strbuf_addstr(&want, names[i]); + strbuf_addstr(&want, recs[i].u.ref.refname); ret = block_iter_seek_key(&it, &br, &want); check_int(ret, ==, 0); @@ -92,7 +92,7 @@ static void t_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check_str(names[i], rec.u.ref.refname); + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); want.len--; ret = block_iter_seek_key(&it, &br, &want); @@ -100,7 +100,7 @@ static void t_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check_str(names[10 * (i / 10)], rec.u.ref.refname); + check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ)); block_iter_close(&it); } @@ -110,7 +110,7 @@ static void t_block_read_write(void) reftable_block_done(&br.block); strbuf_release(&want); for (i = 0; i < N; i++) - reftable_free(names[i]); + reftable_record_release(&recs[i]); } int cmd_main(int argc, const char *argv[]) From c25cbcd352c5831a1270b57104ecb6c0e6789a0c Mon Sep 17 00:00:00 2001 From: Chandra Pratap Date: Wed, 21 Aug 2024 18:00:55 +0530 Subject: [PATCH 05/12] t-reftable-block: use reftable_record_key() instead of strbuf_addstr() In the current testing setup, the record key required for many block iterator functions is manually stored in a strbuf struct and then passed to these functions. This is not ideal when there exists a dedicated function to encode a record's key into a strbuf, namely reftable_record_key(). Use this function instead of manual encoding. Mentored-by: Patrick Steinhardt Mentored-by: Christian Couder Signed-off-by: Chandra Pratap Signed-off-by: Junio C Hamano --- t/unit-tests/t-reftable-block.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c index b106d3c1e4..5887e9205d 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/t-reftable-block.c @@ -83,8 +83,7 @@ static void t_block_read_write(void) for (i = 0; i < N; i++) { struct block_iter it = BLOCK_ITER_INIT; - strbuf_reset(&want); - strbuf_addstr(&want, recs[i].u.ref.refname); + reftable_record_key(&recs[i], &want); ret = block_iter_seek_key(&it, &br, &want); check_int(ret, ==, 0); From 31216ee28a452d39d9fba6cd72d8b072eab50af1 Mon Sep 17 00:00:00 2001 From: Chandra Pratap Date: Wed, 21 Aug 2024 18:00:56 +0530 Subject: [PATCH 06/12] t-reftable-block: use block_iter_reset() instead of block_iter_close() block_iter_reset() restores a block iterator to its state at the time of initialization without freeing any memory while block_iter_close() deallocates the memory for the iterator. In the current testing setup, a block iterator is allocated and deallocated for every iteration of a loop, which hurts performance. Improve upon this by using block_iter_reset() at the start of each iteration instead. This has the added benifit of testing block_iter_reset(), which currently remains untested. Similarly, remove reftable_record_release() for a reftable record that is still in use. Mentored-by: Patrick Steinhardt Mentored-by: Christian Couder Signed-off-by: Chandra Pratap Signed-off-by: Junio C Hamano --- t/unit-tests/t-reftable-block.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c index 5887e9205d..ad3d128ea7 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/t-reftable-block.c @@ -78,11 +78,8 @@ static void t_block_read_write(void) j++; } - reftable_record_release(&rec); - block_iter_close(&it); - for (i = 0; i < N; i++) { - struct block_iter it = BLOCK_ITER_INIT; + block_iter_reset(&it); reftable_record_key(&recs[i], &want); ret = block_iter_seek_key(&it, &br, &want); @@ -100,11 +97,10 @@ static void t_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ)); - - block_iter_close(&it); } block_reader_release(&br); + block_iter_close(&it); reftable_record_release(&rec); reftable_block_done(&br.block); strbuf_release(&want); From 29ee6d5a200e95df64d55a3e1fbbaa004f50c46c Mon Sep 17 00:00:00 2001 From: Chandra Pratap Date: Wed, 21 Aug 2024 18:00:57 +0530 Subject: [PATCH 07/12] t-reftable-block: use xstrfmt() instead of xstrdup() Use xstrfmt() to assign a formatted string to a ref record's refname instead of xstrdup(). This helps save the overhead of a local 'char' buffer as well as makes the test more compact. Mentored-by: Patrick Steinhardt Mentored-by: Christian Couder Signed-off-by: Chandra Pratap Signed-off-by: Junio C Hamano --- t/unit-tests/t-reftable-block.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c index ad3d128ea7..81484bc646 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/t-reftable-block.c @@ -44,10 +44,7 @@ static void t_block_read_write(void) check_int(ret, ==, REFTABLE_API_ERROR); for (i = 0; i < N; i++) { - char name[100]; - snprintf(name, sizeof(name), "branch%02"PRIuMAX, (uintmax_t)i); - - rec.u.ref.refname = xstrdup(name); + rec.u.ref.refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i); rec.u.ref.value_type = REFTABLE_REF_VAL1; memset(rec.u.ref.value.val1, i, GIT_SHA1_RAWSZ); From abcddcef3dec6dc898edd30bdc0b20cfde86acb4 Mon Sep 17 00:00:00 2001 From: Chandra Pratap Date: Wed, 21 Aug 2024 18:00:58 +0530 Subject: [PATCH 08/12] t-reftable-block: remove unnecessary variable 'j' Currently, there are two variables for array indices, 'i' and 'j'. The variable 'j' is used only once and can be easily replaced with 'i'. Get rid of 'j' and replace its occurence with 'i'. Mentored-by: Patrick Steinhardt Mentored-by: Christian Couder Signed-off-by: Chandra Pratap Signed-off-by: Junio C Hamano --- t/unit-tests/t-reftable-block.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c index 81484bc646..6aa86a3edf 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/t-reftable-block.c @@ -29,7 +29,6 @@ static void t_block_read_write(void) int ret; struct block_reader br = { 0 }; struct block_iter it = BLOCK_ITER_INIT; - size_t j = 0; struct strbuf want = STRBUF_INIT; REFTABLE_CALLOC_ARRAY(block.data, block_size); @@ -64,15 +63,14 @@ static void t_block_read_write(void) block_iter_seek_start(&it, &br); - while (1) { + for (i = 0; ; i++) { ret = block_iter_next(&it, &rec); check_int(ret, >=, 0); if (ret > 0) { check_int(i, ==, N); break; } - check(reftable_record_equal(&recs[j], &rec, GIT_SHA1_RAWSZ)); - j++; + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); } for (i = 0; i < N; i++) { From 5cba56173be39dd696a89fc9a65d0e5d969e459c Mon Sep 17 00:00:00 2001 From: Chandra Pratap Date: Wed, 21 Aug 2024 18:00:59 +0530 Subject: [PATCH 09/12] t-reftable-block: add tests for log blocks In the current testing setup, block operations are only exercised for ref blocks. Add another test that exercises these operations for log blocks as well. Mentored-by: Patrick Steinhardt Mentored-by: Christian Couder Signed-off-by: Chandra Pratap Signed-off-by: Junio C Hamano --- t/unit-tests/t-reftable-block.c | 93 ++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c index 6aa86a3edf..4c4fb39ab4 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/t-reftable-block.c @@ -12,7 +12,7 @@ https://developers.google.com/open-source/licenses/bsd #include "reftable/constants.h" #include "reftable/reftable-error.h" -static void t_block_read_write(void) +static void t_ref_block_read_write(void) { const int header_off = 21; /* random */ struct reftable_record recs[30]; @@ -103,9 +103,98 @@ static void t_block_read_write(void) reftable_record_release(&recs[i]); } +static void t_log_block_read_write(void) +{ + const int header_off = 21; + struct reftable_record recs[30]; + const size_t N = ARRAY_SIZE(recs); + const size_t block_size = 2048; + struct reftable_block block = { 0 }; + struct block_writer bw = { + .last_key = STRBUF_INIT, + }; + struct reftable_record rec = { + .type = BLOCK_TYPE_LOG, + }; + size_t i = 0; + int ret; + struct block_reader br = { 0 }; + struct block_iter it = BLOCK_ITER_INIT; + struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT; + + REFTABLE_CALLOC_ARRAY(block.data, block_size); + block.len = block_size; + block_source_from_strbuf(&block.source ,&buf); + block_writer_init(&bw, BLOCK_TYPE_LOG, block.data, block_size, + header_off, hash_size(GIT_SHA1_FORMAT_ID)); + + for (i = 0; i < N; i++) { + rec.u.log.refname = xstrfmt("branch%02"PRIuMAX , (uintmax_t)i); + rec.u.log.update_index = i; + rec.u.log.value_type = REFTABLE_LOG_UPDATE; + + recs[i] = rec; + ret = block_writer_add(&bw, &rec); + rec.u.log.refname = NULL; + rec.u.log.value_type = REFTABLE_LOG_DELETION; + check_int(ret, ==, 0); + } + + ret = block_writer_finish(&bw); + check_int(ret, >, 0); + + block_writer_release(&bw); + + block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + + block_iter_seek_start(&it, &br); + + for (i = 0; ; i++) { + ret = block_iter_next(&it, &rec); + check_int(ret, >=, 0); + if (ret > 0) { + check_int(i, ==, N); + break; + } + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + } + + for (i = 0; i < N; i++) { + block_iter_reset(&it); + strbuf_reset(&want); + strbuf_addstr(&want, recs[i].u.log.refname); + + ret = block_iter_seek_key(&it, &br, &want); + check_int(ret, ==, 0); + + ret = block_iter_next(&it, &rec); + check_int(ret, ==, 0); + + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + + want.len--; + ret = block_iter_seek_key(&it, &br, &want); + check_int(ret, ==, 0); + + ret = block_iter_next(&it, &rec); + check_int(ret, ==, 0); + check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ)); + } + + block_reader_release(&br); + block_iter_close(&it); + reftable_record_release(&rec); + reftable_block_done(&br.block); + strbuf_release(&want); + strbuf_release(&buf); + for (i = 0; i < N; i++) + reftable_record_release(&recs[i]); +} + int cmd_main(int argc, const char *argv[]) { - TEST(t_block_read_write(), "read-write operations on blocks work"); + TEST(t_log_block_read_write(), "read-write operations on log blocks work"); + TEST(t_ref_block_read_write(), "read-write operations on ref blocks work"); return test_done(); } From 1528c481d71e60f66851b054ad22695beb965fe2 Mon Sep 17 00:00:00 2001 From: Chandra Pratap Date: Wed, 21 Aug 2024 18:01:00 +0530 Subject: [PATCH 10/12] t-reftable-block: add tests for obj blocks In the current testing setup, block operations are left unexercised for obj blocks. Add a test that exercises these operations for obj blocks. Mentored-by: Patrick Steinhardt Mentored-by: Christian Couder Signed-off-by: Chandra Pratap Signed-off-by: Junio C Hamano --- t/unit-tests/t-reftable-block.c | 82 +++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c index 4c4fb39ab4..beb2d6f81b 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/t-reftable-block.c @@ -191,9 +191,91 @@ static void t_log_block_read_write(void) reftable_record_release(&recs[i]); } +static void t_obj_block_read_write(void) +{ + const int header_off = 21; + struct reftable_record recs[30]; + const size_t N = ARRAY_SIZE(recs); + const size_t block_size = 1024; + struct reftable_block block = { 0 }; + struct block_writer bw = { + .last_key = STRBUF_INIT, + }; + struct reftable_record rec = { + .type = BLOCK_TYPE_OBJ, + }; + size_t i = 0; + int ret; + struct block_reader br = { 0 }; + struct block_iter it = BLOCK_ITER_INIT; + struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT; + + REFTABLE_CALLOC_ARRAY(block.data, block_size); + block.len = block_size; + block_source_from_strbuf(&block.source, &buf); + block_writer_init(&bw, BLOCK_TYPE_OBJ, block.data, block_size, + header_off, hash_size(GIT_SHA1_FORMAT_ID)); + + for (i = 0; i < N; i++) { + uint8_t bytes[] = { i, i + 1, i + 2, i + 3, i + 5 }, *allocated; + DUP_ARRAY(allocated, bytes, ARRAY_SIZE(bytes)); + + rec.u.obj.hash_prefix = allocated; + rec.u.obj.hash_prefix_len = 5; + + recs[i] = rec; + ret = block_writer_add(&bw, &rec); + rec.u.obj.hash_prefix = NULL; + rec.u.obj.hash_prefix_len = 0; + check_int(ret, ==, 0); + } + + ret = block_writer_finish(&bw); + check_int(ret, >, 0); + + block_writer_release(&bw); + + block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + + block_iter_seek_start(&it, &br); + + for (i = 0; ; i++) { + ret = block_iter_next(&it, &rec); + check_int(ret, >=, 0); + if (ret > 0) { + check_int(i, ==, N); + break; + } + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + } + + for (i = 0; i < N; i++) { + block_iter_reset(&it); + reftable_record_key(&recs[i], &want); + + ret = block_iter_seek_key(&it, &br, &want); + check_int(ret, ==, 0); + + ret = block_iter_next(&it, &rec); + check_int(ret, ==, 0); + + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + } + + block_reader_release(&br); + block_iter_close(&it); + reftable_record_release(&rec); + reftable_block_done(&br.block); + strbuf_release(&want); + strbuf_release(&buf); + for (i = 0; i < N; i++) + reftable_record_release(&recs[i]); +} + int cmd_main(int argc, const char *argv[]) { TEST(t_log_block_read_write(), "read-write operations on log blocks work"); + TEST(t_obj_block_read_write(), "read-write operations on obj blocks work"); TEST(t_ref_block_read_write(), "read-write operations on ref blocks work"); return test_done(); From 772408fe7548f4f0fe886eaccda9d3e0aaa8589c Mon Sep 17 00:00:00 2001 From: Chandra Pratap Date: Wed, 21 Aug 2024 18:01:01 +0530 Subject: [PATCH 11/12] t-reftable-block: add tests for index blocks In the current testing setup, block operations are left unexercised for index blocks. Add a test that exercises these operations for index blocks. Mentored-by: Patrick Steinhardt Mentored-by: Christian Couder Signed-off-by: Chandra Pratap Signed-off-by: Junio C Hamano --- t/unit-tests/t-reftable-block.c | 88 +++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c index beb2d6f81b..582a8e6036 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/t-reftable-block.c @@ -272,8 +272,96 @@ static void t_obj_block_read_write(void) reftable_record_release(&recs[i]); } +static void t_index_block_read_write(void) +{ + const int header_off = 21; + struct reftable_record recs[30]; + const size_t N = ARRAY_SIZE(recs); + const size_t block_size = 1024; + struct reftable_block block = { 0 }; + struct block_writer bw = { + .last_key = STRBUF_INIT, + }; + struct reftable_record rec = { + .type = BLOCK_TYPE_INDEX, + .u.idx.last_key = STRBUF_INIT, + }; + size_t i = 0; + int ret; + struct block_reader br = { 0 }; + struct block_iter it = BLOCK_ITER_INIT; + struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT; + + REFTABLE_CALLOC_ARRAY(block.data, block_size); + block.len = block_size; + block_source_from_strbuf(&block.source, &buf); + block_writer_init(&bw, BLOCK_TYPE_INDEX, block.data, block_size, + header_off, hash_size(GIT_SHA1_FORMAT_ID)); + + for (i = 0; i < N; i++) { + strbuf_init(&recs[i].u.idx.last_key, 9); + + recs[i].type = BLOCK_TYPE_INDEX; + strbuf_addf(&recs[i].u.idx.last_key, "branch%02"PRIuMAX, (uintmax_t)i); + recs[i].u.idx.offset = i; + + ret = block_writer_add(&bw, &recs[i]); + check_int(ret, ==, 0); + } + + ret = block_writer_finish(&bw); + check_int(ret, >, 0); + + block_writer_release(&bw); + + block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + + block_iter_seek_start(&it, &br); + + for (i = 0; ; i++) { + ret = block_iter_next(&it, &rec); + check_int(ret, >=, 0); + if (ret > 0) { + check_int(i, ==, N); + break; + } + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + } + + for (i = 0; i < N; i++) { + block_iter_reset(&it); + reftable_record_key(&recs[i], &want); + + ret = block_iter_seek_key(&it, &br, &want); + check_int(ret, ==, 0); + + ret = block_iter_next(&it, &rec); + check_int(ret, ==, 0); + + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + + want.len--; + ret = block_iter_seek_key(&it, &br, &want); + check_int(ret, ==, 0); + + ret = block_iter_next(&it, &rec); + check_int(ret, ==, 0); + check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ)); + } + + block_reader_release(&br); + block_iter_close(&it); + reftable_record_release(&rec); + reftable_block_done(&br.block); + strbuf_release(&want); + strbuf_release(&buf); + for (i = 0; i < N; i++) + reftable_record_release(&recs[i]); +} + int cmd_main(int argc, const char *argv[]) { + TEST(t_index_block_read_write(), "read-write operations on index blocks work"); TEST(t_log_block_read_write(), "read-write operations on log blocks work"); TEST(t_obj_block_read_write(), "read-write operations on obj blocks work"); TEST(t_ref_block_read_write(), "read-write operations on ref blocks work"); From 08e83b5ec5db41dd01ce2af54ee67cb1d77e8a6e Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 28 Aug 2024 00:08:03 -0400 Subject: [PATCH 12/12] t-reftable-block: mark unused argv/argc This is conceptually the same as the cases in df9d638c24 (unit-tests: ignore unused argc/argv, 2024-08-17), but this unit test was migrated from the reftable tests in a parallel branch. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- t/unit-tests/t-reftable-block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c index 582a8e6036..f0124fc3d0 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/t-reftable-block.c @@ -359,7 +359,7 @@ static void t_index_block_read_write(void) reftable_record_release(&recs[i]); } -int cmd_main(int argc, const char *argv[]) +int cmd_main(int argc UNUSED, const char *argv[] UNUSED) { TEST(t_index_block_read_write(), "read-write operations on index blocks work"); TEST(t_log_block_read_write(), "read-write operations on log blocks work");