network/pkg/namespace/dns_manager_test.go

218 lines
5.4 KiB
Go

package namespace
import (
"fmt"
"testing"
"go.uber.org/zap"
)
func TestDNSRecordManager_FQDNFormat(t *testing.T) {
// Test that FQDN is correctly formatted
tests := []struct {
namespace string
baseDomain string
expected string
}{
{"alice", "devnet-orama.network", "ns-alice.devnet-orama.network."},
{"bob", "testnet-orama.network", "ns-bob.testnet-orama.network."},
{"my-namespace", "mainnet-orama.network", "ns-my-namespace.mainnet-orama.network."},
{"test123", "example.com", "ns-test123.example.com."},
}
for _, tt := range tests {
t.Run(tt.namespace, func(t *testing.T) {
fqdn := fmt.Sprintf("ns-%s.%s.", tt.namespace, tt.baseDomain)
if fqdn != tt.expected {
t.Errorf("FQDN = %s, want %s", fqdn, tt.expected)
}
})
}
}
func TestDNSRecordManager_WildcardFQDNFormat(t *testing.T) {
// Test that wildcard FQDN is correctly formatted
tests := []struct {
namespace string
baseDomain string
expected string
}{
{"alice", "devnet-orama.network", "*.ns-alice.devnet-orama.network."},
{"bob", "testnet-orama.network", "*.ns-bob.testnet-orama.network."},
}
for _, tt := range tests {
t.Run(tt.namespace, func(t *testing.T) {
wildcardFqdn := fmt.Sprintf("*.ns-%s.%s.", tt.namespace, tt.baseDomain)
if wildcardFqdn != tt.expected {
t.Errorf("Wildcard FQDN = %s, want %s", wildcardFqdn, tt.expected)
}
})
}
}
func TestNewDNSRecordManager(t *testing.T) {
mockDB := newMockRQLiteClient()
logger := zap.NewNop()
baseDomain := "devnet-orama.network"
manager := NewDNSRecordManager(mockDB, baseDomain, logger)
if manager == nil {
t.Fatal("NewDNSRecordManager returned nil")
}
}
func TestDNSRecordManager_NamespacePrefix(t *testing.T) {
// Test the namespace prefix used for tracking ownership
namespace := "my-namespace"
expected := "namespace:my-namespace"
prefix := "namespace:" + namespace
if prefix != expected {
t.Errorf("Namespace prefix = %s, want %s", prefix, expected)
}
}
func TestDNSRecordTTL(t *testing.T) {
// DNS records should have a 60-second TTL for quick failover
expectedTTL := 60
// This is testing the constant used in the code
ttl := 60
if ttl != expectedTTL {
t.Errorf("TTL = %d, want %d", ttl, expectedTTL)
}
}
func TestDNSRecordManager_MultipleDomainFormats(t *testing.T) {
// Test support for different domain formats
baseDomains := []string{
"devnet-orama.network",
"testnet-orama.network",
"mainnet-orama.network",
"custom.example.com",
"subdomain.custom.example.com",
}
for _, baseDomain := range baseDomains {
t.Run(baseDomain, func(t *testing.T) {
namespace := "test"
fqdn := fmt.Sprintf("ns-%s.%s.", namespace, baseDomain)
// Verify FQDN ends with trailing dot
if fqdn[len(fqdn)-1] != '.' {
t.Errorf("FQDN should end with trailing dot: %s", fqdn)
}
// Verify format is correct
expectedPrefix := "ns-test."
if len(fqdn) <= len(expectedPrefix) {
t.Errorf("FQDN too short: %s", fqdn)
}
if fqdn[:len(expectedPrefix)] != expectedPrefix {
t.Errorf("FQDN should start with %s: %s", expectedPrefix, fqdn)
}
})
}
}
func TestDNSRecordManager_IPValidation(t *testing.T) {
// Test IP address formats that should be accepted
validIPs := []string{
"192.168.1.1",
"10.0.0.1",
"172.16.0.1",
"1.2.3.4",
"255.255.255.255",
}
for _, ip := range validIPs {
t.Run(ip, func(t *testing.T) {
// Basic validation: IP should not be empty
if ip == "" {
t.Error("IP should not be empty")
}
})
}
}
func TestDNSRecordManager_EmptyNodeIPs(t *testing.T) {
// Creating records with empty node IPs should be an error
nodeIPs := []string{}
if len(nodeIPs) == 0 {
// This condition should trigger the error in CreateNamespaceRecords
err := &ClusterError{Message: "no node IPs provided for DNS records"}
if err.Message != "no node IPs provided for DNS records" {
t.Error("Expected error message for empty IPs")
}
}
}
func TestDNSRecordManager_RecordTypes(t *testing.T) {
// DNS records for namespace gateways should be A records
expectedRecordType := "A"
recordType := "A"
if recordType != expectedRecordType {
t.Errorf("Record type = %s, want %s", recordType, expectedRecordType)
}
}
func TestDNSRecordManager_CreatedByField(t *testing.T) {
// Records should be created by "cluster-manager"
expected := "cluster-manager"
createdBy := "cluster-manager"
if createdBy != expected {
t.Errorf("CreatedBy = %s, want %s", createdBy, expected)
}
}
func TestDNSRecordManager_RoundRobinConcept(t *testing.T) {
// Test that multiple A records for the same FQDN enable round-robin
nodeIPs := []string{
"192.168.1.100",
"192.168.1.101",
"192.168.1.102",
}
// For round-robin DNS, we need one A record per IP
expectedRecordCount := len(nodeIPs)
if expectedRecordCount != 3 {
t.Errorf("Expected %d A records for round-robin, got %d", 3, expectedRecordCount)
}
// Each IP should be unique
seen := make(map[string]bool)
for _, ip := range nodeIPs {
if seen[ip] {
t.Errorf("Duplicate IP in node list: %s", ip)
}
seen[ip] = true
}
}
func TestDNSRecordManager_FQDNWithTrailingDot(t *testing.T) {
// DNS FQDNs should always end with a trailing dot
// This is important for proper DNS resolution
tests := []struct {
input string
expected string
}{
{"ns-alice.devnet-orama.network", "ns-alice.devnet-orama.network."},
}
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
fqdn := tt.input + "."
if fqdn != tt.expected {
t.Errorf("FQDN = %s, want %s", fqdn, tt.expected)
}
})
}
}