master
go 250 lines 6.08 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package dnsdist
4
5 import (
6 "context"
7 "net/http"
8 "net/http/httptest"
9 "os"
10 "testing"
11
12 "github.com/stretchr/testify/assert"
13 "github.com/stretchr/testify/require"
14
15 "github.com/netdata/netdata/go/plugins/pkg/tlscfg"
16 "github.com/netdata/netdata/go/plugins/pkg/web"
17 "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/collecttest"
18 )
19
20 var (
21 dataConfigJSON, _ = os.ReadFile("testdata/config.json")
22 dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
23
24 dataVer151JSONStat, _ = os.ReadFile("testdata/v1.5.1/jsonstat.json")
25 )
26
27 func Test_testDataIsValid(t *testing.T) {
28 for name, data := range map[string][]byte{
29 "dataConfigJSON": dataConfigJSON,
30 "dataConfigYAML": dataConfigYAML,
31 "dataVer151JSONStat": dataVer151JSONStat,
32 } {
33 require.NotNil(t, data, name)
34 }
35 }
36
37 func TestCollector_ConfigurationSerialize(t *testing.T) {
38 collecttest.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
39 }
40
41 func TestCollector_Init(t *testing.T) {
42 tests := map[string]struct {
43 config Config
44 wantFail bool
45 }{
46 "success on default config": {
47 config: New().Config,
48 },
49 "fails on unset URL": {
50 wantFail: true,
51 config: Config{
52 HTTPConfig: web.HTTPConfig{
53 RequestConfig: web.RequestConfig{URL: ""},
54 },
55 },
56 },
57 "fails on invalid TLSCA": {
58 wantFail: true,
59 config: Config{
60 HTTPConfig: web.HTTPConfig{
61 RequestConfig: web.RequestConfig{
62 URL: "http://127.0.0.1:38001",
63 },
64 ClientConfig: web.ClientConfig{
65 TLSConfig: tlscfg.TLSConfig{TLSCA: "testdata/tls"},
66 },
67 },
68 },
69 },
70 }
71
72 for name, test := range tests {
73 t.Run(name, func(t *testing.T) {
74 collr := New()
75 collr.Config = test.config
76
77 if test.wantFail {
78 assert.Error(t, collr.Init(context.Background()))
79 } else {
80 assert.NoError(t, collr.Init(context.Background()))
81 }
82 })
83 }
84 }
85
86 func TestCollector_Charts(t *testing.T) {
87 collr := New()
88 require.NoError(t, collr.Init(context.Background()))
89 assert.NotNil(t, collr.Charts())
90 }
91
92 func TestCollector_Cleanup(t *testing.T) {
93 assert.NotPanics(t, func() { New().Cleanup(context.Background()) })
94 }
95
96 func TestCollector_Check(t *testing.T) {
97 tests := map[string]struct {
98 prepare func() (collr *Collector, cleanup func())
99 wantFail bool
100 }{
101 "success on valid response v1.5.1": {
102 prepare: preparePowerDNSdistV151,
103 wantFail: false,
104 },
105 "fails on 404 response": {
106 prepare: preparePowerDNSdist404,
107 wantFail: true,
108 },
109 "fails on connection refused": {
110 prepare: preparePowerDNSdistConnectionRefused,
111 wantFail: true,
112 },
113 "fails with invalid data": {
114 prepare: preparePowerDNSdistInvalidData,
115 wantFail: true,
116 },
117 }
118
119 for name, test := range tests {
120 t.Run(name, func(t *testing.T) {
121 collr, cleanup := test.prepare()
122 defer cleanup()
123 require.NoError(t, collr.Init(context.Background()))
124
125 if test.wantFail {
126 assert.Error(t, collr.Check(context.Background()))
127 } else {
128 assert.NoError(t, collr.Check(context.Background()))
129 }
130 })
131 }
132 }
133
134 func TestCollector_Collect(t *testing.T) {
135 tests := map[string]struct {
136 prepare func() (collr *Collector, cleanup func())
137 wantCollected map[string]int64
138 }{
139 "success on valid response v1.5.1": {
140 prepare: preparePowerDNSdistV151,
141 wantCollected: map[string]int64{
142 "acl-drops": 1,
143 "cache-hits": 1,
144 "cache-misses": 1,
145 "cpu-sys-msec": 411,
146 "cpu-user-msec": 939,
147 "downstream-send-errors": 1,
148 "downstream-timeouts": 1,
149 "dyn-blocked": 1,
150 "empty-queries": 1,
151 "latency-avg100": 14237,
152 "latency-avg1000": 9728,
153 "latency-avg10000": 1514,
154 "latency-avg1000000": 15,
155 "latency-slow": 1,
156 "latency0-1": 1,
157 "latency1-10": 3,
158 "latency10-50": 996,
159 "latency100-1000": 4,
160 "latency50-100": 1,
161 "no-policy": 1,
162 "noncompliant-queries": 1,
163 "noncompliant-responses": 1,
164 "queries": 1003,
165 "rdqueries": 1003,
166 "real-memory-usage": 202125312,
167 "responses": 1003,
168 "rule-drop": 1,
169 "rule-nxdomain": 1,
170 "rule-refused": 1,
171 "self-answered": 1,
172 "servfail-responses": 1,
173 "trunc-failures": 1,
174 },
175 },
176 "fails on 404 response": {
177 prepare: preparePowerDNSdist404,
178 },
179 "fails on connection refused": {
180 prepare: preparePowerDNSdistConnectionRefused,
181 },
182 "fails with invalid data": {
183 prepare: preparePowerDNSdistInvalidData,
184 },
185 }
186
187 for name, test := range tests {
188 t.Run(name, func(t *testing.T) {
189 collr, cleanup := test.prepare()
190 defer cleanup()
191 require.NoError(t, collr.Init(context.Background()))
192
193 mx := collr.Collect(context.Background())
194
195 assert.Equal(t, test.wantCollected, mx)
196 if len(test.wantCollected) > 0 {
197 collecttest.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
198 }
199 })
200 }
201 }
202
203 func preparePowerDNSdistV151() (*Collector, func()) {
204 srv := preparePowerDNSDistEndpoint()
205 collr := New()
206 collr.URL = srv.URL
207
208 return collr, srv.Close
209 }
210
211 func preparePowerDNSdist404() (*Collector, func()) {
212 srv := httptest.NewServer(http.HandlerFunc(
213 func(w http.ResponseWriter, r *http.Request) {
214 w.WriteHeader(http.StatusNotFound)
215 }))
216 collr := New()
217 collr.URL = srv.URL
218
219 return collr, srv.Close
220 }
221
222 func preparePowerDNSdistConnectionRefused() (*Collector, func()) {
223 collr := New()
224 collr.URL = "http://127.0.0.1:38001"
225
226 return collr, func() {}
227 }
228
229 func preparePowerDNSdistInvalidData() (*Collector, func()) {
230 srv := httptest.NewServer(http.HandlerFunc(
231 func(w http.ResponseWriter, r *http.Request) {
232 _, _ = w.Write([]byte("hello and\n goodbye"))
233 }))
234 collr := New()
235 collr.URL = srv.URL
236
237 return collr, srv.Close
238 }
239
240 func preparePowerDNSDistEndpoint() *httptest.Server {
241 return httptest.NewServer(http.HandlerFunc(
242 func(w http.ResponseWriter, r *http.Request) {
243 switch r.URL.String() {
244 case "/jsonstat?command=stats":
245 _, _ = w.Write(dataVer151JSONStat)
246 default:
247 w.WriteHeader(http.StatusNotFound)
248 }
249 }))
250 }