package link import ( "context" "errors" "strings" "testing" "time" "git.novox.be/novox/mesh-sdk/go/busretry" "github.com/nats-io/nats.go" ) // A declared tool check asked over a real bus, through the queue, on the link the node-engine holds: // the tool's answer is read, and a tool nothing serves is said as such (novox/hq ADR 0240, to-be 48 ยง3). func TestNatsAToolCheckIsAskedOnTheLink(t *testing.T) { conn, js := aBus(t) const node = "toolcheck" served, err := conn.Subscribe(ToolSubject("sensors", "sensors_health", node), func(m *nats.Msg) { _ = m.Respond([]byte(`{"result":{"healthy":true}}`)) }) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = served.Unsubscribe() }) if err := conn.Flush(); err != nil { t.Fatal(err) } q := &Session{Membership: Membership{Node: node}} q.Attach(t.Context(), &natsLink{conn: conn, js: js, node: node}) ctx, cancel := context.WithTimeout(t.Context(), 2*time.Second) defer cancel() a, err := q.AskTool(ctx, "sensors", "sensors_health") if err != nil || !a.Healthy { t.Fatalf("a served healthy tool read as %+v (%v)", a, err) } _, err = q.AskTool(ctx, "sensors", "nothing_serves_this") if err == nil || !strings.Contains(err.Error(), "nothing on this machine answers") { t.Fatalf("a tool nothing serves read as %v", err) } // The bus's "no responders" is kept beside ErrNotAsked, so a reader that asks again while its request reached no one // (busretry.Undelivered) sees it (issue 1966: the seat list's first read fell into its holder's re-serve and was never // asked again). _, err = (&natsLink{conn: conn, js: js, node: node}).Ask(ctx, ToolSubject("sensors", "nothing_serves_this", node), nil) if !errors.Is(err, ErrNotAsked) || !errors.Is(err, nats.ErrNoResponders) || !busretry.Undelivered(err) { t.Fatalf("an ask nothing serves read as %v: want ErrNotAsked and the bus's no responders, undelivered", err) } }