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
151 lines
5.9 KiB
Go
151 lines
5.9 KiB
Go
package agentstatus
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"runtime"
|
|
"strconv"
|
|
"testing"
|
|
)
|
|
|
|
func TestDiscoverCodexRuntimeCandidatesEnumeratesAllManagerBinsAfterPathMatch(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("shell fixture is Unix-only")
|
|
}
|
|
home := t.TempDir()
|
|
managerBin := filepath.Join(home, "manager-bin")
|
|
pathBin := filepath.Join(home, "path-bin")
|
|
bunBin := filepath.Join(home, "bun-global-bin")
|
|
pnpmBin := filepath.Join(home, "pnpm-global-bin")
|
|
npmPrefix := filepath.Join(home, "npm-prefix")
|
|
brewPrefix := filepath.Join(home, "brew-prefix")
|
|
discoveryMarkers := filepath.Join(home, "discovery-markers")
|
|
if err := os.MkdirAll(discoveryMarkers, 0o755); err != nil {
|
|
t.Fatalf("mkdir discovery markers: %v", err)
|
|
}
|
|
|
|
pathCodex := filepath.Join(pathBin, "codex")
|
|
bunCodex := filepath.Join(bunBin, "codex")
|
|
pnpmCodex := filepath.Join(pnpmBin, "codex")
|
|
npmCodex := filepath.Join(npmPrefix, "bin", "codex")
|
|
brewCodex := filepath.Join(brewPrefix, "bin", "codex")
|
|
for _, path := range []string{pathCodex, bunCodex, pnpmCodex, npmCodex, brewCodex} {
|
|
writeExecutable(t, path, "#!/bin/sh\nexit 0\n")
|
|
}
|
|
writeExecutable(t, filepath.Join(managerBin, "bun"), concurrentManagerFixture(discoveryMarkers, "bun", "if [ \"$1\" = pm ] && [ \"$2\" = bin ] && [ \"$3\" = -g ]; then echo \""+bunBin+"\"; fi"))
|
|
writeExecutable(t, filepath.Join(managerBin, "pnpm"), concurrentManagerFixture(discoveryMarkers, "pnpm", "if [ \"$1\" = bin ] && [ \"$2\" = -g ]; then echo \""+pnpmBin+"\"; fi"))
|
|
writeExecutable(t, filepath.Join(managerBin, "npm"), concurrentManagerFixture(discoveryMarkers, "npm", "if [ \"$1\" = prefix ] && [ \"$2\" = -g ]; then echo \""+npmPrefix+"\"; fi"))
|
|
writeExecutable(t, filepath.Join(managerBin, "brew"), concurrentManagerFixture(discoveryMarkers, "brew", "if [ \"$1\" = --prefix ]; then echo \""+brewPrefix+"\"; fi"))
|
|
|
|
service := probeTestService(home)
|
|
service.Environ = func() []string {
|
|
return []string{"PATH=" + managerBin + string(os.PathListSeparator) + pathBin + string(os.PathListSeparator) + "/usr/bin:/bin"}
|
|
}
|
|
candidates := service.discoverCodexRuntimeCandidates(context.Background(), ProviderSpec{Provider: "codex"})
|
|
|
|
if got, want := candidateLaunchers(candidates), []string{pathCodex, bunCodex, pnpmCodex, npmCodex, brewCodex}; !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("launchers = %#v, want %#v", got, want)
|
|
}
|
|
for index, source := range []codexRuntimeCandidateSource{
|
|
codexRuntimeCandidateSourcePath,
|
|
codexRuntimeCandidateSourceBunGlobal,
|
|
codexRuntimeCandidateSourcePNPMGlobal,
|
|
codexRuntimeCandidateSourceNPMGlobal,
|
|
codexRuntimeCandidateSourceHomebrew,
|
|
} {
|
|
if got := candidates[index].Sources; !reflect.DeepEqual(got, []codexRuntimeCandidateSource{source}) {
|
|
t.Fatalf("candidate %d sources = %#v, want %#v", index, got, []codexRuntimeCandidateSource{source})
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDiscoverCodexRuntimeCandidatesDeduplicatesLauncherAliases(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("symlink fixture is Unix-only")
|
|
}
|
|
home := t.TempDir()
|
|
target := filepath.Join(home, "package", "bin", "codex")
|
|
aliasDir := filepath.Join(home, "alias-bin")
|
|
alias := filepath.Join(aliasDir, "codex")
|
|
writeExecutable(t, target, "#!/bin/sh\nexit 0\n")
|
|
if err := os.MkdirAll(aliasDir, 0o755); err != nil {
|
|
t.Fatalf("mkdir alias dir: %v", err)
|
|
}
|
|
if err := os.Symlink(target, alias); err != nil {
|
|
t.Fatalf("create launcher alias: %v", err)
|
|
}
|
|
|
|
service := probeTestService(home)
|
|
service.Environ = func() []string {
|
|
return []string{"PATH=" + filepath.Dir(target) + string(os.PathListSeparator) + aliasDir}
|
|
}
|
|
candidates := service.discoverCodexRuntimeCandidates(context.Background(), ProviderSpec{Provider: "codex"})
|
|
if len(candidates) != 1 {
|
|
t.Fatalf("candidate count = %d, want one: %#v", len(candidates), candidates)
|
|
}
|
|
realTarget, err := filepath.EvalSymlinks(target)
|
|
if err != nil {
|
|
t.Fatalf("resolve target: %v", err)
|
|
}
|
|
if candidates[0].LauncherPath != target || candidates[0].RealPath != realTarget {
|
|
t.Fatalf("candidate = %#v, want launcher %q and real path %q", candidates[0], target, realTarget)
|
|
}
|
|
}
|
|
|
|
func TestCodexRuntimeCandidateCollectorDeduplicatesPackageRoots(t *testing.T) {
|
|
home := t.TempDir()
|
|
pkgRoot := filepath.Join(home, "node_modules", "@openai", "codex")
|
|
writePackageManifest(t, pkgRoot, "@openai/codex", "0.142.0")
|
|
first := filepath.Join(pkgRoot, "bin", "codex")
|
|
second := filepath.Join(pkgRoot, "alternate", "codex")
|
|
writeExecutable(t, first, "#!/bin/sh\nexit 0\n")
|
|
writeExecutable(t, second, "#!/bin/sh\nexit 0\n")
|
|
|
|
collector := codexRuntimeCandidateCollector{}
|
|
collector.add(first, codexRuntimeCandidateSourcePath)
|
|
collector.add(second, codexRuntimeCandidateSourceBunGlobal)
|
|
if len(collector.candidates) != 1 {
|
|
t.Fatalf("candidate count = %d, want one: %#v", len(collector.candidates), collector.candidates)
|
|
}
|
|
candidate := collector.candidates[0]
|
|
realPkgRoot, err := filepath.EvalSymlinks(pkgRoot)
|
|
if err != nil {
|
|
t.Fatalf("resolve package root: %v", err)
|
|
}
|
|
if candidate.PackageRoot != realPkgRoot {
|
|
t.Fatalf("package root = %q, want %q", candidate.PackageRoot, realPkgRoot)
|
|
}
|
|
if got, want := candidate.Sources, []codexRuntimeCandidateSource{codexRuntimeCandidateSourcePath, codexRuntimeCandidateSourceBunGlobal}; !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("sources = %#v, want %#v", got, want)
|
|
}
|
|
}
|
|
|
|
func concurrentManagerFixture(markerDir, markerName, resultCommand string) string {
|
|
return `#!/bin/sh
|
|
marker_dir=` + strconv.Quote(markerDir) + `
|
|
touch "$marker_dir/` + markerName + `"
|
|
attempt=0
|
|
while [ ! -f "$marker_dir/bun" ] ||
|
|
[ ! -f "$marker_dir/pnpm" ] ||
|
|
[ ! -f "$marker_dir/npm" ] ||
|
|
[ ! -f "$marker_dir/brew" ]; do
|
|
attempt=$((attempt + 1))
|
|
if [ "$attempt" -ge 100 ]; then
|
|
exit 1
|
|
fi
|
|
sleep 0.02
|
|
done
|
|
` + resultCommand + `
|
|
`
|
|
}
|
|
|
|
func candidateLaunchers(candidates []codexRuntimeCandidate) []string {
|
|
result := make([]string, 0, len(candidates))
|
|
for _, candidate := range candidates {
|
|
result = append(result, candidate.LauncherPath)
|
|
}
|
|
return result
|
|
}
|