use of org.opendaylight.controller.cluster.DataPersistenceProvider in project controller by opendaylight.
the class RaftActorTest method testFakeSnapshotsForFollowerWithInRealSnapshots.
@Test
public void testFakeSnapshotsForFollowerWithInRealSnapshots() throws Exception {
final String persistenceId = factory.generateActorId("follower-");
final String leaderId = factory.generateActorId("leader-");
ActorRef leaderActor1 = factory.createActor(MessageCollectorActor.props());
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
config.setIsolatedLeaderCheckInterval(new FiniteDuration(1, TimeUnit.DAYS));
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
Map<String, String> peerAddresses = new HashMap<>();
peerAddresses.put(leaderId, leaderActor1.path().toString());
TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId, peerAddresses, config, dataPersistenceProvider), persistenceId);
MockRaftActor followerActor = mockActorRef.underlyingActor();
followerActor.getRaftActorContext().setCommitIndex(4);
followerActor.getRaftActorContext().setLastApplied(4);
followerActor.getRaftActorContext().getTermInformation().update(1, persistenceId);
followerActor.waitForInitializeBehaviorComplete();
Follower follower = new Follower(followerActor.getRaftActorContext());
followerActor.setCurrentBehavior(follower);
assertEquals(RaftState.Follower, followerActor.getCurrentBehavior().state());
// create 6 entries in the log - 0 to 4 are applied and will get picked up as part of the capture snapshot
MockRaftActorContext.MockReplicatedLogBuilder logBuilder = new MockRaftActorContext.MockReplicatedLogBuilder();
followerActor.getRaftActorContext().setReplicatedLog(logBuilder.createEntries(0, 6, 1).build());
// log has indices 0-5
assertEquals(6, followerActor.getReplicatedLog().size());
// snapshot on 4
followerActor.getRaftActorContext().getSnapshotManager().capture(new SimpleReplicatedLogEntry(5, 1, new MockRaftActorContext.MockPayload("D")), 4);
verify(followerActor.snapshotCohortDelegate).createSnapshot(anyObject(), anyObject());
assertEquals(6, followerActor.getReplicatedLog().size());
// fake snapshot on index 6
List<ReplicatedLogEntry> entries = Arrays.asList((ReplicatedLogEntry) new SimpleReplicatedLogEntry(6, 1, new MockRaftActorContext.MockPayload("foo-6")));
followerActor.onReceiveCommand(new AppendEntries(1, leaderId, 5, 1, entries, 5, 5, (short) 0));
assertEquals(7, followerActor.getReplicatedLog().size());
// fake snapshot on index 7
assertEquals(RaftState.Follower, followerActor.getCurrentBehavior().state());
entries = Arrays.asList((ReplicatedLogEntry) new SimpleReplicatedLogEntry(7, 1, new MockRaftActorContext.MockPayload("foo-7")));
followerActor.onReceiveCommand(new AppendEntries(1, leaderId, 6, 1, entries, 6, 6, (short) 0));
assertEquals(8, followerActor.getReplicatedLog().size());
assertEquals(RaftState.Follower, followerActor.getCurrentBehavior().state());
ByteString snapshotBytes = fromObject(Arrays.asList(new MockRaftActorContext.MockPayload("foo-0"), new MockRaftActorContext.MockPayload("foo-1"), new MockRaftActorContext.MockPayload("foo-2"), new MockRaftActorContext.MockPayload("foo-3"), new MockRaftActorContext.MockPayload("foo-4")));
followerActor.onReceiveCommand(new CaptureSnapshotReply(ByteState.of(snapshotBytes.toByteArray()), java.util.Optional.empty()));
assertTrue(followerActor.getRaftActorContext().getSnapshotManager().isCapturing());
// The commit is needed to complete the snapshot creation process
followerActor.getRaftActorContext().getSnapshotManager().commit(-1, -1);
// capture snapshot reply should remove the snapshotted entries only till replicatedToAllIndex
// indexes 5,6,7 left in the log
assertEquals(3, followerActor.getReplicatedLog().size());
assertEquals(7, followerActor.getReplicatedLog().lastIndex());
entries = Arrays.asList((ReplicatedLogEntry) new SimpleReplicatedLogEntry(8, 1, new MockRaftActorContext.MockPayload("foo-7")));
// send an additional entry 8 with leaderCommit = 7
followerActor.onReceiveCommand(new AppendEntries(1, leaderId, 7, 1, entries, 7, 7, (short) 0));
// 7 and 8, as lastapplied is 7
assertEquals(2, followerActor.getReplicatedLog().size());
}
use of org.opendaylight.controller.cluster.DataPersistenceProvider in project controller by opendaylight.
the class RaftActorTest method testRealSnapshotWhenReplicatedToAllIndexNotInReplicatedLog.
@Test
public void testRealSnapshotWhenReplicatedToAllIndexNotInReplicatedLog() throws Exception {
String persistenceId = factory.generateActorId("leader-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
config.setIsolatedLeaderCheckInterval(new FiniteDuration(1, TimeUnit.DAYS));
config.setSnapshotBatchCount(5);
DataPersistenceProvider dataPersistenceProvider = createProvider();
Map<String, String> peerAddresses = ImmutableMap.<String, String>builder().put("member1", "address").build();
TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId, peerAddresses, config, dataPersistenceProvider), persistenceId);
MockRaftActor leaderActor = mockActorRef.underlyingActor();
leaderActor.getRaftActorContext().setCommitIndex(3);
leaderActor.getRaftActorContext().setLastApplied(3);
leaderActor.getRaftActorContext().getTermInformation().update(1, persistenceId);
leaderActor.getReplicatedLog().setSnapshotIndex(3);
leaderActor.waitForInitializeBehaviorComplete();
Leader leader = new Leader(leaderActor.getRaftActorContext());
leaderActor.setCurrentBehavior(leader);
leader.setReplicatedToAllIndex(3);
assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
// Persist another entry (this will cause a CaptureSnapshot to be triggered
leaderActor.persistData(mockActorRef, new MockIdentifier("x"), new MockRaftActorContext.MockPayload("duh"), false);
// Now send a CaptureSnapshotReply
mockActorRef.tell(new CaptureSnapshotReply(ByteState.of(fromObject("foo").toByteArray()), java.util.Optional.empty()), mockActorRef);
// Trimming log in this scenario is a no-op
assertEquals(3, leaderActor.getReplicatedLog().getSnapshotIndex());
assertTrue(leaderActor.getRaftActorContext().getSnapshotManager().isCapturing());
assertEquals(3, leader.getReplicatedToAllIndex());
}
use of org.opendaylight.controller.cluster.DataPersistenceProvider in project controller by opendaylight.
the class RaftActorTest method testSwitchBehavior.
@Test
public void testSwitchBehavior() {
String persistenceId = factory.generateActorId("leader-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
config.setCustomRaftPolicyImplementationClass(DisableElectionsRaftPolicy.class.getName());
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
config.setIsolatedLeaderCheckInterval(new FiniteDuration(1, TimeUnit.DAYS));
config.setSnapshotBatchCount(5);
DataPersistenceProvider dataPersistenceProvider = createProvider();
Map<String, String> peerAddresses = ImmutableMap.<String, String>builder().build();
TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId, peerAddresses, config, dataPersistenceProvider), persistenceId);
MockRaftActor leaderActor = mockActorRef.underlyingActor();
leaderActor.waitForRecoveryComplete();
leaderActor.handleCommand(new SwitchBehavior(RaftState.Follower, 100));
assertEquals(100, leaderActor.getRaftActorContext().getTermInformation().getCurrentTerm());
assertEquals(RaftState.Follower, leaderActor.getCurrentBehavior().state());
leaderActor.handleCommand(new SwitchBehavior(RaftState.Leader, 110));
assertEquals(110, leaderActor.getRaftActorContext().getTermInformation().getCurrentTerm());
assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
leaderActor.handleCommand(new SwitchBehavior(RaftState.Candidate, 125));
assertEquals(110, leaderActor.getRaftActorContext().getTermInformation().getCurrentTerm());
assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
leaderActor.handleCommand(new SwitchBehavior(RaftState.IsolatedLeader, 125));
assertEquals(110, leaderActor.getRaftActorContext().getTermInformation().getCurrentTerm());
assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
}
use of org.opendaylight.controller.cluster.DataPersistenceProvider in project controller by opendaylight.
the class RaftActorTest method testUpdateConfigParam.
@Test
public void testUpdateConfigParam() throws Exception {
DefaultConfigParamsImpl emptyConfig = new DefaultConfigParamsImpl();
String persistenceId = factory.generateActorId("follower-");
ImmutableMap<String, String> peerAddresses = ImmutableMap.<String, String>builder().put("member1", "address").build();
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
TestActorRef<MockRaftActor> actorRef = factory.createTestActor(MockRaftActor.props(persistenceId, peerAddresses, emptyConfig, dataPersistenceProvider), persistenceId);
MockRaftActor mockRaftActor = actorRef.underlyingActor();
mockRaftActor.waitForInitializeBehaviorComplete();
RaftActorBehavior behavior = mockRaftActor.getCurrentBehavior();
mockRaftActor.updateConfigParams(emptyConfig);
assertSame("Same Behavior", behavior, mockRaftActor.getCurrentBehavior());
assertEquals("Behavior State", RaftState.Follower, mockRaftActor.getCurrentBehavior().state());
DefaultConfigParamsImpl disableConfig = new DefaultConfigParamsImpl();
disableConfig.setCustomRaftPolicyImplementationClass("org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy");
mockRaftActor.updateConfigParams(disableConfig);
assertNotSame("Different Behavior", behavior, mockRaftActor.getCurrentBehavior());
assertEquals("Behavior State", RaftState.Follower, mockRaftActor.getCurrentBehavior().state());
behavior = mockRaftActor.getCurrentBehavior();
mockRaftActor.updateConfigParams(disableConfig);
assertSame("Same Behavior", behavior, mockRaftActor.getCurrentBehavior());
assertEquals("Behavior State", RaftState.Follower, mockRaftActor.getCurrentBehavior().state());
DefaultConfigParamsImpl defaultConfig = new DefaultConfigParamsImpl();
defaultConfig.setCustomRaftPolicyImplementationClass("org.opendaylight.controller.cluster.raft.policy.DefaultRaftPolicy");
mockRaftActor.updateConfigParams(defaultConfig);
assertNotSame("Different Behavior", behavior, mockRaftActor.getCurrentBehavior());
assertEquals("Behavior State", RaftState.Follower, mockRaftActor.getCurrentBehavior().state());
behavior = mockRaftActor.getCurrentBehavior();
mockRaftActor.updateConfigParams(defaultConfig);
assertSame("Same Behavior", behavior, mockRaftActor.getCurrentBehavior());
assertEquals("Behavior State", RaftState.Follower, mockRaftActor.getCurrentBehavior().state());
}
use of org.opendaylight.controller.cluster.DataPersistenceProvider in project controller by opendaylight.
the class RaftActorTest method testReplicateWithPersistencePending.
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testReplicateWithPersistencePending() throws Exception {
final String leaderId = factory.generateActorId("leader-");
final String followerId = factory.generateActorId("follower-");
final ActorRef followerActor = factory.createActor(MessageCollectorActor.props());
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
config.setIsolatedLeaderCheckInterval(new FiniteDuration(1, TimeUnit.DAYS));
DataPersistenceProvider mockPersistenceProvider = mock(DataPersistenceProvider.class);
doReturn(true).when(mockPersistenceProvider).isRecoveryApplicable();
TestActorRef<MockRaftActor> leaderActorRef = factory.createTestActor(MockRaftActor.props(leaderId, ImmutableMap.of(followerId, followerActor.path().toString()), config, mockPersistenceProvider), leaderId);
MockRaftActor leaderActor = leaderActorRef.underlyingActor();
leaderActor.waitForInitializeBehaviorComplete();
leaderActor.getRaftActorContext().getTermInformation().update(1, leaderId);
Leader leader = new Leader(leaderActor.getRaftActorContext());
leaderActor.setCurrentBehavior(leader);
leaderActor.persistData(leaderActorRef, new MockIdentifier("1"), new MockRaftActorContext.MockPayload("1"), false);
ReplicatedLogEntry logEntry = leaderActor.getReplicatedLog().get(0);
assertNotNull("ReplicatedLogEntry not found", logEntry);
assertEquals("isPersistencePending", true, logEntry.isPersistencePending());
assertEquals("getCommitIndex", -1, leaderActor.getRaftActorContext().getCommitIndex());
leaderActor.onReceiveCommand(new AppendEntriesReply(followerId, 1, true, 0, 1, (short) 0));
assertEquals("getCommitIndex", -1, leaderActor.getRaftActorContext().getCommitIndex());
ArgumentCaptor<Procedure> callbackCaptor = ArgumentCaptor.forClass(Procedure.class);
verify(mockPersistenceProvider).persistAsync(eq(logEntry), callbackCaptor.capture());
callbackCaptor.getValue().apply(logEntry);
assertEquals("getCommitIndex", 0, leaderActor.getRaftActorContext().getCommitIndex());
assertEquals("getLastApplied", 0, leaderActor.getRaftActorContext().getLastApplied());
}
Aggregations