public async Task StreamingSession_SendRequest_ParameterValidation() { // Arrange var transportHandler = new Mock <TransportHandler>(new Mock <IDuplexPipe>().Object, NullLogger.Instance); var session = new StreamingSession(new Mock <RequestHandler>().Object, transportHandler.Object, NullLogger.Instance); // Act + Assert await Assert.ThrowsAsync <ArgumentNullException>(() => session.SendRequestAsync(null, CancellationToken.None)); }
/// <summary> /// Sends a streaming request through the connection. /// </summary> /// <param name="request"><see cref="StreamingRequest"/> to be sent.</param> /// <param name="cancellationToken"><see cref="CancellationToken"/> to cancel the send process.</param> /// <returns>The <see cref="ReceiveResponse"/> returned from the client.</returns> public virtual async Task <ReceiveResponse> SendStreamingRequestAsync(StreamingRequest request, CancellationToken cancellationToken = default) { if (request == null) { throw new ArgumentNullException(nameof(request)); } // This request could come fast while the session, transport and application are still being set up. // Wait for the session to signal that application and transport started before using the session. await _sessionInitializedTask.Task.ConfigureAwait(false); if (_session == null) { throw new InvalidOperationException("Cannot send streaming request since the session is not set up."); } return(await _session.SendRequestAsync(request, cancellationToken).ConfigureAwait(false)); }
public async Task StreamingSession_SendRequest_ReceiveResponse(int streamLength, int streamCount, int chunkCount) { // Arrange var request = new StreamingRequest() { Verb = "GET", Path = "api/version", Streams = new List <ResponseMessageStream>() }; request.AddStream(new StringContent("Hello human, I'm Bender!")); var requestHandler = new Mock <RequestHandler>(); var requestCompletionSource = new TaskCompletionSource <bool>(); requestHandler .Setup(r => r.ProcessRequestAsync(It.IsAny <ReceiveRequest>(), null, null, CancellationToken.None)) .ReturnsAsync(() => new StreamingResponse() { StatusCode = 200 }) .Callback(() => requestCompletionSource.SetResult(true)); var transportHandler = new Mock <TransportHandler>(new Mock <IDuplexPipe>().Object, NullLogger.Instance); var responseCompletionSource = new TaskCompletionSource <bool>(); var transportHandlerSetup = transportHandler.Setup(t => t.SendRequestAsync(It.IsAny <Guid>(), It.IsAny <RequestModel>(), CancellationToken.None)); var session = new StreamingSession(requestHandler.Object, transportHandler.Object, NullLogger.Instance); Header responseHeader = null; ReceiveResponse response = null; transportHandlerSetup.Callback( (Guid requestId, RequestModel requestPayload, CancellationToken cancellationToken) => { responseHeader = new Header() { Id = requestId, Type = PayloadTypes.Response }; response = new ReceiveResponse() { StatusCode = 200, Streams = StreamingDataGenerator.CreateStreams(requestId, streamLength, streamCount, chunkCount, PayloadTypes.Response) }; session.ReceiveResponse(responseHeader, response); foreach (AugmentedStreamDefinition definition in response.Streams) { var chunkList = definition.Chunks; for (int i = 0; i < chunkCount; i++) { bool isLast = i == chunkCount - 1; session.ReceiveStream( new Header() { End = isLast, Id = definition.Id, PayloadLength = chunkList[i].Length, Type = PayloadTypes.Stream }, chunkList[i]); } } }); // Act var responseTask = session.SendRequestAsync(request, CancellationToken.None); var responseWithTimeout = await Task.WhenAny(responseTask, Task.Delay(TimeSpan.FromSeconds(5))); // Assert Assert.Equal(responseTask, responseWithTimeout); var receivedResponse = await responseTask; Assert.Equal(response.StatusCode, receivedResponse.StatusCode); Assert.Equal(response.Streams.Count, receivedResponse.Streams.Count); Assert.True(response.Streams.SequenceEqual(receivedResponse.Streams)); }