Files
mesh-host/internal/witness/contract_test.go
T
jschoubben ff4dc71ce4 Witness the node tools alone: the controller's lease names no build any more
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
2026-11-02 11:22:21 +01:00

41 lines
1.5 KiB
Go

package witness
import (
"encoding/json"
"strings"
"testing"
"time"
"github.com/novox/mesh-host/internal/link"
)
// The contract, held (novox/hq to-be 45 §8).
// The runtime is asked by its own name and this machine's: only this machine's runtime can answer.
func TestTheRuntimeIsAskedByItsNameAndThisMachines(t *testing.T) {
if got := link.PingSubject(NodeToolsService, "anchor"); got != "$SRV.PING.node-tools.anchor" {
t.Fatalf("the host asks %s; the runtime answers $SRV.PING.node-tools.<node>", got)
}
}
// What is judged by default is the mesh's core process on every machine, by the name it is composed under, and
// nothing else: the controller ended (issue 1126), so its name is judged as any other.
func TestOnlyTheCoreProcessIsJudgedByDefault(t *testing.T) {
for name, want := range map[string]string{"mesh-controller": ByNone, "node-tools": ByPing, "greeter": ByNone} {
if got := Default(name); got != want {
t.Errorf("%s is judged by %q, want %q", name, got, want)
}
}
if NodeToolsWithin != 60*time.Second || PingWithin != 5*time.Second {
t.Fatal("the bounds are to-be 45 §8's: the runtime within sixty seconds, a PING answered within five")
}
}
// A verdict on the wire names its component as the controller's condition does.
func TestAVerdictNamesItsComponent(t *testing.T) {
raw, _ := json.Marshal(link.Rollback{Component: Component(ByPing), Outcome: link.RolledBack})
if !strings.Contains(string(raw), `"component":"node-tools"`) {
t.Fatalf("a verdict names its component as %s", raw)
}
}