@@ -205,6 +205,167 @@ func TestRingStreamUsageGatherer_GetStreamUsage(t *testing.T) {
205
205
}
206
206
}
207
207
208
+ func TestRingStreamUsageGatherer_GetZoneAwarePartitionConsumers (t * testing.T ) {
209
+ tests := []struct {
210
+ name string
211
+ instances []ring.InstanceDesc
212
+ expectedAssignedPartitionsRequests []* logproto.GetAssignedPartitionsRequest
213
+ getAssignedPartitionsResponses []* logproto.GetAssignedPartitionsResponse
214
+ getAssignedPartitionsResponseErrs []error
215
+ expected map [string ]map [int32 ]string
216
+ }{{
217
+ name : "single zone" ,
218
+ instances : []ring.InstanceDesc {{
219
+ Addr : "instance-a-0" ,
220
+ Zone : "a" ,
221
+ }},
222
+ expectedAssignedPartitionsRequests : []* logproto.GetAssignedPartitionsRequest {{}},
223
+ getAssignedPartitionsResponses : []* logproto.GetAssignedPartitionsResponse {{
224
+ AssignedPartitions : map [int32 ]int64 {
225
+ 0 : time .Now ().UnixNano (),
226
+ },
227
+ }},
228
+ getAssignedPartitionsResponseErrs : []error {nil },
229
+ expected : map [string ]map [int32 ]string {"a" : {0 : "instance-a-0" }},
230
+ }, {
231
+ name : "two zones" ,
232
+ instances : []ring.InstanceDesc {{
233
+ Addr : "instance-a-0" ,
234
+ Zone : "a" ,
235
+ }, {
236
+ Addr : "instance-b-0" ,
237
+ Zone : "b" ,
238
+ }},
239
+ expectedAssignedPartitionsRequests : []* logproto.GetAssignedPartitionsRequest {{}, {}},
240
+ getAssignedPartitionsResponses : []* logproto.GetAssignedPartitionsResponse {{
241
+ AssignedPartitions : map [int32 ]int64 {
242
+ 0 : time .Now ().UnixNano (),
243
+ },
244
+ }, {
245
+ AssignedPartitions : map [int32 ]int64 {
246
+ 0 : time .Now ().UnixNano (),
247
+ },
248
+ }},
249
+ getAssignedPartitionsResponseErrs : []error {nil , nil },
250
+ expected : map [string ]map [int32 ]string {
251
+ "a" : {0 : "instance-a-0" },
252
+ "b" : {0 : "instance-b-0" },
253
+ },
254
+ }, {
255
+ name : "two zones, subset of partitions in zone b" ,
256
+ instances : []ring.InstanceDesc {{
257
+ Addr : "instance-a-0" ,
258
+ Zone : "a" ,
259
+ }, {
260
+ Addr : "instance-b-0" ,
261
+ Zone : "b" ,
262
+ }},
263
+ expectedAssignedPartitionsRequests : []* logproto.GetAssignedPartitionsRequest {{}, {}},
264
+ getAssignedPartitionsResponses : []* logproto.GetAssignedPartitionsResponse {{
265
+ AssignedPartitions : map [int32 ]int64 {
266
+ 0 : time .Now ().UnixNano (),
267
+ 1 : time .Now ().UnixNano (),
268
+ },
269
+ }, {
270
+ AssignedPartitions : map [int32 ]int64 {
271
+ 0 : time .Now ().UnixNano (),
272
+ },
273
+ }},
274
+ getAssignedPartitionsResponseErrs : []error {nil , nil },
275
+ expected : map [string ]map [int32 ]string {
276
+ "a" : {0 : "instance-a-0" , 1 : "instance-a-0" },
277
+ "b" : {0 : "instance-b-0" },
278
+ },
279
+ }, {
280
+ name : "two zones, error in zone b" ,
281
+ instances : []ring.InstanceDesc {{
282
+ Addr : "instance-a-0" ,
283
+ Zone : "a" ,
284
+ }, {
285
+ Addr : "instance-b-0" ,
286
+ Zone : "b" ,
287
+ }},
288
+ expectedAssignedPartitionsRequests : []* logproto.GetAssignedPartitionsRequest {{}, {}},
289
+ getAssignedPartitionsResponses : []* logproto.GetAssignedPartitionsResponse {{
290
+ AssignedPartitions : map [int32 ]int64 {
291
+ 0 : time .Now ().UnixNano (),
292
+ 1 : time .Now ().UnixNano (),
293
+ },
294
+ }, nil },
295
+ getAssignedPartitionsResponseErrs : []error {nil , errors .New ("an unexpected error occurred" )},
296
+ expected : map [string ]map [int32 ]string {
297
+ "a" : {0 : "instance-a-0" , 1 : "instance-a-0" },
298
+ "b" : {},
299
+ },
300
+ }, {
301
+ name : "two zones, different number of instances per zone" ,
302
+ instances : []ring.InstanceDesc {{
303
+ Addr : "instance-a-0" ,
304
+ Zone : "a" ,
305
+ }, {
306
+ Addr : "instance-a-1" ,
307
+ Zone : "a" ,
308
+ }, {
309
+ Addr : "instance-b-0" ,
310
+ Zone : "b" ,
311
+ }},
312
+ expectedAssignedPartitionsRequests : []* logproto.GetAssignedPartitionsRequest {{}, {}, {}},
313
+ getAssignedPartitionsResponses : []* logproto.GetAssignedPartitionsResponse {{
314
+ AssignedPartitions : map [int32 ]int64 {
315
+ 0 : time .Now ().UnixNano (),
316
+ },
317
+ }, {
318
+ AssignedPartitions : map [int32 ]int64 {
319
+ 1 : time .Now ().UnixNano (),
320
+ },
321
+ }, {
322
+ AssignedPartitions : map [int32 ]int64 {
323
+ 0 : time .Now ().UnixNano (),
324
+ 1 : time .Now ().UnixNano (),
325
+ },
326
+ }},
327
+ getAssignedPartitionsResponseErrs : []error {nil , nil , nil },
328
+ expected : map [string ]map [int32 ]string {
329
+ "a" : {0 : "instance-a-0" , 1 : "instance-a-1" },
330
+ "b" : {0 : "instance-b-0" , 1 : "instance-b-0" },
331
+ },
332
+ }}
333
+
334
+ for _ , test := range tests {
335
+ t .Run (test .name , func (t * testing.T ) {
336
+ // Set up the mock clients, one for each pair of mock RPC responses.
337
+ clients := make ([]* mockIngestLimitsClient , len (test .instances ))
338
+ for i := range test .instances {
339
+ // These test cases assume one request/response per instance.
340
+ expectedNumAssignedPartitionsRequests := 0
341
+ if test .expectedAssignedPartitionsRequests [i ] != nil {
342
+ expectedNumAssignedPartitionsRequests = 1
343
+ }
344
+ clients [i ] = & mockIngestLimitsClient {
345
+ t : t ,
346
+ expectedAssignedPartitionsRequest : test .expectedAssignedPartitionsRequests [i ],
347
+ getAssignedPartitionsResponse : test .getAssignedPartitionsResponses [i ],
348
+ getAssignedPartitionsResponseErr : test .getAssignedPartitionsResponseErrs [i ],
349
+ expectedNumAssignedPartitionsRequests : expectedNumAssignedPartitionsRequests ,
350
+ }
351
+ t .Cleanup (clients [i ].AssertExpectedNumRequests )
352
+ }
353
+ // Set up the mocked ring and client pool for the tests.
354
+ readRing , clientPool := newMockRingWithClientPool (t , "test" , clients , test .instances )
355
+ cache := NewNopCache [string , * logproto.GetAssignedPartitionsResponse ]()
356
+ g := NewRingStreamUsageGatherer (readRing , clientPool , 2 , cache , log .NewNopLogger ())
357
+
358
+ // Set a maximum upper bound on the test execution time.
359
+ ctx , cancel := context .WithTimeout (context .Background (), 15 * time .Second )
360
+ defer cancel ()
361
+
362
+ result , err := g .getZoneAwarePartitionConsumers (ctx , test .instances )
363
+ require .NoError (t , err )
364
+ require .Equal (t , test .expected , result )
365
+ })
366
+ }
367
+ }
368
+
208
369
func TestRingStreamUsageGatherer_GetPartitionConsumers (t * testing.T ) {
209
370
tests := []struct {
210
371
name string
0 commit comments