reftable/stack: test compaction with already-locked tables
We're lacking test coverage for compacting tables when some of the tables that we are about to compact are locked. Add two tests that exercise this, one for auto-compaction and one for full compaction. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Aug 8, 2024 at 16:06 UTC
8030100bdafc508eaa7900ebcfd67a2d6b02749e
1 file changed
+77
reftable/stack_test.c
+77
@@ -891,6 +891,45 @@ static void test_reftable_stack_auto_compaction(void)
891
clear_dir(dir);
892
}
893
894
+static void test_reftable_stack_auto_compaction_with_locked_tables(void)
895
+{
896
+ struct reftable_write_options opts = {
897
+ .disable_auto_compact = 1,
898
+ };
899
+ struct reftable_stack *st = NULL;
900
+ struct strbuf buf = STRBUF_INIT;
901
+ char *dir = get_tmp_dir(__LINE__);
902
+ int err;
903
+
904
+ err = reftable_new_stack(&st, dir, &opts);
905
+ EXPECT_ERR(err);
906
+
907
+ write_n_ref_tables(st, 5);
908
+ EXPECT(st->merged->stack_len == 5);
909
+
910
+ /*
911
+ * Given that all tables we have written should be roughly the same
912
+ * size, we expect that auto-compaction will want to compact all of the
913
+ * tables. Locking any of the tables will keep it from doing so.
914
+ */
915
+ strbuf_reset(&buf);
916
+ strbuf_addf(&buf, "%s/%s.lock", dir, st->readers[2]->name);
917
+ write_file_buf(buf.buf, "", 0);
918
+
919
+ /*
920
+ * Ideally, we'd handle the situation where any of the tables is locked
921
+ * gracefully. We don't (yet) do this though and thus fail.
922
+ */
923
+ err = reftable_stack_auto_compact(st);
924
+ EXPECT(err == REFTABLE_LOCK_ERROR);
925
+ EXPECT(st->stats.failures == 1);
926
+ EXPECT(st->merged->stack_len == 5);
927
+
928
+ reftable_stack_destroy(st);
929
+ strbuf_release(&buf);
930
+ clear_dir(dir);
931
+}
932
+
933
static void test_reftable_stack_add_performs_auto_compaction(void)
934
{
935
struct reftable_write_options opts = { 0 };
@@ -939,6 +978,42 @@ static void test_reftable_stack_add_performs_auto_compaction(void)
978
clear_dir(dir);
979
}
980
981
+static void test_reftable_stack_compaction_with_locked_tables(void)
982
+{
983
+ struct reftable_write_options opts = {
984
+ .disable_auto_compact = 1,
985
+ };
986
+ struct reftable_stack *st = NULL;
987
+ struct strbuf buf = STRBUF_INIT;
988
+ char *dir = get_tmp_dir(__LINE__);
989
+ int err;
990
+
991
+ err = reftable_new_stack(&st, dir, &opts);
992
+ EXPECT_ERR(err);
993
+
994
+ write_n_ref_tables(st, 3);
995
+ EXPECT(st->merged->stack_len == 3);
996
+
997
+ /* Lock one of the tables that we're about to compact. */
998
+ strbuf_reset(&buf);
999
+ strbuf_addf(&buf, "%s/%s.lock", dir, st->readers[1]->name);
1000
+ write_file_buf(buf.buf, "", 0);
1001
+
1002
+ /*
1003
+ * Compaction is expected to fail given that we were not able to
1004
+ * compact all tables.
1005
+ */
1006
+ err = reftable_stack_compact_all(st, NULL);
1007
+ EXPECT(err == REFTABLE_LOCK_ERROR);
1008
+ /* TODO: this is wrong, we should get notified about the failure. */
1009
+ EXPECT(st->stats.failures == 0);
1010
+ EXPECT(st->merged->stack_len == 3);
1011
+
1012
+ reftable_stack_destroy(st);
1013
+ strbuf_release(&buf);
1014
+ clear_dir(dir);
1015
+}
1016
+
1017
static void test_reftable_stack_compaction_concurrent(void)
1018
{
1019
struct reftable_write_options opts = { 0 };
@@ -1016,9 +1091,11 @@ int stack_test_main(int argc, const char *argv[])
1091
RUN_TEST(test_reftable_stack_add);
1092
RUN_TEST(test_reftable_stack_add_one);
1093
RUN_TEST(test_reftable_stack_auto_compaction);
1094
+ RUN_TEST(test_reftable_stack_auto_compaction_with_locked_tables);
1095
RUN_TEST(test_reftable_stack_add_performs_auto_compaction);
1096
RUN_TEST(test_reftable_stack_compaction_concurrent);
1097
RUN_TEST(test_reftable_stack_compaction_concurrent_clean);
1098
+ RUN_TEST(test_reftable_stack_compaction_with_locked_tables);
1099
RUN_TEST(test_reftable_stack_hash_id);
1100
RUN_TEST(test_reftable_stack_lock_failure);
1101
RUN_TEST(test_reftable_stack_log_normalize);