First Commit
ci / go (push) Waiting to run
ci / go-db (agent) (push) Waiting to run
ci / go-db (config) (push) Waiting to run
ci / go-db (db) (push) Waiting to run
ci / go-db (evidence) (push) Waiting to run
ci / go-db (llmrec) (push) Waiting to run
ci / go-db (server) (push) Waiting to run
web / web (push) Waiting to run
docs / links (push) Canceled after 0s
detections / detections (push) Canceled after 0s
ci / go (push) Waiting to run
ci / go-db (agent) (push) Waiting to run
ci / go-db (config) (push) Waiting to run
ci / go-db (db) (push) Waiting to run
ci / go-db (evidence) (push) Waiting to run
ci / go-db (llmrec) (push) Waiting to run
ci / go-db (server) (push) Waiting to run
web / web (push) Waiting to run
docs / links (push) Canceled after 0s
detections / detections (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Autumn-27/artex/agent"
|
||||
"github.com/Autumn-27/artex/db"
|
||||
)
|
||||
|
||||
// 没有任何配置时,解析结果必须是全零 —— 也就是 SDK 与 task_llm 各自的内置默认,
|
||||
// 与「重试可配」这个特性上线之前逐字节一致。
|
||||
func TestResolveRetryUnconfigured(t *testing.T) {
|
||||
got := resolveRetry(db.RetryOverride{}, db.LLMRetryPolicy{})
|
||||
if got != (agent.RetryConfig{}) {
|
||||
t.Fatalf("resolveRetry=%+v, want zero", got)
|
||||
}
|
||||
retries, backoff := sameProviderRetryPolicy(got)
|
||||
if retries != sameProviderStreamRetries {
|
||||
t.Fatalf("retries=%d, want %d", retries, sameProviderStreamRetries)
|
||||
}
|
||||
if d := backoff(1); d != time.Second {
|
||||
t.Fatalf("backoff(1)=%v, want 1s (the default ladder)", d)
|
||||
}
|
||||
}
|
||||
|
||||
// The global policy applies to a profile that overrides nothing.
|
||||
func TestResolveRetryFromGlobal(t *testing.T) {
|
||||
pol := db.LLMRetryPolicy{
|
||||
Connect: db.RetryRule{Attempts: 5, IntervalMS: 2000},
|
||||
Empty: db.RetryRule{Attempts: -1},
|
||||
Stream: db.RetryRule{Attempts: 4, IntervalMS: 1500},
|
||||
}
|
||||
got := resolveRetry(db.RetryOverride{}, pol)
|
||||
want := agent.RetryConfig{
|
||||
ConnectAttempts: 5, ConnectInterval: 2 * time.Second,
|
||||
EmptyAttempts: -1,
|
||||
StreamAttempts: 4, StreamInterval: 1500 * time.Millisecond,
|
||||
}
|
||||
if got != want {
|
||||
t.Fatalf("resolveRetry=%+v, want %+v", got, want)
|
||||
}
|
||||
retries, backoff := sameProviderRetryPolicy(got)
|
||||
if retries != 4 {
|
||||
t.Fatalf("retries=%d, want 4", retries)
|
||||
}
|
||||
for _, attempt := range []int{0, 3} {
|
||||
if d := backoff(attempt); d != 1500*time.Millisecond {
|
||||
t.Fatalf("backoff(%d)=%v, want a fixed 1.5s", attempt, d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A profile override wins field by field: the pinned count replaces the global
|
||||
// one, while the interval it left alone still comes from the global policy.
|
||||
func TestResolveRetryProfileOverridesPerField(t *testing.T) {
|
||||
pol := db.LLMRetryPolicy{
|
||||
Connect: db.RetryRule{Attempts: 5, IntervalMS: 2000},
|
||||
Stream: db.RetryRule{Attempts: 4, IntervalMS: 1500},
|
||||
}
|
||||
over := db.RetryOverride{
|
||||
Connect: db.RetryRule{Attempts: 1},
|
||||
Stream: db.RetryRule{IntervalMS: 250},
|
||||
}
|
||||
got := resolveRetry(over, pol)
|
||||
if got.ConnectAttempts != 1 || got.ConnectInterval != 2*time.Second {
|
||||
t.Fatalf("connect=%d/%v, want 1 attempt inheriting the 2s interval", got.ConnectAttempts, got.ConnectInterval)
|
||||
}
|
||||
if got.StreamAttempts != 4 || got.StreamInterval != 250*time.Millisecond {
|
||||
t.Fatalf("stream=%d/%v, want the global 4 attempts with a pinned 250ms", got.StreamAttempts, got.StreamInterval)
|
||||
}
|
||||
}
|
||||
|
||||
// -1 turns the same-provider layer off entirely (0 retries), rather than being
|
||||
// mistaken for "unset".
|
||||
func TestSameProviderRetryDisabled(t *testing.T) {
|
||||
retries, _ := sameProviderRetryPolicy(agent.RetryConfig{StreamAttempts: -1})
|
||||
if retries != 0 {
|
||||
t.Fatalf("retries=%d, want 0 (disabled)", retries)
|
||||
}
|
||||
}
|
||||
|
||||
// Values beyond the sane range are clamped on the way into the DB, so a hostile
|
||||
// or fat-fingered payload can't park a worker for a day.
|
||||
func TestRetryRuleClamp(t *testing.T) {
|
||||
pol := db.LLMRetryPolicy{
|
||||
Connect: db.RetryRule{Attempts: -50, IntervalMS: -1},
|
||||
Stream: db.RetryRule{Attempts: 9999, IntervalMS: 99_999_999},
|
||||
}
|
||||
got := resolveRetry(db.RetryOverride{}, pol.Clamped())
|
||||
if got.ConnectAttempts != -1 || got.ConnectInterval != 0 {
|
||||
t.Fatalf("connect=%d/%v, want -1 attempts and no interval", got.ConnectAttempts, got.ConnectInterval)
|
||||
}
|
||||
if got.StreamAttempts != 20 || got.StreamInterval != time.Hour {
|
||||
t.Fatalf("stream=%d/%v, want the 20-attempt / 1h caps", got.StreamAttempts, got.StreamInterval)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user