dnscontrol/providers/bind/soa_test.go
Tom Limoncelli 24083d3f76
Add integration test for SOA (#1147)
* Add integration test for SOA

* Add docs for SOA record

* MAINT: Rename SoaInfo to SoaDefaults.

gorename -v -from '"github.com/StackExchange/dnscontrol/v3/providers/bind".SoaInfo' -to SoaDefaults
2021-05-07 14:39:26 -04:00

153 lines
5.9 KiB
Go

package bind
import (
"fmt"
"testing"
"time"
"github.com/StackExchange/dnscontrol/v3/models"
)
func mkRC(target string, rec *models.RecordConfig) *models.RecordConfig {
rec.SetTarget(target)
return rec
}
func Test_makeSoa(t *testing.T) {
origin := "example.com"
var tests = []struct {
def *SoaDefaults
existing *models.RecordConfig
desired *models.RecordConfig
expectedSoa *models.RecordConfig
expectedSerial uint32
}{
{
// If everything is blank, the hard-coded defaults should kick in.
&SoaDefaults{"", "", 0, 0, 0, 0, 0, models.DefaultTTL},
mkRC("", &models.RecordConfig{SoaMbox: "", SoaSerial: 0, SoaRefresh: 0, SoaRetry: 0, SoaExpire: 0, SoaMinttl: 0}),
mkRC("", &models.RecordConfig{SoaMbox: "", SoaSerial: 0, SoaRefresh: 0, SoaRetry: 0, SoaExpire: 0, SoaMinttl: 0}),
mkRC("DEFAULT_NOT_SET.", &models.RecordConfig{SoaMbox: "DEFAULT_NOT_SET.", SoaSerial: 1, SoaRefresh: 3600, SoaRetry: 600, SoaExpire: 604800, SoaMinttl: 1440}),
2019022300,
},
{
// If everything is filled, leave the desired values in place.
&SoaDefaults{"ns.example.com", "root.example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
mkRC("a", &models.RecordConfig{SoaMbox: "aa", SoaSerial: 10, SoaRefresh: 11, SoaRetry: 12, SoaExpire: 13, SoaMinttl: 14}),
mkRC("b", &models.RecordConfig{SoaMbox: "bb", SoaSerial: 15, SoaRefresh: 16, SoaRetry: 17, SoaExpire: 18, SoaMinttl: 19}),
mkRC("b", &models.RecordConfig{SoaMbox: "bb", SoaSerial: 15, SoaRefresh: 16, SoaRetry: 17, SoaExpire: 18, SoaMinttl: 19}),
2019022300,
},
{
// Test incrementing serial.
&SoaDefaults{"ns.example.com", "root.example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
mkRC("a", &models.RecordConfig{SoaMbox: "aa", SoaSerial: 2019022301, SoaRefresh: 11, SoaRetry: 12, SoaExpire: 13, SoaMinttl: 14}),
mkRC("b", &models.RecordConfig{SoaMbox: "bb", SoaSerial: 0, SoaRefresh: 16, SoaRetry: 17, SoaExpire: 18, SoaMinttl: 19}),
mkRC("b", &models.RecordConfig{SoaMbox: "bb", SoaSerial: 2019022301, SoaRefresh: 16, SoaRetry: 17, SoaExpire: 18, SoaMinttl: 19}),
2019022302,
},
{
// Test incrementing serial_2.
&SoaDefaults{"ns.example.com", "root.example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
mkRC("a", &models.RecordConfig{SoaMbox: "aa", SoaSerial: 0, SoaRefresh: 11, SoaRetry: 12, SoaExpire: 13, SoaMinttl: 14}),
mkRC("b", &models.RecordConfig{SoaMbox: "bb", SoaSerial: 2019022304, SoaRefresh: 16, SoaRetry: 17, SoaExpire: 18, SoaMinttl: 19}),
mkRC("b", &models.RecordConfig{SoaMbox: "bb", SoaSerial: 2019022304, SoaRefresh: 16, SoaRetry: 17, SoaExpire: 18, SoaMinttl: 19}),
2019022305,
},
{
// If there are gaps in existing or desired, fill in as appropriate.
&SoaDefaults{"ns.example.com", "root.example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
mkRC("", &models.RecordConfig{SoaMbox: "aa", SoaSerial: 0, SoaRefresh: 11, SoaRetry: 0, SoaExpire: 13, SoaMinttl: 0}),
mkRC("b", &models.RecordConfig{SoaMbox: "", SoaSerial: 15, SoaRefresh: 0, SoaRetry: 17, SoaExpire: 0, SoaMinttl: 19}),
mkRC("b", &models.RecordConfig{SoaMbox: "aa", SoaSerial: 15, SoaRefresh: 11, SoaRetry: 17, SoaExpire: 13, SoaMinttl: 19}),
2019022300,
},
{
// Gaps + existing==nil
&SoaDefaults{"ns.example.com", "root.example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
nil,
mkRC("b", &models.RecordConfig{SoaMbox: "", SoaSerial: 15, SoaRefresh: 0, SoaRetry: 17, SoaExpire: 0, SoaMinttl: 19}),
mkRC("b", &models.RecordConfig{SoaMbox: "root.example.com", SoaSerial: 15, SoaRefresh: 2, SoaRetry: 17, SoaExpire: 4, SoaMinttl: 19}),
2019022300,
},
{
// Gaps + desired==nil
// NB(tom): In the code as of 2020-02-23, desired will never be nil.
&SoaDefaults{"ns.example.com", "root.example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
mkRC("", &models.RecordConfig{SoaMbox: "aa", SoaSerial: 0, SoaRefresh: 11, SoaRetry: 0, SoaExpire: 13, SoaMinttl: 0}),
nil,
mkRC("ns.example.com", &models.RecordConfig{SoaMbox: "aa", SoaSerial: 1, SoaRefresh: 11, SoaRetry: 3, SoaExpire: 13, SoaMinttl: 5}),
2019022300,
},
}
// Fake out the tests so they think today is 2019-02-23
nowFunc = func() time.Time {
fakeToday, _ := time.Parse("20060102", "20190223")
return fakeToday
}
for i, tst := range tests {
if tst.existing != nil {
tst.existing.SetLabel("@", origin)
tst.existing.Type = "SOA"
}
if tst.desired != nil {
tst.desired.SetLabel("@", origin)
tst.desired.Type = "SOA"
}
tst.expectedSoa.SetLabel("@", origin)
tst.expectedSoa.Type = "SOA"
r1, r2 := makeSoa(origin, tst.def, tst.existing, tst.desired)
if !areEqualSoa(r1, tst.expectedSoa) {
t.Fatalf("Test %d soa:\nExpected (%v)\n got (%v)\n", i, tst.expectedSoa.String(), r1.String())
}
if r2 != tst.expectedSerial {
t.Fatalf("Test:%d soa: Expected (%v) got (%v)\n", i, tst.expectedSerial, r2)
}
}
}
func areEqualSoa(r1, r2 *models.RecordConfig) bool {
if r1.NameFQDN != r2.NameFQDN {
fmt.Printf("ERROR: fqdn %q != %q\n", r1.NameFQDN, r2.NameFQDN)
return false
}
if r1.Name != r2.Name {
fmt.Printf("ERROR: name %q != %q\n", r1.Name, r2.Name)
return false
}
if r1.GetTargetField() != r2.GetTargetField() {
fmt.Printf("ERROR: target %q != %q\n", r1, r2.GetTargetField())
return false
}
if r1.SoaMbox != r2.SoaMbox {
fmt.Printf("ERROR: mbox %v != %v\n", r1.SoaMbox, r2.SoaMbox)
return false
}
if r1.SoaSerial != r2.SoaSerial {
fmt.Printf("ERROR: serial %v != %v\n", r1.SoaSerial, r2.SoaSerial)
return false
}
if r1.SoaRefresh != r2.SoaRefresh {
fmt.Printf("ERROR: refresh %v != %v\n", r1.SoaRefresh, r2.SoaRefresh)
return false
}
if r1.SoaRetry != r2.SoaRetry {
fmt.Printf("ERROR: retry %v != %v\n", r1.SoaRetry, r2.SoaRetry)
return false
}
if r1.SoaExpire != r2.SoaExpire {
fmt.Printf("ERROR: expire %v != %v\n", r1.SoaExpire, r2.SoaExpire)
return false
}
if r1.SoaMinttl != r2.SoaMinttl {
fmt.Printf("ERROR: minttl %v != %v\n", r1.SoaMinttl, r2.SoaMinttl)
return false
}
return true
}