+ @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,
+ Optional.<ConfigParams>of(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());
+ }
+
+ @Test
+ public void testGetSnapshot() throws Exception {
+ TEST_LOG.info("testGetSnapshot starting");
+
+ JavaTestKit kit = new JavaTestKit(getSystem());
+
+ String persistenceId = factory.generateActorId("test-actor-");
+ DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
+ config.setCustomRaftPolicyImplementationClass(DisableElectionsRaftPolicy.class.getName());
+
+ long term = 3;
+ long seqN = 1;
+ InMemoryJournal.addEntry(persistenceId, seqN++, new UpdateElectionTerm(term, "member-1"));
+ InMemoryJournal.addEntry(persistenceId, seqN++, new MockRaftActorContext.MockReplicatedLogEntry(term, 0,
+ new MockRaftActorContext.MockPayload("A")));
+ InMemoryJournal.addEntry(persistenceId, seqN++, new MockRaftActorContext.MockReplicatedLogEntry(term, 1,
+ new MockRaftActorContext.MockPayload("B")));
+ InMemoryJournal.addEntry(persistenceId, seqN++, new ApplyJournalEntries(1));
+ InMemoryJournal.addEntry(persistenceId, seqN++, new MockRaftActorContext.MockReplicatedLogEntry(term, 2,
+ new MockRaftActorContext.MockPayload("C")));
+
+ TestActorRef<MockRaftActor> raftActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
+ ImmutableMap.<String, String>builder().put("member1", "address").build(), Optional.<ConfigParams>of(config)).
+ withDispatcher(Dispatchers.DefaultDispatcherId()), persistenceId);
+ MockRaftActor mockRaftActor = raftActorRef.underlyingActor();
+
+ mockRaftActor.waitForRecoveryComplete();
+
+ // Wait for snapshot after recovery
+ verify(mockRaftActor.snapshotCohortDelegate, timeout(5000)).createSnapshot(any(ActorRef.class));
+
+ mockRaftActor.snapshotCohortDelegate = mock(RaftActorSnapshotCohort.class);
+
+ raftActorRef.tell(GetSnapshot.INSTANCE, kit.getRef());
+
+ ArgumentCaptor<ActorRef> replyActor = ArgumentCaptor.forClass(ActorRef.class);
+ verify(mockRaftActor.snapshotCohortDelegate, timeout(5000)).createSnapshot(replyActor.capture());
+
+ byte[] stateSnapshot = new byte[]{1,2,3};
+ replyActor.getValue().tell(new CaptureSnapshotReply(stateSnapshot), ActorRef.noSender());
+
+ GetSnapshotReply reply = kit.expectMsgClass(GetSnapshotReply.class);
+
+ assertEquals("getId", persistenceId, reply.getId());
+ Snapshot replySnapshot = SerializationUtils.deserialize(reply.getSnapshot());
+ assertEquals("getElectionTerm", term, replySnapshot.getElectionTerm());
+ assertEquals("getElectionVotedFor", "member-1", replySnapshot.getElectionVotedFor());
+ assertEquals("getLastAppliedIndex", 1L, replySnapshot.getLastAppliedIndex());
+ assertEquals("getLastAppliedTerm", term, replySnapshot.getLastAppliedTerm());
+ assertEquals("getLastIndex", 2L, replySnapshot.getLastIndex());
+ assertEquals("getLastTerm", term, replySnapshot.getLastTerm());
+ assertArrayEquals("getState", stateSnapshot, replySnapshot.getState());
+ assertEquals("getUnAppliedEntries size", 1, replySnapshot.getUnAppliedEntries().size());
+ assertEquals("UnApplied entry index ", 2L, replySnapshot.getUnAppliedEntries().get(0).getIndex());
+
+ // Test with timeout
+
+ mockRaftActor.getSnapshotMessageSupport().setSnapshotReplyActorTimeout(Duration.create(200, TimeUnit.MILLISECONDS));
+ reset(mockRaftActor.snapshotCohortDelegate);
+
+ raftActorRef.tell(GetSnapshot.INSTANCE, kit.getRef());
+ Failure failure = kit.expectMsgClass(akka.actor.Status.Failure.class);
+ assertEquals("Failure cause type", TimeoutException.class, failure.cause().getClass());
+
+ mockRaftActor.getSnapshotMessageSupport().setSnapshotReplyActorTimeout(Duration.create(30, TimeUnit.SECONDS));
+
+ // Test with persistence disabled.
+
+ mockRaftActor.setPersistence(false);
+ reset(mockRaftActor.snapshotCohortDelegate);
+
+ raftActorRef.tell(GetSnapshot.INSTANCE, kit.getRef());
+ reply = kit.expectMsgClass(GetSnapshotReply.class);
+ verify(mockRaftActor.snapshotCohortDelegate, never()).createSnapshot(any(ActorRef.class));
+
+ assertEquals("getId", persistenceId, reply.getId());
+ replySnapshot = SerializationUtils.deserialize(reply.getSnapshot());
+ assertEquals("getElectionTerm", term, replySnapshot.getElectionTerm());
+ assertEquals("getElectionVotedFor", "member-1", replySnapshot.getElectionVotedFor());
+ assertEquals("getLastAppliedIndex", -1L, replySnapshot.getLastAppliedIndex());
+ assertEquals("getLastAppliedTerm", -1L, replySnapshot.getLastAppliedTerm());
+ assertEquals("getLastIndex", -1L, replySnapshot.getLastIndex());
+ assertEquals("getLastTerm", -1L, replySnapshot.getLastTerm());
+ assertEquals("getState length", 0, replySnapshot.getState().length);
+ assertEquals("getUnAppliedEntries size", 0, replySnapshot.getUnAppliedEntries().size());
+
+ TEST_LOG.info("testGetSnapshot ending");
+ }