Skip to content

Commit 97be038

Browse files
committed
Address flaky tests
- Prevent extra SBA refresh request after refresh is disabled - Address race condition in thread dump test - Catch network-related SQLServer connection error - Remove retry from eureka server timeout - More buffer for infra around health aggregator parallelization test (allow +1s for +3s work)
1 parent f1f03fd commit 97be038

5 files changed

Lines changed: 33 additions & 17 deletions

File tree

src/Connectors/test/Connectors.Test/RelationalDatabaseHealthContributorTest.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,10 @@ public async Task SQLServer_Not_Connected_Returns_Down_Status()
111111
result.Description.Should().Be("SQL Server health check failed");
112112
result.Details.Should().Contain("host", "localhost");
113113
result.Details.Should().Contain("service", "Example");
114-
result.Details.Should().ContainKey("error").WhoseValue.As<string>().Should().StartWith("SqlException: Connection Timeout Expired.");
114+
115+
result.Details.Should().ContainKey("error").WhoseValue.As<string>().Should().Match(exception =>
116+
exception.StartsWith("SqlException: Connection Timeout Expired.", StringComparison.InvariantCulture) ||
117+
exception.StartsWith("SqlException: A network-related or instance-specific error", StringComparison.InvariantCulture));
115118
}
116119

117120
[Fact(Skip = "Integration test - Requires local SQL Server instance")]

src/Discovery/test/Eureka.Test/EurekaServiceCollectionExtensionsTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public async Task AddEurekaDiscoveryClient_UsesServerTimeout()
6262
var appSettings = new Dictionary<string, string?>
6363
{
6464
["Eureka:Client:EurekaServer:ConnectTimeoutSeconds"] = "1",
65-
["Eureka:Client:EurekaServer:RetryCount"] = "1"
65+
["Eureka:Client:EurekaServer:RetryCount"] = "0"
6666
};
6767

6868
IConfiguration configuration = new ConfigurationBuilder().AddInMemoryCollection(appSettings).Build();

src/Management/src/Endpoint/SpringBootAdminClient/SpringBootAdminPeriodicRefresh.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,20 @@ private async Task TimerLoopAsync(TimeSpan interval)
4444

4545
do
4646
{
47-
LogStartingRefreshCycle();
48-
49-
try
50-
{
51-
await _runner.RunAsync(isFirstTime, _timerTokenSource.Token);
52-
}
53-
catch (Exception exception) when (!exception.IsCancellation())
47+
// A tick queued just before periodic refresh was disabled would still be delivered here.
48+
// Checking the period prevents executing a stale tick when refresh has been turned off.
49+
if (isFirstTime || _periodicTimer.Period != Timeout.InfiniteTimeSpan)
5450
{
55-
LogRefreshCycleFailed(exception);
51+
LogStartingRefreshCycle();
52+
53+
try
54+
{
55+
await _runner.RunAsync(isFirstTime, _timerTokenSource.Token);
56+
}
57+
catch (Exception exception) when (!exception.IsCancellation())
58+
{
59+
LogRefreshCycleFailed(exception);
60+
}
5661
}
5762

5863
isFirstTime = false;

src/Management/test/Endpoint.Test/Actuators/Health/HealthAggregationTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -366,9 +366,9 @@ public async Task Aggregates_contributors_in_parallel()
366366
{
367367
List<IHealthContributor> contributors =
368368
[
369-
new SlowContributor(1.Seconds()),
370369
new SlowContributor(2.Seconds()),
371-
new SlowContributor(3.Seconds())
370+
new SlowContributor(3.Seconds()),
371+
new SlowContributor(4.Seconds())
372372
];
373373

374374
WebApplicationBuilder builder = TestWebApplicationBuilderFactory.Create();
@@ -408,7 +408,7 @@ public async Task Aggregates_contributors_in_parallel()
408408
}
409409
""");
410410

411-
stopwatch.Elapsed.Should().BeGreaterThan(500.Milliseconds()).And.BeLessThan(5.Seconds());
411+
stopwatch.Elapsed.Should().BeGreaterThan(500.Milliseconds()).And.BeLessThan(6.Seconds());
412412
}
413413

414414
[Fact]

src/Management/test/Endpoint.Test/Actuators/ThreadDump/EventPipeThreadDumperTest.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,22 @@ public sealed class EventPipeThreadDumperTest
1616
public async Task Can_resolve_source_location_from_pdb()
1717
{
1818
using var backgroundCancellationSource = new CancellationTokenSource();
19+
using var threadStarted = new ManualResetEventSlim(false);
1920

2021
var backgroundThread = new Thread(NestedType.BackgroundThreadCallback)
2122
{
2223
IsBackground = true
2324
};
2425

25-
backgroundThread.Start(backgroundCancellationSource.Token);
26+
backgroundThread.Start((backgroundCancellationSource.Token, threadStarted));
27+
threadStarted.Wait(TestContext.Current.CancellationToken);
2628

2729
using var loggerProvider = new CapturingLoggerProvider();
2830
using var loggerFactory = new LoggerFactory([loggerProvider]);
2931
ILogger<EventPipeThreadDumper> logger = loggerFactory.CreateLogger<EventPipeThreadDumper>();
3032

31-
var optionsMonitor = new TestOptionsMonitor<ThreadDumpEndpointOptions>();
33+
// Use a longer collection window to provide enough sample opportunities on a loaded CI runner.
34+
var optionsMonitor = TestOptionsMonitor.Create(new ThreadDumpEndpointOptions { Duration = 100 });
3235
var dumper = new EventPipeThreadDumper(optionsMonitor, logger);
3336

3437
IList<ThreadInfo> threads = await dumper.DumpThreadsAsync(TestContext.Current.CancellationToken);
@@ -87,11 +90,16 @@ private static class NestedType
8790
{
8891
public static void BackgroundThreadCallback(object? argument)
8992
{
90-
var cancellationToken = (CancellationToken)argument!;
93+
(CancellationToken cancellationToken, ManualResetEventSlim threadReady) = ((CancellationToken, ManualResetEventSlim))argument!;
94+
95+
threadReady.Set();
9196

9297
while (!cancellationToken.IsCancellationRequested)
9398
{
94-
Thread.Sleep(TimeSpan.FromMilliseconds(50));
99+
// Only actively-running threads are shown in the thread dump, so we need to make sure the CPU is in use.
100+
// Thread.Sleep(0) yields to allow the EventPipe rundown thread to make progress on .NET 8.
101+
Thread.SpinWait(250);
102+
Thread.Sleep(0);
95103
}
96104
}
97105
}

0 commit comments

Comments
 (0)