github.com/thanos-io/thanos@v0.32.5/test/e2e/distributed_query_test.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package e2e_test 5 6 import ( 7 "context" 8 "testing" 9 "time" 10 11 "github.com/efficientgo/core/testutil" 12 "github.com/efficientgo/e2e" 13 "github.com/prometheus/common/model" 14 15 "github.com/thanos-io/thanos/pkg/promclient" 16 "github.com/thanos-io/thanos/test/e2e/e2ethanos" 17 ) 18 19 func TestDistributedQueryExecution(t *testing.T) { 20 t.Parallel() 21 22 // Build up. 23 e, err := e2e.New(e2e.WithName("dist-query")) 24 testutil.Ok(t, err) 25 t.Cleanup(e2ethanos.CleanScenario(t, e)) 26 27 prom1, sidecar1 := e2ethanos.NewPrometheusWithSidecar(e, "prom1", e2ethanos.DefaultPromConfig("prom1", 0, "", ""), "", e2ethanos.DefaultPrometheusImage(), "", "remote-write-receiver") 28 prom2, sidecar2 := e2ethanos.NewPrometheusWithSidecar(e, "prom2", e2ethanos.DefaultPromConfig("prom2", 0, "", ""), "", e2ethanos.DefaultPrometheusImage(), "", "remote-write-receiver") 29 testutil.Ok(t, e2e.StartAndWaitReady(prom1, prom2, sidecar1, sidecar2)) 30 31 qry1 := e2ethanos.NewQuerierBuilder(e, "1").WithStrictEndpoints(sidecar1.InternalEndpoint("grpc")).Init() 32 qry2 := e2ethanos.NewQuerierBuilder(e, "2").WithStrictEndpoints(sidecar2.InternalEndpoint("grpc")).Init() 33 testutil.Ok(t, e2e.StartAndWaitReady(qry1, qry2)) 34 35 qryEndpoints := []string{qry1.InternalEndpoint("grpc"), qry2.InternalEndpoint("grpc")} 36 fanoutQry := e2ethanos.NewQuerierBuilder(e, "3").WithStrictEndpoints(qryEndpoints...).Init() 37 distQry := e2ethanos.NewQuerierBuilder(e, "4").WithStrictEndpoints(qryEndpoints...). 38 WithEngine("thanos"). 39 WithQueryMode("distributed"). 40 Init() 41 testutil.Ok(t, e2e.StartAndWaitReady(fanoutQry)) 42 testutil.Ok(t, e2e.StartAndWaitReady(distQry)) 43 44 // Use current time to make debugging through UI easier. 45 now := time.Now() 46 nowFunc := func() time.Time { return now } 47 timeOffset := nowFunc().UnixNano() 48 samples := []fakeMetricSample{ 49 {"i1", 1, timeOffset + 30*1000*1000}, {"i1", 2, timeOffset + 60*1000*1000}, {"i1", 3, timeOffset + 90*1000*1000}, 50 {"i2", 5, timeOffset + 30*1000*1000}, {"i2", 6, timeOffset + 60*1000*1000}, {"i2", 7, timeOffset + 90*1000*1000}, 51 {"i3", 9, timeOffset + 30*1000*1000}, {"i3", 10, timeOffset + 60*1000*1000}, {"i3", 11, timeOffset + 90*1000*1000}, 52 } 53 ctx := context.Background() 54 testutil.Ok(t, synthesizeFakeMetricSamples(ctx, prom1, samples)) 55 testutil.Ok(t, synthesizeFakeMetricSamples(ctx, prom2, samples)) 56 57 queryFunc := func() string { return "sum(sum_over_time(my_fake_metric[2m]))" } 58 queryOpts := promclient.QueryOptions{ 59 Deduplicate: true, 60 } 61 62 // Test range query. 63 var fanoutQryRangeResult, distQryRangeResult model.Matrix 64 rangeQuery(t, ctx, fanoutQry.Endpoint("http"), queryFunc, nowFunc().UnixMilli(), nowFunc().Add(5*time.Minute).UnixMilli(), 30, queryOpts, func(res model.Matrix) error { 65 fanoutQryRangeResult = res 66 return nil 67 }) 68 rangeQuery(t, ctx, fanoutQry.Endpoint("http"), queryFunc, nowFunc().UnixMilli(), nowFunc().Add(5*time.Minute).UnixMilli(), 30, queryOpts, func(res model.Matrix) error { 69 distQryRangeResult = res 70 return nil 71 }) 72 testutil.Assert(t, len(fanoutQryRangeResult) != 0) 73 testutil.Assert(t, len(distQryRangeResult) != 0) 74 testutil.Equals(t, fanoutQryRangeResult, distQryRangeResult) 75 76 // Test instant query. 77 queryAndAssert(t, ctx, distQry.Endpoint("http"), queryFunc, nowFunc, queryOpts, model.Vector{ 78 { 79 Metric: map[model.LabelName]model.LabelValue{}, 80 Value: 30, 81 Timestamp: 0, 82 }, 83 }) 84 }