Search in sources :

Example 31 with TestKit

use of akka.testkit.javadsl.TestKit in project controller by opendaylight.

the class FollowerTest method testCaptureSnapshotOnMiddleEntryInAppendEntries.

@Test
public void testCaptureSnapshotOnMiddleEntryInAppendEntries() {
    String id = "testCaptureSnapshotOnMiddleEntryInAppendEntries";
    logStart(id);
    InMemoryJournal.addEntry(id, 1, new UpdateElectionTerm(1, null));
    DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
    config.setSnapshotBatchCount(2);
    config.setCustomRaftPolicyImplementationClass(DisableElectionsRaftPolicy.class.getName());
    final AtomicReference<MockRaftActor> followerRaftActor = new AtomicReference<>();
    RaftActorSnapshotCohort snapshotCohort = newRaftActorSnapshotCohort(followerRaftActor);
    Builder builder = MockRaftActor.builder().persistent(Optional.of(true)).id(id).peerAddresses(ImmutableMap.of("leader", "")).config(config).snapshotCohort(snapshotCohort);
    TestActorRef<MockRaftActor> followerActorRef = actorFactory.createTestActor(builder.props().withDispatcher(Dispatchers.DefaultDispatcherId()), id);
    followerRaftActor.set(followerActorRef.underlyingActor());
    followerRaftActor.get().waitForInitializeBehaviorComplete();
    InMemorySnapshotStore.addSnapshotSavedLatch(id);
    InMemoryJournal.addDeleteMessagesCompleteLatch(id);
    InMemoryJournal.addWriteMessagesCompleteLatch(id, 1, ApplyJournalEntries.class);
    List<ReplicatedLogEntry> entries = Arrays.asList(newReplicatedLogEntry(1, 0, "one"), newReplicatedLogEntry(1, 1, "two"), newReplicatedLogEntry(1, 2, "three"));
    AppendEntries appendEntries = new AppendEntries(1, "leader", -1, -1, entries, 2, -1, (short) 0);
    followerActorRef.tell(appendEntries, leaderActor);
    AppendEntriesReply reply = MessageCollectorActor.expectFirstMatching(leaderActor, AppendEntriesReply.class);
    assertEquals("isSuccess", true, reply.isSuccess());
    final Snapshot snapshot = InMemorySnapshotStore.waitForSavedSnapshot(id, Snapshot.class);
    InMemoryJournal.waitForDeleteMessagesComplete(id);
    InMemoryJournal.waitForWriteMessagesComplete(id);
    // We expect the ApplyJournalEntries for index 2 to remain in the persisted log b/c it's still queued for
    // persistence by the time we initiate capture so the last persisted journal sequence number doesn't include it.
    // This is OK - on recovery it will be a no-op since index 2 has already been applied.
    List<Object> journalEntries = InMemoryJournal.get(id, Object.class);
    assertEquals("Persisted journal entries size: " + journalEntries, 1, journalEntries.size());
    assertEquals("Persisted journal entry type", ApplyJournalEntries.class, journalEntries.get(0).getClass());
    assertEquals("ApplyJournalEntries index", 2, ((ApplyJournalEntries) journalEntries.get(0)).getToIndex());
    assertEquals("Snapshot unapplied size", 0, snapshot.getUnAppliedEntries().size());
    assertEquals("Snapshot getLastAppliedTerm", 1, snapshot.getLastAppliedTerm());
    assertEquals("Snapshot getLastAppliedIndex", 2, snapshot.getLastAppliedIndex());
    assertEquals("Snapshot getLastTerm", 1, snapshot.getLastTerm());
    assertEquals("Snapshot getLastIndex", 2, snapshot.getLastIndex());
    assertEquals("Snapshot state", ImmutableList.of(entries.get(0).getData(), entries.get(1).getData(), entries.get(2).getData()), MockRaftActor.fromState(snapshot.getState()));
    assertEquals("Journal size", 0, followerRaftActor.get().getReplicatedLog().size());
    assertEquals("Snapshot index", 2, followerRaftActor.get().getReplicatedLog().getSnapshotIndex());
    // Reinstate the actor from persistence
    actorFactory.killActor(followerActorRef, new TestKit(getSystem()));
    followerActorRef = actorFactory.createTestActor(builder.props().withDispatcher(Dispatchers.DefaultDispatcherId()), id);
    followerRaftActor.set(followerActorRef.underlyingActor());
    followerRaftActor.get().waitForInitializeBehaviorComplete();
    assertEquals("Journal size", 0, followerRaftActor.get().getReplicatedLog().size());
    assertEquals("Last index", 2, followerRaftActor.get().getReplicatedLog().lastIndex());
    assertEquals("Last applied index", 2, followerRaftActor.get().getRaftActorContext().getLastApplied());
    assertEquals("Commit index", 2, followerRaftActor.get().getRaftActorContext().getCommitIndex());
    assertEquals("State", ImmutableList.of(entries.get(0).getData(), entries.get(1).getData(), entries.get(2).getData()), followerRaftActor.get().getState());
}
Also used : Builder(org.opendaylight.controller.cluster.raft.MockRaftActor.Builder) DefaultConfigParamsImpl(org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl) AtomicReference(java.util.concurrent.atomic.AtomicReference) ByteString(com.google.protobuf.ByteString) AppendEntries(org.opendaylight.controller.cluster.raft.messages.AppendEntries) TestKit(akka.testkit.javadsl.TestKit) MockRaftActor(org.opendaylight.controller.cluster.raft.MockRaftActor) ApplySnapshot(org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot) Snapshot(org.opendaylight.controller.cluster.raft.persisted.Snapshot) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) ReplicatedLogEntry(org.opendaylight.controller.cluster.raft.ReplicatedLogEntry) RaftActorSnapshotCohort(org.opendaylight.controller.cluster.raft.RaftActorSnapshotCohort) AppendEntriesReply(org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply) DisableElectionsRaftPolicy(org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy) UpdateElectionTerm(org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm) Test(org.junit.Test)

Example 32 with TestKit

use of akka.testkit.javadsl.TestKit in project controller by opendaylight.

the class ShardManagerGetSnapshotReplyActorTest method testGetSnapshotFailureReply.

@Test
public void testGetSnapshotFailureReply() {
    TestKit kit = new TestKit(getSystem());
    ActorRef replyActor = getSystem().actorOf(ShardManagerGetSnapshotReplyActor.props(Arrays.asList("shard1", "shard2"), "config", null, kit.getRef(), "shard-manager", Duration.create(100, TimeUnit.SECONDS)), "testGetSnapshotFailureReply");
    kit.watch(replyActor);
    replyActor.tell(new GetSnapshotReply(ShardIdentifier.create("shard1", MEMBER_1, "config").toString(), Snapshot.create(ByteState.of(new byte[] { 1, 2, 3 }), Collections.<ReplicatedLogEntry>emptyList(), 2, 1, 2, 1, 1, "member-1", null)), ActorRef.noSender());
    replyActor.tell(new Failure(new RuntimeException()), ActorRef.noSender());
    kit.expectMsgClass(Failure.class);
    kit.expectTerminated(replyActor);
}
Also used : ActorRef(akka.actor.ActorRef) TestKit(akka.testkit.javadsl.TestKit) Failure(akka.actor.Status.Failure) GetSnapshotReply(org.opendaylight.controller.cluster.raft.client.messages.GetSnapshotReply) AbstractActorTest(org.opendaylight.controller.cluster.datastore.AbstractActorTest) Test(org.junit.Test)

Example 33 with TestKit

use of akka.testkit.javadsl.TestKit in project controller by opendaylight.

the class ShardManagerTest method testShardPersistenceWithRestoredData.

@Test
public void testShardPersistenceWithRestoredData() throws Exception {
    LOG.info("testShardPersistenceWithRestoredData starting");
    new TestKit(getSystem()) {

        {
            MockConfiguration mockConfig = new MockConfiguration(ImmutableMap.<String, List<String>>builder().put("default", Arrays.asList("member-1", "member-2")).put("astronauts", Arrays.asList("member-2")).put("people", Arrays.asList("member-1", "member-2")).build());
            String[] restoredShards = { "default", "astronauts" };
            ShardManagerSnapshot snapshot = new ShardManagerSnapshot(Arrays.asList(restoredShards), Collections.emptyMap());
            InMemorySnapshotStore.addSnapshot("shard-manager-" + shardMrgIDSuffix, snapshot);
            // create shardManager to come up with restored data
            TestActorRef<TestShardManager> newRestoredShardManager = actorFactory.createTestActor(newShardMgrProps(mockConfig).withDispatcher(Dispatchers.DefaultDispatcherId()));
            newRestoredShardManager.underlyingActor().waitForRecoveryComplete();
            newRestoredShardManager.tell(new FindLocalShard("people", false), getRef());
            LocalShardNotFound notFound = expectMsgClass(duration("5 seconds"), LocalShardNotFound.class);
            assertEquals("for uninitialized shard", "people", notFound.getShardName());
            // Verify a local shard is created for the restored shards,
            // although we expect a NotInitializedException for the shards
            // as the actor initialization
            // message is not sent for them
            newRestoredShardManager.tell(new FindLocalShard("default", false), getRef());
            expectMsgClass(duration("5 seconds"), NotInitializedException.class);
            newRestoredShardManager.tell(new FindLocalShard("astronauts", false), getRef());
            expectMsgClass(duration("5 seconds"), NotInitializedException.class);
        }
    };
    LOG.info("testShardPersistenceWithRestoredData ending");
}
Also used : LocalShardNotFound(org.opendaylight.controller.cluster.datastore.messages.LocalShardNotFound) ShardManagerSnapshot(org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot) FindLocalShard(org.opendaylight.controller.cluster.datastore.messages.FindLocalShard) MockConfiguration(org.opendaylight.controller.cluster.datastore.utils.MockConfiguration) TestKit(akka.testkit.javadsl.TestKit) AddressFromURIString(akka.actor.AddressFromURIString) Test(org.junit.Test) AbstractShardManagerTest(org.opendaylight.controller.cluster.datastore.AbstractShardManagerTest)

Example 34 with TestKit

use of akka.testkit.javadsl.TestKit in project controller by opendaylight.

the class ShardManagerTest method testRoleChangeNotificationToFollowerWithShardLeaderStateChangedReleaseReady.

@Test
public void testRoleChangeNotificationToFollowerWithShardLeaderStateChangedReleaseReady() throws Exception {
    new TestKit(getSystem()) {

        {
            TestShardManager shardManager = newTestShardManager();
            String memberId = "member-1-shard-default-" + shardMrgIDSuffix;
            shardManager.onReceiveCommand(new RoleChangeNotification(memberId, null, RaftState.Follower.name()));
            verify(ready, never()).countDown();
            shardManager.onReceiveCommand(MockClusterWrapper.createMemberUp("member-2", getRef().path().toString()));
            shardManager.onReceiveCommand(new ShardLeaderStateChanged(memberId, "member-2-shard-default-" + shardMrgIDSuffix, mock(DataTree.class), DataStoreVersions.CURRENT_VERSION));
            verify(ready, times(1)).countDown();
        }
    };
}
Also used : ShardLeaderStateChanged(org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged) RoleChangeNotification(org.opendaylight.controller.cluster.notifications.RoleChangeNotification) TestKit(akka.testkit.javadsl.TestKit) AddressFromURIString(akka.actor.AddressFromURIString) Test(org.junit.Test) AbstractShardManagerTest(org.opendaylight.controller.cluster.datastore.AbstractShardManagerTest)

Example 35 with TestKit

use of akka.testkit.javadsl.TestKit in project controller by opendaylight.

the class ShardManagerTest method testRemoveShardReplicaRemote.

@Test
public void testRemoveShardReplicaRemote() throws Exception {
    MockConfiguration mockConfig = new MockConfiguration(ImmutableMap.<String, List<String>>builder().put("default", Arrays.asList("member-1", "member-2")).put("astronauts", Arrays.asList("member-1")).build());
    String shardManagerID = ShardManagerIdentifier.builder().type(shardMrgIDSuffix).build().toString();
    // Create an ActorSystem ShardManager actor for member-1.
    final ActorSystem system1 = newActorSystem("Member1");
    Cluster.get(system1).join(AddressFromURIString.parse("akka://cluster-test@127.0.0.1:2558"));
    ActorRef mockDefaultShardActor = newMockShardActor(system1, Shard.DEFAULT_NAME, "member-1");
    final TestActorRef<TestShardManager> newReplicaShardManager = TestActorRef.create(system1, newTestShardMgrBuilder().configuration(mockConfig).shardActor(mockDefaultShardActor).cluster(new ClusterWrapperImpl(system1)).props().withDispatcher(Dispatchers.DefaultDispatcherId()), shardManagerID);
    // Create an ActorSystem ShardManager actor for member-2.
    final ActorSystem system2 = newActorSystem("Member2");
    Cluster.get(system2).join(AddressFromURIString.parse("akka://cluster-test@127.0.0.1:2558"));
    String name = ShardIdentifier.create("default", MEMBER_2, shardMrgIDSuffix).toString();
    String memberId2 = "member-2-shard-default-" + shardMrgIDSuffix;
    final TestActorRef<MockRespondActor> mockShardLeaderActor = TestActorRef.create(system2, Props.create(MockRespondActor.class, RemoveServer.class, new RemoveServerReply(ServerChangeStatus.OK, memberId2)), name);
    LOG.error("Mock Shard Leader Actor : {}", mockShardLeaderActor);
    final TestActorRef<TestShardManager> leaderShardManager = TestActorRef.create(system2, newTestShardMgrBuilder().configuration(mockConfig).shardActor(mockShardLeaderActor).cluster(new ClusterWrapperImpl(system2)).props().withDispatcher(Dispatchers.DefaultDispatcherId()), shardManagerID);
    // Because mockShardLeaderActor is created at the top level of the actor system it has an address like so,
    // akka://cluster-test@127.0.0.1:2559/user/member-2-shard-default-config1
    // However when a shard manager has a local shard which is a follower and a leader that is remote it will
    // try to compute an address for the remote shard leader using the ShardPeerAddressResolver. This address will
    // look like so,
    // akka://cluster-test@127.0.0.1:2559/user/shardmanager-config1/member-2-shard-default-config1
    // In this specific case if we did a FindPrimary for shard default from member-1 we would come up
    // with the address of an actor which does not exist, therefore any message sent to that actor would go to
    // dead letters.
    // To work around this problem we create a ForwardingActor with the right address and pass to it the
    // mockShardLeaderActor. The ForwardingActor simply forwards all messages to the mockShardLeaderActor and every
    // thing works as expected
    final ActorRef actorRef = leaderShardManager.underlyingActor().context().actorOf(Props.create(ForwardingActor.class, mockShardLeaderActor), "member-2-shard-default-" + shardMrgIDSuffix);
    LOG.error("Forwarding actor : {}", actorRef);
    new TestKit(system1) {

        {
            newReplicaShardManager.tell(new UpdateSchemaContext(TestModel.createTestContext()), getRef());
            leaderShardManager.tell(new UpdateSchemaContext(TestModel.createTestContext()), getRef());
            leaderShardManager.tell(new ActorInitialized(), mockShardLeaderActor);
            newReplicaShardManager.tell(new ActorInitialized(), mockShardLeaderActor);
            short leaderVersion = DataStoreVersions.CURRENT_VERSION - 1;
            leaderShardManager.tell(new ShardLeaderStateChanged(memberId2, memberId2, mock(DataTree.class), leaderVersion), mockShardLeaderActor);
            leaderShardManager.tell(new RoleChangeNotification(memberId2, RaftState.Candidate.name(), RaftState.Leader.name()), mockShardLeaderActor);
            String memberId1 = "member-1-shard-default-" + shardMrgIDSuffix;
            newReplicaShardManager.tell(new ShardLeaderStateChanged(memberId1, memberId2, mock(DataTree.class), leaderVersion), mockShardActor);
            newReplicaShardManager.tell(new RoleChangeNotification(memberId1, RaftState.Candidate.name(), RaftState.Follower.name()), mockShardActor);
            newReplicaShardManager.underlyingActor().waitForMemberUp();
            leaderShardManager.underlyingActor().waitForMemberUp();
            // construct a mock response message
            newReplicaShardManager.tell(new RemoveShardReplica("default", MEMBER_1), getRef());
            RemoveServer removeServer = MessageCollectorActor.expectFirstMatching(mockShardLeaderActor, RemoveServer.class);
            String removeServerId = ShardIdentifier.create("default", MEMBER_1, shardMrgIDSuffix).toString();
            assertEquals("RemoveServer serverId", removeServerId, removeServer.getServerId());
            expectMsgClass(duration("5 seconds"), Status.Success.class);
        }
    };
}
Also used : ActorSystem(akka.actor.ActorSystem) FollowerInitialSyncUpStatus(org.opendaylight.controller.cluster.raft.base.messages.FollowerInitialSyncUpStatus) ChangeShardMembersVotingStatus(org.opendaylight.controller.cluster.datastore.messages.ChangeShardMembersVotingStatus) Status(akka.actor.Status) ServerChangeStatus(org.opendaylight.controller.cluster.raft.messages.ServerChangeStatus) ChangeServersVotingStatus(org.opendaylight.controller.cluster.raft.messages.ChangeServersVotingStatus) ClusterWrapperImpl(org.opendaylight.controller.cluster.datastore.ClusterWrapperImpl) UpdateSchemaContext(org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext) ForwardingActor(org.opendaylight.controller.cluster.datastore.utils.ForwardingActor) ShardLeaderStateChanged(org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged) ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) RoleChangeNotification(org.opendaylight.controller.cluster.notifications.RoleChangeNotification) AddressFromURIString(akka.actor.AddressFromURIString) TestKit(akka.testkit.javadsl.TestKit) MockConfiguration(org.opendaylight.controller.cluster.datastore.utils.MockConfiguration) List(java.util.List) ActorInitialized(org.opendaylight.controller.cluster.datastore.messages.ActorInitialized) RemoveShardReplica(org.opendaylight.controller.cluster.datastore.messages.RemoveShardReplica) RemoveServer(org.opendaylight.controller.cluster.raft.messages.RemoveServer) RemoveServerReply(org.opendaylight.controller.cluster.raft.messages.RemoveServerReply) Test(org.junit.Test) AbstractShardManagerTest(org.opendaylight.controller.cluster.datastore.AbstractShardManagerTest)

Aggregations

TestKit (akka.testkit.javadsl.TestKit)124 Test (org.junit.Test)115 ActorRef (akka.actor.ActorRef)84 TestActorRef (akka.testkit.TestActorRef)63 AbstractShardManagerTest (org.opendaylight.controller.cluster.datastore.AbstractShardManagerTest)44 UpdateSchemaContext (org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext)37 AddressFromURIString (akka.actor.AddressFromURIString)28 ActorInitialized (org.opendaylight.controller.cluster.datastore.messages.ActorInitialized)26 FindLocalShard (org.opendaylight.controller.cluster.datastore.messages.FindLocalShard)22 RoleChangeNotification (org.opendaylight.controller.cluster.notifications.RoleChangeNotification)22 Configuration (org.opendaylight.controller.cluster.datastore.config.Configuration)17 ShardLeaderStateChanged (org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged)17 FindPrimary (org.opendaylight.controller.cluster.datastore.messages.FindPrimary)16 MockConfiguration (org.opendaylight.controller.cluster.datastore.utils.MockConfiguration)16 Props (akka.actor.Props)15 YangInstanceIdentifier (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)15 Failure (akka.actor.Status.Failure)14 AbstractActorTest (org.opendaylight.controller.cluster.datastore.AbstractActorTest)14 FiniteDuration (scala.concurrent.duration.FiniteDuration)14 ActorContext (org.opendaylight.controller.cluster.datastore.utils.ActorContext)13