Files

117 lines
5.0 KiB
Go

package preflight
import (
"io/fs"
"strings"
"testing"
"testing/fstest"
"server-deploy/internal/inspect"
)
func hostFiles() fstest.MapFS {
return fstest.MapFS{
"etc/os-release": {Data: []byte("ID=ubuntu\nVERSION_ID=\"26.04\"\nVERSION_CODENAME=resolute\n")},
"var/lib/dpkg/status": {Data: []byte("Package: base-files\nStatus: install ok installed\nArchitecture: amd64\nVersion: 1.0\n")},
"var/lib/dpkg/updates": {Mode: fs.ModeDir | 0700},
}
}
func TestPackageStateBlocksFreshInstallCandidates(t *testing.T) {
for _, state := range []string{"install ok installed", "deinstall ok config-files", "install reinstreq half-installed"} {
files := hostFiles()
files["var/lib/dpkg/status"].Data = []byte("Package: containerd\nStatus: " + state + "\nArchitecture: amd64\nVersion: 1.2.3\n")
p := Plan(Probe(baseline(), files, 0, Disk{State: "observed", AvailableBytes: 20 << 30}))
if len(p.ProposedChanges) != 0 || !contains(p.Blockers, "existing_packages_require_review") {
t.Errorf("existing package state %s overlooked", state)
}
}
files := hostFiles()
delete(files, "var/lib/dpkg/status")
if p := Plan(Probe(baseline(), files, 0, Disk{State: "observed", AvailableBytes: 20 << 30})); len(p.ProposedChanges) != 0 {
t.Fatal("unknown inventory treated as empty")
}
}
func baseline() inspect.Report {
return inspect.Report{ProtocolVersion: 1, OS: "linux", Architecture: "amd64", SystemdRuntime: "present", DockerClient: "missing"}
}
func TestHostFactsAndNonExecutableProposal(t *testing.T) {
r := Probe(baseline(), hostFiles(), 0, Disk{State: "observed", AvailableBytes: 20 << 30})
if r.Distribution.ID != "ubuntu" || r.Distribution.Version != "26.04" || r.Distribution.State != "observed" || r.Privilege != "root" {
t.Fatalf("incorrect host facts: %+v", r)
}
p := Plan(r)
if p.Executable || len(p.ProposedChanges) == 0 || !contains(p.Blockers, "package_versions_unresolved") || !contains(p.Blockers, "host_identity_unverified") {
t.Fatalf("unsafe proposal: %+v", p)
}
}
func TestExistingResourcesNeverProposeFreshInstall(t *testing.T) {
for _, path := range []string{"var/lib/docker", "var/lib/containerd", "etc/docker", "var/lib/server-deploy", "etc/apt/sources.list.d/docker.sources", "etc/apt/sources.list.d/docker.list"} {
files := hostFiles()
files[path] = &fstest.MapFile{Mode: fs.ModeDir | 0700}
p := Plan(Probe(baseline(), files, 0, Disk{State: "observed", AvailableBytes: 20 << 30}))
if len(p.ProposedChanges) != 0 || !contains(p.Blockers, "existing_resources_require_review") {
t.Errorf("fresh install proposed over %s", path)
}
}
runtime := baseline()
runtime.DockerClient = "present"
if p := Plan(Probe(runtime, hostFiles(), 0, Disk{State: "observed", AvailableBytes: 20 << 30})); len(p.ProposedChanges) != 0 {
t.Fatal("existing Docker overlooked")
}
}
func TestUnknownAndInsufficientHostFailsClosed(t *testing.T) {
for _, tc := range []struct {
name string
runtime inspect.Report
uid int
disk Disk
blocker string
}{
{"nonroot", baseline(), 1000, Disk{State: "observed", AvailableBytes: 20 << 30}, "root_required"},
{"disk unknown", baseline(), 0, Disk{State: "unknown"}, "disk_unverified"},
{"disk low", baseline(), 0, Disk{State: "observed", AvailableBytes: 1}, "disk_below_bootstrap_floor"},
{"unsupported", inspect.Report{OS: "windows", Architecture: "amd64"}, 0, Disk{}, "unsupported_platform"},
} {
t.Run(tc.name, func(t *testing.T) {
p := Plan(Probe(tc.runtime, hostFiles(), tc.uid, tc.disk))
if !contains(p.Blockers, tc.blocker) || p.Executable || len(p.ProposedChanges) != 0 {
t.Fatalf("unsafe proposal: %+v", p)
}
})
}
}
func TestOSReleaseRejectsAmbiguityAndNeverEvaluatesShell(t *testing.T) {
for _, content := range []string{"ID=ubuntu\nID=debian\nVERSION_ID=26.04\nVERSION_CODENAME=resolute", "ID=$(touch secret)\nVERSION_ID=26.04\nVERSION_CODENAME=resolute", "ID=ubuntu\nVERSION_ID=\"26.04\nVERSION_CODENAME=resolute", strings.Repeat("#", 65537)} {
files := hostFiles()
files["etc/os-release"].Data = []byte(content)
p := Plan(Probe(baseline(), files, 0, Disk{State: "observed", AvailableBytes: 20 << 30}))
if len(p.ProposedChanges) != 0 || !contains(p.Blockers, "distribution_unverified") {
t.Fatal("ambiguous distribution accepted")
}
}
files := hostFiles()
files["etc/os-release"].Data = []byte("ID=ubuntu\nVERSION_ID=26.04\nVERSION_CODENAME=noble\n")
if p := Plan(Probe(baseline(), files, 0, Disk{State: "observed", AvailableBytes: 20 << 30})); !contains(p.Blockers, "unsupported_distribution") {
t.Fatal("mismatched suite accepted")
}
}
type deniedFS struct{}
func (deniedFS) Open(string) (fs.File, error) { return nil, fs.ErrPermission }
func TestAccessFailuresAreNotAbsence(t *testing.T) {
r := Probe(baseline(), deniedFS{}, 0, Disk{State: "observed", AvailableBytes: 20 << 30})
if r.Distribution.State != "unknown" || r.Resources[0].State != "unknown" || len(Plan(r).ProposedChanges) != 0 {
t.Fatal("permission failure treated as clean host")
}
}
func contains(values []string, want string) bool {
for _, v := range values {
if v == want {
return true
}
}
return false
}