cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.79.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

internal/promapi/config_test.go

209lines · modecode

1package promapi_test
2
3import (
4 "fmt"
5 "net/http"
6 "net/http/httptest"
7 "strconv"
8 "strings"
9 "testing"
10 "time"
11
12 "github.com/prometheus/client_golang/prometheus"
13 "github.com/stretchr/testify/assert"
14 "github.com/stretchr/testify/require"
15
16 "github.com/cloudflare/pint/internal/promapi"
17)
18
19func TestConfig(t *testing.T) {
20 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
21 switch r.URL.Path {
22 case "/30s" + promapi.APIPathConfig:
23 w.WriteHeader(http.StatusOK)
24 w.Header().Set("Content-Type", "application/json")
25 _, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"global:\n scrape_interval: 30s\n"}}`))
26 case "/1m" + promapi.APIPathConfig:
27 w.WriteHeader(http.StatusOK)
28 w.Header().Set("Content-Type", "application/json")
29 _, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"global:\n scrape_interval: 1m\n"}}`))
30 case "/default" + promapi.APIPathConfig:
31 w.WriteHeader(http.StatusOK)
32 w.Header().Set("Content-Type", "application/json")
33 _, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"global:\n {}\n"}}`))
34 case "/once" + promapi.APIPathConfig:
35 w.WriteHeader(http.StatusOK)
36 w.Header().Set("Content-Type", "application/json")
37 _, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"global:\n {}\n"}}`))
38 case "/slow" + promapi.APIPathConfig:
39 w.WriteHeader(http.StatusOK)
40 w.Header().Set("Content-Type", "application/json")
41 time.Sleep(time.Second * 2)
42 _, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"global:\n {}\n"}}`))
43 case "/error" + promapi.APIPathConfig:
44 w.WriteHeader(http.StatusInternalServerError)
45 _, _ = w.Write([]byte("fake error\n"))
46 case "/badYaml" + promapi.APIPathConfig:
47 w.WriteHeader(http.StatusOK)
48 w.Header().Set("Content-Type", "application/json")
49 _, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"invalid yaml"}}`))
50 case "/badJson" + promapi.APIPathConfig:
51 w.WriteHeader(http.StatusOK)
52 w.Header().Set("Content-Type", "application/json")
53 _, _ = w.Write([]byte(`{"status":"success","data":{"yaml"}}`))
54 case "/apiError" + promapi.APIPathConfig:
55 w.WriteHeader(http.StatusOK)
56 w.Header().Set("Content-Type", "application/json")
57 _, _ = w.Write([]byte(`{"status":"error","errorType":"bad_data","error":"custom error message"}`))
58 default:
59 w.WriteHeader(http.StatusBadRequest)
60 w.Header().Set("Content-Type", "application/json")
61 _, _ = w.Write([]byte(`{"status":"error","errorType":"bad_data","error":"unhandled path"}`))
62 }
63 }))
64 t.Cleanup(srv.Close)
65
66 type testCaseT struct {
67 prefix string
68 err string
69 cfg promapi.ConfigResult
70 timeout time.Duration
71 }
72
73 defaults := promapi.PrometheusConfig{
74 Global: promapi.ConfigSectionGlobal{
75 ScrapeInterval: time.Minute,
76 ScrapeTimeout: time.Second * 10,
77 EvaluationInterval: time.Minute,
78 ExternalLabels: nil,
79 },
80 }
81
82 testCases := []testCaseT{
83 {
84 prefix: "/default",
85 timeout: time.Second,
86 cfg: promapi.ConfigResult{
87 URI: srv.URL + "/default",
88 Config: defaults,
89 },
90 },
91 {
92 prefix: "/1m",
93 timeout: time.Second,
94 cfg: promapi.ConfigResult{
95 URI: srv.URL + "/1m",
96 Config: defaults,
97 },
98 },
99 {
100 prefix: "/30s",
101 timeout: time.Second,
102 cfg: promapi.ConfigResult{
103 URI: srv.URL + "/30s",
104 Config: promapi.PrometheusConfig{
105 Global: promapi.ConfigSectionGlobal{
106 ScrapeInterval: time.Second * 30,
107 ScrapeTimeout: time.Second * 10,
108 EvaluationInterval: time.Minute,
109 ExternalLabels: nil,
110 },
111 },
112 },
113 },
114 {
115 prefix: "/slow",
116 timeout: time.Millisecond * 10,
117 err: "connection timeout",
118 },
119 {
120 prefix: "/error",
121 timeout: time.Second,
122 err: "server_error: 500 Internal Server Error",
123 },
124 {
125 prefix: "/badYaml",
126 timeout: time.Second,
127 err: fmt.Sprintf("failed to decode config data in %s/badYaml response: yaml: unmarshal errors:\n line 1: cannot unmarshal !!str `invalid...` into promapi.PrometheusConfig", srv.URL),
128 },
129 {
130 prefix: "/badJson",
131 timeout: time.Second,
132 err: "bad_response: JSON parse error: invalid character '}' after object key",
133 },
134 {
135 prefix: "/apiError",
136 timeout: time.Second,
137 err: "bad_data: custom error message",
138 },
139 }
140
141 for _, tc := range testCases {
142 t.Run(strings.TrimPrefix(tc.prefix, "/"), func(t *testing.T) {
143 prom := promapi.NewPrometheus("test", srv.URL+tc.prefix, "", nil, tc.timeout, 1, 100, nil)
144 prom.StartWorkers()
145 t.Cleanup(prom.Close)
146
147 cfg, err := prom.Config(t.Context(), time.Minute)
148 if tc.err != "" {
149 require.EqualError(t, err, tc.err, tc)
150 } else {
151 require.NoError(t, err)
152 require.Equal(t, *cfg, tc.cfg)
153 }
154 })
155 }
156}
157
158func TestConfigHeaders(t *testing.T) {
159 type testCaseT struct {
160 config map[string]string
161 request map[string]string
162 shouldFail bool
163 }
164
165 testCases := []testCaseT{
166 {
167 config: nil,
168 request: nil,
169 },
170 {
171 config: nil,
172 request: map[string]string{"X-Foo": "bar"},
173 shouldFail: true,
174 },
175 {
176 config: map[string]string{"X-Foo": "bar", "X-Bar": "foo"},
177 request: map[string]string{"X-Foo": "bar", "X-Bar": "foo"},
178 },
179 }
180
181 for i, tc := range testCases {
182 t.Run(strconv.Itoa(i), func(t *testing.T) {
183 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
184 for k, v := range tc.request {
185 if tc.shouldFail {
186 assert.NotEqual(t, r.Header.Get(k), v)
187 } else {
188 assert.Equal(t, r.Header.Get(k), v)
189 }
190 }
191 w.WriteHeader(http.StatusOK)
192 w.Header().Set("Content-Type", "application/json")
193 _, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"global:\n scrape_interval: 30s\n"}}`))
194 }))
195 t.Cleanup(srv.Close)
196
197 fg := promapi.NewFailoverGroup("test", srv.URL, []*promapi.Prometheus{
198 promapi.NewPrometheus("test", srv.URL, "", tc.config, time.Second, 1, 100, nil),
199 }, true, "up", nil, nil, nil)
200
201 reg := prometheus.NewRegistry()
202 fg.StartWorkers(reg)
203 defer fg.Close(reg)
204
205 _, err := fg.Config(t.Context(), 0)
206 require.NoError(t, err)
207 })
208 }
209}
210