Files
tutti/packages/agent/host/runtime_environment_test.go
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

95 lines
3.2 KiB
Go

package agenthost
import (
"reflect"
"strings"
"testing"
storesqlite "github.com/tutti-os/tutti/packages/agent/store-sqlite"
)
func TestAgentRailPlacementEnvironmentSuppliesCanonicalValuesLast(t *testing.T) {
env, err := withAgentRailPlacementEnvironment([]string{
"KEEP=value",
AgentCWDEnvironmentVariable + "=/stale",
"tutti_agent_cwd=/case-distinct-cwd",
AgentRailPlacementEnvironmentVariable + "={\"version\":1,\"kind\":\"conversations\",\"sectionKey\":\"conversations\"}",
"tutti_agent_rail_placement=case-distinct-placement",
AgentRailPlacementEnvironmentVariable + "=duplicate",
"TAIL=value",
}, "/workspace/app/pkg", &RailPlacement{
Version: 1, Kind: RailPlacementKindProject, ProjectPath: "/workspace/app",
SectionKey: "project:/ignored",
})
if err != nil {
t.Fatalf("withAgentRailPlacementEnvironment() error = %v", err)
}
if got := countEnvironmentKey(env, AgentCWDEnvironmentVariable); got != 1 {
t.Fatalf("cwd environment count = %d, env=%#v", got, env)
}
if got := countEnvironmentKey(env, AgentRailPlacementEnvironmentVariable); got != 1 {
t.Fatalf("rail environment count = %d, env=%#v", got, env)
}
cwd, _ := testEnvironmentValue(env, AgentCWDEnvironmentVariable)
if cwd != "/workspace/app/pkg" {
t.Fatalf("cwd environment = %q", cwd)
}
encoded, _ := testEnvironmentValue(env, AgentRailPlacementEnvironmentVariable)
placement, err := ParseAgentRailPlacementEnvironment(encoded)
if err != nil {
t.Fatalf("ParseAgentRailPlacementEnvironment() error = %v", err)
}
if placement.Kind != RailPlacementKindProject ||
placement.ProjectPath != storesqlite.NormalizeProjectPath("/workspace/app") ||
placement.SectionKey != storesqlite.RailSectionKeyForProject("/workspace/app") {
t.Fatalf("parsed placement = %#v", placement)
}
if keep, _ := testEnvironmentValue(env, "KEEP"); keep != "value" {
t.Fatalf("unrelated environment was not preserved: %#v", env)
}
want := []string{
"KEEP=value",
"tutti_agent_cwd=/case-distinct-cwd",
"tutti_agent_rail_placement=case-distinct-placement",
"TAIL=value",
AgentCWDEnvironmentVariable + "=/workspace/app/pkg",
AgentRailPlacementEnvironmentVariable + "=" + encoded,
}
if !reflect.DeepEqual(env, want) {
t.Fatalf("environment = %#v, want canonical values last after %#v", env, want)
}
}
func TestParseAgentRailPlacementEnvironmentRejectsUntrustedShapes(t *testing.T) {
for _, value := range []string{
"",
`{"version":2,"kind":"conversations","sectionKey":"conversations"}`,
`{"version":1,"kind":"conversations","sectionKey":"conversations","unknown":true}`,
`{"version":1,"kind":"conversations","sectionKey":"conversations"} {}`,
} {
if placement, err := ParseAgentRailPlacementEnvironment(value); err == nil {
t.Fatalf("ParseAgentRailPlacementEnvironment(%q) = %#v, want error", value, placement)
}
}
}
func countEnvironmentKey(env []string, key string) int {
count := 0
for _, entry := range env {
if strings.HasPrefix(entry, key+"=") {
count++
}
}
return count
}
func testEnvironmentValue(env []string, key string) (string, bool) {
prefix := key + "="
for _, entry := range env {
if strings.HasPrefix(entry, prefix) {
return strings.TrimPrefix(entry, prefix), true
}
}
return "", false
}