182 lines
5.8 KiB
Go
182 lines
5.8 KiB
Go
package dsl_test
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"github.com/BytemarkHosting/go-pdns/pipe/backend"
|
|
. "github.com/BytemarkHosting/go-pdns/pipe/dsl"
|
|
h "github.com/BytemarkHosting/go-pdns/pipe/test_helpers"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func ReplyHandler(x string) func(c *Context) {
|
|
return func(c *Context) { c.Reply(x) }
|
|
}
|
|
|
|
func NullHandler(c *Context) {}
|
|
|
|
var ErrorReplyError = errors.New("Foo")
|
|
|
|
func ErrorReplyHandler(c *Context) { c.Error = ErrorReplyError }
|
|
|
|
func SOAQuery() *backend.Query {
|
|
q := h.FakeQuery(3)
|
|
q.QName = "example.com"
|
|
q.QType = "SOA"
|
|
return q
|
|
}
|
|
|
|
func AssertTableEntry(t *testing.T, d *DSL, qtype, matcher, msg string) {
|
|
table := qtype + "\t:\t" + matcher + "\n"
|
|
h.AssertEqualString(t, table, d.String(), msg)
|
|
}
|
|
|
|
func AssertLookup(t *testing.T, d *DSL, q *backend.Query, n int, err error) []*backend.Response {
|
|
rsp, rspErr := d.Lookup(q)
|
|
if err == nil {
|
|
h.RefuteError(t, err, "Lookup shouldn't return error")
|
|
} else if rspErr == nil {
|
|
t.Logf("Expected error %s but no error was returned", err)
|
|
t.FailNow()
|
|
} else {
|
|
h.AssertEqualString(t, err.Error(), rspErr.Error(), "Expected error not returned")
|
|
}
|
|
|
|
rspStrs := []string{}
|
|
for _, r := range rsp {
|
|
r.ProtocolVersion = 1
|
|
str, err := r.String()
|
|
h.RefuteError(t, err, "sanity")
|
|
rspStrs = append(rspStrs, str)
|
|
}
|
|
|
|
h.AssertEqualInt(t, n, len(rsp), fmt.Sprintf("One response expected, got:\n%s", strings.Join(rspStrs, "")))
|
|
return rsp
|
|
}
|
|
|
|
// Don't test all the autogenerated helpers explicitly, just a common one.
|
|
func TestAutogeneratedExampleRegistersCorrectCallbackWhenRun(t *testing.T) {
|
|
d := New()
|
|
d.SOA(`example\.com`, NullHandler)
|
|
AssertTableEntry(t, d, "SOA", `^(?i)example\.com$`, "SOA callback not registered")
|
|
}
|
|
|
|
func TestDefaultTTLFromNewIsOneHour(t *testing.T) {
|
|
d := New()
|
|
d.SOA(`*`, ReplyHandler("Foo"))
|
|
rsp := AssertLookup(t, d, SOAQuery(), 1, nil)
|
|
h.AssertEqualString(t, "3600", rsp[0].TTL, "Default TTL not honoured")
|
|
}
|
|
|
|
func TestAlternativeTTLCanBeSpecifiedUsingNewWithTTL(t *testing.T) {
|
|
d := NewWithTTL(86400)
|
|
d.SOA(`*`, ReplyHandler("Foo"))
|
|
rsp := AssertLookup(t, d, SOAQuery(), 1, nil)
|
|
h.AssertEqualString(t, "86400", rsp[0].TTL, "Custom TTL not honoured")
|
|
}
|
|
|
|
func TestBeforeCallbackIsCalledIfSpecified(t *testing.T) {
|
|
d := New()
|
|
d.Before(ReplyHandler("Before"))
|
|
d.SOA(`*`, ReplyHandler("SOA 1"))
|
|
d.SOA(`*`, ReplyHandler("SOA 2"))
|
|
rsp := AssertLookup(t, d, SOAQuery(), 4, nil)
|
|
h.AssertEqualString(t, "Before", rsp[0].Content, "First Before not called")
|
|
h.AssertEqualString(t, "SOA 1", rsp[1].Content, "First SOA not called")
|
|
h.AssertEqualString(t, "Before", rsp[2].Content, "Second Before not called")
|
|
h.AssertEqualString(t, "SOA 2", rsp[3].Content, "Second SOA not called")
|
|
}
|
|
|
|
func TestLookupCallbackOrderIsDefined(t *testing.T) {
|
|
d := New()
|
|
d.SOA(`*`, ReplyHandler("SOA 1"))
|
|
d.MX(`*`, ReplyHandler("MX 1"))
|
|
d.SOA(`*`, ReplyHandler("SOA 2"))
|
|
d.SOA(`*`, ReplyHandler("SOA 3"))
|
|
d.AAAA(`*`, ReplyHandler("AAAA 1"))
|
|
d.A(`*`, ReplyHandler("AAAA 2"))
|
|
rsp := AssertLookup(t, d, h.FakeQuery(1), 6, nil)
|
|
msg := "Order is wrong"
|
|
h.AssertEqualString(t, "SOA 1", rsp[0].Content, msg)
|
|
h.AssertEqualString(t, "SOA 2", rsp[1].Content, msg)
|
|
h.AssertEqualString(t, "SOA 3", rsp[2].Content, msg)
|
|
h.AssertEqualString(t, "MX 1", rsp[3].Content, msg)
|
|
h.AssertEqualString(t, "AAAA 1", rsp[4].Content, msg)
|
|
h.AssertEqualString(t, "AAAA 2", rsp[5].Content, msg)
|
|
}
|
|
|
|
func TestOnlyMatchingCallbacksAreRun(t *testing.T) {
|
|
d := New()
|
|
d.SOA(`example\.com`, ReplyHandler("Good"))
|
|
d.SOA(`example\.org`, ReplyHandler("Bad"))
|
|
rsp := AssertLookup(t, d, SOAQuery(), 1, nil)
|
|
h.AssertEqualString(t, "Good", rsp[0].Content, "Wrong callback run")
|
|
}
|
|
|
|
func TestOnlyCallbacksOfTheRightQTypeAreRun(t *testing.T) {
|
|
d := New()
|
|
d.SOA(`example\.com`, ReplyHandler("Good"))
|
|
d.NS(`example\.com`, ReplyHandler("Bad"))
|
|
rsp := AssertLookup(t, d, SOAQuery(), 1, nil)
|
|
h.AssertEqualString(t, "Good", rsp[0].Content, "Wrong callback run")
|
|
}
|
|
|
|
func TestCaptureGroupsArePutIntoContextMatches(t *testing.T) {
|
|
d := New()
|
|
var captures []string
|
|
d.SOA(`([a-z]{3})\.([a-z]{3})\.([a-z]{3})\.example\.com`, func(c *Context) {
|
|
captures = c.Matches
|
|
c.Reply("OK")
|
|
})
|
|
q := SOAQuery()
|
|
q.QName = "BAZ.bar.foo.example.com"
|
|
rsp := AssertLookup(t, d, q, 1, nil)
|
|
h.AssertEqualInt(t, 3, len(captures), "Wrong number of match groups returned")
|
|
h.AssertEqualString(t, "OK", rsp[0].Content, "Wrong callback run?")
|
|
// case-insensitive, so we don't mangle these
|
|
h.AssertEqualString(t, "BAZ", captures[0], "Part 1 not captured")
|
|
h.AssertEqualString(t, "bar", captures[1], "Part 2 not captured")
|
|
h.AssertEqualString(t, "foo", captures[2], "Part 3 not captured")
|
|
}
|
|
|
|
func TestBeforeCanModifyCaptureGroups(t *testing.T) {
|
|
d := New()
|
|
d.Before(func(c *Context) { c.Matches = append(c.Matches, "modify-cg") })
|
|
d.SOA(`*`, func(c *Context) { c.Reply(c.Matches[0]) })
|
|
rsp := AssertLookup(t, d, SOAQuery(), 1, nil)
|
|
h.AssertEqualString(t, "modify-cg", rsp[0].Content, "Capture modification lost")
|
|
}
|
|
|
|
func TestChangesToMatchesInOrdinaryCallbacksDoNotPersist(t *testing.T) {
|
|
d := New()
|
|
var ok bool
|
|
|
|
d.SOA(`*`, func(c *Context) { c.Matches = append(c.Matches, "Bad") })
|
|
d.SOA(`*`, func(c *Context) { ok = (len(c.Matches) == 0) })
|
|
AssertLookup(t, d, SOAQuery(), 0, nil)
|
|
h.Assert(t, ok, "Change was persisted")
|
|
}
|
|
|
|
func TestCallbackReturningErrorIsReported(t *testing.T) {
|
|
d := New()
|
|
d.SOA(`*`, ErrorReplyHandler)
|
|
AssertLookup(t, d, SOAQuery(), 0, ErrorReplyError)
|
|
}
|
|
|
|
func TestCallbackReturningErrorBlanksAnswers(t *testing.T) {
|
|
d := New()
|
|
d.SOA(`*`, ReplyHandler("Foo"))
|
|
d.SOA(`*`, ErrorReplyHandler)
|
|
AssertLookup(t, d, SOAQuery(), 0, ErrorReplyError)
|
|
}
|
|
|
|
func TestCallbackReturningErrorStopsLaterCallbacksFromRunning(t *testing.T) {
|
|
d := New()
|
|
ok := true
|
|
d.SOA(`*`, ErrorReplyHandler)
|
|
d.SOA(`*`, func(c *Context) { ok = false })
|
|
AssertLookup(t, d, SOAQuery(), 0, ErrorReplyError)
|
|
h.Assert(t, ok, "Later callback was run")
|
|
}
|