public async Task SendMessageAsync_should_throw_MongoConnectionClosedException_for_waiting_tasks() { 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 message1 = new KillCursorsMessage(1, new[] { 1L }); var task1 = _subject.SendMessageAsync(message1, _messageEncoderSettings, CancellationToken.None); var message2 = new KillCursorsMessage(2, new[] { 2L }); var task2 = _subject.SendMessageAsync(message2, _messageEncoderSettings, CancellationToken.None); writeTcs.SetException(new SocketException()); Func <Task> act1 = () => task1; act1.ShouldThrow <MongoConnectionException>() .WithInnerException <SocketException>() .And.ConnectionId.Should().Be(_subject.ConnectionId); Func <Task> act2 = () => task2; act2.ShouldThrow <MongoConnectionClosedException>(); _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesEvent>(); _capturedEvents.Next().Should().BeOfType <CommandStartedEvent>(); _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesEvent>(); _capturedEvents.Next().Should().BeOfType <CommandStartedEvent>(); _capturedEvents.Next().Should().BeOfType <ConnectionFailedEvent>(); _capturedEvents.Next().Should().BeOfType <CommandFailedEvent>(); _capturedEvents.Next().Should().BeOfType <CommandFailedEvent>(); _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesFailedEvent>(); _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesFailedEvent>(); _capturedEvents.Any().Should().BeFalse(); } }
public void SendMessageAsync_should_throw_MessageNotSentException_for_queued_messages() { 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); _subject.OpenAsync(CancellationToken.None).Wait(); var message1 = new KillCursorsMessage(1, new[] { 1L }); var task1 = _subject.SendMessageAsync(message1, _messageEncoderSettings, CancellationToken.None); var message2 = new KillCursorsMessage(2, new[] { 2L }); var task2 = _subject.SendMessageAsync(message2, _messageEncoderSettings, CancellationToken.None); writeTcs.SetException(new SocketException()); Action act1 = () => task1.GetAwaiter().GetResult(); act1.ShouldThrow <SocketException>(); Action act2 = () => task2.GetAwaiter().GetResult(); act2.ShouldThrow <MongoMessageNotSentException>(); _listener.ReceivedWithAnyArgs().ConnectionBeforeSendingMessages(default(ConnectionBeforeSendingMessagesEvent)); _listener.ReceivedWithAnyArgs().ConnectionErrorSendingMessages(default(ConnectionErrorSendingMessagesEvent)); _listener.ReceivedWithAnyArgs().ConnectionFailed(default(ConnectionFailedEvent)); } }
public void SendMessageshould_throw_MongoConnectionClosedException_for_waiting_tasks( [Values(false, true)] bool async1, [Values(false, true)] bool async2) { using (var stream = Substitute.For <Stream>()) { var message1 = new KillCursorsMessage(1, new[] { 1L }); var message2 = new KillCursorsMessage(2, new[] { 2L }); _streamFactory.CreateStream(null, CancellationToken.None) .ReturnsForAnyArgs(stream); var task1IsBlocked = false; var writeTcs = new TaskCompletionSource <int>(); stream .When(s => s.Write(Arg.Any <byte[]>(), Arg.Any <int>(), Arg.Any <int>())) .Do(_ => { task1IsBlocked = true; writeTcs.Task.GetAwaiter().GetResult(); }); stream.WriteAsync(null, 0, 0, CancellationToken.None) .ReturnsForAnyArgs(_ => { task1IsBlocked = true; return(writeTcs.Task); }); _subject.Open(CancellationToken.None); _capturedEvents.Clear(); Task task1; if (async1) { task1 = _subject.SendMessageAsync(message1, _messageEncoderSettings, CancellationToken.None); } else { task1 = Task.Run(() => { _subject.SendMessage(message1, _messageEncoderSettings, CancellationToken.None); }); } SpinWait.SpinUntil(() => task1IsBlocked); Task task2; if (async2) { task2 = _subject.SendMessageAsync(message2, _messageEncoderSettings, CancellationToken.None); } else { var task2IsRunning = false; task2 = Task.Run(() => { task2IsRunning = true; _subject.SendMessage(message2, _messageEncoderSettings, CancellationToken.None); }); SpinWait.SpinUntil(() => task2IsRunning, 100); } writeTcs.SetException(new SocketException()); Func <Task> act1 = () => task1; act1.ShouldThrow <MongoConnectionException>() .WithInnerException <SocketException>() .And.ConnectionId.Should().Be(_subject.ConnectionId); Func <Task> act2 = () => task2; act2.ShouldThrow <MongoConnectionClosedException>(); _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesEvent>(); _capturedEvents.Next().Should().BeOfType <CommandStartedEvent>(); _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesEvent>(); _capturedEvents.Next().Should().BeOfType <CommandStartedEvent>(); _capturedEvents.Next().Should().BeOfType <ConnectionFailedEvent>(); _capturedEvents.Next().Should().BeOfType <CommandFailedEvent>(); _capturedEvents.Next().Should().BeOfType <CommandFailedEvent>(); _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesFailedEvent>(); _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesFailedEvent>(); _capturedEvents.Any().Should().BeFalse(); } }
public void SendMessageshould_throw_MongoConnectionClosedException_for_waiting_tasks( [Values(false, true)] bool async1, [Values(false, true)] bool async2) { var mockStream = new Mock <Stream>(); using (mockStream.Object) { var message1 = new KillCursorsMessage(1, new[] { 1L }); var message2 = new KillCursorsMessage(2, new[] { 2L }); _mockStreamFactory.Setup(f => f.CreateStream(_endPoint, CancellationToken.None)) .Returns(mockStream.Object); var task1IsBlocked = false; var writeTcs = new TaskCompletionSource <int>(); mockStream.Setup(s => s.Write(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>())) .Callback(() => { task1IsBlocked = true; writeTcs.Task.GetAwaiter().GetResult(); }); mockStream.Setup(s => s.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>())) .Returns(() => { task1IsBlocked = true; return(writeTcs.Task); }); _subject.Open(CancellationToken.None); _capturedEvents.Clear(); Task task1; if (async1) { task1 = _subject.SendMessageAsync(message1, _messageEncoderSettings, CancellationToken.None); } else { task1 = Task.Run(() => { _subject.SendMessage(message1, _messageEncoderSettings, CancellationToken.None); }); } SpinWait.SpinUntil(() => task1IsBlocked, TimeSpan.FromSeconds(5)).Should().BeTrue(); task1IsBlocked.Should().BeTrue(); Task task2; if (async2) { task2 = _subject.SendMessageAsync(message2, _messageEncoderSettings, CancellationToken.None); } else { var task2IsRunning = 0; task2 = Task.Run(() => { Interlocked.Exchange(ref task2IsRunning, 1); _subject.SendMessage(message2, _messageEncoderSettings, CancellationToken.None); }); SpinWait.SpinUntil(() => Interlocked.CompareExchange(ref task2IsRunning, 0, 0) == 1, TimeSpan.FromSeconds(5)).Should().BeTrue(); } writeTcs.SetException(new SocketException()); Func <Task> act1 = () => task1; act1.ShouldThrow <MongoConnectionException>() .WithInnerException <SocketException>() .And.ConnectionId.Should().Be(_subject.ConnectionId); Func <Task> act2 = () => task2; act2.ShouldThrow <MongoConnectionClosedException>(); SpinWait.SpinUntil(() => _capturedEvents.Count >= 9, TimeSpan.FromSeconds(5)); _capturedEvents.Count.Should().Be(9); var allEvents = new List <object>(); while (_capturedEvents.Any()) { allEvents.Add(_capturedEvents.Next()); } var request1Events = GetEventsForRequest(allEvents, message1.RequestId); request1Events.Should().HaveCount(4); request1Events[0].Should().BeOfType <ConnectionSendingMessagesEvent>(); request1Events[1].Should().BeOfType <CommandStartedEvent>(); request1Events[2].Should().BeOfType <CommandFailedEvent>(); request1Events[3].Should().BeOfType <ConnectionSendingMessagesFailedEvent>(); var request2Events = GetEventsForRequest(allEvents, message2.RequestId); request2Events.Should().HaveCount(4); request2Events[0].Should().BeOfType <ConnectionSendingMessagesEvent>(); request2Events[1].Should().BeOfType <CommandStartedEvent>(); request2Events[2].Should().BeOfType <CommandFailedEvent>(); request2Events[3].Should().BeOfType <ConnectionSendingMessagesFailedEvent>(); var connectionFailedEvents = allEvents.OfType <ConnectionFailedEvent>().ToList(); connectionFailedEvents.Should().HaveCount(1); } }
public void SendMessageshould_throw_MongoConnectionClosedException_for_waiting_tasks( [Values(false, true)] bool async1, [Values(false, true)] bool async2) { var mockStream = new Mock <Stream>(); using (mockStream.Object) { var message1 = new KillCursorsMessage(1, new[] { 1L }); var message2 = new KillCursorsMessage(2, new[] { 2L }); _mockStreamFactory.Setup(f => f.CreateStream(_endPoint, CancellationToken.None)) .Returns(mockStream.Object); var task1IsBlocked = false; var writeTcs = new TaskCompletionSource <int>(); mockStream.Setup(s => s.Write(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>())) .Callback(() => { task1IsBlocked = true; writeTcs.Task.GetAwaiter().GetResult(); }); mockStream.Setup(s => s.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>())) .Returns(() => { task1IsBlocked = true; return(writeTcs.Task); }); _subject.Open(CancellationToken.None); _capturedEvents.Clear(); Task task1; if (async1) { task1 = _subject.SendMessageAsync(message1, _messageEncoderSettings, CancellationToken.None); } else { task1 = Task.Run(() => { _subject.SendMessage(message1, _messageEncoderSettings, CancellationToken.None); }); } SpinWait.SpinUntil(() => task1IsBlocked, 1000).Should().BeTrue(); task1IsBlocked.Should().BeTrue(); Task task2; if (async2) { task2 = _subject.SendMessageAsync(message2, _messageEncoderSettings, CancellationToken.None); } else { var task2IsRunning = 0; task2 = Task.Run(() => { Interlocked.Exchange(ref task2IsRunning, 1); _subject.SendMessage(message2, _messageEncoderSettings, CancellationToken.None); }); SpinWait.SpinUntil(() => Interlocked.CompareExchange(ref task2IsRunning, 0, 0) == 1, 1000).Should().BeTrue(); } writeTcs.SetException(new SocketException()); Func <Task> act1 = () => task1; act1.ShouldThrow <MongoConnectionException>() .WithInnerException <SocketException>() .And.ConnectionId.Should().Be(_subject.ConnectionId); Func <Task> act2 = () => task2; act2.ShouldThrow <MongoConnectionClosedException>(); _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesEvent>(); _capturedEvents.Next().Should().BeOfType <CommandStartedEvent>(); _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesEvent>(); _capturedEvents.Next().Should().BeOfType <CommandStartedEvent>(); _capturedEvents.Next().Should().BeOfType <ConnectionFailedEvent>(); _capturedEvents.Next().Should().BeOfType <CommandFailedEvent>(); var events7And8Types = new Type[] { _capturedEvents.Next().GetType(), _capturedEvents.Next().GetType() }; var expectedEventTypes = new Type[] { typeof(CommandFailedEvent), typeof(ConnectionSendingMessagesFailedEvent) }; events7And8Types.Should().BeEquivalentTo(expectedEventTypes); _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesFailedEvent>(); _capturedEvents.Any().Should().BeFalse(); } }