mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 10:13:14 -04:00 
			
		
		
		
	Add more tests and include the forgotten chaos_test.go as well
This commit is contained in:
		
							
								
								
									
										83
									
								
								middleware/chaos/chaos_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								middleware/chaos/chaos_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| package chaos | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/miekg/coredns/middleware" | ||||
|  | ||||
| 	"github.com/miekg/dns" | ||||
| 	"golang.org/x/net/context" | ||||
| ) | ||||
|  | ||||
| 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, test := range tests { | ||||
| 		req := new(dns.Msg) | ||||
| 		if test.qtype == 0 { | ||||
| 			test.qtype = dns.TypeTXT | ||||
| 		} | ||||
| 		req.SetQuestion(dns.Fqdn(test.qname), test.qtype) | ||||
| 		em.Next = test.next | ||||
|  | ||||
| 		rec := middleware.NewResponseRecorder(&middleware.TestResponseWriter{}) | ||||
| 		code, err := em.ServeDNS(ctx, rec, req) | ||||
|  | ||||
| 		if err != test.expectedErr { | ||||
| 			t.Errorf("Test %d: Expected error %v, but got %v", i, test.expectedErr, err) | ||||
| 		} | ||||
| 		if code != int(test.expectedCode) { | ||||
| 			t.Errorf("Test %d: Expected status code %d, but got %d", i, test.expectedCode, code) | ||||
| 		} | ||||
| 		if test.expectedReply != "" { | ||||
| 			answer := rec.Msg().Answer[0].(*dns.TXT).Txt[0] | ||||
| 			if answer != test.expectedReply { | ||||
| 				t.Errorf("Test %d: Expected answer %s, but got %s", i, test.expectedReply, answer) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func genHandler(rcode int, err error) middleware.Handler { | ||||
| 	return middleware.HandlerFunc(func(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { | ||||
| 		return rcode, err | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| const version = "CoreDNS-001" | ||||
							
								
								
									
										112
									
								
								middleware/etcd/group_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								middleware/etcd/group_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | ||||
| // +build etcd | ||||
|  | ||||
| package etcd | ||||
|  | ||||
| // etcd needs to be running on http://127.0.0.1:2379 | ||||
| // *and* needs connectivity to the internet for remotely resolving | ||||
| // names. | ||||
|  | ||||
| import ( | ||||
| 	"sort" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/miekg/coredns/middleware" | ||||
| 	"github.com/miekg/coredns/middleware/etcd/msg" | ||||
|  | ||||
| 	"github.com/miekg/dns" | ||||
| ) | ||||
|  | ||||
| func TestGroupLookup(t *testing.T) { | ||||
| 	for _, serv := range servicesGroup { | ||||
| 		set(t, etc, serv.Key, 0, serv) | ||||
| 		defer delete(t, etc, serv.Key) | ||||
| 	} | ||||
| 	for _, tc := range dnsTestCasesGroup { | ||||
| 		m := new(dns.Msg) | ||||
| 		m.SetQuestion(dns.Fqdn(tc.Qname), tc.Qtype) | ||||
|  | ||||
| 		rec := middleware.NewResponseRecorder(&middleware.TestResponseWriter{}) | ||||
| 		_, err := etc.ServeDNS(ctx, rec, m) | ||||
| 		if err != nil { | ||||
| 			t.Errorf("expected no error, got %v\n", err) | ||||
| 			return | ||||
| 		} | ||||
| 		resp := rec.Msg() | ||||
|  | ||||
| 		sort.Sort(rrSet(resp.Answer)) | ||||
| 		sort.Sort(rrSet(resp.Ns)) | ||||
| 		sort.Sort(rrSet(resp.Extra)) | ||||
|  | ||||
| 		if resp.Rcode != tc.Rcode { | ||||
| 			t.Errorf("rcode is %q, expected %q", dns.RcodeToString[resp.Rcode], dns.RcodeToString[tc.Rcode]) | ||||
| 			t.Logf("%v\n", resp) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if len(resp.Answer) != len(tc.Answer) { | ||||
| 			t.Errorf("answer for %q contained %d results, %d expected", tc.Qname, len(resp.Answer), len(tc.Answer)) | ||||
| 			t.Logf("%v\n", resp) | ||||
| 			continue | ||||
| 		} | ||||
| 		if len(resp.Ns) != len(tc.Ns) { | ||||
| 			t.Errorf("authority for %q contained %d results, %d expected", tc.Qname, len(resp.Ns), len(tc.Ns)) | ||||
| 			t.Logf("%v\n", resp) | ||||
| 			continue | ||||
| 		} | ||||
| 		if len(resp.Extra) != len(tc.Extra) { | ||||
| 			t.Errorf("additional for %q contained %d results, %d expected", tc.Qname, len(resp.Extra), len(tc.Extra)) | ||||
| 			t.Logf("%v\n", resp) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if !checkSection(t, tc, Answer, resp.Answer) { | ||||
| 			t.Logf("%v\n", resp) | ||||
| 		} | ||||
| 		if !checkSection(t, tc, Ns, resp.Ns) { | ||||
| 			t.Logf("%v\n", resp) | ||||
|  | ||||
| 		} | ||||
| 		if !checkSection(t, tc, Extra, resp.Extra) { | ||||
| 			t.Logf("%v\n", resp) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Note the key is encoded as DNS name, while in "reality" it is a etcd path. | ||||
| var servicesGroup = []*msg.Service{ | ||||
| 	{Host: "127.0.0.1", Key: "a.dom.skydns.test.", Group: "g1"}, | ||||
| 	{Host: "127.0.0.2", Key: "b.sub.dom.skydns.test.", Group: "g1"}, | ||||
|  | ||||
| 	{Host: "127.0.0.1", Key: "a.dom2.skydns.test.", Group: "g1"}, | ||||
| 	{Host: "127.0.0.2", Key: "b.sub.dom2.skydns.test.", Group: ""}, | ||||
|  | ||||
| 	{Host: "127.0.0.1", Key: "a.dom1.skydns.test.", Group: "g1"}, | ||||
| 	{Host: "127.0.0.2", Key: "b.sub.dom1.skydns.test.", Group: "g2"}, | ||||
| } | ||||
|  | ||||
| var dnsTestCasesGroup = []dnsTestCase{ | ||||
| 	// Groups | ||||
| 	{ | ||||
| 		// hits the group 'g1' and only includes those records | ||||
| 		Qname: "dom.skydns.test.", Qtype: dns.TypeA, | ||||
| 		Answer: []dns.RR{ | ||||
| 			newA("dom.skydns.test. 300 IN A 127.0.0.1"), | ||||
| 			newA("dom.skydns.test. 300 IN A 127.0.0.2"), | ||||
| 		}, | ||||
| 	}, | ||||
| 	{ | ||||
| 		// One has group, the other has not...  Include the non-group always. | ||||
| 		Qname: "dom2.skydns.test.", Qtype: dns.TypeA, | ||||
| 		Answer: []dns.RR{ | ||||
| 			newA("dom2.skydns.test. 300 IN A 127.0.0.1"), | ||||
| 			newA("dom2.skydns.test. 300 IN A 127.0.0.2"), | ||||
| 		}, | ||||
| 	}, | ||||
| 	{ | ||||
| 		// The groups differ. | ||||
| 		Qname: "dom1.skydns.test.", Qtype: dns.TypeA, | ||||
| 		Answer: []dns.RR{ | ||||
| 			newA("dom1.skydns.test. 300 IN A 127.0.0.1"), | ||||
| 		}, | ||||
| 	}, | ||||
| } | ||||
| @@ -41,6 +41,7 @@ func (e Etcd) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i | ||||
| 		// rwrite and return | ||||
| 		// Nodata response | ||||
| 		// also catch other types, so that they return NODATA | ||||
| 		// TODO(miek) nodata function see below | ||||
| 		return 0, nil | ||||
| 	} | ||||
| 	if isEtcdNameError(err) { | ||||
| @@ -55,11 +56,12 @@ func (e Etcd) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i | ||||
| 	} | ||||
|  | ||||
| 	if len(records) == 0 { | ||||
| 		// NODATE function, see below | ||||
| 		m := new(dns.Msg) | ||||
| 		m.SetReply(state.Req) | ||||
| 		m.Ns = []dns.RR{e.SOA(zone, state)} | ||||
| 		state.W.WriteMsg(m) | ||||
| 		return dns.RcodeNameError, nil | ||||
| 		return dns.RcodeSuccess, nil | ||||
|  | ||||
| 	} | ||||
| 	if len(records) > 0 { | ||||
| @@ -68,6 +70,9 @@ func (e Etcd) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i | ||||
| 	if len(extra) > 0 { | ||||
| 		m.Extra = append(m.Extra, extra...) | ||||
| 	} | ||||
|  | ||||
| 	m = dedup(m) | ||||
|  | ||||
| 	state.W.WriteMsg(m) | ||||
| 	return 0, nil | ||||
| } | ||||
| @@ -76,3 +81,11 @@ func (e Etcd) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i | ||||
| func (e Etcd) NoData(zone string, state middleware.State) { | ||||
| 	// TODO(miek): write it | ||||
| } | ||||
|  | ||||
| func dedup(m *dns.Msg) *dns.Msg { | ||||
| 	ma := make(map[string]dns.RR) | ||||
| 	m.Answer = dns.Dedup(m.Answer, ma) | ||||
| 	m.Ns = dns.Dedup(m.Ns, ma) | ||||
| 	m.Extra = dns.Dedup(m.Extra, ma) | ||||
| 	return m | ||||
| } | ||||
|   | ||||
| @@ -36,6 +36,11 @@ var dnsTestCases = []dnsTestCase{ | ||||
| 		Qname: "a.server1.dev.region1.skydns.test.", Qtype: dns.TypeSRV, | ||||
| 		Answer: []dns.RR{newSRV("a.server1.dev.region1.skydns.test. 300 SRV 10 100 8080 dev.server1.")}, | ||||
| 	}, | ||||
| 	// SRV Test (case test) | ||||
| 	{ | ||||
| 		Qname: "a.SERVer1.dEv.region1.skydns.tEst.", Qtype: dns.TypeSRV, | ||||
| 		Answer: []dns.RR{newSRV("a.SERVer1.dEv.region1.skydns.tEst. 300 SRV 10 100 8080 dev.server1.")}, | ||||
| 	}, | ||||
| 	// NXDOMAIN Test | ||||
| 	{ | ||||
| 		Qname: "doesnotexist.skydns.test.", Qtype: dns.TypeA, | ||||
|   | ||||
							
								
								
									
										154
									
								
								middleware/etcd/other_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								middleware/etcd/other_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,154 @@ | ||||
| // +build etcd | ||||
|  | ||||
| // tests mx and txt records | ||||
|  | ||||
| package etcd | ||||
|  | ||||
| // etcd needs to be running on http://127.0.0.1:2379 | ||||
| // *and* needs connectivity to the internet for remotely resolving | ||||
| // names. | ||||
|  | ||||
| import ( | ||||
| 	"sort" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/miekg/coredns/middleware" | ||||
| 	"github.com/miekg/coredns/middleware/etcd/msg" | ||||
|  | ||||
| 	"github.com/miekg/dns" | ||||
| ) | ||||
|  | ||||
| func TestOtherLookup(t *testing.T) { | ||||
| 	for _, serv := range servicesOther { | ||||
| 		set(t, etc, serv.Key, 0, serv) | ||||
| 		defer delete(t, etc, serv.Key) | ||||
| 	} | ||||
| 	for _, tc := range dnsTestCasesOther { | ||||
| 		m := new(dns.Msg) | ||||
| 		m.SetQuestion(dns.Fqdn(tc.Qname), tc.Qtype) | ||||
|  | ||||
| 		rec := middleware.NewResponseRecorder(&middleware.TestResponseWriter{}) | ||||
| 		_, err := etc.ServeDNS(ctx, rec, m) | ||||
| 		if err != nil { | ||||
| 			t.Errorf("expected no error, got %v\n", err) | ||||
| 			return | ||||
| 		} | ||||
| 		resp := rec.Msg() | ||||
|  | ||||
| 		sort.Sort(rrSet(resp.Answer)) | ||||
| 		sort.Sort(rrSet(resp.Ns)) | ||||
| 		sort.Sort(rrSet(resp.Extra)) | ||||
|  | ||||
| 		if resp.Rcode != tc.Rcode { | ||||
| 			t.Errorf("rcode is %q, expected %q", dns.RcodeToString[resp.Rcode], dns.RcodeToString[tc.Rcode]) | ||||
| 			t.Logf("%v\n", resp) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if len(resp.Answer) != len(tc.Answer) { | ||||
| 			t.Errorf("answer for %q contained %d results, %d expected", tc.Qname, len(resp.Answer), len(tc.Answer)) | ||||
| 			t.Logf("%v\n", resp) | ||||
| 			continue | ||||
| 		} | ||||
| 		if len(resp.Ns) != len(tc.Ns) { | ||||
| 			t.Errorf("authority for %q contained %d results, %d expected", tc.Qname, len(resp.Ns), len(tc.Ns)) | ||||
| 			t.Logf("%v\n", resp) | ||||
| 			continue | ||||
| 		} | ||||
| 		if len(resp.Extra) != len(tc.Extra) { | ||||
| 			t.Errorf("additional for %q contained %d results, %d expected", tc.Qname, len(resp.Extra), len(tc.Extra)) | ||||
| 			t.Logf("%v\n", resp) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if !checkSection(t, tc, Answer, resp.Answer) { | ||||
| 			t.Logf("%v\n", resp) | ||||
| 		} | ||||
| 		if !checkSection(t, tc, Ns, resp.Ns) { | ||||
| 			t.Logf("%v\n", resp) | ||||
|  | ||||
| 		} | ||||
| 		if !checkSection(t, tc, Extra, resp.Extra) { | ||||
| 			t.Logf("%v\n", resp) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Note the key is encoded as DNS name, while in "reality" it is a etcd path. | ||||
| var servicesOther = []*msg.Service{ | ||||
| 	{Host: "dev.server1", Port: 8080, Key: "a.server1.dev.region1.skydns.test."}, | ||||
|  | ||||
| 	// mx | ||||
| 	{Host: "mx.skydns.test", Priority: 50, Mail: true, Key: "a.mail.skydns.test."}, | ||||
| 	{Host: "mx.miek.nl", Priority: 50, Mail: true, Key: "b.mail.skydns.test."}, | ||||
| 	{Host: "a.ipaddr.skydns.test", Priority: 30, Mail: true, Key: "a.mx.skydns.test."}, | ||||
|  | ||||
| 	{Host: "a.ipaddr.skydns.test", Mail: true, Key: "a.mx2.skydns.test."}, | ||||
| 	{Host: "b.ipaddr.skydns.test", Mail: true, Key: "b.mx2.skydns.test."}, | ||||
|  | ||||
| 	{Host: "172.16.1.1", Key: "a.ipaddr.skydns.test."}, | ||||
| 	{Host: "172.16.1.2", Key: "b.ipaddr.skydns.test."}, | ||||
|  | ||||
| 	// txt | ||||
| 	{Text: "abc", Key: "a1.txt.skydns.test."}, | ||||
| 	{Text: "abc abc", Key: "a2.txt.skydns.test."}, | ||||
|  | ||||
| 	// duplicate ip address | ||||
| 	{Host: "10.11.11.10", Key: "http.multiport.http.skydns.test.", Port: 80}, | ||||
| 	{Host: "10.11.11.10", Key: "https.multiport.http.skydns.test.", Port: 443}, | ||||
| } | ||||
|  | ||||
| var dnsTestCasesOther = []dnsTestCase{ | ||||
| 	// MX Tests | ||||
| 	{ | ||||
| 		// NODATA as this is not an Mail: true record. | ||||
| 		Qname: "a.server1.dev.region1.skydns.test.", Qtype: dns.TypeMX, | ||||
| 		Ns: []dns.RR{ | ||||
| 			newSOA("skydns.test. 300 SOA ns.dns.skydns.test. hostmaster.skydns.test. 0 0 0 0 0"), | ||||
| 		}, | ||||
| 	}, | ||||
| 	{ | ||||
| 		Qname: "a.mail.skydns.test.", Qtype: dns.TypeMX, | ||||
| 		Answer: []dns.RR{newMX("a.mail.skydns.test. 300 IN MX 50 mx.skydns.test.")}, | ||||
| 		Extra: []dns.RR{ | ||||
| 			newA("a.ipaddr.skydns.test.	300	IN	A	172.16.1.1"), | ||||
| 			newCNAME("mx.skydns.test.	300	IN	CNAME	a.ipaddr.skydns.test."), | ||||
| 		}, | ||||
| 	}, | ||||
| 	{ | ||||
| 		Qname: "mx2.skydns.test.", Qtype: dns.TypeMX, | ||||
| 		Answer: []dns.RR{ | ||||
| 			newMX("mx2.skydns.test. 300 IN MX 10 a.ipaddr.skydns.test."), | ||||
| 			newMX("mx2.skydns.test. 300 IN MX 10 b.ipaddr.skydns.test."), | ||||
| 		}, | ||||
| 		Extra: []dns.RR{ | ||||
| 			newA("a.ipaddr.skydns.test. 300 A 172.16.1.1"), | ||||
| 			newA("b.ipaddr.skydns.test. 300 A 172.16.1.2"), | ||||
| 		}, | ||||
| 	}, | ||||
| 	// Txt | ||||
| 	{ | ||||
| 		Qname: "a1.txt.skydns.test.", Qtype: dns.TypeTXT, | ||||
| 		Answer: []dns.RR{ | ||||
| 			newTXT("a1.txt.skydns.test. 300 IN TXT \"abc\""), | ||||
| 		}, | ||||
| 	}, | ||||
| 	{ | ||||
| 		Qname: "a2.txt.skydns.test.", Qtype: dns.TypeTXT, | ||||
| 		Answer: []dns.RR{ | ||||
| 			newTXT("a2.txt.skydns.test. 300 IN TXT \"abc abc\""), | ||||
| 		}, | ||||
| 	}, | ||||
| 	{ | ||||
| 		Qname: "txt.skydns.test.", Qtype: dns.TypeTXT, | ||||
| 		Answer: []dns.RR{ | ||||
| 			newTXT("txt.skydns.test. 300 IN TXT \"abc abc\""), | ||||
| 			newTXT("txt.skydns.test. 300 IN TXT \"abc\""), | ||||
| 		}, | ||||
| 	}, | ||||
| 	// Duplicate IP address test | ||||
| 	{ | ||||
| 		Qname: "multiport.http.skydns.test.", Qtype: dns.TypeA, | ||||
| 		Answer: []dns.RR{newA("multiport.http.skydns.test. 300 IN A 10.11.11.10")}, | ||||
| 	}, | ||||
| } | ||||
| @@ -37,7 +37,7 @@ const ( | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	ctx, _ = context.WithTimeout(ctx.Background(), etcdTimeout) | ||||
| 	ctx, _ = context.WithTimeout(context.Background(), etcdTimeout) | ||||
|  | ||||
| 	etcdCfg := etcdc.Config{ | ||||
| 		Endpoints: []string{"http://localhost:2379"}, | ||||
| @@ -88,7 +88,7 @@ func TestLookup(t *testing.T) { | ||||
| 			t.Errorf("expected no error, got %v\n", err) | ||||
| 			return | ||||
| 		} | ||||
| 		resp := rec.Reply() | ||||
| 		resp := rec.Msg() | ||||
|  | ||||
| 		sort.Sort(rrSet(resp.Answer)) | ||||
| 		sort.Sort(rrSet(resp.Ns)) | ||||
|   | ||||
| @@ -37,8 +37,8 @@ func addStubEdns0(m *dns.Msg) *dns.Msg { | ||||
| 	return m | ||||
| } | ||||
|  | ||||
| // Look in .../dns/stub/<domain>/xx for msg.Services. Loop through them | ||||
| // extract <domain> and add them as forwarders (ip:port-combos) for | ||||
| // Look in .../dns/stub/<zone>/xx for msg.Services. Loop through them | ||||
| // extract <zone> and add them as forwarders (ip:port-combos) for | ||||
| // the stub zones. Only numeric (i.e. IP address) hosts are used. | ||||
| // TODO(miek): makes this Startup Function. | ||||
| func (e Etcd) UpdateStubZones(zone string) error { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user