cloudflare/pint

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.75.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

internal/promapi/config_test.go

191lines · 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 default:
51 w.WriteHeader(http.StatusBadRequest)
52 w.Header().Set("Content-Type", "application/json")
53 _, _ = w.Write([]byte(`{"status":"error","errorType":"bad_data","error":"unhandled path"}`))
54 }
55 }))
56 t.Cleanup(srv.Close)
57
58 type testCaseT struct {
59 prefix string
60 err string
61 cfg promapi.ConfigResult
62 timeout time.Duration
63 }
64
65 defaults := promapi.PrometheusConfig{
66 Global: promapi.ConfigSectionGlobal{
67 ScrapeInterval: time.Minute,
68 ScrapeTimeout: time.Second * 10,
69 EvaluationInterval: time.Minute,
70 ExternalLabels: nil,
71 },
72 }
73
74 testCases := []testCaseT{
75 {
76 prefix: "/default",
77 timeout: time.Second,
78 cfg: promapi.ConfigResult{
79 URI: srv.URL + "/default",
80 Config: defaults,
81 },
82 },
83 {
84 prefix: "/1m",
85 timeout: time.Second,
86 cfg: promapi.ConfigResult{
87 URI: srv.URL + "/1m",
88 Config: defaults,
89 },
90 },
91 {
92 prefix: "/30s",
93 timeout: time.Second,
94 cfg: promapi.ConfigResult{
95 URI: srv.URL + "/30s",
96 Config: promapi.PrometheusConfig{
97 Global: promapi.ConfigSectionGlobal{
98 ScrapeInterval: time.Second * 30,
99 ScrapeTimeout: time.Second * 10,
100 EvaluationInterval: time.Minute,
101 ExternalLabels: nil,
102 },
103 },
104 },
105 },
106 {
107 prefix: "/slow",
108 timeout: time.Millisecond * 10,
109 err: "connection timeout",
110 },
111 {
112 prefix: "/error",
113 timeout: time.Second,
114 err: "server_error: 500 Internal Server Error",
115 },
116 {
117 prefix: "/badYaml",
118 timeout: time.Second,
119 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),
120 },
121 }
122
123 for _, tc := range testCases {
124 t.Run(strings.TrimPrefix(tc.prefix, "/"), func(t *testing.T) {
125 prom := promapi.NewPrometheus("test", srv.URL+tc.prefix, "", nil, tc.timeout, 1, 100, nil)
126 prom.StartWorkers()
127 t.Cleanup(prom.Close)
128
129 cfg, err := prom.Config(t.Context(), time.Minute)
130 if tc.err != "" {
131 require.EqualError(t, err, tc.err, tc)
132 } else {
133 require.NoError(t, err)
134 require.Equal(t, *cfg, tc.cfg)
135 }
136 })
137 }
138}
139
140func TestConfigHeaders(t *testing.T) {
141 type testCaseT struct {
142 config map[string]string
143 request map[string]string
144 shouldFail bool
145 }
146
147 testCases := []testCaseT{
148 {
149 config: nil,
150 request: nil,
151 },
152 {
153 config: nil,
154 request: map[string]string{"X-Foo": "bar"},
155 shouldFail: true,
156 },
157 {
158 config: map[string]string{"X-Foo": "bar", "X-Bar": "foo"},
159 request: map[string]string{"X-Foo": "bar", "X-Bar": "foo"},
160 },
161 }
162
163 for i, tc := range testCases {
164 t.Run(strconv.Itoa(i), func(t *testing.T) {
165 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
166 for k, v := range tc.request {
167 if tc.shouldFail {
168 assert.NotEqual(t, r.Header.Get(k), v)
169 } else {
170 assert.Equal(t, r.Header.Get(k), v)
171 }
172 }
173 w.WriteHeader(http.StatusOK)
174 w.Header().Set("Content-Type", "application/json")
175 _, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"global:\n scrape_interval: 30s\n"}}`))
176 }))
177 t.Cleanup(srv.Close)
178
179 fg := promapi.NewFailoverGroup("test", srv.URL, []*promapi.Prometheus{
180 promapi.NewPrometheus("test", srv.URL, "", tc.config, time.Second, 1, 100, nil),
181 }, true, "up", nil, nil, nil)
182
183 reg := prometheus.NewRegistry()
184 fg.StartWorkers(reg)
185 defer fg.Close(reg)
186
187 _, err := fg.Config(t.Context(), 0)
188 require.NoError(t, err)
189 })
190 }
191}
192