mesh/merge-gate head 378e65780d0b merged into trunk 791b92c875d3 — pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every …
mesh/repo-check head 378e65780d0b merged into trunk 791b92c875d3 — pass: its merge-check.sh passed
mesh/delivery delivered
68 lines
2.7 KiB
Go
68 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/novox/mesh-controller/internal/inventory"
|
|
)
|
|
|
|
// A machine out of touch when a tier is sent is not sent to and not waited for (novox/hq ADR 0435 §1, issue 1161): the
|
|
// walk judges it with the silent check's one verdict, machineFacts.silent, and a sleeping machine is away once presence says so.
|
|
|
|
// 1161/AC1: away is the silent check's verdict; AC4: a machine heard is not away.
|
|
func TestAMachineIsAwayAsTheSilentCheckJudgesIt(t *testing.T) {
|
|
now := time.Now().UTC()
|
|
machines := []machineFacts{
|
|
{name: "heard", lastHeard: now.Add(-time.Minute)},
|
|
{name: "quiet", lastHeard: now.Add(-silentBound - time.Minute)},
|
|
{name: "stuck", lastHeard: now, presence: presenceSilent},
|
|
{name: "back", lastHeard: now.Add(-time.Hour), presence: presenceHeard},
|
|
{name: "new"},
|
|
}
|
|
got := awayOf(machines, now)
|
|
for node, want := range map[string]bool{"heard": false, "quiet": true, "stuck": true, "back": false,
|
|
"new": false} {
|
|
if got[node] != want {
|
|
t.Errorf("1161/AC1: %s away is %v; want %v (away: %v)", node, got[node], want, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 1161/AC1, AC2: the plan keeps the machines of the tier it passed as away, sorted and once.
|
|
func TestAPlanKeepsTheMachinesItPassedAsAway(t *testing.T) {
|
|
p := &inventory.Plan{}
|
|
away := map[string]bool{"g14": true, "ace": true}
|
|
rememberAway(p, []string{"anchor", "g14"}, away)
|
|
rememberAway(p, []string{"g14", "ace"}, away)
|
|
if !slices.Equal(p.Away, []string{"ace", "g14"}) {
|
|
t.Fatalf("1161/AC2: the plan keeps %v away; want ace, g14", p.Away)
|
|
}
|
|
}
|
|
|
|
// 1161/AC2: the plan says it, where its other passed machines are said.
|
|
func TestAPlanSaysTheMachinesItPassedAsAway(t *testing.T) {
|
|
say := awaySaying(inventory.Plan{Away: []string{"g14"}})
|
|
if !strings.Contains(say, "g14 was away: sent when it is heard again") {
|
|
t.Fatalf("1161/AC2: the plan says %q", say)
|
|
}
|
|
if got := awaySaying(inventory.Plan{}); got != "" {
|
|
t.Fatalf("1161/AC2: a plan that passed no machine says %q", got)
|
|
}
|
|
}
|
|
|
|
// 1161/AC1: the gate does not wait for a machine passed as away, unless a send reached it; AC4: a machine heard is waited for.
|
|
func TestAGateDoesNotWaitForAMachinePassedAsAway(t *testing.T) {
|
|
p := inventory.Plan{Away: []string{"g14"}}
|
|
none := &inventory.PlanModule{}
|
|
if got := runningHeard(p, []string{"anchor", "g14"}, none); !slices.Equal(got, []string{"anchor"}) {
|
|
t.Fatalf("1161/AC1: the gate waits on %v; want anchor alone", got)
|
|
}
|
|
sent := &inventory.PlanModule{Rest: map[string]inventory.SentDeclaration{"g14": {Digest: "d"}}}
|
|
if got := runningHeard(p, []string{"anchor", "g14"}, sent); !slices.Equal(got, []string{"anchor", "g14"}) {
|
|
t.Fatalf("1161/AC4: a machine a send reached is waited for: %v", got)
|
|
}
|
|
}
|