package main import ( "context" "encoding/json" "strings" "testing" "time" "github.com/novox/mesh-controller/internal/broker" "github.com/novox/mesh-controller/internal/link" ) // consoleWaits is how long the console waits for an answer (mesh-tools node-tools/internal/bus // RequestTimeout) — the shortest wait of a caller the mesh ships. const consoleWaits = 30 * time.Second // **A call's one answer is never later than its caller or the bus allow** (novox/hq issue 265): a // holder answers within AnswerWithin, which must be inside both the console's wait and the window the // bus gives an answer. Before, the console waited 30s, the bus 60s, and a push ran as long as it ran. func TestAVerbAnswersInsideEveryWaitOnIt(t *testing.T) { if link.AnswerWithin >= consoleWaits/2 { t.Errorf("a call answers within %s: not well inside the console's %s", link.AnswerWithin, consoleWaits) } if link.AnswerWithin >= broker.ResponseTTL { t.Errorf("a call answers within %s, after the bus stops permitting an answer at %s", link.AnswerWithin, broker.ResponseTTL) } } // A push — named or through command — answers before it runs: it sends the machine holding the bus // first, and the broker reloading its user list forgets the answer it was about to permit. func TestAPushAnswersBeforeItSends(t *testing.T) { for _, c := range []struct { verb string args map[string]any want bool }{ {"push", map[string]any{"node": "anchor", "why": "w"}, true}, {"push", map[string]any{"why": "w"}, true}, {"command", map[string]any{"command": "push anchor --why w"}, true}, {"command", map[string]any{"command": "push --behind --why=w"}, true}, {"command", map[string]any{"command": "builds"}, false}, {"status", map[string]any{}, false}, {"assign", map[string]any{"node": "anchor", "module": "m"}, false}, } { argv, err := argvFor(c.verb, c.args) if err != nil { t.Fatalf("%s %v: %v", c.verb, c.args, err) } if got := answersFirst(argv); got != c.want { t.Errorf("%s %v answers first: %v, want %v", c.verb, c.args, got, c.want) } } } // `calls` is served, takes a call's id and nothing else, and says plainly when it holds no such call. func TestCallsIsServedAndSaysWhatItKeeps(t *testing.T) { handlers, behind, err := seatToolHandlers() if err != nil || len(behind) != 0 { t.Fatalf("%v %v", behind, err) } calls, ok := handlers["calls"] if !ok { t.Fatal("calls is not served") } if _, err := calls(context.Background(), json.RawMessage(`{"node":"anchor"}`)); err == nil || !strings.Contains(err.Error(), `"node"`) { t.Errorf("calls took an argument it does not declare: %v", err) } if _, err := calls(context.Background(), json.RawMessage(`{"call":"call-0-0"}`)); err == nil || !strings.Contains(err.Error(), "not across a restart") { t.Errorf("an unknown call was not said plainly: %v", err) } got, err := calls(context.Background(), json.RawMessage(`{}`)) if err != nil { t.Fatal(err) } if _, listed := got.(map[string]any)["calls"]; !listed { t.Errorf("calls answered %v", got) } }