示例#1
0
        public async Task CanSendData()
        {
            var data = new byte[] { 1, 1, 2, 3, 5, 8 };

            var sendTcs         = new TaskCompletionSource <byte[]>();
            var mockHttpHandler = new Mock <HttpMessageHandler>();

            mockHttpHandler.Protected()
            .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
            .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
            {
                await Task.Yield();
                if (request.Method == HttpMethod.Post)
                {
                    sendTcs.SetResult(await request.Content.ReadAsByteArrayAsync());
                }

                return(request.Method == HttpMethod.Options
                        ? ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationResponse())
                        : ResponseUtils.CreateResponse(HttpStatusCode.OK));
            });

            var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object);

            try
            {
                await connection.StartAsync();

                await connection.SendAsync(data);

                Assert.Equal(data, await sendTcs.Task.OrTimeout());
            }
            finally
            {
                await connection.DisposeAsync();
            }
        }
        public async Task ResolverReturnsNoAddresses_DisposeWhileWaitForReady_Error()
        {
            // Arrange
            var testMessageHandler = TestHttpMessageHandler.Create(async request =>
            {
                var reply = new HelloReply {
                    Message = "Hello world"
                };
                var streamContent = await ClientTestHelpers.CreateResponseContent(reply).DefaultTimeout();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });

            var services = new ServiceCollection();

            services.AddSingleton <TestResolver>();
            services.AddSingleton <ResolverFactory, TestResolverFactory>();
            services.AddSingleton <ISubchannelTransportFactory>(new TestSubchannelTransportFactory());

            var invoker = HttpClientCallInvokerFactory.Create(testMessageHandler, "test:///localhost", configure: o =>
            {
                o.Credentials     = ChannelCredentials.Insecure;
                o.ServiceProvider = services.BuildServiceProvider();
            });

            // Act
            var callOptions = new CallOptions().WithWaitForReady();
            var call        = invoker.AsyncUnaryCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, callOptions, new HelloRequest());

            var exTask = ExceptionAssert.ThrowsAsync <RpcException>(() => call.ResponseAsync);

            call.Dispose();

            var ex = await exTask.DefaultTimeout();

            Assert.AreEqual(StatusCode.Cancelled, ex.StatusCode);
            Assert.AreEqual("gRPC call disposed.", ex.Status.Detail);
        }
示例#3
0
        public async Task AsyncServerStreamingCall_MessagesReturnedTogether_MessagesReceived()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponsesContent(
                    new HelloReply
                {
                    Message = "Hello world 1"
                },
                    new HelloReply
                {
                    Message = "Hello world 2"
                }).DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var call = invoker.AsyncServerStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(), new HelloRequest());

            var responseStream = call.ResponseStream;

            // Assert
            Assert.IsNull(responseStream.Current);

            Assert.IsTrue(await responseStream.MoveNext(CancellationToken.None).DefaultTimeout());
            Assert.IsNotNull(responseStream.Current);
            Assert.AreEqual("Hello world 1", responseStream.Current.Message);

            Assert.IsTrue(await responseStream.MoveNext(CancellationToken.None).DefaultTimeout());
            Assert.IsNotNull(responseStream.Current);
            Assert.AreEqual("Hello world 2", responseStream.Current.Message);

            Assert.IsFalse(await responseStream.MoveNext(CancellationToken.None).DefaultTimeout());
        }
        public async Task HttpConnectionSetsRequestedWithOnAllRequests(HttpTransportType transportType)
        {
            var testHttpHandler  = new TestHttpMessageHandler(autoNegotiate: false);
            var requestsExecuted = false;

            testHttpHandler.OnNegotiate((_, cancellationToken) =>
            {
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationContent()));
            });

            testHttpHandler.OnRequest(async(request, next, token) =>
            {
                var requestedWithHeader = request.Headers.GetValues(HeaderNames.XRequestedWith);
                var requestedWithValue  = Assert.Single(requestedWithHeader);
                Assert.Equal("XMLHttpRequest", requestedWithValue);

                requestsExecuted = true;

                return(await next());
            });

            testHttpHandler.OnRequest((request, next, token) =>
            {
                return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.NoContent)));
            });

            await WithConnectionAsync(
                CreateConnection(testHttpHandler, transportType : transportType),
                async (connection) =>
            {
                await connection.StartAsync().DefaultTimeout();
                await connection.Transport.Output.WriteAsync(Encoding.UTF8.GetBytes("Hello World"));
            });

            // Fail safe in case the code is modified and some requests don't execute as a result
            Assert.True(requestsExecuted);
        }
        public async Task Intercept_WrapClientStream_ClientStreamWrapperExecuted()
        {
            // Arrange
            var serviceMethod = new Method <string, string>(MethodType.Unary, "ServiceName", "Unary", Marshallers.StringMarshaller, Marshallers.StringMarshaller);

            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var requestContent = await request.Content.ReadAsStreamAsync();
                await requestContent.CopyToAsync(new MemoryStream());

                var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply {
                    Message = "PASS"
                }).DefaultTimeout();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });

            var stringBuilder = new StringBuilder();
            var invoker       = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var callInvoker = invoker.Intercept(new ClientStreamingCountingInterceptor());

            var call = callInvoker.AsyncClientStreamingCall(serviceMethod, Host, new CallOptions());
            await call.RequestStream.WriteAsync("A");

            await call.RequestStream.WriteAsync("B");

            await call.RequestStream.WriteAsync("C");

            await call.RequestStream.CompleteAsync();

            // Assert
            Assert.AreEqual("3", await call.ResponseAsync);

            Assert.AreEqual(StatusCode.OK, call.GetStatus().StatusCode);
            Assert.IsNotNull(call.GetTrailers());
        }
示例#6
0
        public async Task MoveNextAsync_MultipleMessages_MessagesReceived()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponsesContent(
                    new HelloReply
                {
                    Message = "Hello world 1"
                },
                    new HelloReply
                {
                    Message = "Hello world 2"
                }).DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var call = invoker.AsyncServerStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(), new HelloRequest());

            var enumerator = call.ResponseStream.ReadAllAsync().GetAsyncEnumerator();

            // Assert
            Assert.IsNull(enumerator.Current);

            Assert.IsTrue(await enumerator.MoveNextAsync().AsTask().DefaultTimeout());
            Assert.IsNotNull(enumerator.Current);
            Assert.AreEqual("Hello world 1", enumerator.Current.Message);

            Assert.IsTrue(await enumerator.MoveNextAsync().AsTask().DefaultTimeout());
            Assert.IsNotNull(enumerator.Current);
            Assert.AreEqual("Hello world 2", enumerator.Current.Message);

            Assert.IsFalse(await enumerator.MoveNextAsync().AsTask().DefaultTimeout());
        }
示例#7
0
        public async Task MoveNextAsync_CancelCall_ThrowOperationCanceledOnCancellation_EnumeratorThrows()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponsesContent(
                    new HelloReply
                    {
                        Message = "Hello world 1"
                    },
                    new HelloReply
                    {
                        Message = "Hello world 2"
                    }).DefaultTimeout();

                return ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent);
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient, configure: o => o.ThrowOperationCanceledOnCancellation = true);
            var cts = new CancellationTokenSource();

            // Act
            var call = invoker.AsyncServerStreamingCall<HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(cancellationToken: cts.Token), new HelloRequest());

            var enumerator = call.ResponseStream.ReadAllAsync().GetAsyncEnumerator();

            // Assert
            Assert.IsNull(enumerator.Current);

            Assert.IsTrue(await enumerator.MoveNextAsync().AsTask().DefaultTimeout());
            Assert.IsNotNull(enumerator.Current);
            Assert.AreEqual("Hello world 1", enumerator.Current.Message);

            cts.Cancel();

            await ExceptionAssert.ThrowsAsync<OperationCanceledException>(() => enumerator.MoveNextAsync().AsTask()).DefaultTimeout();
            Assert.AreEqual(StatusCode.Cancelled, call.GetStatus().StatusCode);
        }
示例#8
0
        public void AsyncClientStreamingCall_DeadlineDuringSend_ResponseThrowsDeadlineExceededStatus()
        {
            // Arrange
            var httpClient = TestHelpers.CreateTestClient(async request =>
            {
                var content = (PushStreamContent)request.Content;
                await content.PushComplete.DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var call = invoker.AsyncClientStreamingCall <HelloRequest, HelloReply>(TestHelpers.ServiceMethod, string.Empty, new CallOptions(deadline: DateTime.UtcNow.AddSeconds(0.5)));

            // Assert
            var responseTask = call.ResponseAsync;

            Assert.IsFalse(responseTask.IsCompleted, "Response not returned until client stream is complete.");

            var ex = Assert.ThrowsAsync <RpcException>(async() => await responseTask.DefaultTimeout());

            Assert.AreEqual(StatusCode.DeadlineExceeded, ex.Status.StatusCode);
        }
示例#9
0
        public async Task AsyncClientStreamingCall_WriteAfterResult_Error()
        {
            // Arrange
            var requestContent = new MemoryStream();

            var callCount  = 0;
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                Interlocked.Increment(ref callCount);

                _ = request.Content !.ReadAsStreamAsync();

                var reply = new HelloReply {
                    Message = "Hello world"
                };
                var streamContent = await ClientTestHelpers.CreateResponseContent(reply).DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });
            var serviceConfig = ServiceConfigHelpers.CreateHedgingServiceConfig();
            var invoker       = HttpClientCallInvokerFactory.Create(httpClient, serviceConfig: serviceConfig);

            // Act
            var call = invoker.AsyncClientStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.GetServiceMethod(MethodType.ClientStreaming), string.Empty, new CallOptions());

            // Assert
            var responseMessage = await call.ResponseAsync.DefaultTimeout();

            Assert.AreEqual("Hello world", responseMessage.Message);

            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => call.RequestStream.WriteAsync(new HelloRequest {
                Name = "1"
            })).DefaultTimeout();

            Assert.AreEqual(StatusCode.OK, ex.StatusCode);
        }
        public async Task NegotiateThatReturnsRedirectUrlForeverThrowsAfter100Tries()
        {
            var testHttpHandler = new TestHttpMessageHandler(autoNegotiate: false);

            testHttpHandler.OnNegotiate((request, cancellationToken) =>
            {
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK,
                                                    JsonConvert.SerializeObject(new
                {
                    url = "https://another.domain.url/chat"
                })));
            });

            using (var noErrorScope = new VerifyNoErrorsScope())
            {
                await WithConnectionAsync(
                    CreateConnection(testHttpHandler, loggerFactory : noErrorScope.LoggerFactory),
                    async (connection) =>
                {
                    var exception = await Assert.ThrowsAsync <InvalidOperationException>(() => connection.StartAsync().DefaultTimeout());
                    Assert.Equal("Negotiate redirection limit exceeded.", exception.Message);
                });
            }
        }
        public async Task NegotiateCanHaveNewFields()
        {
            string connectionId = null;

            var testHttpHandler = new TestHttpMessageHandler(autoNegotiate: false);

            testHttpHandler.OnNegotiate((request, cancellationToken) => ResponseUtils.CreateResponse(HttpStatusCode.OK,
                                                                                                     JsonConvert.SerializeObject(new
            {
                connectionId        = "0rge0d00-0040-0030-0r00-000q00r00e00",
                availableTransports = new object[]
                {
                    new
                    {
                        transport       = "LongPolling",
                        transferFormats = new[] { "Text" }
                    },
                },
                newField = "ignore this",
            })));
            testHttpHandler.OnLongPoll(cancellationToken => ResponseUtils.CreateResponse(HttpStatusCode.NoContent));
            testHttpHandler.OnLongPollDelete((token) => ResponseUtils.CreateResponse(HttpStatusCode.Accepted));

            using (var noErrorScope = new VerifyNoErrorsScope())
            {
                await WithConnectionAsync(
                    CreateConnection(testHttpHandler, loggerFactory : noErrorScope.LoggerFactory),
                    async (connection) =>
                {
                    await connection.StartAsync().DefaultTimeout();
                    connectionId = connection.ConnectionId;
                });
            }

            Assert.Equal("0rge0d00-0040-0030-0r00-000q00r00e00", connectionId);
        }
示例#12
0
        public async Task LongPollingTransportCanBeCanceled()
        {
            using (StartVerifiableLog())
            {
                var cts = new CancellationTokenSource();

                var httpHandler = new TestHttpMessageHandler(autoNegotiate: false);
                httpHandler.OnNegotiate((request, cancellationToken) =>
                {
                    // Cancel token so that the first request poll will throw
                    cts.Cancel();
                    return(ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationContent()));
                });

                var lp = new LongPollingTransport(new HttpClient(httpHandler));

                await WithConnectionAsync(
                    CreateConnection(httpHandler, transport : lp, transportType : HttpTransportType.LongPolling),
                    async (connection) =>
                {
                    var ex = await Assert.ThrowsAsync <AggregateException>(async() => await connection.StartAsync(cts.Token).DefaultTimeout());
                });
            }
        }
示例#13
0
        public async Task AsyncClientStreamingCall_DeadlineBeforeWrite_ResponseThrowsDeadlineExceededStatus()
        {
            // Arrange
            var tcs = new TaskCompletionSource<object?>(TaskCreationOptions.RunContinuationsAsynchronously);
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                await tcs.Task.DefaultTimeout();
                return ResponseUtils.CreateResponse(HttpStatusCode.OK);
            });
            var systemClock = new TestSystemClock(DateTime.UtcNow);
            var invoker = HttpClientCallInvokerFactory.Create(httpClient, systemClock: systemClock);

            // Act
            var call = invoker.AsyncClientStreamingCall<HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(deadline: systemClock.UtcNow.AddMilliseconds(10)));

            // Ensure the deadline has passed
            systemClock.UtcNow = systemClock.UtcNow.AddMilliseconds(200);
            await Task.Delay(200);

            // Assert
            var ex = await ExceptionAssert.ThrowsAsync<RpcException>(() => call.RequestStream.WriteAsync(new HelloRequest())).DefaultTimeout();
            Assert.AreEqual(StatusCode.DeadlineExceeded, ex.StatusCode);
            Assert.AreEqual(StatusCode.DeadlineExceeded, call.GetStatus().StatusCode);
        }
示例#14
0
        public void InterceptMetadata_AddRequestHeader_HeaderInRequest()
        {
            // Arrange
            const string HeaderKey   = "x-client-interceptor";
            const string HeaderValue = "hello-world";

            string?requestHeaderValue = null;
            var    httpClient         = TestHelpers.CreateTestClient(async request =>
            {
                if (request.Headers.TryGetValues(HeaderKey, out var values))
                {
                    requestHeaderValue = values.Single();
                }

                var streamContent = await TestHelpers.CreateResponseContent(new HelloReply {
                    Message = "PASS"
                }).DefaultTimeout();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });

            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var callInvoker = invoker.Intercept(metadata =>
            {
                metadata = metadata ?? new Metadata();
                metadata.Add(new Metadata.Entry(HeaderKey, HeaderValue));
                return(metadata);
            });

            var result = callInvoker.BlockingUnaryCall(TestHelpers.ServiceMethod, Host, new CallOptions(), new HelloRequest());

            // Assert
            Assert.AreEqual("PASS", result.Message);
            Assert.AreEqual(HeaderValue, requestHeaderValue);
        }
示例#15
0
        public async Task AsyncUnaryCall_ErrorParsingTrailers_ThrowsError()
        {
            // Arrange
            var testSink      = new TestSink();
            var loggerFactory = new TestLoggerFactory(testSink, true);

            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply()).DefaultTimeout();
                var response      = ResponseUtils.CreateResponse(
                    HttpStatusCode.OK,
                    streamContent,
                    grpcStatusCode: StatusCode.Aborted,
                    customTrailers: new Dictionary <string, string>
                {
                    ["blah-bin"] = "!"
                });
                response.Headers.Add("custom", "ABC");
                return(response);
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient, loggerFactory);

            // Act
            var call = invoker.AsyncUnaryCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(), new HelloRequest());
            var ex   = await ExceptionAssert.ThrowsAsync <RpcException>(() => call.ResponseAsync).DefaultTimeout();

            // Assert
            Assert.AreEqual(StatusCode.Aborted, ex.StatusCode);
            Assert.AreEqual(null, ex.Status.Detail);
            Assert.AreEqual(0, ex.Trailers.Count);

            var log = testSink.Writes.Single(w => w.EventId.Name == "ErrorParsingTrailers");

            Assert.AreEqual("Error parsing trailers.", log.State.ToString());
            Assert.AreEqual("Invalid Base-64 header value.", log.Exception.Message);
        }
示例#16
0
        public async Task AsyncClientStreamingCall_DeadlineDuringSend_ResponseThrowsDeadlineExceededStatus()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var content = (PushStreamContent)request.Content;
                await content.PushComplete.DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            });
            var testSystemClock = new TestSystemClock(DateTime.UtcNow);
            var invoker         = HttpClientCallInvokerFactory.Create(httpClient, systemClock: testSystemClock);

            // Act
            var call = invoker.AsyncClientStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(deadline: testSystemClock.UtcNow.AddSeconds(0.5)));

            // Assert
            var responseTask = call.ResponseAsync;

            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => responseTask).DefaultTimeout();

            Assert.AreEqual(StatusCode.DeadlineExceeded, ex.StatusCode);
            Assert.AreEqual(StatusCode.DeadlineExceeded, call.GetStatus().StatusCode);
        }
示例#17
0
        public void GlobalSetup()
        {
            var ms = new MemoryStream();

            MessageHelpers.WriteMessage(ms, new HelloReply());
            var requestMessage = ms.ToArray();

            var handler = TestHttpMessageHandler.Create(r =>
            {
                var content = new ByteArrayContent(requestMessage);
                content.Headers.ContentType = new MediaTypeHeaderValue("application/grpc");

                return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, content)));
            });

            var httpClient = new HttpClient(handler);

            var channel = GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
            {
                HttpClient = httpClient
            });

            _client = new Greeter.GreeterClient(channel);
        }
        private async Task <HttpResponseMessage> HandleRequest(HttpRequestMessage request)
        {
            var requestStream = await request.Content !.ReadAsStreamAsync().DefaultTimeout();

            var helloRequest = await StreamExtensions.ReadMessageAsync(
                requestStream,
                new DefaultDeserializationContext(),
                NullLogger.Instance,
                ClientTestHelpers.ServiceMethod.RequestMarshaller.ContextualDeserializer,
                "gzip",
                maximumMessageSize : null,
                GrpcProtocolConstants.DefaultCompressionProviders,
                singleMessage : true,
                CancellationToken.None).AsTask().DefaultTimeout();

            var reply = new HelloReply
            {
                Message = "Hello " + helloRequest !.Name
            };

            var streamContent = await ClientTestHelpers.CreateResponseContent(reply).DefaultTimeout();

            return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
        }
示例#19
0
        public async Task AsyncClientStreamingCall_DeadlineDuringWrite_ResponseThrowsDeadlineExceededStatus()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                var stream  = new SyncPointMemoryStream();
                var content = new StreamContent(stream);
                return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, content, grpcStatusCode: null)));
            });
            var systemClock = new TestSystemClock(DateTime.UtcNow);
            var invoker     = HttpClientCallInvokerFactory.Create(httpClient, systemClock: systemClock);
            var deadline    = systemClock.UtcNow.AddMilliseconds(0.1);

            // Act
            var call = invoker.AsyncClientStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(deadline: deadline));

            systemClock.UtcNow = deadline;

            // Assert
            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => call.RequestStream.WriteAsync(new HelloRequest())).DefaultTimeout();

            Assert.AreEqual(StatusCode.DeadlineExceeded, ex.StatusCode);
            Assert.AreEqual(StatusCode.DeadlineExceeded, call.GetStatus().StatusCode);
        }
示例#20
0
        public async Task AsyncServerStreamingCall_MessagesReturnedTogether_MessagesReceived()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                HelloReply reply = new HelloReply
                {
                    Message = "Hello world"
                };

                return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, new ByteArrayContent(Array.Empty <byte>()))));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var call = invoker.AsyncDuplexStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions());

            var responseStream = call.ResponseStream;

            // Assert
            Assert.IsNull(responseStream.Current);
            Assert.IsFalse(await responseStream.MoveNext(CancellationToken.None).DefaultTimeout());
            Assert.IsNull(responseStream.Current);
        }
        public async Task CallCredentialsWithHttp_NoMetadataOnRequest()
        {
            // Arrange
            bool?hasAuthorizationValue = null;
            var  httpClient            = ClientTestHelpers.CreateTestClient(async request =>
            {
                hasAuthorizationValue = request.Headers.TryGetValues("authorization", out _);

                var reply = new HelloReply {
                    Message = "Hello world"
                };
                var streamContent = await ClientTestHelpers.CreateResponseContent(reply).DefaultTimeout();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            }, new Uri("http://localhost"));

            var testSink      = new TestSink();
            var loggerFactory = new TestLoggerFactory(testSink, true);

            var invoker = HttpClientCallInvokerFactory.Create(httpClient, loggerFactory);

            // Act
            var callCredentials = CallCredentials.FromInterceptor((context, metadata) =>
            {
                metadata.Add("authorization", "SECRET_TOKEN");
                return(Task.CompletedTask);
            });
            var call = invoker.AsyncUnaryCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(credentials: callCredentials), new HelloRequest());
            await call.ResponseAsync.DefaultTimeout();

            // Assert
            Assert.AreEqual(false, hasAuthorizationValue);

            var log = testSink.Writes.Single(w => w.EventId.Name == "CallCredentialsNotUsed");

            Assert.AreEqual("The configured CallCredentials were not used because the call does not use TLS.", log.State.ToString());
        }
示例#22
0
 public IHttpActionResult CreateFile([FromBody] PythonFileDM file)
 {
     RC.PythonFileManager.Commit(CommitTypeEnum.ADD, file);
     return(ResponseUtils.CreateResponse(HttpStatusCode.OK, file));
 }
示例#23
0
 public IHttpActionResult UpdateFile([FromBody] PythonFileDM file, [FromUri] int id)
 {
     RC.PythonFileManager.Commit(CommitTypeEnum.UPDATE, file, id: id);
     return(ResponseUtils.CreateResponse(HttpStatusCode.OK, file));
 }
示例#24
0
        public IHttpActionResult GetFile([FromUri] int id)
        {
            var result = RC.PythonFileManager.Pull((item) => item.ID == id);

            return(ResponseUtils.CreateResponse(HttpStatusCode.OK, result));
        }
示例#25
0
        public IHttpActionResult GetFiles()
        {
            var results = RC.PythonFileManager.PullAll();

            return(ResponseUtils.CreateResponse(HttpStatusCode.OK, results));
        }
示例#26
0
        public async Task AsyncDuplexStreamingCall_MessagesStreamed_MessagesReceived()
        {
            // Arrange
            var streamContent = new SyncPointMemoryStream();

            PushStreamContent <HelloRequest, HelloReply>?content = null;

            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                content = (PushStreamContent <HelloRequest, HelloReply>)request.Content !;
                await content.PushComplete.DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, new StreamContent(streamContent)));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var call = invoker.AsyncDuplexStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions());

            var requestStream  = call.RequestStream;
            var responseStream = call.ResponseStream;

            // Assert
            await call.RequestStream.WriteAsync(new HelloRequest { Name = "1" }).DefaultTimeout();

            await call.RequestStream.WriteAsync(new HelloRequest { Name = "2" }).DefaultTimeout();

            await call.RequestStream.CompleteAsync().DefaultTimeout();

            var deserializationContext = new DefaultDeserializationContext();

            Assert.IsNotNull(content);
            var requestContent = await content !.ReadAsStreamAsync().DefaultTimeout();
            var requestMessage = await requestContent.ReadMessageAsync(
                deserializationContext,
                NullLogger.Instance,
                ClientTestHelpers.ServiceMethod.RequestMarshaller.ContextualDeserializer,
                GrpcProtocolConstants.IdentityGrpcEncoding,
                maximumMessageSize : null,
                GrpcProtocolConstants.DefaultCompressionProviders,
                singleMessage : false,
                CancellationToken.None).AsTask().DefaultTimeout();

            Assert.AreEqual("1", requestMessage !.Name);
            requestMessage = await requestContent.ReadMessageAsync(
                deserializationContext,
                NullLogger.Instance,
                ClientTestHelpers.ServiceMethod.RequestMarshaller.ContextualDeserializer,
                GrpcProtocolConstants.IdentityGrpcEncoding,
                maximumMessageSize : null,
                GrpcProtocolConstants.DefaultCompressionProviders,
                singleMessage : false,
                CancellationToken.None).AsTask().DefaultTimeout();

            Assert.AreEqual("2", requestMessage !.Name);

            Assert.IsNull(responseStream.Current);

            var moveNextTask1 = responseStream.MoveNext(CancellationToken.None);

            Assert.IsFalse(moveNextTask1.IsCompleted);

            await streamContent.AddDataAndWait(await ClientTestHelpers.GetResponseDataAsync(new HelloReply
            {
                Message = "Hello world 1"
            }).DefaultTimeout()).DefaultTimeout();

            Assert.IsTrue(await moveNextTask1.DefaultTimeout());
            Assert.IsNotNull(responseStream.Current);
            Assert.AreEqual("Hello world 1", responseStream.Current.Message);

            var moveNextTask2 = responseStream.MoveNext(CancellationToken.None);

            Assert.IsFalse(moveNextTask2.IsCompleted);

            await streamContent.AddDataAndWait(await ClientTestHelpers.GetResponseDataAsync(new HelloReply
            {
                Message = "Hello world 2"
            }).DefaultTimeout()).DefaultTimeout();

            Assert.IsTrue(await moveNextTask2.DefaultTimeout());
            Assert.IsNotNull(responseStream.Current);
            Assert.AreEqual("Hello world 2", responseStream.Current.Message);

            var moveNextTask3 = responseStream.MoveNext(CancellationToken.None);

            Assert.IsFalse(moveNextTask3.IsCompleted);

            await streamContent.AddDataAndWait(Array.Empty <byte>()).DefaultTimeout();

            Assert.IsFalse(await moveNextTask3.DefaultTimeout());

            var moveNextTask4 = responseStream.MoveNext(CancellationToken.None);

            Assert.IsTrue(moveNextTask4.IsCompleted);
            Assert.IsFalse(await moveNextTask3.DefaultTimeout());
        }
示例#27
0
        public async Task AsyncClientStreamingCall_Success_RequestContentSent()
        {
            // Arrange
            PushStreamContent <HelloRequest, HelloReply>?content = null;

            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                content = (PushStreamContent <HelloRequest, HelloReply>)request.Content !;
                await content.PushComplete.DefaultTimeout();

                HelloReply reply = new HelloReply
                {
                    Message = "Hello world"
                };

                var streamContent = await ClientTestHelpers.CreateResponseContent(reply).DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var call = invoker.AsyncClientStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions());

            // Assert
            Assert.IsNotNull(call);
            Assert.IsNotNull(content);

            var responseTask = call.ResponseAsync;

            Assert.IsFalse(responseTask.IsCompleted, "Response not returned until client stream is complete.");

            var streamTask = content !.ReadAsStreamAsync().DefaultTimeout();

            await call.RequestStream.WriteAsync(new HelloRequest { Name = "1" }).DefaultTimeout();

            await call.RequestStream.WriteAsync(new HelloRequest { Name = "2" }).DefaultTimeout();

            await call.RequestStream.CompleteAsync().DefaultTimeout();

            var requestContent = await streamTask.DefaultTimeout();

            var requestMessage = await requestContent.ReadMessageAsync(
                NullLogger.Instance,
                ClientTestHelpers.ServiceMethod.RequestMarshaller.ContextualDeserializer,
                GrpcProtocolConstants.IdentityGrpcEncoding,
                maximumMessageSize : null,
                GrpcProtocolConstants.DefaultCompressionProviders,
                singleMessage : false,
                CancellationToken.None).AsTask().DefaultTimeout();

            Assert.AreEqual("1", requestMessage !.Name);
            requestMessage = await requestContent.ReadMessageAsync(
                NullLogger.Instance,
                ClientTestHelpers.ServiceMethod.RequestMarshaller.ContextualDeserializer,
                GrpcProtocolConstants.IdentityGrpcEncoding,
                maximumMessageSize : null,
                GrpcProtocolConstants.DefaultCompressionProviders,
                singleMessage : false,
                CancellationToken.None).AsTask().DefaultTimeout();

            Assert.AreEqual("2", requestMessage !.Name);

            var responseMessage = await responseTask.DefaultTimeout();

            Assert.AreEqual("Hello world", responseMessage.Message);
        }
    public async Task LongPollingTransportSendsAvailableMessagesWhenTheyArrive()
    {
        var sentRequests = new List <byte[]>();
        var tcs          = new TaskCompletionSource <HttpResponseMessage>();
        var firstPoll    = true;

        var mockHttpHandler = new Mock <HttpMessageHandler>();

        mockHttpHandler.Protected()
        .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
        .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) =>
        {
            await Task.Yield();
            if (request.Method == HttpMethod.Post)
            {
                // Build a new request object, but convert the entire payload to string
                sentRequests.Add(await request.Content.ReadAsByteArrayAsync());
            }
            else if (request.Method == HttpMethod.Get)
            {
                // First poll completes immediately
                if (firstPoll)
                {
                    firstPoll = false;
                    return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
                }

                cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken));
                // This is the poll task
                return(await tcs.Task);
            }
            else if (request.Method == HttpMethod.Delete)
            {
                return(ResponseUtils.CreateResponse(HttpStatusCode.Accepted));
            }
            return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
        });

        using (var httpClient = new HttpClient(mockHttpHandler.Object))
        {
            var longPollingTransport = new LongPollingTransport(httpClient);

            try
            {
                // Start the transport
                await longPollingTransport.StartAsync(TestUri, TransferFormat.Binary);

                longPollingTransport.Output.Write(Encoding.UTF8.GetBytes("Hello"));
                longPollingTransport.Output.Write(Encoding.UTF8.GetBytes("World"));
                await longPollingTransport.Output.FlushAsync();

                longPollingTransport.Output.Complete();

                await longPollingTransport.Running.DefaultTimeout();

                await longPollingTransport.Input.ReadAllAsync();

                Assert.Single(sentRequests);
                Assert.Equal(new[] { (byte)'H', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)'W', (byte)'o', (byte)'r', (byte)'l', (byte)'d' }, sentRequests[0]);
            }
            finally
            {
                await longPollingTransport.StopAsync();
            }
        }
    }
示例#29
0
        public async Task AsyncUnaryCall_CompressMetadataSentWithRequest_RequestMessageCompressed(bool compressionDisabledOnOptions)
        {
            // Arrange
            HttpRequestMessage?httpRequestMessage = null;
            HelloRequest?      helloRequest       = null;
            bool?isRequestNotCompressed           = null;

            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                httpRequestMessage = request;

                var requestData        = await request.Content.ReadAsByteArrayAsync();
                isRequestNotCompressed = requestData[0] == 0;

                helloRequest = await StreamExtensions.ReadSingleMessageAsync(
                    new MemoryStream(requestData),
                    NullLogger.Instance,
                    ClientTestHelpers.ServiceMethod.RequestMarshaller.ContextualDeserializer,
                    "gzip",
                    maximumMessageSize: null,
                    GrpcProtocolConstants.DefaultCompressionProviders,
                    CancellationToken.None);

                HelloReply reply = new HelloReply
                {
                    Message = "Hello world"
                };

                var streamContent = await ClientTestHelpers.CreateResponseContent(reply).DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });

            var compressionProviders = GrpcProtocolConstants.DefaultCompressionProviders.Values.ToList();

            compressionProviders.Add(new TestCompressionProvider());

            var invoker = HttpClientCallInvokerFactory.Create(httpClient, configure: o => o.CompressionProviders = compressionProviders);

            var compressionMetadata = CreateClientCompressionMetadata("gzip");
            var callOptions         = new CallOptions(headers: compressionMetadata);

            if (compressionDisabledOnOptions)
            {
                callOptions = callOptions.WithWriteOptions(new WriteOptions(WriteFlags.NoCompress));
            }

            // Act
            var call = invoker.AsyncUnaryCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, callOptions, new HelloRequest
            {
                Name = "Hello"
            });

            // Assert
            var response = await call.ResponseAsync;

            Assert.IsNotNull(response);
            Assert.AreEqual("Hello world", response.Message);

            Debug.Assert(httpRequestMessage != null);
            Assert.AreEqual("identity,gzip,deflate,test", httpRequestMessage.Headers.GetValues(GrpcProtocolConstants.MessageAcceptEncodingHeader).Single());
            Assert.AreEqual("gzip", httpRequestMessage.Headers.GetValues(GrpcProtocolConstants.MessageEncodingHeader).Single());
            Assert.AreEqual(false, httpRequestMessage.Headers.Contains(GrpcProtocolConstants.CompressionRequestAlgorithmHeader));

            Debug.Assert(helloRequest != null);
            Assert.AreEqual("Hello", helloRequest.Name);

            Assert.AreEqual(compressionDisabledOnOptions, isRequestNotCompressed);
        }
        public async Task PickAsync_HedgingWithDrop_ThrowsError()
        {
            // Arrange
            string?authority          = null;
            var    testMessageHandler = TestHttpMessageHandler.Create(async request =>
            {
                authority = request.RequestUri !.Authority;
                var reply = new HelloReply {
                    Message = "Hello world"
                };

                var streamContent = await ClientTestHelpers.CreateResponseContent(reply).DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });

            var services = new ServiceCollection();

            services.AddNUnitLogger();
            services.AddSingleton <TestResolver>();
            services.AddSingleton <ResolverFactory, TestResolverFactory>();
            DropLoadBalancer?loadBalancer = null;

            services.AddSingleton <LoadBalancerFactory>(new DropLoadBalancerFactory(c =>
            {
                loadBalancer = new DropLoadBalancer(c);
                return(loadBalancer);
            }));
            services.AddSingleton <ISubchannelTransportFactory>(new TestSubchannelTransportFactory());

            var invoker = HttpClientCallInvokerFactory.Create(testMessageHandler, "test:///localhost", configure: o =>
            {
                o.Credentials     = ChannelCredentials.Insecure;
                o.ServiceProvider = services.BuildServiceProvider();
                o.ServiceConfig   = new ServiceConfig
                {
                    MethodConfigs =
                    {
                        new MethodConfig
                        {
                            Names         = { MethodName.Default     },
                            HedgingPolicy = new HedgingPolicy
                            {
                                MaxAttempts         = 5,
                                HedgingDelay        = TimeSpan.FromMinutes(10),
                                NonFatalStatusCodes ={ StatusCode.DataLoss                    }
                            }
                        }
                    },
                    LoadBalancingConfigs = { new LoadBalancingConfig("drop") }
                };
            });

            // Act
            var call = invoker.AsyncUnaryCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions().WithWaitForReady(), new HelloRequest());

            // Assert
            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => call.ResponseAsync).DefaultTimeout();

            Assert.AreEqual(StatusCode.DataLoss, ex.StatusCode);

            Assert.AreEqual(1, loadBalancer !.PickCount);
        }