package host import ( "bytes" "log" "os" "path/filepath" "strings" "testing" "time" ) func TestSystemChannelDefaultsToStable(t *testing.T) { env := func(v string) func(string) string { return func(k string) string { if k == systemChannelEnv { return v } return "" } } for _, c := range []struct { name string set string want, wantBadCh string }{ {"unset", "", "stable", ""}, {"set", " canary ", "canary", ""}, {"a branch canary", "canary/paul", "canary/paul", ""}, // Not a channel: it would travel into a bucket key and an on-box // state file, so the box follows stable and says which value it // refused, rather than asking for a pointer nobody publishes. {"a path traversal", "../../etc", "stable", "../../etc"}, {"a word with a space", "not a channel", "stable", "not a channel"}, } { t.Run(c.name, func(t *testing.T) { got, bad := systemChannel(env(c.set)) if got != c.want || bad != c.wantBadCh { t.Fatalf("systemChannel(%q) = %q, %q; want %q, %q", c.set, got, bad, c.want, c.wantBadCh) } }) } } // The refused value is said ONCE, where the leg is armed — not on every one // of the two-second ticks that read the channel. func TestNewSystemLegSaysWhichChannelValueItRefused(t *testing.T) { var buf bytes.Buffer out, flags := log.Writer(), log.Flags() log.SetOutput(&buf) log.SetFlags(0) defer func() { log.SetOutput(out); log.SetFlags(flags) }() leg := newSystemLeg(nil, nil, func(k string) string { if k == systemChannelEnv { return "canary/too/deep" } return "" }, t.TempDir(), t.TempDir()) if leg.channel != "stable" { t.Fatalf("channel = %q, want stable", leg.channel) } said := strings.Count(buf.String(), "canary/too/deep") lines := len(strings.Split(strings.TrimSpace(buf.String()), "\n")) if said != 1 || lines != 1 { t.Fatalf("arming said the refused value %d times over %d lines:\n%s", said, lines, buf.String()) } } func TestSystemStateProbeReadsRootsResult(t *testing.T) { opt := t.TempDir() if got := systemStateProbe(opt); got != nil { t.Fatalf("no result.json → %+v, want nil", got) } root := systemRootDir(opt) os.MkdirAll(root, 0o755) at := time.Date(2026, 9, 6, 9, 0, 0, 0, time.UTC) writeJSONDurable(filepath.Join(root, "result.json"), systemResult{Channel: "stable", Version: "v3", PromotedAt: at, Outcome: "applied", At: at}, 0o644) got := systemStateProbe(opt) if got == nil || got.Version != "v3" || got.Outcome != "applied" || !got.PromotedAt.Equal(at) { t.Fatalf("probe = %+v", got) } }