Skip to content

Commit e0de429

Browse files
authored
Refactor tests for indices settings (#982)
- Refactor tests to test the output of the collector - Add missing metric descriptions in Describe() Signed-off-by: Joe Adams <github@joeadams.io>
1 parent 4301b8d commit e0de429

File tree

3 files changed

+132
-70
lines changed

3 files changed

+132
-70
lines changed

collector/indices_settings.go

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,9 @@ type IndicesSettings struct {
3232
client *http.Client
3333
url *url.URL
3434

35-
up prometheus.Gauge
3635
readOnlyIndices prometheus.Gauge
3736

38-
totalScrapes, jsonParseFailures prometheus.Counter
39-
metrics []*indicesSettingsMetric
37+
metrics []*indicesSettingsMetric
4038
}
4139

4240
var (
@@ -58,22 +56,11 @@ func NewIndicesSettings(logger *slog.Logger, client *http.Client, url *url.URL)
5856
client: client,
5957
url: url,
6058

61-
up: prometheus.NewGauge(prometheus.GaugeOpts{
62-
Name: prometheus.BuildFQName(namespace, "indices_settings_stats", "up"),
63-
Help: "Was the last scrape of the Elasticsearch Indices Settings endpoint successful.",
64-
}),
65-
totalScrapes: prometheus.NewCounter(prometheus.CounterOpts{
66-
Name: prometheus.BuildFQName(namespace, "indices_settings_stats", "total_scrapes"),
67-
Help: "Current total Elasticsearch Indices Settings scrapes.",
68-
}),
6959
readOnlyIndices: prometheus.NewGauge(prometheus.GaugeOpts{
7060
Name: prometheus.BuildFQName(namespace, "indices_settings_stats", "read_only_indices"),
7161
Help: "Current number of read only indices within cluster",
7262
}),
73-
jsonParseFailures: prometheus.NewCounter(prometheus.CounterOpts{
74-
Name: prometheus.BuildFQName(namespace, "indices_settings_stats", "json_parse_failures"),
75-
Help: "Number of errors while parsing JSON.",
76-
}),
63+
7764
metrics: []*indicesSettingsMetric{
7865
{
7966
Type: prometheus.GaugeValue,
@@ -126,10 +113,11 @@ func NewIndicesSettings(logger *slog.Logger, client *http.Client, url *url.URL)
126113

127114
// Describe add Snapshots metrics descriptions
128115
func (cs *IndicesSettings) Describe(ch chan<- *prometheus.Desc) {
129-
ch <- cs.up.Desc()
130-
ch <- cs.totalScrapes.Desc()
131116
ch <- cs.readOnlyIndices.Desc()
132-
ch <- cs.jsonParseFailures.Desc()
117+
118+
for _, metric := range cs.metrics {
119+
ch <- metric.Desc
120+
}
133121
}
134122

135123
func (cs *IndicesSettings) getAndParseURL(u *url.URL, data interface{}) error {
@@ -155,12 +143,10 @@ func (cs *IndicesSettings) getAndParseURL(u *url.URL, data interface{}) error {
155143

156144
bts, err := io.ReadAll(res.Body)
157145
if err != nil {
158-
cs.jsonParseFailures.Inc()
159146
return err
160147
}
161148

162149
if err := json.Unmarshal(bts, data); err != nil {
163-
cs.jsonParseFailures.Inc()
164150
return err
165151
}
166152
return nil
@@ -181,26 +167,15 @@ func (cs *IndicesSettings) fetchAndDecodeIndicesSettings() (IndicesSettingsRespo
181167

182168
// Collect gets all indices settings metric values
183169
func (cs *IndicesSettings) Collect(ch chan<- prometheus.Metric) {
184-
185-
cs.totalScrapes.Inc()
186-
defer func() {
187-
ch <- cs.up
188-
ch <- cs.totalScrapes
189-
ch <- cs.jsonParseFailures
190-
ch <- cs.readOnlyIndices
191-
}()
192-
193170
asr, err := cs.fetchAndDecodeIndicesSettings()
194171
if err != nil {
195172
cs.readOnlyIndices.Set(0)
196-
cs.up.Set(0)
197173
cs.logger.Warn(
198174
"failed to fetch and decode cluster settings stats",
199175
"err", err,
200176
)
201177
return
202178
}
203-
cs.up.Set(1)
204179

205180
var c int
206181
for indexName, value := range asr {
@@ -217,4 +192,6 @@ func (cs *IndicesSettings) Collect(ch chan<- prometheus.Metric) {
217192
}
218193
}
219194
cs.readOnlyIndices.Set(float64(c))
195+
196+
ch <- cs.readOnlyIndices
220197
}

collector/indices_settings_test.go

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@
1414
package collector
1515

1616
import (
17-
"fmt"
17+
"io"
1818
"net/http"
1919
"net/http/httptest"
2020
"net/url"
21+
"os"
22+
"path"
23+
"strings"
2124
"testing"
2225

26+
"github.com/prometheus/client_golang/prometheus/testutil"
2327
"github.com/prometheus/common/promslog"
2428
)
2529

@@ -54,53 +58,65 @@ func TestIndicesSettings(t *testing.T) {
5458

5559
// curl http://localhost:9200/_all/_settings
5660

57-
tcs := map[string]string{
58-
"6.5.4": `{"viber":{"settings":{"index":{"creation_date":"1618593207186","number_of_shards":"5","number_of_replicas":"1","uuid":"lWg86KTARzO3r7lELytT1Q","version":{"created":"6050499"},"provided_name":"viber"}}},"instagram":{"settings":{"index":{"mapping":{"total_fields":{"limit":"10000"}},"number_of_shards":"5","blocks":{"read_only_allow_delete":"true"},"provided_name":"instagram","creation_date":"1618593203353","number_of_replicas":"1","uuid":"msb6eG7aT8GmNe-a4oyVtQ","version":{"created":"6050499"}}}},"twitter":{"settings":{"index":{"number_of_shards":"5","blocks":{"read_only_allow_delete":"true"},"provided_name":"twitter","creation_date":"1618593193641","number_of_replicas":"1","uuid":"YRUT8t4aSkKsNmGl7K3y4Q","version":{"created":"6050499"}}}},"facebook":{"settings":{"index":{"creation_date":"1618593199101","number_of_shards":"5","number_of_replicas":"1","uuid":"trZhb_YOTV-RWKitTYw81A","version":{"created":"6050499"},"provided_name":"facebook"}}}}`,
61+
tests := []struct {
62+
name string
63+
file string
64+
want string
65+
}{
66+
{
67+
name: "6.5.4",
68+
file: "6.5.4.json",
69+
want: `# HELP elasticsearch_indices_settings_creation_timestamp_seconds index setting creation_date
70+
# TYPE elasticsearch_indices_settings_creation_timestamp_seconds gauge
71+
elasticsearch_indices_settings_creation_timestamp_seconds{index="facebook"} 1.618593199101e+09
72+
elasticsearch_indices_settings_creation_timestamp_seconds{index="instagram"} 1.618593203353e+09
73+
elasticsearch_indices_settings_creation_timestamp_seconds{index="twitter"} 1.618593193641e+09
74+
elasticsearch_indices_settings_creation_timestamp_seconds{index="viber"} 1.618593207186e+09
75+
# HELP elasticsearch_indices_settings_replicas index setting number_of_replicas
76+
# TYPE elasticsearch_indices_settings_replicas gauge
77+
elasticsearch_indices_settings_replicas{index="facebook"} 1
78+
elasticsearch_indices_settings_replicas{index="instagram"} 1
79+
elasticsearch_indices_settings_replicas{index="twitter"} 1
80+
elasticsearch_indices_settings_replicas{index="viber"} 1
81+
# HELP elasticsearch_indices_settings_stats_read_only_indices Current number of read only indices within cluster
82+
# TYPE elasticsearch_indices_settings_stats_read_only_indices gauge
83+
elasticsearch_indices_settings_stats_read_only_indices 2
84+
# HELP elasticsearch_indices_settings_total_fields index mapping setting for total_fields
85+
# TYPE elasticsearch_indices_settings_total_fields gauge
86+
elasticsearch_indices_settings_total_fields{index="facebook"} 1000
87+
elasticsearch_indices_settings_total_fields{index="instagram"} 10000
88+
elasticsearch_indices_settings_total_fields{index="twitter"} 1000
89+
elasticsearch_indices_settings_total_fields{index="viber"} 1000
90+
`,
91+
},
5992
}
60-
for ver, out := range tcs {
61-
for hn, handler := range map[string]http.Handler{
62-
"plain": http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
63-
fmt.Fprintln(w, out)
64-
}),
65-
} {
66-
ts := httptest.NewServer(handler)
93+
94+
for _, tt := range tests {
95+
t.Run(tt.name, func(t *testing.T) {
96+
f, err := os.Open(path.Join("../fixtures/indices_settings", tt.file))
97+
if err != nil {
98+
t.Fatal(err)
99+
}
100+
defer f.Close()
101+
102+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
103+
io.Copy(w, f)
104+
}))
67105
defer ts.Close()
68106

69107
u, err := url.Parse(ts.URL)
70108
if err != nil {
71-
t.Fatalf("Failed to parse URL: %s", err)
109+
t.Fatal(err)
72110
}
111+
73112
c := NewIndicesSettings(promslog.NewNopLogger(), http.DefaultClient, u)
74-
nsr, err := c.fetchAndDecodeIndicesSettings()
75113
if err != nil {
76-
t.Fatalf("Failed to fetch or decode indices settings: %s", err)
77-
}
78-
t.Logf("[%s/%s] All Indices Settings Response: %+v", hn, ver, nsr)
79-
// if nsr.Cluster.Routing.Allocation.Enabled != "ALL" {
80-
// t.Errorf("Wrong setting for cluster routing allocation enabled")
81-
// }
82-
var counter int
83-
var totalFields int
84-
for key, value := range nsr {
85-
if value.Settings.IndexInfo.Blocks.ReadOnly == "true" {
86-
counter++
87-
if key != "instagram" && key != "twitter" {
88-
t.Errorf("Wrong read_only index")
89-
}
90-
}
91-
if value.Settings.IndexInfo.Mapping.TotalFields.Limit == "10000" {
92-
totalFields++
93-
if key != "instagram" {
94-
t.Errorf("Expected 10000 total_fields only for instagram")
95-
}
96-
}
114+
t.Fatal(err)
97115
}
98-
if counter != 2 {
99-
t.Errorf("Wrong number of read_only indexes")
100-
}
101-
if totalFields != 1 {
102-
t.Errorf(("Wrong number of total_fields found"))
116+
117+
if err := testutil.CollectAndCompare(c, strings.NewReader(tt.want)); err != nil {
118+
t.Fatal(err)
103119
}
104-
}
120+
})
105121
}
106122
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
{
2+
"viber": {
3+
"settings": {
4+
"index": {
5+
"creation_date": "1618593207186",
6+
"number_of_shards": "5",
7+
"number_of_replicas": "1",
8+
"uuid": "lWg86KTARzO3r7lELytT1Q",
9+
"version": {
10+
"created": "6050499"
11+
},
12+
"provided_name": "viber"
13+
}
14+
}
15+
},
16+
"instagram": {
17+
"settings": {
18+
"index": {
19+
"mapping": {
20+
"total_fields": {
21+
"limit": "10000"
22+
}
23+
},
24+
"number_of_shards": "5",
25+
"blocks": {
26+
"read_only_allow_delete": "true"
27+
},
28+
"provided_name": "instagram",
29+
"creation_date": "1618593203353",
30+
"number_of_replicas": "1",
31+
"uuid": "msb6eG7aT8GmNe-a4oyVtQ",
32+
"version": {
33+
"created": "6050499"
34+
}
35+
}
36+
}
37+
},
38+
"twitter": {
39+
"settings": {
40+
"index": {
41+
"number_of_shards": "5",
42+
"blocks": {
43+
"read_only_allow_delete": "true"
44+
},
45+
"provided_name": "twitter",
46+
"creation_date": "1618593193641",
47+
"number_of_replicas": "1",
48+
"uuid": "YRUT8t4aSkKsNmGl7K3y4Q",
49+
"version": {
50+
"created": "6050499"
51+
}
52+
}
53+
}
54+
},
55+
"facebook": {
56+
"settings": {
57+
"index": {
58+
"creation_date": "1618593199101",
59+
"number_of_shards": "5",
60+
"number_of_replicas": "1",
61+
"uuid": "trZhb_YOTV-RWKitTYw81A",
62+
"version": {
63+
"created": "6050499"
64+
},
65+
"provided_name": "facebook"
66+
}
67+
}
68+
}
69+
}

0 commit comments

Comments
 (0)