Skip to content

Commit de3ef28

Browse files
ANcpLuaclaude
andcommitted
Fix SSE fallback test race condition with ResponseHeadersRead
Changed the test to use HttpCompletionOption.ResponseHeadersRead which returns as soon as the HTTP connection is established (headers received), then publishes the event. This eliminates the race condition where the event could be published before the endpoint subscribes to the SSE stream. Previously, the test used Task.Delay(100ms) hoping the subscription would happen in time, which caused timeouts in CI environments (GitHub Actions). Added 5-second timeout for safety. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 1153108 commit de3ef28

File tree

1 file changed

+17
-21
lines changed

1 file changed

+17
-21
lines changed

SWEN3.Paperless.RabbitMq.Tests/Unit/SseExtensionsFallbackTests.cs

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,28 +29,24 @@ public async Task MapSse_OnNet8_ShouldWriteCorrectSseFormat()
2929
var sseStream = server.Host.Services.GetRequiredService<ISseStream<Messages.SseTestEvent>>();
3030

3131
// Act
32-
// Start the SSE request (will block until data is available)
33-
var responseTask = client.GetStreamAsync("/sse", TestContext.Current.CancellationToken);
34-
35-
// Start a task to publish the event after giving the endpoint time to subscribe
36-
_ = Task.Run(async () =>
37-
{
38-
await Task.Delay(100, TestContext.Current.CancellationToken);
39-
sseStream.Publish(new Messages.SseTestEvent { Id = 1, Message = "Hello" });
40-
}, TestContext.Current.CancellationToken);
41-
42-
// Assert
43-
var stream = await responseTask;
32+
// Start the request
33+
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
34+
var request = new HttpRequestMessage(HttpMethod.Get, "/sse");
35+
36+
// Use ResponseHeadersRead to return as soon as headers are received, keeping the stream open
37+
using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cts.Token);
38+
response.EnsureSuccessStatusCode();
39+
40+
var stream = await response.Content.ReadAsStreamAsync(cts.Token);
4441
using var reader = new StreamReader(stream, Encoding.UTF8);
45-
46-
// Read the stream. We expect:
47-
// event: test-event\n
48-
// data: {"id":1,"msg":"Hello"}\n
49-
// \n
50-
51-
var line1 = await reader.ReadLineAsync(TestContext.Current.CancellationToken);
52-
var line2 = await reader.ReadLineAsync(TestContext.Current.CancellationToken);
53-
var line3 = await reader.ReadLineAsync(TestContext.Current.CancellationToken);
42+
43+
// Publish an event *after* connection is established (headers received)
44+
sseStream.Publish(new Messages.SseTestEvent { Id = 1, Message = "Hello" });
45+
46+
// Read the stream
47+
var line1 = await reader.ReadLineAsync(cts.Token);
48+
var line2 = await reader.ReadLineAsync(cts.Token);
49+
var line3 = await reader.ReadLineAsync(cts.Token);
5450

5551
line1.Should().Be("event: test-event");
5652
line2.Should().Be("data: {\"id\":1,\"msg\":\"Hello\"}");

0 commit comments

Comments
 (0)