mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 10:13:14 -04:00 
			
		
		
		
	Add the rcode to the cached item and use this when we synthesize the answer again. We could also infer the rcode from the reassembled message, but this seems easier and is only an integer. Also set the autoritative bit to 0 for all from-cache answers. Fixes 357
		
			
				
	
	
		
			152 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package cache
 | |
| 
 | |
| import (
 | |
| 	"io/ioutil"
 | |
| 	"log"
 | |
| 	"testing"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/miekg/coredns/middleware"
 | |
| 	"github.com/miekg/coredns/middleware/pkg/response"
 | |
| 	"github.com/miekg/coredns/middleware/test"
 | |
| 
 | |
| 	lru "github.com/hashicorp/golang-lru"
 | |
| 	"github.com/miekg/dns"
 | |
| )
 | |
| 
 | |
| type cacheTestCase struct {
 | |
| 	test.Case
 | |
| 	in                 test.Case
 | |
| 	AuthenticatedData  bool
 | |
| 	Authoritative      bool
 | |
| 	RecursionAvailable bool
 | |
| 	Truncated          bool
 | |
| }
 | |
| 
 | |
| var cacheTestCases = []cacheTestCase{
 | |
| 	{
 | |
| 		RecursionAvailable: true, AuthenticatedData: true, Authoritative: true,
 | |
| 		Case: test.Case{
 | |
| 			Qname: "miek.nl.", Qtype: dns.TypeMX,
 | |
| 			Answer: []dns.RR{
 | |
| 				test.MX("miek.nl.	3600	IN	MX	1 aspmx.l.google.com."),
 | |
| 				test.MX("miek.nl.	3600	IN	MX	10 aspmx2.googlemail.com."),
 | |
| 			},
 | |
| 		},
 | |
| 		in: test.Case{
 | |
| 			Qname: "miek.nl.", Qtype: dns.TypeMX,
 | |
| 			Answer: []dns.RR{
 | |
| 				test.MX("miek.nl.	3601	IN	MX	1 aspmx.l.google.com."),
 | |
| 				test.MX("miek.nl.	3601	IN	MX	10 aspmx2.googlemail.com."),
 | |
| 			},
 | |
| 		},
 | |
| 	},
 | |
| 	{
 | |
| 		RecursionAvailable: true, AuthenticatedData: true, Authoritative: true,
 | |
| 		Case: test.Case{
 | |
| 			Qname: "mIEK.nL.", Qtype: dns.TypeMX,
 | |
| 			Answer: []dns.RR{
 | |
| 				test.MX("mIEK.nL.	3600	IN	MX	1 aspmx.l.google.com."),
 | |
| 				test.MX("mIEK.nL.	3600	IN	MX	10 aspmx2.googlemail.com."),
 | |
| 			},
 | |
| 		},
 | |
| 		in: test.Case{
 | |
| 			Qname: "mIEK.nL.", Qtype: dns.TypeMX,
 | |
| 			Answer: []dns.RR{
 | |
| 				test.MX("mIEK.nL.	3601	IN	MX	1 aspmx.l.google.com."),
 | |
| 				test.MX("mIEK.nL.	3601	IN	MX	10 aspmx2.googlemail.com."),
 | |
| 			},
 | |
| 		},
 | |
| 	},
 | |
| 	{
 | |
| 		Truncated: true,
 | |
| 		Case: test.Case{
 | |
| 			Qname: "miek.nl.", Qtype: dns.TypeMX,
 | |
| 			Answer: []dns.RR{test.MX("miek.nl.	1800	IN	MX	1 aspmx.l.google.com.")},
 | |
| 		},
 | |
| 		in: test.Case{},
 | |
| 	},
 | |
| 	{
 | |
| 		RecursionAvailable: true, Authoritative: true,
 | |
| 		Case: test.Case{
 | |
| 			Rcode: dns.RcodeNameError,
 | |
| 			Qname: "example.org.", Qtype: dns.TypeA,
 | |
| 			Ns: []dns.RR{
 | |
| 				test.SOA("example.org. 3600 IN	SOA	sns.dns.icann.org. noc.dns.icann.org. 2016082540 7200 3600 1209600 3600"),
 | |
| 			},
 | |
| 		},
 | |
| 		in: test.Case{
 | |
| 			Rcode: dns.RcodeNameError,
 | |
| 			Qname: "example.org.", Qtype: dns.TypeA,
 | |
| 			Ns: []dns.RR{
 | |
| 				test.SOA("example.org. 3600 IN	SOA	sns.dns.icann.org. noc.dns.icann.org. 2016082540 7200 3600 1209600 3600"),
 | |
| 			},
 | |
| 		},
 | |
| 	},
 | |
| }
 | |
| 
 | |
| func cacheMsg(m *dns.Msg, tc cacheTestCase) *dns.Msg {
 | |
| 	m.RecursionAvailable = tc.RecursionAvailable
 | |
| 	m.AuthenticatedData = tc.AuthenticatedData
 | |
| 	m.Authoritative = tc.Authoritative
 | |
| 	m.Rcode = tc.Rcode
 | |
| 	m.Truncated = tc.Truncated
 | |
| 	m.Answer = tc.in.Answer
 | |
| 	m.Ns = tc.in.Ns
 | |
| 	//	m.Extra = tc.in.Extra , not the OPT record!
 | |
| 	return m
 | |
| }
 | |
| 
 | |
| func newTestCache(ttl time.Duration) (*Cache, *ResponseWriter) {
 | |
| 	c := &Cache{Zones: []string{"."}, pcap: defaultCap, ncap: defaultCap, pttl: ttl, nttl: ttl}
 | |
| 	c.pcache, _ = lru.New(c.pcap)
 | |
| 	c.ncache, _ = lru.New(c.ncap)
 | |
| 
 | |
| 	crr := &ResponseWriter{nil, c}
 | |
| 	return c, crr
 | |
| }
 | |
| 
 | |
| func TestCache(t *testing.T) {
 | |
| 	c, crr := newTestCache(maxTTL)
 | |
| 
 | |
| 	log.SetOutput(ioutil.Discard)
 | |
| 
 | |
| 	for _, tc := range cacheTestCases {
 | |
| 		m := tc.in.Msg()
 | |
| 		m = cacheMsg(m, tc)
 | |
| 		do := tc.in.Do
 | |
| 
 | |
| 		mt, _ := response.Typify(m)
 | |
| 		k := key(m, mt, do)
 | |
| 		crr.set(m, k, mt, c.pttl)
 | |
| 
 | |
| 		name := middleware.Name(m.Question[0].Name).Normalize()
 | |
| 		qtype := m.Question[0].Qtype
 | |
| 		i, ok, _ := c.get(name, qtype, do)
 | |
| 		if ok && m.Truncated {
 | |
| 			t.Errorf("Truncated message should not have been cached")
 | |
| 			continue
 | |
| 		}
 | |
| 
 | |
| 		if ok {
 | |
| 			resp := i.toMsg(m)
 | |
| 
 | |
| 			if !test.Header(t, tc.Case, resp) {
 | |
| 				t.Logf("%v\n", resp)
 | |
| 				continue
 | |
| 			}
 | |
| 
 | |
| 			if !test.Section(t, tc.Case, test.Answer, resp.Answer) {
 | |
| 				t.Logf("%v\n", resp)
 | |
| 			}
 | |
| 			if !test.Section(t, tc.Case, test.Ns, resp.Ns) {
 | |
| 				t.Logf("%v\n", resp)
 | |
| 
 | |
| 			}
 | |
| 			if !test.Section(t, tc.Case, test.Extra, resp.Extra) {
 | |
| 				t.Logf("%v\n", resp)
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 |