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

FakeTimeProvider does not support creating a CancellationTokenSource with an infinite delay #4114

Closed
martincostello opened this issue Jun 24, 2023 · 2 comments

Comments

@martincostello
Copy link
Member

martincostello commented Jun 24, 2023

Description

If code creates a CancellationTokenSource with an infinite delay, when that code is invoked with FakeTimeProvider instead of TimeProvider.System an ArgumentOutOfRangeException is thrown.

Reproduction Steps

Execute the following xunit test targeting net8.0:

using Microsoft.Extensions.Time.Testing;

namespace FakeTimeProviderIssueRepro;

public static class FakeTimeProviderTests
{
    public static IEnumerable<object[]> TimeProviders => new[]
    {
        new[] { TimeProvider.System },
        new[] { new FakeTimeProvider() },
    };

    [Theory]
    [MemberData(nameof(TimeProviders))]
    public static void Can_Create_Infinite_CancellationTokenSource_With_TimeProvider(TimeProvider timeProvider)
    {
        using var cts = new CancellationTokenSource(Timeout.InfiniteTimeSpan, timeProvider);
        cts.IsCancellationRequested.ShouldBeFalse();
    }
}

Expected behavior

Both tests pass.

Actual behavior

The test using FakeTimeProvider fails with the following exception:

Can_Create_Infinite_CancellationTokenSource_With_TimeProvider(timeProvider: 2000-01-01T00:00:00.000) 

Duration: 2 ms

Message: 
  System.ArgumentOutOfRangeException : Argument not in the range [-1..4294967294] (Parameter 'dueTime')
  Actual value was 4294967295.

Stack Trace: 
  Throw.ArgumentOutOfRangeException(String paramName, Object actualValue, String message)
  Waiter.ChangeAndValidateDurations(TimeSpan dueTime, TimeSpan period)
  Waiter.ctor(FakeTimeProvider fakeTimeProvider, TimeSpan dueTime, TimeSpan period, TimerCallback callback, Object state)
  FakeTimeProviderTimer.ctor(FakeTimeProvider fakeTimeProvider, TimeSpan dueTime, TimeSpan period, TimerCallback callback, Object state)
  FakeTimeProvider.CreateTimer(TimerCallback callback, Object state, TimeSpan dueTime, TimeSpan period)
  CancellationTokenSource.InitializeWithTimer(UInt32 millisecondsDelay, TimeProvider timeProvider)
  CancellationTokenSource.ctor(TimeSpan delay, TimeProvider timeProvider)
  FakeTimeProviderTests.Can_Create_Infinite_CancellationTokenSource_With_TimeProvider(TimeProvider timeProvider) line 20
  InvokeStub_FakeTimeProviderTests.Can_Create_Infinite_CancellationTokenSource_With_TimeProvider(Object, Object, IntPtr*)
  MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

Regression?

No.

Known Workarounds

None.

Configuration

  • .NET SDK 8.0.100-preview.5.23303.2
  • Microsoft.Extensions.TimeProvider.Testing 8.0.0-preview.5.23308.3

Other information

No response

@martincostello
Copy link
Member Author

Digging into the code, I think this is actually an issue in dotnet/runtime caused by the cast to uint in this method. Just verifying and if so will open a new issue there and close this one.

@martincostello
Copy link
Member Author

dotnet/runtime#88000

@martincostello martincostello closed this as not planned Won't fix, can't repro, duplicate, stale Jun 24, 2023
@ghost ghost removed the untriaged label Jun 24, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Jul 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant