Files
mesh-catalog/modules/pacman/cmd/pacman-tools/dkms_test.go
T

116 lines
4.6 KiB
Go

package main
// The DKMS gate (novox/hq ADR 0508 §3; acceptance 1841/AC4). The META is captured from a machine whose ZFS
// module declares Linux-Maximum 7.2; the BUILD_EXCLUSIVE_KERNEL case is a made-up module's pattern.
import (
"os"
"strings"
"testing"
)
func TestTheNewKernelsReleaseIsDerivedAsTheInstalledOnesIs(t *testing.T) {
for _, c := range [][4]string{
{"7.2.8.arch1-2", "7.2.8-arch1-2", "7.3.1.arch1-1", "7.3.1-arch1-1"},
{"6.18.54-2", "6.18.54-2-lts", "6.18.60-1", "6.18.60-1-lts"},
} {
if got := NewRelease(c[0], c[1], c[2]); got != c[3] {
t.Errorf("%v: %s", c, got)
}
}
for release, past := range map[string]bool{"7.3.1-arch1-1": true, "7.2.9-arch1-1": false, "7.2-arch1-1": false, "8.0.1": true, "6.18.60-1-lts": false} {
if pastMaximum(release, "7.2") != past {
t.Errorf("%s past 7.2: want %v", release, past)
}
}
}
// gateMachine is a machine with the linux and LTS kernels and these DKMS modules' sources.
func gateMachine(t *testing.T, dkmsStatus string, sources map[string]string) *Machine {
files := func(paths ...string) Ran { return Ran{Stdout: strings.Join(paths, "\n") + "\n"} }
m := machine(byLine(map[string]Ran{
"pacman -Qlq -- linux": files("/usr/lib/modules/7.2.8-arch1-2/", "/usr/lib/modules/7.2.8-arch1-2/vmlinuz"),
"pacman -Qlq -- linux-headers": files("/usr/lib/modules/7.2.8-arch1-2/build/Makefile"),
"pacman -Qlq -- linux-lts": files("/usr/lib/modules/6.18.54-2-lts/vmlinuz"),
"pacman -Qlq -- linux-firmware": files("/usr/lib/firmware/amdgpu/"),
"dkms status": {Stdout: dkmsStatus},
}, nil), 1000)
m.ReadFile = func(path string) ([]byte, error) {
if s, ok := sources[path]; ok {
return []byte(s), nil
}
return nil, errNoFile
}
return m
}
func capturedZFSSource(t *testing.T) map[string]string {
out := map[string]string{}
for _, f := range []string{"META", "dkms.conf"} {
raw, err := os.ReadFile("testdata/dkms-zfs-linux-maximum-7.2/" + f)
if err != nil {
t.Fatal(err)
}
out["/usr/src/zfs-2.4.4/"+f] = string(raw)
}
return out
}
func gateUpgrades(t *testing.T, m *Machine, linuxTo string, reachable bool) *Upgrades {
updates := newBucket()
if _, err := updates.Put("node-a", UpdatesValue{Reachable: reachable, Packages: []VersionChange{
{Name: "bash", From: "5.3.15-1", To: "5.3.20-1"},
{Name: "linux", From: "7.2.8.arch1-2", To: linuxTo},
{Name: "linux-firmware", From: "20261001-1", To: "20261015-1"},
{Name: "linux-headers", From: "7.2.8.arch1-2", To: linuxTo},
{Name: "linux-lts", From: "6.18.54-2", To: "6.18.60-1"},
}}); err != nil {
t.Fatal(err)
}
return &Upgrades{Node: "node-a", Machine: m, Updates: updates}
}
const zfsStatus = "zfs/2.4.4, 7.2.8-arch1-2, x86_64: installed\nzfs/2.4.4, 6.18.54-2-lts, x86_64: installed\n"
func TestAKernelPastAModulesLinuxMaximumIsHeldWithItsHeaders(t *testing.T) {
u := gateUpgrades(t, gateMachine(t, zfsStatus, capturedZFSSource(t)), "7.3.1.arch1-1", true)
held, ignore, why := u.Gate()
if why != "" {
t.Fatal(why)
}
if len(held) != 1 || held[0] != (HeldKernel{Package: "linux", Version: "7.3.1.arch1-1", Module: "zfs/2.4.4", Bound: "Linux-Maximum: 7.2"}) {
t.Errorf("held: %+v", held)
}
if strings.Join(ignore, " ") != "linux linux-headers" {
t.Errorf("left out: %v (the LTS kernel stays within the bound and is upgraded)", ignore)
}
}
func TestAKernelWithinTheBoundIsNotHeld(t *testing.T) {
u := gateUpgrades(t, gateMachine(t, zfsStatus, capturedZFSSource(t)), "7.2.9.arch1-1", true)
if held, ignore, why := u.Gate(); why != "" || len(held) != 0 || len(ignore) != 0 {
t.Errorf("%+v %v %q", held, ignore, why)
}
}
func TestABuildExclusivePatternHoldsTheKernelsItDoesNotMatch(t *testing.T) {
src := map[string]string{"/usr/src/made-up-driver-1.0/dkms.conf": "PACKAGE_NAME=\"made-up-driver\"\nBUILD_EXCLUSIVE_KERNEL=\"^(6\\.|7\\.[0-2]\\.)\"\n"}
u := gateUpgrades(t, gateMachine(t, "made-up-driver/1.0, 7.2.8-arch1-2, x86_64: installed\n", src), "7.3.1.arch1-1", true)
held, ignore, why := u.Gate()
if why != "" || len(held) != 1 || held[0].Package != "linux" || held[0].Bound != `BUILD_EXCLUSIVE_KERNEL=^(6\.|7\.[0-2]\.)` ||
strings.Join(ignore, " ") != "linux linux-headers" {
t.Errorf("%+v %v %q", held, ignore, why)
}
}
func TestNoRunWhenWhatTheUpgradeWouldChangeIsNotKnown(t *testing.T) {
u := gateUpgrades(t, gateMachine(t, zfsStatus, capturedZFSSource(t)), "7.3.1.arch1-1", false)
if _, _, why := u.Gate(); !strings.Contains(why, "could not reach its mirrors") {
t.Errorf("unreachable: %q", why)
}
u.Updates = newBucket()
if _, _, why := u.Gate(); !strings.Contains(why, "not on the bus") {
t.Errorf("no updates key: %q", why)
}
}