cloudflare/pint

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.40.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

internal/promapi/config_test.go

189lines · modecode

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