package main // The service manager's verbs over a fake runner (novox/hq ADR 0177, to-be 41 WP4), ported with the // TypeScript module's tests: which manager a call reaches and how, acts on the system manager escalated, // failures named rather than read as empty answers, whether the mesh declares a unit — and the system // journal read escalated (novox/hq issue 255). import ( "encoding/json" "errors" "os" "reflect" "strings" "testing" ) type call struct { cmd string args []string env []string } func fake(answer func(c call) Ran, calls *[]call) Runner { return func(cmd string, args []string, env []string) Ran { c := call{cmd, args, env} if calls != nil { *calls = append(*calls, c) } return answer(c) } } const ( list = "sshd.service loaded active running OpenSSH Daemon\nbroken.service loaded failed failed A broken thing\n" showMesh = "LoadState=loaded\nActiveState=active\nSubState=running\nUnitFileState=enabled\nMainPID=42\nExecMainStatus=0\nDescription=showcase, a mesh daemon\nFragmentPath=/etc/systemd/system/showcase.service\n" showPackage = "LoadState=loaded\nActiveState=active\nSubState=running\nUnitFileState=enabled\nMainPID=7\nExecMainStatus=0\nDescription=OpenSSH Daemon\nFragmentPath=/usr/lib/systemd/system/sshd.service\n" ) var files = map[string]string{ "/etc/systemd/system/showcase.service": MeshUnitHeader + " Do not edit — this file is replaced whenever the\n[Unit]\n", "/usr/lib/systemd/system/sshd.service": "[Unit]\nDescription=OpenSSH Daemon\n", } func read(p string) (string, error) { if s, ok := files[p]; ok { return s, nil } return "", errors.New("ENOENT") } func manager(run Runner, uid int, name string) *Manager { return &Manager{Account: "operator", UID: uid, User: name, Run: run, Read: read, Env: []string{"HOME=/h"}} } func operator(run Runner) *Manager { return manager(run, 1000, "operator") } func TestAnActAndASystemJournalReadGoThroughSudoUnlessRoot(t *testing.T) { for _, verb := range []string{"start", "stop", "restart", "enable", "disable"} { if p, _ := escalated("systemctl", []string{verb, "x.service"}, System, 1000); p != "sudo" { t.Errorf("%s was not escalated", verb) } } if p, a := escalated("systemctl", []string{"restart", "sshd.service"}, System, 1000); p != "sudo" || !reflect.DeepEqual(a, []string{"-n", "systemctl", "restart", "sshd.service"}) { t.Errorf("%s %v", p, a) } if p, _ := escalated("systemctl", []string{"restart", "sshd.service"}, System, 0); p != "systemctl" { t.Error("root escalated") } for _, args := range [][]string{{"show", "sshd.service"}, {"list-units", "restart"}} { if p, _ := escalated("systemctl", args, System, 1000); p != "systemctl" { t.Errorf("a read was escalated: %v", args) } } if p, _ := escalated("systemctl", []string{"--user", "restart", "x.service"}, User, 1000); p != "systemctl" { t.Error("the user scope was escalated") } // The system journal is read as root: unescalated, an account outside the journal's group sees only // its own entries and every service's journal reads empty (issue 255). if p, a := escalated("journalctl", []string{"-u", "x"}, System, 1000); p != "sudo" || a[1] != "journalctl" { t.Errorf("the system journal read was not escalated: %s %v", p, a) } if p, _ := escalated("journalctl", []string{"--user", "-u", "x"}, User, 1000); p != "journalctl" { t.Error("the account's own journal was escalated") } } func TestTheUserScopeIsPlainUserWithTheAccountsRuntimeDirectoryAndBus(t *testing.T) { var calls []call m := manager(fake(func(call) Ran { return Ran{Stdout: list} }, &calls), 1234, "operator") if _, err := m.Units(User, ""); err != nil { t.Fatal(err) } if calls[0].cmd != "systemctl" || calls[0].args[0] != "--user" { t.Fatalf("%+v", calls[0]) } env := strings.Join(calls[0].env, "\n") if !strings.Contains(env, "XDG_RUNTIME_DIR=/run/user/1234") || !strings.Contains(env, "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1234/bus") || !strings.Contains(env, "HOME=/h") { t.Fatalf("%v", calls[0].env) } if _, err := m.Journal(User, "watcher.service", 10); err != nil { t.Fatal(err) } if calls[1].cmd != "journalctl" || calls[1].args[0] != "--user" { t.Fatalf("%+v", calls[1]) } } func TestTheSystemScopeIsGivenNoSessionWords(t *testing.T) { var calls []call if _, err := operator(fake(func(call) Ran { return Ran{Stdout: list} }, &calls)).Units(System, ""); err != nil { t.Fatal(err) } if calls[0].env != nil { t.Fatalf("%v", calls[0].env) } for _, a := range calls[0].args { if a == "--user" { t.Fatal("--user in a system call") } } } func TestTheUserScopeFromAnotherAccountIsRefused(t *testing.T) { m := manager(fake(func(call) Ran { return Ran{Stdout: list} }, nil), 0, "root") if _, err := m.Units(User, ""); err == nil || !strings.Contains(err.Error(), "operator's service manager, and this runs as root") { t.Fatalf("%v", err) } } func TestASystemActEscalatesAndAnswersTheStateAfter(t *testing.T) { var calls []call m := operator(fake(func(c call) Ran { if contains(c.args, "show") { return Ran{Stdout: showPackage} } return Ran{} }, &calls)) r, err := m.Act(System, "restart", "sshd.service") if err != nil { t.Fatal(err) } if got := append([]string{calls[0].cmd}, calls[0].args...); !reflect.DeepEqual(got, []string{"sudo", "-n", "systemctl", "restart", "sshd.service"}) { t.Fatalf("%v", got) } if r["ok"] != true || r["active"] != "active" || r["mesh_declared"] != false || r["note"] != nil { t.Fatalf("%v", r) } } func TestTheRestoreNoteIsOnlyOnAUnitTheMeshDeclares(t *testing.T) { m := operator(fake(func(c call) Ran { if contains(c.args, "show") { return Ran{Stdout: showMesh} } return Ran{} }, nil)) r, _ := m.Act(System, "stop", "showcase.service") if r["mesh_declared"] != true || !strings.Contains(r["note"].(string), "host restores its declared state") { t.Fatalf("%v", r) } } func TestStatusSaysWhetherTheMeshDeclaresTheUnit(t *testing.T) { answer := func(s string) Runner { return fake(func(call) Ran { return Ran{Stdout: s} }, nil) } mesh, _ := operator(answer(showMesh)).Status(System, "showcase.service") pkg, _ := operator(answer(showPackage)).Status(System, "sshd.service") none, _ := operator(answer("LoadState=not-found\nFragmentPath=\n")).Status(System, "nope.service") if mesh["mesh_declared"] != true || mesh["MainPID"] != "42" || pkg["mesh_declared"] != false || none["mesh_declared"] != false { t.Fatalf("%v %v %v", mesh, pkg, none) } if MeshUnitHeader != "# Generated by the mesh." { t.Fatal("the header is not the one the host writes") } } func TestRefusalsAreNamed(t *testing.T) { refused := operator(fake(func(call) Ran { return Ran{Status: 1, Stderr: "sudo: a password is required\n"} }, nil)) if _, err := refused.Act(System, "start", "x.service"); err == nil || !strings.Contains(err.Error(), "may not run it without a prompt: sudo: a password is required") { t.Fatalf("%v", err) } missing := operator(fake(func(call) Ran { return Ran{Status: 127, Error: "ENOENT"} }, nil)) if _, err := missing.Act(System, "start", "x.service"); err == nil || !strings.Contains(err.Error(), "sudo is not installed here") { t.Fatalf("%v", err) } polkitRefused := manager(fake(func(call) Ran { return Ran{Status: 1, Stderr: "Failed to stop x.service: Access denied as the requested operation requires interactive authentication.\n"} }, nil), 0, "root") if _, err := polkitRefused.Act(System, "stop", "x.service"); err == nil || !strings.Contains(err.Error(), "the service manager refused the runtime's account") { t.Fatalf("%v", err) } failing := operator(fake(func(call) Ran { return Ran{Status: 1, Stderr: "Failed to list units: Connection timed out\n"} }, nil)) if _, err := failing.Units(System, ""); err == nil || !strings.Contains(err.Error(), "systemctl failed (1): Failed to list units: Connection timed out") { t.Fatalf("%v", err) } } func TestAnUnreachableUserManagerIsSaidEvenWhenSystemctlExitsZero(t *testing.T) { said := "Failed to connect to user scope bus via local transport: No such file or directory\n" m := operator(fake(func(call) Ran { return Ran{Stderr: said} }, nil)) if _, err := m.Units(User, ""); err == nil || !strings.Contains(err.Error(), "operator's own service manager does not answer at /run/user/1000") { t.Fatalf("%v", err) } nonzero := operator(fake(func(call) Ran { return Ran{Status: 1, Stderr: said} }, nil)) if _, err := nonzero.Status(User, "x.service"); err == nil || !strings.Contains(err.Error(), "does not answer") { t.Fatalf("%v", err) } } func TestFailedReportsEachManagerAndOneThatDoesNotAnswerByItsError(t *testing.T) { m := operator(fake(func(c call) Ran { if c.args[0] == "--user" { return Ran{Status: 1, Stderr: "Failed to connect to user scope bus via local transport: No such file or directory\n"} } return Ran{Stdout: list} }, nil)) r := m.Failed() system, _ := json.Marshal(r["system"]) if string(system) != `[{"unit":"broken.service","load":"loaded","active":"failed","sub":"failed","description":"A broken thing"}]` { t.Fatalf("%s", system) } if e, ok := r["user"].(map[string]string); !ok || !strings.Contains(e["error"], "does not answer") { t.Fatalf("%v", r["user"]) } } func TestAUnitsNameIsNeverAnOption(t *testing.T) { for _, bad := range []string{"--host=elsewhere", "a b", ""} { if unitArg(bad) == nil { t.Errorf("%q accepted", bad) } } var calls []call m := operator(fake(func(call) Ran { return Ran{Stdout: list} }, &calls)) if _, err := m.Act(System, "stop", "-H"); err == nil || len(calls) != 0 { t.Fatalf("an option ran as a unit: %v %d", err, len(calls)) } if _, err := m.Units(System, "-x*"); err != nil { t.Fatal(err) } if a := calls[0].args; a[len(a)-2] != "--" || a[len(a)-1] != "-x*" { t.Fatalf("%v", a) } } // The manifest owns the systemd package, claims the seat's eight verbs, and lists exactly the tools served. func TestTheManifestOwnsThePackageAndListsWhatIsServed(t *testing.T) { raw, err := os.ReadFile("../../module.json") if err != nil { t.Fatal(err) } var m struct { Capabilities []string `json:"capabilities"` Tools []string `json:"tools"` Claims []struct { Name string `json:"name"` Serves []string `json:"serves"` } `json:"claims"` Resources []struct { Type string `json:"type"` Package string `json:"package"` } `json:"resources"` } _ = json.Unmarshal(raw, &m) owns := false for _, r := range m.Resources { owns = owns || (r.Type == "package" && r.Package == "systemd") } if !owns || !contains(m.Capabilities, "package-manager") { t.Fatal("the manifest does not own the systemd package") } served := map[string]bool{} for _, tool := range tools(operator(nil)) { served[tool.Name] = true } want := map[string]bool{} for _, v := range m.Claims[0].Serves { want[seat+"."+v] = true } for _, n := range m.Tools { want[n] = true } if !reflect.DeepEqual(served, want) { t.Fatalf("served %v, the manifest says %v", served, want) } } func contains(list []string, s string) bool { for _, x := range list { if x == s { return true } } return false }