@@ -717,3 +717,45 @@ TEST(snapshot, takeSnapshotFail, setUp, tearDown, 0, fsm_snapshot_async_params)
717
717
/* No crash or leaks have occurred */
718
718
return MUNIT_OK ;
719
719
}
720
+
721
+ /* A follower doesn't convert to candidate state while it's installing a snapshot. */
722
+ TEST (snapshot , snapshotBlocksCandidate , setUp , tearDown , 0 , NULL )
723
+ {
724
+ struct fixture * f = data ;
725
+ (void )params ;
726
+
727
+ /* Set very low threshold and trailing entries number */
728
+ SET_SNAPSHOT_THRESHOLD (3 );
729
+ SET_SNAPSHOT_TRAILING (1 );
730
+ SET_SNAPSHOT_TIMEOUT (200 );
731
+
732
+ raft_set_election_timeout (CLUSTER_RAFT (2 ), 600 );
733
+
734
+ /* Apply a few of entries, to force a snapshot to be taken. Drop all network
735
+ * traffic between servers 0 and 2 in order for AppendEntries RPCs to not be
736
+ * replicated */
737
+ fprintf (stderr , "saturating\n" );
738
+ CLUSTER_SATURATE_BOTHWAYS (0 , 2 );
739
+ CLUSTER_MAKE_PROGRESS ;
740
+ CLUSTER_MAKE_PROGRESS ;
741
+ CLUSTER_MAKE_PROGRESS ;
742
+
743
+ /* Reconnect both servers and set a high disk latency on server 2 */
744
+ CLUSTER_SET_DISK_LATENCY (2 , 2000 );
745
+ CLUSTER_DESATURATE_BOTHWAYS (0 , 2 );
746
+ fprintf (stderr , "desaturating\n" );
747
+
748
+ /* Wait a while and check that the leader has sent a snapshot */
749
+ CLUSTER_STEP_UNTIL_ELAPSED (500 );
750
+ munit_assert_int (CLUSTER_N_SEND (0 , RAFT_IO_INSTALL_SNAPSHOT ), = = , 1 );
751
+ munit_assert_int (CLUSTER_N_RECV (2 , RAFT_IO_INSTALL_SNAPSHOT ), = = , 1 );
752
+
753
+ /* Disconnect the servers again so that heartbeats, etc. won't arrive */
754
+ fprintf (stderr , "resaturating\n" );
755
+ CLUSTER_SATURATE_BOTHWAYS (0 , 2 );
756
+ munit_assert_int (CLUSTER_STATE (2 ), = = , RAFT_FOLLOWER );
757
+ munit_assert_ptr (CLUSTER_RAFT (2 )-> snapshot .put .data , != , NULL );
758
+ CLUSTER_STEP_UNTIL_ELAPSED (1500 );
759
+ munit_assert_int (CLUSTER_STATE (2 ), = = , RAFT_FOLLOWER );
760
+ return MUNIT_OK ;
761
+ }
0 commit comments