Skip to content

RunTrackerAsync_IfProviderThrows_LogsError test times out on Windows + .NET 10.0 #7009

@joperezr

Description

@joperezr

Description

The test RunTrackerAsync_IfProviderThrows_LogsError in ResourceMonitoringServiceTests.cs is consistently timing out on Windows when running on .NET 10.0. The test passes successfully on .NET 8.0 and .NET 9.0, indicating a regression or behavioral change in .NET 10.0.

Reproduction Steps

  1. Target .NET 10.0 for the test project Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests
  2. Run the test RunTrackerAsync_IfProviderThrows_LogsError on Windows
  3. Observe the test timeout

Expected behavior

The test should complete within a reasonable time (< 5 seconds) as it does on .NET 8.0 and .NET 9.0. The test should:

  1. Start the ResourceMonitorService with a FakeTimeProvider
  2. Enable the FaultProvider to throw exceptions
  3. Advance time using the fake clock
  4. Wait for the publisher to be called (signaled via ManualResetEventSlim)
  5. Assert that the error was logged

Actual behavior

The test times out with the assertion failure:

Assert.True(attempts < maxAttempts, "Timeout waiting for publisher to be called");

The polling loop exhausts all 100 attempts without the publisher being called, suggesting that the FakeTimeProvider.Delay() mechanism is not properly responding to clock.Advance() calls in .NET 10.0.

Regression?

Yes, this is a regression. The test passes on:

  • ✅ .NET 8.0 on Windows
  • ✅ .NET 9.0 on Windows
  • ✅ .NET 10.0 on Linux (likely)
  • ❌ .NET 10.0 on Windows

Known Workarounds

The test has been temporarily disabled on .NET 10.0 using:

[Fact(
#if NET10_0
    Skip = "Flaky on Windows + .NET 10.0, see https://github.com/dotnet/extensions/issues/6996"
#endif
)]

A similar pattern (polling with clock.Advance()) was successfully applied to fix ResourceUtilizationTracker_LogsSnapshotInformation, which suggests the underlying issue may be related to timing/scheduling differences in how TimeProvider.Delay() interacts with FakeTimeProvider.Advance() in .NET 10.0.

Configuration

  • .NET Version: .NET 10.0 RC2 (likely)
  • OS: Windows (specific version TBD from CI logs)
  • Test Framework: xUnit
  • Related Package: Microsoft.Extensions.Diagnostics.ResourceMonitoring

Test Code Location

File: test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/ResourceMonitoringServiceTests.cs
Test: RunTrackerAsync_IfProviderThrows_LogsError (line ~226)

Relevant Code

The test uses FakeTimeProvider to control time in ResourceMonitorService.ExecuteAsync():

protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
    while (true)
    {
        await _timeProvider.Delay(_samplingInterval, cancellationToken).ConfigureAwait(false);
        // ... sampling code ...
    }
}

The test attempts to trigger this loop by advancing the fake clock:

var maxAttempts = 100;
var attempts = 0;
while (!e.Wait(10) && attempts++ < maxAttempts)
{
    clock.Advance(TimeSpan.FromMilliseconds(1));
}

Other information

This issue is part of the .NET 10.0 migration effort tracked in PR #6995. The behavior suggests there may be subtle changes in:

  • Task scheduling in .NET 10.0
  • TimeProvider implementation
  • FakeTimeProvider from Microsoft.Extensions.Time.Testing
  • How Delay() responds to time advancement

Related Changes:

  • Fixed similar issue in ResourceUtilizationTracker_LogsSnapshotInformation by adding polling + Task.Delay(10)
  • Both tests were updated from simple "advance twice and wait" to a polling pattern

Investigation Needed:

  1. Check if there are breaking changes or known issues with TimeProvider in .NET 10.0
  2. Verify FakeTimeProvider behavior on different .NET versions
  3. Determine if additional synchronization is needed between Advance() and Delay() completion
  4. Consider if the issue is Windows-specific (possibly related to thread scheduling differences)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions