mirror of
				https://github.com/coredns/coredns.git
				synced 2025-11-04 03:03:14 -05:00 
			
		
		
		
	
		
			
	
	
		
			137 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			137 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package forward
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"sync/atomic"
							 | 
						||
| 
								 | 
							
									"testing"
							 | 
						||
| 
								 | 
							
									"time"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"github.com/coredns/coredns/plugin/pkg/dnstest"
							 | 
						||
| 
								 | 
							
									"github.com/coredns/coredns/plugin/test"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"github.com/miekg/dns"
							 | 
						||
| 
								 | 
							
									"golang.org/x/net/context"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestHealth(t *testing.T) {
							 | 
						||
| 
								 | 
							
									const expected = 0
							 | 
						||
| 
								 | 
							
									i := uint32(0)
							 | 
						||
| 
								 | 
							
									s := dnstest.NewServer(func(w dns.ResponseWriter, r *dns.Msg) {
							 | 
						||
| 
								 | 
							
										if r.Question[0].Name == "." {
							 | 
						||
| 
								 | 
							
											atomic.AddUint32(&i, 1)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										ret := new(dns.Msg)
							 | 
						||
| 
								 | 
							
										ret.SetReply(r)
							 | 
						||
| 
								 | 
							
										w.WriteMsg(ret)
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									defer s.Close()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									p := NewProxy(s.Addr, nil /* no TLS */)
							 | 
						||
| 
								 | 
							
									f := New()
							 | 
						||
| 
								 | 
							
									f.SetProxy(p)
							 | 
						||
| 
								 | 
							
									defer f.Close()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									req := new(dns.Msg)
							 | 
						||
| 
								 | 
							
									req.SetQuestion("example.org.", dns.TypeA)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									f.ServeDNS(context.TODO(), &test.ResponseWriter{}, req)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									time.Sleep(1 * time.Second)
							 | 
						||
| 
								 | 
							
									i1 := atomic.LoadUint32(&i)
							 | 
						||
| 
								 | 
							
									if i1 != expected {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected number of health checks to be %d, got %d", expected, i1)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestHealthTimeout(t *testing.T) {
							 | 
						||
| 
								 | 
							
									const expected = 1
							 | 
						||
| 
								 | 
							
									i := uint32(0)
							 | 
						||
| 
								 | 
							
									s := dnstest.NewServer(func(w dns.ResponseWriter, r *dns.Msg) {
							 | 
						||
| 
								 | 
							
										if r.Question[0].Name == "." {
							 | 
						||
| 
								 | 
							
											// health check, answer
							 | 
						||
| 
								 | 
							
											atomic.AddUint32(&i, 1)
							 | 
						||
| 
								 | 
							
											ret := new(dns.Msg)
							 | 
						||
| 
								 | 
							
											ret.SetReply(r)
							 | 
						||
| 
								 | 
							
											w.WriteMsg(ret)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										// not a health check, do a timeout
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									defer s.Close()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									p := NewProxy(s.Addr, nil /* no TLS */)
							 | 
						||
| 
								 | 
							
									f := New()
							 | 
						||
| 
								 | 
							
									f.SetProxy(p)
							 | 
						||
| 
								 | 
							
									defer f.Close()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									req := new(dns.Msg)
							 | 
						||
| 
								 | 
							
									req.SetQuestion("example.org.", dns.TypeA)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									f.ServeDNS(context.TODO(), &test.ResponseWriter{}, req)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									time.Sleep(1 * time.Second)
							 | 
						||
| 
								 | 
							
									i1 := atomic.LoadUint32(&i)
							 | 
						||
| 
								 | 
							
									if i1 != expected {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected number of health checks to be %d, got %d", expected, i1)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestHealthFailTwice(t *testing.T) {
							 | 
						||
| 
								 | 
							
									const expected = 2
							 | 
						||
| 
								 | 
							
									i := uint32(0)
							 | 
						||
| 
								 | 
							
									s := dnstest.NewServer(func(w dns.ResponseWriter, r *dns.Msg) {
							 | 
						||
| 
								 | 
							
										if r.Question[0].Name == "." {
							 | 
						||
| 
								 | 
							
											atomic.AddUint32(&i, 1)
							 | 
						||
| 
								 | 
							
											i1 := atomic.LoadUint32(&i)
							 | 
						||
| 
								 | 
							
											// Timeout health until we get the second one
							 | 
						||
| 
								 | 
							
											if i1 < 2 {
							 | 
						||
| 
								 | 
							
												return
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											ret := new(dns.Msg)
							 | 
						||
| 
								 | 
							
											ret.SetReply(r)
							 | 
						||
| 
								 | 
							
											w.WriteMsg(ret)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									defer s.Close()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									p := NewProxy(s.Addr, nil /* no TLS */)
							 | 
						||
| 
								 | 
							
									f := New()
							 | 
						||
| 
								 | 
							
									f.SetProxy(p)
							 | 
						||
| 
								 | 
							
									defer f.Close()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									req := new(dns.Msg)
							 | 
						||
| 
								 | 
							
									req.SetQuestion("example.org.", dns.TypeA)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									f.ServeDNS(context.TODO(), &test.ResponseWriter{}, req)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									time.Sleep(3 * time.Second)
							 | 
						||
| 
								 | 
							
									i1 := atomic.LoadUint32(&i)
							 | 
						||
| 
								 | 
							
									if i1 != expected {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected number of health checks to be %d, got %d", expected, i1)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestHealthMaxFails(t *testing.T) {
							 | 
						||
| 
								 | 
							
									const expected = 0
							 | 
						||
| 
								 | 
							
									i := uint32(0)
							 | 
						||
| 
								 | 
							
									s := dnstest.NewServer(func(w dns.ResponseWriter, r *dns.Msg) {
							 | 
						||
| 
								 | 
							
										// timeout
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									defer s.Close()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									p := NewProxy(s.Addr, nil /* no TLS */)
							 | 
						||
| 
								 | 
							
									f := New()
							 | 
						||
| 
								 | 
							
									f.maxfails = 0
							 | 
						||
| 
								 | 
							
									f.SetProxy(p)
							 | 
						||
| 
								 | 
							
									defer f.Close()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									req := new(dns.Msg)
							 | 
						||
| 
								 | 
							
									req.SetQuestion("example.org.", dns.TypeA)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									f.ServeDNS(context.TODO(), &test.ResponseWriter{}, req)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									time.Sleep(1 * time.Second)
							 | 
						||
| 
								 | 
							
									i1 := atomic.LoadUint32(&i)
							 | 
						||
| 
								 | 
							
									if i1 != expected {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected number of health checks to be %d, got %d", expected, i1)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |