Files
mesh-catalog/modules/time-sync/cmd/time-sync-tools/manifest_test.go
T
jochen 21d8a7f6b4 time-sync: one time daemon, timesyncd, with its servers declared
Three machines ran timesyncd and one ran ntpd. The module declares
timesyncd running with a 50-mesh.conf drop-in (European pool) and ntp absent
(hq ADR 0180). A run-once step of its Go binary stops and disables ntpd first
and takes out only dangling wants-links, so removing the package leaves no
enabled unit pointing at nothing. A provider's drop-in sorting after the
mesh's still wins and is reported, not removed. Tools: time_sync_status,
_servers, _sync_now (to-be 42 Phase 1).
2026-10-04 12:50:20 +02:00

60 lines
2.1 KiB
Go

package main
// The module's shape (novox/hq to-be 42 Phase 1, research 027): its servers in a drop-in timesyncd
// reads, timesyncd running and enabled and restarted when they change, ntp absent (ADR 0180) — and
// the step that retires ntpd declared before the package goes and before timesyncd is started, so the
// host, which applies a module's resources in order, never removes a daemon that is still enabled.
import (
"strings"
"testing"
)
func TestTheOrderIsServersStepDaemonThenNtpAbsent(t *testing.T) {
m := manifest(t)
var ids []string
for _, r := range m.Resources {
ids = append(ids, r["id"].(string))
}
if strings.Join(ids, " ") != "servers retire-ntpd daemon ntp" {
t.Fatalf("order: %v", ids)
}
step := m.resource(t, "retire-ntpd")
if step["type"] != "process" || step["run-once"] != true || step["user"] != nil {
t.Fatalf("step: %v", step)
}
if run := step["run"].([]any); run[0] != "./"+binaryName || run[1] != "retire" || run[2] != "ntpd.service" {
t.Fatalf("run: %v", run)
}
daemon := m.resource(t, "daemon")
if daemon["unit"] != Daemon || daemon["state"] != "running" || daemon["boot"] != "enabled" {
t.Fatalf("daemon: %v", daemon)
}
if on := daemon["restart-on"].([]any); len(on) != 1 || on[0] != "servers" {
t.Fatalf("restart-on: %v", on)
}
if ntp := m.resource(t, "ntp"); ntp["package"] != "ntp" || ntp["absent"] != true {
t.Fatalf("ntp: %v", ntp)
}
}
func TestTheDropInSetsEuropeanServersAndTheDistributionsFallback(t *testing.T) {
f := manifest(t).resource(t, "servers")
if f["path"] != MeshDropIn {
t.Fatalf("path: %v", f["path"])
}
files := ParseCatConfig("# " + MeshDropIn + "\n" + f["content"].(string))
if len(files) != 1 || len(files[0].NTP) != 4 || len(files[0].FallbackNTP) != 4 {
t.Fatalf("%+v", files)
}
for _, s := range files[0].NTP {
if !strings.HasSuffix(s, ".europe.pool.ntp.org") {
t.Errorf("%s", s)
}
}
// A drop-in is read in name order; the mesh's must sort before a provider's own, which keeps it.
if !(strings.Compare("50-mesh.conf", "provider.conf") < 0) {
t.Fatal("the mesh's drop-in no longer sorts before a provider's")
}
}