pangolin_exporter
243 строки · 9.4 Кб
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.
13package collector
14
15import (
16"context"
17"testing"
18"time"
19
20"github.com/DATA-DOG/go-sqlmock"
21"github.com/prometheus/client_golang/prometheus"
22dto "github.com/prometheus/client_model/go"
23"github.com/smartystreets/goconvey/convey"
24)
25
26func TestPGStatUserTablesCollector(t *testing.T) {
27db, mock, err := sqlmock.New()
28if err != nil {
29t.Fatalf("Error opening a stub db connection: %s", err)
30}
31defer db.Close()
32
33inst := &instance{db: db}
34
35lastVacuumTime, err := time.Parse("2006-01-02Z", "2023-06-02Z")
36if err != nil {
37t.Fatalf("Error parsing vacuum time: %s", err)
38}
39lastAutoVacuumTime, err := time.Parse("2006-01-02Z", "2023-06-03Z")
40if err != nil {
41t.Fatalf("Error parsing vacuum time: %s", err)
42}
43lastAnalyzeTime, err := time.Parse("2006-01-02Z", "2023-06-04Z")
44if err != nil {
45t.Fatalf("Error parsing vacuum time: %s", err)
46}
47lastAutoAnalyzeTime, err := time.Parse("2006-01-02Z", "2023-06-05Z")
48if err != nil {
49t.Fatalf("Error parsing vacuum time: %s", err)
50}
51
52columns := []string{
53"datname",
54"schemaname",
55"relname",
56"seq_scan",
57"seq_tup_read",
58"idx_scan",
59"idx_tup_fetch",
60"n_tup_ins",
61"n_tup_upd",
62"n_tup_del",
63"n_tup_hot_upd",
64"n_live_tup",
65"n_dead_tup",
66"n_mod_since_analyze",
67"last_vacuum",
68"last_autovacuum",
69"last_analyze",
70"last_autoanalyze",
71"vacuum_count",
72"autovacuum_count",
73"analyze_count",
74"autoanalyze_count",
75"total_size"}
76rows := sqlmock.NewRows(columns).
77AddRow("postgres",
78"public",
79"a_table",
801,
812,
823,
834,
845,
856,
867,
878,
889,
8910,
900,
91lastVacuumTime,
92lastAutoVacuumTime,
93lastAnalyzeTime,
94lastAutoAnalyzeTime,
9511,
9612,
9713,
9814,
9915)
100mock.ExpectQuery(sanitizeQuery(statUserTablesQuery)).WillReturnRows(rows)
101ch := make(chan prometheus.Metric)
102go func() {
103defer close(ch)
104c := PGStatUserTablesCollector{}
105
106if err := c.Update(context.Background(), inst, ch); err != nil {
107t.Errorf("Error calling PGStatUserTablesCollector.Update: %s", err)
108}
109}()
110
111expected := []MetricResult{
112{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_COUNTER, value: 1},
113{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_COUNTER, value: 2},
114{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_COUNTER, value: 3},
115{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_COUNTER, value: 4},
116{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_COUNTER, value: 5},
117{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_COUNTER, value: 6},
118{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_COUNTER, value: 7},
119{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_COUNTER, value: 8},
120{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_GAUGE, value: 9},
121{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_GAUGE, value: 10},
122{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_GAUGE, value: 0},
123{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_GAUGE, value: 1685664000},
124{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_GAUGE, value: 1685750400},
125{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_GAUGE, value: 1685836800},
126{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_GAUGE, value: 1685923200},
127{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_COUNTER, value: 11},
128{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_COUNTER, value: 12},
129{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_COUNTER, value: 13},
130{labels: labelMap{"datname": "postgres", "schemaname": "public", "relname": "a_table"}, metricType: dto.MetricType_COUNTER, value: 14},
131}
132
133convey.Convey("Metrics comparison", t, func() {
134for _, expect := range expected {
135m := readMetric(<-ch)
136convey.So(expect, convey.ShouldResemble, m)
137}
138})
139if err := mock.ExpectationsWereMet(); err != nil {
140t.Errorf("there were unfulfilled exceptions: %s", err)
141}
142}
143
144func TestPGStatUserTablesCollectorNullValues(t *testing.T) {
145db, mock, err := sqlmock.New()
146if err != nil {
147t.Fatalf("Error opening a stub db connection: %s", err)
148}
149defer db.Close()
150
151inst := &instance{db: db}
152
153columns := []string{
154"datname",
155"schemaname",
156"relname",
157"seq_scan",
158"seq_tup_read",
159"idx_scan",
160"idx_tup_fetch",
161"n_tup_ins",
162"n_tup_upd",
163"n_tup_del",
164"n_tup_hot_upd",
165"n_live_tup",
166"n_dead_tup",
167"n_mod_since_analyze",
168"last_vacuum",
169"last_autovacuum",
170"last_analyze",
171"last_autoanalyze",
172"vacuum_count",
173"autovacuum_count",
174"analyze_count",
175"autoanalyze_count",
176"total_size"}
177rows := sqlmock.NewRows(columns).
178AddRow("postgres",
179nil,
180nil,
181nil,
182nil,
183nil,
184nil,
185nil,
186nil,
187nil,
188nil,
189nil,
190nil,
191nil,
192nil,
193nil,
194nil,
195nil,
196nil,
197nil,
198nil,
199nil,
200nil)
201mock.ExpectQuery(sanitizeQuery(statUserTablesQuery)).WillReturnRows(rows)
202ch := make(chan prometheus.Metric)
203go func() {
204defer close(ch)
205c := PGStatUserTablesCollector{}
206
207if err := c.Update(context.Background(), inst, ch); err != nil {
208t.Errorf("Error calling PGStatUserTablesCollector.Update: %s", err)
209}
210}()
211
212expected := []MetricResult{
213{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_COUNTER, value: 0},
214{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_COUNTER, value: 0},
215{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_COUNTER, value: 0},
216{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_COUNTER, value: 0},
217{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_COUNTER, value: 0},
218{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_COUNTER, value: 0},
219{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_COUNTER, value: 0},
220{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_COUNTER, value: 0},
221{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_GAUGE, value: 0},
222{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_GAUGE, value: 0},
223{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_GAUGE, value: 0},
224{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_GAUGE, value: 0},
225{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_GAUGE, value: 0},
226{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_GAUGE, value: 0},
227{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_GAUGE, value: 0},
228{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_COUNTER, value: 0},
229{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_COUNTER, value: 0},
230{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_COUNTER, value: 0},
231{labels: labelMap{"datname": "postgres", "schemaname": "unknown", "relname": "unknown"}, metricType: dto.MetricType_COUNTER, value: 0},
232}
233
234convey.Convey("Metrics comparison", t, func() {
235for _, expect := range expected {
236m := readMetric(<-ch)
237convey.So(expect, convey.ShouldResemble, m)
238}
239})
240if err := mock.ExpectationsWereMet(); err != nil {
241t.Errorf("there were unfulfilled exceptions: %s", err)
242}
243}
244