Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Microsoft.Extensions.TimeProvider.Testing] FakeTimeProvider does not simulate timers correctly, misses executions #5722

Open
bara-pweber opened this issue Dec 4, 2024 · 0 comments
Labels
bug This issue describes a behavior which is not expected - a bug. untriaged

Comments

@bara-pweber
Copy link

Description

I am working with a non-periodic Timer that re-schedules itself with the ITimer.Change method. I noticed that FakeTimeProvider.Advance only ever executes the timer once, even if I provide a TimeSpan that covers multiple executions.

Reproduction Steps

public class TimerBugRepro
{
    [Fact]
    public void TestWithSystemTime() // Works
    {
        Assert.Equal(2, RunTestWithTimeProvider(TimeProvider.System, () => Thread.Sleep(TimeSpan.FromSeconds(3))));
    }

    [Fact]
    public void TestWithFakeTime() // Fails
    {
        var fakeTime = new FakeTimeProvider();
        Assert.Equal(2, RunTestWithTimeProvider(fakeTime, () => fakeTime.Advance(TimeSpan.FromSeconds(3))));
    }

    private int RunTestWithTimeProvider(TimeProvider timeProvider, Action sleepAction)
    {
        int count = 0;
        ITimer timer = null;
        timer = timeProvider.CreateTimer(
            _ =>
            {
                Interlocked.Increment(ref count);
                timer.Change(TimeSpan.FromSeconds(2), Timeout.InfiniteTimeSpan);
            },
            null,
            Timeout.InfiniteTimeSpan,
            Timeout.InfiniteTimeSpan);

        timer.Change(TimeSpan.FromMilliseconds(1), Timeout.InfiniteTimeSpan); // Both tests work for TimeSpan.Zero

        sleepAction();

        return count;
    }
}

Expected behavior

The FakeTimeProvider.Advance should correctly simulate the behavior for TimeProvider.System + Thread.Sleep.

Actual behavior

The Fake-Timer does not get re-sheduled correctly.

Regression?

No response

Known Workarounds

No response

Configuration

.NET SDK version: 9.0.100
TargetFramework: net8.0
Microsoft.Extensions.TimeProvider.Testing version: 9.0.0
OS: Windows 10 10.0.19045

Other information

No response

@bara-pweber bara-pweber added bug This issue describes a behavior which is not expected - a bug. untriaged labels Dec 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue describes a behavior which is not expected - a bug. untriaged
Projects
None yet
Development

No branches or pull requests

1 participant