Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
38 lines
1.2 KiB
Go
38 lines
1.2 KiB
Go
package wecom
|
||
|
||
import (
|
||
"testing"
|
||
"time"
|
||
)
|
||
|
||
// TestReconnectDelayOverflow guards against the bug where large attempt
|
||
// counters produced a negative time.Duration, bypassing the max-delay
|
||
// cap and causing a busy reconnect loop (e.g. "reconnecting in -1s").
|
||
func TestReconnectDelayOverflow(t *testing.T) {
|
||
tests := []struct {
|
||
name string
|
||
attempt int
|
||
want time.Duration
|
||
}{
|
||
{"zero attempt clamps to base", 0, defaultReconnectBaseDelay},
|
||
{"negative attempt clamps to base", -5, defaultReconnectBaseDelay},
|
||
{"attempt 1 = base", 1, defaultReconnectBaseDelay},
|
||
{"attempt 2 = 2× base", 2, 2 * defaultReconnectBaseDelay},
|
||
{"attempt 5 = 16s", 5, 16 * time.Second},
|
||
{"attempt 6 caps at max", 6, defaultReconnectMaxDelay},
|
||
{"attempt 100 caps at max", 100, defaultReconnectMaxDelay},
|
||
{"attempt 4601 caps at max (regression)", 4601, defaultReconnectMaxDelay},
|
||
}
|
||
for _, tt := range tests {
|
||
t.Run(tt.name, func(t *testing.T) {
|
||
got := reconnectDelay(tt.attempt)
|
||
if got != tt.want {
|
||
t.Errorf("reconnectDelay(%d) = %v, want %v", tt.attempt, got, tt.want)
|
||
}
|
||
if got <= 0 {
|
||
t.Errorf("reconnectDelay(%d) returned non-positive %v — would cause busy loop", tt.attempt, got)
|
||
}
|
||
})
|
||
}
|
||
}
|