public void SendMessageToAndWaitForResponseWithUncontactableEndpoint()
        {
            var endpoints = new Mock <IStoreInformationAboutEndpoints>();
            {
                endpoints.Setup(e => e.CanCommunicateWithEndpoint(It.IsAny <EndpointId>()))
                .Returns(false);
            }

            var channel = new Mock <IProtocolChannel>();
            var pipe    = new Mock <IDirectIncomingMessages>();
            Func <ChannelTemplate, EndpointId, Tuple <IProtocolChannel, IDirectIncomingMessages> > channelBuilder =
                (template, id) =>
            {
                return(new Tuple <IProtocolChannel, IDirectIncomingMessages>(channel.Object, pipe.Object));
            };
            var diagnostics = new SystemDiagnostics((log, s) => { }, null);
            var layer       = new ProtocolLayer(
                endpoints.Object,
                channelBuilder,
                new[]
            {
                ChannelTemplate.NamedPipe,
            },
                diagnostics);

            Assert.Throws <EndpointNotContactableException>(
                () => layer.SendMessageAndWaitForResponse(
                    new EndpointId("A"),
                    new SuccessMessage(new EndpointId("B"), new MessageId()),
                    1,
                    TimeSpan.FromSeconds(1)));
        }
        public void SignOutWithoutBeingSignedIn()
        {
            var endpoints = new Mock <IStoreInformationAboutEndpoints>();

            var protocolInfo = new ProtocolInformation(
                new Version(1, 0),
                new Uri("net.pipe://localhost/protocol/message/invalid"),
                new Uri("net.pipe://localhost/protocol/data/invalid"));
            var channel = new Mock <IProtocolChannel>();
            {
                channel.Setup(c => c.OpenChannel())
                .Verifiable();
                channel.Setup(c => c.LocalConnectionPointForVersion(It.IsAny <Version>()))
                .Returns(protocolInfo);
                channel.Setup(c => c.CloseChannel())
                .Verifiable();
            }

            var pipe = new Mock <IDirectIncomingMessages>();
            Func <ChannelTemplate, EndpointId, Tuple <IProtocolChannel, IDirectIncomingMessages> > channelBuilder =
                (template, id) => new Tuple <IProtocolChannel, IDirectIncomingMessages>(channel.Object, pipe.Object);
            var diagnostics = new SystemDiagnostics((log, s) => { }, null);
            var layer       = new ProtocolLayer(
                endpoints.Object,
                channelBuilder,
                new[]
            {
                ChannelTemplate.NamedPipe,
            },
                diagnostics);

            layer.SignOut();
            Assert.IsFalse(layer.IsSignedIn);
            channel.Verify(c => c.CloseChannel(), Times.Never());
        }
        public void SendMessageToWithOpenChannel()
        {
            var remoteEndpoint = new EndpointId("b");
            var endpointInfo   = new EndpointInformation(
                remoteEndpoint,
                new DiscoveryInformation(new Uri("net.pipe://localhost/discovery")),
                new ProtocolInformation(
                    ProtocolVersions.V1,
                    new Uri("net.pipe://localhost/messages"),
                    new Uri("net.pipe://localhost/data")));
            var endpoints = new Mock <IStoreInformationAboutEndpoints>();
            {
                endpoints.Setup(e => e.CanCommunicateWithEndpoint(It.IsAny <EndpointId>()))
                .Returns(true);
                endpoints.Setup(e => e.TryGetConnectionFor(It.IsAny <EndpointId>(), out endpointInfo))
                .Returns(true);
            }

            var msg     = new SuccessMessage(new EndpointId("B"), new MessageId());
            var channel = new Mock <IProtocolChannel>();
            {
                channel.Setup(c => c.OpenChannel())
                .Verifiable();
                channel.Setup(c => c.LocalConnectionPointForVersion(It.IsAny <Version>()))
                .Returns(endpointInfo.ProtocolInformation);
                channel.Setup(c => c.Send(It.IsAny <ProtocolInformation>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>()))
                .Callback <ProtocolInformation, ICommunicationMessage, int>(
                    (e, m, r) =>
                {
                    Assert.AreSame(endpointInfo.ProtocolInformation, e);
                    Assert.AreSame(msg, m);
                })
                .Verifiable();
            }

            var pipe = new Mock <IDirectIncomingMessages>();
            Func <ChannelTemplate, EndpointId, Tuple <IProtocolChannel, IDirectIncomingMessages> > channelBuilder =
                (template, id) => new Tuple <IProtocolChannel, IDirectIncomingMessages>(channel.Object, pipe.Object);
            var diagnostics = new SystemDiagnostics((log, s) => { }, null);
            var layer       = new ProtocolLayer(
                endpoints.Object,
                channelBuilder,
                new[]
            {
                ChannelTemplate.NamedPipe,
            },
                diagnostics);

            layer.SignIn();

            layer.SendMessageTo(remoteEndpoint, msg, 1);
            channel.Verify(c => c.OpenChannel(), Times.Once());
            channel.Verify(c => c.Send(It.IsAny <ProtocolInformation>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>()), Times.Once());
        }
        public void OnEndpointDisconnectedAfterSigningIn()
        {
            var endpoint     = new EndpointId("a");
            var endpointInfo = new EndpointInformation(
                endpoint,
                new DiscoveryInformation(new Uri("net.pipe://localhost/discovery")),
                new ProtocolInformation(
                    ProtocolVersions.V1,
                    new Uri("net.pipe://localhost/messages"),
                    new Uri("net.pipe://localhost/data")));
            var endpoints = new Mock <IStoreInformationAboutEndpoints>();
            {
                endpoints.Setup(e => e.CanCommunicateWithEndpoint(It.IsAny <EndpointId>()))
                .Returns(true);
                endpoints.Setup(e => e.TryGetConnectionFor(It.IsAny <EndpointId>(), out endpointInfo))
                .Returns(true);
            }

            var channel = new Mock <IProtocolChannel>();
            {
                channel.Setup(c => c.LocalConnectionPointForVersion(It.IsAny <Version>()))
                .Returns(endpointInfo.ProtocolInformation);
                channel.Setup(c => c.EndpointDisconnected(It.IsAny <ProtocolInformation>()))
                .Callback <ProtocolInformation>(e => Assert.AreEqual(endpointInfo.ProtocolInformation, e))
                .Verifiable();
            }

            var pipe = new Mock <IDirectIncomingMessages>();
            {
                pipe.Setup(p => p.OnEndpointSignedOff(It.IsAny <EndpointId>()))
                .Callback <EndpointId>(e => Assert.AreEqual(endpoint, e))
                .Verifiable();
            }

            Func <ChannelTemplate, EndpointId, Tuple <IProtocolChannel, IDirectIncomingMessages> > channelBuilder =
                (template, id) => new Tuple <IProtocolChannel, IDirectIncomingMessages>(channel.Object, pipe.Object);
            var diagnostics = new SystemDiagnostics((log, s) => { }, null);
            var layer       = new ProtocolLayer(
                endpoints.Object,
                channelBuilder,
                new[]
            {
                ChannelTemplate.NamedPipe,
            },
                diagnostics);

            layer.SignIn();
            endpoints.Raise(d => d.OnEndpointDisconnecting += null, new EndpointEventArgs(endpoint));

            channel.Verify(c => c.EndpointDisconnected(It.IsAny <ProtocolInformation>()), Times.Once());
            pipe.Verify(p => p.OnEndpointSignedOff(It.IsAny <EndpointId>()), Times.Once());
        }
        public void UploadDataWithOpenedChannel()
        {
            var remoteEndpoint = new EndpointId("b");
            var endpointInfo   = new EndpointInformation(
                remoteEndpoint,
                new DiscoveryInformation(new Uri("net.pipe://localhost/discovery")),
                new ProtocolInformation(
                    ProtocolVersions.V1,
                    new Uri("net.pipe://localhost/messages"),
                    new Uri("net.pipe://localhost/data")));
            var endpoints = new Mock <IStoreInformationAboutEndpoints>();
            {
                endpoints.Setup(e => e.CanCommunicateWithEndpoint(It.IsAny <EndpointId>()))
                .Returns(true);
                endpoints.Setup(e => e.TryGetConnectionFor(It.IsAny <EndpointId>(), out endpointInfo))
                .Returns(true);
            }

            var file    = "B";
            var channel = new Mock <IProtocolChannel>();
            {
                channel.Setup(c => c.OpenChannel())
                .Verifiable();
                channel.Setup(c => c.LocalConnectionPointForVersion(It.IsAny <Version>()))
                .Returns(endpointInfo.ProtocolInformation);
                channel.Setup(
                    c => c.TransferData(
                        It.IsAny <ProtocolInformation>(),
                        It.IsAny <string>(),
                        It.IsAny <CancellationToken>(),
                        It.IsAny <TaskScheduler>(),
                        It.IsAny <int>()))
                .Callback <ProtocolInformation, string, CancellationToken, TaskScheduler, int>(
                    (e, p, c, s, r) =>
                {
                    Assert.AreSame(endpointInfo.ProtocolInformation, e);
                    Assert.AreSame(file, p);
                })
                .Returns <ProtocolInformation, string, CancellationToken, TaskScheduler, int>(
                    (e, p, c, s, r) => Task.Factory.StartNew(() => { }, c, TaskCreationOptions.None, s))
                .Verifiable();
            }

            var pipe = new Mock <IDirectIncomingMessages>();
            Func <ChannelTemplate, EndpointId, Tuple <IProtocolChannel, IDirectIncomingMessages> > channelBuilder =
                (template, id) =>
            {
                return(new Tuple <IProtocolChannel, IDirectIncomingMessages>(channel.Object, pipe.Object));
            };
            var diagnostics = new SystemDiagnostics((log, s) => { }, null);
            var layer       = new ProtocolLayer(
                endpoints.Object,
                channelBuilder,
                new[]
            {
                ChannelTemplate.NamedPipe,
            },
                diagnostics);

            layer.SignIn();

            layer.UploadData(remoteEndpoint, file, new CancellationToken(), new CurrentThreadTaskScheduler(), 1);
            channel.Verify(c => c.OpenChannel(), Times.Once());
            channel.Verify(
                c => c.TransferData(
                    It.IsAny <ProtocolInformation>(),
                    It.IsAny <string>(),
                    It.IsAny <CancellationToken>(),
                    It.IsAny <TaskScheduler>(),
                    It.IsAny <int>()),
                Times.Once());
        }
        public void SendMessageToAndWaitForResponseWithOpenedChannel()
        {
            var remoteEndpoint = new EndpointId("b");
            var endpointInfo   = new EndpointInformation(
                remoteEndpoint,
                new DiscoveryInformation(new Uri("net.pipe://localhost/discovery")),
                new ProtocolInformation(
                    ProtocolVersions.V1,
                    new Uri("net.pipe://localhost/messages"),
                    new Uri("net.pipe://localhost/data")));
            var endpoints = new Mock <IStoreInformationAboutEndpoints>();
            {
                endpoints.Setup(e => e.CanCommunicateWithEndpoint(It.IsAny <EndpointId>()))
                .Returns(true);
                endpoints.Setup(e => e.TryGetConnectionFor(It.IsAny <EndpointId>(), out endpointInfo))
                .Returns(true);
            }

            var retryCount = 1;
            var msg        = new SuccessMessage(new EndpointId("B"), new MessageId());
            var channel    = new Mock <IProtocolChannel>();
            {
                channel.Setup(c => c.OpenChannel())
                .Verifiable();
                channel.Setup(c => c.LocalConnectionPointForVersion(It.IsAny <Version>()))
                .Returns(endpointInfo.ProtocolInformation);
                channel.Setup(c => c.Send(It.IsAny <ProtocolInformation>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>()))
                .Callback <ProtocolInformation, ICommunicationMessage, int>(
                    (e, m, r) =>
                {
                    Assert.AreSame(endpointInfo.ProtocolInformation, e);
                    Assert.AreSame(msg, m);
                    Assert.AreEqual(retryCount, r);
                })
                .Verifiable();
            }

            var timeout      = TimeSpan.FromSeconds(1);
            var responseTask = Task <ICommunicationMessage> .Factory.StartNew(
                () => new SuccessMessage(remoteEndpoint, msg.Id),
                new CancellationToken(),
                TaskCreationOptions.None,
                new CurrentThreadTaskScheduler());

            var pipe = new Mock <IDirectIncomingMessages>();
            {
                pipe.Setup(p => p.ForwardResponse(It.IsAny <EndpointId>(), It.IsAny <MessageId>(), It.IsAny <TimeSpan>()))
                .Callback <EndpointId, MessageId, TimeSpan>(
                    (e, m, t) =>
                {
                    Assert.AreSame(remoteEndpoint, e);
                    Assert.AreSame(msg.Id, m);
                    Assert.AreEqual(timeout, t);
                })
                .Returns(responseTask)
                .Verifiable();
            }

            Func <ChannelTemplate, EndpointId, Tuple <IProtocolChannel, IDirectIncomingMessages> > channelBuilder =
                (template, id) =>
            {
                return(new Tuple <IProtocolChannel, IDirectIncomingMessages>(channel.Object, pipe.Object));
            };
            var diagnostics = new SystemDiagnostics((log, s) => { }, null);
            var layer       = new ProtocolLayer(
                endpoints.Object,
                channelBuilder,
                new[]
            {
                ChannelTemplate.NamedPipe,
            },
                diagnostics);

            layer.SignIn();

            var response = layer.SendMessageAndWaitForResponse(remoteEndpoint, msg, retryCount, timeout);

            Assert.AreSame(responseTask, response);

            channel.Verify(c => c.OpenChannel(), Times.Once());
            channel.Verify(c => c.Send(It.IsAny <ProtocolInformation>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>()), Times.Once());
            pipe.Verify(p => p.ForwardResponse(It.IsAny <EndpointId>(), It.IsAny <MessageId>(), It.IsAny <TimeSpan>()), Times.Once());
        }