@@ -20,7 +20,8 @@ all() ->
2020
2121all_tests () ->
2222 [
23- basics
23+ basics ,
24+ snapshot_replication
2425 ].
2526
2627groups () ->
@@ -56,6 +57,60 @@ end_per_testcase(_TestCase, _Config) ->
5657% %%===================================================================
5758
5859
60+ snapshot_replication (_Config ) ->
61+ Members = [{kv1 , node ()}, {kv2 , node ()}],
62+ KvId = hd (Members ),
63+
64+ {ok , _ , _ } = ra_kv :start_cluster (? SYS , ? FUNCTION_NAME ,
65+ #{members => Members }),
66+ ra :transfer_leadership (KvId , KvId ),
67+ {ok , #{}} = ra_kv :put (KvId , <<" k1" >>, <<" k1-value01" >>, 5000 ),
68+ % % write 10k entries of the same key
69+ [{ok , #{}} = ra_kv :put (KvId , integer_to_binary (I ), I , 5000 )
70+ || I <- lists :seq (1 , 5000 )],
71+
72+ ct :pal (" kv get ~p " , [ra_kv :get (KvId , <<" k1" >>, 5000 )]),
73+ ct :pal (" leaderboard ~p " , [ets :tab2list (ra_leaderboard )]),
74+
75+ ? assertMatch ({ok , #{machine := #{num_keys := _ }}, KvId },
76+ ra :member_overview (KvId )),
77+ ra_log_wal :force_roll_over (ra_log_wal ),
78+ % % wait for rollover processing
79+ ra_log_wal :last_writer_seq (ra_log_wal , <<>>),
80+ % % wait for segment writer to process
81+ ra_log_segment_writer :await (ra_log_segment_writer ),
82+ % % promt ra_kv to take a snapshot
83+ ok = ra :aux_command (KvId , take_snapshot ),
84+ ok = ra_lib :retry (
85+ fun () ->
86+ {ok , #{log := #{snapshot_index := SnapIdx ,
87+ last_index := LastIdx }}, _ } =
88+ ra :member_overview (KvId ),
89+ SnapIdx == LastIdx
90+ end , 100 , 100 ),
91+
92+ KvId3 = {kv3 , node ()},
93+ ok = ra_kv :add_member (? SYS , KvId3 , KvId ),
94+ KvId3Pid = whereis (kv3 ),
95+ ? assert (is_pid (KvId3Pid )),
96+ {ok , #{}} = ra_kv :put (KvId , <<" k3" >>, <<" k3-value01" >>, 5000 ),
97+ {ok , #{}} = ra_kv :put (KvId , <<" k4" >>, <<" k3-value01" >>, 5000 ),
98+ ok = ra :aux_command (KvId , take_snapshot ),
99+ % timer:sleep(1000),
100+ {ok , #{log := #{last_index := Kv1LastIndex }}, _ } =
101+ ra :member_overview (KvId ),
102+ ok = ra_lib :retry (
103+ fun () ->
104+ {ok , #{log := #{last_index := LastIdx }}, _ } =
105+ ra :member_overview (KvId3 ),
106+ Kv1LastIndex == LastIdx
107+ end , 100 , 100 ),
108+ ct :pal (" counters ~p " , [ra_counters :counters (KvId3 , [last_applied ])]),
109+ % % ensure kv3 did not crash during snapshot replication
110+ ? assertEqual (KvId3Pid , whereis (kv3 )),
111+ ra :delete_cluster ([KvId , {kv2 , node ()}, KvId3 ]),
112+ ok .
113+
59114basics (_Config ) ->
60115 Members = [{kv1 , node ()}],
61116 KvId = hd (Members ),
@@ -136,4 +191,5 @@ basics(_Config) ->
136191 undefined , 1000 ),
137192 ? assertEqual (Reads4 , Reads5 ),
138193 ct :pal (" counters ~p " , [ra_counters :overview (KvId )]),
194+ ra :delete_cluster ([KvId , KvId2 ]),
139195 ok .
0 commit comments