1 package metrics_test
2
3 import (
4 "os"
5 "path/filepath"
6 "testing"
7
8 "github.com/cybertec-postgresql/pgwatch/v5/internal/metrics"
9 "github.com/stretchr/testify/assert"
10 "gopkg.in/yaml.v3"
11 )
12
13 func TestDeaultMetrics(t *testing.T) {
14 fmr, err := metrics.NewYAMLMetricReaderWriter(ctx, "")
15 assert.NoError(t, err)
16
17
18 metricsDefs, err := fmr.GetMetrics()
19 assert.NoError(t, err)
20
21
22 err = fmr.WriteMetrics(metricsDefs)
23 assert.Error(t, err)
24
25
26 err = fmr.DeleteMetric("test")
27 assert.Error(t, err)
28
29
30 err = fmr.UpdateMetric("test", metrics.Metric{})
31 assert.Error(t, err)
32
33
34 err = fmr.DeletePreset("test")
35 assert.Error(t, err)
36
37
38 err = fmr.UpdatePreset("test", metrics.Preset{})
39 assert.Error(t, err)
40 }
41
42 func TestWriteMetricsToFile(t *testing.T) {
43
44 metricDefs := metrics.Metrics{
45 MetricDefs: metrics.MetricDefs{
46 "test_metric": metrics.Metric{
47 SQLs: map[int]string{
48 1: "SELECT 1",
49 },
50 InitSQL: "SELECT 1",
51 NodeStatus: "primary",
52 Gauges: []string{"gauge1", "gauge2"},
53 IsInstanceLevel: true,
54 StorageName: "storage1",
55 Description: "Test metric",
56 },
57 },
58 PresetDefs: metrics.PresetDefs{
59 "test_preset": metrics.Preset{
60 Description: "Test preset",
61 Metrics: map[string]float64{
62 "test_metric": 1.0,
63 },
64 },
65 },
66 }
67
68
69 tempDir := t.TempDir()
70 tempFile := filepath.Join(tempDir, "metrics.yaml")
71
72 fmr, err := metrics.NewYAMLMetricReaderWriter(ctx, tempFile)
73 assert.NoError(t, err)
74
75
76 err = fmr.WriteMetrics(&metricDefs)
77 assert.NoError(t, err)
78
79
80 metrics, err := fmr.GetMetrics()
81 assert.NoError(t, err)
82
83
84 assert.Equal(t, metricDefs, *metrics)
85 }
86 func TestMetricsToFile(t *testing.T) {
87
88 metricDefs := metrics.Metrics{
89 MetricDefs: metrics.MetricDefs{
90 "existing_metric": metrics.Metric{
91 SQLs: map[int]string{
92 1: "SELECT 1",
93 },
94 InitSQL: "SELECT 1",
95 NodeStatus: "primary",
96 Gauges: []string{"gauge1", "gauge2"},
97 IsInstanceLevel: true,
98 StorageName: "storage1",
99 Description: "Existing metric",
100 },
101 },
102 PresetDefs: metrics.PresetDefs{
103 "test_preset": metrics.Preset{
104 Description: "Test preset",
105 Metrics: map[string]float64{
106 "existing_metric": 1.0,
107 },
108 },
109 },
110 }
111
112
113 tempDir := t.TempDir()
114 tempFile := filepath.Join(tempDir, "metrics.yaml")
115
116 fmr, err := metrics.NewYAMLMetricReaderWriter(ctx, tempFile)
117 assert.NoError(t, err)
118
119
120 err = fmr.WriteMetrics(&metricDefs)
121 assert.NoError(t, err)
122
123
124 newMetric := metrics.Metric{
125 SQLs: map[int]string{
126 1: "SELECT 2",
127 },
128 InitSQL: "SELECT 2",
129 NodeStatus: "primary",
130 Gauges: []string{"gauge3", "gauge4"},
131 IsInstanceLevel: true,
132 StorageName: "storage2",
133 Description: "New metric",
134 }
135 err = fmr.UpdateMetric("new_metric", newMetric)
136 assert.NoError(t, err)
137
138
139 updatedMetrics, err := fmr.GetMetrics()
140 assert.NoError(t, err)
141
142
143 expectedMetrics := metricDefs
144 expectedMetrics.MetricDefs["new_metric"] = newMetric
145 assert.Equal(t, expectedMetrics, *updatedMetrics)
146
147
148 err = fmr.DeleteMetric("new_metric")
149 assert.NoError(t, err)
150
151
152 updatedMetrics, err = fmr.GetMetrics()
153 assert.NoError(t, err)
154
155
156 assert.Zero(t, updatedMetrics.MetricDefs["new_metric"])
157 }
158
159 func TestPresetsToFile(t *testing.T) {
160
161 presetDefs := metrics.PresetDefs{
162 "existing_preset": metrics.Preset{
163 Description: "Existing preset",
164 Metrics: map[string]float64{
165 "existing_metric": 1.0,
166 },
167 },
168 }
169
170
171 tempDir := t.TempDir()
172 tempFile := filepath.Join(tempDir, "metrics.yaml")
173
174 fmr, err := metrics.NewYAMLMetricReaderWriter(ctx, tempFile)
175 assert.NoError(t, err)
176
177
178 err = fmr.WriteMetrics(&metrics.Metrics{
179 PresetDefs: presetDefs,
180 })
181 assert.NoError(t, err)
182
183
184 newPreset := metrics.Preset{
185 Description: "New preset",
186 Metrics: map[string]float64{
187 "new_metric": 1.0,
188 },
189 }
190 err = fmr.UpdatePreset("new_preset", newPreset)
191 assert.NoError(t, err)
192
193
194 updatedMetrics, err := fmr.GetMetrics()
195 assert.NoError(t, err)
196
197
198 expectedPresets := presetDefs
199 expectedPresets["new_preset"] = newPreset
200 assert.Equal(t, expectedPresets, updatedMetrics.PresetDefs)
201
202
203 err = fmr.DeletePreset("new_preset")
204 assert.NoError(t, err)
205
206
207 updatedMetrics, err = fmr.GetMetrics()
208 assert.NoError(t, err)
209
210
211 assert.Zero(t, updatedMetrics.PresetDefs["new_preset"])
212 }
213
214 func TestErrorHandlingToFile(t *testing.T) {
215 fmr, err := metrics.NewYAMLMetricReaderWriter(ctx, "/")
216 assert.NoError(t, err)
217
218
219 err = fmr.WriteMetrics(&metrics.Metrics{})
220 assert.Error(t, err)
221
222
223 _, err = fmr.GetMetrics()
224 assert.Error(t, err)
225
226
227 err = fmr.DeleteMetric("test")
228 assert.Error(t, err)
229
230
231 err = fmr.UpdateMetric("test", metrics.Metric{})
232 assert.Error(t, err)
233
234
235 err = fmr.DeletePreset("test")
236 assert.Error(t, err)
237
238
239 err = fmr.UpdatePreset("test", metrics.Preset{})
240 assert.Error(t, err)
241
242
243 tempDir := t.TempDir()
244 tempFile := filepath.Join(tempDir, "metrics.yaml")
245 file, err := os.Create(tempFile)
246 assert.NoError(t, err)
247 defer file.Close()
248 _, err = file.WriteString("invalid yaml")
249 assert.NoError(t, err)
250
251 fmr, err = metrics.NewYAMLMetricReaderWriter(ctx, tempFile)
252 assert.NoError(t, err)
253
254 _, err = fmr.GetMetrics()
255 assert.Error(t, err)
256 }
257
258 func TestCreateMetricAndPreset(t *testing.T) {
259
260 a := assert.New(t)
261
262 t.Run("YAML_CreateMetric_Success", func(t *testing.T) {
263 tmpFile := filepath.Join(t.TempDir(), "test_metrics.yaml")
264 defer os.Remove(tmpFile)
265
266
267 yamlrw, err := metrics.NewYAMLMetricReaderWriter(ctx, tmpFile)
268 a.NoError(err)
269
270
271 emptyMetrics := &metrics.Metrics{
272 MetricDefs: make(map[string]metrics.Metric),
273 PresetDefs: make(map[string]metrics.Preset),
274 }
275 err = yamlrw.WriteMetrics(emptyMetrics)
276 a.NoError(err)
277
278
279 testMetric := metrics.Metric{
280 Description: "Test metric for creation",
281 }
282 err = yamlrw.CreateMetric("test_metric", testMetric)
283 a.NoError(err)
284
285
286 m, err := yamlrw.GetMetrics()
287 a.NoError(err)
288 a.Contains(m.MetricDefs, "test_metric")
289 a.Equal("Test metric for creation", m.MetricDefs["test_metric"].Description)
290
291
292 err = yamlrw.CreateMetric("test_metric", testMetric)
293 a.Error(err)
294 a.Equal(metrics.ErrMetricExists, err)
295 })
296
297 t.Run("YAML_CreatePreset_Success", func(t *testing.T) {
298 tmpFile := filepath.Join(t.TempDir(), "test_presets.yaml")
299 defer os.Remove(tmpFile)
300
301 yamlrw, err := metrics.NewYAMLMetricReaderWriter(ctx, tmpFile)
302 a.NoError(err)
303
304
305 emptyMetrics := &metrics.Metrics{
306 MetricDefs: make(map[string]metrics.Metric),
307 PresetDefs: make(map[string]metrics.Preset),
308 }
309 err = yamlrw.WriteMetrics(emptyMetrics)
310 a.NoError(err)
311
312
313 testPreset := metrics.Preset{
314 Description: "Test preset for creation",
315 Metrics: map[string]float64{"db_stats": 60},
316 }
317 err = yamlrw.CreatePreset("test_preset", testPreset)
318 a.NoError(err)
319
320
321 m, err := yamlrw.GetMetrics()
322 a.NoError(err)
323 a.Contains(m.PresetDefs, "test_preset")
324 a.Equal("Test preset for creation", m.PresetDefs["test_preset"].Description)
325
326
327 err = yamlrw.CreatePreset("test_preset", testPreset)
328 a.Error(err)
329 a.Equal(metrics.ErrPresetExists, err)
330 })
331 }
332
333 func TestMetricsDir(t *testing.T) {
334 a := assert.New(t)
335
336
337 metrics1 := metrics.Metrics{
338 MetricDefs: map[string]metrics.Metric{
339 "metric1": {
340 Description: "metric1 description",
341 },
342 },
343 PresetDefs: map[string]metrics.Preset{
344 "preset1": {
345 Description: "preset1 description",
346 Metrics: map[string]float64{
347 "metric1": 10,
348 },
349 },
350 },
351 }
352
353
354 metrics2 := metrics.Metrics{
355 MetricDefs: map[string]metrics.Metric{
356 "metric2": {
357 Description: "metric2 description",
358 },
359 },
360 PresetDefs: map[string]metrics.Preset{
361 "preset2": {
362 Description: "preset2 description",
363 Metrics: map[string]float64{
364 "metric2": 10,
365 },
366 },
367 },
368 }
369
370 metrics1File, err := yaml.Marshal(metrics1)
371 a.NoError(err)
372 metrics2File, err := yaml.Marshal(metrics2)
373 a.NoError(err)
374
375
376 tempDir := t.TempDir()
377 err = os.WriteFile(filepath.Join(tempDir, "metrics1.yaml"), metrics1File, 0644)
378 a.NoError(err)
379 err = os.WriteFile(filepath.Join(tempDir, "metrics2.yaml"), metrics2File, 0644)
380 a.NoError(err)
381
382
383 yamlrw, err := metrics.NewYAMLMetricReaderWriter(ctx, tempDir)
384 a.NoError(err)
385
386
387 ms, err := yamlrw.GetMetrics()
388 a.NoError(err)
389 a.Equal("metric1 description", ms.MetricDefs["metric1"].Description)
390 a.Equal("preset1 description", ms.PresetDefs["preset1"].Description)
391 a.Equal("metric2 description", ms.MetricDefs["metric2"].Description)
392 a.Equal("preset2 description", ms.PresetDefs["preset2"].Description)
393 }