Пример #1
0
        public void TestTransport_must_associate_successfully_with_another_TestTransport()
        {
            //arrange
            var registry = new AssociationRegistry();
            var transportA = new TestTransport(addressA, registry);
            var transportB = new TestTransport(addressB, registry);

            //act

            //must complete returned promises to receive events
            var localConnectionFuture = transportA.Listen();
            localConnectionFuture.Wait(DefaultTimeout);
            localConnectionFuture.Result.Item2.SetResult(new ActorAssociationEventListener(Self));

            var remoteConnectionFuture = transportB.Listen();
            remoteConnectionFuture.Wait(DefaultTimeout);
            remoteConnectionFuture.Result.Item2.SetResult(new ActorAssociationEventListener(Self));

            var ready = registry.TransportsReady(addressA, addressB);
            Assert.True(ready);

            transportA.Associate(addressB);
            expectMsgPF<AssociationHandle>(DefaultTimeout, "Expect InboundAssociation from A",
                m => m.AsInstanceOf<InboundAssociation>().Association);

            //assert
            var associateAttempt = (registry.LogSnapshot().Single(x => x is AssociateAttempt)).AsInstanceOf<AssociateAttempt>();
            Assert.Equal(addressA, associateAttempt.LocalAddress);
            Assert.Equal(addressB, associateAttempt.RemoteAddress);
        }
Пример #2
0
        public void TestTransport_must_associate_successfully_with_another_TestTransport()
        {
            //arrange
            var registry   = new AssociationRegistry();
            var transportA = new TestTransport(addressA, registry);
            var transportB = new TestTransport(addressB, registry);

            //act

            //must complete returned promises to receive events
            var localConnectionFuture = transportA.Listen();

            localConnectionFuture.Wait(DefaultTimeout);
            localConnectionFuture.Result.Item2.SetResult(new ActorAssociationEventListener(Self));

            var remoteConnectionFuture = transportB.Listen();

            remoteConnectionFuture.Wait(DefaultTimeout);
            remoteConnectionFuture.Result.Item2.SetResult(new ActorAssociationEventListener(Self));

            var ready = registry.TransportsReady(addressA, addressB);

            Assert.True(ready);

            transportA.Associate(addressB);
            ExpectMsgPf <AssociationHandle>(DefaultTimeout, "Expect InboundAssociation from A",
                                            m => m.AsInstanceOf <InboundAssociation>().Association);

            //assert
            var associateAttempt = (registry.LogSnapshot().Single(x => x is AssociateAttempt)).AsInstanceOf <AssociateAttempt>();

            Assert.Equal(addressA, associateAttempt.LocalAddress);
            Assert.Equal(addressB, associateAttempt.RemoteAddress);
        }
Пример #3
0
        public void TestTransport_fail_to_association_with_nonexisting_Address()
        {
            //arrange
            var registry   = new AssociationRegistry();
            var transportA = new TestTransport(addressA, registry);

            //act
            var result = transportA.Listen();

            result.Wait(DefaultTimeout);
            result.Result.Item2.SetResult(new ActorAssociationEventListener(Self));

            //assert
            XAssert.Throws <InvalidAssociationException>(() =>
            {
                var associateTask = transportA.Associate(nonExistantAddress);
                associateTask.Wait(DefaultTimeout);
                var fireException = associateTask.Result;
            });
        }
Пример #4
0
        public void TestTransport_should_emulate_sending_PDUs()
        {
            //arrange
            var registry = new AssociationRegistry();
            var transportA = new TestTransport(addressA, registry);
            var transportB = new TestTransport(addressB, registry);

            //act

            //must complete returned promises to receive events
            var localConnectionFuture = transportA.Listen();
            localConnectionFuture.Wait(DefaultTimeout);
            localConnectionFuture.Result.Item2.SetResult(new ActorAssociationEventListener(Self));

            var remoteConnectionFuture = transportB.Listen();
            remoteConnectionFuture.Wait(DefaultTimeout);
            remoteConnectionFuture.Result.Item2.SetResult(new ActorAssociationEventListener(Self));

            var ready = registry.TransportsReady(addressA, addressB);
            Assert.True(ready);

            var associate = transportA.Associate(addressB);
            var handleB = expectMsgPF<AssociationHandle>(DefaultTimeout, "Expect InboundAssociation from A", o =>
            {
                var handle = o as InboundAssociation;
                if (handle != null && handle.Association.RemoteAddress.Equals(addressA)) return handle.Association;
                return null;
            });
            handleB.ReadHandlerSource.SetResult(new ActorHandleEventListener(Self));

            associate.Wait(DefaultTimeout);
            var handleA = associate.Result;

            //Initialize handles
            handleA.ReadHandlerSource.SetResult(new ActorHandleEventListener(Self));

            var akkaPDU = ByteString.CopyFromUtf8("AkkaPDU");

            var exists = registry.ExistsAssociation(addressA, addressB);
            Assert.True(exists);

            handleA.Write(akkaPDU);

            //assert
            expectMsgPF(DefaultTimeout, "Expect InboundPayload from A", o =>
            {
                var payload = o as InboundPayload;
                if (payload != null && payload.Payload.Equals(akkaPDU)) return akkaPDU;
                return null;
            });

            var writeAttempt = (registry.LogSnapshot().Single(x => x is WriteAttempt)).AsInstanceOf<WriteAttempt>();
            Assert.True(writeAttempt.Sender.Equals(addressA) && writeAttempt.Recipient.Equals(addressB)
                && writeAttempt.Payload.Equals(akkaPDU));
        }
Пример #5
0
        public void TestTransport_fail_to_association_with_nonexisting_Address()
        {
            //arrange
            var registry = new AssociationRegistry();
            var transportA = new TestTransport(addressA, registry);

            //act
            var result = transportA.Listen();
            result.Wait(DefaultTimeout);
            result.Result.Item2.SetResult(new ActorAssociationEventListener(Self));

            //assert
            intercept<InvalidAssociationException>(() =>
            {
                var associateTask = transportA.Associate(nonExistantAddress);
                associateTask.Wait(DefaultTimeout);
                var fireException = associateTask.Result;
            });
        }
Пример #6
0
        public void TestTransport_should_emulate_disassociation()
        {
            //arrange
            var registry = new AssociationRegistry();
            var transportA = new TestTransport(addressA, registry);
            var transportB = new TestTransport(addressB, registry);

            //act

            //must complete returned promises to receive events
            var localConnectionFuture = transportA.Listen();
            localConnectionFuture.Wait(DefaultTimeout);
            localConnectionFuture.Result.Item2.SetResult(new ActorAssociationEventListener(Self));

            var remoteConnectionFuture = transportB.Listen();
            remoteConnectionFuture.Wait(DefaultTimeout);
            remoteConnectionFuture.Result.Item2.SetResult(new ActorAssociationEventListener(Self));

            var ready = registry.TransportsReady(addressA, addressB);
            Assert.True(ready);

            var associate = transportA.Associate(addressB);
            var handleB = expectMsgPF<AssociationHandle>(DefaultTimeout, "Expect InboundAssociation from A", o =>
            {
                var handle = o as InboundAssociation;
                if (handle != null && handle.Association.RemoteAddress.Equals(addressA)) return handle.Association;
                return null;
            });
            handleB.ReadHandlerSource.SetResult(new ActorHandleEventListener(Self));

            associate.Wait(DefaultTimeout);
            var handleA = associate.Result;

            //Initialize handles
            handleA.ReadHandlerSource.SetResult(new ActorHandleEventListener(Self));

            var exists = registry.ExistsAssociation(addressA, addressB);
            Assert.True(exists);

            handleA.Disassociate();

            var msg = expectMsgPF(DefaultTimeout, "Expected Disassociated", o => o.AsInstanceOf<Disassociated>());

            //assert
            Assert.NotNull(msg);

            exists = registry.ExistsAssociation(addressA, addressB);
            Assert.True(!exists, "Association should no longer exist");

            var disassociateAttempt = registry.LogSnapshot().Single(x => x is DisassociateAttempt).AsInstanceOf<DisassociateAttempt>();
            Assert.True(disassociateAttempt.Requestor.Equals(addressA) && disassociateAttempt.Remote.Equals(addressB));
        }
Пример #7
0
        public void TestTransport_should_emulate_disassociation()
        {
            //arrange
            var registry   = new AssociationRegistry();
            var transportA = new TestTransport(addressA, registry);
            var transportB = new TestTransport(addressB, registry);

            //act

            //must complete returned promises to receive events
            var localConnectionFuture = transportA.Listen();

            localConnectionFuture.Wait(DefaultTimeout);
            localConnectionFuture.Result.Item2.SetResult(new ActorAssociationEventListener(Self));

            var remoteConnectionFuture = transportB.Listen();

            remoteConnectionFuture.Wait(DefaultTimeout);
            remoteConnectionFuture.Result.Item2.SetResult(new ActorAssociationEventListener(Self));

            var ready = registry.TransportsReady(addressA, addressB);

            Assert.True(ready);

            var associate = transportA.Associate(addressB);
            var handleB   = ExpectMsgPf <AssociationHandle>(DefaultTimeout, "Expect InboundAssociation from A", o =>
            {
                var handle = o as InboundAssociation;
                if (handle != null && handle.Association.RemoteAddress.Equals(addressA))
                {
                    return(handle.Association);
                }
                return(null);
            });

            handleB.ReadHandlerSource.SetResult(new ActorHandleEventListener(Self));

            associate.Wait(DefaultTimeout);
            var handleA = associate.Result;

            //Initialize handles
            handleA.ReadHandlerSource.SetResult(new ActorHandleEventListener(Self));

            var exists = registry.ExistsAssociation(addressA, addressB);

            Assert.True(exists);

            handleA.Disassociate();

            var msg = ExpectMsgPf(DefaultTimeout, "Expected Disassociated", o => o.AsInstanceOf <Disassociated>());

            //assert
            Assert.NotNull(msg);

            exists = registry.ExistsAssociation(addressA, addressB);
            Assert.True(!exists, "Association should no longer exist");

            var disassociateAttempt = registry.LogSnapshot().Single(x => x is DisassociateAttempt).AsInstanceOf <DisassociateAttempt>();

            Assert.True(disassociateAttempt.Requestor.Equals(addressA) && disassociateAttempt.Remote.Equals(addressB));
        }
Пример #8
0
        public void TestTransport_should_emulate_sending_PDUs()
        {
            //arrange
            var registry   = new AssociationRegistry();
            var transportA = new TestTransport(addressA, registry);
            var transportB = new TestTransport(addressB, registry);

            //act

            //must complete returned promises to receive events
            var localConnectionFuture = transportA.Listen();

            localConnectionFuture.Wait(DefaultTimeout);
            localConnectionFuture.Result.Item2.SetResult(new ActorAssociationEventListener(Self));

            var remoteConnectionFuture = transportB.Listen();

            remoteConnectionFuture.Wait(DefaultTimeout);
            remoteConnectionFuture.Result.Item2.SetResult(new ActorAssociationEventListener(Self));

            var ready = registry.TransportsReady(addressA, addressB);

            Assert.True(ready);

            var associate = transportA.Associate(addressB);
            var handleB   = ExpectMsgPf <AssociationHandle>(DefaultTimeout, "Expect InboundAssociation from A", o =>
            {
                var handle = o as InboundAssociation;
                if (handle != null && handle.Association.RemoteAddress.Equals(addressA))
                {
                    return(handle.Association);
                }
                return(null);
            });

            handleB.ReadHandlerSource.SetResult(new ActorHandleEventListener(Self));

            associate.Wait(DefaultTimeout);
            var handleA = associate.Result;

            //Initialize handles
            handleA.ReadHandlerSource.SetResult(new ActorHandleEventListener(Self));

            var akkaPDU = ByteString.CopyFromUtf8("AkkaPDU");

            var exists = registry.ExistsAssociation(addressA, addressB);

            Assert.True(exists);

            handleA.Write(akkaPDU);

            //assert
            ExpectMsgPf(DefaultTimeout, "Expect InboundPayload from A", o =>
            {
                var payload = o as InboundPayload;
                if (payload != null && payload.Payload.Equals(akkaPDU))
                {
                    return(akkaPDU);
                }
                return(null);
            });

            var writeAttempt = (registry.LogSnapshot().Single(x => x is WriteAttempt)).AsInstanceOf <WriteAttempt>();

            Assert.True(writeAttempt.Sender.Equals(addressA) && writeAttempt.Recipient.Equals(addressB) &&
                        writeAttempt.Payload.Equals(akkaPDU));
        }
Пример #9
0
        public void Properly_quarantine_stashed_inbound_connections()
        {
            var localAddress     = new Address("akka.test", "system1", "localhost", 1);
            var rawLocalAddress  = new Address("test", "system1", "localhost", 1);
            var remoteAddress    = new Address("akka.test", "system2", "localhost", 2);
            var rawRemoteAddress = new Address("test", "system2", "localhost", 2);
            var remoteUID        = 16;

            var config = ConfigurationFactory.ParseString(@"
                  akka.remote.enabled-transports = [""akka.remote.test""]
                  akka.remote.retry-gate-closed-for = 5s     
                  akka.remote.log-remote-lifecycle-events = on  
     
            akka.remote.test {
                registry-key = JMeMndLLsw
                local-address = """ + $"test://{localAddress.System}@{localAddress.Host}:{localAddress.Port}" + @"""
            }").WithFallback(_remoteSystem.Settings.Config);

            var thisSystem = ActorSystem.Create("this-system", config);

            MuteSystem(thisSystem);

            try
            {
                // Set up a mock remote system using the test transport
                var registry             = AssociationRegistry.Get("JMeMndLLsw");
                var remoteTransport      = new TestTransport(rawRemoteAddress, registry);
                var remoteTransportProbe = CreateTestProbe();

                registry.RegisterTransport(remoteTransport, Task.FromResult <IAssociationEventListener>
                                               (new ActorAssociationEventListener(remoteTransportProbe)));

                // Hijack associations through the test transport
                AwaitCondition(() => registry.TransportsReady(rawLocalAddress, rawRemoteAddress));
                var testTransport = registry.TransportFor(rawLocalAddress).Item1;
                testTransport.WriteBehavior.PushConstant(true);

                // Force an outbound associate on the real system (which we will hijack)
                // we send no handshake packet, so this remains a pending connection
                var dummySelection = thisSystem.ActorSelection(ActorPath.Parse(remoteAddress + "/user/noonethere"));
                dummySelection.Tell("ping", Sys.DeadLetters);

                var remoteHandle = remoteTransportProbe.ExpectMsg <InboundAssociation>(TimeSpan.FromMinutes(4));
                remoteHandle.Association.ReadHandlerSource.TrySetResult((IHandleEventListener)(new ActionHandleEventListener(ev => {})));

                // Now we initiate an emulated inbound connection to the real system
                var inboundHandleProbe = CreateTestProbe();
                var inboundHandleTask  = remoteTransport.Associate(rawLocalAddress);
                inboundHandleTask.Wait(TimeSpan.FromSeconds(3));
                var inboundHandle = inboundHandleTask.Result;
                inboundHandle.ReadHandlerSource.SetResult(new ActorHandleEventListener(inboundHandleProbe));

                AwaitAssert(() =>
                {
                    registry.GetRemoteReadHandlerFor(inboundHandle.AsInstanceOf <TestAssociationHandle>()).Should().NotBeNull();
                });

                var pduCodec = new AkkaPduProtobuffCodec(Sys);

                var handshakePacket = pduCodec.ConstructAssociate(new HandshakeInfo(rawRemoteAddress, remoteUID));

                // Finish the inbound handshake so now it is handed up to Remoting
                inboundHandle.Write(handshakePacket);

                // No disassociation now, the connection is still stashed
                inboundHandleProbe.ExpectNoMsg(1000);

                // Quarantine unrelated connection
                RARP.For(thisSystem).Provider.Quarantine(remoteAddress, -1);
                inboundHandleProbe.ExpectNoMsg(1000);

                // Quarantine the connection
                RARP.For(thisSystem).Provider.Quarantine(remoteAddress, remoteUID);

                // Even though the connection is stashed it will be disassociated
                inboundHandleProbe.ExpectMsg <Disassociated>();
            }
            finally
            {
                Shutdown(thisSystem);
            }
        }
Пример #10
0
        public void Stash_inbound_connections_until_UID_is_known_for_pending_outbound()
        {
            var localAddress     = new Address("akka.test", "system1", "localhost", 1);
            var rawLocalAddress  = new Address("test", "system1", "localhost", 1);
            var remoteAddress    = new Address("akka.test", "system2", "localhost", 2);
            var rawRemoteAddress = new Address("test", "system2", "localhost", 2);

            var config = ConfigurationFactory.ParseString(@"
                  akka.remote.enabled-transports = [""akka.remote.test""]
                  akka.remote.retry-gate-closed-for = 5s     
                  akka.remote.log-remote-lifecycle-events = on
                  akka.loglevel = DEBUG
     
            akka.remote.test {
                registry-key = TRKAzR
                local-address = """ + $"test://{localAddress.System}@{localAddress.Host}:{localAddress.Port}" + @"""
            }").WithFallback(_remoteSystem.Settings.Config);

            var thisSystem = ActorSystem.Create("this-system", config);

            MuteSystem(thisSystem);

            try
            {
                // Set up a mock remote system using the test transport
                var registry             = AssociationRegistry.Get("TRKAzR");
                var remoteTransport      = new TestTransport(rawRemoteAddress, registry);
                var remoteTransportProbe = CreateTestProbe();

                registry.RegisterTransport(remoteTransport, Task.FromResult <IAssociationEventListener>
                                               (new ActorAssociationEventListener(remoteTransportProbe)));

                // Hijack associations through the test transport
                AwaitCondition(() => registry.TransportsReady(rawLocalAddress, rawRemoteAddress));
                var testTransport = registry.TransportFor(rawLocalAddress).Item1;
                testTransport.WriteBehavior.PushConstant(true);

                // Force an outbound associate on the real system (which we will hijack)
                // we send no handshake packet, so this remains a pending connection
                var dummySelection = thisSystem.ActorSelection(ActorPath.Parse(remoteAddress + "/user/noonethere"));
                dummySelection.Tell("ping", Sys.DeadLetters);

                var remoteHandle = remoteTransportProbe.ExpectMsg <InboundAssociation>(TimeSpan.FromMinutes(4));
                remoteHandle.Association.ReadHandlerSource.TrySetResult((IHandleEventListener)(new ActionHandleEventListener(ev => { })));

                // Now we initiate an emulated inbound connection to the real system
                var inboundHandleProbe = CreateTestProbe();
                var inboundHandleTask  = remoteTransport.Associate(rawLocalAddress);
                inboundHandleTask.Wait(TimeSpan.FromSeconds(3));
                var inboundHandle = inboundHandleTask.Result;
                inboundHandle.ReadHandlerSource.SetResult(new ActorHandleEventListener(inboundHandleProbe));

                AwaitAssert(() =>
                {
                    registry.GetRemoteReadHandlerFor(inboundHandle.AsInstanceOf <TestAssociationHandle>()).Should().NotBeNull();
                });

                var pduCodec = new AkkaPduProtobuffCodec(Sys);

                var handshakePacket = pduCodec.ConstructAssociate(new HandshakeInfo(rawRemoteAddress, 0));
                var brokenPacket    = pduCodec.ConstructPayload(ByteString.CopyFrom(0, 1, 2, 3, 4, 5, 6));

                // Finish the inbound handshake so now it is handed up to Remoting
                inboundHandle.Write(handshakePacket);
                // Now bork the connection with a malformed packet that can only signal an error if the Endpoint is already registered
                // but not while it is stashed
                inboundHandle.Write(brokenPacket);

                // No disassociation now - the connection is still stashed
                inboundHandleProbe.ExpectNoMsg(1000);

                // Finish the handshake for the outbound connection - this will unstash the inbound pending connection.
                remoteHandle.Association.Write(handshakePacket);

                inboundHandleProbe.ExpectMsg <Disassociated>(TimeSpan.FromMinutes(5));
            }
            finally
            {
                Shutdown(thisSystem);
            }
        }