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.
154 lines
3.9 KiB
Go
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")
|
|
}
|
|
}
|