aboutsummaryrefslogtreecommitdiff
path: root/middleware/rewrite/rewrite_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'middleware/rewrite/rewrite_test.go')
-rw-r--r--middleware/rewrite/rewrite_test.go280
1 files changed, 212 insertions, 68 deletions
diff --git a/middleware/rewrite/rewrite_test.go b/middleware/rewrite/rewrite_test.go
index 64d0d5eec..e4c0afc50 100644
--- a/middleware/rewrite/rewrite_test.go
+++ b/middleware/rewrite/rewrite_test.go
@@ -1,6 +1,8 @@
package rewrite
import (
+ "bytes"
+ "reflect"
"testing"
"github.com/coredns/coredns/middleware"
@@ -16,14 +18,73 @@ func msgPrinter(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, err
return 0, nil
}
+func TestNewRule(t *testing.T) {
+ tests := []struct {
+ args []string
+ shouldError bool
+ expType reflect.Type
+ }{
+ {[]string{}, true, nil},
+ {[]string{"foo"}, true, nil},
+ {[]string{"name"}, true, nil},
+ {[]string{"name", "a.com"}, true, nil},
+ {[]string{"name", "a.com", "b.com", "c.com"}, true, nil},
+ {[]string{"name", "a.com", "b.com"}, false, reflect.TypeOf(&nameRule{})},
+ {[]string{"type"}, true, nil},
+ {[]string{"type", "a"}, true, nil},
+ {[]string{"type", "any", "a", "a"}, true, nil},
+ {[]string{"type", "any", "a"}, false, reflect.TypeOf(&typeRule{})},
+ {[]string{"type", "XY", "WV"}, true, nil},
+ {[]string{"type", "ANY", "WV"}, true, nil},
+ {[]string{"class"}, true, nil},
+ {[]string{"class", "IN"}, true, nil},
+ {[]string{"class", "ch", "in", "in"}, true, nil},
+ {[]string{"class", "ch", "in"}, false, reflect.TypeOf(&classRule{})},
+ {[]string{"class", "XY", "WV"}, true, nil},
+ {[]string{"class", "IN", "WV"}, true, nil},
+ {[]string{"edns0"}, true, nil},
+ {[]string{"edns0", "local"}, true, nil},
+ {[]string{"edns0", "local", "set"}, true, nil},
+ {[]string{"edns0", "local", "set", "0xffee"}, true, nil},
+ {[]string{"edns0", "local", "set", "65518", "abcdefg"}, false, reflect.TypeOf(&edns0LocalRule{})},
+ {[]string{"edns0", "local", "set", "0xffee", "abcdefg"}, false, reflect.TypeOf(&edns0LocalRule{})},
+ {[]string{"edns0", "local", "append", "0xffee", "abcdefg"}, false, reflect.TypeOf(&edns0LocalRule{})},
+ {[]string{"edns0", "local", "replace", "0xffee", "abcdefg"}, false, reflect.TypeOf(&edns0LocalRule{})},
+ {[]string{"edns0", "local", "foo", "0xffee", "abcdefg"}, true, nil},
+ {[]string{"edns0", "local", "set", "0xffee", "0xabcdefg"}, true, nil},
+ {[]string{"edns0", "nsid", "set", "junk"}, true, nil},
+ {[]string{"edns0", "nsid", "set"}, false, reflect.TypeOf(&edns0NsidRule{})},
+ {[]string{"edns0", "nsid", "append"}, false, reflect.TypeOf(&edns0NsidRule{})},
+ {[]string{"edns0", "nsid", "replace"}, false, reflect.TypeOf(&edns0NsidRule{})},
+ {[]string{"edns0", "nsid", "foo"}, true, nil},
+ }
+
+ for i, tc := range tests {
+ r, err := newRule(tc.args...)
+ if err == nil && tc.shouldError {
+ t.Errorf("Test %d: expected error but got success", i)
+ } else if err != nil && !tc.shouldError {
+ t.Errorf("Test %d: expected success but got error: %s", i, err)
+ }
+
+ if !tc.shouldError && reflect.TypeOf(r) != tc.expType {
+ t.Errorf("Test %d: expected %q but got %q", i, tc.expType, r)
+ }
+ }
+}
+
func TestRewrite(t *testing.T) {
+ rules := []Rule{}
+ r, _ := newNameRule("from.nl.", "to.nl.")
+ rules = append(rules, r)
+ r, _ = newClassRule("CH", "IN")
+ rules = append(rules, r)
+ r, _ = newTypeRule("ANY", "HINFO")
+ rules = append(rules, r)
+
rw := Rewrite{
- Next: middleware.HandlerFunc(msgPrinter),
- Rules: []Rule{
- Fields["name"].New("from.nl.", "to.nl."),
- Fields["class"].New("CH", "IN"),
- Fields["type"].New("ANY", "HINFO"),
- },
+ Next: middleware.HandlerFunc(msgPrinter),
+ Rules: rules,
noRevert: true,
}
@@ -56,7 +117,7 @@ func TestRewrite(t *testing.T) {
resp := rec.Msg
if resp.Question[0].Name != tc.to {
- t.Errorf("Test %d: Expected Name to be '%s' but was '%s'", i, tc.to, resp.Question[0].Name)
+ t.Errorf("Test %d: Expected Name to be %q but was %q", i, tc.to, resp.Question[0].Name)
}
if resp.Question[0].Qtype != tc.toT {
t.Errorf("Test %d: Expected Type to be '%d' but was '%d'", i, tc.toT, resp.Question[0].Qtype)
@@ -65,79 +126,162 @@ func TestRewrite(t *testing.T) {
t.Errorf("Test %d: Expected Class to be '%d' but was '%d'", i, tc.toC, resp.Question[0].Qclass)
}
}
+}
+
+func TestRewriteEDNS0Local(t *testing.T) {
+ rw := Rewrite{
+ Next: middleware.HandlerFunc(msgPrinter),
+ noRevert: true,
+ }
- /*
- regexps := [][]string{
- {"/reg/", ".*", "/to", ""},
- {"/r/", "[a-z]+", "/toaz", "!.html|"},
- {"/url/", "a([a-z0-9]*)s([A-Z]{2})", "/to/{path}", ""},
- {"/ab/", "ab", "/ab?{query}", ".txt|"},
- {"/ab/", "ab", "/ab?type=html&{query}", ".html|"},
- {"/abc/", "ab", "/abc/{file}", ".html|"},
- {"/abcd/", "ab", "/a/{dir}/{file}", ".html|"},
- {"/abcde/", "ab", "/a#{fragment}", ".html|"},
- {"/ab/", `.*\.jpg`, "/ajpg", ""},
- {"/reggrp", `/ad/([0-9]+)([a-z]*)`, "/a{1}/{2}", ""},
- {"/reg2grp", `(.*)`, "/{1}", ""},
- {"/reg3grp", `(.*)/(.*)/(.*)`, "/{1}{2}{3}", ""},
+ tests := []struct {
+ fromOpts []dns.EDNS0
+ args []string
+ toOpts []dns.EDNS0
+ }{
+ {
+ []dns.EDNS0{},
+ []string{"local", "set", "0xffee", "0xabcdef"},
+ []dns.EDNS0{&dns.EDNS0_LOCAL{Code: 0xffee, Data: []byte{0xab, 0xcd, 0xef}}},
+ },
+ {
+ []dns.EDNS0{},
+ []string{"local", "append", "0xffee", "abcdefghijklmnop"},
+ []dns.EDNS0{&dns.EDNS0_LOCAL{Code: 0xffee, Data: []byte("abcdefghijklmnop")}},
+ },
+ {
+ []dns.EDNS0{},
+ []string{"local", "replace", "0xffee", "abcdefghijklmnop"},
+ []dns.EDNS0{},
+ },
+ {
+ []dns.EDNS0{},
+ []string{"nsid", "set"},
+ []dns.EDNS0{&dns.EDNS0_NSID{Code: dns.EDNS0NSID, Nsid: ""}},
+ },
+ {
+ []dns.EDNS0{},
+ []string{"nsid", "append"},
+ []dns.EDNS0{&dns.EDNS0_NSID{Code: dns.EDNS0NSID, Nsid: ""}},
+ },
+ {
+ []dns.EDNS0{},
+ []string{"nsid", "replace"},
+ []dns.EDNS0{},
+ },
+ }
+
+ ctx := context.TODO()
+ for i, tc := range tests {
+ m := new(dns.Msg)
+ m.SetQuestion("example.com.", dns.TypeA)
+ m.Question[0].Qclass = dns.ClassINET
+
+ r, err := newEdns0Rule(tc.args...)
+ if err != nil {
+ t.Errorf("Error creating test rule: %s", err)
+ continue
}
+ rw.Rules = []Rule{r}
- for _, regexpRule := range regexps {
- var ext []string
- if s := strings.Split(regexpRule[3], "|"); len(s) > 1 {
- ext = s[:len(s)-1]
- }
- rule, err := NewComplexRule(regexpRule[0], regexpRule[1], regexpRule[2], 0, ext, nil)
- if err != nil {
- t.Fatal(err)
- }
- rw.Rules = append(rw.Rules, rule)
+ rec := dnsrecorder.New(&test.ResponseWriter{})
+ rw.ServeDNS(ctx, rec, m)
+
+ resp := rec.Msg
+ o := resp.IsEdns0()
+ if o == nil {
+ t.Errorf("Test %d: EDNS0 options not set", i)
+ continue
}
- */
- /*
- statusTests := []struct {
- status int
- base string
- to string
- regexp string
- statusExpected bool
- }{
- {400, "/status", "", "", true},
- {400, "/ignore", "", "", false},
- {400, "/", "", "^/ignore", false},
- {400, "/", "", "(.*)", true},
- {400, "/status", "", "", true},
+ if !optsEqual(o.Option, tc.toOpts) {
+ t.Errorf("Test %d: Expected %v but got %v", i, tc.toOpts, o)
}
+ }
+}
- for i, s := range statusTests {
- urlPath := fmt.Sprintf("/status%d", i)
- rule, err := NewComplexRule(s.base, s.regexp, s.to, s.status, nil, nil)
- if err != nil {
- t.Fatalf("Test %d: No error expected for rule but found %v", i, err)
- }
- rw.Rules = []Rule{rule}
- req, err := http.NewRequest("GET", urlPath, nil)
- if err != nil {
- t.Fatalf("Test %d: Could not create HTTP request: %v", i, err)
- }
+func TestEdns0LocalMultiRule(t *testing.T) {
+ rules := []Rule{}
+ r, _ := newEdns0Rule("local", "replace", "0xffee", "abcdef")
+ rules = append(rules, r)
+ r, _ = newEdns0Rule("local", "set", "0xffee", "fedcba")
+ rules = append(rules, r)
+
+ rw := Rewrite{
+ Next: middleware.HandlerFunc(msgPrinter),
+ Rules: rules,
+ noRevert: true,
+ }
+
+ tests := []struct {
+ fromOpts []dns.EDNS0
+ toOpts []dns.EDNS0
+ }{
+ {
+ nil,
+ []dns.EDNS0{&dns.EDNS0_LOCAL{Code: 0xffee, Data: []byte("fedcba")}},
+ },
+ {
+ []dns.EDNS0{&dns.EDNS0_LOCAL{Code: 0xffee, Data: []byte("foobar")}},
+ []dns.EDNS0{&dns.EDNS0_LOCAL{Code: 0xffee, Data: []byte("abcdef")}},
+ },
+ }
- rec := httptest.NewRecorder()
- code, err := rw.ServeHTTP(rec, req)
- if err != nil {
- t.Fatalf("Test %d: No error expected for handler but found %v", i, err)
+ ctx := context.TODO()
+ for i, tc := range tests {
+ m := new(dns.Msg)
+ m.SetQuestion("example.com.", dns.TypeA)
+ m.Question[0].Qclass = dns.ClassINET
+ if tc.fromOpts != nil {
+ o := m.IsEdns0()
+ if o == nil {
+ m.SetEdns0(4096, true)
+ o = m.IsEdns0()
}
- if s.statusExpected {
- if rec.Body.String() != "" {
- t.Errorf("Test %d: Expected empty body but found %s", i, rec.Body.String())
+ o.Option = append(o.Option, tc.fromOpts...)
+ }
+ rec := dnsrecorder.New(&test.ResponseWriter{})
+ rw.ServeDNS(ctx, rec, m)
+
+ resp := rec.Msg
+ o := resp.IsEdns0()
+ if o == nil {
+ t.Errorf("Test %d: EDNS0 options not set", i)
+ continue
+ }
+ if !optsEqual(o.Option, tc.toOpts) {
+ t.Errorf("Test %d: Expected %v but got %v", i, tc.toOpts, o)
+ }
+ }
+}
+
+func optsEqual(a, b []dns.EDNS0) bool {
+ if len(a) != len(b) {
+ return false
+ }
+ for i := range a {
+ switch aa := a[i].(type) {
+ case *dns.EDNS0_LOCAL:
+ if bb, ok := b[i].(*dns.EDNS0_LOCAL); ok {
+ if aa.Code != bb.Code {
+ return false
}
- if code != s.status {
- t.Errorf("Test %d: Expected status code %d found %d", i, s.status, code)
+ if !bytes.Equal(aa.Data, bb.Data) {
+ return false
}
} else {
- if code != 0 {
- t.Errorf("Test %d: Expected no status code found %d", i, code)
+ return false
+ }
+ case *dns.EDNS0_NSID:
+ if bb, ok := b[i].(*dns.EDNS0_NSID); ok {
+ if aa.Nsid != bb.Nsid {
+ return false
}
+ } else {
+ return false
}
+ default:
+ return false
}
- */
+ }
+ return true
}