public async Task <WriteConcernResult> ExecuteAsync(IConnection connection, CancellationToken cancellationToken)
        {
            var messages = new List <RequestMessage>();

            var writeMessage = CreateWriteMessage(connection);

            messages.Add(writeMessage);

            BsonDocument getLastErrorCommand = null;
            QueryMessage getLastErrorMessage = null;

            if (_writeConcern.IsAcknowledged)
            {
                getLastErrorCommand = CreateGetLastErrorCommand();
                getLastErrorMessage = CreateGetLastErrorMessage(getLastErrorCommand);
                messages.Add(getLastErrorMessage);
            }

            await connection.SendMessagesAsync(messages, _messageEncoderSettings, cancellationToken).ConfigureAwait(false);

            if (getLastErrorMessage != null && getLastErrorMessage.WasSent)
            {
                var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);
                var reply           = await connection.ReceiveMessageAsync(getLastErrorMessage.RequestId, encoderSelector, _messageEncoderSettings, cancellationToken).ConfigureAwait(false);

                return(ProcessReply(connection.ConnectionId, getLastErrorCommand, (ReplyMessage <BsonDocument>)reply));
            }
            else
            {
                return(null);
            }
        }
Example #2
0
        public void ReceiveMessageAsync_should_complete_when_reply_is_not_already_on_the_stream()
        {
            using (var stream = new BlockingMemoryStream())
            {
                _streamFactory.CreateStreamAsync(null, CancellationToken.None)
                .ReturnsForAnyArgs(Task.FromResult <Stream>(stream));

                _subject.OpenAsync(CancellationToken.None).Wait();

                var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);
                var receivedTask    = _subject.ReceiveMessageAsync(10, encoderSelector, _messageEncoderSettings, CancellationToken.None);

                receivedTask.IsCompleted.Should().BeFalse();

                var messageToReceive = MessageHelper.BuildSuccessReply <BsonDocument>(new BsonDocument(), BsonDocumentSerializer.Instance, responseTo: 10);
                MessageHelper.WriteResponsesToStream(stream, new[] { messageToReceive });

                var received = receivedTask.Result;

                var expected = MessageHelper.TranslateMessagesToBsonDocuments(new[] { messageToReceive });
                var actual   = MessageHelper.TranslateMessagesToBsonDocuments(new[] { received });

                actual.Should().BeEquivalentTo(expected);
            }
        }
Example #3
0
        public void ReceiveMessageAsync_should_handle_out_of_order_replies()
        {
            using (var stream = new BlockingMemoryStream())
            {
                _streamFactory.CreateStreamAsync(null, CancellationToken.None)
                .ReturnsForAnyArgs(Task.FromResult <Stream>(stream));

                _subject.OpenAsync(CancellationToken.None).Wait();

                var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);
                var receivedTask11  = _subject.ReceiveMessageAsync(11, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                var receivedTask10  = _subject.ReceiveMessageAsync(10, encoderSelector, _messageEncoderSettings, CancellationToken.None);

                var messageToReceive10 = MessageHelper.BuildSuccessReply <BsonDocument>(new BsonDocument(), BsonDocumentSerializer.Instance, responseTo: 10);
                var messageToReceive11 = MessageHelper.BuildSuccessReply <BsonDocument>(new BsonDocument(), BsonDocumentSerializer.Instance, responseTo: 11);
                MessageHelper.WriteResponsesToStream(stream, new[] { messageToReceive10, messageToReceive11 });

                var received11 = receivedTask11.Result;
                var received10 = receivedTask10.Result;

                var expected = MessageHelper.TranslateMessagesToBsonDocuments(new[] { messageToReceive11, messageToReceive10 });
                var actual   = MessageHelper.TranslateMessagesToBsonDocuments(new[] { received11, received10 });

                actual.Should().BeEquivalentTo(expected);
            }
        }
        public void ReceiveMessage_should_not_produce_unobserved_task_exceptions_on_fail(
            [Values(false, true)] bool async)
        {
            var unobservedTaskExceptionRaised = false;
            var mockStream = new Mock <Stream>();
            EventHandler <UnobservedTaskExceptionEventArgs> eventHandler = (s, args) =>
            {
                if (args.Exception.InnerException is MongoConnectionException)
                {
                    unobservedTaskExceptionRaised = true;
                }
            };

            try
            {
                TaskScheduler.UnobservedTaskException += eventHandler;
                var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);

                _mockStreamFactory
                .Setup(f => f.CreateStream(_endPoint, CancellationToken.None))
                .Returns(mockStream.Object);

                if (async)
                {
                    mockStream
                    .Setup(s => s.ReadAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
                    .Throws(new SocketException());
                }
                else
                {
                    mockStream
                    .Setup(s => s.Read(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>()))
                    .Throws(new SocketException());
                }

                _subject.Open(CancellationToken.None);

                Exception exception;
                if (async)
                {
                    exception = Record.Exception(() => _subject.ReceiveMessageAsync(1, encoderSelector, _messageEncoderSettings, CancellationToken.None).GetAwaiter().GetResult());
                }
                else
                {
                    exception = Record.Exception(() => _subject.ReceiveMessage(1, encoderSelector, _messageEncoderSettings, CancellationToken.None));
                }
                exception.Should().BeOfType <MongoConnectionException>();

                GC.Collect();                  // Collects the unobserved tasks
                GC.WaitForPendingFinalizers(); // Assures finilizers are executed

                unobservedTaskExceptionRaised.Should().BeFalse();
            }
            finally
            {
                TaskScheduler.UnobservedTaskException -= eventHandler;
                mockStream.Object?.Dispose();
            }
        }
Example #5
0
        public void ReceiveMessage_should_handle_out_of_order_replies(
            [Values(false, true)]
            bool async1,
            [Values(false, true)]
            bool async2)
        {
            using (var stream = new BlockingMemoryStream())
            {
                _streamFactory.CreateStream(null, CancellationToken.None)
                .ReturnsForAnyArgs(stream);
                _subject.Open(CancellationToken.None);
                _capturedEvents.Clear();

                var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);

                Task <ResponseMessage> receivedTask10;
                if (async1)
                {
                    receivedTask10 = _subject.ReceiveMessageAsync(10, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    var receivedTask10IsRunning = false;
                    receivedTask10 = Task.Run(() => { receivedTask10IsRunning = true; return(_subject.ReceiveMessage(10, encoderSelector, _messageEncoderSettings, CancellationToken.None)); });
                    SpinWait.SpinUntil(() => receivedTask10IsRunning);
                }

                Task <ResponseMessage> receivedTask11;
                if (async2)
                {
                    receivedTask11 = _subject.ReceiveMessageAsync(11, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    var receivedTask11IsRunning = false;
                    receivedTask11 = Task.Run(() => { receivedTask11IsRunning = true; return(_subject.ReceiveMessage(11, encoderSelector, _messageEncoderSettings, CancellationToken.None)); });
                    SpinWait.SpinUntil(() => receivedTask11IsRunning);
                }

                var messageToReceive10 = MessageHelper.BuildReply <BsonDocument>(new BsonDocument("_id", 10), BsonDocumentSerializer.Instance, responseTo: 10);
                var messageToReceive11 = MessageHelper.BuildReply <BsonDocument>(new BsonDocument("_id", 11), BsonDocumentSerializer.Instance, responseTo: 11);
                MessageHelper.WriteResponsesToStream(stream, new[] { messageToReceive11, messageToReceive10 }); // out of order

                var received10 = receivedTask10.GetAwaiter().GetResult();
                var received11 = receivedTask11.GetAwaiter().GetResult();

                var expected = MessageHelper.TranslateMessagesToBsonDocuments(new[] { messageToReceive10, messageToReceive11 });
                var actual   = MessageHelper.TranslateMessagesToBsonDocuments(new[] { received10, received11 });

                actual.Should().BeEquivalentTo(expected);

                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivedMessageEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivedMessageEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
        public void ReceiveMessage_should_throw_MongoConnectionClosedException_when_connection_has_failed(
            [Values(false, true)]
            bool async1,
            [Values(false, true)]
            bool async2)
        {
            var mockStream = new Mock <Stream>();

            using (mockStream.Object)
            {
                _mockStreamFactory.Setup(f => f.CreateStream(_endPoint, CancellationToken.None))
                .Returns(mockStream.Object);
                var readTcs = new TaskCompletionSource <int>();
                readTcs.SetException(new SocketException());
                mockStream.Setup(s => s.Read(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>()))
                .Returns(() => readTcs.Task.GetAwaiter().GetResult());
                mockStream.Setup(s => s.ReadAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
                .Returns(readTcs.Task);
                _subject.Open(CancellationToken.None);
                _capturedEvents.Clear();

                var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);

                Action act1;
                if (async1)
                {
                    act1 = () => _subject.ReceiveMessageAsync(1, encoderSelector, _messageEncoderSettings, CancellationToken.None).GetAwaiter().GetResult();
                }
                else
                {
                    act1 = () => _subject.ReceiveMessage(1, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }

                Action act2;
                if (async2)
                {
                    act2 = () => _subject.ReceiveMessageAsync(2, encoderSelector, _messageEncoderSettings, CancellationToken.None).GetAwaiter().GetResult();
                }
                else
                {
                    act2 = () => _subject.ReceiveMessage(2, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }

                act1.ShouldThrow <MongoConnectionException>()
                .WithInnerException <SocketException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                act2.ShouldThrow <MongoConnectionClosedException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
        private void ReceiveMessages(params ReplyMessage <BsonDocument>[] messages)
        {
            MessageHelper.WriteResponsesToStream(_stream, messages);
            var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);

            foreach (var message in messages)
            {
                _subject.ReceiveMessageAsync(message.ResponseTo, encoderSelector, _messageEncoderSettings, CancellationToken.None).Wait();
            }
        }
        public CursorBatch <TDocument> Execute(IConnection connection, CancellationToken cancellationToken)
        {
            var message = CreateMessage();

            connection.SendMessage(message, _messageEncoderSettings, cancellationToken);
            var encoderSelector = new ReplyMessageEncoderSelector <TDocument>(_serializer);
            var reply           = connection.ReceiveMessage(message.RequestId, encoderSelector, _messageEncoderSettings, cancellationToken);

            return(ProcessReply(connection.ConnectionId, (ReplyMessage <TDocument>)reply));
        }
Example #9
0
        public async Task <TCommandResult> ExecuteAsync(IConnection connection, CancellationToken cancellationToken)
        {
            var message = CreateMessage();
            await connection.SendMessageAsync(message, _messageEncoderSettings, cancellationToken).ConfigureAwait(false);

            var encoderSelector = new ReplyMessageEncoderSelector <RawBsonDocument>(RawBsonDocumentSerializer.Instance);
            var reply           = await connection.ReceiveMessageAsync(message.RequestId, encoderSelector, _messageEncoderSettings, cancellationToken).ConfigureAwait(false);

            return(ProcessReply(connection.ConnectionId, (ReplyMessage <RawBsonDocument>)reply));
        }
Example #10
0
        public async Task <CursorBatch <TDocument> > ExecuteAsync(IConnection connection, CancellationToken cancellationToken)
        {
            var message = CreateMessage();
            await connection.SendMessageAsync(message, _messageEncoderSettings, cancellationToken).ConfigureAwait(false);

            var encoderSelector = new ReplyMessageEncoderSelector <TDocument>(_serializer);
            var reply           = await connection.ReceiveMessageAsync(message.RequestId, encoderSelector, _messageEncoderSettings, cancellationToken).ConfigureAwait(false);

            return(ProcessReply(connection.ConnectionId, (ReplyMessage <TDocument>)reply));
        }
Example #11
0
        public void ReceiveMessage_should_throw_MongoConnectionClosedException_when_connection_has_failed(
            [Values(false, true)]
            bool async1,
            [Values(false, true)]
            bool async2)
        {
            using (var stream = Substitute.For <Stream>())
            {
                _streamFactory.CreateStream(null, CancellationToken.None)
                .ReturnsForAnyArgs(stream);
                var readTcs = new TaskCompletionSource <int>();
                readTcs.SetException(new SocketException());
                stream.Read(null, 0, 0)
                .ReturnsForAnyArgs(_ => readTcs.Task.GetAwaiter().GetResult());
                stream.ReadAsync(null, 0, 0, CancellationToken.None)
                .ReturnsForAnyArgs(readTcs.Task);
                _subject.Open(CancellationToken.None);
                _capturedEvents.Clear();

                var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);

                Action act1;
                if (async1)
                {
                    act1 = () => _subject.ReceiveMessageAsync(1, encoderSelector, _messageEncoderSettings, CancellationToken.None).GetAwaiter().GetResult();
                }
                else
                {
                    act1 = () => _subject.ReceiveMessage(1, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }

                Action act2;
                if (async2)
                {
                    act2 = () => _subject.ReceiveMessageAsync(2, encoderSelector, _messageEncoderSettings, CancellationToken.None).GetAwaiter().GetResult();
                }
                else
                {
                    act2 = () => _subject.ReceiveMessage(2, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }

                act1.ShouldThrow <MongoConnectionException>()
                .WithInnerException <SocketException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                act2.ShouldThrow <MongoConnectionClosedException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
Example #12
0
        public WriteConcernResult Execute(IConnection connection, CancellationToken cancellationToken)
        {
            QueryMessage getLastErrorMessage;
            var          messages = CreateMessages(connection, out getLastErrorMessage);

            connection.SendMessages(messages, _messageEncoderSettings, cancellationToken);
            if (getLastErrorMessage != null && getLastErrorMessage.WasSent)
            {
                var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);
                var reply           = connection.ReceiveMessage(getLastErrorMessage.RequestId, encoderSelector, _messageEncoderSettings, cancellationToken);
                return(ProcessReply(connection.ConnectionId, getLastErrorMessage.Query, (ReplyMessage <BsonDocument>)reply));
            }
            else
            {
                return(null);
            }
        }
Example #13
0
        public void ReceiveMessage_should_complete_when_reply_is_not_already_on_the_stream(
            [Values(false, true)]
            bool async)
        {
            using (var stream = new BlockingMemoryStream())
            {
                var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);

                Task <ResponseMessage> receiveMessageTask;
                if (async)
                {
                    _streamFactory.CreateStreamAsync(null, CancellationToken.None)
                    .ReturnsForAnyArgs(Task.FromResult <Stream>(stream));
                    _subject.OpenAsync(CancellationToken.None).GetAwaiter().GetResult();
                    _capturedEvents.Clear();

                    receiveMessageTask = _subject.ReceiveMessageAsync(10, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    _streamFactory.CreateStream(null, CancellationToken.None)
                    .ReturnsForAnyArgs(stream);
                    _subject.Open(CancellationToken.None);
                    _capturedEvents.Clear();

                    receiveMessageTask = Task.Run(() => _subject.ReceiveMessage(10, encoderSelector, _messageEncoderSettings, CancellationToken.None));
                }

                receiveMessageTask.IsCompleted.Should().BeFalse();

                var messageToReceive = MessageHelper.BuildReply <BsonDocument>(new BsonDocument(), BsonDocumentSerializer.Instance, responseTo: 10);
                MessageHelper.WriteResponsesToStream(stream, new[] { messageToReceive });

                var received = receiveMessageTask.GetAwaiter().GetResult();

                var expected = MessageHelper.TranslateMessagesToBsonDocuments(new[] { messageToReceive });
                var actual   = MessageHelper.TranslateMessagesToBsonDocuments(new[] { received });

                actual.Should().BeEquivalentTo(expected);

                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivedMessageEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
        public TCommandResult Execute(IConnection connection, CancellationToken cancellationToken)
        {
            var message = CreateMessage();

            connection.SendMessage(message, _messageEncoderSettings, cancellationToken);

            switch (_responseHandling())
            {
            case CommandResponseHandling.Ignore:
                IgnoreResponse(connection, message, cancellationToken);
                return(default(TCommandResult));

            default:
                var encoderSelector = new ReplyMessageEncoderSelector <RawBsonDocument>(RawBsonDocumentSerializer.Instance);
                var reply           = connection.ReceiveMessage(message.RequestId, encoderSelector, _messageEncoderSettings, cancellationToken);
                return(ProcessReply(connection.ConnectionId, (ReplyMessage <RawBsonDocument>)reply));
            }
        }
Example #15
0
        public async Task ReceiveMessageAsync_should_throw_network_exception_to_all_awaiters()
        {
            using (var stream = Substitute.For <Stream>())
            {
                _streamFactory.CreateStreamAsync(null, CancellationToken.None)
                .ReturnsForAnyArgs(Task.FromResult <Stream>(stream));

                var readTcs = new TaskCompletionSource <int>();
                stream.ReadAsync(null, 0, 0, CancellationToken.None)
                .ReturnsForAnyArgs(readTcs.Task);

                var writeTcs = new TaskCompletionSource <int>();
                stream.WriteAsync(null, 0, 0, CancellationToken.None)
                .ReturnsForAnyArgs(writeTcs.Task);

                await _subject.OpenAsync(CancellationToken.None);

                _capturedEvents.Clear();

                var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);
                var task1           = _subject.ReceiveMessageAsync(1, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                var task2           = _subject.ReceiveMessageAsync(2, encoderSelector, _messageEncoderSettings, CancellationToken.None);

                readTcs.SetException(new SocketException());

                Func <Task> act1 = () => task1;
                act1.ShouldThrow <MongoConnectionException>()
                .WithInnerException <SocketException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                Func <Task> act2 = () => task2;
                act2.ShouldThrow <MongoConnectionException>()
                .WithInnerException <SocketException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
        public void ReceiveMessage_should_throw_a_FormatException_when_message_is_an_invalid_size(
            [Values(-1, 48000001)]
            int length,
            [Values(false, true)]
            bool async)
        {
            using (var stream = new BlockingMemoryStream())
            {
                var bytes = BitConverter.GetBytes(length);
                stream.Write(bytes, 0, bytes.Length);
                stream.Seek(0, SeekOrigin.Begin);
                var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);

                Exception exception;
                if (async)
                {
                    _mockStreamFactory
                    .Setup(f => f.CreateStreamAsync(_endPoint, CancellationToken.None))
                    .ReturnsAsync(stream);
                    _subject.OpenAsync(CancellationToken.None).GetAwaiter().GetResult();
                    exception = Record
                                .Exception(() => _subject.ReceiveMessageAsync(10, encoderSelector, _messageEncoderSettings, CancellationToken.None)
                                           .GetAwaiter()
                                           .GetResult());
                }
                else
                {
                    _mockStreamFactory.Setup(f => f.CreateStream(_endPoint, CancellationToken.None))
                    .Returns(stream);
                    _subject.Open(CancellationToken.None);
                    exception = Record.Exception(() => _subject.ReceiveMessage(10, encoderSelector, _messageEncoderSettings, CancellationToken.None));
                }

                exception.Should().BeOfType <MongoConnectionException>();
                var e = exception.InnerException.Should().BeOfType <FormatException>().Subject;
                e.Message.Should().Be("The size of the message is invalid.");
            }
        }
Example #17
0
        public async Task ReceiveMessageAsync_should_throw_MongoConnectionClosedException_when_connection_has_failed()
        {
            using (var stream = Substitute.For <Stream>())
            {
                _streamFactory.CreateStreamAsync(null, CancellationToken.None)
                .ReturnsForAnyArgs(Task.FromResult <Stream>(stream));

                var readTcs = new TaskCompletionSource <int>();
                stream.ReadAsync(null, 0, 0, CancellationToken.None)
                .ReturnsForAnyArgs(readTcs.Task);

                var writeTcs = new TaskCompletionSource <int>();
                stream.WriteAsync(null, 0, 0, CancellationToken.None)
                .ReturnsForAnyArgs(writeTcs.Task);

                await _subject.OpenAsync(CancellationToken.None);

                var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);
                var task1           = _subject.ReceiveMessageAsync(1, encoderSelector, _messageEncoderSettings, CancellationToken.None);

                readTcs.SetException(new SocketException());

                Func <Task> act1 = () => task1;
                act1.ShouldThrow <MongoConnectionException>()
                .WithInnerException <SocketException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                var task2 = _subject.ReceiveMessageAsync(2, encoderSelector, _messageEncoderSettings, CancellationToken.None);

                Func <Task> act2 = () => task2;
                act2.ShouldThrow <MongoConnectionClosedException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                _listener.ReceivedWithAnyArgs().ConnectionBeforeReceivingMessage(default(ConnectionBeforeReceivingMessageEvent));
                _listener.ReceivedWithAnyArgs().ConnectionErrorReceivingMessage(default(ConnectionErrorReceivingMessageEvent));
            }
        }
        public async Task <TCommandResult> ExecuteAsync(IConnection connection, CancellationToken cancellationToken)
        {
            bool messageContainsSessionId;
            var  message = CreateMessage(connection.Description, out messageContainsSessionId);
            await connection.SendMessageAsync(message, _messageEncoderSettings, cancellationToken).ConfigureAwait(false);

            if (messageContainsSessionId)
            {
                _session.WasUsed();
            }

            switch (_responseHandling())
            {
            case CommandResponseHandling.Ignore:
                IgnoreResponse(connection, message, cancellationToken);
                return(default(TCommandResult));

            default:
                var encoderSelector = new ReplyMessageEncoderSelector <RawBsonDocument>(RawBsonDocumentSerializer.Instance);
                var reply           = await connection.ReceiveMessageAsync(message.RequestId, encoderSelector, _messageEncoderSettings, cancellationToken).ConfigureAwait(false);

                return(ProcessReply(connection.ConnectionId, (ReplyMessage <RawBsonDocument>)reply));
            }
        }
        public void ReceiveMessage_should_throw_network_exception_to_all_awaiters(
            [Values(false, true)]
            bool async1,
            [Values(false, true)]
            bool async2)
        {
            using (var stream = Substitute.For<Stream>())
            {
                var encoderSelector = new ReplyMessageEncoderSelector<BsonDocument>(BsonDocumentSerializer.Instance);

                _streamFactory.CreateStream(null, CancellationToken.None)
                  .ReturnsForAnyArgs(stream);
                var readTcs = new TaskCompletionSource<int>();
                stream.Read(null, 0, 0)
                    .ReturnsForAnyArgs(_ => readTcs.Task.GetAwaiter().GetResult());
                stream.ReadAsync(null, 0, 0, CancellationToken.None)
                    .ReturnsForAnyArgs(readTcs.Task);
                _subject.Open(CancellationToken.None);
                _capturedEvents.Clear();

                Task task1;
                if (async1)
                {
                    task1 = _subject.ReceiveMessageAsync(1, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    var task1IsRunning = false;
                    task1 = Task.Run(() => { task1IsRunning = true; return _subject.ReceiveMessage(1, encoderSelector, _messageEncoderSettings, CancellationToken.None); });
                    SpinWait.SpinUntil(() => task1IsRunning, 100);
                }

                Task task2;
                if (async2)
                {
                    task2 = _subject.ReceiveMessageAsync(2, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    var task2IsRunning = false;
                    task2 = Task.Run(() => { task2IsRunning = true; return _subject.ReceiveMessage(2, encoderSelector, _messageEncoderSettings, CancellationToken.None); });
                    SpinWait.SpinUntil(() => task2IsRunning);
                }

                readTcs.SetException(new SocketException());

                Func<Task> act1 = () => task1;
                act1.ShouldThrow<MongoConnectionException>()
                    .WithInnerException<SocketException>()
                    .And.ConnectionId.Should().Be(_subject.ConnectionId);

                Func<Task> act2 = () => task2;
                act2.ShouldThrow<MongoConnectionException>()
                    .WithInnerException<SocketException>()
                    .And.ConnectionId.Should().Be(_subject.ConnectionId);

                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionFailedEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
 private void ReceiveMessages(params ReplyMessage<BsonDocument>[] messages)
 {
     MessageHelper.WriteResponsesToStream(_stream, messages);
     var encoderSelector = new ReplyMessageEncoderSelector<BsonDocument>(BsonDocumentSerializer.Instance);
     foreach (var message in messages)
     {
         _subject.ReceiveMessageAsync(message.ResponseTo, encoderSelector, _messageEncoderSettings, CancellationToken.None).Wait();
     }
 }
        public void ReceiveMessage_should_complete_when_reply_is_not_already_on_the_stream(
            [Values(false, true)]
            bool async)
        {
            using (var stream = new BlockingMemoryStream())
            {
                var encoderSelector = new ReplyMessageEncoderSelector<BsonDocument>(BsonDocumentSerializer.Instance);

                Task<ResponseMessage> receiveMessageTask;
                if (async)
                {
                    _mockStreamFactory.Setup(f => f.CreateStreamAsync(_endPoint, CancellationToken.None))
                       .Returns(Task.FromResult<Stream>(stream));
                    _subject.OpenAsync(CancellationToken.None).GetAwaiter().GetResult();
                    _capturedEvents.Clear();

                    receiveMessageTask = _subject.ReceiveMessageAsync(10, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    _mockStreamFactory.Setup(f => f.CreateStream(_endPoint, CancellationToken.None))
                       .Returns(stream);
                    _subject.Open(CancellationToken.None);
                    _capturedEvents.Clear();

                    receiveMessageTask = Task.Run(() => _subject.ReceiveMessage(10, encoderSelector, _messageEncoderSettings, CancellationToken.None));
                }

                receiveMessageTask.IsCompleted.Should().BeFalse();

                var messageToReceive = MessageHelper.BuildReply<BsonDocument>(new BsonDocument(), BsonDocumentSerializer.Instance, responseTo: 10);
                MessageHelper.WriteResponsesToStream(stream, new[] { messageToReceive });

                var received = receiveMessageTask.GetAwaiter().GetResult();

                var expected = MessageHelper.TranslateMessagesToBsonDocuments(new[] { messageToReceive });
                var actual = MessageHelper.TranslateMessagesToBsonDocuments(new[] { received });

                actual.Should().BeEquivalentTo(expected);

                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivedMessageEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
        private void IgnoreResponse(IConnection connection, QueryMessage message, CancellationToken cancellationToken)
        {
            var encoderSelector = new ReplyMessageEncoderSelector <IgnoredReply>(IgnoredReplySerializer.Instance);

            connection.ReceiveMessageAsync(message.RequestId, encoderSelector, _messageEncoderSettings, cancellationToken).IgnoreExceptions();
        }
        public void ReceiveMessage_should_handle_out_of_order_replies(
            [Values(false, true)]
            bool async1,
            [Values(false, true)]
            bool async2)
        {
            using (var stream = new BlockingMemoryStream())
            {
                _mockStreamFactory.Setup(f => f.CreateStream(_endPoint, CancellationToken.None))
                    .Returns(stream);
                _subject.Open(CancellationToken.None);
                _capturedEvents.Clear();

                var encoderSelector = new ReplyMessageEncoderSelector<BsonDocument>(BsonDocumentSerializer.Instance);

                Task<ResponseMessage> receivedTask10;
                if (async1)
                {
                    receivedTask10 = _subject.ReceiveMessageAsync(10, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    var receivedTask10IsRunning = 0;
                    receivedTask10 = Task.Run(() => { Interlocked.Exchange(ref receivedTask10IsRunning, 1); return _subject.ReceiveMessage(10, encoderSelector, _messageEncoderSettings, CancellationToken.None); });
                    SpinWait.SpinUntil(() => Interlocked.CompareExchange(ref receivedTask10IsRunning, 0, 0) == 1, 1000).Should().BeTrue();
                }

                Task<ResponseMessage> receivedTask11;
                if (async2)
                {
                    receivedTask11 = _subject.ReceiveMessageAsync(11, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    var receivedTask11IsRunning = 0;
                    receivedTask11 = Task.Run(() => { Interlocked.Exchange(ref receivedTask11IsRunning, 1); return _subject.ReceiveMessage(11, encoderSelector, _messageEncoderSettings, CancellationToken.None); });
                    SpinWait.SpinUntil(() => Interlocked.CompareExchange(ref receivedTask11IsRunning, 0, 0) == 1, 1000).Should().BeTrue();
                }

                var messageToReceive10 = MessageHelper.BuildReply<BsonDocument>(new BsonDocument("_id", 10), BsonDocumentSerializer.Instance, responseTo: 10);
                var messageToReceive11 = MessageHelper.BuildReply<BsonDocument>(new BsonDocument("_id", 11), BsonDocumentSerializer.Instance, responseTo: 11);
                MessageHelper.WriteResponsesToStream(stream, new[] { messageToReceive11, messageToReceive10 }); // out of order

                var received10 = receivedTask10.GetAwaiter().GetResult();
                var received11 = receivedTask11.GetAwaiter().GetResult();

                var expected = MessageHelper.TranslateMessagesToBsonDocuments(new[] { messageToReceive10, messageToReceive11 });
                var actual = MessageHelper.TranslateMessagesToBsonDocuments(new[] { received10, received11 });

                actual.Should().BeEquivalentTo(expected);

                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivedMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivedMessageEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
Example #24
0
        public void ReceiveMessage_should_throw_network_exception_to_all_awaiters(
            [Values(false, true)]
            bool async1,
            [Values(false, true)]
            bool async2)
        {
            using (var stream = Substitute.For <Stream>())
            {
                var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);

                _streamFactory.CreateStream(null, CancellationToken.None)
                .ReturnsForAnyArgs(stream);
                var readTcs = new TaskCompletionSource <int>();
                stream.Read(null, 0, 0)
                .ReturnsForAnyArgs(_ => readTcs.Task.GetAwaiter().GetResult());
                stream.ReadAsync(null, 0, 0, CancellationToken.None)
                .ReturnsForAnyArgs(readTcs.Task);
                _subject.Open(CancellationToken.None);
                _capturedEvents.Clear();

                Task task1;
                if (async1)
                {
                    task1 = _subject.ReceiveMessageAsync(1, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    var task1IsRunning = false;
                    task1 = Task.Run(() => { task1IsRunning = true; return(_subject.ReceiveMessage(1, encoderSelector, _messageEncoderSettings, CancellationToken.None)); });
                    SpinWait.SpinUntil(() => task1IsRunning, 100);
                }

                Task task2;
                if (async2)
                {
                    task2 = _subject.ReceiveMessageAsync(2, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    var task2IsRunning = false;
                    task2 = Task.Run(() => { task2IsRunning = true; return(_subject.ReceiveMessage(2, encoderSelector, _messageEncoderSettings, CancellationToken.None)); });
                    SpinWait.SpinUntil(() => task2IsRunning);
                }

                readTcs.SetException(new SocketException());

                Func <Task> act1 = () => task1;
                act1.ShouldThrow <MongoConnectionException>()
                .WithInnerException <SocketException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                Func <Task> act2 = () => task2;
                act2.ShouldThrow <MongoConnectionException>()
                .WithInnerException <SocketException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
        public void ReceiveMessage_should_throw_network_exception_to_all_awaiters(
            [Values(false, true)]
            bool async1,
            [Values(false, true)]
            bool async2)
        {
            var mockStream = new Mock <Stream>();

            using (mockStream.Object)
            {
                var encoderSelector = new ReplyMessageEncoderSelector <BsonDocument>(BsonDocumentSerializer.Instance);

                _mockStreamFactory.Setup(f => f.CreateStream(_endPoint, CancellationToken.None))
                .Returns(mockStream.Object);
                var readTcs = new TaskCompletionSource <int>();
                mockStream.Setup(s => s.Read(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>()))
                .Returns(() => readTcs.Task.GetAwaiter().GetResult());
                mockStream.Setup(s => s.ReadAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
                .Returns(readTcs.Task);
                _subject.Open(CancellationToken.None);
                _capturedEvents.Clear();

                Task task1;
                if (async1)
                {
                    task1 = _subject.ReceiveMessageAsync(1, encoderSelector, _messageEncoderSettings, It.IsAny <CancellationToken>());
                }
                else
                {
                    task1 = Task.Run(() => _subject.ReceiveMessage(1, encoderSelector, _messageEncoderSettings, CancellationToken.None));
                }

                Task task2;
                if (async2)
                {
                    task2 = _subject.ReceiveMessageAsync(2, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    task2 = Task.Run(() => _subject.ReceiveMessage(2, encoderSelector, _messageEncoderSettings, CancellationToken.None));
                }

                SpinWait.SpinUntil(() => _capturedEvents.Count >= 2, TimeSpan.FromSeconds(5)).Should().BeTrue();

                readTcs.SetException(new SocketException());

                Func <Task> act1 = () => task1;
                act1.ShouldThrow <MongoConnectionException>()
                .WithInnerException <SocketException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                Func <Task> act2 = () => task2;
                act2.ShouldThrow <MongoConnectionException>()
                .WithInnerException <SocketException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
        public void ReceiveMessage_should_throw_network_exception_to_all_awaiters(
            [Values(false, true)]
            bool async1,
            [Values(false, true)]
            bool async2)
        {
            var mockStream = new Mock<Stream>();
            using (mockStream.Object)
            {
                var encoderSelector = new ReplyMessageEncoderSelector<BsonDocument>(BsonDocumentSerializer.Instance);

                _mockStreamFactory.Setup(f => f.CreateStream(_endPoint, CancellationToken.None))
                  .Returns(mockStream.Object);
                var readTcs = new TaskCompletionSource<int>();
                mockStream.Setup(s => s.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>()))
                    .Returns(() => readTcs.Task.GetAwaiter().GetResult());
                mockStream.Setup(s => s.ReadAsync(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<CancellationToken>()))
                    .Returns(readTcs.Task);
                _subject.Open(CancellationToken.None);
                _capturedEvents.Clear();

                Task task1;
                if (async1)
                {
                    task1 = _subject.ReceiveMessageAsync(1, encoderSelector, _messageEncoderSettings, It.IsAny<CancellationToken>());
                }
                else
                {
                    var task1IsRunning = 0;
                    task1 = Task.Run(() => { Interlocked.Exchange(ref task1IsRunning, 1); return _subject.ReceiveMessage(1, encoderSelector, _messageEncoderSettings, CancellationToken.None); });
                    SpinWait.SpinUntil(() => Interlocked.CompareExchange(ref task1IsRunning, 0, 0) == 1, 1000).Should().BeTrue();
                }

                Task task2;
                if (async2)
                {
                    task2 = _subject.ReceiveMessageAsync(2, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    var task2IsRunning = 0;
                    task2 = Task.Run(() => { Interlocked.Exchange(ref task2IsRunning, 1); return _subject.ReceiveMessage(2, encoderSelector, _messageEncoderSettings, CancellationToken.None); });
                    SpinWait.SpinUntil(() => Interlocked.CompareExchange(ref task2IsRunning, 0, 0) == 1, 1000).Should().BeTrue();
                }

                readTcs.SetException(new SocketException());

                Func<Task> act1 = () => task1;
                act1.ShouldThrow<MongoConnectionException>()
                    .WithInnerException<SocketException>()
                    .And.ConnectionId.Should().Be(_subject.ConnectionId);

                Func<Task> act2 = () => task2;
                act2.ShouldThrow<MongoConnectionException>()
                    .WithInnerException<SocketException>()
                    .And.ConnectionId.Should().Be(_subject.ConnectionId);

                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionFailedEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
        public void ReceiveMessage_should_throw_MongoConnectionClosedException_when_connection_has_failed(
            [Values(false, true)]
            bool async1,
            [Values(false, true)]
            bool async2)
        {
            using (var stream = Substitute.For<Stream>())
            {
                _streamFactory.CreateStream(null, CancellationToken.None)
                   .ReturnsForAnyArgs(stream);
                var readTcs = new TaskCompletionSource<int>();
                readTcs.SetException(new SocketException());
                stream.Read(null, 0, 0)
                    .ReturnsForAnyArgs(_ => readTcs.Task.GetAwaiter().GetResult());
                stream.ReadAsync(null, 0, 0, CancellationToken.None)
                    .ReturnsForAnyArgs(readTcs.Task);
                _subject.Open(CancellationToken.None);
                _capturedEvents.Clear();

                var encoderSelector = new ReplyMessageEncoderSelector<BsonDocument>(BsonDocumentSerializer.Instance);

                Action act1;
                if (async1)
                {
                    act1 = () => _subject.ReceiveMessageAsync(1, encoderSelector, _messageEncoderSettings, CancellationToken.None).GetAwaiter().GetResult();
                }
                else
                {
                    act1 = () => _subject.ReceiveMessage(1, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }

                Action act2;
                if (async2)
                {
                    act2 = () => _subject.ReceiveMessageAsync(2, encoderSelector, _messageEncoderSettings, CancellationToken.None).GetAwaiter().GetResult();
                }
                else
                {
                    act2 = () => _subject.ReceiveMessage(2, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }

                act1.ShouldThrow<MongoConnectionException>()
                    .WithInnerException<SocketException>()
                    .And.ConnectionId.Should().Be(_subject.ConnectionId);

                act2.ShouldThrow<MongoConnectionClosedException>()
                    .And.ConnectionId.Should().Be(_subject.ConnectionId);

                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionFailedEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
        public async Task ReceiveMessageAsync_should_throw_MongoConnectionClosedException_when_connection_has_failed()
        {
            using (var stream = Substitute.For<Stream>())
            {
                _streamFactory.CreateStreamAsync(null, CancellationToken.None)
                    .ReturnsForAnyArgs(Task.FromResult<Stream>(stream));

                var readTcs = new TaskCompletionSource<int>();
                stream.ReadAsync(null, 0, 0, CancellationToken.None)
                    .ReturnsForAnyArgs(readTcs.Task);

                var writeTcs = new TaskCompletionSource<int>();
                stream.WriteAsync(null, 0, 0, CancellationToken.None)
                    .ReturnsForAnyArgs(writeTcs.Task);

                await _subject.OpenAsync(CancellationToken.None);
                _capturedEvents.Clear();

                var encoderSelector = new ReplyMessageEncoderSelector<BsonDocument>(BsonDocumentSerializer.Instance);
                var task1 = _subject.ReceiveMessageAsync(1, encoderSelector, _messageEncoderSettings, CancellationToken.None);

                readTcs.SetException(new SocketException());

                Func<Task> act1 = () => task1;
                act1.ShouldThrow<MongoConnectionException>()
                    .WithInnerException<SocketException>()
                    .And.ConnectionId.Should().Be(_subject.ConnectionId);

                var task2 = _subject.ReceiveMessageAsync(2, encoderSelector, _messageEncoderSettings, CancellationToken.None);

                Func<Task> act2 = () => task2;
                act2.ShouldThrow<MongoConnectionClosedException>()
                    .And.ConnectionId.Should().Be(_subject.ConnectionId);

                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionFailedEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
        public void ReceiveMessageAsync_should_handle_out_of_order_replies()
        {
            using (var stream = new BlockingMemoryStream())
            {
                _streamFactory.CreateStreamAsync(null, CancellationToken.None)
                    .ReturnsForAnyArgs(Task.FromResult<Stream>(stream));

                _subject.OpenAsync(CancellationToken.None).Wait();
                _capturedEvents.Clear();

                var encoderSelector = new ReplyMessageEncoderSelector<BsonDocument>(BsonDocumentSerializer.Instance);
                var receivedTask11 = _subject.ReceiveMessageAsync(11, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                var receivedTask10 = _subject.ReceiveMessageAsync(10, encoderSelector, _messageEncoderSettings, CancellationToken.None);

                var messageToReceive10 = MessageHelper.BuildSuccessReply<BsonDocument>(new BsonDocument(), BsonDocumentSerializer.Instance, responseTo: 10);
                var messageToReceive11 = MessageHelper.BuildSuccessReply<BsonDocument>(new BsonDocument(), BsonDocumentSerializer.Instance, responseTo: 11);
                MessageHelper.WriteResponsesToStream(stream, new[] { messageToReceive10, messageToReceive11 });

                var received11 = receivedTask11.Result;
                var received10 = receivedTask10.Result;

                var expected = MessageHelper.TranslateMessagesToBsonDocuments(new[] { messageToReceive11, messageToReceive10 });
                var actual = MessageHelper.TranslateMessagesToBsonDocuments(new[] { received11, received10 });

                actual.Should().BeEquivalentTo(expected);

                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivedMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivedMessageEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
        public void ReceiveMessageAsync_should_complete_when_reply_is_not_already_on_the_stream()
        {
            using (var stream = new BlockingMemoryStream())
            {
                _streamFactory.CreateStreamAsync(null, CancellationToken.None)
                    .ReturnsForAnyArgs(Task.FromResult<Stream>(stream));

                _subject.OpenAsync(CancellationToken.None).Wait();
                _capturedEvents.Clear();

                var encoderSelector = new ReplyMessageEncoderSelector<BsonDocument>(BsonDocumentSerializer.Instance);
                var receivedTask = _subject.ReceiveMessageAsync(10, encoderSelector, _messageEncoderSettings, CancellationToken.None);

                receivedTask.IsCompleted.Should().BeFalse();

                var messageToReceive = MessageHelper.BuildReply<BsonDocument>(new BsonDocument(), BsonDocumentSerializer.Instance, responseTo: 10);
                MessageHelper.WriteResponsesToStream(stream, new[] { messageToReceive });

                var received = receivedTask.Result;

                var expected = MessageHelper.TranslateMessagesToBsonDocuments(new[] { messageToReceive });
                var actual = MessageHelper.TranslateMessagesToBsonDocuments(new[] { received });

                actual.Should().BeEquivalentTo(expected);

                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivedMessageEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
        public void ReceiveMessage_should_throw_MongoConnectionClosedException_when_connection_has_failed(
            [Values(false, true)]
            bool async1,
            [Values(false, true)]
            bool async2)
        {
            var mockStream = new Mock<Stream>();
            using (mockStream.Object)
            {
                _mockStreamFactory.Setup(f => f.CreateStream(_endPoint, CancellationToken.None))
                   .Returns(mockStream.Object);
                var readTcs = new TaskCompletionSource<int>();
                readTcs.SetException(new SocketException());
                mockStream.Setup(s => s.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>()))
                    .Returns(() => readTcs.Task.GetAwaiter().GetResult());
                mockStream.Setup(s => s.ReadAsync(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<CancellationToken>()))
                    .Returns(readTcs.Task);
                _subject.Open(CancellationToken.None);
                _capturedEvents.Clear();

                var encoderSelector = new ReplyMessageEncoderSelector<BsonDocument>(BsonDocumentSerializer.Instance);

                Action act1;
                if (async1)
                {
                    act1 = () => _subject.ReceiveMessageAsync(1, encoderSelector, _messageEncoderSettings, CancellationToken.None).GetAwaiter().GetResult();
                }
                else
                {
                    act1 = () => _subject.ReceiveMessage(1, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }

                Action act2;
                if (async2)
                {
                    act2 = () => _subject.ReceiveMessageAsync(2, encoderSelector, _messageEncoderSettings, CancellationToken.None).GetAwaiter().GetResult();
                }
                else
                {
                    act2 = () => _subject.ReceiveMessage(2, encoderSelector, _messageEncoderSettings, CancellationToken.None);
                }

                act1.ShouldThrow<MongoConnectionException>()
                    .WithInnerException<SocketException>()
                    .And.ConnectionId.Should().Be(_subject.ConnectionId);

                act2.ShouldThrow<MongoConnectionClosedException>()
                    .And.ConnectionId.Should().Be(_subject.ConnectionId);

                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionFailedEvent>();
                _capturedEvents.Next().Should().BeOfType<ConnectionReceivingMessageFailedEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }