Skip to content

Commit cc9dd30

Browse files
move tests in the file
Signed-off-by: Krasi Georgiev <8903888+krasi-georgiev@users.noreply.github.com>
1 parent 3994362 commit cc9dd30

File tree

1 file changed

+130
-130
lines changed

1 file changed

+130
-130
lines changed

pkg/query/querier_test.go

Lines changed: 130 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,136 @@ func (s series) Iterator() chunkenc.Iterator {
294294
return newMockedSeriesIterator(s.samples)
295295
}
296296

297+
// TestQuerier_Select_After_promql tests expected results with and without deduplication after passing all data to promql.
298+
// To test with real data:
299+
// Collect the expected results from Prometheus or Thanos through "/api/v1/query_range" and save to a file.
300+
// Collect raw data to be used for local storage:
301+
// scripts/insecure_grpcurl_series.sh queriesGrpcIP:port '[{"name": "__name__", "value":"cluster_version"},{"name":"_id","value":"xxx"}]' 1597823000000 1597824600000 > localStorage.json
302+
// Remove all white space from the file and put each series in a new line.
303+
// When collecting the raw data mint should be Prometheus query time minus the default look back delta(default is 5min or 300000ms)
304+
// For example if the Prometheus query mint is 1597823700000 the grpccurl query mint should be 1597823400000.
305+
// This is because when promql displays data for a given range it looks back 5min before the requested time window.
306+
func TestQuerier_Select_After_promql(t *testing.T) {
307+
logger := log.NewLogfmtLogger(os.Stderr)
308+
309+
for _, tcase := range []struct {
310+
name string
311+
storeAPI storepb.StoreServer
312+
replicaLabels []string // Replica label groups chunks by the label value and strips it from the final result.
313+
hints *storage.SelectHints
314+
equivalentQuery string
315+
316+
expected []series
317+
expectedAfterDedup series
318+
expectedWarning string
319+
}{
320+
321+
{
322+
// Simulate Prom with 1m scrape interval scraping 30s apart.
323+
// This should start with replica-1 until a brief outage,
324+
// then switch to replica-2 after not seeing a value for 2 * interval = 120s.
325+
name: "switch to replica 2 after an outage",
326+
storeAPI: &storeServer{
327+
resps: []*storepb.SeriesResponse{
328+
storeSeriesResponse(t, labels.FromStrings("a", "a"), []sample{{0, 1}, {60000, 3}, {120000, 5} /* outage for 3 minutes */, {300000, 11}, {360000, 13}}),
329+
storeSeriesResponse(t, labels.FromStrings("a", "b"), []sample{{30000, 2}, {90000, 5}, {150000, 6}, {210000, 8}, {270000, 10}, {330000, 12}}),
330+
},
331+
},
332+
hints: &storage.SelectHints{
333+
Start: 0,
334+
End: 360000,
335+
Step: 60000,
336+
},
337+
replicaLabels: []string{"a"},
338+
equivalentQuery: `{a=~"a|b"}`,
339+
expected: []series{
340+
{
341+
lset: labels.FromStrings("a", "a"),
342+
samples: []sample{{0, 1}, {60000, 3}, {120000, 5}, {t: 180000, v: 5}, {t: 240000, v: 5}, {t: 300000, v: 11}, {t: 360000, v: 13}},
343+
},
344+
{
345+
lset: labels.FromStrings("a", "b"),
346+
samples: []sample{{t: 60000, v: 2}, {t: 120000, v: 5}, {t: 180000, v: 6}, {t: 240000, v: 8}, {t: 300000, v: 10}, {t: 360000, v: 12}},
347+
},
348+
},
349+
expectedAfterDedup: series{
350+
lset: labels.Labels{},
351+
samples: []sample{{0, 1}, {60000, 2}, {120000, 5}, {t: 180000, v: 6}, {t: 240000, v: 8}, {t: 300000, v: 10}, {t: 360000, v: 12}},
352+
},
353+
},
354+
355+
{
356+
// // Regression test against https://github.com/thanos-io/thanos/issues/2890.
357+
name: "when switching replicas make sure the time window between samples is never bigger then the lookback delta",
358+
storeAPI: func() storepb.StoreServer {
359+
s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2890-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages)
360+
testutil.Ok(t, err)
361+
return s
362+
}(),
363+
equivalentQuery: `cluster_version{}`,
364+
replicaLabels: []string{"replica"},
365+
hints: &storage.SelectHints{
366+
Start: 1597823700000,
367+
End: 1597824600000,
368+
Step: 3000,
369+
},
370+
expected: jsonToSeries(t, "testdata/issue2890-expected.json"),
371+
expectedAfterDedup: jsonToSeries(t, "testdata/issue2890-expected-dedup.json")[0],
372+
},
373+
} {
374+
timeout := 5 * time.Minute
375+
e := promql.NewEngine(promql.EngineOpts{
376+
Logger: logger,
377+
Timeout: timeout,
378+
MaxSamples: math.MaxInt64,
379+
})
380+
381+
t.Run(tcase.name, func(t *testing.T) {
382+
for _, sc := range []struct {
383+
dedup bool
384+
expected []series
385+
}{
386+
{dedup: false, expected: tcase.expected},
387+
{dedup: true, expected: []series{tcase.expectedAfterDedup}},
388+
} {
389+
390+
resolution := time.Duration(tcase.hints.Step) * time.Millisecond
391+
t.Run(fmt.Sprintf("dedup=%v, resolution=%v", sc.dedup, resolution.String()), func(t *testing.T) {
392+
var actual []series
393+
// Boostrap a local store and pass the data through promql.
394+
{
395+
g := gate.New(2)
396+
mq := &mockedQueryable{
397+
Creator: func(mint, maxt int64) storage.Querier {
398+
return newQuerier(context.Background(), nil, nil, mint, maxt, tcase.replicaLabels, nil, tcase.storeAPI, sc.dedup, 0, true, false, g, timeout)
399+
},
400+
}
401+
t.Cleanup(func() {
402+
testutil.Ok(t, mq.Close())
403+
})
404+
q, err := e.NewRangeQuery(mq, tcase.equivalentQuery, timestamp.Time(tcase.hints.Start), timestamp.Time(tcase.hints.End), resolution)
405+
testutil.Ok(t, err)
406+
t.Cleanup(q.Close)
407+
res := q.Exec(context.Background())
408+
testutil.Ok(t, res.Err)
409+
actual = promqlResToSeries(res)
410+
if tcase.expectedWarning != "" {
411+
warns := res.Warnings
412+
testutil.Assert(t, len(warns) == 1, "expected only single warnings")
413+
testutil.Equals(t, tcase.expectedWarning, warns[0].Error())
414+
}
415+
}
416+
417+
testutil.Equals(t, sc.expected, actual, "promql result doesn't match the expected output")
418+
if sc.dedup {
419+
testutil.Assert(t, len(actual) == 1, "expected only single response, subqueries?")
420+
}
421+
})
422+
}
423+
})
424+
}
425+
}
426+
297427
func TestQuerier_Select(t *testing.T) {
298428
logger := log.NewLogfmtLogger(os.Stderr)
299429

@@ -578,136 +708,6 @@ func testSelectResponse(t *testing.T, expected []series, res storage.SeriesSet)
578708
}
579709
}
580710

581-
// TestQuerier_Select_After_promql tests expected results with and without deduplication after passing all data to promql.
582-
// To test with real data:
583-
// Collect the expected results from Prometheus or Thanos through "/api/v1/query_range" and save to a file.
584-
// Collect raw data to be used for local storage:
585-
// scripts/insecure_grpcurl_series.sh queriesGrpcIP:port '[{"name": "__name__", "value":"cluster_version"},{"name":"_id","value":"xxx"}]' 1597823000000 1597824600000 > localStorage.json
586-
// Remove all white space from the file and put each series in a new line.
587-
// When collecting the raw data mint should be Prometheus query time minus the default look back delta(default is 5min or 300000ms)
588-
// For example if the Prometheus query mint is 1597823700000 the grpccurl query mint should be 1597823400000.
589-
// This is because when promql displays data for a given range it looks back 5min before the requested time window.
590-
func TestQuerier_Select_After_promql(t *testing.T) {
591-
logger := log.NewLogfmtLogger(os.Stderr)
592-
593-
for _, tcase := range []struct {
594-
name string
595-
storeAPI storepb.StoreServer
596-
replicaLabels []string // Replica label groups chunks by the label value and strips it from the final result.
597-
hints *storage.SelectHints
598-
equivalentQuery string
599-
600-
expected []series
601-
expectedAfterDedup series
602-
expectedWarning string
603-
}{
604-
605-
{
606-
// Simulate Prom with 1m scrape interval scraping 30s apart.
607-
// This should start with replica-1 until a brief outage,
608-
// then switch to replica-2 after not seeing a value for 2 * interval = 120s.
609-
name: "switch to replica 2 after an outage",
610-
storeAPI: &storeServer{
611-
resps: []*storepb.SeriesResponse{
612-
storeSeriesResponse(t, labels.FromStrings("a", "a"), []sample{{0, 1}, {60000, 3}, {120000, 5} /* outage for 3 minutes */, {300000, 11}, {360000, 13}}),
613-
storeSeriesResponse(t, labels.FromStrings("a", "b"), []sample{{30000, 2}, {90000, 5}, {150000, 6}, {210000, 8}, {270000, 10}, {330000, 12}}),
614-
},
615-
},
616-
hints: &storage.SelectHints{
617-
Start: 0,
618-
End: 360000,
619-
Step: 60000,
620-
},
621-
replicaLabels: []string{"a"},
622-
equivalentQuery: `{a=~"a|b"}`,
623-
expected: []series{
624-
{
625-
lset: labels.FromStrings("a", "a"),
626-
samples: []sample{{0, 1}, {60000, 3}, {120000, 5}, {t: 180000, v: 5}, {t: 240000, v: 5}, {t: 300000, v: 11}, {t: 360000, v: 13}},
627-
},
628-
{
629-
lset: labels.FromStrings("a", "b"),
630-
samples: []sample{{t: 60000, v: 2}, {t: 120000, v: 5}, {t: 180000, v: 6}, {t: 240000, v: 8}, {t: 300000, v: 10}, {t: 360000, v: 12}},
631-
},
632-
},
633-
expectedAfterDedup: series{
634-
lset: labels.Labels{},
635-
samples: []sample{{0, 1}, {60000, 2}, {120000, 5}, {t: 180000, v: 6}, {t: 240000, v: 8}, {t: 300000, v: 10}, {t: 360000, v: 12}},
636-
},
637-
},
638-
639-
{
640-
// // Regression test against https://github.com/thanos-io/thanos/issues/2890.
641-
name: "when switching replicas make sure the time window between samples is never bigger then the lookback delta",
642-
storeAPI: func() storepb.StoreServer {
643-
s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2890-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages)
644-
testutil.Ok(t, err)
645-
return s
646-
}(),
647-
equivalentQuery: `cluster_version{}`,
648-
replicaLabels: []string{"replica"},
649-
hints: &storage.SelectHints{
650-
Start: 1597823700000,
651-
End: 1597824600000,
652-
Step: 3000,
653-
},
654-
expected: jsonToSeries(t, "testdata/issue2890-expected.json"),
655-
expectedAfterDedup: jsonToSeries(t, "testdata/issue2890-expected-dedup.json")[0],
656-
},
657-
} {
658-
timeout := 5 * time.Minute
659-
e := promql.NewEngine(promql.EngineOpts{
660-
Logger: logger,
661-
Timeout: timeout,
662-
MaxSamples: math.MaxInt64,
663-
})
664-
665-
t.Run(tcase.name, func(t *testing.T) {
666-
for _, sc := range []struct {
667-
dedup bool
668-
expected []series
669-
}{
670-
{dedup: false, expected: tcase.expected},
671-
{dedup: true, expected: []series{tcase.expectedAfterDedup}},
672-
} {
673-
674-
resolution := time.Duration(tcase.hints.Step) * time.Millisecond
675-
t.Run(fmt.Sprintf("dedup=%v, resolution=%v", sc.dedup, resolution.String()), func(t *testing.T) {
676-
var actual []series
677-
// Boostrap a local store and pass the data through promql.
678-
{
679-
g := gate.New(2)
680-
mq := &mockedQueryable{
681-
Creator: func(mint, maxt int64) storage.Querier {
682-
return newQuerier(context.Background(), nil, nil, mint, maxt, tcase.replicaLabels, nil, tcase.storeAPI, sc.dedup, 0, true, false, g, timeout)
683-
},
684-
}
685-
t.Cleanup(func() {
686-
testutil.Ok(t, mq.Close())
687-
})
688-
q, err := e.NewRangeQuery(mq, tcase.equivalentQuery, timestamp.Time(tcase.hints.Start), timestamp.Time(tcase.hints.End), resolution)
689-
testutil.Ok(t, err)
690-
t.Cleanup(q.Close)
691-
res := q.Exec(context.Background())
692-
testutil.Ok(t, res.Err)
693-
actual = promqlResToSeries(res)
694-
if tcase.expectedWarning != "" {
695-
warns := res.Warnings
696-
testutil.Assert(t, len(warns) == 1, "expected only single warnings")
697-
testutil.Equals(t, tcase.expectedWarning, warns[0].Error())
698-
}
699-
}
700-
701-
testutil.Equals(t, sc.expected, actual, "promql result doesn't match the expected output")
702-
if sc.dedup {
703-
testutil.Assert(t, len(actual) == 1, "expected only single response, subqueries?")
704-
}
705-
})
706-
}
707-
})
708-
}
709-
}
710-
711711
func jsonToSeries(t *testing.T, filename string) []series {
712712
file, err := ioutil.ReadFile(filename)
713713
testutil.Ok(t, err)

0 commit comments

Comments
 (0)