@@ -30,16 +30,24 @@ import (
30
30
"github.com/grafana/loki/v3/pkg/validation"
31
31
)
32
32
33
+ func stringSlice [T fmt.Stringer ](s []T ) []string {
34
+ res := make ([]string , len (s ))
35
+ for i := range res {
36
+ res [i ] = s [i ].String ()
37
+ }
38
+ return res
39
+ }
40
+
33
41
func groupRefs (t * testing.T , chunkRefs []* logproto.ChunkRef ) []* logproto.GroupedChunkRefs {
34
42
t .Helper ()
35
- grouped := make ([]* logproto.GroupedChunkRefs , 0 , len (chunkRefs ))
36
- return groupChunkRefs (chunkRefs , grouped )
43
+ return groupChunkRefs (chunkRefs , nil )
37
44
}
38
45
39
46
func newLimits () * validation.Overrides {
40
47
limits := validation.Limits {}
41
48
flagext .DefaultValues (& limits )
42
49
limits .BloomGatewayEnabled = true
50
+ limits .BloomGatewayShardSize = 1
43
51
44
52
overrides , _ := validation .NewOverrides (limits , nil )
45
53
return overrides
@@ -129,11 +137,46 @@ func TestBloomGateway_FilterChunkRefs(t *testing.T) {
129
137
MaxOutstandingPerTenant : 1024 ,
130
138
}
131
139
132
- t .Run ("shipper error is propagated " , func (t * testing.T ) {
140
+ t .Run ("request fails when providing invalid block " , func (t * testing.T ) {
133
141
now := mktime ("2023-10-03 10:00" )
134
142
135
143
_ , metas , queriers , data := createBlocks (t , tenantID , 10 , now .Add (- 1 * time .Hour ), now , 0x0000 , 0x0fff )
136
144
mockStore := newMockBloomStore (queriers , metas )
145
+
146
+ reg := prometheus .NewRegistry ()
147
+ gw , err := New (cfg , mockStore , logger , reg )
148
+ require .NoError (t , err )
149
+
150
+ err = services .StartAndAwaitRunning (context .Background (), gw )
151
+ require .NoError (t , err )
152
+ t .Cleanup (func () {
153
+ err = services .StopAndAwaitTerminated (context .Background (), gw )
154
+ require .NoError (t , err )
155
+ })
156
+
157
+ chunkRefs := createQueryInputFromBlockData (t , tenantID , data , 100 )
158
+
159
+ expr , err := syntax .ParseExpr (`{foo="bar"} |= "does not match"` )
160
+ require .NoError (t , err )
161
+
162
+ req := & logproto.FilterChunkRefRequest {
163
+ From : now .Add (- 24 * time .Hour ),
164
+ Through : now ,
165
+ Refs : groupRefs (t , chunkRefs ),
166
+ Plan : plan.QueryPlan {AST : expr },
167
+ Blocks : []string {"bloom/invalid/block.tar.gz" },
168
+ }
169
+
170
+ ctx := user .InjectOrgID (context .Background (), tenantID )
171
+ res , err := gw .FilterChunkRefs (ctx , req )
172
+ require .ErrorContainsf (t , err , "could not parse block key" , "%+v" , res )
173
+ })
174
+
175
+ t .Run ("shipper error is propagated" , func (t * testing.T ) {
176
+ now := mktime ("2023-10-03 10:00" )
177
+
178
+ refs , metas , queriers , data := createBlocks (t , tenantID , 10 , now .Add (- 1 * time .Hour ), now , 0x0000 , 0x0fff )
179
+ mockStore := newMockBloomStore (queriers , metas )
137
180
mockStore .err = errors .New ("request failed" )
138
181
139
182
reg := prometheus .NewRegistry ()
@@ -160,6 +203,7 @@ func TestBloomGateway_FilterChunkRefs(t *testing.T) {
160
203
Through : now ,
161
204
Refs : groupRefs (t , chunkRefs ),
162
205
Plan : plan.QueryPlan {AST : expr },
206
+ Blocks : stringSlice (refs ),
163
207
}
164
208
165
209
ctx , cancelFn := context .WithTimeout (context .Background (), 10 * time .Second )
@@ -175,7 +219,7 @@ func TestBloomGateway_FilterChunkRefs(t *testing.T) {
175
219
now := mktime ("2024-01-25 10:00" )
176
220
177
221
// replace store implementation and re-initialize workers and sub-services
178
- _ , metas , queriers , data := createBlocks (t , tenantID , 10 , now .Add (- 1 * time .Hour ), now , 0x0000 , 0x0fff )
222
+ refs , metas , queriers , data := createBlocks (t , tenantID , 10 , now .Add (- 1 * time .Hour ), now , 0x0000 , 0x0fff )
179
223
mockStore := newMockBloomStore (queriers , metas )
180
224
mockStore .delay = 2000 * time .Millisecond
181
225
@@ -203,6 +247,7 @@ func TestBloomGateway_FilterChunkRefs(t *testing.T) {
203
247
Through : now ,
204
248
Refs : groupRefs (t , chunkRefs ),
205
249
Plan : plan.QueryPlan {AST : expr },
250
+ Blocks : stringSlice (refs ),
206
251
}
207
252
208
253
ctx , cancelFn := context .WithTimeout (context .Background (), 500 * time .Millisecond )
@@ -228,11 +273,12 @@ func TestBloomGateway_FilterChunkRefs(t *testing.T) {
228
273
require .NoError (t , err )
229
274
})
230
275
276
+ // input chunks need to be sorted by their fingerprint
231
277
chunkRefs := []* logproto.ChunkRef {
232
- {Fingerprint : 3000 , UserID : tenantID , From : now .Add (- 24 * time .Hour ), Through : now .Add (- 23 * time .Hour ), Checksum : 1 },
233
278
{Fingerprint : 1000 , UserID : tenantID , From : now .Add (- 22 * time .Hour ), Through : now .Add (- 21 * time .Hour ), Checksum : 2 },
234
- {Fingerprint : 2000 , UserID : tenantID , From : now .Add (- 20 * time .Hour ), Through : now .Add (- 19 * time .Hour ), Checksum : 3 },
235
279
{Fingerprint : 1000 , UserID : tenantID , From : now .Add (- 23 * time .Hour ), Through : now .Add (- 22 * time .Hour ), Checksum : 4 },
280
+ {Fingerprint : 2000 , UserID : tenantID , From : now .Add (- 20 * time .Hour ), Through : now .Add (- 19 * time .Hour ), Checksum : 3 },
281
+ {Fingerprint : 3000 , UserID : tenantID , From : now .Add (- 24 * time .Hour ), Through : now .Add (- 23 * time .Hour ), Checksum : 1 },
236
282
}
237
283
req := & logproto.FilterChunkRefRequest {
238
284
From : now .Add (- 24 * time .Hour ),
@@ -284,13 +330,24 @@ func TestBloomGateway_FilterChunkRefs(t *testing.T) {
284
330
Checksum : uint32 (idx ),
285
331
},
286
332
}
333
+ ref := bloomshipper.BlockRef {
334
+ Ref : bloomshipper.Ref {
335
+ TenantID : tenantID ,
336
+ TableName : "table_1" ,
337
+ Bounds : v1 .NewBounds (0 , 10000 ),
338
+ StartTimestamp : now .Add (- 24 * time .Hour ),
339
+ EndTimestamp : now ,
340
+ Checksum : uint32 (idx ),
341
+ },
342
+ }
287
343
expr , err := syntax .ParseExpr (`{foo="bar"} |= "foo"` )
288
344
require .NoError (t , err )
289
345
req := & logproto.FilterChunkRefRequest {
290
346
From : now .Add (- 24 * time .Hour ),
291
347
Through : now ,
292
348
Refs : groupRefs (t , chunkRefs ),
293
349
Plan : plan.QueryPlan {AST : expr },
350
+ Blocks : stringSlice ([]bloomshipper.BlockRef {ref }),
294
351
}
295
352
ctx := user .InjectOrgID (context .Background (), tenantID )
296
353
_ , err = gw .FilterChunkRefs (ctx , req )
@@ -303,7 +360,7 @@ func TestBloomGateway_FilterChunkRefs(t *testing.T) {
303
360
now := mktime ("2023-10-03 10:00" )
304
361
305
362
// replace store implementation and re-initialize workers and sub-services
306
- _ , metas , queriers , data := createBlocks (t , tenantID , 10 , now .Add (- 1 * time .Hour ), now , 0x0000 , 0x0fff )
363
+ refs , metas , queriers , data := createBlocks (t , tenantID , 10 , now .Add (- 1 * time .Hour ), now , 0x0000 , 0x0fff )
307
364
308
365
reg := prometheus .NewRegistry ()
309
366
store := newMockBloomStore (queriers , metas )
@@ -329,6 +386,7 @@ func TestBloomGateway_FilterChunkRefs(t *testing.T) {
329
386
Through : now ,
330
387
Refs : inputChunkRefs ,
331
388
Plan : plan.QueryPlan {AST : expr },
389
+ Blocks : stringSlice (refs ),
332
390
}
333
391
ctx := user .InjectOrgID (context .Background (), tenantID )
334
392
res , err := gw .FilterChunkRefs (ctx , req )
@@ -361,6 +419,7 @@ func TestBloomGateway_FilterChunkRefs(t *testing.T) {
361
419
Through : now ,
362
420
Refs : inputChunkRefs ,
363
421
Plan : plan.QueryPlan {AST : expr },
422
+ Blocks : stringSlice (refs ),
364
423
}
365
424
ctx := user .InjectOrgID (context .Background (), tenantID )
366
425
res , err := gw .FilterChunkRefs (ctx , req )
0 commit comments