@@ -22,6 +22,7 @@ all_tests() ->
2222 resend_write_lost_in_wal_crash ,
2323 resend_after_written_event_lost_in_wal_crash ,
2424 resend_write_after_tick ,
25+ snapshot_before_written ,
2526 handle_overwrite ,
2627 handle_overwrite_append ,
2728 receive_segment ,
@@ -52,7 +53,7 @@ all_tests() ->
5253 wal_down_read_availability ,
5354 wal_down_append_throws ,
5455 wal_down_write_returns_error_wal_down ,
55-
56+ wal_down_stage ,
5657 detect_lost_written_range ,
5758 snapshot_installation ,
5859 snapshot_written_after_installation ,
@@ -141,6 +142,39 @@ end_per_testcase(_, Config) ->
141142-define (N2 , {n2 , node ()}).
142143% -define(N3, {n3, node()}).
143144
145+ snapshot_before_written (Config ) ->
146+ % % snapshot_written comes in before written event for lower entries.
147+
148+ Log0 = write_n (1 , 6 , 1 ,
149+ ra_log_init (Config , #{min_snapshot_interval => 0 })),
150+ receive
151+ {ra_log_event , {written , 1 , _ }} -> ok
152+ after 2000 ->
153+ exit (written_timeout )
154+ end ,
155+ % % write 10 entries
156+ Log1 = write_n (6 , 20 , 1 , Log0 ),
157+ SnapIdx = 10 ,
158+ % % do snapshot in
159+ {Log2 , Effs } = ra_log :update_release_cursor (SnapIdx , #{}, macctx (),
160+ [10 , 4 ], Log1 ),
161+ run_effs (Effs ),
162+ {Log3 , Effs3 } = receive
163+ {ra_log_event , {snapshot_written , {10 , 1 }, _ ,
164+ snapshot , _ } = Evt } ->
165+ ra_log :handle_event (Evt , Log2 )
166+ after 5000 ->
167+ flush (),
168+ exit (snapshot_written_timeout )
169+ end ,
170+ run_effs (Effs3 ),
171+
172+ _Log4 = assert_log_events (Log3 ,
173+ fun (L ) ->
174+ {19 , 1 } == ra_log :last_written (L )
175+ end ),
176+ ok .
177+
144178handle_overwrite (Config ) ->
145179 Log0 = ra_log_init (Config ),
146180 {ok , Log1 } = ra_log :write ([{1 , 1 , " value" },
@@ -154,9 +188,11 @@ handle_overwrite(Config) ->
154188 % ensure immediate truncation
155189 {1 , 2 } = ra_log :last_index_term (Log3 ),
156190 {ok , Log4 } = ra_log :write ([{2 , 2 , " value" }], Log3 ),
191+
157192 % simulate the first written event coming after index 20 has already
158193 % been written in a new term
159194 {Log , _ } = ra_log :handle_event ({written , 1 , [2 , 1 ]}, Log4 ),
195+ ct :pal (" Log ~p " , [Log ]),
160196 % ensure last written has not been incremented
161197 {0 , 0 } = ra_log :last_written (Log ),
162198 {2 , 2 } = ra_log :last_written (
@@ -1253,6 +1289,27 @@ wal_down_write_returns_error_wal_down(Config) ->
12531289 {error , wal_down } = ra_log :write ([{1 , 1 , hi }], Log0 ),
12541290 ok .
12551291
1292+ wal_down_stage (Config ) ->
1293+ [SupPid ] = [P || {ra_log_wal_sup , P , _ , _ }
1294+ <- supervisor :which_children (ra_log_sup )],
1295+
1296+ Log0 = ra_log :begin_tx (ra_log_init (Config )),
1297+ Log1 = ra_log :append ({2 , 1 , ho },
1298+ ra_log :append ({1 , 1 , hi }, Log0 )),
1299+ ct :pal (" o1 ~p " , [ra_log :overview (Log1 )]),
1300+ ok = supervisor :terminate_child (SupPid , ra_log_wal ),
1301+ {error , wal_down , Log2 } = ra_log :commit_tx (Log1 ),
1302+ {ok , _ } = supervisor :restart_child (SupPid , ra_log_wal ),
1303+ % % check it is possible to write the next entries
1304+ ? assertEqual (1 , ra_log :next_index (Log2 )),
1305+ Log3 = ra_log :append ({1 , 1 , hi }, ra_log :begin_tx (Log2 )),
1306+ {ok , Log4 } = ra_log :commit_tx (Log3 ),
1307+ ra_log_wal :force_roll_over (ra_log_wal ),
1308+ ct :pal (" o4 ~p " , [ra_log :overview (Log4 )]),
1309+ Log = deliver_all_log_events (Log4 , 200 ),
1310+ ct :pal (" o ~p " , [ra_log :overview (Log )]),
1311+ ok .
1312+
12561313detect_lost_written_range (Config ) ->
12571314 Log0 = ra_log_init (Config , #{wal => ra_log_wal }),
12581315 {0 , 0 } = ra_log :last_index_term (Log0 ),
0 commit comments