master
go 238 lines 5.49 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package puppet
4
5 import (
6 "context"
7 "net/http"
8 "net/http/httptest"
9 "os"
10 "testing"
11
12 "github.com/netdata/netdata/go/plugins/pkg/web"
13 "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/collecttest"
14
15 "github.com/stretchr/testify/assert"
16 "github.com/stretchr/testify/require"
17 )
18
19 var (
20 dataConfigJSON, _ = os.ReadFile("testdata/config.json")
21 dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
22
23 serviceStatusResponse, _ = os.ReadFile("testdata/serviceStatusResponse.json")
24 )
25
26 func Test_testDataIsValid(t *testing.T) {
27 for name, data := range map[string][]byte{
28 "dataConfigJSON": dataConfigJSON,
29 "dataConfigYAML": dataConfigYAML,
30 "serviceStatusResponse": serviceStatusResponse,
31 } {
32 require.NotNil(t, data, name)
33 }
34 }
35
36 func TestCollector_ConfigurationSerialize(t *testing.T) {
37 collecttest.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
38 }
39
40 func TestCollector_Init(t *testing.T) {
41 tests := map[string]struct {
42 wantFail bool
43 config Config
44 }{
45 "success with default": {
46 wantFail: false,
47 config: New().Config,
48 },
49 "fail when URL not set": {
50 wantFail: true,
51 config: Config{
52 HTTPConfig: web.HTTPConfig{
53 RequestConfig: web.RequestConfig{URL: ""},
54 },
55 },
56 },
57 }
58
59 for name, test := range tests {
60 t.Run(name, func(t *testing.T) {
61 collr := New()
62 collr.Config = test.config
63
64 if test.wantFail {
65 assert.Error(t, collr.Init(context.Background()))
66 } else {
67 assert.NoError(t, collr.Init(context.Background()))
68 }
69 })
70 }
71 }
72
73 func TestCollector_Charts(t *testing.T) {
74 assert.NotNil(t, New().Charts())
75 }
76
77 func TestCollector_Check(t *testing.T) {
78 tests := map[string]struct {
79 wantFail bool
80 prepare func(t *testing.T) (*Collector, func())
81 }{
82 "success default config": {
83 wantFail: false,
84 prepare: prepareCaseOkDefault,
85 },
86 "fails on unexpected json response": {
87 wantFail: true,
88 prepare: prepareCaseUnexpectedJsonResponse,
89 },
90 "fails on invalid format response": {
91 wantFail: true,
92 prepare: prepareCaseInvalidFormatResponse,
93 },
94 "fails on connection refused": {
95 wantFail: true,
96 prepare: prepareCaseConnectionRefused,
97 },
98 }
99
100 for name, test := range tests {
101 t.Run(name, func(t *testing.T) {
102 collr, cleanup := test.prepare(t)
103 defer cleanup()
104
105 if test.wantFail {
106 assert.Error(t, collr.Check(context.Background()))
107 } else {
108 assert.NoError(t, collr.Check(context.Background()))
109 }
110 })
111 }
112 }
113
114 func TestCollector_Collect(t *testing.T) {
115 tests := map[string]struct {
116 prepare func(t *testing.T) (*Collector, func())
117 wantMetrics map[string]int64
118 }{
119 "success default config": {
120 prepare: prepareCaseOkDefault,
121 wantMetrics: map[string]int64{
122 "cpu_usage": 49,
123 "fd_max": 524288,
124 "fd_used": 234,
125 "gc_cpu_usage": 0,
126 "jvm_heap_committed": 1073741824,
127 "jvm_heap_init": 1073741824,
128 "jvm_heap_max": 1073741824,
129 "jvm_heap_used": 550502400,
130 "jvm_nonheap_committed": 334102528,
131 "jvm_nonheap_init": 7667712,
132 "jvm_nonheap_max": -1,
133 "jvm_nonheap_used": 291591160,
134 },
135 },
136 "fails on unexpected json response": {
137 prepare: prepareCaseUnexpectedJsonResponse,
138 },
139 "fails on invalid format response": {
140 prepare: prepareCaseInvalidFormatResponse,
141 },
142 "fails on connection refused": {
143 prepare: prepareCaseConnectionRefused,
144 },
145 }
146
147 for name, test := range tests {
148 t.Run(name, func(t *testing.T) {
149 collr, cleanup := test.prepare(t)
150 defer cleanup()
151
152 mx := collr.Collect(context.Background())
153
154 require.Equal(t, test.wantMetrics, mx)
155
156 if len(test.wantMetrics) > 0 {
157 collecttest.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
158 }
159 })
160 }
161 }
162
163 func prepareCaseOkDefault(t *testing.T) (*Collector, func()) {
164 t.Helper()
165 srv := httptest.NewServer(http.HandlerFunc(
166 func(w http.ResponseWriter, r *http.Request) {
167 switch r.URL.Path {
168 case "/status/v1/services":
169 if r.URL.RawQuery != urlQueryStatusService {
170 w.WriteHeader(http.StatusNotFound)
171 } else {
172 _, _ = w.Write(serviceStatusResponse)
173 }
174 default:
175 w.WriteHeader(http.StatusNotFound)
176 }
177 }))
178
179 collr := New()
180 collr.URL = srv.URL
181 require.NoError(t, collr.Init(context.Background()))
182
183 return collr, srv.Close
184 }
185
186 func prepareCaseUnexpectedJsonResponse(t *testing.T) (*Collector, func()) {
187 t.Helper()
188 resp := `
189 {
190 "elephant": {
191 "burn": false,
192 "mountain": true,
193 "fog": false,
194 "skin": -1561907625,
195 "burst": "anyway",
196 "shadow": 1558616893
197 },
198 "start": "ever",
199 "base": 2093056027,
200 "mission": -2007590351,
201 "victory": 999053756,
202 "die": false
203 }
204 `
205 srv := httptest.NewServer(http.HandlerFunc(
206 func(w http.ResponseWriter, r *http.Request) {
207 _, _ = w.Write([]byte(resp))
208 }))
209
210 collr := New()
211 collr.URL = srv.URL
212 require.NoError(t, collr.Init(context.Background()))
213
214 return collr, srv.Close
215 }
216
217 func prepareCaseInvalidFormatResponse(t *testing.T) (*Collector, func()) {
218 t.Helper()
219 srv := httptest.NewServer(http.HandlerFunc(
220 func(w http.ResponseWriter, r *http.Request) {
221 _, _ = w.Write([]byte("hello and\n goodbye"))
222 }))
223
224 collr := New()
225 collr.URL = srv.URL
226 require.NoError(t, collr.Init(context.Background()))
227
228 return collr, srv.Close
229 }
230
231 func prepareCaseConnectionRefused(t *testing.T) (*Collector, func()) {
232 t.Helper()
233 collr := New()
234 collr.URL = "http://127.0.0.1:65001"
235 require.NoError(t, collr.Init(context.Background()))
236
237 return collr, func() {}
238 }