Files
mesh-controller/cmd/mesh-controller/board_test.go
T
jschoubben c3b88b9148 Rename mesh-control -> mesh-controller, substrate -> foundation
One name per thing, per the HQ glossary: the module/container/image/binary/repo
becomes mesh-controller, the seat the-controller, and the store+broker pair the
foundation (embedded base bundles, default template and example lock renamed with
their go:embed directives). No behaviour change — a pure vocabulary rename.

Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
2026-09-16 18:40:40 +02:00

155 lines
6.3 KiB
Go

package main
import (
"strings"
"testing"
"time"
"github.com/novox/mesh-controller/internal/inventory"
)
// Refused and failed stay distinct all the way to the page.
//
// **Refused means the machine is exactly as it was and what is wrong is in what was sent; failed
// means it is in a state nobody declared and what is wrong is on the machine.** They are fixed in
// different places, so a page saying "error" for both sends half its readers to the wrong one.
func TestRefusedAndFailedReachThePageAsDifferentThings(t *testing.T) {
rendered := render(t, viewOf(answers{
nodes: []inventory.Node{{Name: "anchor"}, {Name: "laptop"}},
wrong: []inventory.Doing{
{Node: "anchor", Outcome: "refused", Refused: "not a declaration this host speaks",
At: time.Now()},
{Node: "laptop", Outcome: "failed", At: time.Now(),
Failed: []inventory.FailedResource{{ID: "web.container", Error: "no such image"}}},
},
}))
// The rendered outcome, not the word anywhere on the page: both words appear in the
// stylesheet, so a plain Contains passes whatever the machine actually said. It did.
for _, want := range []string{`<span class="outcome refused">refused</span>`,
`<span class="outcome failed">failed</span>`} {
if !strings.Contains(rendered, want) {
t.Fatalf("the page does not distinguish the two — missing %s:\n%s", want, rendered)
}
}
// And the host's own words, which say exactly what it could not accept.
for _, want := range []string{"not a declaration this host speaks", "web.container", "no such image"} {
if !strings.Contains(rendered, want) {
t.Fatalf("the page does not say %q, so a reader must go and ask:\n%s", want, rendered)
}
}
}
// Nothing wrong is said, not left blank. An empty page and a well mesh must not look alike.
func TestAWellMeshSaysSoRatherThanShowingNothing(t *testing.T) {
rendered := render(t, viewOf(answers{nodes: []inventory.Node{{Name: "anchor"}}}))
for _, want := range []string{
"Every machine is doing what it was told",
"Every machine has been heard from",
"Every module is what its source last had",
} {
if !strings.Contains(rendered, want) {
t.Fatalf("a well mesh does not say %q:\n%s", want, rendered)
}
}
}
// A board that cannot reach the mesh must not render an empty page: that says "nothing is wrong"
// in the one situation where nobody can know it.
func TestABoardThatCannotReadTheMeshSaysSo(t *testing.T) {
rendered := render(t, view{Unreachable: "the store did not answer"})
if !strings.Contains(rendered, "the store did not answer") {
t.Fatalf("the reason is not on the page:\n%s", rendered)
}
if strings.Contains(rendered, "Every machine is doing what it was told") {
t.Fatal("a board that could not read the mesh reported that the mesh is well")
}
}
// Quiet is not broken, and the page says which it is.
func TestQuietIsNotReportedAsBroken(t *testing.T) {
rendered := render(t, viewOf(answers{
nodes: []inventory.Node{{Name: "laptop"}},
quiet: []inventory.Node{{Name: "laptop"}},
}))
if !strings.Contains(rendered, "not the same as tried and could not") {
t.Fatalf("the page does not separate quiet from broken:\n%s", rendered)
}
if !strings.Contains(rendered, "Every machine is doing what it was told") {
t.Fatalf("a quiet machine was counted as broken:\n%s", rendered)
}
}
// The page renders what a machine said, and a hostile string in it is not markup.
//
// What is on this page comes from machines, and a machine's own words are the whole reason the
// page is useful. They are also the one thing here that nobody in this repository wrote.
func TestWhatAMachineSaidIsNotMarkup(t *testing.T) {
rendered := render(t, viewOf(answers{
nodes: []inventory.Node{{Name: "anchor"}},
wrong: []inventory.Doing{{Node: "anchor", Outcome: "refused",
Refused: `<script>alert("from the machine")</script>`, At: time.Now()}},
}))
if strings.Contains(rendered, "<script>alert") {
t.Fatalf("a machine's words were rendered as markup:\n%s", rendered)
}
if !strings.Contains(rendered, "&lt;script&gt;") {
t.Fatalf("the words were not shown at all, so the reader cannot see what it said:\n%s", rendered)
}
}
// A module behind its source names the machines running the old one — the part with consequences.
func TestBeingBehindNamesTheMachinesRunningTheOldOne(t *testing.T) {
rendered := render(t, viewOf(answers{
nodes: []inventory.Node{{Name: "laptop"}},
behind: map[string][]string{"web": {"laptop"}},
sources: map[string]inventory.Source{"web": {BuiltFrom: "aaaaaaaaaa", Head: "bbbbbbbbbb"}},
}))
for _, want := range []string{"web", "aaaaaaaa", "bbbbbbbb", "running on laptop"} {
if !strings.Contains(rendered, want) {
t.Fatalf("the page does not say %q:\n%s", want, rendered)
}
}
}
func render(t *testing.T, v view) string {
t.Helper()
var out strings.Builder
if err := page.Execute(&out, v); err != nil {
t.Fatal(err)
}
return out.String()
}
// The board and the command must answer the same question the same way.
//
// A machine not running what the mesh would send it was added to `status` and would have been
// missing here — which is the one thing this page's design forbids: two answers to the same
// question, disagreeing, with a person in front of each.
func TestTheBoardSaysWhichMachinesHaveNotBeenSentWhatTheyShouldBe(t *testing.T) {
rendered := render(t, viewOf(answers{
nodes: []inventory.Node{{Name: "anchor"}, {Name: "laptop"}},
waiting: []inventory.Machine{
{Node: "anchor"},
{Node: "laptop", Never: true},
},
}))
if !strings.Contains(rendered, "is not running what the mesh would send it") {
t.Fatalf("the page does not say a machine is out of date:\n%s", rendered)
}
// Never told is a different situation with the same remedy, and the page keeps them apart.
if !strings.Contains(rendered, "has never been sent anything") {
t.Fatalf("the page does not separate never told from out of date:\n%s", rendered)
}
if !strings.Contains(rendered, "push --behind") {
t.Fatalf("the page does not say what sends them:\n%s", rendered)
}
}
// And says so when there is nothing waiting, rather than leaving the question unanswered.
func TestAMeshWithNothingWaitingSaysSo(t *testing.T) {
rendered := render(t, viewOf(answers{nodes: []inventory.Node{{Name: "anchor"}}}))
if !strings.Contains(rendered, "Every machine is running what the mesh would send it") {
t.Fatalf("the page leaves the question unanswered:\n%s", rendered)
}
}