Skip to content

Commit

Permalink
Prevent Advance/SetUtcNow moving time backwards
Browse files Browse the repository at this point in the history
  • Loading branch information
egil committed Jun 6, 2023
1 parent 91916ff commit 145515a
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Threading;
using Microsoft.Shared.Diagnostics;

namespace Microsoft.Extensions.Time.Testing;

Expand Down Expand Up @@ -68,7 +69,12 @@ public override DateTimeOffset GetUtcNow()
/// <param name="value">The date and time in the UTC timezone.</param>
public void SetUtcNow(DateTimeOffset value)
{
while (_now <= value && TryGetWaiterToWake(value) is FakeTimeProviderTimer.Waiter waiter)
if (value < _now)
{
Throw.ArgumentOutOfRangeException(nameof(value), $"Cannot go back in time. Current time is {GetUtcNow()}.");
}

while (value >= _now && TryGetWaiterToWake(value) is FakeTimeProviderTimer.Waiter waiter)
{
_now = waiter.WakeupTime;
waiter.TriggerAndSchedule(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,15 @@ public void AdvanceGoesForward()
Assert.Equal(1234, elapsedTime.TotalMilliseconds);
}

[Fact]
public void TimeCannotGoBackwards()
{
var timeProvider = new FakeTimeProvider();

Assert.Throws<ArgumentOutOfRangeException>(() => timeProvider.Advance(TimeSpan.FromTicks(-1)));
Assert.Throws<ArgumentOutOfRangeException>(() => timeProvider.SetUtcNow(timeProvider.Epoch - TimeSpan.FromTicks(1)));
}

[Fact]
public void ToStr()
{
Expand Down

0 comments on commit 145515a

Please sign in to comment.