pangolin_exporter

Форк
0
/
pg_stat_database_test.go 
523 строки · 17.7 Кб
1
// Copyright 2023 The Prometheus Authors
2
// Licensed under the Apache License, Version 2.0 (the "License");
3
// you may not use this file except in compliance with the License.
4
// You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software
9
// distributed under the License is distributed on an "AS IS" BASIS,
10
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
// See the License for the specific language governing permissions and
12
// limitations under the License.
13
package collector
14

15
import (
16
	"context"
17
	"testing"
18
	"time"
19

20
	"github.com/DATA-DOG/go-sqlmock"
21
	"github.com/go-kit/log"
22
	"github.com/prometheus/client_golang/prometheus"
23
	dto "github.com/prometheus/client_model/go"
24
	"github.com/smartystreets/goconvey/convey"
25
)
26

27
func TestPGStatDatabaseCollector(t *testing.T) {
28
	db, mock, err := sqlmock.New()
29
	if err != nil {
30
		t.Fatalf("Error opening a stub db connection: %s", err)
31
	}
32
	defer db.Close()
33

34
	inst := &instance{db: db}
35

36
	columns := []string{
37
		"datid",
38
		"datname",
39
		"numbackends",
40
		"xact_commit",
41
		"xact_rollback",
42
		"blks_read",
43
		"blks_hit",
44
		"tup_returned",
45
		"tup_fetched",
46
		"tup_inserted",
47
		"tup_updated",
48
		"tup_deleted",
49
		"conflicts",
50
		"temp_files",
51
		"temp_bytes",
52
		"deadlocks",
53
		"blk_read_time",
54
		"blk_write_time",
55
		"active_time",
56
		"stats_reset",
57
	}
58

59
	srT, err := time.Parse("2006-01-02 15:04:05.00000-07", "2023-05-25 17:10:42.81132-07")
60
	if err != nil {
61
		t.Fatalf("Error parsing time: %s", err)
62
	}
63

64
	rows := sqlmock.NewRows(columns).
65
		AddRow(
66
			"pid",
67
			"postgres",
68
			354,
69
			4945,
70
			289097744,
71
			1242257,
72
			int64(3275602074),
73
			89320867,
74
			450139,
75
			2034563757,
76
			0,
77
			int64(2725688749),
78
			23,
79
			52,
80
			74,
81
			925,
82
			16,
83
			823,
84
			33,
85
			srT)
86

87
	mock.ExpectQuery(sanitizeQuery(statDatabaseQuery)).WillReturnRows(rows)
88

89
	ch := make(chan prometheus.Metric)
90
	go func() {
91
		defer close(ch)
92
		c := PGStatDatabaseCollector{
93
			log: log.With(log.NewNopLogger(), "collector", "pg_stat_database"),
94
		}
95

96
		if err := c.Update(context.Background(), inst, ch); err != nil {
97
			t.Errorf("Error calling PGStatDatabaseCollector.Update: %s", err)
98
		}
99
	}()
100

101
	expected := []MetricResult{
102
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_GAUGE, value: 354},
103
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 4945},
104
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 289097744},
105
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 1242257},
106
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 3275602074},
107
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 89320867},
108
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 450139},
109
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 2034563757},
110
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 0},
111
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 2725688749},
112
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 23},
113
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 52},
114
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 74},
115
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 925},
116
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 16},
117
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 823},
118
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 0.033},
119
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 1685059842},
120
	}
121

122
	convey.Convey("Metrics comparison", t, func() {
123
		for _, expect := range expected {
124
			m := readMetric(<-ch)
125
			convey.So(expect, convey.ShouldResemble, m)
126
		}
127
	})
128
	if err := mock.ExpectationsWereMet(); err != nil {
129
		t.Errorf("there were unfulfilled exceptions: %s", err)
130
	}
131
}
132

133
func TestPGStatDatabaseCollectorNullValues(t *testing.T) {
134
	db, mock, err := sqlmock.New()
135
	if err != nil {
136
		t.Fatalf("Error opening a stub db connection: %s", err)
137
	}
138
	defer db.Close()
139

140
	srT, err := time.Parse("2006-01-02 15:04:05.00000-07", "2023-05-25 17:10:42.81132-07")
141
	if err != nil {
142
		t.Fatalf("Error parsing time: %s", err)
143
	}
144
	inst := &instance{db: db}
145

146
	columns := []string{
147
		"datid",
148
		"datname",
149
		"numbackends",
150
		"xact_commit",
151
		"xact_rollback",
152
		"blks_read",
153
		"blks_hit",
154
		"tup_returned",
155
		"tup_fetched",
156
		"tup_inserted",
157
		"tup_updated",
158
		"tup_deleted",
159
		"conflicts",
160
		"temp_files",
161
		"temp_bytes",
162
		"deadlocks",
163
		"blk_read_time",
164
		"blk_write_time",
165
		"active_time",
166
		"stats_reset",
167
	}
168

169
	rows := sqlmock.NewRows(columns).
170
		AddRow(
171
			nil,
172
			"postgres",
173
			354,
174
			4945,
175
			289097744,
176
			1242257,
177
			int64(3275602074),
178
			89320867,
179
			450139,
180
			2034563757,
181
			0,
182
			int64(2725688749),
183
			23,
184
			52,
185
			74,
186
			925,
187
			16,
188
			823,
189
			32,
190
			srT).
191
		AddRow(
192
			"pid",
193
			"postgres",
194
			354,
195
			4945,
196
			289097744,
197
			1242257,
198
			int64(3275602074),
199
			89320867,
200
			450139,
201
			2034563757,
202
			0,
203
			int64(2725688749),
204
			23,
205
			52,
206
			74,
207
			925,
208
			16,
209
			823,
210
			32,
211
			srT)
212
	mock.ExpectQuery(sanitizeQuery(statDatabaseQuery)).WillReturnRows(rows)
213

214
	ch := make(chan prometheus.Metric)
215
	go func() {
216
		defer close(ch)
217
		c := PGStatDatabaseCollector{
218
			log: log.With(log.NewNopLogger(), "collector", "pg_stat_database"),
219
		}
220

221
		if err := c.Update(context.Background(), inst, ch); err != nil {
222
			t.Errorf("Error calling PGStatDatabaseCollector.Update: %s", err)
223
		}
224
	}()
225

226
	expected := []MetricResult{
227
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_GAUGE, value: 354},
228
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 4945},
229
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 289097744},
230
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 1242257},
231
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 3275602074},
232
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 89320867},
233
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 450139},
234
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 2034563757},
235
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 0},
236
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 2725688749},
237
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 23},
238
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 52},
239
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 74},
240
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 925},
241
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 16},
242
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 823},
243
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 0.032},
244
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 1685059842},
245
	}
246

247
	convey.Convey("Metrics comparison", t, func() {
248
		for _, expect := range expected {
249
			m := readMetric(<-ch)
250
			convey.So(expect, convey.ShouldResemble, m)
251
		}
252
	})
253
	if err := mock.ExpectationsWereMet(); err != nil {
254
		t.Errorf("there were unfulfilled exceptions: %s", err)
255
	}
256
}
257
func TestPGStatDatabaseCollectorRowLeakTest(t *testing.T) {
258
	db, mock, err := sqlmock.New()
259
	if err != nil {
260
		t.Fatalf("Error opening a stub db connection: %s", err)
261
	}
262
	defer db.Close()
263

264
	inst := &instance{db: db}
265

266
	columns := []string{
267
		"datid",
268
		"datname",
269
		"numbackends",
270
		"xact_commit",
271
		"xact_rollback",
272
		"blks_read",
273
		"blks_hit",
274
		"tup_returned",
275
		"tup_fetched",
276
		"tup_inserted",
277
		"tup_updated",
278
		"tup_deleted",
279
		"conflicts",
280
		"temp_files",
281
		"temp_bytes",
282
		"deadlocks",
283
		"blk_read_time",
284
		"blk_write_time",
285
		"active_time",
286
		"stats_reset",
287
	}
288

289
	srT, err := time.Parse("2006-01-02 15:04:05.00000-07", "2023-05-25 17:10:42.81132-07")
290
	if err != nil {
291
		t.Fatalf("Error parsing time: %s", err)
292
	}
293

294
	rows := sqlmock.NewRows(columns).
295
		AddRow(
296
			"pid",
297
			"postgres",
298
			354,
299
			4945,
300
			289097744,
301
			1242257,
302
			int64(3275602074),
303
			89320867,
304
			450139,
305
			2034563757,
306
			0,
307
			int64(2725688749),
308
			23,
309
			52,
310
			74,
311
			925,
312
			16,
313
			823,
314
			14,
315
			srT).
316
		AddRow(
317
			nil,
318
			nil,
319
			nil,
320
			nil,
321
			nil,
322
			nil,
323
			nil,
324
			nil,
325
			nil,
326
			nil,
327
			nil,
328
			nil,
329
			nil,
330
			nil,
331
			nil,
332
			nil,
333
			nil,
334
			nil,
335
			nil,
336
			nil,
337
		).
338
		AddRow(
339
			"pid",
340
			"postgres",
341
			355,
342
			4946,
343
			289097745,
344
			1242258,
345
			int64(3275602075),
346
			89320868,
347
			450140,
348
			2034563758,
349
			1,
350
			int64(2725688750),
351
			24,
352
			53,
353
			75,
354
			926,
355
			17,
356
			824,
357
			15,
358
			srT)
359
	mock.ExpectQuery(sanitizeQuery(statDatabaseQuery)).WillReturnRows(rows)
360

361
	ch := make(chan prometheus.Metric)
362
	go func() {
363
		defer close(ch)
364
		c := PGStatDatabaseCollector{
365
			log: log.With(log.NewNopLogger(), "collector", "pg_stat_database"),
366
		}
367

368
		if err := c.Update(context.Background(), inst, ch); err != nil {
369
			t.Errorf("Error calling PGStatDatabaseCollector.Update: %s", err)
370
		}
371
	}()
372

373
	expected := []MetricResult{
374
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_GAUGE, value: 354},
375
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 4945},
376
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 289097744},
377
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 1242257},
378
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 3275602074},
379
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 89320867},
380
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 450139},
381
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 2034563757},
382
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 0},
383
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 2725688749},
384
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 23},
385
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 52},
386
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 74},
387
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 925},
388
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 16},
389
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 823},
390
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 0.014},
391
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 1685059842},
392

393
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_GAUGE, value: 355},
394
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 4946},
395
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 289097745},
396
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 1242258},
397
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 3275602075},
398
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 89320868},
399
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 450140},
400
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 2034563758},
401
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 1},
402
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 2725688750},
403
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 24},
404
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 53},
405
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 75},
406
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 926},
407
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 17},
408
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 824},
409
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 0.015},
410
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 1685059842},
411
	}
412

413
	convey.Convey("Metrics comparison", t, func() {
414
		for _, expect := range expected {
415
			m := readMetric(<-ch)
416
			convey.So(expect, convey.ShouldResemble, m)
417
		}
418
	})
419
	if err := mock.ExpectationsWereMet(); err != nil {
420
		t.Errorf("there were unfulfilled exceptions: %s", err)
421
	}
422
}
423

424
func TestPGStatDatabaseCollectorTestNilStatReset(t *testing.T) {
425
	db, mock, err := sqlmock.New()
426
	if err != nil {
427
		t.Fatalf("Error opening a stub db connection: %s", err)
428
	}
429
	defer db.Close()
430

431
	inst := &instance{db: db}
432

433
	columns := []string{
434
		"datid",
435
		"datname",
436
		"numbackends",
437
		"xact_commit",
438
		"xact_rollback",
439
		"blks_read",
440
		"blks_hit",
441
		"tup_returned",
442
		"tup_fetched",
443
		"tup_inserted",
444
		"tup_updated",
445
		"tup_deleted",
446
		"conflicts",
447
		"temp_files",
448
		"temp_bytes",
449
		"deadlocks",
450
		"blk_read_time",
451
		"blk_write_time",
452
		"active_time",
453
		"stats_reset",
454
	}
455

456
	rows := sqlmock.NewRows(columns).
457
		AddRow(
458
			"pid",
459
			"postgres",
460
			354,
461
			4945,
462
			289097744,
463
			1242257,
464
			int64(3275602074),
465
			89320867,
466
			450139,
467
			2034563757,
468
			0,
469
			int64(2725688749),
470
			23,
471
			52,
472
			74,
473
			925,
474
			16,
475
			823,
476
			7,
477
			nil)
478

479
	mock.ExpectQuery(sanitizeQuery(statDatabaseQuery)).WillReturnRows(rows)
480

481
	ch := make(chan prometheus.Metric)
482
	go func() {
483
		defer close(ch)
484
		c := PGStatDatabaseCollector{
485
			log: log.With(log.NewNopLogger(), "collector", "pg_stat_database"),
486
		}
487

488
		if err := c.Update(context.Background(), inst, ch); err != nil {
489
			t.Errorf("Error calling PGStatDatabaseCollector.Update: %s", err)
490
		}
491
	}()
492

493
	expected := []MetricResult{
494
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_GAUGE, value: 354},
495
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 4945},
496
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 289097744},
497
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 1242257},
498
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 3275602074},
499
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 89320867},
500
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 450139},
501
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 2034563757},
502
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 0},
503
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 2725688749},
504
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 23},
505
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 52},
506
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 74},
507
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 925},
508
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 16},
509
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 823},
510
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 0.007},
511
		{labels: labelMap{"datid": "pid", "datname": "postgres"}, metricType: dto.MetricType_COUNTER, value: 0},
512
	}
513

514
	convey.Convey("Metrics comparison", t, func() {
515
		for _, expect := range expected {
516
			m := readMetric(<-ch)
517
			convey.So(expect, convey.ShouldResemble, m)
518
		}
519
	})
520
	if err := mock.ExpectationsWereMet(); err != nil {
521
		t.Errorf("there were unfulfilled exceptions: %s", err)
522
	}
523
}
524

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.