A pure copy of 30 test files and internal/beside/beside.go; they do not compile until the next commit rewrites their imports. Source: novox/mesh-controller 6c2a8d62100cb7d491f8eb9a623e1eeea5ec0de1, internal/catalogue and internal/beside.
99 lines
3.8 KiB
Go
99 lines
3.8 KiB
Go
package catalogue
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// novox/hq ADR 0223 part 3: a machine's names are one seat's. The `hosts` module holding
|
|
// `node-hosts-file` became `hostname` holding `node-hostname`, which writes /etc/hostname beside the
|
|
// machine's own lines in /etc/hosts. The seat was renamed (ADR 0122), so what claims the old name — a
|
|
// manifest registered before the rename — still holds the one seat.
|
|
|
|
func withHostnameAlias(t *testing.T) {
|
|
t.Helper()
|
|
was := aliases
|
|
t.Cleanup(func() { aliases = was })
|
|
UseAliases(map[string]string{"node-hosts-file": "node-hostname"})
|
|
}
|
|
|
|
func TestTheHostsFilesFormerNameResolvesToTheHostnameSeat(t *testing.T) {
|
|
if _, known := SeatNamed("node-hostname"); !known {
|
|
t.Fatal("node-hostname is not in the mesh's set")
|
|
}
|
|
withHostnameAlias(t)
|
|
seat, known := SeatNamed("node-hosts-file")
|
|
if !known || seat.Name != "node-hostname" || seat.Scope != ScopeNode {
|
|
t.Fatalf("the former name did not resolve: %+v %v", seat, known)
|
|
}
|
|
var verbs []string
|
|
for _, v := range seat.Serves {
|
|
verbs = append(verbs, v.Name)
|
|
}
|
|
if strings.Join(verbs, " ") != "entries add remove" {
|
|
t.Errorf("the renamed seat serves %v; its verbs are unchanged", verbs)
|
|
}
|
|
}
|
|
|
|
// One seat under either name: the module registered before the rename and the one after cannot both
|
|
// hold it on one machine.
|
|
func TestTheOldAndTheNewClaimantAreOneSeatOnAMachine(t *testing.T) {
|
|
withHostnameAlias(t)
|
|
cat := shelf(
|
|
mod("hosts", nil, nil, nil, Claim{Name: "node-hosts-file"}),
|
|
mod("hostname", nil, nil, nil, Claim{Name: "node-hostname"}),
|
|
)
|
|
_, err := Resolve(cat, []string{"hosts", "hostname"}, workstation(), World{})
|
|
if err == nil || !strings.Contains(err.Error(), "node-hostname") {
|
|
t.Errorf("hosts and hostname both held the machine's names on one machine: %v", err)
|
|
}
|
|
if _, err := Resolve(cat, []string{"hosts"}, workstation(), World{}); err != nil {
|
|
t.Errorf("a machine still assigned hosts under the old name does not resolve: %v", err)
|
|
}
|
|
}
|
|
|
|
// The catalogue's module: /etc/hostname is the operator's `hostname` setting. Without it the module is
|
|
// left out, naming the key — the mesh never renames a machine on its own — and a mesh-wide setting
|
|
// naming ${machine:name} gives every machine its mesh name.
|
|
func TestTheMachinesNameIsItsSetting(t *testing.T) {
|
|
cat := map[string]Manifest{"hostname": catalogueManifest(t, "hostname")}
|
|
got, err := Resolve(cat, []string{"hostname"}, Node{Name: "ace", At: "ace.internal"}, World{})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
machines := map[string]string{"ace.internal": "10.42.0.2"}
|
|
nameOf := func(settings SettingsBy) (string, string) {
|
|
t.Helper()
|
|
composed, err := got.Compose(Rendering{Names: machines, Machines: machines, Suffix: "internal",
|
|
Settings: settings})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if why := composed.LeftOut["hostname"]; why != "" {
|
|
return "", why
|
|
}
|
|
for _, r := range composed.Resources {
|
|
if r["path"] == "/etc/hostname" {
|
|
return r["content"].(string), ""
|
|
}
|
|
}
|
|
t.Fatal("no /etc/hostname composed")
|
|
return "", ""
|
|
}
|
|
|
|
if _, why := nameOf(nil); !strings.Contains(why, "hostname") {
|
|
t.Errorf("with no setting the machine's name was written, or left out for another reason: %q", why)
|
|
}
|
|
if name, why := nameOf(SettingsBy{"hostname": {{From: "ace", Values: map[string]any{"hostname": "Ace"}}}}); name != "Ace\n" {
|
|
t.Errorf("the operator's name for the machine gave %q (%s)", name, why)
|
|
}
|
|
mesh := Layer{From: "the mesh", Values: map[string]any{"hostname": "${machine:name}"}}
|
|
if name, why := nameOf(SettingsBy{"hostname": {mesh}}); name != "ace\n" {
|
|
t.Errorf("a mesh-wide ${machine:name} gave %q (%s)", name, why)
|
|
}
|
|
node := Layer{From: "ace", Values: map[string]any{"hostname": "Ace"}}
|
|
if name, why := nameOf(SettingsBy{"hostname": {mesh, node}}); name != "Ace\n" {
|
|
t.Errorf("a machine's own name over the mesh-wide one gave %q (%s)", name, why)
|
|
}
|
|
}
|