The controller ended by its unassignment (issue 1126, ADR 0590), so no build is judged by the lease: the lease witness, its contract and the direct get the witness asked it with are removed, and its tests now prove each rollback path on the node tools' PING. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
66 lines
2.1 KiB
Go
66 lines
2.1 KiB
Go
package link
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/nats-io/nats.go"
|
|
)
|
|
|
|
// What a witness asks, asked of a real server with the grants the mesh composes (novox/hq to-be 45 §8):
|
|
// whether the PING works as the subject named, and whether a host without them
|
|
// is told apart — "cannot ask", never "the build did not answer". See testdata/witness-grants.conf.
|
|
func TestNatsWitnessAsksWhatItIsGranted(t *testing.T) {
|
|
url := os.Getenv("MESH_TEST_NATS_GRANTS")
|
|
if url == "" {
|
|
t.Skip("MESH_TEST_NATS_GRANTS unset")
|
|
}
|
|
dial := func(user, password, inbox string) *nats.Conn {
|
|
t.Helper()
|
|
conn, err := nats.Connect(url, nats.UserInfo(user, password), nats.CustomInboxPrefix(inbox))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(conn.Close)
|
|
return conn
|
|
}
|
|
anchor := &natsLink{conn: dial("node.anchor", "a", "_INBOX.node.anchor")}
|
|
bare := &natsLink{conn: dial("node.bare", "b", "_INBOX.node.bare")}
|
|
ask := func() (context.Context, context.CancelFunc) {
|
|
return context.WithTimeout(context.Background(), 2*time.Second)
|
|
}
|
|
|
|
// No runtime on the bus: not there to answer.
|
|
ctx, cancel := ask()
|
|
if err := anchor.Ping(ctx, "node-tools", "anchor"); !errors.Is(err, ErrNoAnswer) {
|
|
t.Fatalf("a PING nobody serves is %v, want no answer", err)
|
|
}
|
|
cancel()
|
|
// The runtime, answering as the services protocol does.
|
|
runtime := dial("runtime", "r", "_INBOX.runtime")
|
|
sub, err := runtime.Subscribe("$SRV.PING.node-tools.anchor", func(m *nats.Msg) {
|
|
_ = m.Respond([]byte(`{"type":"io.nats.micro.v1.ping_response","name":"node-tools","id":"anchor","version":"0.1.0"}`))
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() { _ = sub.Unsubscribe() })
|
|
if err := runtime.Flush(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ctx, cancel = ask()
|
|
if err := anchor.Ping(ctx, "node-tools", "anchor"); err != nil {
|
|
t.Fatalf("this machine's runtime answered and the witness heard %v", err)
|
|
}
|
|
cancel()
|
|
// And a host not granted the PING cannot ask, though the runtime is there.
|
|
ctx, cancel = ask()
|
|
if err := bare.Ping(ctx, "node-tools", "anchor"); !errors.Is(err, ErrCannotAsk) {
|
|
t.Fatalf("a host without the grant heard %v, want it unable to ask", err)
|
|
}
|
|
cancel()
|
|
}
|