package obs
import (
"os"
"path/filepath"
"testing"
)
// Under systemd the forge runs in a child of its unit, and the unit's
// MemoryMax is on the parent. The limit that binds is the tightest one
// on the way to the root, and "current" is read where that limit is.
func TestTheMemoryLimitIsFoundOnAnAncestor(t *testing.T) {
root := t.TempDir()
unit := filepath.Join(root, "system.slice", "forge.service")
leaf := filepath.Join(unit, "main")
if err := os.MkdirAll(leaf, 0o755); err != nil {
t.Fatal(err)
}
write := func(dir, name, v string) {
if err := os.WriteFile(filepath.Join(dir, name), []byte(v+"\n"), 0o644); err != nil {
t.Fatal(err)
}
}
write(leaf, "memory.max", "max")
write(leaf, "memory.current", "100")
write(unit, "memory.max", "11811160064")
write(unit, "memory.current", "7000")
write(filepath.Join(root, "system.slice"), "memory.max", "max")
b := cgroupLimitFrom(leaf, root)
if b.max != 11811160064 || b.dir != unit {
t.Errorf("FAIL: limit %d at %q, want the unit's", b.max, b.dir)
}
if got := b.current(); got != 7000 {
t.Errorf("FAIL: current %d, want the bounded cgroup's 7000", got)
}
// A tighter limit nearer the process wins.
write(leaf, "memory.max", "4294967296")
if b := cgroupLimitFrom(leaf, root); b.max != 4294967296 || b.dir != leaf {
t.Errorf("FAIL: limit %d at %q, want the leaf's tighter one", b.max, b.dir)
}
// No limit anywhere, and no cgroup at all, read as none.
write(leaf, "memory.max", "max")
write(unit, "memory.max", "max")
if b := cgroupLimitFrom(leaf, root); b.max != 0 {
t.Errorf("FAIL: limit %d where every level says max", b.max)
}
if b := cgroupLimitFrom("", root); b.max != 0 || b.dir != "" {
t.Errorf("FAIL: a process with no cgroup has a bound: %+v", b)
}
if !t.Failed() {
t.Log("ok")
}
}