checker-resolver-propagation/checker/zone_test.go
Pierre-Olivier Mercier 7d23348098
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
Derive probed record types from the working zone
Stop blindly probing a fixed list (which always included CAA): read the
auto-filled zone and only probe the RR types each owner actually has,
keeping SOA/NS at the apex. The recordTypes option still works as an
explicit override; missing zone falls back to the legacy default.
2026-05-25 18:30:38 +08:00

154 lines
3.9 KiB
Go

package checker
import (
"reflect"
"testing"
"github.com/miekg/dns"
sdk "git.happydns.org/checker-sdk-go/checker"
)
func TestResolveQTypes_ExplicitOverride(t *testing.T) {
apex := "example.com."
names := []string{apex, "www.example.com."}
opts := sdk.CheckerOptions{
"zone": map[string]any{}, // ignored when recordTypes is set
}
owner, union, err := resolveQTypes(opts, "A,AAAA", apex, names)
if err != nil {
t.Fatalf("err: %v", err)
}
want := []uint16{dns.TypeA, dns.TypeAAAA}
for _, n := range names {
if !reflect.DeepEqual(owner[n], want) {
t.Errorf("owner[%s] = %v, want %v", n, owner[n], want)
}
}
if !reflect.DeepEqual(union, want) {
t.Errorf("union = %v, want %v", union, want)
}
}
func TestResolveQTypes_NoZoneNoOption(t *testing.T) {
apex := "example.com."
names := []string{apex}
owner, union, err := resolveQTypes(sdk.CheckerOptions{}, "", apex, names)
if err != nil {
t.Fatalf("err: %v", err)
}
if !reflect.DeepEqual(owner[apex], fallbackQTypes) {
t.Errorf("apex types = %v, want fallback %v", owner[apex], fallbackQTypes)
}
if len(union) != len(fallbackQTypes) {
t.Errorf("union len = %d, want %d", len(union), len(fallbackQTypes))
}
}
func TestResolveQTypes_FromZone_NoCAA(t *testing.T) {
apex := "example.com."
names := []string{apex}
// A zone with MX + TXT services at the apex, but no CAA.
zone := map[string]any{
"domain_name": "example.com",
"services": map[string]any{
"": []any{
map[string]any{
"_svctype": "svcs.MXs",
"_domain": "example.com",
"Service": map[string]any{
"mx": []any{
map[string]any{
"Hdr": map[string]any{
"Name": "example.com.",
"Rrtype": float64(dns.TypeMX),
},
"Mx": "mail.example.com.",
"Preference": float64(10),
},
},
},
},
map[string]any{
"_svctype": "svcs.TXT",
"_domain": "example.com",
"Service": map[string]any{
"Hdr": map[string]any{
"Name": "example.com.",
"Rrtype": float64(dns.TypeTXT),
},
"Txt": []any{"v=spf1 -all"},
},
},
},
},
}
opts := sdk.CheckerOptions{"zone": zone}
owner, union, err := resolveQTypes(opts, "", apex, names)
if err != nil {
t.Fatalf("err: %v", err)
}
got := map[uint16]bool{}
for _, qt := range owner[apex] {
got[qt] = true
}
// Must have MX, TXT, plus the always-on SOA/NS.
for _, qt := range []uint16{dns.TypeSOA, dns.TypeNS, dns.TypeMX, dns.TypeTXT} {
if !got[qt] {
t.Errorf("apex missing %s", dns.TypeToString[qt])
}
}
// Must NOT include CAA (not in zone).
if got[dns.TypeCAA] {
t.Errorf("apex unexpectedly includes CAA: %v", owner[apex])
}
// Union should match the apex set (single owner).
if !reflect.DeepEqual(owner[apex], union) {
t.Errorf("union %v != apex %v", union, owner[apex])
}
}
func TestResolveQTypes_UnknownOwnerFallback(t *testing.T) {
apex := "example.com."
unknown := "www.example.com."
names := []string{apex, unknown}
zone := map[string]any{
"services": map[string]any{
// only apex services
"": []any{
map[string]any{
"_svctype": "abstract.Origin",
"_domain": "example.com",
"Service": map[string]any{
"soa": map[string]any{
"Hdr": map[string]any{
"Name": "example.com.",
"Rrtype": float64(dns.TypeSOA),
},
},
},
},
},
},
}
opts := sdk.CheckerOptions{"zone": zone}
owner, _, err := resolveQTypes(opts, "", apex, names)
if err != nil {
t.Fatalf("err: %v", err)
}
wantUnknown := []uint16{dns.TypeA, dns.TypeAAAA}
if !reflect.DeepEqual(owner[unknown], wantUnknown) {
t.Errorf("unknown owner types = %v, want %v", owner[unknown], wantUnknown)
}
}
func TestResolveQTypes_InvalidExplicit(t *testing.T) {
_, _, err := resolveQTypes(sdk.CheckerOptions{}, "nope,bogus", "example.com.", []string{"example.com."})
if err == nil {
t.Fatalf("expected error for invalid recordTypes")
}
}