@@ -891,6 +891,45 @@ static void test_reftable_stack_auto_compaction(void)
891891 clear_dir (dir );
892892}
893893
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+
894933static void test_reftable_stack_add_performs_auto_compaction (void )
895934{
896935 struct reftable_write_options opts = { 0 };
@@ -939,6 +978,42 @@ static void test_reftable_stack_add_performs_auto_compaction(void)
939978 clear_dir (dir );
940979}
941980
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+
9421017static void test_reftable_stack_compaction_concurrent (void )
9431018{
9441019 struct reftable_write_options opts = { 0 };
@@ -1016,9 +1091,11 @@ int stack_test_main(int argc, const char *argv[])
10161091 RUN_TEST (test_reftable_stack_add );
10171092 RUN_TEST (test_reftable_stack_add_one );
10181093 RUN_TEST (test_reftable_stack_auto_compaction );
1094+ RUN_TEST (test_reftable_stack_auto_compaction_with_locked_tables );
10191095 RUN_TEST (test_reftable_stack_add_performs_auto_compaction );
10201096 RUN_TEST (test_reftable_stack_compaction_concurrent );
10211097 RUN_TEST (test_reftable_stack_compaction_concurrent_clean );
1098+ RUN_TEST (test_reftable_stack_compaction_with_locked_tables );
10221099 RUN_TEST (test_reftable_stack_hash_id );
10231100 RUN_TEST (test_reftable_stack_lock_failure );
10241101 RUN_TEST (test_reftable_stack_log_normalize );
0 commit comments