@@ -205,6 +205,40 @@ def test_large_snapshot(network, args):
205205 )
206206
207207
208+ def test_empty_snapshot (network , args ):
209+
210+ LOG .info ("Check that empty snapshot is ignored" )
211+
212+ with tempfile .TemporaryDirectory () as snapshots_dir :
213+ LOG .debug (f"Using { snapshots_dir } as snapshots directory" )
214+
215+ snapshot_name = "snapshot_1000_1500.committed"
216+
217+ with open (
218+ os .path .join (snapshots_dir , snapshot_name ), "wb+"
219+ ) as temp_empty_snapshot :
220+
221+ LOG .debug (f"Created empty snapshot { temp_empty_snapshot .name } " )
222+
223+ # Check the file is indeed empty
224+ assert (
225+ os .stat (temp_empty_snapshot .name ).st_size == 0
226+ ), temp_empty_snapshot .name
227+
228+ # Create new node and join network
229+ new_node = network .create_node ("local://localhost" )
230+ network .join_node (new_node , args .package , args , snapshots_dir = snapshots_dir )
231+ new_node .stop ()
232+
233+ # Check that the empty snapshot is correctly skipped
234+ if not new_node .check_log_for_error_message (
235+ f"Ignoring empty snapshot file { snapshot_name } "
236+ ):
237+ raise AssertionError (
238+ f"Expected empty snapshot file { snapshot_name } to be skipped in node logs"
239+ )
240+
241+
208242def split_all_ledger_files_in_dir (input_dir , output_dir ):
209243 # A ledger file can only be split at a seqno that contains a signature
210244 # (so that all files end on a signature that verifies their integrity).
@@ -292,6 +326,7 @@ def run_file_operations(args):
292326 test_forced_ledger_chunk (network , args )
293327 test_forced_snapshot (network , args )
294328 test_large_snapshot (network , args )
329+ test_empty_snapshot (network , args )
295330
296331 primary , _ = network .find_primary ()
297332 # Scoped transactions are not handled by historical range queries
@@ -589,6 +624,47 @@ def run_service_subject_name_check(args):
589624 assert cert .subject .rfc4514_string () == "CN=This test service" , cert
590625
591626
627+ def run_empty_ledger_dir_check (args ):
628+ with infra .network .network (
629+ args .nodes ,
630+ args .binary_dir ,
631+ args .debug_nodes ,
632+ args .perf_nodes ,
633+ pdb = args .pdb ,
634+ ) as network :
635+ LOG .info ("Check that empty ledger directory is handled correctly" )
636+ with tempfile .TemporaryDirectory () as tmp_dir :
637+ LOG .debug (f"Using { tmp_dir } as ledger directory" )
638+
639+ dir_name = os .path .basename (tmp_dir )
640+
641+ # Check tmp_dir is indeed empty
642+ assert len (os .listdir (tmp_dir )) == 0 , tmp_dir
643+
644+ # Start network, this should not fail
645+ network .start_and_open (args , ledger_dir = tmp_dir )
646+ primary , _ = network .find_primary ()
647+ network .stop_all_nodes ()
648+
649+ # Now write a file in the directory
650+ with open (os .path .join (tmp_dir , "ledger_1000_1500.committed" ), "wb" ) as f :
651+ f .write (b"bar" )
652+
653+ # Start new network, this should fail
654+ try :
655+ network .start (args , ledger_dir = tmp_dir )
656+ except Exception :
657+ pass
658+
659+ # Check that the node has failed with the expected error message
660+ if not primary .check_log_for_error_message (
661+ f"On start, ledger directory should not exist or be empty ({ dir_name } )"
662+ ):
663+ raise AssertionError (
664+ f"Expected node error message with non-empty ledger directory { dir_name } "
665+ )
666+
667+
592668def run (args ):
593669 run_max_uncommitted_tx_count (args )
594670 run_file_operations (args )
@@ -599,3 +675,4 @@ def run(args):
599675 run_preopen_readiness_check (args )
600676 run_sighup_check (args )
601677 run_service_subject_name_check (args )
678+ run_empty_ledger_dir_check (args )
0 commit comments