1 parent
cc7466823b
commit
e8c5b414d9
44 files changed
+7649
-344
No files matched your search
@@ -0,0 +1,81 @@
|
||||
package zonefile
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// nameTypeRdata renders every record as "name TYPE rdata", skipping the line
|
||||
// number and the TTL. The shipped examples are edited by hand, so pinning the
|
||||
// exact record set is enough; pinning line numbers would make a comment change
|
||||
// look like a parser bug.
|
||||
func nameTypeRdata(t *testing.T, z *Zone) []string {
|
||||
t.Helper()
|
||||
out := make([]string, 0, len(z.Records))
|
||||
for _, rec := range z.Records {
|
||||
parts := strings.SplitN(rec.RR.String(), "\t", 5)
|
||||
if len(parts) != 5 {
|
||||
t.Fatalf("record on line %d does not render as 5 tab-separated fields: %q",
|
||||
rec.Line, rec.Text())
|
||||
}
|
||||
out = append(out, parts[0]+" "+parts[3]+" "+parts[4])
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// TestExampleLocalZoneIsOriginIndependent parses deploy/local.example.zone the
|
||||
// way the product parses it — with the origin taken from the file name, which
|
||||
// for local.example.zone is "local." — and pins that every name in the example
|
||||
// is fully qualified anyway.
|
||||
//
|
||||
// This is not a style test. The origin a master file is read with is its base
|
||||
// name, so a relative owner name silently becomes <name>.local. and the zone
|
||||
// answers for names nobody asked about. The example is what an operator copies,
|
||||
// and it used to mix relative owners with absolute ones: a file that looked
|
||||
// right and matched nothing.
|
||||
func TestExampleLocalZoneIsOriginIndependent(t *testing.T) {
|
||||
path := filepath.Join("..", "..", "deploy", "local.example.zone")
|
||||
if got, want := OriginFromPath(path), "local."; got != want {
|
||||
t.Fatalf("OriginFromPath(%q) = %q, want %q — the example depends on this origin",
|
||||
path, got, want)
|
||||
}
|
||||
|
||||
z, err := ParseFile(path, OriginFromPath(path))
|
||||
if err != nil {
|
||||
t.Fatalf("ParseFile(%s): %v", path, err)
|
||||
}
|
||||
got := nameTypeRdata(t, z)
|
||||
want := []string{
|
||||
"lan. SOA ns1.lan. hostmaster.lan. 2024010101 3600 600 604800 300",
|
||||
"lan. NS ns1.lan.",
|
||||
"lan. NS ns2.lan.",
|
||||
"ns1.lan. A 192.168.1.2",
|
||||
"ns2.lan. A 192.168.1.3",
|
||||
"router.lan. A 192.168.1.1",
|
||||
"nas.lan. A 192.168.1.10",
|
||||
"nas.lan. AAAA fd00::10",
|
||||
"*.lan. A 192.168.1.50",
|
||||
"*.internal.lan. A 10.0.0.50",
|
||||
"_ntp._udp.lan. SRV 0 0 123 ns1.lan.",
|
||||
"_ldap._tcp.lan. SRV 10 0 389 nas.lan.",
|
||||
`_dmarc._domain.lan. TXT "v=DMARC1; p=reject; rua=mailto:dmarc.lan"`,
|
||||
`_lan. TXT "internal network, do not use on the open internet"`,
|
||||
}
|
||||
if !slices.Equal(got, want) {
|
||||
t.Errorf("records mismatch\n got: %q\nwant: %q", got, want)
|
||||
}
|
||||
if z.DefaultTTL != 300 {
|
||||
t.Errorf("DefaultTTL = %d, want the $TTL 300", z.DefaultTTL)
|
||||
}
|
||||
for _, rec := range z.Records {
|
||||
if !strings.HasSuffix(rec.Name, ".") {
|
||||
t.Errorf("record %q is not fully qualified; the example is read with the "+
|
||||
"origin %q derived from the file name", rec.Name, z.Origin)
|
||||
}
|
||||
}
|
||||
if z.SOA == nil || z.SOA.Serial != 2024010101 {
|
||||
t.Errorf("SOA = %v, want the serial 2024010101", z.SOA)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user