220 lines
3.5 KiB
Markdown
220 lines
3.5 KiB
Markdown
# EonaCat.DeterministicTime
|
|
|
|
EonaCat.DeterministicTime is a **.NET library for deterministic, testable, and replayable time**.
|
|
|
|
It replaces `DateTime.UtcNow`, `Stopwatch`, `Timer`, and `Task.Delay` with deterministic equivalents and supports advanced features like:
|
|
|
|
scheduling,
|
|
time scaling,
|
|
replay,
|
|
NTP offsets,
|
|
ASP.NET Framework integration.
|
|
ASP.NET Core integration.
|
|
|
|
---
|
|
|
|
## Installation
|
|
|
|
```
|
|
dotnet add package EonaCat.DeterministicTime
|
|
```
|
|
|
|
|
|
### ASP.NET Core integration (optional)
|
|
|
|
```
|
|
dotnet add package DeterministicTime.AspNetCore
|
|
```
|
|
|
|
### ASP.NET Framework integration (optional)
|
|
|
|
```
|
|
dotnet add package DeterministicTime.AspNetFramework
|
|
```
|
|
|
|
ASP.NET 4.8 → add DeterministicTime.AspNetFramework and register HttpModule in web.config:
|
|
```xml
|
|
<system.web>
|
|
<httpModules>
|
|
<add name="DeterministicTime" type="DeterministicTimeHttpModule"/>
|
|
</httpModules>
|
|
</system.web>
|
|
```
|
|
|
|
---
|
|
## Basic Usage
|
|
|
|
```csharp
|
|
using DeterministicTime;
|
|
|
|
DateTime now = DeterministicTime.UtcNow;
|
|
DateTime localNow = DeterministicTime.Now;
|
|
```
|
|
|
|
---
|
|
## Freeze Time
|
|
|
|
```csharp
|
|
using (TimeScope.Frozen(DateTime.Parse("2025-01-01T00:00:00Z")))
|
|
{
|
|
Console.WriteLine(DeterministicTime.UtcNow); // frozen
|
|
}
|
|
```
|
|
|
|
---
|
|
## Scale Time
|
|
|
|
```csharp
|
|
using (TimeScope.Scaled(10)) // 10x faster
|
|
{
|
|
// all timers and delays scale 10x
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Advance Time Manually
|
|
|
|
```csharp
|
|
DeterministicTime.Advance(TimeSpan.FromHours(2));
|
|
```
|
|
|
|
---
|
|
|
|
## Offset Time
|
|
|
|
```csharp
|
|
using (TimeScope.Offset(TimeSpan.FromMinutes(5)))
|
|
{
|
|
// all UtcNow calls are offset by 5 minutes
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Deterministic Stopwatch
|
|
|
|
```csharp
|
|
var sw = DeterministicStopwatch.StartNew();
|
|
// do work
|
|
sw.Stop();
|
|
Console.WriteLine(sw.Elapsed);
|
|
```
|
|
|
|
|
|
---
|
|
|
|
## Deterministic Timer
|
|
|
|
```csharp
|
|
int fired = 0;
|
|
DeterministicTimer.Start(TimeSpan.FromSeconds(10), () => fired++);
|
|
DeterministicTime.Advance(TimeSpan.FromSeconds(10));
|
|
Console.WriteLine(fired); // 1
|
|
```
|
|
|
|
---
|
|
|
|
## Deterministic Delay
|
|
|
|
```csharp
|
|
bool completed = false;
|
|
await DeterministicDelay.For(TimeSpan.FromSeconds(5)).ContinueWith(_ => completed = true);
|
|
DeterministicTime.Advance(TimeSpan.FromSeconds(5));
|
|
Console.WriteLine(completed); // true
|
|
```
|
|
|
|
|
|
---
|
|
|
|
## Deterministic Scheduler
|
|
|
|
```csharp
|
|
var scheduler = DeterministicScheduler.Global;
|
|
scheduler.Every(TimeSpan.FromMinutes(1), () => Console.WriteLine("Tick"));
|
|
DeterministicTime.Advance(TimeSpan.FromMinutes(5)); // fires 5 times
|
|
```
|
|
|
|
---
|
|
|
|
## Time Recording & Replay
|
|
|
|
### Record
|
|
|
|
```csharp
|
|
using var recording = TimeRecording.Start();
|
|
// run code
|
|
recording.Save("run.json");
|
|
```
|
|
|
|
### Replay
|
|
|
|
```csharp
|
|
using (TimeReplay.Load("run.json"))
|
|
{
|
|
// deterministic replay of UtcNow calls
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## NTP Synchronization
|
|
|
|
```csharp
|
|
using (NtpSynchronization.Sync(myNtpProvider))
|
|
{
|
|
// deterministic time aligned with NTP
|
|
}
|
|
|
|
```
|
|
|
|
---
|
|
|
|
## Distributed Time Source
|
|
|
|
```csharp
|
|
IDistributedTimeCoordinator coordinator = ...;
|
|
DeterministicTime.Push(new DistributedTimeSource(coordinator));
|
|
Console.WriteLine(DeterministicTime.UtcNow);
|
|
```
|
|
|
|
---
|
|
|
|
## ASP.NET Core Middleware
|
|
|
|
```csharp
|
|
app.UseDeterministicTime();
|
|
```
|
|
|
|
* Each request runs in its own deterministic scope
|
|
|
|
* Works with frozen/scaled time and timers
|
|
|
|
|
|
---
|
|
|
|
|
|
## Advanced Features Summary
|
|
|
|
* **Deterministic UtcNow & Now**
|
|
|
|
* **Stopwatch replacement**
|
|
|
|
* **One-shot and repeated timers**
|
|
|
|
* **Task.Delay replacement**
|
|
|
|
* **Time scaling, freezing, offset**
|
|
|
|
* **Scheduler for background jobs**
|
|
|
|
* **Recording & replay for testing**
|
|
|
|
* **NTP synchronization & distributed clocks**
|
|
|
|
* **ASP.NET Framework integration**
|
|
|
|
* **ASP.NET Core integration**
|
|
|
|
|