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); }
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); }
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(); } } }