network/e2e/production/nameserver_test.go
2026-01-26 10:04:30 +02:00

182 lines
5.2 KiB
Go

//go:build e2e
package production
import (
"context"
"net"
"strings"
"testing"
"time"
"github.com/DeBrosOfficial/network/e2e"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestNameserver_NSRecords tests that NS records are properly configured for the domain
func TestNameserver_NSRecords(t *testing.T) {
e2e.SkipIfLocal(t)
env, err := e2e.LoadTestEnv()
require.NoError(t, err, "Failed to load test environment")
if len(env.Config.Nameservers) == 0 {
t.Skip("No nameservers configured in e2e/config.yaml")
}
t.Run("NS records exist for base domain", func(t *testing.T) {
nsRecords, err := net.LookupNS(env.BaseDomain)
require.NoError(t, err, "Should be able to look up NS records for %s", env.BaseDomain)
require.NotEmpty(t, nsRecords, "Should have NS records")
t.Logf("Found %d NS records for %s:", len(nsRecords), env.BaseDomain)
for _, ns := range nsRecords {
t.Logf(" - %s", ns.Host)
}
// Verify our nameservers are listed
for _, expected := range env.Config.Nameservers {
found := false
for _, ns := range nsRecords {
// Trim trailing dot for comparison
nsHost := strings.TrimSuffix(ns.Host, ".")
if nsHost == expected || nsHost == expected+"." {
found = true
break
}
}
assert.True(t, found, "NS records should include %s", expected)
}
})
}
// TestNameserver_GlueRecords tests that glue records point to correct IPs
func TestNameserver_GlueRecords(t *testing.T) {
e2e.SkipIfLocal(t)
env, err := e2e.LoadTestEnv()
require.NoError(t, err, "Failed to load test environment")
if len(env.Config.Nameservers) == 0 {
t.Skip("No nameservers configured in e2e/config.yaml")
}
nameserverServers := e2e.GetNameserverServers(env.Config)
if len(nameserverServers) == 0 {
t.Skip("No servers marked as nameservers in config")
}
t.Run("Glue records resolve to correct IPs", func(t *testing.T) {
for i, ns := range env.Config.Nameservers {
ips, err := net.LookupHost(ns)
require.NoError(t, err, "Nameserver %s should resolve", ns)
require.NotEmpty(t, ips, "Nameserver %s should have IP addresses", ns)
t.Logf("Nameserver %s resolves to: %v", ns, ips)
// If we have the expected IP, verify it matches
if i < len(nameserverServers) {
expectedIP := nameserverServers[i].IP
found := false
for _, ip := range ips {
if ip == expectedIP {
found = true
break
}
}
assert.True(t, found, "Glue record for %s should point to %s (got %v)", ns, expectedIP, ips)
}
}
})
}
// TestNameserver_CoreDNSResponds tests that our CoreDNS servers respond to queries
func TestNameserver_CoreDNSResponds(t *testing.T) {
e2e.SkipIfLocal(t)
env, err := e2e.LoadTestEnv()
require.NoError(t, err, "Failed to load test environment")
nameserverServers := e2e.GetNameserverServers(env.Config)
if len(nameserverServers) == 0 {
t.Skip("No servers marked as nameservers in config")
}
t.Run("CoreDNS servers respond to queries", func(t *testing.T) {
for _, server := range nameserverServers {
t.Run(server.Name, func(t *testing.T) {
// Create a custom resolver that queries this specific server
resolver := &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{
Timeout: 5 * time.Second,
}
return d.DialContext(ctx, "udp", server.IP+":53")
},
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// Query the base domain
ips, err := resolver.LookupHost(ctx, env.BaseDomain)
if err != nil {
// Log the error but don't fail - server might be configured differently
t.Logf("⚠ CoreDNS at %s (%s) query error: %v", server.Name, server.IP, err)
return
}
t.Logf("✓ CoreDNS at %s (%s) responded: %s -> %v", server.Name, server.IP, env.BaseDomain, ips)
assert.NotEmpty(t, ips, "CoreDNS should return IP addresses")
})
}
})
}
// TestNameserver_QueryLatency tests DNS query latency from our nameservers
func TestNameserver_QueryLatency(t *testing.T) {
e2e.SkipIfLocal(t)
env, err := e2e.LoadTestEnv()
require.NoError(t, err, "Failed to load test environment")
nameserverServers := e2e.GetNameserverServers(env.Config)
if len(nameserverServers) == 0 {
t.Skip("No servers marked as nameservers in config")
}
t.Run("DNS query latency is acceptable", func(t *testing.T) {
for _, server := range nameserverServers {
resolver := &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{
Timeout: 5 * time.Second,
}
return d.DialContext(ctx, "udp", server.IP+":53")
},
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
start := time.Now()
_, err := resolver.LookupHost(ctx, env.BaseDomain)
latency := time.Since(start)
if err != nil {
t.Logf("⚠ Query to %s failed: %v", server.Name, err)
continue
}
t.Logf("DNS latency from %s (%s): %v", server.Name, server.IP, latency)
// DNS queries should be fast (under 500ms is reasonable)
assert.Less(t, latency, 500*time.Millisecond,
"DNS query to %s should complete in under 500ms", server.Name)
}
})
}