package dns import ( "path/filepath" "testing" "github.com/miekg/dns" "git.wntrmute.dev/mc/mcns/internal/db" "log/slog" ) func openTestDB(t *testing.T) *db.DB { t.Helper() dir := t.TempDir() database, err := db.Open(filepath.Join(dir, "test.db")) if err != nil { t.Fatalf("open db: %v", err) } if err := database.Migrate(); err != nil { t.Fatalf("migrate: %v", err) } t.Cleanup(func() { _ = database.Close() }) return database } func setupTestServer(t *testing.T) (*Server, *db.DB) { t.Helper() database := openTestDB(t) logger := slog.Default() _, err := database.CreateZone("test.example.com", "ns.example.com.", "admin.example.com.", 3600, 600, 86400, 300) if err != nil { t.Fatalf("create zone: %v", err) } _, err = database.CreateRecord("test.example.com", "metacrypt", "A", "192.168.88.181", 300) if err != nil { t.Fatalf("create A record: %v", err) } _, err = database.CreateRecord("test.example.com", "metacrypt", "A", "100.95.252.120", 300) if err != nil { t.Fatalf("create A record 2: %v", err) } _, err = database.CreateRecord("test.example.com", "mcr", "AAAA", "2001:db8::1", 300) if err != nil { t.Fatalf("create AAAA record: %v", err) } _, err = database.CreateRecord("test.example.com", "alias", "CNAME", "metacrypt.test.example.com.", 300) if err != nil { t.Fatalf("create CNAME record: %v", err) } srv := New(database, []string{"1.1.1.1:53"}, logger) return srv, database } func TestFindZone(t *testing.T) { srv, _ := setupTestServer(t) zone := srv.findZone("metacrypt.test.example.com.") if zone == nil { t.Fatal("expected to find zone") } if zone.Name != "test.example.com" { t.Fatalf("got zone %q, want %q", zone.Name, "test.example.com") } zone = srv.findZone("nonexistent.com.") if zone != nil { t.Fatal("expected nil for nonexistent zone") } } func TestBuildSOA(t *testing.T) { srv, database := setupTestServer(t) zone, err := database.GetZone("test.example.com") if err != nil { t.Fatalf("get zone: %v", err) } soa := srv.buildSOA(zone) if soa.Ns != "ns.example.com." { t.Fatalf("got ns %q, want %q", soa.Ns, "ns.example.com.") } if soa.Hdr.Name != "test.example.com." { t.Fatalf("got name %q, want %q", soa.Hdr.Name, "test.example.com.") } } func TestRecordToRR_A(t *testing.T) { srv, _ := setupTestServer(t) rec := db.Record{Name: "metacrypt", Type: "A", Value: "192.168.88.181", TTL: 300} rr := srv.recordToRR("metacrypt.test.example.com.", rec) if rr == nil { t.Fatal("expected non-nil RR") } a, ok := rr.(*dns.A) if !ok { t.Fatalf("expected *dns.A, got %T", rr) } if a.A.String() != "192.168.88.181" { t.Fatalf("got IP %q, want %q", a.A.String(), "192.168.88.181") } } func TestRecordToRR_AAAA(t *testing.T) { srv, _ := setupTestServer(t) rec := db.Record{Name: "mcr", Type: "AAAA", Value: "2001:db8::1", TTL: 300} rr := srv.recordToRR("mcr.test.example.com.", rec) if rr == nil { t.Fatal("expected non-nil RR") } aaaa, ok := rr.(*dns.AAAA) if !ok { t.Fatalf("expected *dns.AAAA, got %T", rr) } if aaaa.AAAA.String() != "2001:db8::1" { t.Fatalf("got IP %q, want %q", aaaa.AAAA.String(), "2001:db8::1") } } func TestRecordToRR_CNAME(t *testing.T) { srv, _ := setupTestServer(t) rec := db.Record{Name: "alias", Type: "CNAME", Value: "metacrypt.test.example.com.", TTL: 300} rr := srv.recordToRR("alias.test.example.com.", rec) if rr == nil { t.Fatal("expected non-nil RR") } cname, ok := rr.(*dns.CNAME) if !ok { t.Fatalf("expected *dns.CNAME, got %T", rr) } if cname.Target != "metacrypt.test.example.com." { t.Fatalf("got target %q, want %q", cname.Target, "metacrypt.test.example.com.") } }