carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package host
2
3import (
4 "net"
5 "path/filepath"
6 "testing"
7
8 "github.com/carlosframework/platform/internal/registry"
9)
10
11func TestWarnExternalSocketsShapeAndConditions(t *testing.T) {
12 sock := func(h string) string { return "/run/carlos/" + h + ".sock" }
13 cases := []struct {
14 name string
15 rt registry.Route
16 serving, owns bool
17 warn bool
18 }{
19 {"hibernate=0 live socket warns", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x")}, true, false, true},
20 {"hibernate=0 dead socket quiet", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x")}, false, false, false},
21 {"hibernate=1 unowned live socket warns", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x"), Hibernate: true}, true, false, true},
22 {"hibernate=1 owned live socket quiet", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x"), Hibernate: true}, true, true, false},
23 {"hibernate=0 live socket ready status warns", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x"), Status: "ready"}, true, false, true},
24 {"addr route (issue #18) never warns", registry.Route{Kind: "instance", App: "a", Host: "x", Addr: "127.0.0.1:9000"}, true, false, false},
25 {"unit backing belongs to #14 advisory", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x"), Backing: registry.BackingUnit}, true, false, false},
26 {"platform route out of scope", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x"), Platform: true}, true, false, false},
27 {"appless route out of scope", registry.Route{Kind: "instance", Host: "x", Socket: sock("x")}, true, false, false},
28 {"non-ready status out of scope", registry.Route{Kind: "instance", App: "a", Host: "x", Socket: sock("x"), Status: "draining"}, true, false, false},
29 }
30 for _, c := range cases {
31 t.Run(c.name, func(t *testing.T) {
32 serving := func(string) bool { return c.serving }
33 owns := func(string) bool { return c.owns }
34 got := warnExternalSockets([]registry.Route{c.rt}, serving, owns)
35 if (len(got) == 1) != c.warn {
36 t.Errorf("warn = %v, want %v", len(got) == 1, c.warn)
37 }
38 })
39 }
40}
41
42// The probe distinguishes a live LISTENER from a stale socket FILE and a
43// missing path — only the first is "served".
44func TestSocketServingProbe(t *testing.T) {
45 dir := t.TempDir()
46 live := filepath.Join(dir, "live.sock")
47 l, err := net.Listen("unix", live)
48 if err != nil {
49 t.Fatal(err)
50 }
51 defer l.Close()
52 go func() {
53 for {
54 c, err := l.Accept()
55 if err != nil {
56 return
57 }
58 c.Close()
59 }
60 }()
61 if !socketServing(live) {
62 t.Error("live listener not reported as serving")
63 }
64 stale := filepath.Join(dir, "stale.sock")
65 l2, err := net.Listen("unix", stale)
66 if err != nil {
67 t.Fatal(err)
68 }
69 l2.(*net.UnixListener).SetUnlinkOnClose(false)
70 l2.Close()
71 if socketServing(stale) {
72 t.Error("stale socket file reported as serving")
73 }
74 if socketServing(filepath.Join(dir, "absent.sock")) {
75 t.Error("missing path reported as serving")
76 }
77}
78