package reachable import ( "context" "os" "strings" "testing" ) // Defends novox/hq ADR 0100: converging previews every listening socket and every published // container port. Fixtures are captured from a real machine. func fixture(t *testing.T, name string) string { t.Helper() raw, err := os.ReadFile("testdata/" + name) if err != nil { t.Fatal(err) } return string(raw) } func find(rs []Reach, protocol, address string, port int) (Reach, bool) { for _, r := range rs { if r.Protocol == protocol && r.Address == address && r.Port == port { return r, true } } return Reach{}, false } func TestSocketsAreReadWithWhatHoldsThem(t *testing.T) { got := Sockets(fixture(t, "ss.txt")) if r, ok := find(got, "tcp", "0.0.0.0", 22); !ok || r.By != "sshd" { t.Errorf("ssh not read: %+v", r) } if r, ok := find(got, "tcp", "::", 445); !ok || r.By != "smbd" { t.Errorf("an IPv6 wildcard listener not read: %+v", r) } if _, ok := find(got, "udp", "fe80::849e:ccff:fea8:24c7", 123); !ok { t.Error("a link-local address with a scope was not read") } if r, ok := find(got, "udp", "127.0.0.1", 53); !ok || r.By != "dnsmasq" { t.Errorf("a loopback udp socket not read: %+v", r) } } func TestPublishedPortsNameTheirContainerAndItsPort(t *testing.T) { got := Published(fixture(t, "docker-ps.txt")) if r, ok := find(got, "tcp", "0.0.0.0", 8770); !ok || r.By != "whisper" || r.ContainerPort != 8000 || !r.Published { t.Errorf("a published port: %+v", r) } if r, ok := find(got, "tcp", "0.0.0.0", 9001); !ok || r.ContainerPort != 9001 { t.Errorf("a published range was not expanded: %+v", r) } if r, ok := find(got, "tcp", "127.0.0.1", 15673); !ok || r.ContainerPort != 15672 { t.Errorf("a loopback-published port: %+v", r) } for _, r := range got { if r.By == "umami_db" { t.Errorf("an exposed and unpublished port was reported reachable: %+v", r) } } } func TestAPublishedPortIsReportedOnceAsPublished(t *testing.T) { merged := Merge(Sockets(fixture(t, "ss.txt")), Published(fixture(t, "docker-ps.txt"))) n := 0 for _, r := range merged { if r.Protocol == "tcp" && r.Address == "0.0.0.0" && r.Port == 8770 { n++ if !r.Published { t.Errorf("the runtime's proxy was reported instead of the published port: %+v", r) } } } if n != 1 { t.Errorf("port 8770 reported %d times", n) } if _, ok := find(merged, "tcp", "0.0.0.0", 22); !ok { t.Error("a socket was lost in the merge") } } func TestCollectAsksSsAndTheRuntime(t *testing.T) { var asked []string run := func(_ context.Context, name string, args ...string) (string, error) { asked = append(asked, name+" "+strings.Join(args, " ")) if name == "ss" { return fixture(t, "ss.txt"), nil } return fixture(t, "docker-ps.txt"), nil } got, err := Collect(context.Background(), run) if err != nil || len(got) == 0 { t.Fatalf("%v %v", got, err) } if len(asked) != 2 { t.Errorf("asked %v", asked) } }