Skip to content

Commit f60d3ad

Browse files
authored
fix flaky test; improving test logging (#6874)
1 parent b58316c commit f60d3ad

File tree

6 files changed

+151
-96
lines changed

6 files changed

+151
-96
lines changed

test/WebJobs.Script.Tests.Integration/ApplicationInsights/ApplicationInsightsEndToEndTestsBase.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
using Microsoft.ApplicationInsights.Extensibility.Implementation;
1414
using Microsoft.Azure.WebJobs.Host;
1515
using Microsoft.Azure.WebJobs.Logging;
16-
using Microsoft.Azure.WebJobs.Script.Diagnostics;
17-
using Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics;
1816
using Microsoft.Extensions.Configuration;
1917
using Microsoft.Extensions.DependencyInjection;
2018
using Microsoft.Extensions.Hosting;
@@ -235,7 +233,7 @@ private void ValidateException(ExceptionTelemetry telemetry, string expectedInvo
235233
ValidateTelemetry(telemetry, expectedInvocationId, expectedOperationName, expectedCategory, SeverityLevel.Error);
236234
}
237235

238-
[Fact(Skip = "Disabled due to https://github.com/Azure/azure-functions-host/issues/6521")]
236+
[Fact]
239237
public async Task Validate_HostLogs()
240238
{
241239
// Validate the host startup traces. Order by message string as the requests may come in

test/WebJobs.Script.Tests.Integration/ApplicationInsights/ApplicationInsightsTestFixture.cs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,5 @@ public void Dispose()
7878
// everything is flushed and can't affect subsequent tests.
7979
Thread.Sleep(2000);
8080
}
81-
82-
private class ScriptHostBuilder : IConfigureBuilder<IWebJobsBuilder>
83-
{
84-
public void Configure(IWebJobsBuilder builder)
85-
{
86-
builder.Services.Configure<ScriptJobHostOptions>(o =>
87-
{
88-
o.Functions = new[] { "Scenarios", "HttpTrigger-Scenarios" };
89-
});
90-
}
91-
}
9281
}
9382
}

test/WebJobs.Script.Tests.Integration/Host/WebJobsScriptHostServiceTests.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ public async Task Restarts_CanCancel_Restarts()
288288
_testHost.Dispose();
289289
int buildCalls = 0;
290290

291-
var testHost = new TestFunctionHost(TestScriptPath, TestLogPath,
291+
using (var testHost = new TestFunctionHost(TestScriptPath, TestLogPath,
292292
configureWebHostServices: services =>
293293
{
294294
services.Configure<LoggerFilterOptions>(o =>
@@ -336,17 +336,18 @@ IHost Intercept(IScriptHostBuilder builder, bool skipHostStartup, bool skipHostC
336336

337337
return new InterceptingScriptHostBuilder(appHostOptions, s, rootServiceScopeFactory, Intercept);
338338
});
339-
});
340-
341-
var scriptHostService = testHost.WebHostServices.GetService<IScriptHostManager>() as WebJobsScriptHostService;
339+
}))
340+
{
341+
var scriptHostService = testHost.WebHostServices.GetService<IScriptHostManager>() as WebJobsScriptHostService;
342342

343-
List<Task> restarts = new List<Task>();
344-
restarts.Add(testHost.RestartAsync(CancellationToken.None));
345-
restarts.Add(testHost.RestartAsync(CancellationToken.None));
343+
List<Task> restarts = new List<Task>();
344+
restarts.Add(testHost.RestartAsync(CancellationToken.None));
345+
restarts.Add(testHost.RestartAsync(CancellationToken.None));
346346

347-
await Task.WhenAll(restarts);
347+
await Task.WhenAll(restarts);
348348

349-
await TestHelpers.Await(() => scriptHostService.State == ScriptHostState.Running, userMessageCallback: testHost.GetLog);
349+
await TestHelpers.Await(() => scriptHostService.State == ScriptHostState.Running, userMessageCallback: testHost.GetLog);
350+
}
350351
}
351352

352353
public void Dispose()

test/WebJobs.Script.Tests.Integration/ScriptHostEndToEnd/ScriptHostEndToEndTestFixture.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ public virtual async Task DisposeAsync()
249249
await JobHost.StopAsync();
250250
await Host.StopAsync();
251251
JobHost.Dispose();
252+
Host.Dispose();
252253
}
253254
Environment.SetEnvironmentVariable(RpcWorkerConstants.FunctionWorkerRuntimeSettingName, string.Empty);
254255
}

test/WebJobs.Script.Tests.Integration/TestFunctionHost.cs

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Diagnostics;
67
using System.IO;
78
using System.Linq;
89
using System.Net.Http;
@@ -13,6 +14,7 @@
1314
using Microsoft.AspNetCore.Builder;
1415
using Microsoft.AspNetCore.Hosting;
1516
using Microsoft.AspNetCore.TestHost;
17+
using Microsoft.Azure.WebJobs.Host.Executors;
1618
using Microsoft.Azure.WebJobs.Script.ExtensionBundle;
1719
using Microsoft.Azure.WebJobs.Script.Models;
1820
using Microsoft.Azure.WebJobs.Script.WebHost;
@@ -43,6 +45,13 @@ public class TestFunctionHost : IDisposable
4345
private readonly TestLoggerProvider _scriptHostLoggerProvider = new TestLoggerProvider();
4446
private readonly WebJobsScriptHostService _hostService;
4547

48+
private readonly Timer _stillRunningTimer;
49+
private readonly DateTimeOffset _created = DateTimeOffset.UtcNow;
50+
private readonly string _createdStack;
51+
private readonly string _id = Guid.NewGuid().ToString();
52+
private bool _timerFired = false;
53+
private bool _isDisposed = false;
54+
4655
public TestFunctionHost(string scriptPath,
4756
Action<IServiceCollection> configureWebHostServices = null,
4857
Action<IWebJobsBuilder> configureScriptHostWebJobsBuilder = null,
@@ -139,6 +148,12 @@ public TestFunctionHost(string scriptPath, string logPath,
139148
lifetime.ApplicationStopping.Register(async () => await _testServer.Host.StopAsync());
140149

141150
StartAsync().GetAwaiter().GetResult();
151+
152+
_stillRunningTimer = new Timer(StillRunningCallback, _testServer, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30));
153+
154+
// store off a bit of the creation stack for easier debugging if this host doesn't shut down.
155+
var stack = new StackTrace(true).ToString().Split(Environment.NewLine).Take(5);
156+
_createdStack = string.Join($"{Environment.NewLine} ", stack);
142157
}
143158

144159
public IServiceProvider JobHostServices => _hostService.Services;
@@ -172,6 +187,39 @@ public async Task RestartAsync(CancellationToken cancellationToken)
172187
await _hostService.RestartHostAsync(cancellationToken);
173188
}
174189

190+
private void StillRunningCallback(object state)
191+
{
192+
var idProvider = JobHostServices?.GetService<IHostIdProvider>();
193+
var jobOptions = JobHostServices?.GetService<IOptions<ScriptJobHostOptions>>();
194+
195+
if (idProvider == null || jobOptions == null)
196+
{
197+
return;
198+
}
199+
200+
var functions = jobOptions?.Value.Functions ?? new[] { "" };
201+
202+
string allowList = $"[{string.Join(", ", functions)}]";
203+
string hostId = idProvider.GetHostIdAsync(CancellationToken.None).Result;
204+
205+
var ago = (int)(DateTime.UtcNow - _created).TotalSeconds;
206+
207+
// This helps debugging tests that may not be disposing their hosts.
208+
StringBuilder sb = new StringBuilder();
209+
210+
sb.AppendLine($"A host created at '{_created:yyyy-MM-dd HH:mm:ss}' ({ago}s ago) is still running. Details:");
211+
sb.AppendLine($" Host id: {hostId}");
212+
sb.AppendLine($" Test host id: {_id}");
213+
sb.AppendLine($" ScriptRoot: {jobOptions.Value.RootScriptPath}");
214+
sb.AppendLine($" Allow list: {allowList}");
215+
sb.AppendLine($" The captured stack from this test host's constructor:");
216+
sb.AppendLine(_createdStack);
217+
218+
Console.Write(sb.ToString());
219+
220+
_timerFired = true;
221+
}
222+
175223
private Task StartAsync()
176224
{
177225
bool exit = false;
@@ -286,8 +334,21 @@ public async Task<HostStatus> GetHostStatusAsync()
286334

287335
public void Dispose()
288336
{
289-
HttpClient.Dispose();
290-
_testServer.Dispose();
337+
if (!_isDisposed)
338+
{
339+
HttpClient.Dispose();
340+
_testServer.Dispose();
341+
342+
_stillRunningTimer?.Change(-1, -1);
343+
_stillRunningTimer?.Dispose();
344+
345+
if (_timerFired)
346+
{
347+
Console.WriteLine($"The test host with id {_id} is now disposed.");
348+
}
349+
350+
_isDisposed = true;
351+
}
291352
}
292353

293354
private async Task<bool> IsHostStarted()

0 commit comments

Comments
 (0)