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).
81 lines
2.0 KiB
Go
81 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
type resource map[string]any
|
|
|
|
type manifestShape struct {
|
|
Module string `json:"module"`
|
|
Version string `json:"version"`
|
|
Capabilities []string `json:"capabilities"`
|
|
Claims []map[string]any `json:"claims"`
|
|
Tools []string `json:"tools"`
|
|
Resources []resource `json:"resources"`
|
|
Build struct {
|
|
Artifacts []map[string]any `json:"artifacts"`
|
|
} `json:"build"`
|
|
}
|
|
|
|
func manifest(t *testing.T) manifestShape {
|
|
t.Helper()
|
|
raw, err := os.ReadFile("../../module.json")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var m manifestShape
|
|
if err := json.Unmarshal(raw, &m); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return m
|
|
}
|
|
|
|
func (m manifestShape) resource(t *testing.T, id string) resource {
|
|
t.Helper()
|
|
for _, r := range m.Resources {
|
|
if r["id"] == id {
|
|
return r
|
|
}
|
|
}
|
|
t.Fatalf("no resource %s", id)
|
|
return nil
|
|
}
|
|
|
|
// TestToolsAreTheManifests holds the served tools and the manifest's list to one another, and the
|
|
// bundle to the shape the builder compiles and the runtime loads.
|
|
func TestToolsAreTheManifests(t *testing.T) {
|
|
m := manifest(t)
|
|
names := map[string]bool{}
|
|
for _, tool := range tools(machine(nil, 1000)) {
|
|
if names[tool.Name] {
|
|
t.Errorf("%s is served twice", tool.Name)
|
|
}
|
|
names[tool.Name] = true
|
|
}
|
|
for _, want := range m.Tools {
|
|
if !names[want] {
|
|
t.Errorf("the manifest lists %s and the bundle does not serve it", want)
|
|
}
|
|
delete(names, want)
|
|
}
|
|
if len(names) != 0 {
|
|
t.Errorf("served and not listed: %v", names)
|
|
}
|
|
var tools map[string]any
|
|
for _, a := range m.Build.Artifacts {
|
|
if a["name"] == "tools" {
|
|
tools = a
|
|
}
|
|
}
|
|
if tools == nil || tools["kind"] != "bundle" || tools["language"] != "go" || tools["system"] != "arch" ||
|
|
tools["from"] != "cmd/"+binaryName || tools["binary"] != binaryName {
|
|
t.Fatalf("the tools artifact: %v", tools)
|
|
}
|
|
if loads, _ := tools["loads"].([]any); len(loads) != 1 || loads[0] != binaryName {
|
|
t.Fatalf("loads: %v", tools["loads"])
|
|
}
|
|
}
|