avahi: the discovery daemon declared, and why it hears nothing reported
On all four machines and owned by none. The module declares the package and the daemon. It leaves nsswitch.conf and nss-mdns as found — the hosts: line is one list every name source shares, and the host writes blocks, not line members — and opens nothing: the mesh's filter drops inbound UDP 5353 on every machine and `listens` has no local-link scope. avahi_status, _browse, _resolve and _services report both (to-be 42 Phase 1).
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// call is one command a fake runner was asked to run.
|
||||
type call struct {
|
||||
name string
|
||||
args []string
|
||||
}
|
||||
|
||||
func (c call) String() string {
|
||||
if len(c.args) == 0 {
|
||||
return c.name
|
||||
}
|
||||
return c.name + " " + strings.Join(c.args, " ")
|
||||
}
|
||||
|
||||
// fake is a runner answering by the command line it is given, recording every call.
|
||||
func fake(answer func(c call) Ran, calls *[]call) Runner {
|
||||
return func(_ context.Context, name string, args ...string) Ran {
|
||||
c := call{name, append([]string(nil), args...)}
|
||||
if calls != nil {
|
||||
*calls = append(*calls, c)
|
||||
}
|
||||
return answer(c)
|
||||
}
|
||||
}
|
||||
|
||||
// byLine answers from a table keyed by the whole command line, and refuses anything else as a
|
||||
// command the test did not expect.
|
||||
func byLine(table map[string]Ran, calls *[]call) Runner {
|
||||
return fake(func(c call) Ran {
|
||||
if r, ok := table[c.String()]; ok {
|
||||
return r
|
||||
}
|
||||
return Ran{Status: 99, Stderr: "unexpected command: " + c.String()}
|
||||
}, calls)
|
||||
}
|
||||
|
||||
func machine(run Runner, uid int) *Machine {
|
||||
return &Machine{Run: run, UID: uid, User: "operator", Account: "operator",
|
||||
ReadFile: func(string) ([]byte, error) { return nil, errNoFile },
|
||||
Now: func() time.Time { return time.Date(2026, 10, 4, 12, 0, 0, 0, time.UTC) },
|
||||
Sleep: func(time.Duration) {}}
|
||||
}
|
||||
|
||||
type noFile struct{}
|
||||
|
||||
func (noFile) Error() string { return "no such file" }
|
||||
|
||||
var errNoFile = noFile{}
|
||||
|
||||
func TestAnActNeedingRootGoesThroughSudoWithoutAPromptUnlessThisIsRoot(t *testing.T) {
|
||||
if p, a := Escalated(1000, "visudo", "-c"); p != "sudo" || strings.Join(a, " ") != "-n visudo -c" {
|
||||
t.Fatalf("not root: %s %v", p, a)
|
||||
}
|
||||
if p, a := Escalated(0, "visudo", "-c"); p != "visudo" || strings.Join(a, " ") != "-c" {
|
||||
t.Fatalf("root: %s %v", p, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFailuresAreNamedNeverReadAsEmpty(t *testing.T) {
|
||||
cases := []struct {
|
||||
r Ran
|
||||
want string
|
||||
}{
|
||||
{Ran{Status: 127, Err: "ENOENT"}, "sudo is not installed here"},
|
||||
{Ran{Status: 1, Stderr: "sudo: a password is required\n"}, "may not run it without a prompt: sudo: a password is required"},
|
||||
{Ran{Status: 124, Err: "no answer within 20 s"}, "did not answer: no answer within 20 s"},
|
||||
{Ran{Status: 2, Stderr: "boom\nmore"}, "failed (2): boom"},
|
||||
}
|
||||
for _, c := range cases {
|
||||
m := machine(fake(func(call) Ran { return c.r }, nil), 1000)
|
||||
if _, err := m.Root("thing"); err == nil || !strings.Contains(err.Error(), c.want) {
|
||||
t.Errorf("%+v: %v, want %q", c.r, err, c.want)
|
||||
}
|
||||
}
|
||||
m := machine(fake(func(call) Ran { return Ran{Status: 127, Err: "ENOENT"} }, nil), 1000)
|
||||
if _, err := m.Out("thing"); err == nil || !strings.Contains(err.Error(), "thing is not installed") {
|
||||
t.Errorf("a missing program: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnArgumentIsNeverAnOption(t *testing.T) {
|
||||
for _, bad := range []any{"-rf", "a\nb", 3.0} {
|
||||
if _, err := text(map[string]any{"x": bad}, "x", true); err == nil {
|
||||
t.Errorf("%v was accepted", bad)
|
||||
}
|
||||
}
|
||||
if s, err := text(map[string]any{"x": " ok "}, "x", true); err != nil || s != "ok" {
|
||||
t.Errorf("a plain value: %q %v", s, err)
|
||||
}
|
||||
if _, err := text(map[string]any{}, "x", true); err == nil {
|
||||
t.Error("a missing required value was accepted")
|
||||
}
|
||||
if n, _ := whole(map[string]any{"n": 10000.0}, "n", 5, 1, 100); n != 100 {
|
||||
t.Errorf("not bounded: %d", n)
|
||||
}
|
||||
if _, err := whole(map[string]any{"n": 0.0}, "n", 5, 1, 100); err == nil {
|
||||
t.Error("below the least was accepted")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user