@@ -40,75 +40,82 @@ func TestDistributor_DistributeRequest(t *testing.T) {
4040 isRead bool
4141 isDelete bool
4242 expStatusCode int
43- expectedTotalCalls int
43+ expectedMaxCalls int
44+ expectedMinCalls int
4445 headersNotPreserved bool
4546 route string
4647 // Paths where responses are merged, we need to supply a valid response body.
4748 // Note that the actual merging logic is tested elsewhere (merger_test.go).
4849 responseBody []byte
4950 }{
5051 {
51- name : "Write /alerts, Simple AM request, all AM healthy" ,
52- numAM : 4 ,
53- numHappyAM : 4 ,
54- replicationFactor : 3 ,
55- expStatusCode : http .StatusOK ,
56- expectedTotalCalls : 3 ,
57- route : "/alerts" ,
52+ name : "Write /alerts, Simple AM request, all AM healthy" ,
53+ numAM : 4 ,
54+ numHappyAM : 4 ,
55+ replicationFactor : 3 ,
56+ expStatusCode : http .StatusOK ,
57+ expectedMinCalls : 3 ,
58+ expectedMaxCalls : 3 ,
59+ route : "/alerts" ,
5860 }, {
5961 name : "Write /alerts, Less than quorum AM available" ,
6062 numAM : 1 ,
6163 numHappyAM : 1 ,
6264 replicationFactor : 3 ,
6365 expStatusCode : http .StatusInternalServerError ,
64- expectedTotalCalls : 0 ,
66+ expectedMinCalls : 0 ,
67+ expectedMaxCalls : 0 ,
6568 headersNotPreserved : true , // There is nothing to preserve since it does not hit any AM.
6669 route : "/alerts" ,
6770 }, {
68- name : "Write /alerts, Less than quorum AM succeed" ,
69- numAM : 5 ,
70- numHappyAM : 3 , // Though we have 3 happy, it will hit >1 unhappy AM.
71- replicationFactor : 3 ,
72- expStatusCode : http .StatusInternalServerError ,
73- expectedTotalCalls : 3 ,
74- route : "/alerts" ,
71+ name : "Write /alerts, Less than quorum AM succeed" ,
72+ numAM : 5 ,
73+ numHappyAM : 3 , // Though we have 3 happy, it will hit >1 unhappy AM.
74+ replicationFactor : 3 ,
75+ expStatusCode : http .StatusInternalServerError ,
76+ expectedMinCalls : 3 ,
77+ expectedMaxCalls : 3 ,
78+ route : "/alerts" ,
7579 }, {
76- name : "Read /v1/alerts is sent to 3 AMs" ,
77- numAM : 5 ,
78- numHappyAM : 5 ,
79- replicationFactor : 3 ,
80- isRead : true ,
81- expStatusCode : http .StatusOK ,
82- expectedTotalCalls : 3 ,
83- route : "/v1/alerts" ,
84- responseBody : []byte (`{"status":"success","data":[]}` ),
80+ name : "Read /v1/alerts is sent to 3 AMs" ,
81+ numAM : 5 ,
82+ numHappyAM : 5 ,
83+ replicationFactor : 3 ,
84+ isRead : true ,
85+ expStatusCode : http .StatusOK ,
86+ expectedMinCalls : 3 ,
87+ expectedMaxCalls : 3 ,
88+ route : "/v1/alerts" ,
89+ responseBody : []byte (`{"status":"success","data":[]}` ),
8590 }, {
86- name : "Read /v2/alerts is sent to 3 AMs" ,
87- numAM : 5 ,
88- numHappyAM : 5 ,
89- replicationFactor : 3 ,
90- isRead : true ,
91- expStatusCode : http .StatusOK ,
92- expectedTotalCalls : 3 ,
93- route : "/v2/alerts" ,
94- responseBody : []byte (`[]` ),
91+ name : "Read /v2/alerts is sent to 3 AMs" ,
92+ numAM : 5 ,
93+ numHappyAM : 5 ,
94+ replicationFactor : 3 ,
95+ isRead : true ,
96+ expStatusCode : http .StatusOK ,
97+ expectedMinCalls : 3 ,
98+ expectedMaxCalls : 3 ,
99+ route : "/v2/alerts" ,
100+ responseBody : []byte (`[]` ),
95101 }, {
96- name : "Read /v2/alerts/groups is sent to 3 AMs" ,
97- numAM : 5 ,
98- numHappyAM : 5 ,
99- replicationFactor : 3 ,
100- isRead : true ,
101- expStatusCode : http .StatusOK ,
102- expectedTotalCalls : 3 ,
103- route : "/v2/alerts/groups" ,
104- responseBody : []byte (`[]` ),
102+ name : "Read /v2/alerts/groups is sent to 3 AMs" ,
103+ numAM : 5 ,
104+ numHappyAM : 5 ,
105+ replicationFactor : 3 ,
106+ isRead : true ,
107+ expStatusCode : http .StatusOK ,
108+ expectedMinCalls : 3 ,
109+ expectedMaxCalls : 3 ,
110+ route : "/v2/alerts/groups" ,
111+ responseBody : []byte (`[]` ),
105112 }, {
106113 name : "Read /v1/alerts/groups not supported" ,
107114 numAM : 5 ,
108115 numHappyAM : 5 ,
109116 replicationFactor : 3 ,
110117 expStatusCode : http .StatusNotFound ,
111- expectedTotalCalls : 0 ,
118+ expectedMaxCalls : 0 ,
112119 headersNotPreserved : true ,
113120 route : "/v1/alerts/groups" ,
114121 }, {
@@ -117,128 +124,142 @@ func TestDistributor_DistributeRequest(t *testing.T) {
117124 numHappyAM : 5 ,
118125 replicationFactor : 3 ,
119126 expStatusCode : http .StatusNotFound ,
120- expectedTotalCalls : 0 ,
127+ expectedMinCalls : 0 ,
128+ expectedMaxCalls : 0 ,
121129 headersNotPreserved : true ,
122130 route : "/alerts/groups" ,
123131 }, {
124- name : "Read /v1/silences is sent to 3 AMs" ,
125- numAM : 5 ,
126- numHappyAM : 5 ,
127- replicationFactor : 3 ,
128- isRead : true ,
129- expStatusCode : http .StatusOK ,
130- expectedTotalCalls : 3 ,
131- route : "/v1/silences" ,
132- responseBody : []byte (`{"status":"success","data":[]}` ),
132+ name : "Read /v1/silences is sent to 3 AMs" ,
133+ numAM : 5 ,
134+ numHappyAM : 5 ,
135+ replicationFactor : 3 ,
136+ isRead : true ,
137+ expStatusCode : http .StatusOK ,
138+ expectedMinCalls : 3 ,
139+ expectedMaxCalls : 3 ,
140+ route : "/v1/silences" ,
141+ responseBody : []byte (`{"status":"success","data":[]}` ),
133142 }, {
134- name : "Read /v2/silences is sent to 3 AMs" ,
135- numAM : 5 ,
136- numHappyAM : 5 ,
137- replicationFactor : 3 ,
138- isRead : true ,
139- expStatusCode : http .StatusOK ,
140- expectedTotalCalls : 3 ,
141- route : "/v2/silences" ,
142- responseBody : []byte (`[]` ),
143+ name : "Read /v2/silences is sent to 3 AMs" ,
144+ numAM : 5 ,
145+ numHappyAM : 5 ,
146+ replicationFactor : 3 ,
147+ isRead : true ,
148+ expStatusCode : http .StatusOK ,
149+ expectedMinCalls : 3 ,
150+ expectedMaxCalls : 3 ,
151+ route : "/v2/silences" ,
152+ responseBody : []byte (`[]` ),
143153 }, {
144- name : "Write /silences is sent to only 1 AM" ,
145- numAM : 5 ,
146- numHappyAM : 5 ,
147- replicationFactor : 3 ,
148- expStatusCode : http .StatusOK ,
149- expectedTotalCalls : 1 ,
150- route : "/silences" ,
154+ name : "Write /silences is sent to only 1 AM" ,
155+ numAM : 5 ,
156+ numHappyAM : 5 ,
157+ replicationFactor : 3 ,
158+ expStatusCode : http .StatusOK ,
159+ expectedMinCalls : 1 ,
160+ expectedMaxCalls : 1 ,
161+ route : "/silences" ,
151162 }, {
152- name : "Read /v1/silence/id is sent to 3 AMs" ,
153- numAM : 5 ,
154- numHappyAM : 5 ,
155- replicationFactor : 3 ,
156- isRead : true ,
157- expStatusCode : http .StatusOK ,
158- expectedTotalCalls : 3 ,
159- route : "/v1/silence/id" ,
160- responseBody : []byte (`{"status":"success","data":{"id":"aaa","updatedAt":"2020-01-01T00:00:00Z"}}` ),
163+ name : "Read /v1/silence/id is sent to 3 AMs" ,
164+ numAM : 5 ,
165+ numHappyAM : 5 ,
166+ replicationFactor : 3 ,
167+ isRead : true ,
168+ expStatusCode : http .StatusOK ,
169+ expectedMinCalls : 3 ,
170+ expectedMaxCalls : 3 ,
171+ route : "/v1/silence/id" ,
172+ responseBody : []byte (`{"status":"success","data":{"id":"aaa","updatedAt":"2020-01-01T00:00:00Z"}}` ),
161173 }, {
162- name : "Read /v2/silence/id is sent to 3 AMs" ,
163- numAM : 5 ,
164- numHappyAM : 5 ,
165- replicationFactor : 3 ,
166- isRead : true ,
167- expStatusCode : http .StatusOK ,
168- expectedTotalCalls : 3 ,
169- route : "/v2/silence/id" ,
170- responseBody : []byte (`{"id":"aaa","updatedAt":"2020-01-01T00:00:00Z"}` ),
174+ name : "Read /v2/silence/id is sent to 3 AMs" ,
175+ numAM : 5 ,
176+ numHappyAM : 5 ,
177+ replicationFactor : 3 ,
178+ isRead : true ,
179+ expStatusCode : http .StatusOK ,
180+ expectedMinCalls : 3 ,
181+ expectedMaxCalls : 3 ,
182+ route : "/v2/silence/id" ,
183+ responseBody : []byte (`{"id":"aaa","updatedAt":"2020-01-01T00:00:00Z"}` ),
171184 },
172185 {
173186 name : "Write /silence/id not supported" ,
174187 numAM : 5 ,
175188 numHappyAM : 5 ,
176189 replicationFactor : 3 ,
177190 expStatusCode : http .StatusNotFound ,
178- expectedTotalCalls : 0 ,
191+ expectedMinCalls : 0 ,
192+ expectedMaxCalls : 0 ,
179193 headersNotPreserved : true ,
180194 route : "/silence/id" ,
181195 }, {
182- name : "Delete /silence/id is sent to only 1 AM" ,
183- numAM : 5 ,
184- numHappyAM : 5 ,
185- replicationFactor : 3 ,
186- isDelete : true ,
187- expStatusCode : http .StatusOK ,
188- expectedTotalCalls : 1 ,
189- route : "/silence/id" ,
196+ name : "Delete /silence/id is sent to only 1 AM" ,
197+ numAM : 5 ,
198+ numHappyAM : 5 ,
199+ replicationFactor : 3 ,
200+ isDelete : true ,
201+ expStatusCode : http .StatusOK ,
202+ expectedMinCalls : 1 ,
203+ expectedMaxCalls : 1 ,
204+ route : "/silence/id" ,
190205 }, {
191- name : "Read /status is sent to only 1 AM" ,
192- numAM : 5 ,
193- numHappyAM : 5 ,
194- replicationFactor : 3 ,
195- isRead : true ,
196- expStatusCode : http .StatusOK ,
197- expectedTotalCalls : 1 ,
198- route : "/status" ,
206+ name : "Read /status is sent to only 1 AM" ,
207+ numAM : 5 ,
208+ numHappyAM : 5 ,
209+ replicationFactor : 3 ,
210+ isRead : true ,
211+ expStatusCode : http .StatusOK ,
212+ expectedMinCalls : 1 ,
213+ expectedMaxCalls : 1 ,
214+ route : "/status" ,
199215 }, {
200- name : "Read /status should try all alert managers on error" ,
201- numAM : 3 ,
202- numHappyAM : 0 ,
203- replicationFactor : 3 ,
204- isRead : true ,
205- expStatusCode : http .StatusInternalServerError ,
206- expectedTotalCalls : 3 ,
207- route : "/status" ,
216+ name : "Read /status should try all alert managers on error" ,
217+ numAM : 3 ,
218+ numHappyAM : 0 ,
219+ replicationFactor : 3 ,
220+ isRead : true ,
221+ expStatusCode : http .StatusInternalServerError ,
222+ expectedMinCalls : 3 ,
223+ expectedMaxCalls : 3 ,
224+ route : "/status" ,
208225 }, {
209- name : "Read /status is sent to 3 AM when 2 are not happy" ,
210- numAM : 3 ,
211- numHappyAM : 1 ,
212- replicationFactor : 3 ,
213- isRead : true ,
214- expStatusCode : http .StatusOK ,
215- expectedTotalCalls : 3 ,
216- route : "/status" ,
226+ name : "Read /status is sent to atleast 2 AM when 2 are not happy" ,
227+ numAM : 3 ,
228+ numHappyAM : 1 ,
229+ replicationFactor : 3 ,
230+ isRead : true ,
231+ expStatusCode : http .StatusOK ,
232+ expectedMinCalls : 2 ,
233+ expectedMaxCalls : 3 ,
234+ route : "/status" ,
217235 }, {
218236 name : "Write /status not supported" ,
219237 numAM : 5 ,
220238 numHappyAM : 5 ,
221239 replicationFactor : 3 ,
222240 expStatusCode : http .StatusNotFound ,
223- expectedTotalCalls : 0 ,
241+ expectedMinCalls : 0 ,
242+ expectedMaxCalls : 0 ,
224243 headersNotPreserved : true ,
225244 route : "/status" ,
226245 }, {
227- name : "Read /receivers is sent to only 1 AM" ,
228- numAM : 5 ,
229- numHappyAM : 5 ,
230- replicationFactor : 3 ,
231- isRead : true ,
232- expStatusCode : http .StatusOK ,
233- expectedTotalCalls : 1 ,
234- route : "/receivers" ,
246+ name : "Read /receivers is sent to only 1 AM" ,
247+ numAM : 5 ,
248+ numHappyAM : 5 ,
249+ replicationFactor : 3 ,
250+ isRead : true ,
251+ expStatusCode : http .StatusOK ,
252+ expectedMinCalls : 1 ,
253+ expectedMaxCalls : 1 ,
254+ route : "/receivers" ,
235255 }, {
236256 name : "Write /receivers not supported" ,
237257 numAM : 5 ,
238258 numHappyAM : 5 ,
239259 replicationFactor : 3 ,
240260 expStatusCode : http .StatusNotFound ,
241- expectedTotalCalls : 0 ,
261+ expectedMinCalls : 0 ,
262+ expectedMaxCalls : 0 ,
242263 headersNotPreserved : true ,
243264 route : "/receivers" ,
244265 },
@@ -282,7 +303,7 @@ func TestDistributor_DistributeRequest(t *testing.T) {
282303 // Since the response is sent as soon as the quorum is reached, when we
283304 // reach this point the 3rd AM may not have received the request yet.
284305 // To avoid flaky test we retry until we hit the desired state within a reasonable timeout.
285- test .Poll (t , time .Second , c . expectedTotalCalls , func () interface {} {
306+ test .Poll (t , time .Second , true , func () interface {} {
286307 totalReqCount := 0
287308 for _ , a := range ams {
288309 reqCount := a .requestsCount (route )
@@ -291,7 +312,10 @@ func TestDistributor_DistributeRequest(t *testing.T) {
291312 totalReqCount += reqCount
292313 }
293314
294- return totalReqCount
315+ if totalReqCount <= c .expectedMaxCalls && totalReqCount >= c .expectedMinCalls {
316+ return true
317+ }
318+ return false
295319 })
296320 })
297321 }
0 commit comments