A module is for any mesh; the check reads the list of names at the root and the covered modules, and the kernel module's fixtures now say what they show.
240 lines
8.7 KiB
Go
240 lines
8.7 KiB
Go
package main
|
|
|
|
// The module's shape (novox/hq issue 746): the setting's default is madvise, the value the mesh chose
|
|
// (ADR 0381), not what the kernel boots with; the script is written into the
|
|
// module's own state and run by a sandboxed oneshot unit that is reloaded (applied again) when the script,
|
|
// and so the setting, changes and restarted only when the unit does; and the script itself sets, verifies,
|
|
// gives back and refuses as it says.
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestTheDefaultIsMadviseAndTheUnitFollowsTheSetting(t *testing.T) {
|
|
m := manifest(t)
|
|
s := m.Config["transparent-huge-pages"]
|
|
if s["type"] != "string" || s["default"] != "madvise" || s["description"] == "" || s["trusted"] != true {
|
|
t.Fatalf("the setting: %v", s)
|
|
}
|
|
var ids []string
|
|
for _, r := range m.Resources {
|
|
ids = append(ids, r["id"].(string))
|
|
}
|
|
if strings.Join(ids, " ") != "state huge-pages unit apply" {
|
|
t.Fatalf("order: %v", ids)
|
|
}
|
|
script := m.resource(t, "huge-pages")
|
|
// The script runs as root, so the setting it is written from is set at the terminal alone (issue 339).
|
|
if script["path"] != "${dir:state}/huge-pages" || script["mode"] != "0755" || script["trusted"] != true ||
|
|
!strings.Contains(script.text(t), "want='${config:transparent-huge-pages}'") {
|
|
t.Fatalf("the script: %v", script["path"])
|
|
}
|
|
unit := m.resource(t, "unit").text(t)
|
|
for _, line := range []string{"Type=oneshot", "RemainAfterExit=yes", "ExecStart=${dir:state}/huge-pages apply",
|
|
"ExecReload=${dir:state}/huge-pages apply", "ExecStop=${dir:state}/huge-pages restore", "WantedBy=sysinit.target",
|
|
"DefaultDependencies=no", "ProtectSystem=strict", "ReadWritePaths=${dir:state}", "ProtectHome=yes", "PrivateNetwork=yes",
|
|
"NoNewPrivileges=yes"} {
|
|
if !strings.Contains(unit, line+"\n") {
|
|
t.Errorf("the unit lacks %q", line)
|
|
}
|
|
}
|
|
apply := m.resource(t, "apply")
|
|
if apply["unit"] != "mesh-kernel-huge-pages.service" || apply["state"] != "running" || apply["boot"] != "enabled" {
|
|
t.Fatalf("apply: %v", apply)
|
|
}
|
|
// A new value reloads (apply again); only a new unit restarts, whose stop would pass back through the
|
|
// mode the machine was found with.
|
|
if on := apply["restart-on"].([]any); len(on) != 1 || on[0] != "unit" {
|
|
t.Fatalf("restart-on: %v", on)
|
|
}
|
|
if on := apply["reload-on"].([]any); len(on) != 1 || on[0] != "huge-pages" {
|
|
t.Fatalf("reload-on: %v", on)
|
|
}
|
|
if h := apply["health"].(map[string]any); h["kind"] != "unit" {
|
|
t.Fatalf("health: %v", h)
|
|
}
|
|
}
|
|
|
|
// bed is the script as the mesh writes it for one value of the setting, a stand-in transparent_hugepage
|
|
// directory, the module's state, and a PATH whose journalctl records that it was asked to rotate.
|
|
type bed struct {
|
|
script, sys, state, rotated, path, bin string
|
|
}
|
|
|
|
func newBed(t *testing.T, want, found string) bed {
|
|
return newBedIn(t, t.TempDir(), want, found)
|
|
}
|
|
|
|
// newBedIn writes the script for want into dir; a second bed in the same dir shares the machine and the
|
|
// state, as a reload with a new value does.
|
|
func newBedIn(t *testing.T, dir, want, found string) bed {
|
|
t.Helper()
|
|
b := bed{script: filepath.Join(dir, "huge-pages"), sys: filepath.Join(dir, "thp"), state: filepath.Join(dir, "state"),
|
|
rotated: filepath.Join(dir, "rotated")}
|
|
content := manifest(t).resource(t, "huge-pages").text(t)
|
|
content = strings.ReplaceAll(content, "${config:transparent-huge-pages}", want)
|
|
content = strings.ReplaceAll(content, "${dir:state}", b.state)
|
|
if strings.Contains(content, "${") {
|
|
t.Fatalf("a substitution the test does not make is left in the script")
|
|
}
|
|
bin := filepath.Join(dir, "bin")
|
|
for _, d := range []string{b.sys, b.state, bin} {
|
|
if err := os.MkdirAll(d, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
write(t, b.script, content, 0o755)
|
|
if found != "" {
|
|
write(t, filepath.Join(b.sys, "enabled"), found, 0o644)
|
|
}
|
|
write(t, filepath.Join(bin, "journalctl"), "#!/bin/sh\necho \"$@\" >>"+b.rotated+"\n", 0o755)
|
|
b.bin = bin
|
|
b.booted(t, "running")
|
|
b.path = bin + string(os.PathListSeparator) + os.Getenv("PATH")
|
|
return b
|
|
}
|
|
|
|
// booted makes the service manager say state for is-system-running.
|
|
func (b bed) booted(t *testing.T, state string) {
|
|
t.Helper()
|
|
write(t, filepath.Join(b.bin, "systemctl"), "#!/bin/sh\n[ \"$1\" = is-system-running ] && echo "+state+"\n", 0o755)
|
|
}
|
|
|
|
func write(t *testing.T, p, content string, mode os.FileMode) {
|
|
t.Helper()
|
|
if err := os.WriteFile(p, []byte(content), mode); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func (b bed) run(t *testing.T, verb string) (string, error) {
|
|
t.Helper()
|
|
cmd := exec.Command("sh", b.script, verb, b.sys, b.state)
|
|
cmd.Env = append(os.Environ(), "PATH="+b.path)
|
|
out, err := cmd.CombinedOutput()
|
|
return string(out), err
|
|
}
|
|
|
|
func (b bed) file(t *testing.T, p string) string {
|
|
t.Helper()
|
|
raw, err := os.ReadFile(p)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return string(raw)
|
|
}
|
|
|
|
func TestApplySetsTheModeRotatesTheJournalOnceAndRestoreGivesBackWhatWasFound(t *testing.T) {
|
|
// a real machine's file on 2026-10-14, read through node-reads.
|
|
b := newBed(t, "madvise", "[always] madvise never\n")
|
|
out, err := b.run(t, "apply")
|
|
if err != nil || !strings.Contains(out, "always -> madvise") {
|
|
t.Fatalf("apply: %v %s", err, out)
|
|
}
|
|
if got := b.file(t, filepath.Join(b.sys, "enabled")); got != "madvise\n" {
|
|
t.Fatalf("written: %q", got)
|
|
}
|
|
if got := b.file(t, filepath.Join(b.state, "found")); got != "always\n" {
|
|
t.Fatalf("found: %q", got)
|
|
}
|
|
if got := b.file(t, b.rotated); got != "--rotate\n" {
|
|
t.Fatalf("rotation: %q", got)
|
|
}
|
|
// Applied again (a restart with the same value): nothing written, nothing rotated, found kept.
|
|
if out, err := b.run(t, "apply"); err != nil || !strings.Contains(out, "madvise, as set") {
|
|
t.Fatalf("again: %v %s", err, out)
|
|
}
|
|
if got := b.file(t, b.rotated); got != "--rotate\n" {
|
|
t.Fatalf("rotated again: %q", got)
|
|
}
|
|
if out, err := b.run(t, "restore"); err != nil || !strings.Contains(out, "back to always") {
|
|
t.Fatalf("restore: %v %s", err, out)
|
|
}
|
|
if got := b.file(t, filepath.Join(b.sys, "enabled")); got != "always\n" {
|
|
t.Fatalf("restored: %q", got)
|
|
}
|
|
// Nothing of the module is kept once it is stopped.
|
|
if _, err := os.Stat(filepath.Join(b.state, "found")); !os.IsNotExist(err) {
|
|
t.Fatalf("found kept after restore: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestAReloadWithANewValueGoesStraightThereAndNeverRewritesFound(t *testing.T) {
|
|
dir := t.TempDir()
|
|
b := newBedIn(t, dir, "madvise", "[always] madvise never\n")
|
|
if out, err := b.run(t, "apply"); err != nil {
|
|
t.Fatalf("apply: %v %s", err, out)
|
|
}
|
|
// The setting changes to never: the mesh rewrites the script and reloads the unit, which applies again.
|
|
n := newBedIn(t, dir, "never", "")
|
|
out, err := n.run(t, "apply")
|
|
if err != nil || !strings.Contains(out, "madvise -> never") {
|
|
t.Fatalf("reload: %v %s", err, out)
|
|
}
|
|
if got := n.file(t, filepath.Join(n.state, "found")); got != "always\n" {
|
|
t.Fatalf("found rewritten by a reload: %q", got)
|
|
}
|
|
}
|
|
|
|
func TestNoRotationWhileTheMachineIsStarting(t *testing.T) {
|
|
for _, state := range []string{"initializing", "starting"} {
|
|
b := newBed(t, "madvise", "[always] madvise never\n")
|
|
b.booted(t, state)
|
|
out, err := b.run(t, "apply")
|
|
if err != nil || !strings.Contains(out, "still starting") {
|
|
t.Fatalf("%s: %v %s", state, err, out)
|
|
}
|
|
if got := b.file(t, filepath.Join(b.sys, "enabled")); got != "madvise\n" {
|
|
t.Fatalf("%s: not set: %q", state, got)
|
|
}
|
|
if got := b.file(t, b.rotated); got != "" {
|
|
t.Fatalf("%s: rotated at boot: %q", state, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAlwaysIsSetWithoutRotating(t *testing.T) {
|
|
b := newBed(t, "always", "always [madvise] never\n")
|
|
if out, err := b.run(t, "apply"); err != nil || !strings.Contains(out, "madvise -> always") {
|
|
t.Fatalf("apply: %v %s", err, out)
|
|
}
|
|
if got := b.file(t, b.rotated); got != "" {
|
|
t.Fatalf("rotated for always: %q", got)
|
|
}
|
|
}
|
|
|
|
func TestAValueTheKernelDoesNotTakeIsRefusedBeforeAnythingIsWritten(t *testing.T) {
|
|
b := newBed(t, "sometimes", "[always] madvise never\n")
|
|
out, err := b.run(t, "apply")
|
|
if err == nil || !strings.Contains(out, "takes always, madvise or never") {
|
|
t.Fatalf("accepted: %v %s", err, out)
|
|
}
|
|
if got := b.file(t, filepath.Join(b.sys, "enabled")); got != "[always] madvise never\n" {
|
|
t.Fatalf("written anyway: %q", got)
|
|
}
|
|
}
|
|
|
|
func TestAWriteThatDoesNotTakeFailsTheUnit(t *testing.T) {
|
|
if os.Getuid() == 0 {
|
|
t.Skip("root writes a read-only file")
|
|
}
|
|
b := newBed(t, "madvise", "[always] madvise never\n")
|
|
if err := os.Chmod(filepath.Join(b.sys, "enabled"), 0o444); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if out, err := b.run(t, "apply"); err == nil {
|
|
t.Fatalf("a refused write passed: %s", out)
|
|
}
|
|
}
|
|
|
|
func TestAKernelWithoutHugePagesIsSaid(t *testing.T) {
|
|
b := newBed(t, "madvise", "")
|
|
if out, err := b.run(t, "apply"); err == nil || !strings.Contains(out, "built without transparent huge pages") {
|
|
t.Fatalf("%v %s", err, out)
|
|
}
|
|
}
|