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 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());
        }