master
go 264 lines 6.13 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package ipfs
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 apiv0PinLsData, _ = os.ReadFile("testdata/api_v0_pin_ls.json")
24 apiv0StatsBwData, _ = os.ReadFile("testdata/api_v0_stats_bw.json")
25 apiv0StatsRepoData, _ = os.ReadFile("testdata/api_v0_stats_repo.json")
26 apiv0SwarmPeersData, _ = os.ReadFile("testdata/api_v0_swarm_peers.json")
27 )
28
29 func Test_testDataIsValid(t *testing.T) {
30 for name, data := range map[string][]byte{
31 "dataConfigJSON": dataConfigJSON,
32 "dataConfigYAML": dataConfigYAML,
33 "apiv0PinLsData": apiv0PinLsData,
34 "apiv0StatsBwData": apiv0StatsBwData,
35 "apiv0StatsRepoData": apiv0StatsRepoData,
36 "apiv0SwarmPeersData": apiv0SwarmPeersData,
37 } {
38 require.NotNil(t, data, name)
39 }
40 }
41
42 func TestCollector_ConfigurationSerialize(t *testing.T) {
43 collecttest.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
44 }
45
46 func TestCollector_Init(t *testing.T) {
47 tests := map[string]struct {
48 wantFail bool
49 config Config
50 }{
51 "success with default": {
52 wantFail: false,
53 config: New().Config,
54 },
55 "fail when URL not set": {
56 wantFail: true,
57 config: Config{
58 HTTPConfig: web.HTTPConfig{
59 RequestConfig: web.RequestConfig{URL: ""},
60 },
61 },
62 },
63 }
64
65 for name, test := range tests {
66 t.Run(name, func(t *testing.T) {
67 collr := New()
68 collr.Config = test.config
69
70 if test.wantFail {
71 assert.Error(t, collr.Init(context.Background()))
72 } else {
73 assert.NoError(t, collr.Init(context.Background()))
74 }
75 })
76 }
77 }
78
79 func TestCollector_Charts(t *testing.T) {
80 assert.NotNil(t, New().Charts())
81 }
82
83 func TestCollector_Check(t *testing.T) {
84 tests := map[string]struct {
85 wantFail bool
86 prepare func(t *testing.T) (*Collector, func())
87 }{
88 "success default config": {
89 wantFail: false,
90 prepare: prepareCaseOkDefault,
91 },
92 "success all queries enabled": {
93 wantFail: false,
94 prepare: prepareCaseOkDefault,
95 },
96 "fails on unexpected json response": {
97 wantFail: true,
98 prepare: prepareCaseUnexpectedJsonResponse,
99 },
100 "fails on invalid format response": {
101 wantFail: true,
102 prepare: prepareCaseInvalidFormatResponse,
103 },
104 "fails on connection refused": {
105 wantFail: true,
106 prepare: prepareCaseConnectionRefused,
107 },
108 }
109
110 for name, test := range tests {
111 t.Run(name, func(t *testing.T) {
112 collr, cleanup := test.prepare(t)
113 defer cleanup()
114
115 if test.wantFail {
116 assert.Error(t, collr.Check(context.Background()))
117 } else {
118 assert.NoError(t, collr.Check(context.Background()))
119 }
120 })
121 }
122 }
123
124 func TestCollector_Collect(t *testing.T) {
125 tests := map[string]struct {
126 prepare func(t *testing.T) (*Collector, func())
127 wantMetrics map[string]int64
128 }{
129 "success default config": {
130 prepare: prepareCaseOkDefault,
131 wantMetrics: map[string]int64{
132 "in": 20113594,
133 "out": 3113852,
134 "peers": 6,
135 },
136 },
137 "success all queries enabled": {
138 prepare: prepareCaseOkAllQueriesEnabled,
139 wantMetrics: map[string]int64{
140 "in": 20113594,
141 "objects": 1,
142 "out": 3113852,
143 "peers": 6,
144 "pinned": 1,
145 "recursive_pins": 1,
146 "size": 25495,
147 "used_percent": 0,
148 },
149 },
150 "fails on unexpected json response": {
151 prepare: prepareCaseUnexpectedJsonResponse,
152 },
153 "fails on invalid format response": {
154 prepare: prepareCaseInvalidFormatResponse,
155 },
156 "fails on connection refused": {
157 prepare: prepareCaseConnectionRefused,
158 },
159 }
160
161 for name, test := range tests {
162 t.Run(name, func(t *testing.T) {
163 collr, cleanup := test.prepare(t)
164 defer cleanup()
165
166 mx := collr.Collect(context.Background())
167
168 require.Equal(t, test.wantMetrics, mx)
169
170 if len(test.wantMetrics) > 0 {
171 collecttest.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
172 }
173 })
174 }
175 }
176
177 func prepareCaseOkDefault(t *testing.T) (*Collector, func()) {
178 t.Helper()
179 srv := httptest.NewServer(http.HandlerFunc(
180 func(w http.ResponseWriter, r *http.Request) {
181 switch r.URL.Path {
182 case urlPathStatsBandwidth:
183 _, _ = w.Write(apiv0StatsBwData)
184 case urlPathStatsRepo:
185 _, _ = w.Write(apiv0StatsRepoData)
186 case urlPathSwarmPeers:
187 _, _ = w.Write(apiv0SwarmPeersData)
188 case urlPathPinLs:
189 _, _ = w.Write(apiv0PinLsData)
190 default:
191 w.WriteHeader(http.StatusNotFound)
192 }
193 }))
194
195 collr := New()
196 collr.URL = srv.URL
197 require.NoError(t, collr.Init(context.Background()))
198
199 return collr, srv.Close
200 }
201
202 func prepareCaseOkAllQueriesEnabled(t *testing.T) (*Collector, func()) {
203 t.Helper()
204 collr, cleanup := prepareCaseOkDefault(t)
205
206 collr.QueryRepoApi = true
207 collr.QueryPinApi = true
208
209 return collr, cleanup
210 }
211
212 func prepareCaseUnexpectedJsonResponse(t *testing.T) (*Collector, func()) {
213 t.Helper()
214 resp := `
215 {
216 "elephant": {
217 "burn": false,
218 "mountain": true,
219 "fog": false,
220 "skin": -1561907625,
221 "burst": "anyway",
222 "shadow": 1558616893
223 },
224 "start": "ever",
225 "base": 2093056027,
226 "mission": -2007590351,
227 "victory": 999053756,
228 "die": false
229 }
230 `
231 srv := httptest.NewServer(http.HandlerFunc(
232 func(w http.ResponseWriter, r *http.Request) {
233 _, _ = w.Write([]byte(resp))
234 }))
235
236 collr := New()
237 collr.URL = srv.URL
238 require.NoError(t, collr.Init(context.Background()))
239
240 return collr, srv.Close
241 }
242
243 func prepareCaseInvalidFormatResponse(t *testing.T) (*Collector, func()) {
244 t.Helper()
245 srv := httptest.NewServer(http.HandlerFunc(
246 func(w http.ResponseWriter, r *http.Request) {
247 _, _ = w.Write([]byte("hello and\n goodbye"))
248 }))
249
250 collr := New()
251 collr.URL = srv.URL
252 require.NoError(t, collr.Init(context.Background()))
253
254 return collr, srv.Close
255 }
256
257 func prepareCaseConnectionRefused(t *testing.T) (*Collector, func()) {
258 t.Helper()
259 collr := New()
260 collr.URL = "http://127.0.0.1:65001"
261 require.NoError(t, collr.Init(context.Background()))
262
263 return collr, func() {}
264 }