Beispiel #1
0
func BenchmarkLookup(b *testing.B) {
	zone, err := Parse(strings.NewReader(dbMiekNL), testzone, "stdin")
	if err != nil {
		return
	}

	fm := File{Next: test.ErrorHandler(), Zones: Zones{Z: map[string]*Zone{testzone: zone}, Names: []string{testzone}}}
	ctx := context.TODO()
	rec := middleware.NewResponseRecorder(&test.ResponseWriter{})

	tc := test.Case{
		Qname: "www.miek.nl.", Qtype: dns.TypeA,
		Answer: []dns.RR{
			test.CNAME("www.miek.nl.	1800	IN	CNAME	a.miek.nl."),
			test.A("a.miek.nl.	1800	IN	A	139.162.196.78"),
		},
	}

	m := tc.Msg()

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		fm.ServeDNS(ctx, rec, m)
	}
}
Beispiel #2
0
func TestDebugLookupFalse(t *testing.T) {
	for _, serv := range servicesDebug {
		set(t, etc, serv.Key, 0, serv)
		defer delete(t, etc, serv.Key)
	}
	for _, tc := range dnsTestCasesDebugFalse {
		m := tc.Msg()

		rec := middleware.NewResponseRecorder(&test.ResponseWriter{})
		_, err := etc.ServeDNS(ctxt, rec, m)
		if err != nil {
			t.Errorf("expected no error, got %v\n", err)
			continue
		}
		resp := rec.Msg()

		sort.Sort(test.RRSet(resp.Answer))
		sort.Sort(test.RRSet(resp.Ns))
		sort.Sort(test.RRSet(resp.Extra))

		if !test.Header(t, tc, resp) {
			t.Logf("%v\n", resp)
			continue
		}
		if !test.Section(t, tc, test.Answer, resp.Answer) {
			t.Logf("%v\n", resp)
		}
		if !test.Section(t, tc, test.Ns, resp.Ns) {
			t.Logf("%v\n", resp)
		}
		if !test.Section(t, tc, test.Extra, resp.Extra) {
			t.Logf("%v\n", resp)
		}
	}
}
Beispiel #3
0
func TestLookup(t *testing.T) {
	for _, serv := range services {
		set(t, etc, serv.Key, 0, serv)
		defer delete(t, etc, serv.Key)
	}
	for _, tc := range dnsTestCases {
		m := tc.Msg()

		rec := middleware.NewResponseRecorder(&test.ResponseWriter{})
		_, err := etc.ServeDNS(ctxt, rec, m)
		if err != nil {
			t.Errorf("expected no error, got: %v for %s %s\n", err, m.Question[0].Name, dns.Type(m.Question[0].Qtype))
			return
		}
		resp := rec.Msg()

		sort.Sort(test.RRSet(resp.Answer))
		sort.Sort(test.RRSet(resp.Ns))
		sort.Sort(test.RRSet(resp.Extra))

		if !test.Header(t, tc, resp) {
			t.Logf("%v\n", resp)
			continue
		}
		if !test.Section(t, tc, test.Answer, resp.Answer) {
			t.Logf("%v\n", resp)
		}
		if !test.Section(t, tc, test.Ns, resp.Ns) {
			t.Logf("%v\n", resp)
		}
		if !test.Section(t, tc, test.Extra, resp.Extra) {
			t.Logf("%v\n", resp)
		}
	}
}
Beispiel #4
0
func BenchmarkLookupDNSSEC(b *testing.B) {
	zone, err := Parse(strings.NewReader(dbMiekNL_signed), testzone, "stdin")
	if err != nil {
		return
	}

	fm := File{Next: test.ErrorHandler(), Zones: Zones{Z: map[string]*Zone{testzone: zone}, Names: []string{testzone}}}
	ctx := context.TODO()
	rec := middleware.NewResponseRecorder(&test.ResponseWriter{})

	tc := test.Case{
		Qname: "b.miek.nl.", Qtype: dns.TypeA, Do: true,
		Rcode: dns.RcodeNameError,
		Ns: []dns.RR{
			test.NSEC("archive.miek.nl.	14400	IN	NSEC	go.dns.miek.nl. CNAME RRSIG NSEC"),
			test.RRSIG("archive.miek.nl.	14400	IN	RRSIG	NSEC 8 3 14400 20160426031301 20160327031301 12051 miek.nl. jEpx8lcp4do5fWXg="),
			test.NSEC("miek.nl.	14400	IN	NSEC	a.miek.nl. A NS SOA MX AAAA RRSIG NSEC DNSKEY"),
			test.RRSIG("miek.nl.	14400	IN	RRSIG	NSEC 8 2 14400 20160426031301 20160327031301 12051 miek.nl. mFfc3r/9PSC1H6oSpdC"),
			test.RRSIG("miek.nl.	1800	IN	RRSIG	SOA 8 2 1800 20160426031301 20160327031301 12051 miek.nl. FIrzy07acBbtyQczy1dc="),
			test.SOA("miek.nl.	1800	IN	SOA	linode.atoom.net. miek.miek.nl. 1282630057 14400 3600 604800 14400"),
		},
	}

	m := tc.Msg()

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		fm.ServeDNS(ctx, rec, m)
	}
}
Beispiel #5
0
func TestLoggedStatus(t *testing.T) {
	var f bytes.Buffer
	var next erroringMiddleware
	rule := Rule{
		NameScope: ".",
		Format:    DefaultLogFormat,
		Log:       log.New(&f, "", 0),
	}

	logger := Logger{
		Rules: []Rule{rule},
		Next:  next,
	}

	ctx := context.TODO()
	r := new(dns.Msg)
	r.SetQuestion("example.org.", dns.TypeA)

	rec := middleware.NewResponseRecorder(&test.ResponseWriter{})

	rcode, _ := logger.ServeDNS(ctx, rec, r)
	if rcode != 0 {
		t.Error("Expected rcode to be 0 - was", rcode)
	}

	logged := f.String()
	if !strings.Contains(logged, "A IN example.org. udp false 512") {
		t.Error("Expected it to be logged. Logged string -", logged)
	}
}
Beispiel #6
0
func (l Logger) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
	state := middleware.State{W: w, Req: r}
	for _, rule := range l.Rules {
		if middleware.Name(rule.NameScope).Matches(state.Name()) {
			responseRecorder := middleware.NewResponseRecorder(w)
			rcode, err := l.Next.ServeDNS(ctx, responseRecorder, r)

			if rcode > 0 {
				// There was an error up the chain, but no response has been written yet.
				// The error must be handled here so the log entry will record the response size.
				if l.ErrorFunc != nil {
					l.ErrorFunc(responseRecorder, r, rcode)
				} else {
					rc := middleware.RcodeToString(rcode)

					answer := new(dns.Msg)
					answer.SetRcode(r, rcode)
					state.SizeAndDo(answer)

					metrics.Report(state, metrics.Dropped, rc, answer.Len(), time.Now())
					w.WriteMsg(answer)
				}
				rcode = 0
			}
			rep := middleware.NewReplacer(r, responseRecorder, CommonLogEmptyValue)
			rule.Log.Println(rep.Replace(rule.Format))
			return rcode, err

		}
	}
	return l.Next.ServeDNS(ctx, w, r)
}
Beispiel #7
0
func TestStubCycle(t *testing.T) {
	// reuse servics from stub_test.go
	for _, serv := range servicesStub {
		set(t, etc, serv.Key, 0, serv)
		defer delete(t, etc, serv.Key)
	}
	etc.updateStubZones()

	for _, tc := range dnsTestCasesCycleStub {
		m := tc.Msg()
		if tc.Do {
			// add our wacky edns fluff
			m.Extra[0] = ednsStub
		}

		rec := middleware.NewResponseRecorder(&test.ResponseWriter{})
		_, err := etc.ServeDNS(ctxt, rec, m)
		if err == nil {
			t.Errorf("expected error, got none")
			continue
		}
		// err should have been, set msg is nil, CoreDNS middlware handling takes
		// care of proper error to client.
	}
}
Beispiel #8
0
func TestLookupNil(t *testing.T) {
	fm := File{Next: test.ErrorHandler(), Zones: Zones{Z: map[string]*Zone{testzone: nil}, Names: []string{testzone}}}
	ctx := context.TODO()

	m := dnsTestCases[0].Msg()
	rec := middleware.NewResponseRecorder(&test.ResponseWriter{})
	fm.ServeDNS(ctx, rec, m)
}
Beispiel #9
0
func TestErrors(t *testing.T) {
	buf := bytes.Buffer{}
	em := ErrorHandler{Log: log.New(&buf, "", 0)}

	testErr := errors.New("test error")
	tests := []struct {
		next         middleware.Handler
		expectedCode int
		expectedLog  string
		expectedErr  error
	}{
		{
			next:         genErrorHandler(dns.RcodeSuccess, nil),
			expectedCode: dns.RcodeSuccess,
			expectedLog:  "",
			expectedErr:  nil,
		},
		{
			next:         genErrorHandler(dns.RcodeNotAuth, testErr),
			expectedCode: dns.RcodeNotAuth,
			expectedLog:  fmt.Sprintf("[ERROR %d %s] %v\n", dns.RcodeNotAuth, "example.org. A", testErr),
			expectedErr:  testErr,
		},
	}

	ctx := context.TODO()
	req := new(dns.Msg)
	req.SetQuestion("example.org.", dns.TypeA)

	for i, tc := range tests {
		em.Next = tc.next
		buf.Reset()
		rec := middleware.NewResponseRecorder(&test.ResponseWriter{})
		code, err := em.ServeDNS(ctx, rec, req)

		if err != tc.expectedErr {
			t.Errorf("Test %d: Expected error %v, but got %v",
				i, tc.expectedErr, err)
		}
		if code != tc.expectedCode {
			t.Errorf("Test %d: Expected status code %d, but got %d",
				i, tc.expectedCode, code)
		}
		if log := buf.String(); !strings.Contains(log, tc.expectedLog) {
			t.Errorf("Test %d: Expected log %q, but got %q",
				i, tc.expectedLog, log)
		}
	}
}
Beispiel #10
0
func (m Metrics) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
	state := middleware.State{W: w, Req: r}

	qname := state.QName()
	zone := middleware.Zones(m.ZoneNames).Matches(qname)
	if zone == "" {
		zone = "."
	}

	// Record response to get status code and size of the reply.
	rw := middleware.NewResponseRecorder(w)
	status, err := m.Next.ServeDNS(ctx, rw, r)

	Report(state, zone, rw.Rcode(), rw.Size(), rw.Start())

	return status, err
}
Beispiel #11
0
func TestStubLookup(t *testing.T) {
	for _, serv := range servicesStub {
		set(t, etc, serv.Key, 0, serv)
		defer delete(t, etc, serv.Key)
	}
	etc.updateStubZones()

	for _, tc := range dnsTestCasesStub {
		m := tc.Msg()

		rec := middleware.NewResponseRecorder(&test.ResponseWriter{})
		_, err := etc.ServeDNS(ctxt, rec, m)
		if err != nil {
			if tc.Rcode != dns.RcodeServerFailure {
				t.Errorf("expected no error, got %v\n", err)
			}
			// This is OK, we expect this backend to *not* work.
			continue
		}
		resp := rec.Msg()
		if resp == nil {
			// etcd not running?
			continue
		}

		sort.Sort(test.RRSet(resp.Answer))
		sort.Sort(test.RRSet(resp.Ns))
		sort.Sort(test.RRSet(resp.Extra))

		if !test.Header(t, tc, resp) {
			t.Logf("%v\n", resp)
			continue
		}
		if !test.Section(t, tc, test.Answer, resp.Answer) {
			t.Logf("%v\n", resp)
		}
		if !test.Section(t, tc, test.Ns, resp.Ns) {
			t.Logf("%v\n", resp)
		}
		if !test.Section(t, tc, test.Extra, resp.Extra) {
			t.Logf("%v\n", resp)
		}
	}
}
Beispiel #12
0
func TestLookupZone(t *testing.T) {
	zone, err := file.Parse(strings.NewReader(dbMiekNL), "miek.nl.", "stdin")
	if err != nil {
		return
	}
	fm := file.File{Next: test.ErrorHandler(), Zones: file.Zones{Z: map[string]*file.Zone{"miek.nl.": zone}, Names: []string{"miek.nl."}}}
	dnskey, rm1, rm2 := newKey(t)
	defer rm1()
	defer rm2()
	dh := NewDnssec([]string{"miek.nl."}, []*DNSKEY{dnskey}, fm)
	ctx := context.TODO()

	for _, tc := range dnsTestCases {
		m := tc.Msg()

		rec := middleware.NewResponseRecorder(&test.ResponseWriter{})
		_, err := dh.ServeDNS(ctx, rec, m)
		if err != nil {
			t.Errorf("expected no error, got %v\n", err)
			return
		}
		resp := rec.Msg()

		sort.Sort(test.RRSet(resp.Answer))
		sort.Sort(test.RRSet(resp.Ns))
		sort.Sort(test.RRSet(resp.Extra))

		if !test.Header(t, tc, resp) {
			t.Logf("%v\n", resp)
			continue
		}
		if !test.Section(t, tc, test.Answer, resp.Answer) {
			t.Logf("%v\n", resp)
		}
		if !test.Section(t, tc, test.Ns, resp.Ns) {
			t.Logf("%v\n", resp)
		}
		if !test.Section(t, tc, test.Extra, resp.Extra) {
			t.Logf("%v\n", resp)
		}
	}
}
Beispiel #13
0
func TestLookupENT(t *testing.T) {
	zone, err := Parse(strings.NewReader(dbMiekENTNL), testzone, "stdin")
	if err != nil {
		t.Fatalf("expect no error when reading zone, got %q", err)
	}

	fm := File{Next: test.ErrorHandler(), Zones: Zones{Z: map[string]*Zone{testzone: zone}, Names: []string{testzone}}}
	ctx := context.TODO()

	for _, tc := range entTestCases {
		m := tc.Msg()

		rec := middleware.NewResponseRecorder(&test.ResponseWriter{})
		_, err := fm.ServeDNS(ctx, rec, m)
		if err != nil {
			t.Errorf("expected no error, got %v\n", err)
			return
		}
		resp := rec.Msg()

		sort.Sort(test.RRSet(resp.Answer))
		sort.Sort(test.RRSet(resp.Ns))
		sort.Sort(test.RRSet(resp.Extra))

		if !test.Header(t, tc, resp) {
			t.Logf("%v\n", resp)
			continue
		}

		if !test.Section(t, tc, test.Answer, resp.Answer) {
			t.Logf("%v\n", resp)
		}
		if !test.Section(t, tc, test.Ns, resp.Ns) {
			t.Logf("%v\n", resp)

		}
		if !test.Section(t, tc, test.Extra, resp.Extra) {
			t.Logf("%v\n", resp)
		}
	}
}
Beispiel #14
0
func TestMultiLookup(t *testing.T) {
	etcMulti := etc
	etcMulti.Zones = []string{"skydns.test.", "miek.nl."}
	etcMulti.Next = test.ErrorHandler()

	for _, serv := range servicesMulti {
		set(t, etcMulti, serv.Key, 0, serv)
		defer delete(t, etcMulti, serv.Key)
	}
	for _, tc := range dnsTestCasesMulti {
		m := tc.Msg()

		rec := middleware.NewResponseRecorder(&test.ResponseWriter{})
		_, err := etcMulti.ServeDNS(ctxt, rec, m)
		if err != nil {
			t.Errorf("expected no error, got %v\n", err)
			return
		}
		resp := rec.Msg()

		sort.Sort(test.RRSet(resp.Answer))
		sort.Sort(test.RRSet(resp.Ns))
		sort.Sort(test.RRSet(resp.Extra))

		if !test.Header(t, tc, resp) {
			t.Logf("%v\n", resp)
			continue
		}
		if !test.Section(t, tc, test.Answer, resp.Answer) {
			t.Logf("%v\n", resp)
		}
		if !test.Section(t, tc, test.Ns, resp.Ns) {
			t.Logf("%v\n", resp)
		}
		if !test.Section(t, tc, test.Extra, resp.Extra) {
			t.Logf("%v\n", resp)
		}
	}
}
Beispiel #15
0
func TestVisibleErrorWithPanic(t *testing.T) {
	const panicMsg = "I'm a panic"
	eh := ErrorHandler{
		Debug: true,
		Next: middleware.HandlerFunc(func(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
			panic(panicMsg)
		}),
	}

	ctx := context.TODO()
	req := new(dns.Msg)
	req.SetQuestion("example.org.", dns.TypeA)

	rec := middleware.NewResponseRecorder(&test.ResponseWriter{})

	code, err := eh.ServeDNS(ctx, rec, req)
	if code != 0 {
		t.Errorf("Expected error handler to return 0 (it should write to response), got status %d", code)
	}
	if err != nil {
		t.Errorf("Expected error handler to return nil error (it should panic!), but got '%v'", err)
	}
}
Beispiel #16
0
func TestLookupDNSKEY(t *testing.T) {
	dnskey, rm1, rm2 := newKey(t)
	defer rm1()
	defer rm2()
	dh := NewDnssec([]string{"miek.nl."}, []*DNSKEY{dnskey}, test.ErrorHandler())
	ctx := context.TODO()

	for _, tc := range dnssecTestCases {
		m := tc.Msg()

		rec := middleware.NewResponseRecorder(&test.ResponseWriter{})
		_, err := dh.ServeDNS(ctx, rec, m)
		if err != nil {
			t.Errorf("expected no error, got %v\n", err)
			return
		}
		resp := rec.Msg()

		sort.Sort(test.RRSet(resp.Answer))
		sort.Sort(test.RRSet(resp.Ns))
		sort.Sort(test.RRSet(resp.Extra))

		if !test.Header(t, tc, resp) {
			t.Logf("%v\n", resp)
			continue
		}
		if !test.Section(t, tc, test.Answer, resp.Answer) {
			t.Logf("%v\n", resp)
		}
		if !test.Section(t, tc, test.Ns, resp.Ns) {
			t.Logf("%v\n", resp)
		}
		if !test.Section(t, tc, test.Extra, resp.Extra) {
			t.Logf("%v\n", resp)
		}
	}
}
Beispiel #17
0
func TestChaos(t *testing.T) {
	em := Chaos{
		Version: version,
		Authors: map[string]bool{"Miek Gieben": true},
	}

	tests := []struct {
		next          middleware.Handler
		qname         string
		qtype         uint16
		expectedCode  int
		expectedReply string
		expectedErr   error
	}{
		{
			next:          genHandler(dns.RcodeSuccess, nil),
			qname:         "version.bind",
			expectedCode:  dns.RcodeSuccess,
			expectedReply: version,
			expectedErr:   nil,
		},
		{
			next:          genHandler(dns.RcodeSuccess, nil),
			qname:         "authors.bind",
			expectedCode:  dns.RcodeSuccess,
			expectedReply: "Miek Gieben",
			expectedErr:   nil,
		},
		{
			next:         genHandler(dns.RcodeSuccess, nil),
			qname:        "authors.bind",
			qtype:        dns.TypeSRV,
			expectedCode: dns.RcodeSuccess,
			expectedErr:  nil,
		},
	}

	ctx := context.TODO()

	for i, tc := range tests {
		req := new(dns.Msg)
		if tc.qtype == 0 {
			tc.qtype = dns.TypeTXT
		}
		req.SetQuestion(dns.Fqdn(tc.qname), tc.qtype)
		req.Question[0].Qclass = dns.ClassCHAOS
		em.Next = tc.next

		rec := middleware.NewResponseRecorder(&test.ResponseWriter{})
		code, err := em.ServeDNS(ctx, rec, req)

		if err != tc.expectedErr {
			t.Errorf("Test %d: Expected error %v, but got %v", i, tc.expectedErr, err)
		}
		if code != int(tc.expectedCode) {
			t.Errorf("Test %d: Expected status code %d, but got %d", i, tc.expectedCode, code)
		}
		if tc.expectedReply != "" {
			answer := rec.Msg().Answer[0].(*dns.TXT).Txt[0]
			if answer != tc.expectedReply {
				t.Errorf("Test %d: Expected answer %s, but got %s", i, tc.expectedReply, answer)
			}
		}
	}
}
Beispiel #18
0
func TestRewrite(t *testing.T) {
	rw := Rewrite{
		Next: middleware.HandlerFunc(msgPrinter),
		Rules: []Rule{
			NewSimpleRule("from.nl.", "to.nl."),
			NewSimpleRule("CH", "IN"),
			NewSimpleRule("ANY", "HINFO"),
		},
		noRevert: true,
	}

	tests := []struct {
		from  string
		fromT uint16
		fromC uint16
		to    string
		toT   uint16
		toC   uint16
	}{
		{"from.nl.", dns.TypeA, dns.ClassINET, "to.nl.", dns.TypeA, dns.ClassINET},
		{"a.nl.", dns.TypeA, dns.ClassINET, "a.nl.", dns.TypeA, dns.ClassINET},
		{"a.nl.", dns.TypeA, dns.ClassCHAOS, "a.nl.", dns.TypeA, dns.ClassINET},
		{"a.nl.", dns.TypeANY, dns.ClassINET, "a.nl.", dns.TypeHINFO, dns.ClassINET},
		// name is rewritten, type is not.
		{"from.nl.", dns.TypeANY, dns.ClassINET, "to.nl.", dns.TypeANY, dns.ClassINET},
		// name is not, type is, but class is, because class is the 2nd rule.
		{"a.nl.", dns.TypeANY, dns.ClassCHAOS, "a.nl.", dns.TypeANY, dns.ClassINET},
	}

	ctx := context.TODO()
	for i, tc := range tests {
		m := new(dns.Msg)
		m.SetQuestion(tc.from, tc.fromT)
		m.Question[0].Qclass = tc.fromC

		rec := middleware.NewResponseRecorder(&test.ResponseWriter{})
		rw.ServeDNS(ctx, rec, m)
		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)
		}
		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)
		}
		if resp.Question[0].Qclass != tc.toC {
			t.Errorf("Test %d: Expected Class to be '%d' but was '%d'", i, tc.toC, resp.Question[0].Qclass)
		}
	}

	/*
		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}", ""},
		}

		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)
		}
	*/
	/*
		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},
		}

		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)
			}

			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)
			}
			if s.statusExpected {
				if rec.Body.String() != "" {
					t.Errorf("Test %d: Expected empty body but found %s", i, rec.Body.String())
				}
				if code != s.status {
					t.Errorf("Test %d: Expected status code %d found %d", i, s.status, code)
				}
			} else {
				if code != 0 {
					t.Errorf("Test %d: Expected no status code found %d", i, code)
				}
			}
		}
	*/
}
Beispiel #19
0
func TestLoadBalance(t *testing.T) {
	rm := RoundRobin{Next: handler()}

	// the first X records must be cnames after this test
	tests := []struct {
		answer      []dns.RR
		extra       []dns.RR
		cnameAnswer int
		cnameExtra  int
	}{
		{
			answer: []dns.RR{
				newCNAME("cname1.region2.skydns.test.	300	IN	CNAME	cname2.region2.skydns.test."),
				newCNAME("cname2.region2.skydns.test.	300	IN	CNAME	cname3.region2.skydns.test."),
				newCNAME("cname5.region2.skydns.test.	300	IN	CNAME	cname6.region2.skydns.test."),
				newCNAME("cname6.region2.skydns.test.	300	IN	CNAME	endpoint.region2.skydns.test."),
				newA("endpoint.region2.skydns.test.	300	IN	A	10.240.0.1"),
			},
			cnameAnswer: 4,
		},
		{
			answer: []dns.RR{
				newA("endpoint.region2.skydns.test.	300	IN	A	10.240.0.1"),
				newCNAME("cname.region2.skydns.test.	300	IN	CNAME	endpoint.region2.skydns.test."),
			},
			cnameAnswer: 1,
		},
		{
			answer: []dns.RR{
				newA("endpoint.region2.skydns.test.	300	IN	A	10.240.0.1"),
				newA("endpoint.region2.skydns.test.	300	IN	A	10.240.0.2"),
				newCNAME("cname2.region2.skydns.test.	300	IN	CNAME	cname3.region2.skydns.test."),
				newA("endpoint.region2.skydns.test.	300	IN	A	10.240.0.3"),
			},
			extra: []dns.RR{
				newA("endpoint.region2.skydns.test.	300	IN	A	10.240.0.1"),
				newAAAA("endpoint.region2.skydns.test.	300	IN	AAAA	::1"),
				newCNAME("cname2.region2.skydns.test.	300	IN	CNAME	cname3.region2.skydns.test."),
				newA("endpoint.region2.skydns.test.	300	IN	A	10.240.0.3"),
				newAAAA("endpoint.region2.skydns.test.	300	IN	AAAA	::2"),
			},
			cnameAnswer: 1,
			cnameExtra:  1,
		},
	}

	rec := middleware.NewResponseRecorder(&test.ResponseWriter{})

	for i, test := range tests {
		req := new(dns.Msg)
		req.SetQuestion("region2.skydns.test.", dns.TypeSRV)
		req.Answer = test.answer
		req.Extra = test.extra

		_, err := rm.ServeDNS(context.TODO(), rec, req)
		if err != nil {
			t.Errorf("Test %d: Expected no error, but got %s", i, err)
			continue

		}
		cname := 0
		for _, r := range rec.Msg().Answer {
			if r.Header().Rrtype != dns.TypeCNAME {
				break
			}
			cname++
		}
		if cname != test.cnameAnswer {
			t.Errorf("Test %d: Expected %d cnames in Answer, but got %d", i, test.cnameAnswer, cname)
		}
		cname = 0
		for _, r := range rec.Msg().Extra {
			if r.Header().Rrtype != dns.TypeCNAME {
				break
			}
			cname++
		}
		if cname != test.cnameExtra {
			t.Errorf("Test %d: Expected %d cname in Extra, but got %d", i, test.cnameExtra, cname)
		}
	}
}