ccpoad / internal /util /time_test.go
anyalerob's picture
Upload folder using huggingface_hub
2986042 verified
Raw
History Blame Contribute Delete
4.74 kB
package util
import (
"testing"
"time"
)
func TestCalculateBackoffDuration_504Error(t *testing.T) {
now := time.Now()
statusCode504 := 504
tests := []struct {
name string
prevMs int64
until time.Time
statusCode *int
expectedMin time.Duration
expectedMax time.Duration
description string
}{
{
name: "首次504错误应冷却2分钟",
prevMs: 0,
until: time.Time{},
statusCode: &statusCode504,
expectedMin: 2 * time.Minute,
expectedMax: 2 * time.Minute,
description: "504 Gateway Timeout should trigger 2-minute cooldown on first occurrence (exponential backoff: 2min -> 4min -> 8min ...)",
},
{
name: "连续504错误应指数退避",
prevMs: int64(2 * time.Minute / time.Millisecond),
until: now.Add(2 * time.Minute),
statusCode: &statusCode504,
expectedMin: 4 * time.Minute,
expectedMax: 4 * time.Minute,
description: "Subsequent 504 errors should double the cooldown (2min -> 4min)",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
duration := CalculateBackoffDuration(tt.prevMs, tt.until, now, tt.statusCode)
if duration < tt.expectedMin || duration > tt.expectedMax {
t.Errorf("%s\n期望冷却时间: %v-%v\n实际冷却时间: %v",
tt.description, tt.expectedMin, tt.expectedMax, duration)
}
})
}
}
func TestCalculateBackoffDuration_ChannelErrors(t *testing.T) {
now := time.Now()
tests := []struct {
statusCode int
expected time.Duration
}{
{500, 2 * time.Minute}, // Internal Server Error: 2min -> 4min -> 8min ...
{502, 2 * time.Minute}, // Bad Gateway: 2min -> 4min -> 8min ...
{503, 2 * time.Minute}, // Service Unavailable: 2min -> 4min -> 8min ...
{504, 2 * time.Minute}, // Gateway Timeout: 2min -> 4min -> 8min ...
{520, 2 * time.Minute}, // Web Server Returned an Unknown Error: 2min -> 4min -> 8min ...
{521, 2 * time.Minute}, // Web Server Is Down: 2min -> 4min -> 8min ...
{524, 2 * time.Minute}, // A Timeout Occurred: 2min -> 4min -> 8min ...
{599, 2 * time.Minute}, // Stream Incomplete (内部状态码): 2min -> 4min -> 8min ...
}
for _, tt := range tests {
t.Run("StatusCode_"+string(rune(tt.statusCode)), func(t *testing.T) {
duration := CalculateBackoffDuration(0, time.Time{}, now, &tt.statusCode)
if duration != tt.expected {
t.Errorf("状态码%d首次错误应冷却%v,实际%v",
tt.statusCode, tt.expected, duration)
}
})
}
}
func TestCalculateBackoffDuration_AuthErrors(t *testing.T) {
now := time.Now()
tests := []struct {
statusCode int
expected time.Duration
}{
{401, 5 * time.Minute}, // Unauthorized
{402, 5 * time.Minute}, // Payment Required
{403, 5 * time.Minute}, // Forbidden
}
for _, tt := range tests {
t.Run("StatusCode_"+string(rune(tt.statusCode)), func(t *testing.T) {
duration := CalculateBackoffDuration(0, time.Time{}, now, &tt.statusCode)
if duration != tt.expected {
t.Errorf("认证错误%d首次应冷却%v,实际%v",
tt.statusCode, tt.expected, duration)
}
})
}
}
func TestCalculateBackoffDuration_OtherErrors(t *testing.T) {
now := time.Now()
tests := []struct {
statusCode int
expected time.Duration
}{
{429, time.Minute}, // Too Many Requests - 1分钟冷却
}
for _, tt := range tests {
t.Run("StatusCode_"+string(rune(tt.statusCode)), func(t *testing.T) {
duration := CalculateBackoffDuration(0, time.Time{}, now, &tt.statusCode)
if duration != tt.expected {
t.Errorf("状态码%d首次错误应冷却%v,实际%v",
tt.statusCode, tt.expected, duration)
}
})
}
}
func TestCalculateBackoffDuration_TimeoutError(t *testing.T) {
now := time.Now()
statusCode598 := 598
duration := CalculateBackoffDuration(0, time.Time{}, now, &statusCode598)
if duration != TimeoutErrorCooldown {
t.Errorf("超时错误(598)应固定冷却%v,实际%v",
TimeoutErrorCooldown, duration)
}
}
func TestCalculateBackoffDuration_ExponentialBackoff(t *testing.T) {
now := time.Now()
statusCode := 500 // 使用服务器错误测试指数退避(2分钟起始)
// 测试指数退避序列:2min -> 4min -> 8min -> 16min -> 30min(上限)
expectedSequence := []time.Duration{
2 * time.Minute, // 初始
4 * time.Minute, // 2x
8 * time.Minute, // 4x
16 * time.Minute, // 8x
30 * time.Minute, // 达到上限
30 * time.Minute, // 保持上限
}
prevMs := int64(0)
for i, expected := range expectedSequence {
duration := CalculateBackoffDuration(prevMs, time.Time{}, now, &statusCode)
if duration != expected {
t.Errorf("第%d次退避应为%v,实际%v", i+1, expected, duration)
}
prevMs = int64(duration / time.Millisecond)
}
}