Files
mesh-host/internal/reachable/collect_test.go
T

101 lines
2.9 KiB
Go

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)
}
}