Search in sources :

Example 21 with ApplyRaftRunnable

use of com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable in project hazelcast by hazelcast.

the class LocalRaftTest method when_leaderStaysInMinority_then_itDemotesItselfToFollower.

@Test
public void when_leaderStaysInMinority_then_itDemotesItselfToFollower() {
    group = newGroup(3);
    group.start();
    RaftNodeImpl leader = group.waitUntilLeaderElected();
    group.split(leader.getLocalMember());
    InternalCompletableFuture f = leader.replicate(new ApplyRaftRunnable("val"));
    try {
        f.joinInternal();
        fail();
    } catch (StaleAppendRequestException ignored) {
    }
}
Also used : StaleAppendRequestException(com.hazelcast.cp.exception.StaleAppendRequestException) ApplyRaftRunnable(com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable) InternalCompletableFuture(com.hazelcast.spi.impl.InternalCompletableFuture) ParallelJVMTest(com.hazelcast.test.annotation.ParallelJVMTest) QuickTest(com.hazelcast.test.annotation.QuickTest) Test(org.junit.Test)

Example 22 with ApplyRaftRunnable

use of com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable in project hazelcast by hazelcast.

the class LocalRaftTest method when_leaderCrashes_then_theFollowerWithLongestLogMayNotBecomeLeaderIfItsLogIsNotMajority.

@Test
public void when_leaderCrashes_then_theFollowerWithLongestLogMayNotBecomeLeaderIfItsLogIsNotMajority() throws Exception {
    group = newGroup(5);
    group.start();
    RaftNodeImpl leader = group.waitUntilLeaderElected();
    leader.replicate(new ApplyRaftRunnable("val1")).get();
    RaftNodeImpl[] followers = group.getNodesExcept(leader.getLocalMember());
    RaftNodeImpl followerWithLongestLog = followers[0];
    long commitIndex = getCommitIndex(leader);
    assertTrueEventually(() -> {
        for (RaftNodeImpl raftNode : group.getNodes()) {
            assertEquals(commitIndex, getCommitIndex(raftNode));
        }
    });
    for (int i = 1; i < followers.length; i++) {
        group.dropMessagesToMember(leader.getLocalMember(), followers[i].getLocalMember(), AppendRequest.class);
    }
    leader.replicate(new ApplyRaftRunnable("val2"));
    assertTrueEventually(() -> assertTrue(getLastLogOrSnapshotEntry(followerWithLongestLog).index() > commitIndex));
    assertTrueAllTheTime(() -> {
        for (RaftNodeImpl raftNode : group.getNodes()) {
            assertEquals(commitIndex, getCommitIndex(raftNode));
        }
    }, 10);
    group.dropMessagesToMember(followerWithLongestLog.getLocalMember(), followers[1].getLocalMember(), VoteRequest.class);
    group.dropMessagesToMember(followerWithLongestLog.getLocalMember(), followers[2].getLocalMember(), VoteRequest.class);
    group.terminateNode(leader.getLocalMember());
    RaftNodeImpl newLeader = group.waitUntilLeaderElected();
    // followerWithLongestLog has 2 entries, other 3 followers have 1 entry
    // and those 3 followers will elect a leader among themselves
    assertTrueEventually(() -> {
        for (RaftNodeImpl raftNode : followers) {
            RaftEndpoint newLeader1 = getLeaderMember(raftNode);
            assertNotEquals(leader.getLocalMember(), newLeader1);
            assertNotEquals(followerWithLongestLog.getLocalMember(), newLeader1);
        }
    });
    for (int i = 1; i < followers.length; i++) {
        assertEquals(commitIndex, getCommitIndex(followers[i]));
        assertEquals(commitIndex, getLastLogOrSnapshotEntry(followers[i]).index());
    }
    // followerWithLongestLog does not truncate its extra log entry until the new leader appends a new entry
    assertTrue(getLastLogOrSnapshotEntry(followerWithLongestLog).index() > commitIndex);
    newLeader.replicate(new ApplyRaftRunnable("val3")).get();
    assertTrueEventually(() -> {
        for (RaftNodeImpl follower : followers) {
            assertEquals(2, getCommitIndex(follower));
            RaftDataService service = group.getService(follower);
            assertEquals(2, service.size());
            assertEquals("val1", service.get(1));
            assertEquals("val3", service.get(2));
        }
    });
    assertEquals(2, getLastLogOrSnapshotEntry(followerWithLongestLog).index());
}
Also used : ApplyRaftRunnable(com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable) RaftDataService(com.hazelcast.cp.internal.raft.impl.dataservice.RaftDataService) ParallelJVMTest(com.hazelcast.test.annotation.ParallelJVMTest) QuickTest(com.hazelcast.test.annotation.QuickTest) Test(org.junit.Test)

Example 23 with ApplyRaftRunnable

use of com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable in project hazelcast by hazelcast.

the class SnapshotTest method when_followersMatchIndexIsUnknown_then_itInstallsSnapshot.

@Test
public void when_followersMatchIndexIsUnknown_then_itInstallsSnapshot() throws ExecutionException, InterruptedException {
    final int entryCount = 50;
    RaftAlgorithmConfig config = new RaftAlgorithmConfig().setCommitIndexAdvanceCountToSnapshot(entryCount);
    group = newGroup(3, config);
    group.start();
    RaftNodeImpl leader = group.waitUntilLeaderElected();
    RaftNodeImpl[] followers = group.getNodesExcept(leader.getLocalMember());
    RaftNodeImpl slowFollower = followers[1];
    group.dropMessagesToMember(leader.getLocalMember(), slowFollower.getLocalMember(), AppendRequest.class);
    group.dropMessagesToMember(leader.getLocalMember(), slowFollower.getLocalMember(), InstallSnapshot.class);
    for (int i = 0; i < entryCount; i++) {
        leader.replicate(new ApplyRaftRunnable("val" + i)).get();
    }
    assertTrueEventually(() -> assertEquals(entryCount, getSnapshotEntry(leader).index()));
    leader.replicate(new ApplyRaftRunnable("valFinal")).get();
    group.allowMessagesToMember(leader.getLocalMember(), slowFollower.getLocalMember(), InstallSnapshot.class);
    assertTrueEventually(() -> assertEquals(entryCount, getCommitIndex(slowFollower)));
    group.resetAllRulesFrom(leader.getLocalMember());
    assertTrueEventually(() -> {
        for (RaftNodeImpl raftNode : group.getNodes()) {
            assertEquals(entryCount + 1, getCommitIndex(raftNode));
            RaftDataService service = group.getService(raftNode);
            assertEquals(entryCount + 1, service.size());
            for (int i = 0; i < entryCount; i++) {
                assertEquals(("val" + i), service.get(i + 1));
            }
            assertEquals("valFinal", service.get(51));
        }
    });
}
Also used : RaftAlgorithmConfig(com.hazelcast.config.cp.RaftAlgorithmConfig) ApplyRaftRunnable(com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable) RaftDataService(com.hazelcast.cp.internal.raft.impl.dataservice.RaftDataService) ParallelJVMTest(com.hazelcast.test.annotation.ParallelJVMTest) QuickTest(com.hazelcast.test.annotation.QuickTest) Test(org.junit.Test)

Example 24 with ApplyRaftRunnable

use of com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable in project hazelcast by hazelcast.

the class SnapshotTest method when_snapshotIsTaken_then_nextEntryIsCommitted.

@Test
public void when_snapshotIsTaken_then_nextEntryIsCommitted() throws ExecutionException, InterruptedException {
    final int entryCount = 50;
    RaftAlgorithmConfig config = new RaftAlgorithmConfig().setCommitIndexAdvanceCountToSnapshot(entryCount);
    group = newGroup(3, config);
    group.start();
    RaftNodeImpl leader = group.waitUntilLeaderElected();
    for (int i = 0; i < entryCount; i++) {
        leader.replicate(new ApplyRaftRunnable("val" + i)).get();
    }
    assertTrueEventually(() -> {
        for (RaftNodeImpl raftNode : group.getNodes()) {
            assertEquals(entryCount, getCommitIndex(raftNode));
            assertEquals(entryCount, getSnapshotEntry(raftNode).index());
        }
    });
    leader.replicate(new ApplyRaftRunnable("valFinal")).get();
    assertTrueEventually(() -> {
        for (RaftNodeImpl raftNode : group.getNodes()) {
            assertEquals(entryCount + 1, getCommitIndex(raftNode));
            RaftDataService service = group.getService(raftNode);
            assertEquals(entryCount + 1, service.size());
            for (int i = 0; i < entryCount; i++) {
                assertEquals(("val" + i), service.get(i + 1));
            }
            assertEquals("valFinal", service.get(51));
        }
    });
}
Also used : RaftAlgorithmConfig(com.hazelcast.config.cp.RaftAlgorithmConfig) ApplyRaftRunnable(com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable) RaftDataService(com.hazelcast.cp.internal.raft.impl.dataservice.RaftDataService) ParallelJVMTest(com.hazelcast.test.annotation.ParallelJVMTest) QuickTest(com.hazelcast.test.annotation.QuickTest) Test(org.junit.Test)

Example 25 with ApplyRaftRunnable

use of com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable in project hazelcast by hazelcast.

the class SnapshotTest method when_followersLastAppendIsMembershipChange_then_itUpdatesRaftNodeStateWithInstalledSnapshot.

@Test
public void when_followersLastAppendIsMembershipChange_then_itUpdatesRaftNodeStateWithInstalledSnapshot() throws ExecutionException, InterruptedException {
    final int entryCount = 50;
    final RaftAlgorithmConfig config = new RaftAlgorithmConfig().setCommitIndexAdvanceCountToSnapshot(entryCount);
    group = newGroup(5, config);
    group.start();
    RaftNodeImpl leader = group.waitUntilLeaderElected();
    RaftNodeImpl[] followers = group.getNodesExcept(leader.getLocalMember());
    leader.replicate(new ApplyRaftRunnable("val")).get();
    assertTrueEventually(() -> {
        for (RaftNodeImpl follower : followers) {
            assertEquals(1L, getCommitIndex(follower));
        }
    });
    RaftNodeImpl slowFollower = followers[0];
    for (RaftNodeImpl follower : followers) {
        if (follower != slowFollower) {
            group.dropMessagesToMember(follower.getLocalMember(), follower.getLeader(), AppendSuccessResponse.class);
            group.dropMessagesToMember(follower.getLocalMember(), follower.getLeader(), AppendFailureResponse.class);
        }
    }
    RaftNodeImpl newRaftNode1 = group.createNewRaftNode();
    Future f1 = leader.replicateMembershipChange(newRaftNode1.getLocalMember(), MembershipChangeMode.ADD);
    assertTrueEventually(() -> {
        for (RaftNodeImpl follower : followers) {
            assertEquals(2L, getLastLogOrSnapshotEntry(follower).index());
        }
    });
    group.dropMessagesToMember(leader.getLocalMember(), slowFollower.getLocalMember(), AppendRequest.class);
    group.dropMessagesToMember(leader.getLocalMember(), slowFollower.getLocalMember(), InstallSnapshot.class);
    for (RaftNodeImpl follower : followers) {
        if (follower != slowFollower) {
            group.allowAllMessagesToMember(follower.getLocalMember(), leader.getLeader());
        }
    }
    f1.get();
    for (int i = 0; i < entryCount; i++) {
        leader.replicate(new ApplyRaftRunnable("val" + i)).get();
    }
    assertTrueEventually(() -> assertThat(getSnapshotEntry(leader).index(), greaterThanOrEqualTo((long) entryCount)));
    group.allowAllMessagesToMember(leader.getLeader(), slowFollower.getLocalMember());
    assertTrueEventually(() -> assertThat(getSnapshotEntry(slowFollower).index(), greaterThanOrEqualTo((long) entryCount)));
    assertTrueEventually(() -> {
        assertEquals(getCommittedGroupMembers(leader).index(), getCommittedGroupMembers(slowFollower).index());
        assertEquals(ACTIVE, getStatus(slowFollower));
    });
}
Also used : RaftAlgorithmConfig(com.hazelcast.config.cp.RaftAlgorithmConfig) ApplyRaftRunnable(com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable) InternalCompletableFuture(com.hazelcast.spi.impl.InternalCompletableFuture) Future(java.util.concurrent.Future) ParallelJVMTest(com.hazelcast.test.annotation.ParallelJVMTest) QuickTest(com.hazelcast.test.annotation.QuickTest) Test(org.junit.Test)

Aggregations

ApplyRaftRunnable (com.hazelcast.cp.internal.raft.impl.dataservice.ApplyRaftRunnable)55 ParallelJVMTest (com.hazelcast.test.annotation.ParallelJVMTest)50 QuickTest (com.hazelcast.test.annotation.QuickTest)50 Test (org.junit.Test)50 RaftDataService (com.hazelcast.cp.internal.raft.impl.dataservice.RaftDataService)31 RaftAlgorithmConfig (com.hazelcast.config.cp.RaftAlgorithmConfig)23 LocalRaftGroupBuilder (com.hazelcast.cp.internal.raft.impl.testing.LocalRaftGroup.LocalRaftGroupBuilder)15 InternalCompletableFuture (com.hazelcast.spi.impl.InternalCompletableFuture)15 RestoredRaftState (com.hazelcast.cp.internal.raft.impl.persistence.RestoredRaftState)14 InMemoryRaftStateStore (com.hazelcast.cp.internal.raft.impl.testing.InMemoryRaftStateStore)10 Future (java.util.concurrent.Future)8 ArrayList (java.util.ArrayList)5 QueryRaftRunnable (com.hazelcast.cp.internal.raft.impl.dataservice.QueryRaftRunnable)4 LogEntry (com.hazelcast.cp.internal.raft.impl.log.LogEntry)4 RaftGroupMembers (com.hazelcast.cp.internal.raft.impl.state.RaftGroupMembers)4 StaleAppendRequestException (com.hazelcast.cp.exception.StaleAppendRequestException)3 CannotReplicateException (com.hazelcast.cp.exception.CannotReplicateException)2 LeaderDemotedException (com.hazelcast.cp.exception.LeaderDemotedException)2 DestroyRaftGroupCmd (com.hazelcast.cp.internal.raft.command.DestroyRaftGroupCmd)2 RaftUtil.getSnapshotEntry (com.hazelcast.cp.internal.raft.impl.RaftUtil.getSnapshotEntry)2