package host import ( "net" "path/filepath" "testing" "github.com/carlosframework/platform/internal/registry" ) func TestWarnExternalSocketsShapeAndConditions(t *testing.T) { sock := func(h string) string { return "/run/carlos/" + h + ".sock" } cases := []struct { name string rt registry.Route serving, owns bool warn bool }{ {"hibernate=0 live socket warns", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x")}, true, false, true}, {"hibernate=0 dead socket quiet", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x")}, false, false, false}, {"hibernate=1 unowned live socket warns", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x"), Hibernate: true}, true, false, true}, {"hibernate=1 owned live socket quiet", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x"), Hibernate: true}, true, true, false}, {"hibernate=0 live socket ready status warns", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x"), Status: "ready"}, true, false, true}, {"addr route (issue #18) never warns", registry.Route{Kind: "instance", App: "a", Host: "x", Addr: "127.0.0.1:9000"}, true, false, false}, {"unit backing belongs to #14 advisory", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x"), Backing: registry.BackingUnit}, true, false, false}, {"platform route out of scope", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x"), Platform: true}, true, false, false}, {"appless route out of scope", registry.Route{Kind: "instance", Host: "x", Socket: sock("x")}, true, false, false}, {"non-ready status out of scope", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x"), Status: "draining"}, true, false, false}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { serving := func(string) bool { return c.serving } owns := func(string) bool { return c.owns } got := warnExternalSockets([]registry.Route{c.rt}, serving, owns) if (len(got) == 1) != c.warn { t.Errorf("warn = %v, want %v", len(got) == 1, c.warn) } }) } } // The probe distinguishes a live LISTENER from a stale socket FILE and a // missing path — only the first is "served". func TestSocketServingProbe(t *testing.T) { dir := t.TempDir() live := filepath.Join(dir, "live.sock") l, err := net.Listen("unix", live) if err != nil { t.Fatal(err) } defer l.Close() go func() { for { c, err := l.Accept() if err != nil { return } c.Close() } }() if !socketServing(live) { t.Error("live listener not reported as serving") } stale := filepath.Join(dir, "stale.sock") l2, err := net.Listen("unix", stale) if err != nil { t.Fatal(err) } l2.(*net.UnixListener).SetUnlinkOnClose(false) l2.Close() if socketServing(stale) { t.Error("stale socket file reported as serving") } if socketServing(filepath.Join(dir, "absent.sock")) { t.Error("missing path reported as serving") } }