public async Task Deadline_HandleCallAsyncWaitsForDeadlineToFinish()
        {
            // Arrange
            Task?handleCallTask = null;
            bool?isHandleCallTaskCompleteDuringDeadline = null;
            var  httpContext = HttpContextHelpers.CreateContext(completeAsyncAction: async() =>
            {
                await Task.Delay(200);
                isHandleCallTaskCompleteDuringDeadline = handleCallTask?.IsCompleted;
            });

            httpContext.Request.Headers[GrpcProtocolConstants.TimeoutHeader] = "50m";
            var call = CreateHandler(MethodType.ClientStreaming, handlerAction: () => Task.Delay(100));

            // Act
            handleCallTask = call.HandleCallAsync(httpContext).DefaultTimeout();
            await handleCallTask;

            // Assert
            var serverCallContext = httpContext.Features.Get <IServerCallContextFeature>() !;

            Assert.AreEqual(StatusCode.DeadlineExceeded, serverCallContext.ServerCallContext.Status.StatusCode);

            Assert.IsFalse(isHandleCallTaskCompleteDuringDeadline);
        }
Exemple #2
0
        public async Task Invoke_ThrowExceptionAwaitedRelease_ReleaseCalledAndErrorThrown()
        {
            // Arrange
            var releaseTcs       = new TaskCompletionSource <object?>(TaskCreationOptions.RunContinuationsAsynchronously);
            var serviceActivator = new TcsGrpcServiceActivator <TestService>(releaseTcs);
            var thrownException  = new Exception("Exception!");
            var invoker          = new UnaryServerMethodInvoker <TestService, TestMessage, TestMessage>(
                (service, reader, context) => throw thrownException,
                new Method <TestMessage, TestMessage>(MethodType.Unary, "test", "test", _marshaller, _marshaller),
                HttpContextServerCallContextHelper.CreateMethodOptions(),
                serviceActivator);
            var httpContext = HttpContextHelpers.CreateContext();

            // Act
            var task = invoker.Invoke(httpContext, HttpContextServerCallContextHelper.CreateServerCallContext(), new TestMessage());

            Assert.False(task.IsCompleted);

            releaseTcs.SetResult(null);

            try
            {
                await task;
                Assert.Fail();
            }
            catch (Exception ex)
            {
                // Assert
                Assert.True(serviceActivator.Released);
                Assert.AreEqual(thrownException, ex);
            }
        }
Exemple #3
0
        public async Task Invoke_AwaitedSuccess_ReleaseCalled()
        {
            // Arrange
            var methodTcs        = new TaskCompletionSource <TestMessage>(TaskCreationOptions.RunContinuationsAsynchronously);
            var methodResult     = new TestMessage();
            var serviceActivator = new TestGrpcServiceActivator <TestService>();
            var invoker          = new UnaryServerMethodInvoker <TestService, TestMessage, TestMessage>(
                (service, reader, context) => methodTcs.Task,
                new Method <TestMessage, TestMessage>(MethodType.Unary, "test", "test", _marshaller, _marshaller),
                HttpContextServerCallContextHelper.CreateMethodOptions(),
                serviceActivator);
            var httpContext = HttpContextHelpers.CreateContext();

            // Act
            var task = invoker.Invoke(httpContext, HttpContextServerCallContextHelper.CreateServerCallContext(), new TestMessage());

            Assert.False(task.IsCompleted);

            methodTcs.SetResult(methodResult);
            var awaitedResult = await task;

            // Assert
            Assert.AreEqual(methodResult, awaitedResult);
            Assert.True(serviceActivator.Released);
        }
Exemple #4
0
        public async Task MaxRequestBodySizeFeature_MethodType_HasMaxRequestBodySize(MethodType methodType, bool hasMaxRequestBodySize)
        {
            // Arrange
            var httpContext = HttpContextHelpers.CreateContext();
            var call        = CreateHandler(methodType);

            // Act
            await call.HandleCallAsync(httpContext).DefaultTimeout();

            // Assert
            Assert.AreEqual(hasMaxRequestBodySize, httpContext.Features.Get <IHttpMaxRequestBodySizeFeature>().MaxRequestBodySize != null);
        }
Exemple #5
0
        public async Task SetResponseTrailers_FeatureMissing_ThrowError()
        {
            // Arrange
            var testSink          = new TestSink();
            var testLoggerFactory = new TestLoggerFactory(testSink, true);

            var httpContext = HttpContextHelpers.CreateContext(skipTrailerFeatureSet: true);
            var call        = CreateHandler(MethodType.ClientStreaming, testLoggerFactory);

            // Act
            var ex = await ExceptionAssert.ThrowsAsync <InvalidOperationException>(() => call.HandleCallAsync(httpContext)).DefaultTimeout();

            // Assert
            Assert.AreEqual("Trailers are not supported for this response. The server may not support gRPC.", ex.Message);
        }
Exemple #6
0
        public async Task StatusDebugException_ErrorInHandler_SetInDebugException()
        {
            // Arrange
            var ex          = new Exception("Test exception");
            var httpContext = HttpContextHelpers.CreateContext();
            var call        = CreateHandler(MethodType.ClientStreaming, handlerAction: () => throw ex);

            // Act
            await call.HandleCallAsync(httpContext).DefaultTimeout();

            // Assert
            var serverCallContext = httpContext.Features.Get <IServerCallContextFeature>();

            Assert.AreEqual(ex, serverCallContext.ServerCallContext.Status.DebugException);
        }
Exemple #7
0
        public async Task MaxRequestBodySizeFeature_FeatureIsReadOnly_FailureLogged()
        {
            // Arrange
            var testSink          = new TestSink();
            var testLoggerFactory = new TestLoggerFactory(testSink, true);

            var httpContext = HttpContextHelpers.CreateContext(isMaxRequestBodySizeFeatureReadOnly: true);
            var call        = CreateHandler(MethodType.ClientStreaming, testLoggerFactory);

            // Act
            await call.HandleCallAsync(httpContext).DefaultTimeout();

            // Assert
            Assert.AreEqual(true, httpContext.Features.Get <IHttpMaxRequestBodySizeFeature>().MaxRequestBodySize != null);
            Assert.IsTrue(testSink.Writes.Any(w => w.EventId.Name == "UnableToDisableMaxRequestBodySizeLimit"));
        }
Exemple #8
0
        public async Task ProtocolValidation_IISHttp2Protocol_Success()
        {
            // Arrange
            var testSink          = new TestSink();
            var testLoggerFactory = new TestLoggerFactory(testSink, true);

            var httpContext = HttpContextHelpers.CreateContext(protocol: GrpcProtocolConstants.Http20Protocol);
            var call        = CreateHandler(MethodType.ClientStreaming, testLoggerFactory);

            // Act
            await call.HandleCallAsync(httpContext).DefaultTimeout();

            // Assert
            var log = testSink.Writes.SingleOrDefault(w => w.EventId.Name == "UnsupportedRequestProtocol");

            Assert.IsNull(log);
        }
Exemple #9
0
        public async Task ProtocolValidation_InvalidProtocol_FailureLogged()
        {
            // Arrange
            var testSink          = new TestSink();
            var testLoggerFactory = new TestLoggerFactory(testSink, true);

            var httpContext = HttpContextHelpers.CreateContext(protocol: "HTTP/1.1");
            var call        = CreateHandler(MethodType.ClientStreaming, testLoggerFactory);

            // Act
            await call.HandleCallAsync(httpContext).DefaultTimeout();

            // Assert
            var log = testSink.Writes.SingleOrDefault(w => w.EventId.Name == "UnsupportedRequestProtocol");

            Assert.IsNotNull(log);
            Assert.AreEqual("Request protocol of 'HTTP/1.1' is not supported.", log.Message);
        }
Exemple #10
0
        public async Task ContentTypeValidation_InvalidContentType_FailureLogged()
        {
            // Arrange
            var testSink          = new TestSink();
            var testLoggerFactory = new TestLoggerFactory(testSink, true);

            var httpContext = HttpContextHelpers.CreateContext(contentType: "text/plain");
            var call        = CreateHandler(MethodType.ClientStreaming, testLoggerFactory);

            // Act
            await call.HandleCallAsync(httpContext).DefaultTimeout();

            // Assert
            var log = testSink.Writes.SingleOrDefault(w => w.EventId.Name == "UnsupportedRequestContentType");

            Assert.IsNotNull(log);
            Assert.AreEqual("Request content-type of 'text/plain' is not supported.", log.Message);
        }
        public async Task OnServiceMethodDiscovery_ServiceWithDuplicateMethodNames_Success()
        {
            // Arrange
            var services = new ServiceCollection();

            services.AddSingleton <GreeterServiceWithDuplicateNames>();

            var serverCallHandlerFactory = new ServerCallHandlerFactory <GreeterServiceWithDuplicateNames>(
                NullLoggerFactory.Instance,
                Options.Create <GrpcServiceOptions>(new GrpcServiceOptions()),
                Options.Create <GrpcServiceOptions <GreeterServiceWithDuplicateNames> >(new GrpcServiceOptions <GreeterServiceWithDuplicateNames>()),
                new TestGrpcServiceActivator <GreeterServiceWithDuplicateNames>());

            var provider = new BinderServiceMethodProvider <GreeterServiceWithDuplicateNames>(NullLoggerFactory.Instance);
            var context  = new ServiceMethodProviderContext <GreeterServiceWithDuplicateNames>(serverCallHandlerFactory);

            var httpContext = HttpContextHelpers.CreateContext();

            httpContext.RequestServices = services.BuildServiceProvider();

            // Act
            provider.OnServiceMethodDiscovery(context);

            // Assert
            Assert.AreEqual(2, context.Methods.Count);

            var methodModel = context.Methods[0];

            Assert.AreEqual("SayHello", methodModel.Method.Name);

            var ms = new MemoryStream();

            MessageHelpers.WriteMessage(ms, new HelloRequest
            {
                Name = "World"
            });
            ms.Seek(0, SeekOrigin.Begin);
            httpContext.Request.Body = ms;

            await methodModel.RequestDelegate(httpContext);

            // Expect 12 (unimplemented) from base type
            Assert.AreEqual("12", httpContext.Response.Headers["grpc-status"]);
        }
Exemple #12
0
        public void Invoke_ThrowException_ReleaseCalledAndErrorThrown()
        {
            // Arrange
            var serviceActivator = new TestGrpcServiceActivator <TestService>();
            var ex      = new Exception("Exception!");
            var invoker = new UnaryServerMethodInvoker <TestService, TestMessage, TestMessage>(
                (service, reader, context) => throw ex,
                new Method <TestMessage, TestMessage>(MethodType.Unary, "test", "test", _marshaller, _marshaller),
                HttpContextServerCallContextHelper.CreateMethodOptions(),
                serviceActivator);
            var httpContext = HttpContextHelpers.CreateContext();

            // Act
            var task = invoker.Invoke(httpContext, HttpContextServerCallContextHelper.CreateServerCallContext(), new TestMessage());

            // Assert
            Assert.True(serviceActivator.Released);
            Assert.True(task.IsFaulted);
            Assert.AreEqual(ex, task.Exception !.InnerException);
        }
Exemple #13
0
        public async Task Invoke_SuccessAwaitedRelease_ReleaseCalled()
        {
            // Arrange
            var releaseTcs       = new TaskCompletionSource <object?>(TaskCreationOptions.RunContinuationsAsynchronously);
            var serviceActivator = new TcsGrpcServiceActivator <TestService>(releaseTcs);
            var invoker          = new UnaryServerMethodInvoker <TestService, TestMessage, TestMessage>(
                (service, reader, context) => Task.FromResult(new TestMessage()),
                new Method <TestMessage, TestMessage>(MethodType.Unary, "test", "test", _marshaller, _marshaller),
                HttpContextServerCallContextHelper.CreateMethodOptions(),
                serviceActivator);
            var httpContext = HttpContextHelpers.CreateContext();

            // Act
            var task = invoker.Invoke(httpContext, HttpContextServerCallContextHelper.CreateServerCallContext(), new TestMessage());

            Assert.False(task.IsCompleted);

            releaseTcs.SetResult(null);
            await task;

            // Assert
            Assert.True(serviceActivator.Released);
        }