cloudflare/pint

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.16.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

internal/promapi/config_test.go

177lines · modecode

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