From a8b48024fcc9ff3b1460dda746fd4b149ccf6959 Mon Sep 17 00:00:00 2001 From: viettranx Date: Sat, 11 Apr 2026 23:15:02 +0700 Subject: [PATCH] test(feishu): bound webhook dispatch wait to 2s, not test timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit larkevents_test used `<-t.Context().Done()` as the timeout branch in the dispatch wait select. t.Context() is only canceled when the test function returns, so a missing dispatch call would deadlock the test for the full default go test timeout (10 min) before failing — a real CI hazard, discovered when an unrelated HMAC-verify experiment prevented dispatch and the CI run sat idle for 10 minutes. Replace with `time.After(2*time.Second)` via a named constant, plus a comment warning future readers not to revert the pattern. --- internal/channels/feishu/larkevents_test.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/internal/channels/feishu/larkevents_test.go b/internal/channels/feishu/larkevents_test.go index 52dc144c..da63cbe5 100644 --- a/internal/channels/feishu/larkevents_test.go +++ b/internal/channels/feishu/larkevents_test.go @@ -10,8 +10,18 @@ import ( "net/http/httptest" "strings" "testing" + "time" ) +// dispatchWaitTimeout bounds how long a webhook dispatch test will block on +// the onMessage channel before failing. Kept short (2s) so a regression in +// the dispatch path cannot hang CI for the full go test default (10 min). +// Do NOT replace with t.Context().Done() — that context is only canceled +// after the test returns, which creates a deadlock if the channel never +// receives. This bit Wave C when an unrelated HMAC patch suppressed +// dispatch and the test ran for 10 minutes before timing out. +const dispatchWaitTimeout = 2 * time.Second + // --- helpers --- // encryptEventPayload encrypts a JSON payload using the same AES-CBC scheme @@ -164,7 +174,7 @@ func TestWebhookHandler_TokenMatch_Dispatches(t *testing.T) { if e == nil { t.Error("dispatched event was nil") } - case <-t.Context().Done(): + case <-time.After(dispatchWaitTimeout): t.Error("timeout waiting for dispatched event") } } @@ -257,7 +267,7 @@ func TestWebhookHandler_EncryptedEvent_Decrypted(t *testing.T) { if e == nil { t.Error("dispatched event was nil") } - case <-t.Context().Done(): + case <-time.After(dispatchWaitTimeout): t.Error("timeout waiting for dispatched encrypted event") } }