public async Task ConsumeInputRequestException() { // Setup: // ... Create a message reader that will return a request var mr = new Mock <MessageReader>(Stream.Null, null); mr.SetupSequence(o => o.ReadMessage()) .ReturnsAsync(CommonObjects.RequestMessage) .Returns(Task.FromException <Message>(new EndOfStreamException())); // ... Create a JSON RPC host and register the request handler to throw exception var jh = new JsonRpcHost(GetChannelBase(mr.Object, null).Object); var mockHandler = new Mock <Action <CommonObjects.TestMessageContents, RequestContext <CommonObjects.TestMessageContents> > >(); mockHandler.Setup(m => m(It.IsAny <CommonObjects.TestMessageContents>(), It.IsAny <RequestContext <CommonObjects.TestMessageContents> >())) .Throws(new Exception()); jh.SetRequestHandler(CommonObjects.RequestType, mockHandler.Object); // If: I start the input consumption loop await jh.ConsumeInput().WithTimeout(TimeSpan.FromSeconds(1)); // Then: // ... Read message should have been called twice mr.Verify(o => o.ReadMessage(), Times.Exactly(2)); // ... There should not be any outgoing messages var outgoing = jh.outputQueue.ToArray(); Assert.Empty(outgoing); }
public async Task ConsumeInputRequestMethodNotFound() { // Setup: Create a message reader that will return a request with method that doesn't exist var mr = new Mock <MessageReader>(Stream.Null, null); mr.SetupSequence(o => o.ReadMessage()) .ReturnsAsync(CommonObjects.RequestMessage) .Returns(Task.FromException <Message>(new EndOfStreamException())); // If: I start the input consumption loop var jh = new JsonRpcHost(GetChannelBase(mr.Object, null).Object); await jh.ConsumeInput().WithTimeout(TimeSpan.FromSeconds(1)); // Then: // ... Read message should have been called twice mr.Verify(o => o.ReadMessage(), Times.Exactly(2)); // ... There should be an outgoing message with the error var outgoing = jh.outputQueue.ToArray(); Assert.Single(outgoing); Assert.Equal(MessageType.ResponseError, outgoing[0].MessageType); Assert.Equal(CommonObjects.MessageId, outgoing[0].Id); Assert.Equal(-32601, outgoing[0].Contents.Value <int>("code")); }
public async Task ConsumeInputEndOfStream() { // Setup: Create a message reader that will throw an end of stream exception on read var mr = new Mock <MessageReader>(Stream.Null, null); mr.Setup(o => o.ReadMessage()).Returns(Task.FromException <Message>(new EndOfStreamException())); // If: I start the input consumption thread // Then: // ... It should stop gracefully var jh = new JsonRpcHost(GetChannelBase(mr.Object, null).Object); await jh.ConsumeInput().WithTimeout(TimeSpan.FromSeconds(1)); // ... The read message should have only been called once mr.Verify(o => o.ReadMessage(), Times.Once); }
public async Task ConsumeInputException() { // Setup: // ... Create a message reader that will throw an exception on first read // ... throw an end of stream on second read var mr = new Mock <MessageReader>(Stream.Null, null); mr.SetupSequence(o => o.ReadMessage()) .Returns(Task.FromException <Message>(new Exception())) .Returns(Task.FromException <Message>(new EndOfStreamException())); // If: I start the input consumption loop var jh = new JsonRpcHost(GetChannelBase(mr.Object, null).Object); await jh.ConsumeInput().WithTimeout(TimeSpan.FromSeconds(1)); // Then: // ... Read message should have been called twice mr.Verify(o => o.ReadMessage(), Times.Exactly(2)); }
public async Task ConsumeInput() { // Setup: // ... Create a message reader that will return a message every time var mr = new Mock <MessageReader>(Stream.Null, null); var waitForRead = new TaskCompletionSource <bool>(); mr.Setup(o => o.ReadMessage()) .Callback(() => waitForRead.TrySetResult(true)) .ReturnsAsync(CommonObjects.EventMessage); // ... Create a no-op event handler to handle the message from the message reader var noOpHandler = new Mock <Func <Message, Task> >(); noOpHandler.Setup(f => f(It.IsAny <Message>())).Returns(Task.FromResult(true)); // ... Wire up the event handler to a new JSON RPC host var jh = new JsonRpcHost(GetChannelBase(mr.Object, null).Object); jh.eventHandlers[CommonObjects.EventType.MethodName] = noOpHandler.Object; // If: // ... I start the input consumption thread Task consumeInputTask = jh.ConsumeInput(); // ... Wait for the handler to be called once, indicating the message was processed await waitForRead.Task.WithTimeout(TimeSpan.FromSeconds(1)); // ... Stop the input consumption thread (the hard way) and wait for completion jh.cancellationTokenSource.Cancel(); await consumeInputTask.WithTimeout(TimeSpan.FromSeconds(1)); // Then: The event handler and read message should have been called at least once noOpHandler.Verify(f => f(It.IsAny <Message>()), Times.AtLeastOnce); mr.Verify(o => o.ReadMessage(), Times.AtLeastOnce); }