package main import ( "context" "encoding/base64" "encoding/json" "strings" "testing" "time" "github.com/nats-io/nats.go" "github.com/novox/mesh-controller/internal/inventory" "github.com/novox/mesh-controller/internal/link" "github.com/novox/mesh-controller/internal/testbus" ) // echoEnvironment makes the test binary, run as a command line, say the verb and caller it was given (TestMain). const echoEnvironment = "MESH_TEST_ECHO_ENVIRONMENT" var cliNodes = []inventory.Node{ {Name: "control", Account: "operator"}, {Name: "laptop", Account: "operator"}, {Name: "unnamed"}, } func cliAsked(account string, uid uint32, line ...string) link.CLIAsked { return link.CLIAsked{Line: line, Account: account, UID: uid, Session: "session-1.scope"} } // Who is the controller's terminal, and who is an ordinary call or refused (novox/hq ADR 0272 §4). func TestMeshCLIIsTheTerminalOnlyForTheControlNodesOperator(t *testing.T) { control := []string{"control"} cases := []struct { name, node string asked link.CLIAsked control []string terminal bool refused string why string }{ {"the control-node's operator", "control", cliAsked("operator", 1000, "status"), control, true, "", "the controller's terminal"}, {"another node's operator", "laptop", cliAsked("operator", 1000, "status"), control, false, "", "agents on laptop may run as operator"}, {"another account", "control", cliAsked("agent", 1001, "status"), control, false, "operator account (operator) only", ""}, {"root", "control", cliAsked("root", 0, "status"), control, false, "never root", ""}, {"a node with no operator account", "unnamed", cliAsked("operator", 1000, "status"), control, false, "does not know unnamed's operator account", ""}, {"a node the mesh does not know", "elsewhere", cliAsked("operator", 1000, "status"), control, false, "not a node this mesh knows", ""}, {"two control-nodes", "control", cliAsked("operator", 1000, "status"), []string{"control", "laptop"}, false, "", "2 control-nodes"}, } for _, c := range cases { v := judgeCLI(c.node, c.asked, cliNodes, c.control) if v.terminal != c.terminal { t.Errorf("%s: terminal %v, want %v (%+v)", c.name, v.terminal, c.terminal, v) } if c.refused == "" && v.refused != "" || c.refused != "" && !strings.Contains(v.refused, c.refused) { t.Errorf("%s: refused %q, want %q", c.name, v.refused, c.refused) } if c.why != "" && !strings.Contains(v.why, c.why) { t.Errorf("%s: why %q, want %q", c.name, v.why, c.why) } } } // The terminal runs its line without MESH_VERB, even where this process carries one; an ordinary call names // mesh-cli; both record who asked through mesh-cli. func TestTheTerminalRunsWithoutAVerbAndAnOrdinaryCallNamesMeshCLI(t *testing.T) { t.Setenv(echoEnvironment, "1") t.Setenv("MESH_VERB", "leaked-from-the-serving-process") // The serving controller marks itself (ADR 0266); its terminal line for mesh-cli is still the terminal's. t.Setenv(servedVar, "1") ctx := context.Background() a := runForMeshCLI(ctx, "control", cliAsked("operator", 1000, "status"), cliVerdict{terminal: true, why: "the terminal"}) if a.Exit != 0 || a.Refused != "" || !a.Terminal { t.Fatalf("the terminal's line did not run: %+v", a) } if got := string(a.Stdout); !strings.Contains(got, `verb=""`) || !strings.Contains(got, "operator through mesh-cli on control") || !strings.Contains(got, "terminal=true") { t.Fatalf("the terminal's line ran with %s", got) } a = runForMeshCLI(ctx, "laptop", cliAsked("operator", 1000, "status"), cliVerdict{why: "not the terminal"}) if a.Exit != 0 || a.Terminal || a.Why != "not the terminal" { t.Fatalf("an ordinary line did not run as one: %+v", a) } if got := string(a.Stdout); !strings.Contains(got, `verb="mesh-cli"`) || !strings.Contains(got, "terminal=false") { t.Fatalf("an ordinary line ran with %s", got) } } // An ordinary call meets every refusal of the generic command verb, and nothing runs; a server is never run. func TestAnOrdinaryCallMeetsTheCommandVerbsRefusals(t *testing.T) { t.Setenv(echoEnvironment, "1") ctx := context.Background() ordinary := cliVerdict{why: "not the terminal"} a := runForMeshCLI(ctx, "laptop", cliAsked("operator", 1000, "cleanup", "delete", "x"), ordinary) if a.Refused == "" || len(a.Stdout) != 0 || a.Exit != 1 || a.Why != "not the terminal" { t.Fatalf("a repair without --why ran as an ordinary call: %+v", a) } a = runForMeshCLI(ctx, "laptop", cliAsked("operator", 1000, "settings", "set", "claude-code", "{}"), ordinary) if a.Refused != "" || !strings.Contains(string(a.Stdout), `verb="mesh-cli"`) { t.Fatalf("an ordinary settings set did not run through the settings verb's path with MESH_VERB set: %+v", a) } for _, server := range []string{"serve", "api", "board"} { a := runForMeshCLI(ctx, "control", cliAsked("operator", 1000, server), cliVerdict{terminal: true}) if a.Refused == "" || len(a.Stdout) != 0 { t.Fatalf("%s was run for mesh-cli: %+v", server, a) } } a = runForMeshCLI(ctx, "control", cliAsked("agent", 1001, "status"), cliVerdict{refused: "agent is not answered"}) if a.Refused != "agent is not answered" || len(a.Stdout) != 0 { t.Fatalf("a refused line ran: %+v", a) } } // **Which node is the terminal does not follow a verb** (review of ADR 0272): the controller's module is assigned // and unassigned at the terminal alone, so no caller of `assign` can move the terminal to a node of its choosing. // Asked through the acts themselves, as the verbs ask them; refused before any store is touched (none is given). func TestTheControllersModuleIsMovedAtTheTerminalAlone(t *testing.T) { t.Setenv("MESH_VERB", "assign") ctx := context.Background() if _, err := assignWith(ctx, nil, "laptop", assignOptions{}, "zsh", "mesh-controller"); err == nil || !strings.Contains(err.Error(), "terminal") { t.Fatalf("assigning the controller through a verb was not refused: %v", err) } if _, err := assign(ctx, nil, "laptop", "mesh-controller"); err == nil || !strings.Contains(err.Error(), "terminal") { t.Fatalf("assigning the controller through a verb was not refused: %v", err) } t.Setenv("MESH_VERB", "unassign") if _, err := unassign(ctx, nil, "control", "mesh-controller"); err == nil || !strings.Contains(err.Error(), "terminal") { t.Fatalf("unassigning the controller through a verb was not refused: %v", err) } // Another module through a verb, and the controller's at the terminal, are not refused for it. if err := refusedMovingTheController([]string{"zsh"}); err != nil { t.Fatalf("another module was refused: %v", err) } t.Setenv("MESH_VERB", "") if err := refusedMovingTheController([]string{"mesh-controller"}); err != nil { t.Fatalf("the terminal was refused: %v", err) } } // An ordinary `settings set|clear` goes down the settings verb's own path: composed as that verb composes it, and // run with MESH_VERB set, so its refusals — the terminal-only keys among them — are the settings command's own, // not a blanket refusal of the generic command (review of ADR 0272). func TestAnOrdinarySettingsLineTakesTheSettingsVerbsPath(t *testing.T) { cases := []struct { line []string want string err string }{ {[]string{"settings", "set", "zsh", `{"execute":"withhold"}`, "--node", "laptop"}, `settings set zsh {"execute":"withhold"} --node laptop`, ""}, {[]string{"settings", "set", "zsh", "{}", "--replace"}, "settings set zsh {} --replace", ""}, {[]string{"settings", "clear", "zsh", "--node", "laptop"}, "settings clear zsh --node laptop", ""}, {[]string{"settings", "show", "zsh", "--history"}, "settings show zsh --history", ""}, {[]string{"settings", "preferences"}, "settings preferences", ""}, {[]string{"settings", "set", "zsh"}, "", "settings"}, {[]string{"settings", "set", "zsh", "{}", "--sideways"}, "", "--sideways"}, } for _, c := range cases { argv, err := ordinaryLine(c.line) if c.err != "" { if err == nil || !strings.Contains(err.Error(), c.err) { t.Errorf("%q: refused with %v, want %q", c.line, err, c.err) } continue } if err != nil || strings.Join(argv, " ") != c.want { t.Errorf("%q: composed %q (%v), want %q", c.line, argv, err, c.want) } } // Anything else still meets the generic command verb's refusals. if _, err := ordinaryLine([]string{"retire", "delete", "x"}); err == nil { t.Error("a repair composed as an ordinary line") } } // Every line is said in the controller's journal, with its call, who asked where and how it ran — its command word // only, never the rest of the line (review of ADR 0272). func TestEveryMeshCLILineIsSaidInTheJournal(t *testing.T) { t.Setenv(echoEnvironment, "1") var said []string was := cliJournal cliJournal = func(line string) { said = append(said, line) } t.Cleanup(func() { cliJournal = was }) ctx := link.WithCallID(context.Background(), "call-1") runForMeshCLI(ctx, "control", cliAsked("operator", 1000, "settings", "set", "x", `{"password":"s3cret"}`), cliVerdict{terminal: true, why: "the terminal"}) runForMeshCLI(ctx, "control", cliAsked("agent", 1001, "status"), cliVerdict{refused: "agent is not answered"}) all := strings.Join(said, "\n") if len(said) != 2 || !strings.Contains(all, "call-1") || !strings.Contains(all, "operator on control") || !strings.Contains(all, "as the controller's terminal") || !strings.Contains(all, "refused") { t.Fatalf("the journal said %q", said) } if strings.Contains(all, "s3cret") { t.Fatalf("the journal carries the line's values: %q", said) } } // **An ordinary line runs only what the generic command verb would** (review of ADR 0272, ADR 0266): its reading // forms, and never a command that is the terminal's alone. Each of these, from another node's operator, is refused // and runs nothing. func TestAnOrdinaryLineRunsNothingTheCommandVerbWouldRefuse(t *testing.T) { t.Setenv(echoEnvironment, "1") for _, line := range [][]string{ {"node", "account", "control", "x"}, {"node", "agent-account", "control", "x", "--clear"}, {"token", "issue", "laptop"}, {"secret", "export", "x"}, {"operator", "key", "set", "x"}, {"assign", "laptop", "zsh"}, } { if _, err := ordinaryLine(line); err == nil { t.Errorf("%q composed as an ordinary line", line) } a := runForMeshCLI(context.Background(), "laptop", cliAsked("operator", 1000, line...), cliVerdict{why: "not the terminal"}) if a.Refused == "" || len(a.Stdout) != 0 { t.Errorf("%q ran as an ordinary line: %+v", line, a) } } if argv, err := ordinaryLine([]string{"status"}); err != nil || argv[0] != "status" { t.Fatalf("a read was refused: %v", err) } } // **`calls` never shows a mesh-cli line's answer** (review of ADR 0272): the verb's own answer is read for a line // served over a bus, and neither the answer's text nor the base64 JSON writes its bytes in is there. func TestTheCallsVerbNeverShowsAMeshCLILinesAnswer(t *testing.T) { conn, err := nats.Connect(testbus.URL(t)) if err != nil { t.Fatal(err) } defer conn.Close() stop, err := link.OverNATS{Conn: conn}.ServeCLI(func(context.Context, string, link.CLIAsked) link.CLIAnswer { return link.CLIAnswer{Stdout: []byte("s3cret-join")} }, nil) if err != nil { t.Fatal(err) } defer stop() body, _ := json.Marshal(link.CLIAsked{Line: []string{"token", "issue", "x"}, Account: "operator"}) msg, err := conn.Request(link.CLISubject("control"), body, 5*time.Second) if err != nil { t.Fatal(err) } if !strings.Contains(string(msg.Data), base64.StdEncoding.EncodeToString([]byte("s3cret-join"))) { t.Fatalf("the asker was not given its answer: %s", msg.Data) } recent, _ := link.Calls.Recent() var id string for _, c := range recent { if c.Seat == link.CLISeat { id = c.ID break } } shown, err := callsAnswer(link.Calls, id) if err != nil { t.Fatal(err) } said, _ := json.Marshal(shown) if strings.Contains(string(said), "s3cret-join") || strings.Contains(string(said), base64.StdEncoding.EncodeToString([]byte("s3cret-join"))) { t.Fatalf("calls showed a mesh-cli line's answer: %s", said) } } // **Only the terminal's line carries the terminal's mark** (review of ADR 0272): a mark the serving controller's // environment holds — leaked, or set by anything — is stripped from every other command line it runs, a verb's and // an ordinary mesh-cli line alike, so neither reads as the terminal. func TestTheTerminalsMarkIsStrippedFromEveryOtherLine(t *testing.T) { t.Setenv(echoEnvironment, "1") t.Setenv(cliTerminalVar, "1") t.Setenv(servedVar, "1") for _, env := range [][]string{commandEnvironment("someone", "status", false)} { for _, kv := range env { if strings.HasPrefix(kv, cliTerminalVar+"=") { t.Fatalf("a verb's line carries the terminal's mark: %s", kv) } } } a := runForMeshCLI(context.Background(), "laptop", cliAsked("operator", 1000, "status"), cliVerdict{why: "not the terminal"}) if got := string(a.Stdout); !strings.Contains(got, "terminal=false") || !strings.Contains(got, `verb="mesh-cli"`) { t.Fatalf("an ordinary line with the mark in the serving environment ran as %s", got) } a = runForMeshCLI(context.Background(), "control", cliAsked("operator", 1000, "status"), cliVerdict{terminal: true}) if got := string(a.Stdout); !strings.Contains(got, "terminal=true") { t.Fatalf("the terminal's line ran as %s", got) } } // **Only a login session is the terminal** (review of ADR 0272): the operator's account on the control-node, asking // from a service — the tool runner, a user unit — and not a login session, is an ordinary call. func TestOnlyALoginSessionIsTheTerminal(t *testing.T) { control := []string{"control"} v := judgeCLI("control", link.CLIAsked{Line: []string{"status"}, Account: "operator", UID: 1000}, cliNodes, control) if v.terminal || v.refused != "" || !strings.Contains(v.why, "login session") { t.Fatalf("a line from no login session reads %+v", v) } v = judgeCLI("control", link.CLIAsked{Line: []string{"status"}, Account: "operator", UID: 1000, Session: "session-3.scope"}, cliNodes, control) if !v.terminal { t.Fatalf("a line from a login session on the control-node reads %+v", v) } }