Files
pdns-admin/internal/dnsrecord/validator_test.go

139 lines
3.7 KiB
Go

package dnsrecord
import "testing"
func TestValidateRRSetAcceptsSupportedRecords(t *testing.T) {
v := newTestValidator(t)
cases := []struct {
recordType string
content string
}{
{"A", "192.0.2.10"},
{"AAAA", "2001:db8::1"},
{"CAA", `0 issue "letsencrypt.org"`},
{"CNAME", "target.example.org."},
{"MX", "10 mail.example.org."},
{"NS", "ns1.example.org."},
{"SOA", "ns1.example.org. hostmaster.example.org. 2026010101 3600 600 604800 300"},
{"SRV", "10 20 443 service.example.org."},
{"TXT", `"v=spf1 -all"`},
{"TXT", `"v=DMARC1; p=reject; rua=mailto:postmaster@example.org; ruf=mailto:postmaster@example.org"`},
}
for _, tc := range cases {
t.Run(tc.recordType, func(t *testing.T) {
if _, err := v.ValidateRRSet("www.example.org", tc.recordType, 300, []string{tc.content}); err != nil {
t.Fatalf("ValidateRRSet returned error: %v", err)
}
})
}
}
func TestValidateRRSetRejectsInvalidRecords(t *testing.T) {
v := newTestValidator(t)
cases := []struct {
name string
recordType string
content string
}{
{"bad name", "A", "192.0.2.10"},
{"www.example.org.", "A", "2001:db8::1"},
{"www.example.org.", "AAAA", "192.0.2.10"},
{"www.example.org.", "MX", "mail.example.org."},
{"www.example.org.", "CNAME", "target.example.org"},
{"www.example.org.", "TXT", "not quoted"},
{"www.example.org.", "SOA", "ns1.example.org. hostmaster.example.org."},
{"www.example.org.", "UNSUPPORTED", "value"},
}
for _, tc := range cases {
t.Run(tc.recordType+" "+tc.content, func(t *testing.T) {
if _, err := v.ValidateRRSet(tc.name, tc.recordType, 300, []string{tc.content}); err == nil {
t.Fatal("expected validation error")
}
})
}
}
func TestValidateRRSetAcceptsUnderscoresInOwnerNames(t *testing.T) {
v := newTestValidator(t)
cases := []struct {
name string
recordType string
content string
wantName string
}{
{
name: "_dmarc.example.org",
recordType: "TXT",
content: `"v=DMARC1; p=reject; rua=mailto:postmaster@example.org; ruf=mailto:postmaster@example.org"`,
wantName: "_dmarc.example.org.",
},
{
name: "_sip._tcp.example.org",
recordType: "SRV",
content: "10 20 5060 sip.example.org.",
wantName: "_sip._tcp.example.org.",
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
rrset, err := v.ValidateRRSet(tc.name, tc.recordType, 300, []string{tc.content})
if err != nil {
t.Fatalf("ValidateRRSet returned error: %v", err)
}
if rrset.Name != tc.wantName {
t.Fatalf("unexpected normalized name: %q", rrset.Name)
}
if rrset.Records[0].Content != tc.content {
t.Fatalf("unexpected content: %q", rrset.Records[0].Content)
}
})
}
}
func TestValidateRRSetRejectsUnderscoresInHostnameTargets(t *testing.T) {
v := newTestValidator(t)
cases := []struct {
recordType string
content string
}{
{"CNAME", "_target.example.org."},
{"MX", "10 _mail.example.org."},
{"NS", "_ns.example.org."},
{"SOA", "_ns.example.org. hostmaster.example.org. 2026010101 3600 600 604800 300"},
{"SRV", "10 20 5060 _sip.example.org."},
}
for _, tc := range cases {
t.Run(tc.recordType, func(t *testing.T) {
if _, err := v.ValidateRRSet("www.example.org.", tc.recordType, 300, []string{tc.content}); err == nil {
t.Fatal("expected validation error")
}
})
}
}
func TestValidateRRSetRequiresTTL(t *testing.T) {
v := newTestValidator(t)
if _, err := v.ValidateRRSet("www.example.org.", "A", 0, []string{"192.0.2.10"}); err == nil {
t.Fatal("expected ttl validation error")
}
}
func newTestValidator(t *testing.T) *Validator {
t.Helper()
v, err := NewValidator()
if err != nil {
t.Fatalf("NewValidator returned error: %v", err)
}
return v
}