Skip to content

Commit 008ee01

Browse files
JusterZhuclaude
andcommitted
fix(test): replace Progress\<T\> with SyncProgress\<T\> in OssDownloadExecutorTests to avoid Linux CI flaky failure
System.Progress<T> posts to SynchronizationContext, which may defer/defer callbacks on headless Ubuntu CI runners with .NET 10, causing progressValues to be empty at assertion time. SyncProgress<T> invokes the handler synchronously, eliminating the race. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent f642b0f commit 008ee01

1 file changed

Lines changed: 16 additions & 1 deletion

File tree

tests/CoreTest/Download/Executors/OssDownloadExecutorTests.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,10 @@ public async Task ExecuteAsync_WithProgress_Reports100Percent()
147147
var asset = CreateAsset();
148148
var destPath = Path.Combine(Path.GetTempPath(), $"test_{Guid.NewGuid()}.zip");
149149

150+
// Use a synchronous IProgress<T> instead of System.Progress<T>
151+
// to avoid SynchronizationContext dispatch races on Linux CI runners.
150152
var progressValues = new List<DownloadProgress>();
151-
var progress = new Progress<DownloadProgress>(p => progressValues.Add(p));
153+
var progress = new SyncProgress<DownloadProgress>(p => progressValues.Add(p));
152154

153155
try
154156
{
@@ -289,3 +291,16 @@ public async Task ExecuteAsync_NullProgress_DoesNotThrow()
289291

290292
#endregion
291293
}
294+
295+
/// <summary>
296+
/// Synchronous <see cref="IProgress{T}"/> that invokes the handler immediately.
297+
/// Unlike <see cref="System.Progress{T}"/>, this does not post to
298+
/// <see cref="SynchronizationContext"/>, making it deterministic in test environments
299+
/// where a sync context may defer or drop callbacks (e.g. headless Linux CI runners).
300+
/// </summary>
301+
internal sealed class SyncProgress<T> : IProgress<T>
302+
{
303+
private readonly Action<T> _handler;
304+
public SyncProgress(Action<T> handler) => _handler = handler ?? throw new ArgumentNullException(nameof(handler));
305+
public void Report(T value) => _handler(value);
306+
}

0 commit comments

Comments
 (0)