Skip to content

Commit 5aa9e47

Browse files
authored
fix(dataobj): Fixes timerange matching for dataobj files (#16222)
1 parent bda6b0b commit 5aa9e47

File tree

2 files changed

+118
-1
lines changed

2 files changed

+118
-1
lines changed

‎pkg/dataobj/metastore/metastore.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ func objectOverlapsRange(lbs labels.Labels, start, end time.Time) (bool, string)
332332
if objStart.IsZero() || objEnd.IsZero() {
333333
return false, ""
334334
}
335-
if objStart.Before(start) || objEnd.After(end) {
335+
if objEnd.Before(start) || objStart.After(end) {
336336
return false, ""
337337
}
338338
return true, objPath

‎pkg/dataobj/metastore/metastore_test.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ package metastore
22

33
import (
44
"context"
5+
"strconv"
56
"testing"
67
"time"
78

89
"github.com/go-kit/log"
10+
"github.com/prometheus/prometheus/model/labels"
911
"github.com/stretchr/testify/require"
1012

1113
"github.com/grafana/dskit/backoff"
@@ -302,3 +304,118 @@ func TestDataObjectsPaths(t *testing.T) {
302304
require.Contains(t, paths, "path5")
303305
})
304306
}
307+
308+
func TestObjectOverlapsRange(t *testing.T) {
309+
testPath := "test/path"
310+
311+
tests := []struct {
312+
name string
313+
objStart time.Time
314+
objEnd time.Time
315+
queryStart time.Time
316+
queryEnd time.Time
317+
wantMatch bool
318+
desc string
319+
}{
320+
{
321+
name: "object fully within query range",
322+
objStart: time.Unix(11, 0),
323+
objEnd: time.Unix(12, 0),
324+
queryStart: time.Unix(10, 0),
325+
queryEnd: time.Unix(13, 0),
326+
wantMatch: true,
327+
desc: "query: [10,13], obj: [11,12]",
328+
},
329+
{
330+
name: "object and query equal",
331+
objStart: time.Unix(11, 0),
332+
objEnd: time.Unix(12, 0),
333+
queryStart: time.Unix(11, 0),
334+
queryEnd: time.Unix(122, 0),
335+
wantMatch: true,
336+
desc: "query: [11,12], obj: [11,12]",
337+
},
338+
{
339+
name: "object fully contains query range",
340+
objStart: time.Unix(10, 0),
341+
objEnd: time.Unix(13, 0),
342+
queryStart: time.Unix(11, 0),
343+
queryEnd: time.Unix(12, 0),
344+
wantMatch: true,
345+
desc: "query: [11,12], obj: [10,13]",
346+
},
347+
{
348+
name: "object overlaps start of query range",
349+
objStart: time.Unix(9, 0),
350+
objEnd: time.Unix(11, 0),
351+
queryStart: time.Unix(10, 0),
352+
queryEnd: time.Unix(12, 0),
353+
wantMatch: true,
354+
desc: "query: [10,12], obj: [9,11]",
355+
},
356+
{
357+
name: "object overlaps end of query range",
358+
objStart: time.Unix(11, 0),
359+
objEnd: time.Unix(13, 0),
360+
queryStart: time.Unix(10, 0),
361+
queryEnd: time.Unix(12, 0),
362+
wantMatch: true,
363+
desc: "query: [10,12], obj: [11,13]",
364+
},
365+
{
366+
name: "object ends before query range",
367+
objStart: time.Unix(8, 0),
368+
objEnd: time.Unix(9, 0),
369+
queryStart: time.Unix(10, 0),
370+
queryEnd: time.Unix(11, 0),
371+
wantMatch: false,
372+
desc: "query: [10,11], obj: [8,9]",
373+
},
374+
{
375+
name: "object starts after query range",
376+
objStart: time.Unix(12, 0),
377+
objEnd: time.Unix(13, 0),
378+
queryStart: time.Unix(10, 0),
379+
queryEnd: time.Unix(11, 0),
380+
wantMatch: false,
381+
desc: "query: [10,11], obj: [12,13]",
382+
},
383+
{
384+
name: "object touches start of query range",
385+
objStart: time.Unix(9, 0),
386+
objEnd: time.Unix(10, 0),
387+
queryStart: time.Unix(10, 0),
388+
queryEnd: time.Unix(11, 0),
389+
wantMatch: true,
390+
desc: "query: [10,11], obj: [9,10]",
391+
},
392+
{
393+
name: "object touches end of query range",
394+
objStart: time.Unix(11, 0),
395+
objEnd: time.Unix(12, 0),
396+
queryStart: time.Unix(10, 0),
397+
queryEnd: time.Unix(11, 0),
398+
wantMatch: true,
399+
desc: "query: [10,11], obj: [11,12]",
400+
},
401+
}
402+
403+
for _, tt := range tests {
404+
t.Run(tt.name, func(t *testing.T) {
405+
// Create labels with timestamps in nanoseconds
406+
lbs := labels.Labels{
407+
{Name: "__start__", Value: strconv.FormatInt(tt.objStart.UnixNano(), 10)},
408+
{Name: "__end__", Value: strconv.FormatInt(tt.objEnd.UnixNano(), 10)},
409+
{Name: "__path__", Value: testPath},
410+
}
411+
412+
gotMatch, gotPath := objectOverlapsRange(lbs, tt.queryStart, tt.queryEnd)
413+
require.Equal(t, tt.wantMatch, gotMatch, "overlap match failed for %s", tt.desc)
414+
if tt.wantMatch {
415+
require.Equal(t, testPath, gotPath, "path should match when ranges overlap")
416+
} else {
417+
require.Empty(t, gotPath, "path should be empty when ranges don't overlap")
418+
}
419+
})
420+
}
421+
}

0 commit comments

Comments
 (0)