package main import ( "context" "strings" "testing" "github.com/novox/mesh-controller/internal/link" ) // echoFails makes the echoing test binary end with a failure, as a read that failed would. const echoFails = "MESH_TEST_ECHO_FAILS" // journalled runs lines through runForMeshCLI and answers what the journal said, with a fresh count of read calls. func journalled(t *testing.T) *[]string { t.Helper() t.Setenv(echoEnvironment, "1") said := &[]string{} was, wasReads := cliJournal, cliReads cliJournal = func(line string) { *said = append(*said, line) } cliReads = &readCalls{} t.Cleanup(func() { cliJournal, cliReads = was, wasReads }) return said } // **A call that only reads writes no journal line; one that changes something does** (novox/hq issue 762). func TestAReadCallWritesNoJournalLine(t *testing.T) { said := journalled(t) ctx := link.WithCallID(context.Background(), "call-1") ordinary := cliVerdict{why: "not the terminal"} for _, line := range [][]string{{"plans"}, {"status"}, {"conditions"}, {"node", "list"}, {"builds"}, {"queue"}, {"settings", "show", "zsh"}, {"plans", "--json"}} { if a := runForMeshCLI(ctx, "g14", cliAsked("jochen", 1000, line...), ordinary); a.Exit != 0 || a.Refused != "" { t.Fatalf("%q did not run: %+v", line, a) } } runForMeshCLI(ctx, "control", cliAsked("jochen", 1000, "plans"), cliVerdict{terminal: true, why: "the terminal"}) if len(*said) != 0 { t.Fatalf("read calls wrote journal lines: %q", *said) } runForMeshCLI(ctx, "control", cliAsked("jochen", 1000, "assign", "g14", "zsh"), cliVerdict{terminal: true, why: "the terminal"}) if len(*said) != 1 || !strings.Contains((*said)[0], `asked "assign"`) { t.Fatalf("a call that changes something was not said: %q", *said) } } // **A refused or failed read keeps its line** (novox/hq issue 762). func TestAFailedOrRefusedReadIsSaid(t *testing.T) { said := journalled(t) runForMeshCLI(context.Background(), "g14", cliAsked("root", 0, "plans"), cliVerdict{refused: "root is not answered"}) t.Setenv(echoFails, "1") a := runForMeshCLI(context.Background(), "g14", cliAsked("jochen", 1000, "plans"), cliVerdict{why: "not the terminal"}) if a.Exit == 0 { t.Fatalf("the read did not fail: %+v", a) } if len(*said) != 2 || !strings.Contains((*said)[0], "refused") || !strings.Contains((*said)[1], "failed (exit 3)") { t.Fatalf("the journal said %q", *said) } if line := cliReads.said(readCallsEvery); line != "" { t.Fatalf("a failed read was counted as a read: %q", line) } } // **A verb is classed by what the call does, not its name** (novox/hq issue 762): the same command word reads with // some arguments and writes with others, and a line no reading form names is said. func TestAVerbIsClassedByItsArguments(t *testing.T) { ordinary := cliVerdict{why: "not the terminal"} for _, c := range []struct { line []string reads bool }{ {[]string{"settings", "show", "zsh"}, true}, {[]string{"settings", "preferences"}, true}, {[]string{"settings", "set", "zsh", `{"a":1}`}, false}, {[]string{"settings", "clear", "zsh"}, false}, {[]string{"plans"}, true}, {[]string{"plans", "p-1"}, true}, {[]string{"plans", "go", "p-1"}, false}, {[]string{"plans", "--json", "stop", "p-1"}, false}, {[]string{"plans", "close", "p-1"}, false}, {[]string{"plans", "retry", "p-1"}, false}, {[]string{"conditions"}, true}, {[]string{"conditions", "show", "x"}, true}, {[]string{"conditions", "silence", "x"}, false}, {[]string{"doctor", "run"}, false}, {[]string{"node", "account", "g14", "x"}, false}, {[]string{"assign", "g14", "zsh"}, false}, {[]string{"a-command-added-later"}, false}, {[]string{"serve"}, false}, } { if got := onlyReads(cliAsked("jochen", 1000, c.line...), ordinary); got != c.reads { t.Errorf("%q judged a read: %v, want %v", c.line, got, c.reads) } } if onlyReads(cliAsked("jochen", 1000, "plans"), cliVerdict{refused: "no"}) { t.Error("a refused line judged a read") } stdin := cliAsked("jochen", 1000, "status") stdin.Stdin = []byte("x") if onlyReads(stdin, cliVerdict{terminal: true}) { t.Error("a line carrying standard input judged a read") } } // **Once an hour the read calls are counted per caller, only if there were any** (novox/hq issue 762). func TestTheReadCallsAreCountedPerCaller(t *testing.T) { said := journalled(t) ordinary := cliVerdict{why: "not the terminal"} for range 3 { runForMeshCLI(context.Background(), "g14", cliAsked("jochen", 1000, "plans"), ordinary) } runForMeshCLI(context.Background(), "ace", cliAsked("jochen", 1000, "status"), ordinary) if len(*said) != 0 { t.Fatalf("read calls wrote lines: %q", *said) } line := cliReads.said(readCallsEvery) if !strings.Contains(line, "jochen on ace 1, jochen on g14 3") || !strings.Contains(line, "1h0m0s") { t.Fatalf("the hourly line said %q", line) } if again := cliReads.said(readCallsEvery); again != "" { t.Fatalf("an hour with no read calls said %q", again) } }