public void GetService_DisposeOnSameThread_ThrowsAndDoesNotHangAndDisposeGetsCalled()
        {
            // Arrange
            var services           = new ServiceCollection();
            var disposableResource = new Disposable();

            services.AddSingleton <DisposeServiceProviderInCtorDisposable>(sp =>
                                                                           new DisposeServiceProviderInCtorDisposable(disposableResource, sp));

            var  sp          = services.BuildServiceProvider();
            bool doesNotHang = Task.Run(() =>
            {
                SingleThreadedSynchronizationContext.Run(() =>
                {
                    // Act
                    Assert.Throws <ObjectDisposedException>(() =>
                    {
                        // ctor disposes ServiceProvider
                        var service = sp.GetRequiredService <DisposeServiceProviderInCtorDisposable>();
                    });
                });
            }).Wait(TimeSpan.FromSeconds(10));

            Assert.True(doesNotHang);
            Assert.True(disposableResource.Disposed);
        }
Пример #2
0
        private bool GetAuthorizationLevelAsync_CalledWithSingleThreadedContext_DoesNotDeadlock(ISecretManager secretManager)
        {
            var resetEvent = new ManualResetEvent(false);

            var thread = new Thread(() =>
            {
                HttpRequestMessage request = new HttpRequestMessage();
                request = new HttpRequestMessage();
                request.Headers.Add(AuthorizationLevelAttribute.FunctionsKeyHeaderName, TestFunctionKeyValue1);

                var context = new SingleThreadedSynchronizationContext(true);
                SynchronizationContext.SetSynchronizationContext(context);

                AuthorizationLevelAttribute.GetAuthorizationLevelAsync(request, secretManager, functionName: "TestFunction")
                .ContinueWith(t =>
                {
                    context.Stop();

                    resetEvent.Set();
                });

                context.Run();
            });

            thread.IsBackground = true;
            thread.Start();

            bool eventSignaled = resetEvent.WaitOne(TimeSpan.FromSeconds(5));

            thread.Abort();

            return(eventSignaled);
        }
        public void SendAsync_WorksInSingleThreadedSyncContext()
        {
            // Arrange
            var policy  = Policy.TimeoutAsync <HttpResponseMessage>(TimeSpan.FromSeconds(10));
            var handler = new TestPolicyHttpMessageHandler(policy);

            handler.OnSendAsync = async(req, c, ct) =>
            {
                await Task.Delay(1).ConfigureAwait(false);

                return(null);
            };

            var hangs = true;

            // Act
            using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3)))
            {
                var token = cts.Token;
                token.Register(() => throw new OperationCanceledException(token));

                SingleThreadedSynchronizationContext.Run(() =>
                {
                    // Act
                    var request = new HttpRequestMessage();
                    handler.SendAsync(request, CancellationToken.None).GetAwaiter().GetResult();
                    hangs = false;
                });
            }

            // Assert
            Assert.False(hangs);
        }
Пример #4
0
        public void CheckHealthAsync_WorksInSingleThreadedSyncContext()
        {
            // Arrange
            var service = CreateHealthChecksService(b =>
            {
                b.AddAsyncCheck("test", async() =>
                {
                    await Task.Delay(1).ConfigureAwait(false);
                    return(HealthCheckResult.Healthy());
                });
            });

            var hangs = true;

            // Act
            using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3)))
            {
                var token = cts.Token;
                token.Register(() => throw new OperationCanceledException(token));

                SingleThreadedSynchronizationContext.Run(() =>
                {
                    // Act
                    service.CheckHealthAsync(token).GetAwaiter().GetResult();
                    hangs = false;
                });
            }

            // Assert
            Assert.False(hangs);
        }
        public void AddHttpClient_GetAwaiterAndResult_InSingleThreadedSynchronizationContext_ShouldNotHangs()
        {
            // Arrange
            using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)))
            {
                var token = cts.Token;
                token.Register(() => throw new OperationCanceledException(token));
                var serviceCollection = new ServiceCollection();
                serviceCollection.AddHttpClient("example.com")
                .ConfigurePrimaryHttpMessageHandler(() =>
                {
                    var mockHandler = new Mock <HttpMessageHandler>();
                    mockHandler
                    .Protected()
                    .Setup <Task <HttpResponseMessage> >(
                        "SendAsync",
                        ItExpr.IsAny <HttpRequestMessage>(),
                        ItExpr.IsAny <CancellationToken>()
                        )
                    .Returns(async() =>
                    {
                        await Task.Delay(1).ConfigureAwait(false);
                        return(new HttpResponseMessage(HttpStatusCode.OK));
                    });
                    return(mockHandler.Object);
                });

                var services = serviceCollection.BuildServiceProvider();
                var factory  = services.GetRequiredService <IHttpClientFactory>();
                var client   = factory.CreateClient("example.com");
                var hangs    = true;
                SingleThreadedSynchronizationContext.Run(() =>
                {
                    // Act
                    client.GetAsync("http://example.com", token).GetAwaiter().GetResult();
                    hangs = false;
                });

                // Assert
                Assert.False(hangs);
            }
        }
        internal async Task GeneratedMethods_WithOutParams_DoNotCauseDeadlocks(string fixture)
        {
            var traceWriter = new TestTraceWriter(TraceLevel.Verbose);

            ScriptHostConfiguration config = new ScriptHostConfiguration()
            {
                RootScriptPath = @"TestScripts\FunctionGeneration",
                TraceWriter    = traceWriter
            };

            string             secretsPath     = Path.Combine(Path.GetTempPath(), @"FunctionTests\Secrets");
            ISecretsRepository repository      = new FileSystemSecretsRepository(secretsPath);
            WebHostSettings    webHostSettings = new WebHostSettings();

            webHostSettings.SecretsPath = secretsPath;

            var secretManager = new SecretManager(SettingsManager, repository, NullTraceWriter.Instance);

            using (var manager = new WebScriptHostManager(config, new TestSecretManagerFactory(secretManager), SettingsManager, webHostSettings))
            {
                Thread runLoopThread = new Thread(_ =>
                {
                    manager.RunAndBlock(CancellationToken.None);
                });
                runLoopThread.IsBackground = true;
                runLoopThread.Start();

                await TestHelpers.Await(() =>
                {
                    return(manager.State == ScriptHostState.Running);
                });

                var request = new HttpRequestMessage(HttpMethod.Get, string.Format("http://localhost/api/httptrigger-{0}", fixture));
                FunctionDescriptor function = manager.GetHttpFunctionOrNull(request);

                SynchronizationContext currentContext = SynchronizationContext.Current;
                var resetEvent = new ManualResetEventSlim();

                try
                {
                    var requestThread = new Thread(() =>
                    {
                        var context = new SingleThreadedSynchronizationContext();
                        SynchronizationContext.SetSynchronizationContext(context);

                        manager.HandleRequestAsync(function, request, CancellationToken.None)
                        .ContinueWith(task => resetEvent.Set());

                        Thread.Sleep(500);
                        context.Run();
                    });

                    requestThread.IsBackground = true;
                    requestThread.Start();

                    bool threadSignaled = resetEvent.Wait(TimeSpan.FromSeconds(10));

                    requestThread.Abort();

                    Assert.True(threadSignaled, "Thread execution did not complete");
                }
                finally
                {
                    SynchronizationContext.SetSynchronizationContext(currentContext);
                    manager.Stop();
                }
            }
        }