cloudflare/pint

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.10.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

internal/promapi/query_test.go

224lines · modecode

1package promapi_test
2
3import (
4 "context"
5 "fmt"
6 "net/http"
7 "net/http/httptest"
8 "sync"
9 "testing"
10 "time"
11
12 "github.com/prometheus/common/model"
13 "github.com/stretchr/testify/assert"
14
15 "github.com/cloudflare/pint/internal/promapi"
16)
17
18func TestQuery(t *testing.T) {
19 done := sync.Map{}
20 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
21 err := r.ParseForm()
22 if err != nil {
23 t.Fatal(err)
24 }
25 query := r.Form.Get("query")
26
27 switch query {
28 case "empty":
29 w.WriteHeader(200)
30 w.Header().Set("Content-Type", "application/json")
31 _, _ = w.Write([]byte(`{
32 "status":"success",
33 "data":{
34 "resultType":"vector",
35 "result":[]
36 }
37 }`))
38 case "single_result":
39 w.WriteHeader(200)
40 w.Header().Set("Content-Type", "application/json")
41 _, _ = w.Write([]byte(`{
42 "status":"success",
43 "data":{
44 "resultType":"vector",
45 "result":[{"metric":{},"value":[1614859502.068,"1"]}]
46 }
47 }`))
48 case "three_results":
49 w.WriteHeader(200)
50 w.Header().Set("Content-Type", "application/json")
51 _, _ = w.Write([]byte(`{
52 "status":"success",
53 "data":{
54 "resultType":"vector",
55 "result":[
56 {"metric":{"instance": "1"},"value":[1614859502.068,"1"]},
57 {"metric":{"instance": "2"},"value":[1614859502.168,"2"]},
58 {"metric":{"instance": "3"},"value":[1614859503.000,"3"]}
59 ]
60 }
61 }`))
62 case "once":
63 if _, wasDone := done.Load(r.URL.Path); wasDone {
64 w.WriteHeader(500)
65 _, _ = w.Write([]byte("query already requested\n"))
66 return
67 }
68 w.WriteHeader(200)
69 w.Header().Set("Content-Type", "application/json")
70 _, _ = w.Write([]byte(`{
71 "status":"success",
72 "data":{
73 "resultType":"vector",
74 "result":[{"metric":{},"value":[1614859502.068,"1"]}]
75 }
76 }`))
77 done.Store(r.URL.Path, true)
78 case "matrix":
79 w.WriteHeader(200)
80 w.Header().Set("Content-Type", "application/json")
81 _, _ = w.Write([]byte(`{
82 "status":"success",
83 "data":{
84 "resultType":"matrix",
85 "result":[]
86 }
87 }`))
88 case "timeout":
89 w.WriteHeader(200)
90 w.Header().Set("Content-Type", "application/json")
91 time.Sleep(time.Second)
92 _, _ = w.Write([]byte(`{
93 "status":"success",
94 "data":{
95 "resultType":"vector",
96 "result":[]
97 }
98 }`))
99 default:
100 w.WriteHeader(400)
101 w.Header().Set("Content-Type", "application/json")
102 _, _ = w.Write([]byte(`{
103 "status":"error",
104 "errorType":"bad_data",
105 "error":"unhandled query"
106 }`))
107 }
108 }))
109 defer srv.Close()
110
111 type testCaseT struct {
112 query string
113 timeout time.Duration
114 series model.Vector
115 err string
116 runs int
117 }
118
119 testCases := []testCaseT{
120 {
121 query: "empty",
122 timeout: time.Second,
123 series: model.Vector{},
124 runs: 5,
125 },
126 {
127 query: "single_result",
128 timeout: time.Second,
129 series: model.Vector{
130 &model.Sample{
131 Metric: model.Metric{},
132 Value: model.SampleValue(1),
133 Timestamp: model.Time(1614859502068),
134 },
135 },
136 runs: 5,
137 },
138 {
139 query: "three_results",
140 timeout: time.Second,
141 series: model.Vector{
142 &model.Sample{
143 Metric: model.Metric{"instance": "1"},
144 Value: model.SampleValue(1),
145 Timestamp: model.Time(1614859502068),
146 },
147 &model.Sample{
148 Metric: model.Metric{"instance": "2"},
149 Value: model.SampleValue(2),
150 Timestamp: model.Time(1614859502168),
151 },
152 &model.Sample{
153 Metric: model.Metric{"instance": "3"},
154 Value: model.SampleValue(3),
155 Timestamp: model.Time(1614859503000),
156 },
157 },
158 runs: 5,
159 },
160 {
161 query: "error",
162 timeout: time.Second,
163 err: "bad_data: unhandled query",
164 runs: 5,
165 },
166 {
167 query: "matrix",
168 timeout: time.Second,
169 err: "unknown result type: matrix",
170 runs: 5,
171 },
172 {
173 query: "timeout",
174 timeout: time.Millisecond * 20,
175 err: fmt.Sprintf(`Post "%s/api/v1/query": context deadline exceeded`, srv.URL),
176 runs: 5,
177 },
178 {
179 query: "once",
180 timeout: time.Second,
181 series: model.Vector{
182 &model.Sample{
183 Metric: model.Metric{},
184 Value: model.SampleValue(1),
185 Timestamp: model.Time(1614859502068),
186 },
187 },
188 runs: 5,
189 },
190 // repeat once to ensure it errors
191 {
192 query: "once",
193 timeout: time.Second,
194 err: "server_error: server error: 500",
195 runs: 5,
196 },
197 }
198
199 for _, tc := range testCases {
200 t.Run(tc.query, func(t *testing.T) {
201 assert := assert.New(t)
202
203 prom := promapi.NewPrometheus("test", srv.URL, tc.timeout)
204
205 wg := sync.WaitGroup{}
206 wg.Add(tc.runs)
207 for i := 1; i <= tc.runs; i++ {
208 go func() {
209 qr, err := prom.Query(context.Background(), tc.query)
210 if tc.err != "" {
211 assert.EqualError(err, tc.err, tc)
212 } else {
213 assert.NoError(err)
214 }
215 if qr != nil {
216 assert.Equal(qr.Series, tc.series)
217 }
218 wg.Done()
219 }()
220 }
221 wg.Wait()
222 })
223 }
224}
225