blob: ef8b60ac7f7198b7fcc16dd5093e8d36d524c665 [file] [log] [blame]
Jan Schär75ea9f42024-07-29 17:01:41 +02001package proxy
2
3// Taken and modified from CoreDNS, under Apache 2.0.
4
5import (
6 "sync/atomic"
7 "testing"
8 "time"
9
10 "github.com/miekg/dns"
11
12 "source.monogon.dev/osbase/net/dns/test"
13)
14
15func TestHealth(t *testing.T) {
16 i := uint32(0)
17 s := test.NewServer(func(w dns.ResponseWriter, r *dns.Msg) {
18 if r.Question[0].Name == "." && r.RecursionDesired == true {
19 atomic.AddUint32(&i, 1)
20 }
21 ret := new(dns.Msg)
22 ret.SetReply(r)
23 w.WriteMsg(ret)
24 })
25 defer s.Close()
26
27 hc := NewHealthChecker(true, ".")
28 hc.SetReadTimeout(10 * time.Millisecond)
29 hc.SetWriteTimeout(10 * time.Millisecond)
30
31 p := NewProxy(s.Addr)
32 p.readTimeout = 10 * time.Millisecond
33 err := hc.Check(p)
34 if err != nil {
35 t.Errorf("check failed: %v", err)
36 }
37
38 time.Sleep(20 * time.Millisecond)
39 i1 := atomic.LoadUint32(&i)
40 if i1 != 1 {
41 t.Errorf("Expected number of health checks with RecursionDesired==true to be %d, got %d", 1, i1)
42 }
43}
44
45func TestHealthTCP(t *testing.T) {
46 i := uint32(0)
47 s := test.NewServer(func(w dns.ResponseWriter, r *dns.Msg) {
48 if r.Question[0].Name == "." && r.RecursionDesired == true {
49 atomic.AddUint32(&i, 1)
50 }
51 ret := new(dns.Msg)
52 ret.SetReply(r)
53 w.WriteMsg(ret)
54 })
55 defer s.Close()
56
57 hc := NewHealthChecker(true, ".")
58 hc.SetTCPTransport()
59 hc.SetReadTimeout(10 * time.Millisecond)
60 hc.SetWriteTimeout(10 * time.Millisecond)
61
62 p := NewProxy(s.Addr)
63 p.readTimeout = 10 * time.Millisecond
64 err := hc.Check(p)
65 if err != nil {
66 t.Errorf("check failed: %v", err)
67 }
68
69 time.Sleep(20 * time.Millisecond)
70 i1 := atomic.LoadUint32(&i)
71 if i1 != 1 {
72 t.Errorf("Expected number of health checks with RecursionDesired==true to be %d, got %d", 1, i1)
73 }
74}
75
76func TestHealthNoRecursion(t *testing.T) {
77 i := uint32(0)
78 s := test.NewServer(func(w dns.ResponseWriter, r *dns.Msg) {
79 if r.Question[0].Name == "." && r.RecursionDesired == false {
80 atomic.AddUint32(&i, 1)
81 }
82 ret := new(dns.Msg)
83 ret.SetReply(r)
84 w.WriteMsg(ret)
85 })
86 defer s.Close()
87
88 hc := NewHealthChecker(false, ".")
89 hc.SetReadTimeout(10 * time.Millisecond)
90 hc.SetWriteTimeout(10 * time.Millisecond)
91
92 p := NewProxy(s.Addr)
93 p.readTimeout = 10 * time.Millisecond
94 err := hc.Check(p)
95 if err != nil {
96 t.Errorf("check failed: %v", err)
97 }
98
99 time.Sleep(20 * time.Millisecond)
100 i1 := atomic.LoadUint32(&i)
101 if i1 != 1 {
102 t.Errorf("Expected number of health checks with RecursionDesired==false to be %d, got %d", 1, i1)
103 }
104}
105
106func TestHealthTimeout(t *testing.T) {
107 s := test.NewServer(func(w dns.ResponseWriter, r *dns.Msg) {
108 // timeout
109 })
110 defer s.Close()
111
112 hc := NewHealthChecker(false, ".")
113 hc.SetReadTimeout(10 * time.Millisecond)
114 hc.SetWriteTimeout(10 * time.Millisecond)
115
116 p := NewProxy(s.Addr)
117 p.readTimeout = 10 * time.Millisecond
118 err := hc.Check(p)
119 if err == nil {
120 t.Errorf("expected error")
121 }
122}
123
124func TestHealthDomain(t *testing.T) {
125 hcDomain := "example.org."
126
127 i := uint32(0)
128 s := test.NewServer(func(w dns.ResponseWriter, r *dns.Msg) {
129 if r.Question[0].Name == hcDomain && r.RecursionDesired == true {
130 atomic.AddUint32(&i, 1)
131 }
132 ret := new(dns.Msg)
133 ret.SetReply(r)
134 w.WriteMsg(ret)
135 })
136 defer s.Close()
137
138 hc := NewHealthChecker(true, hcDomain)
139 hc.SetReadTimeout(10 * time.Millisecond)
140 hc.SetWriteTimeout(10 * time.Millisecond)
141
142 p := NewProxy(s.Addr)
143 p.readTimeout = 10 * time.Millisecond
144 err := hc.Check(p)
145 if err != nil {
146 t.Errorf("check failed: %v", err)
147 }
148
149 time.Sleep(12 * time.Millisecond)
150 i1 := atomic.LoadUint32(&i)
151 if i1 != 1 {
152 t.Errorf("Expected number of health checks with Domain==%s to be %d, got %d", hcDomain, 1, i1)
153 }
154}