X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-akka-raft%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fraft%2FRaftActorRecoverySupportTest.java;h=828e3eb89e09c3a087576bf2e9e3e338bb93caa4;hp=6d5e7e7a314ea920a3e7af14a6a719902feb8667;hb=6751227ff9443018d75e3a99da5693230d23d82b;hpb=e1eca73a5ae2ffae8dd78c6fe5281cd2f45d5ef3 diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorRecoverySupportTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorRecoverySupportTest.java index 6d5e7e7a31..828e3eb89e 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorRecoverySupportTest.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorRecoverySupportTest.java @@ -10,9 +10,10 @@ package org.opendaylight.controller.cluster.raft; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.mockito.AdditionalMatchers.aryEq; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; @@ -23,8 +24,11 @@ import akka.persistence.RecoveryCompleted; import akka.persistence.SnapshotMetadata; import akka.persistence.SnapshotOffer; import com.google.common.collect.Sets; +import java.io.Serializable; import java.util.Arrays; import java.util.Collections; +import java.util.List; +import org.apache.commons.lang3.SerializationUtils; import org.hamcrest.Description; import org.junit.Before; import org.junit.Test; @@ -36,10 +40,14 @@ import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.opendaylight.controller.cluster.DataPersistenceProvider; import org.opendaylight.controller.cluster.PersistentDataProvider; +import org.opendaylight.controller.cluster.raft.MockRaftActor.MockSnapshotState; +import org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload; import org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries; import org.opendaylight.controller.cluster.raft.persisted.DeleteEntries; import org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload; import org.opendaylight.controller.cluster.raft.persisted.ServerInfo; +import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry; +import org.opendaylight.controller.cluster.raft.persisted.Snapshot; import org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm; import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload; import org.slf4j.Logger; @@ -61,6 +69,9 @@ public class RaftActorRecoverySupportTest { @Mock private RaftActorRecoveryCohort mockCohort; + @Mock + private RaftActorSnapshotCohort mockSnapshotCohort; + @Mock PersistentDataProvider mockPersistentProvider; @@ -76,7 +87,8 @@ public class RaftActorRecoverySupportTest { MockitoAnnotations.initMocks(this); context = new RaftActorContextImpl(null, null, localId, new ElectionTermImpl(mockPersistentProvider, "test", - LOG), -1, -1, Collections.emptyMap(), configParams, mockPersistence, LOG); + LOG), -1, -1, Collections.emptyMap(), configParams, + mockPersistence, applyState -> { }, LOG); support = new RaftActorRecoverySupport(context, mockCohort); @@ -96,8 +108,7 @@ public class RaftActorRecoverySupportTest { @Test public void testOnReplicatedLogEntry() { - MockRaftActorContext.MockReplicatedLogEntry logEntry = new MockRaftActorContext.MockReplicatedLogEntry(1, - 1, new MockRaftActorContext.MockPayload("1", 5)); + ReplicatedLogEntry logEntry = new SimpleReplicatedLogEntry(1, 1, new MockRaftActorContext.MockPayload("1", 5)); sendMessageToSupport(logEntry); @@ -115,18 +126,12 @@ public class RaftActorRecoverySupportTest { configParams.setJournalRecoveryLogBatchSize(5); ReplicatedLog replicatedLog = context.getReplicatedLog(); - replicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, - 0, new MockRaftActorContext.MockPayload("0"))); - replicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, - 1, new MockRaftActorContext.MockPayload("1"))); - replicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, - 2, new MockRaftActorContext.MockPayload("2"))); - replicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, - 3, new MockRaftActorContext.MockPayload("3"))); - replicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, - 4, new MockRaftActorContext.MockPayload("4"))); - replicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, - 5, new MockRaftActorContext.MockPayload("5"))); + replicatedLog.append(new SimpleReplicatedLogEntry(0, 1, new MockRaftActorContext.MockPayload("0"))); + replicatedLog.append(new SimpleReplicatedLogEntry(1, 1, new MockRaftActorContext.MockPayload("1"))); + replicatedLog.append(new SimpleReplicatedLogEntry(2, 1, new MockRaftActorContext.MockPayload("2"))); + replicatedLog.append(new SimpleReplicatedLogEntry(3, 1, new MockRaftActorContext.MockPayload("3"))); + replicatedLog.append(new SimpleReplicatedLogEntry(4, 1, new MockRaftActorContext.MockPayload("4"))); + replicatedLog.append(new SimpleReplicatedLogEntry(5, 1, new MockRaftActorContext.MockPayload("5"))); sendMessageToSupport(new ApplyJournalEntries(2)); @@ -164,32 +169,75 @@ public class RaftActorRecoverySupportTest { public void testOnSnapshotOffer() { ReplicatedLog replicatedLog = context.getReplicatedLog(); - replicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, - 1, new MockRaftActorContext.MockPayload("1"))); - replicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, - 2, new MockRaftActorContext.MockPayload("2"))); - replicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, - 3, new MockRaftActorContext.MockPayload("3"))); + replicatedLog.append(new SimpleReplicatedLogEntry(1, 1, new MockRaftActorContext.MockPayload("1"))); + replicatedLog.append(new SimpleReplicatedLogEntry(2, 1, new MockRaftActorContext.MockPayload("2"))); + replicatedLog.append(new SimpleReplicatedLogEntry(3, 1, new MockRaftActorContext.MockPayload("3"))); + + ReplicatedLogEntry unAppliedEntry1 = new SimpleReplicatedLogEntry(4, 1, + new MockRaftActorContext.MockPayload("4", 4)); + + ReplicatedLogEntry unAppliedEntry2 = new SimpleReplicatedLogEntry(5, 1, + new MockRaftActorContext.MockPayload("5", 5)); + + long lastAppliedDuringSnapshotCapture = 3; + long lastIndexDuringSnapshotCapture = 5; + long electionTerm = 2; + String electionVotedFor = "member-2"; - byte[] snapshotBytes = {1,2,3,4,5}; + MockSnapshotState snapshotState = new MockSnapshotState(Arrays.asList(new MockPayload("1"))); + Snapshot snapshot = Snapshot.create(snapshotState, + Arrays.asList(unAppliedEntry1, unAppliedEntry2), lastIndexDuringSnapshotCapture, 1, + lastAppliedDuringSnapshotCapture, 1, electionTerm, electionVotedFor, null); - ReplicatedLogEntry unAppliedEntry1 = new MockRaftActorContext.MockReplicatedLogEntry(1, - 4, new MockRaftActorContext.MockPayload("4", 4)); + SnapshotMetadata metadata = new SnapshotMetadata("test", 6, 12345); + SnapshotOffer snapshotOffer = new SnapshotOffer(metadata , snapshot); - ReplicatedLogEntry unAppliedEntry2 = new MockRaftActorContext.MockReplicatedLogEntry(1, - 5, new MockRaftActorContext.MockPayload("5", 5)); + sendMessageToSupport(snapshotOffer); + + assertEquals("Journal log size", 2, context.getReplicatedLog().size()); + assertEquals("Journal data size", 9, context.getReplicatedLog().dataSize()); + assertEquals("Last index", lastIndexDuringSnapshotCapture, context.getReplicatedLog().lastIndex()); + assertEquals("Last applied", lastAppliedDuringSnapshotCapture, context.getLastApplied()); + assertEquals("Commit index", lastAppliedDuringSnapshotCapture, context.getCommitIndex()); + assertEquals("Snapshot term", 1, context.getReplicatedLog().getSnapshotTerm()); + assertEquals("Snapshot index", lastAppliedDuringSnapshotCapture, context.getReplicatedLog().getSnapshotIndex()); + assertEquals("Election term", electionTerm, context.getTermInformation().getCurrentTerm()); + assertEquals("Election votedFor", electionVotedFor, context.getTermInformation().getVotedFor()); + assertFalse("Dynamic server configuration", context.isDynamicServerConfigurationInUse()); + + verify(mockCohort).applyRecoverySnapshot(snapshotState); + } + + @Deprecated + @Test + public void testOnSnapshotOfferWithPreCarbonSnapshot() { + + ReplicatedLogEntry unAppliedEntry1 = new SimpleReplicatedLogEntry(4, 1, + new MockRaftActorContext.MockPayload("4", 4)); + + ReplicatedLogEntry unAppliedEntry2 = new SimpleReplicatedLogEntry(5, 1, + new MockRaftActorContext.MockPayload("5", 5)); long lastAppliedDuringSnapshotCapture = 3; long lastIndexDuringSnapshotCapture = 5; long electionTerm = 2; String electionVotedFor = "member-2"; - Snapshot snapshot = Snapshot.create(snapshotBytes, Arrays.asList(unAppliedEntry1, unAppliedEntry2), - lastIndexDuringSnapshotCapture, 1, lastAppliedDuringSnapshotCapture, 1, electionTerm, electionVotedFor); + List snapshotData = Arrays.asList(new MockPayload("1")); + final MockSnapshotState snapshotState = new MockSnapshotState(snapshotData); + + org.opendaylight.controller.cluster.raft.Snapshot snapshot = org.opendaylight.controller.cluster.raft.Snapshot + .create(SerializationUtils.serialize((Serializable) snapshotData), + Arrays.asList(unAppliedEntry1, unAppliedEntry2), lastIndexDuringSnapshotCapture, 1, + lastAppliedDuringSnapshotCapture, 1, electionTerm, electionVotedFor, null); SnapshotMetadata metadata = new SnapshotMetadata("test", 6, 12345); SnapshotOffer snapshotOffer = new SnapshotOffer(metadata , snapshot); + doAnswer(invocation -> new MockSnapshotState(SerializationUtils.deserialize( + invocation.getArgumentAt(0, byte[].class)))) + .when(mockCohort).deserializePreCarbonSnapshot(any(byte[].class)); + sendMessageToSupport(snapshotOffer); assertEquals("Journal log size", 2, context.getReplicatedLog().size()); @@ -203,16 +251,14 @@ public class RaftActorRecoverySupportTest { assertEquals("Election votedFor", electionVotedFor, context.getTermInformation().getVotedFor()); assertFalse("Dynamic server configuration", context.isDynamicServerConfigurationInUse()); - verify(mockCohort).applyRecoverySnapshot(snapshotBytes); + verify(mockCohort).applyRecoverySnapshot(snapshotState); } @Test public void testOnRecoveryCompletedWithRemainingBatch() { ReplicatedLog replicatedLog = context.getReplicatedLog(); - replicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, - 0, new MockRaftActorContext.MockPayload("0"))); - replicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, - 1, new MockRaftActorContext.MockPayload("1"))); + replicatedLog.append(new SimpleReplicatedLogEntry(0, 1, new MockRaftActorContext.MockPayload("0"))); + replicatedLog.append(new SimpleReplicatedLogEntry(1, 1, new MockRaftActorContext.MockPayload("1"))); sendMessageToSupport(new ApplyJournalEntries(1)); @@ -244,12 +290,9 @@ public class RaftActorRecoverySupportTest { @Test public void testOnDeleteEntries() { ReplicatedLog replicatedLog = context.getReplicatedLog(); - replicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, - 0, new MockRaftActorContext.MockPayload("0"))); - replicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, - 1, new MockRaftActorContext.MockPayload("1"))); - replicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, - 2, new MockRaftActorContext.MockPayload("2"))); + replicatedLog.append(new SimpleReplicatedLogEntry(0, 1, new MockRaftActorContext.MockPayload("0"))); + replicatedLog.append(new SimpleReplicatedLogEntry(1, 1, new MockRaftActorContext.MockPayload("1"))); + replicatedLog.append(new SimpleReplicatedLogEntry(2, 1, new MockRaftActorContext.MockPayload("2"))); sendMessageToSupport(new DeleteEntries(1)); @@ -268,21 +311,20 @@ public class RaftActorRecoverySupportTest { @Test public void testDataRecoveredWithPersistenceDisabled() { - doNothing().when(mockCohort).applyRecoverySnapshot(aryEq(new byte[0])); + doNothing().when(mockCohort).applyRecoverySnapshot(anyObject()); doReturn(false).when(mockPersistence).isRecoveryApplicable(); doReturn(10L).when(mockPersistentProvider).getLastSequenceNumber(); - Snapshot snapshot = Snapshot.create(new byte[]{1}, Collections.emptyList(), 3, 1, 3, 1); + Snapshot snapshot = Snapshot.create(new MockSnapshotState(Arrays.asList(new MockPayload("1"))), + Collections.emptyList(), 3, 1, 3, 1, -1, null, null); SnapshotOffer snapshotOffer = new SnapshotOffer(new SnapshotMetadata("test", 6, 12345), snapshot); sendMessageToSupport(snapshotOffer); sendMessageToSupport(new UpdateElectionTerm(5, "member2")); - sendMessageToSupport(new MockRaftActorContext.MockReplicatedLogEntry(1, - 4, new MockRaftActorContext.MockPayload("4"))); - sendMessageToSupport(new MockRaftActorContext.MockReplicatedLogEntry(1, - 5, new MockRaftActorContext.MockPayload("5"))); + sendMessageToSupport(new SimpleReplicatedLogEntry(4, 1, new MockRaftActorContext.MockPayload("4"))); + sendMessageToSupport(new SimpleReplicatedLogEntry(5, 1, new MockRaftActorContext.MockPayload("5"))); sendMessageToSupport(new ApplyJournalEntries(4)); @@ -300,7 +342,7 @@ public class RaftActorRecoverySupportTest { sendMessageToSupport(RecoveryCompleted.getInstance(), true); - verify(mockCohort).applyRecoverySnapshot(aryEq(new byte[0])); + verify(mockCohort, never()).applyRecoverySnapshot(anyObject()); verify(mockCohort, never()).getRestoreFromSnapshot(); verifyNoMoreInteractions(mockCohort); @@ -353,7 +395,7 @@ public class RaftActorRecoverySupportTest { new ServerInfo(follower2, false), new ServerInfo(follower3, true))); - sendMessageToSupport(new MockRaftActorContext.MockReplicatedLogEntry(1, 0, obj)); + sendMessageToSupport(new SimpleReplicatedLogEntry(0, 1, obj)); //verify new peers assertTrue("Dynamic server configuration", context.isDynamicServerConfigurationInUse()); @@ -374,7 +416,7 @@ public class RaftActorRecoverySupportTest { new ServerInfo("follower2", true), new ServerInfo("follower3", true))); - sendMessageToSupport(new MockRaftActorContext.MockReplicatedLogEntry(1, 1, obj)); + sendMessageToSupport(new SimpleReplicatedLogEntry(1, 1, obj)); //verify new peers assertTrue("Dynamic server configuration", context.isDynamicServerConfigurationInUse()); @@ -389,7 +431,7 @@ public class RaftActorRecoverySupportTest { ServerConfigurationPayload obj = new ServerConfigurationPayload(Arrays.asList( new ServerInfo(localId, true), new ServerInfo(follower, true))); - sendMessageToSupport(new MockRaftActorContext.MockReplicatedLogEntry(1, 0, obj)); + sendMessageToSupport(new SimpleReplicatedLogEntry(0, 1, obj)); //verify new peers assertEquals("New peer Ids", Sets.newHashSet(follower), Sets.newHashSet(context.getPeerIds())); @@ -404,7 +446,8 @@ public class RaftActorRecoverySupportTest { new ServerInfo("follower1", true), new ServerInfo("follower2", true))); - Snapshot snapshot = Snapshot.create(new byte[]{1}, Collections.emptyList(), + MockSnapshotState snapshotState = new MockSnapshotState(Arrays.asList(new MockPayload("1"))); + Snapshot snapshot = Snapshot.create(snapshotState, Collections.emptyList(), -1, -1, -1, -1, electionTerm, electionVotedFor, serverPayload); SnapshotMetadata metadata = new SnapshotMetadata("test", 6, 12345);