Severity: Info
File: tests/Servy.Manager.UnitTests/Utils/LogTailerTests.cs lines 76–89
Description:
RunFromPosition_ShouldHandleFileRotation coordinates with the SUT exclusively via fixed Task.Delay:
// Wait for the tailer to actually enter its inner loop
await Task.Delay(300, TestContext.Current.CancellationToken);
// Simulate Rotation: Truncate and write fresh content …
using (var fs = new FileStream(initialPath, FileMode.Truncate, …))
using (var sw = new StreamWriter(fs) { AutoFlush = true })
{
await sw.WriteLineAsync("ROTATED_CONTENT");
}
// Give the polling loop (150ms) and ReadLineAsync enough time to process the truncation
await Task.Delay(1000, TestContext.Current.CancellationToken);
Both delays are tuned to the current polling interval (150ms). The comment acknowledges the timing assumption. On a slow CI agent, a noisy VM, or under parallel-test load, 300ms may not be enough for the tailer to enter its inner loop; 1000ms may not be enough for the poll + ReadLineAsync to catch the truncated file. Failure mode: the test asserts Assert.Contains(capturedLines, …) on an empty list — red CI for reasons unrelated to product behaviour.
Suggested fix:
Replace both delays with deterministic waits:
- For "enter inner loop": have
LogTailer expose a TaskCompletionSource signalling "first poll started" (an internal or testing-only property), and await that from the test.
- For "poll has observed rotation": wait on
capturedLines reaching count >= 1 via a polling helper with a generous timeout (e.g., 10s) that exits as soon as the assertion becomes true, rather than sleeping unconditionally for 1000ms.
static async Task WaitUntilAsync(Func<bool> predicate, TimeSpan timeout) {
var deadline = DateTime.UtcNow + timeout;
while (DateTime.UtcNow < deadline) {
if (predicate()) return;
await Task.Delay(50);
}
throw new TimeoutException();
}
That pattern keeps the test fast on healthy agents and tolerant on slow ones.
Severity: Info
File:
tests/Servy.Manager.UnitTests/Utils/LogTailerTests.cslines 76–89Description:
RunFromPosition_ShouldHandleFileRotationcoordinates with the SUT exclusively via fixedTask.Delay:Both delays are tuned to the current polling interval (150ms). The comment acknowledges the timing assumption. On a slow CI agent, a noisy VM, or under parallel-test load, 300ms may not be enough for the tailer to enter its inner loop; 1000ms may not be enough for the poll +
ReadLineAsyncto catch the truncated file. Failure mode: the test assertsAssert.Contains(capturedLines, …)on an empty list — red CI for reasons unrelated to product behaviour.Suggested fix:
Replace both delays with deterministic waits:
LogTailerexpose aTaskCompletionSourcesignalling "first poll started" (an internal or testing-only property), andawait thatfrom the test.capturedLinesreachingcount >= 1via a polling helper with a generous timeout (e.g., 10s) that exits as soon as the assertion becomes true, rather than sleeping unconditionally for 1000ms.That pattern keeps the test fast on healthy agents and tolerant on slow ones.