consensus-raft/src/test/java/com/mboysan/consensus/RaftNodeTest.java
/**
     * Tests append event during a broken quorum where one of the disconnected nodes is the leader. The leader will
     * try to write a new entry (cmd0) which will eventually be discarded.
     * While the leader's network connection is still down and the follower connections are repaired a new leader will
     * be elected. The new leader will write a new entry and when the old leader's connection is repaired, it sees
     * the new leader and this new entry (cmd1).
     */
Tests append event during a broken quorum where one of the disconnected nodes is the leader. The leader will
try to write a new entry (cmd0) which will eventually be discarded.
While the leader's network connection is still down and the follower connections are repaired a new leader will
be elected. The new leader will write a new entry and when the old leader's connection is repaired, it sees
the new leader and this new entry (cmd1).
Tests append event during a broken quorum where one of the disconnected nodes is the leader . The leader will try to write a new entry ( cmd0 ) which will eventually be discarded . While the leader ' s network connection is still down and the follower connections are repaired a new leader will be elected . The new leader will write a new entry and when the old leader ' s connection is repaired it sees the new leader and this new entry ( cmd1 ) .
@Test
    void testAppendWhenQuorumNotFormed3() throws Exception {
        int numServers = 5;
        init(numServers);
        int oldLeaderId = assertOneLeader();
        disconnect(oldLeaderId);
        disconnect((oldLeaderId + 2) % numServers);
        disconnect((oldLeaderId + 3) % numServers);
        advanceTimeForElections();
        List<String> expectedCommands = Arrays.asList("cmd0", "cmd1");
        Future<Boolean> future0 = getNode(oldLeaderId).append(expectedCommands.get(0));
        assertThrows(TimeoutException.class, () -> future0.get(1, TimeUnit.SECONDS));
        connect((oldLeaderId + 2) % numServers);
        connect((oldLeaderId + 3) % numServers);
        advanceTimeForElections();  
        int newLeaderId = assertLeaderChanged(oldLeaderId, false /* oldLeader is not aware */);
        Future<Boolean> future1 = getNode(newLeaderId).append(expectedCommands.get(1));
        assertTrue(future1.get()); 
        connect(oldLeaderId);  
        advanceTimeForElections();
        assertLeaderNotChanged(newLeaderId);    
        assertFalse(future0.get()); 
        expectedCommands = List.of("cmd1");
        assertLogsEquals(expectedCommands); 
    }
@ Test void testAppendWhenQuorumNotFormed3 ( ) throws Exception { int numServers = 5 ; init ( numServers ) ; int oldLeaderId = assertOneLeader ( ) ; disconnect ( oldLeaderId ) ; disconnect ( ( oldLeaderId + 2 ) % numServers ) ; disconnect ( ( oldLeaderId + 3 ) % numServers ) ; advanceTimeForElections ( ) ; List < String > expectedCommands = Arrays . asList ( "cmd0" , "cmd1" ) ; Future < Boolean > future0 = getNode ( oldLeaderId ) . append ( expectedCommands . get ( 0 ) ) ; assertThrows ( TimeoutException . class , ( ) -> future0 . get ( 1 , TimeUnit . SECONDS ) ) ; connect ( ( oldLeaderId + 2 ) % numServers ) ; connect ( ( oldLeaderId + 3 ) % numServers ) ; advanceTimeForElections ( ) ; int newLeaderId = assertLeaderChanged ( oldLeaderId , false /* oldLeader is not aware */ ) ; Future < Boolean > future1 = getNode ( newLeaderId ) . append ( expectedCommands . get ( 1 ) ) ; assertTrue ( future1 . get ( ) ) ; connect ( oldLeaderId ) ; advanceTimeForElections ( ) ; assertLeaderNotChanged ( newLeaderId ) ; assertFalse ( future0 . get ( ) ) ; expectedCommands = List . of ( "cmd1" ) ; assertLogsEquals ( expectedCommands ) ; }
Tests append event during a broken quorum where one of the disconnected nodes is the leader.
Tests append event during a broken quorum where one of the disconnected nodes is the leader .
// the "cmd0" entry will not be applied at all // append a new entry to log. oldLeader's entry will not be synced. // connect old leader and discover new one // oldLeader should not be able to become the leader at this point. // this entry is long gone // log item will be applied as soon as the quorum is formed again.