Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions src/Build.UnitTests/BackEnd/Scheduler_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -968,5 +968,51 @@ private void ReportDefaultParentRequestIsFinished()
var buildResult = new BuildResult(_defaultParentRequest);
_scheduler.ReportResult(_defaultParentRequest.NodeRequestId, buildResult);
}

[Fact]
public void ScheduleTimeRecord_AccumulatedTime_DoesNotThrowWhenTimerIsRunning()
{
var record = new ScheduleTimeRecord();
DateTime startTime = new DateTime(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc);

// Before starting: accumulated time should be zero.
record.AccumulatedTime.ShouldBe(TimeSpan.Zero);

// Start the timer.
record.StartState(startTime);

// While running: should NOT throw — should return a positive elapsed time.
record.AccumulatedTime.ShouldBeGreaterThan(TimeSpan.Zero);

// Stop the timer.
DateTime endTime = startTime.AddMilliseconds(500);
record.EndState(endTime);

// After stopping: should return the accumulated time.
record.AccumulatedTime.ShouldBe(TimeSpan.FromMilliseconds(500));
}

[Fact]
public void ScheduleTimeRecord_AccumulatedTime_IncludesPreviousAccumulation()
{
var record = new ScheduleTimeRecord();
DateTime t0 = new DateTime(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc);

// First interval: 200ms.
record.StartState(t0);
record.EndState(t0.AddMilliseconds(200));
record.AccumulatedTime.ShouldBe(TimeSpan.FromMilliseconds(200));

// Start a second interval.
record.StartState(t0.AddMilliseconds(300));

// While second interval is running: should include the 200ms from
// the first interval plus the elapsed time of the current interval.
record.AccumulatedTime.ShouldBeGreaterThan(TimeSpan.FromMilliseconds(200));

// Stop second interval after 100ms.
record.EndState(t0.AddMilliseconds(400));
record.AccumulatedTime.ShouldBe(TimeSpan.FromMilliseconds(300));
}
}
}
10 changes: 9 additions & 1 deletion src/Build/BackEnd/Components/Scheduler/ScheduleTimeRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,20 @@ public ScheduleTimeRecord()

/// <summary>
/// Retrieve the accumulated time.
/// If the timer is still running, returns the accumulated time so far
/// (elapsed time since the timer started plus any previously accumulated time)
/// instead of throwing.
/// </summary>
public TimeSpan AccumulatedTime
{
get
{
ErrorUtilities.VerifyThrow(_startTimeForCurrentState == DateTime.MinValue, "Can't get the accumulated time while the timer is still running.");
if (_startTimeForCurrentState != DateTime.MinValue)
{
// Timer is still running — return best-effort elapsed time.
return _accumulatedTime + (DateTime.UtcNow - _startTimeForCurrentState);
}
Comment thread
YuliiaKovalova marked this conversation as resolved.

return _accumulatedTime;
}
}
Expand Down