97 lines
3.2 KiB
Go
97 lines
3.2 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
// fakeResolver beantwortet CNAME- und PTR-Anfragen aus Tabellen.
|
|
type fakeResolver struct {
|
|
cname map[string]string
|
|
ptr map[string][]string
|
|
}
|
|
|
|
func (f fakeResolver) LookupCNAME(_ context.Context, host string) (string, error) {
|
|
if c, ok := f.cname[host]; ok {
|
|
return c, nil
|
|
}
|
|
return "", errors.New("no such host")
|
|
}
|
|
|
|
func (f fakeResolver) LookupAddr(_ context.Context, addr string) ([]string, error) {
|
|
if p, ok := f.ptr[addr]; ok {
|
|
return p, nil
|
|
}
|
|
return nil, errors.New("no such host")
|
|
}
|
|
|
|
// FQDN: explizit > Hostname mit Punkt > aufgelöster Hostname (Suchdomain) >
|
|
// Reverse-Lookup der Backend-Adresse > kurzer Hostname.
|
|
func TestDetectFQDN(t *testing.T) {
|
|
res := fakeResolver{
|
|
cname: map[string]string{"webdocker11": "webdocker11.lan.r25dc.de.", "kurz": "kurz"},
|
|
ptr: map[string][]string{"10.0.0.11": {"backend11.lan.r25dc.de."}},
|
|
}
|
|
tests := []struct {
|
|
name, explicit, hostname, backend, want string
|
|
}{
|
|
{"explizit gewinnt", "web.example.de", "webdocker11", "10.0.0.11", "web.example.de"},
|
|
{"Hostname ist schon FQDN", "", "pi.home.arpa", "10.0.0.11", "pi.home.arpa"},
|
|
{"über Suchdomain aufgelöst", "", "webdocker11", "10.0.0.11", "webdocker11.lan.r25dc.de"},
|
|
{"Reverse-Lookup der Backend-Adresse", "", "kurz", "10.0.0.11", "backend11.lan.r25dc.de"},
|
|
{"nichts auflösbar: kurzer Hostname", "", "solo", "10.9.9.9", "solo"},
|
|
{"Groß/Klein und Leerraum", " Web.Example.DE ", "x", "", "web.example.de"},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := detectFQDN(context.Background(), res, tt.explicit, tt.hostname, tt.backend); got != tt.want {
|
|
t.Errorf("detectFQDN = %q, erwartet %q", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// NetBird: Interface wt0, sonst eine Adresse aus 100.64.0.0/10 (CGNAT, wie
|
|
// NetBird sie vergibt).
|
|
func TestNetBirdIP(t *testing.T) {
|
|
ip := net.ParseIP
|
|
tests := []struct {
|
|
name string
|
|
addrs map[string][]net.IP
|
|
want string
|
|
}{
|
|
{"wt0", map[string][]net.IP{"eth0": {ip("10.0.0.11")}, "wt0": {ip("fe80::1"), ip("100.92.10.4")}}, "100.92.10.4"},
|
|
{"CGNAT auf anderem Interface", map[string][]net.IP{"eth0": {ip("10.0.0.11")}, "nb0": {ip("100.64.3.2")}}, "100.64.3.2"},
|
|
{"kein Overlay", map[string][]net.IP{"eth0": {ip("10.0.0.11")}, "lo": {ip("127.0.0.1")}}, ""},
|
|
{"100.128.x ist kein CGNAT", map[string][]net.IP{"eth0": {ip("100.128.0.1")}}, ""},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := netbirdIP(tt.addrs); got != tt.want {
|
|
t.Errorf("netbirdIP = %q, erwartet %q", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Ohne Docker (systemd-Agent) kommt das Betriebssystem aus /etc/os-release.
|
|
func TestOSPrettyName(t *testing.T) {
|
|
dir := t.TempDir()
|
|
p := filepath.Join(dir, "os-release")
|
|
os.WriteFile(p, []byte("NAME=\"Debian GNU/Linux\"\nPRETTY_NAME=\"Debian GNU/Linux 13 (trixie)\"\nID=debian\n"), 0o644)
|
|
if got := osPrettyName(p); got != "Debian GNU/Linux 13 (trixie)" {
|
|
t.Errorf("osPrettyName = %q", got)
|
|
}
|
|
os.WriteFile(p, []byte("NAME=Alpine\nID=alpine\n"), 0o644)
|
|
if got := osPrettyName(p); got != "Alpine" {
|
|
t.Errorf("ohne PRETTY_NAME: %q, erwartet NAME", got)
|
|
}
|
|
if got := osPrettyName(filepath.Join(dir, "fehlt")); got != "" {
|
|
t.Errorf("fehlende Datei: %q", got)
|
|
}
|
|
}
|