2 * Copyright (c) 2015 Brocade Communications Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.cluster.raft;
10 import static org.junit.Assert.assertEquals;
11 import akka.persistence.SaveSnapshotSuccess;
12 import com.google.common.collect.ImmutableMap;
13 import java.util.Arrays;
14 import org.junit.Before;
15 import org.junit.Test;
16 import org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload;
17 import org.opendaylight.controller.cluster.raft.base.messages.ApplyJournalEntries;
18 import org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshotReply;
19 import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
20 import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
23 * Tests raft actor persistence recovery end-to-end using real RaftActors and behavior communication.
25 * @author Thomas Pantelis
27 public class RecoveryIntegrationTest extends AbstractRaftActorIntegrationTest {
29 private MockPayload payload0;
30 private MockPayload payload1;
34 follower1Actor = newTestRaftActor(follower1Id, ImmutableMap.of(leaderId, testActorPath(leaderId)),
35 newFollowerConfigParams());
37 peerAddresses = ImmutableMap.<String, String>builder().
38 put(follower1Id, follower1Actor.path().toString()).build();
40 leaderConfigParams = newLeaderConfigParams();
41 leaderActor = newTestRaftActor(leaderId, peerAddresses, leaderConfigParams);
43 follower1CollectorActor = follower1Actor.underlyingActor().collectorActor();
44 leaderCollectorActor = leaderActor.underlyingActor().collectorActor();
46 leaderContext = leaderActor.underlyingActor().getRaftActorContext();
50 public void testStatePersistedBetweenSnapshotCaptureAndPersist() {
52 send2InitialPayloads();
54 // Block these messages initially so we can control the sequence.
55 leaderActor.underlyingActor().startDropMessages(CaptureSnapshotReply.class);
56 follower1Actor.underlyingActor().startDropMessages(AppendEntries.class);
58 MockPayload payload2 = sendPayloadData(leaderActor, "two");
60 // This should trigger a snapshot.
61 MockPayload payload3 = sendPayloadData(leaderActor, "three");
63 MessageCollectorActor.expectMatching(follower1CollectorActor, AppendEntries.class, 3);
65 // Send another payload.
66 MockPayload payload4 = sendPayloadData(leaderActor, "four");
68 // Now deliver the AppendEntries to the follower
69 follower1Actor.underlyingActor().stopDropMessages(AppendEntries.class);
71 MessageCollectorActor.expectMatching(leaderCollectorActor, ApplyJournalEntries.class, 3);
73 // Now deliver the CaptureSnapshotReply to the leader.
74 CaptureSnapshotReply captureSnapshotReply = MessageCollectorActor.expectFirstMatching(
75 leaderCollectorActor, CaptureSnapshotReply.class);
76 leaderActor.underlyingActor().stopDropMessages(CaptureSnapshotReply.class);
77 leaderActor.tell(captureSnapshotReply, leaderActor);
79 // Wait for snapshot complete.
80 MessageCollectorActor.expectFirstMatching(leaderCollectorActor, SaveSnapshotSuccess.class);
82 reinstateLeaderActor();
84 assertEquals("Leader snapshot term", currentTerm, leaderContext.getReplicatedLog().getSnapshotTerm());
85 assertEquals("Leader snapshot index", 1, leaderContext.getReplicatedLog().getSnapshotIndex());
86 assertEquals("Leader journal log size", 3, leaderContext.getReplicatedLog().size());
87 assertEquals("Leader journal last index", 4, leaderContext.getReplicatedLog().lastIndex());
88 assertEquals("Leader commit index", 4, leaderContext.getCommitIndex());
89 assertEquals("Leader last applied", 4, leaderContext.getLastApplied());
91 assertEquals("Leader state", Arrays.asList(payload0, payload1, payload2, payload3, payload4),
92 leaderActor.underlyingActor().getState());
96 public void testStatePersistedAfterSnapshotPersisted() {
98 send2InitialPayloads();
100 // Block these messages initially so we can control the sequence.
101 follower1Actor.underlyingActor().startDropMessages(AppendEntries.class);
103 MockPayload payload2 = sendPayloadData(leaderActor, "two");
105 // This should trigger a snapshot.
106 MockPayload payload3 = sendPayloadData(leaderActor, "three");
108 // Send another payload.
109 MockPayload payload4 = sendPayloadData(leaderActor, "four");
111 MessageCollectorActor.expectMatching(follower1CollectorActor, AppendEntries.class, 3);
113 // Wait for snapshot complete.
114 MessageCollectorActor.expectFirstMatching(leaderCollectorActor, SaveSnapshotSuccess.class);
116 // Now deliver the AppendEntries to the follower
117 follower1Actor.underlyingActor().stopDropMessages(AppendEntries.class);
119 MessageCollectorActor.expectMatching(leaderCollectorActor, ApplyJournalEntries.class, 3);
121 reinstateLeaderActor();
123 assertEquals("Leader snapshot term", currentTerm, leaderContext.getReplicatedLog().getSnapshotTerm());
124 assertEquals("Leader snapshot index", 1, leaderContext.getReplicatedLog().getSnapshotIndex());
125 assertEquals("Leader journal log size", 3, leaderContext.getReplicatedLog().size());
126 assertEquals("Leader journal last index", 4, leaderContext.getReplicatedLog().lastIndex());
127 assertEquals("Leader commit index", 4, leaderContext.getCommitIndex());
128 assertEquals("Leader last applied", 4, leaderContext.getLastApplied());
130 assertEquals("Leader state", Arrays.asList(payload0, payload1, payload2, payload3, payload4),
131 leaderActor.underlyingActor().getState());
134 private void reinstateLeaderActor() {
135 killActor(leaderActor);
137 leaderActor = newTestRaftActor(leaderId, peerAddresses, leaderConfigParams);
139 leaderActor.underlyingActor().waitForRecoveryComplete();
141 leaderContext = leaderActor.underlyingActor().getRaftActorContext();
144 private void send2InitialPayloads() {
145 waitUntilLeader(leaderActor);
146 currentTerm = leaderContext.getTermInformation().getCurrentTerm();
148 payload0 = sendPayloadData(leaderActor, "zero");
149 payload1 = sendPayloadData(leaderActor, "one");
151 // Verify the leader applies the states.
152 MessageCollectorActor.expectMatching(leaderCollectorActor, ApplyJournalEntries.class, 2);
154 assertEquals("Leader last applied", 1, leaderContext.getLastApplied());
156 MessageCollectorActor.clearMessages(leaderCollectorActor);
157 MessageCollectorActor.clearMessages(follower1CollectorActor);