Files
cc-connect/agent/codex/appserver_session_test.go
2026-06-02 23:14:41 +08:00

172 lines
5.1 KiB
Go

package codex
import (
"context"
"encoding/json"
"testing"
"github.com/chenhg5/cc-connect/core"
)
func TestAppServerSession_ApplyThreadRuntimeState(t *testing.T) {
s := &appServerSession{}
effort := "xhigh"
s.applyThreadRuntimeState("/tmp/project", "gpt-5.4", &effort)
if got := s.GetWorkDir(); got != "/tmp/project" {
t.Fatalf("GetWorkDir() = %q, want /tmp/project", got)
}
if got := s.GetModel(); got != "gpt-5.4" {
t.Fatalf("GetModel() = %q, want gpt-5.4", got)
}
if got := s.GetReasoningEffort(); got != "xhigh" {
t.Fatalf("GetReasoningEffort() = %q, want xhigh", got)
}
}
func TestAppServerSession_HandleRateLimitsUpdatedCachesUsage(t *testing.T) {
s := &appServerSession{}
raw, err := json.Marshal(appServerRateLimitsResponse{
RateLimits: appServerRateLimitSnapshot{
LimitID: "codex",
PlanType: "pro",
Primary: &appServerRateLimitWindow{UsedPercent: 25, WindowDurationMins: 15, ResetsAt: 1730947200},
Secondary: &appServerRateLimitWindow{UsedPercent: 42, WindowDurationMins: 60, ResetsAt: 1730950800},
Credits: &appServerCreditsSnapshot{HasCredits: true, Unlimited: false},
},
})
if err != nil {
t.Fatalf("marshal notification: %v", err)
}
s.handleNotification("account/rateLimits/updated", raw)
report, err := s.GetUsage(context.Background())
if err != nil {
t.Fatalf("GetUsage() returned error: %v", err)
}
if report.Provider != "codex" {
t.Fatalf("provider = %q, want codex", report.Provider)
}
if report.Plan != "pro" {
t.Fatalf("plan = %q, want pro", report.Plan)
}
if len(report.Buckets) != 1 {
t.Fatalf("buckets = %d, want 1", len(report.Buckets))
}
if got := report.Buckets[0].Name; got != "codex" {
t.Fatalf("bucket name = %q, want codex", got)
}
if got := report.Buckets[0].Windows[0].WindowSeconds; got != 15*60 {
t.Fatalf("primary window seconds = %d, want %d", got, 15*60)
}
if got := report.Buckets[0].Windows[1].UsedPercent; got != 42 {
t.Fatalf("secondary used percent = %d, want 42", got)
}
if report.Credits == nil || !report.Credits.HasCredits {
t.Fatalf("credits = %#v, want has credits", report.Credits)
}
}
func TestAppServerSession_HandleThreadTokenUsageUpdatedCachesContextUsage(t *testing.T) {
s := &appServerSession{}
raw, err := json.Marshal(appServerThreadTokenUsageNotification{
ThreadID: "thread-1",
TurnID: "turn-1",
TokenUsage: struct {
Total codexTokenUsage `json:"total"`
Last codexTokenUsage `json:"last"`
ModelContextWindow int `json:"modelContextWindow"`
}{
Total: codexTokenUsage{
TotalTokens: 52011395,
InputTokens: 51847383,
CachedInputTokens: 48187904,
OutputTokens: 164012,
ReasoningOutputTokens: 78910,
},
Last: codexTokenUsage{
TotalTokens: 41061,
InputTokens: 40849,
CachedInputTokens: 36864,
OutputTokens: 212,
ReasoningOutputTokens: 32,
},
ModelContextWindow: 258400,
},
})
if err != nil {
t.Fatalf("marshal notification: %v", err)
}
s.handleNotification("thread/tokenUsage/updated", raw)
usage := s.GetContextUsage()
if usage == nil {
t.Fatal("GetContextUsage() = nil, want cached context usage")
}
if usage.UsedTokens != 41061 {
t.Fatalf("used tokens = %d, want 41061", usage.UsedTokens)
}
if usage.BaselineTokens != codexContextBaselineTokens {
t.Fatalf("baseline tokens = %d, want %d", usage.BaselineTokens, codexContextBaselineTokens)
}
if usage.TotalTokens != 41061 {
t.Fatalf("total tokens = %d, want 41061", usage.TotalTokens)
}
if usage.ContextWindow != 258400 {
t.Fatalf("context window = %d, want 258400", usage.ContextWindow)
}
if usage.CachedInputTokens != 36864 {
t.Fatalf("cached input tokens = %d, want 36864", usage.CachedInputTokens)
}
if usage.InputTokens != 40849 {
t.Fatalf("input tokens = %d, want 40849", usage.InputTokens)
}
}
func TestMapAppServerRateLimits_PrefersMultiBucketView(t *testing.T) {
report := mapAppServerRateLimits(appServerRateLimitsResponse{
RateLimits: appServerRateLimitSnapshot{
LimitID: "legacy",
PlanType: "team",
Primary: &appServerRateLimitWindow{UsedPercent: 99, WindowDurationMins: 15},
},
RateLimitsByLimitID: map[string]appServerRateLimitSnapshot{
"codex": {
LimitID: "codex",
LimitName: "Codex",
PlanType: "team",
Primary: &appServerRateLimitWindow{UsedPercent: 10, WindowDurationMins: 15},
},
"codex_other": {
LimitID: "codex_other",
PlanType: "team",
Primary: &appServerRateLimitWindow{UsedPercent: 20, WindowDurationMins: 60},
},
},
})
if report.Plan != "team" {
t.Fatalf("plan = %q, want team", report.Plan)
}
if len(report.Buckets) != 2 {
t.Fatalf("buckets = %d, want 2", len(report.Buckets))
}
if report.Buckets[0].Name != "Codex" {
t.Fatalf("first bucket = %q, want Codex", report.Buckets[0].Name)
}
if report.Buckets[1].Name != "codex_other" {
t.Fatalf("second bucket = %q, want codex_other", report.Buckets[1].Name)
}
}
var _ interface {
GetUsage(context.Context) (*core.UsageReport, error)
} = (*appServerSession)(nil)
var _ interface {
GetContextUsage() *core.ContextUsage
} = (*appServerSession)(nil)