From e91b4941680bf948166c4f1dbd96356c8a623bbb Mon Sep 17 00:00:00 2001 From: IanShaw027 Date: Sat, 8 Aug 2026 15:00:33 +0800 Subject: [PATCH] fix(test): stabilize OpenAI streaming preamble keepalive assertion Keepalive is gated on downstream idle, not upstream tick cadence. The old fixture wrote progress events every 250ms and could finish without a true 1s idle window on loaded CI runners, so ":\n\n" never appeared. Pause after preamble long enough for the keepalive ticker before completing the stream. --- .../service/openai_gateway_service_test.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/backend/internal/service/openai_gateway_service_test.go b/backend/internal/service/openai_gateway_service_test.go index 4ec35804c7..3ac83b4d0d 100644 --- a/backend/internal/service/openai_gateway_service_test.go +++ b/backend/internal/service/openai_gateway_service_test.go @@ -1994,8 +1994,10 @@ func TestOpenAIStreamingPreambleKeepaliveUsesDownstreamIdle(t *testing.T) { cfg := &config.Config{ Gateway: config.GatewayConfig{ StreamDataIntervalTimeout: 0, - StreamKeepaliveInterval: 1, - MaxLineSize: defaultMaxLineSize, + // Keepalive is based on *downstream* idle time (last flush to client), + // not upstream event cadence. Interval is seconds (config unit). + StreamKeepaliveInterval: 1, + MaxLineSize: defaultMaxLineSize, }, } svc := &OpenAIGatewayService{cfg: cfg} @@ -2013,11 +2015,14 @@ func TestOpenAIStreamingPreambleKeepaliveUsesDownstreamIdle(t *testing.T) { go func() { defer func() { _ = pw.Close() }() + // Emit preamble/progress quickly so clientOutputStarted is true, then + // leave a real downstream idle gap longer than keepaliveInterval so the + // ticker can write ":\n\n". Frequent upstream ticks used to refresh + // lastDownstreamWriteAt and flake on loaded CI runners. _, _ = pw.Write([]byte("data: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_1\"}}\n\n")) - for i := 0; i < 6; i++ { - time.Sleep(250 * time.Millisecond) - _, _ = pw.Write([]byte("data: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_1\"}}\n\n")) - } + time.Sleep(50 * time.Millisecond) + _, _ = pw.Write([]byte("data: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_1\"}}\n\n")) + time.Sleep(1300 * time.Millisecond) _, _ = pw.Write([]byte("data: {\"type\":\"response.completed\",\"response\":{\"usage\":{\"input_tokens\":1,\"output_tokens\":2}}}\n\n")) }()