Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

173 lines
5.2 KiB
Go

package agentstatus
import (
"context"
"os"
"path/filepath"
"testing"
"time"
)
func TestCLIVersionCacheReusesVersionUntilExecutableChanges(t *testing.T) {
binaryPath := filepath.Join(t.TempDir(), "agent-cli")
if err := os.WriteFile(binaryPath, []byte("first"), 0o700); err != nil {
t.Fatalf("write first binary: %v", err)
}
cache := NewCLIVersionCache()
loads := 0
load := func() string {
loads++
return "1.0.0"
}
if got := cache.load(binaryPath, load); got != "1.0.0" {
t.Fatalf("first version = %q, want 1.0.0", got)
}
if got := cache.load(binaryPath, load); got != "1.0.0" {
t.Fatalf("cached version = %q, want 1.0.0", got)
}
if loads != 1 {
t.Fatalf("loads = %d, want 1 before binary change", loads)
}
replacementPath := filepath.Join(filepath.Dir(binaryPath), "replacement")
if err := os.WriteFile(replacementPath, []byte("second binary"), 0o700); err != nil {
t.Fatalf("write replacement binary: %v", err)
}
if err := os.Rename(replacementPath, binaryPath); err != nil {
t.Fatalf("replace binary: %v", err)
}
if got := cache.load(binaryPath, load); got != "1.0.0" {
t.Fatalf("version after replacement = %q, want 1.0.0", got)
}
if loads != 2 {
t.Fatalf("loads = %d, want 2 after binary replacement", loads)
}
}
func TestCLIVersionCacheDoesNotStoreFailedReads(t *testing.T) {
binaryPath := filepath.Join(t.TempDir(), "agent-cli")
if err := os.WriteFile(binaryPath, []byte("binary"), 0o700); err != nil {
t.Fatalf("write binary: %v", err)
}
cache := NewCLIVersionCache()
loads := 0
load := func() string {
loads++
if loads == 1 {
return ""
}
return "1.0.0"
}
if got := cache.load(binaryPath, load); got != "" {
t.Fatalf("failed read = %q, want empty", got)
}
if got := cache.load(binaryPath, load); got != "1.0.0" {
t.Fatalf("retry read = %q, want 1.0.0", got)
}
if loads != 2 {
t.Fatalf("loads = %d, want failed read retried", loads)
}
}
func TestGlobalBinDiscoveryCacheReusesResultUntilManagerChanges(t *testing.T) {
managerPath := filepath.Join(t.TempDir(), "pnpm")
if err := os.WriteFile(managerPath, []byte("first"), 0o700); err != nil {
t.Fatalf("write manager: %v", err)
}
cache := NewGlobalBinDiscoveryCache()
loads := 0
load := func() string {
loads++
return "/global/bin"
}
if got := cache.load(managerPath, "bin\x00-g", load); got != "/global/bin" {
t.Fatalf("first bin dir = %q, want /global/bin", got)
}
if got := cache.load(managerPath, "bin\x00-g", load); got != "/global/bin" {
t.Fatalf("cached bin dir = %q, want /global/bin", got)
}
if loads != 1 {
t.Fatalf("loads = %d, want 1 before manager changes", loads)
}
replacementPath := filepath.Join(filepath.Dir(managerPath), "replacement")
if err := os.WriteFile(replacementPath, []byte("second manager"), 0o700); err != nil {
t.Fatalf("write replacement manager: %v", err)
}
if err := os.Rename(replacementPath, managerPath); err != nil {
t.Fatalf("replace manager: %v", err)
}
if got := cache.load(managerPath, "bin\x00-g", load); got != "/global/bin" {
t.Fatalf("bin dir after manager replacement = %q, want /global/bin", got)
}
if loads != 2 {
t.Fatalf("loads = %d, want 2 after manager replacement", loads)
}
}
func TestAdapterProbeCacheStoresOnlyMatchingExecutable(t *testing.T) {
binaryPath := filepath.Join(t.TempDir(), "adapter")
if err := os.WriteFile(binaryPath, []byte("first"), 0o700); err != nil {
t.Fatalf("write first adapter: %v", err)
}
cache := NewAdapterProbeCache()
cache.markReady("codex", binaryPath)
if !cache.ready("codex", binaryPath) {
t.Fatal("ready = false after successful probe")
}
replacementPath := filepath.Join(filepath.Dir(binaryPath), "replacement")
if err := os.WriteFile(replacementPath, []byte("second adapter"), 0o700); err != nil {
t.Fatalf("write replacement adapter: %v", err)
}
if err := os.Rename(replacementPath, binaryPath); err != nil {
t.Fatalf("replace adapter: %v", err)
}
if cache.ready("codex", binaryPath) {
t.Fatal("ready = true after adapter replacement")
}
}
func TestAdapterProbeCacheExpiresPositiveHandshakeEvidence(t *testing.T) {
binaryPath := filepath.Join(t.TempDir(), "codex")
if err := os.WriteFile(binaryPath, []byte("codex"), 0o700); err != nil {
t.Fatalf("write binary: %v", err)
}
cache := NewAdapterProbeCache()
checkedAt := time.Unix(100, 0)
cache.markReadyAt("codex", binaryPath, checkedAt)
if !cache.readyWithin("codex", binaryPath, checkedAt.Add(time.Second), time.Minute) {
t.Fatal("fresh positive handshake cache = false, want true")
}
if cache.readyWithin("codex", binaryPath, checkedAt.Add(time.Minute+time.Nanosecond), time.Minute) {
t.Fatal("expired positive handshake cache = true, want false")
}
}
func TestDetectionCommandLimiterBoundsConcurrentCommands(t *testing.T) {
limiter := NewDetectionCommandLimiter(1)
release, acquired := limiter.acquire(context.Background())
if !acquired {
t.Fatal("first command did not acquire limiter")
}
blockedContext, cancel := context.WithTimeout(
context.Background(),
20*time.Millisecond,
)
defer cancel()
if _, acquired := limiter.acquire(blockedContext); acquired {
t.Fatal("second command acquired a full limiter")
}
release()
nextRelease, acquired := limiter.acquire(context.Background())
if !acquired {
t.Fatal("next command did not acquire released limiter")
}
nextRelease()
}