github.com/thanos-io/thanos@v0.32.5/pkg/query/querier_test.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package query 5 6 import ( 7 "context" 8 "encoding/json" 9 "fmt" 10 "math" 11 "os" 12 "reflect" 13 "sort" 14 "strconv" 15 "strings" 16 "testing" 17 "time" 18 19 "github.com/efficientgo/core/testutil" 20 "github.com/go-kit/log" 21 "github.com/google/go-cmp/cmp" 22 "github.com/pkg/errors" 23 "github.com/prometheus/common/model" 24 "github.com/prometheus/prometheus/model/histogram" 25 "github.com/prometheus/prometheus/model/labels" 26 "github.com/prometheus/prometheus/model/timestamp" 27 "github.com/prometheus/prometheus/model/value" 28 "github.com/prometheus/prometheus/promql" 29 "github.com/prometheus/prometheus/storage" 30 "github.com/prometheus/prometheus/tsdb/chunkenc" 31 "github.com/prometheus/prometheus/util/gate" 32 33 "github.com/thanos-io/thanos/pkg/component" 34 "github.com/thanos-io/thanos/pkg/store" 35 "github.com/thanos-io/thanos/pkg/store/labelpb" 36 "github.com/thanos-io/thanos/pkg/store/storepb" 37 storetestutil "github.com/thanos-io/thanos/pkg/store/storepb/testutil" 38 ) 39 40 type sample struct { 41 t int64 42 v float64 43 } 44 45 func TestQueryableCreator_MaxResolution(t *testing.T) { 46 testProxy := &testStoreServer{resps: []*storepb.SeriesResponse{}} 47 queryableCreator := NewQueryableCreator(nil, nil, newProxyStore(testProxy), 2, 5*time.Second) 48 49 oneHourMillis := int64(1*time.Hour) / int64(time.Millisecond) 50 queryable := queryableCreator( 51 false, 52 nil, 53 nil, 54 oneHourMillis, 55 false, 56 false, 57 false, 58 nil, 59 NoopSeriesStatsReporter, 60 ) 61 62 q, err := queryable.Querier(context.Background(), 0, 42) 63 testutil.Ok(t, err) 64 t.Cleanup(func() { testutil.Ok(t, q.Close()) }) 65 66 querierActual, ok := q.(*querier) 67 68 testutil.Assert(t, ok == true, "expected it to be a querier") 69 testutil.Assert(t, querierActual.maxResolutionMillis == oneHourMillis, "expected max source resolution to be 1 hour in milliseconds") 70 71 } 72 73 // Tests E2E how PromQL works with downsampled data. 74 func TestQuerier_DownsampledData(t *testing.T) { 75 testProxy := &testStoreServer{ 76 resps: []*storepb.SeriesResponse{ 77 storeSeriesResponse(t, labels.FromStrings("__name__", "a", "zzz", "a", "aaa", "bbb"), []sample{{99, 1}, {199, 5}}), // Downsampled chunk from Store. 78 storeSeriesResponse(t, labels.FromStrings("__name__", "a", "zzz", "b", "bbbb", "eee"), []sample{{99, 3}, {199, 8}}), // Downsampled chunk from Store. 79 storeSeriesResponse(t, labels.FromStrings("__name__", "a", "zzz", "c", "qwe", "wqeqw"), []sample{{99, 5}, {199, 15}}), // Downsampled chunk from Store. 80 storeSeriesResponse(t, labels.FromStrings("__name__", "a", "zzz", "c", "htgtreytr", "vbnbv"), []sample{{99, 123}, {199, 15}}), // Downsampled chunk from Store. 81 storeSeriesResponse(t, labels.FromStrings("__name__", "a", "zzz", "d", "asdsad", "qweqwewq"), []sample{{22, 5}, {44, 8}, {199, 15}}), // Raw chunk from Sidecar. 82 storeSeriesResponse(t, labels.FromStrings("__name__", "a", "zzz", "d", "asdsad", "qweqwebb"), []sample{{22, 5}, {44, 8}, {199, 15}}), // Raw chunk from Sidecar. 83 }, 84 } 85 86 timeout := 10 * time.Second 87 q := NewQueryableCreator( 88 nil, 89 nil, 90 newProxyStore(testProxy), 91 2, 92 timeout, 93 )(false, 94 nil, 95 nil, 96 9999999, 97 false, 98 false, 99 false, 100 nil, 101 NoopSeriesStatsReporter, 102 ) 103 engine := promql.NewEngine( 104 promql.EngineOpts{ 105 MaxSamples: math.MaxInt32, 106 Timeout: timeout, 107 }, 108 ) 109 110 // Minimal function to parse time.Time. 111 ptm := func(in string) time.Time { 112 fl, _ := strconv.ParseFloat(in, 64) 113 s, ns := math.Modf(fl) 114 return time.Unix(int64(s), int64(ns*float64(time.Second))) 115 } 116 117 st := ptm("0") 118 ed := ptm("0.2") 119 qry, err := engine.NewRangeQuery( 120 context.Background(), 121 q, 122 promql.NewPrometheusQueryOpts(false, 0), 123 "sum(a) by (zzz)", 124 st, 125 ed, 126 100*time.Millisecond, 127 ) 128 testutil.Ok(t, err) 129 130 res := qry.Exec(context.Background()) 131 testutil.Ok(t, res.Err) 132 m, err := res.Matrix() 133 testutil.Ok(t, err) 134 ser := []promql.Series(m) 135 136 testutil.Assert(t, len(ser) == 4, "should return 4 series (got %d)", len(ser)) 137 138 exp := []promql.Series{ 139 { 140 Metric: labels.FromStrings("zzz", "a"), 141 Floats: []promql.FPoint{{T: 100, F: 1}, {T: 200, F: 5}}, 142 }, 143 { 144 Metric: labels.FromStrings("zzz", "b"), 145 Floats: []promql.FPoint{{T: 100, F: 3}, {T: 200, F: 8}}, 146 }, 147 { 148 Metric: labels.FromStrings("zzz", "c"), 149 // Test case: downsampling code adds all of the samples in the 150 // 5 minute window of each series and pre-aggregates the data. However, 151 // Prometheus engine code only takes the latest sample in each time window of 152 // the retrieved data. Since we were operating in pre-aggregated data here, it lead 153 // to overinflated values. 154 Floats: []promql.FPoint{{T: 100, F: 128}, {T: 200, F: 30}}, 155 }, 156 { 157 Metric: labels.FromStrings("zzz", "d"), 158 // Test case: Prometheus engine in each time window selects the sample 159 // which is closest to the boundaries and adds up the different dimensions. 160 Floats: []promql.FPoint{{T: 100, F: 16}, {T: 200, F: 30}}, 161 }, 162 } 163 164 if !reflect.DeepEqual(ser, exp) { 165 t.Fatalf("response does not match, expected:\n%+v\ngot:\n%+v", exp, ser) 166 } 167 } 168 169 var ( 170 realSeriesWithStaleMarkerMint int64 = 1587690000000 // 04/24/2020 01:00:00 GMT. 171 realSeriesWithStaleMarkerMaxt int64 = 1587693600000 // 04/24/2020 02:00:00 GMT. 172 expectedRealSeriesWithStaleMarkerReplica0 = []sample{ 173 {t: 1587690007139, v: 461993}, {t: 1587690022139, v: 462164}, {t: 1587690037139, v: 462409}, {t: 1587690052139, v: 462662}, {t: 1587690067139, v: 462824}, {t: 1587690082139, v: 462987}, {t: 1587690097155, v: 463108}, {t: 1587690112139, v: 463261}, {t: 1587690127139, v: 463465}, {t: 1587690142139, v: 463642}, 174 {t: 1587690157139, v: 463823}, {t: 1587690172139, v: 464065}, {t: 1587690187139, v: 464333}, {t: 1587690202139, v: 464566}, {t: 1587690217139, v: 464811}, {t: 1587690232140, v: 465032}, {t: 1587690247139, v: 465229}, {t: 1587690262139, v: 465445}, {t: 1587690277139, v: 465700}, {t: 1587690292139, v: 465884}, 175 {t: 1587690307139, v: 466083}, {t: 1587690322139, v: 466250}, {t: 1587690337150, v: 466534}, {t: 1587690352139, v: 466791}, {t: 1587690367139, v: 466970}, {t: 1587690382139, v: 467149}, {t: 1587690397139, v: 467265}, {t: 1587690412139, v: 467383}, {t: 1587690427139, v: 467647}, {t: 1587690442139, v: 467943}, 176 {t: 1587690457139, v: 468121}, {t: 1587690472139, v: 468294}, {t: 1587690487139, v: 468545}, {t: 1587690502139, v: 468676}, {t: 1587690517139, v: 468879}, {t: 1587690532139, v: 469154}, {t: 1587690547139, v: 469281}, {t: 1587690562139, v: 469512}, {t: 1587690577139, v: 469783}, {t: 1587690592139, v: 469964}, 177 {t: 1587690607139, v: 470171}, {t: 1587690622139, v: 470355}, {t: 1587690637139, v: 470656}, {t: 1587690652139, v: 470845}, {t: 1587690667139, v: 471077}, {t: 1587690682139, v: 471315}, {t: 1587690697139, v: 471535}, {t: 1587690712139, v: 471766}, {t: 1587690727139, v: 472002}, {t: 1587690742139, v: 472171}, 178 {t: 1587690757139, v: 472354}, {t: 1587690772139, v: 472736}, {t: 1587690787139, v: 472948}, {t: 1587690802139, v: 473259}, {t: 1587690817139, v: 473460}, {t: 1587690832139, v: 473753}, {t: 1587690847139, v: 474007}, {t: 1587690862139, v: 474286}, {t: 1587690877139, v: 474423}, {t: 1587690892139, v: 474788}, 179 {t: 1587690907139, v: 474925}, {t: 1587690922139, v: 475031}, {t: 1587690937139, v: 475316}, {t: 1587690952139, v: 475573}, {t: 1587690967139, v: 475784}, {t: 1587690982139, v: 475992}, {t: 1587690997139, v: 476341}, {t: 1587691012139, v: 476541}, {t: 1587691027139, v: 476890}, {t: 1587691042139, v: 477033}, 180 {t: 1587691057139, v: 477305}, {t: 1587691072139, v: 477577}, {t: 1587691087139, v: 477771}, {t: 1587691102139, v: 478012}, {t: 1587691117139, v: 478296}, {t: 1587691132139, v: 478559}, {t: 1587691147139, v: 478744}, {t: 1587691162139, v: 478950}, {t: 1587691177139, v: 479201}, {t: 1587691192139, v: 479388}, 181 {t: 1587691207139, v: 479638}, {t: 1587691222154, v: 479907}, {t: 1587691237139, v: 480008}, {t: 1587691252139, v: 480167}, {t: 1587691267139, v: 480472}, {t: 1587691282157, v: 480615}, {t: 1587691297139, v: 480771}, {t: 1587691312139, v: 481027}, {t: 1587691327139, v: 481212}, {t: 1587691342159, v: 481395}, 182 {t: 1587691357139, v: 481598}, {t: 1587691372139, v: 481786}, {t: 1587691387139, v: 482003}, {t: 1587691402141, v: 482236}, {t: 1587691417139, v: 482508}, {t: 1587691432139, v: 482636}, {t: 1587691447139, v: 482780}, {t: 1587691462139, v: 483059}, {t: 1587691477139, v: 483357}, {t: 1587691492139, v: 483566}, 183 {t: 1587691507139, v: 483711}, {t: 1587691522139, v: 483838}, {t: 1587691537139, v: 484091}, {t: 1587691552139, v: 484254}, {t: 1587691567139, v: 484479}, {t: 1587691582139, v: 484748}, {t: 1587691597139, v: 484978}, {t: 1587691612139, v: 485271}, {t: 1587691627139, v: 485488}, {t: 1587691642139, v: 485700}, 184 {t: 1587691657139, v: 485945}, {t: 1587691672139, v: 486228}, {t: 1587691687139, v: 486588}, {t: 1587691702139, v: 486691}, {t: 1587691717139, v: 486881}, {t: 1587691732139, v: 487046}, {t: 1587691747139, v: 487291}, {t: 1587691762177, v: 487410}, {t: 1587691777139, v: 487571}, {t: 1587691792139, v: 487799}, 185 {t: 1587691807139, v: 488050}, {t: 1587691822139, v: 488241}, {t: 1587691837139, v: 488424}, {t: 1587691852139, v: 488629}, {t: 1587691867139, v: 488875}, {t: 1587691882139, v: 489017}, {t: 1587691897139, v: 489254}, {t: 1587691912139, v: 489545}, {t: 1587691927139, v: 489778}, {t: 1587691942139, v: 489912}, 186 {t: 1587691957139, v: 490084}, {t: 1587691972139, v: 490364}, {t: 1587691987139, v: 490510}, {t: 1587692002139, v: 490744}, {t: 1587692017139, v: 490880}, {t: 1587692032139, v: 491025}, {t: 1587692047139, v: 491297}, {t: 1587692062155, v: 491557}, {t: 1587692077139, v: 491839}, {t: 1587692092139, v: 492065}, 187 {t: 1587692107139, v: 492234}, {t: 1587692122139, v: 492526}, {t: 1587692137139, v: 492767}, {t: 1587692152139, v: 492967}, {t: 1587692167139, v: 493218}, {t: 1587692182139, v: 493442}, {t: 1587692197139, v: 493647}, {t: 1587692212139, v: 493920}, {t: 1587692227139, v: 494170}, {t: 1587692242139, v: 494358}, 188 {t: 1587692257139, v: 494632}, {t: 1587692272139, v: 494800}, {t: 1587692287139, v: 495026}, {t: 1587692302139, v: 495222}, {t: 1587692317139, v: 495433}, {t: 1587692332139, v: 495677}, {t: 1587692347139, v: 495901}, {t: 1587692362139, v: 496107}, {t: 1587692377139, v: 496196}, {t: 1587692392139, v: 496245}, 189 {t: 1587692407139, v: 496300}, {t: 1587692422159, v: 496365}, {t: 1587692437139, v: 496401}, {t: 1587692452139, v: 496452}, {t: 1587692467139, v: 496532}, {t: 1587692482139, v: math.Float64frombits(value.StaleNaN)}, {t: 1587692542149, v: 5}, {t: 1587692557139, v: 101}, {t: 1587692572139, v: 312}, {t: 1587692587139, v: 508}, 190 {t: 1587692602144, v: 725}, {t: 1587692617139, v: 990}, {t: 1587692632139, v: 1178}, {t: 1587692647139, v: 1406}, {t: 1587692662154, v: 1640}, {t: 1587692677139, v: 1927}, {t: 1587692692139, v: 2103}, {t: 1587692707139, v: 2300}, {t: 1587692722139, v: 2482}, {t: 1587692737139, v: 2638}, {t: 1587692752139, v: 2806}, 191 {t: 1587692767139, v: 2979}, {t: 1587692782149, v: 3187}, {t: 1587692797139, v: 3441}, {t: 1587692812139, v: 3657}, {t: 1587692827139, v: 3827}, {t: 1587692842139, v: 3985}, {t: 1587692857139, v: 4195}, {t: 1587692872139, v: 4427}, {t: 1587692887139, v: 4646}, {t: 1587692902139, v: 4714}, {t: 1587692917153, v: 4872}, 192 {t: 1587692932139, v: 5131}, {t: 1587692947139, v: 5318}, {t: 1587692962139, v: 5571}, {t: 1587692977155, v: 5748}, {t: 1587692992139, v: 6030}, {t: 1587693007139, v: 6210}, {t: 1587693022139, v: 6399}, {t: 1587693037139, v: 6658}, {t: 1587693052139, v: 6896}, {t: 1587693067139, v: 7098}, {t: 1587693082139, v: 7341}, 193 {t: 1587693097139, v: 7495}, {t: 1587693112139, v: 7647}, {t: 1587693127139, v: 7830}, {t: 1587693142139, v: 8058}, {t: 1587693157139, v: 8209}, {t: 1587693172139, v: 8524}, {t: 1587693187139, v: 8712}, {t: 1587693202139, v: 8904}, {t: 1587693217139, v: 9103}, {t: 1587693232139, v: 9404}, {t: 1587693247155, v: 9556}, 194 {t: 1587693262139, v: 9777}, {t: 1587693277139, v: 9992}, {t: 1587693292139, v: 10268}, {t: 1587693307139, v: 10478}, {t: 1587693322139, v: 10754}, {t: 1587693337139, v: 10998}, {t: 1587693352139, v: 11249}, {t: 1587693367139, v: 11459}, {t: 1587693382139, v: 11778}, {t: 1587693397139, v: 12038}, 195 {t: 1587693412139, v: 12238}, {t: 1587693427139, v: 12450}, {t: 1587693442163, v: 12742}, {t: 1587693457139, v: 12945}, {t: 1587693472139, v: 13181}, {t: 1587693487139, v: 13440}, {t: 1587693502139, v: 13650}, {t: 1587693517139, v: 13966}, {t: 1587693532139, v: 14122}, {t: 1587693547139, v: 14327}, {t: 1587693562139, v: 14592}, 196 {t: 1587693577139, v: 14782}, {t: 1587693592139, v: 14956}, 197 } 198 expectedRealSeriesWithStaleMarkerReplica1 = []sample{ 199 {t: 1587690005791, v: 461968}, {t: 1587690020791, v: 462151}, {t: 1587690035797, v: 462336}, {t: 1587690050791, v: 462650}, {t: 1587690065791, v: 462813}, {t: 1587690080791, v: 462987}, {t: 1587690095791, v: 463095}, {t: 1587690110791, v: 463247}, {t: 1587690125791, v: 463440}, {t: 1587690140791, v: 463642}, {t: 1587690155791, v: 463811}, 200 {t: 1587690170791, v: 464027}, {t: 1587690185791, v: 464308}, {t: 1587690200791, v: 464514}, {t: 1587690215791, v: 464798}, {t: 1587690230791, v: 465018}, {t: 1587690245791, v: 465215}, {t: 1587690260813, v: 465431}, {t: 1587690275791, v: 465651}, {t: 1587690290791, v: 465870}, {t: 1587690305791, v: 466070}, {t: 1587690320792, v: 466248}, 201 {t: 1587690335791, v: 466506}, {t: 1587690350791, v: 466766}, {t: 1587690365791, v: 466970}, {t: 1587690380791, v: 467123}, {t: 1587690395791, v: 467265}, {t: 1587690410791, v: 467383}, {t: 1587690425791, v: 467629}, {t: 1587690440791, v: 467931}, {t: 1587690455791, v: 468097}, {t: 1587690470791, v: 468281}, {t: 1587690485791, v: 468477}, 202 {t: 1587690500791, v: 468649}, {t: 1587690515791, v: 468867}, {t: 1587690530791, v: 469150}, {t: 1587690545791, v: 469268}, {t: 1587690560791, v: 469488}, {t: 1587690575791, v: 469742}, {t: 1587690590791, v: 469951}, {t: 1587690605791, v: 470131}, {t: 1587690620791, v: 470337}, {t: 1587690635791, v: 470631}, {t: 1587690650791, v: 470832}, 203 {t: 1587690665791, v: 471077}, {t: 1587690680791, v: 471311}, {t: 1587690695791, v: 471473}, {t: 1587690710791, v: 471728}, {t: 1587690725791, v: 472002}, {t: 1587690740791, v: 472158}, {t: 1587690755791, v: 472329}, {t: 1587690770791, v: 472722}, {t: 1587690785791, v: 472925}, {t: 1587690800791, v: 473220}, {t: 1587690815791, v: 473460}, 204 {t: 1587690830791, v: 473748}, {t: 1587690845791, v: 473968}, {t: 1587690860791, v: 474261}, {t: 1587690875791, v: 474418}, {t: 1587690890791, v: 474726}, {t: 1587690905791, v: 474913}, {t: 1587690920791, v: 475031}, {t: 1587690935791, v: 475284}, {t: 1587690950791, v: 475563}, {t: 1587690965791, v: 475762}, {t: 1587690980791, v: 475945}, 205 {t: 1587690995791, v: 476302}, {t: 1587691010791, v: 476501}, {t: 1587691025791, v: 476849}, {t: 1587691040800, v: 477020}, {t: 1587691055791, v: 477280}, {t: 1587691070791, v: 477549}, {t: 1587691085791, v: 477758}, {t: 1587691100817, v: 477960}, {t: 1587691115791, v: 478261}, {t: 1587691130791, v: 478559}, {t: 1587691145791, v: 478704}, 206 {t: 1587691160804, v: 478950}, {t: 1587691175791, v: 479173}, {t: 1587691190791, v: 479368}, {t: 1587691205791, v: 479625}, {t: 1587691220805, v: 479866}, {t: 1587691235791, v: 480008}, {t: 1587691250791, v: 480155}, {t: 1587691265791, v: 480472}, {t: 1587691280811, v: 480598}, {t: 1587691295791, v: 480771}, {t: 1587691310791, v: 480996}, 207 {t: 1587691325791, v: 481200}, {t: 1587691340803, v: 481381}, {t: 1587691355791, v: 481584}, {t: 1587691370791, v: 481759}, {t: 1587691385791, v: 482003}, {t: 1587691400803, v: 482189}, {t: 1587691415791, v: 482457}, {t: 1587691430791, v: 482623}, {t: 1587691445791, v: 482768}, {t: 1587691460804, v: 483036}, {t: 1587691475791, v: 483322}, 208 {t: 1587691490791, v: 483566}, {t: 1587691505791, v: 483709}, {t: 1587691520807, v: 483838}, {t: 1587691535791, v: 484091}, {t: 1587691550791, v: 484236}, {t: 1587691565791, v: 484454}, {t: 1587691580816, v: 484710}, {t: 1587691595791, v: 484978}, {t: 1587691610791, v: 485271}, {t: 1587691625791, v: 485476}, {t: 1587691640792, v: 485640}, 209 {t: 1587691655791, v: 485921}, {t: 1587691670791, v: 486201}, {t: 1587691685791, v: 486555}, {t: 1587691700791, v: 486691}, {t: 1587691715791, v: 486831}, {t: 1587691730791, v: 487033}, {t: 1587691745791, v: 487268}, {t: 1587691760803, v: 487370}, {t: 1587691775791, v: 487571}, {t: 1587691790791, v: 487787}, {t: 1587691805791, v: 488036}, 210 {t: 1587691820791, v: 488241}, {t: 1587691835791, v: 488411}, {t: 1587691850791, v: 488625}, {t: 1587691865791, v: 488868}, {t: 1587691880791, v: 489005}, {t: 1587691895791, v: 489237}, {t: 1587691910791, v: 489545}, {t: 1587691925791, v: 489750}, {t: 1587691940791, v: 489899}, {t: 1587691955791, v: 490048}, {t: 1587691970791, v: 490364}, 211 {t: 1587691985791, v: 490485}, {t: 1587692000791, v: 490722}, {t: 1587692015791, v: 490866}, {t: 1587692030791, v: 491025}, {t: 1587692045791, v: 491286}, {t: 1587692060816, v: 491543}, {t: 1587692075791, v: 491787}, {t: 1587692090791, v: 492065}, {t: 1587692105791, v: 492223}, {t: 1587692120816, v: 492501}, {t: 1587692135791, v: 492767}, 212 {t: 1587692150791, v: 492955}, {t: 1587692165791, v: 493194}, {t: 1587692180792, v: 493402}, {t: 1587692195791, v: 493647}, {t: 1587692210791, v: 493897}, {t: 1587692225791, v: 494117}, {t: 1587692240805, v: 494356}, {t: 1587692255791, v: 494620}, {t: 1587692270791, v: 494762}, {t: 1587692285791, v: 495001}, {t: 1587692300805, v: 495222}, 213 {t: 1587692315791, v: 495393}, {t: 1587692330791, v: 495662}, {t: 1587692345791, v: 495875}, {t: 1587692360801, v: 496082}, {t: 1587692375791, v: 496196}, {t: 1587692390791, v: 496245}, {t: 1587692405791, v: 496295}, {t: 1587692420791, v: 496365}, {t: 1587692435791, v: 496401}, {t: 1587692450791, v: 496452}, {t: 1587692465791, v: 496491}, 214 {t: 1587692480791, v: 496544}, {t: 1587692495791, v: math.Float64frombits(value.StaleNaN)}, {t: 1587692555791, v: 75}, {t: 1587692570791, v: 308}, {t: 1587692585791, v: 508}, {t: 1587692600791, v: 701}, {t: 1587692615791, v: 985}, {t: 1587692630791, v: 1153}, {t: 1587692645791, v: 1365}, {t: 1587692660791, v: 1612}, {t: 1587692675803, v: 1922}, {t: 1587692690791, v: 2103}, 215 {t: 1587692705791, v: 2261}, {t: 1587692720791, v: 2469}, {t: 1587692735805, v: 2625}, {t: 1587692750791, v: 2801}, {t: 1587692765791, v: 2955}, {t: 1587692780791, v: 3187}, {t: 1587692795806, v: 3428}, {t: 1587692810791, v: 3657}, {t: 1587692825791, v: 3810}, {t: 1587692840791, v: 3968}, {t: 1587692855791, v: 4195}, {t: 1587692870791, v: 4414}, 216 {t: 1587692885791, v: 4646}, {t: 1587692900791, v: 4689}, {t: 1587692915791, v: 4847}, {t: 1587692930791, v: 5105}, {t: 1587692945791, v: 5309}, {t: 1587692960791, v: 5521}, {t: 1587692975791, v: 5695}, {t: 1587692990810, v: 6010}, {t: 1587693005791, v: 6210}, {t: 1587693020791, v: 6394}, {t: 1587693035791, v: 6597}, {t: 1587693050791, v: 6872}, 217 {t: 1587693065791, v: 7098}, {t: 1587693080791, v: 7329}, {t: 1587693095791, v: 7470}, {t: 1587693110791, v: 7634}, {t: 1587693125821, v: 7830}, {t: 1587693140791, v: 8034}, {t: 1587693155791, v: 8209}, {t: 1587693170791, v: 8499}, {t: 1587693185791, v: 8688}, {t: 1587693200791, v: 8893}, {t: 1587693215791, v: 9052}, {t: 1587693230791, v: 9379}, 218 {t: 1587693245791, v: 9544}, {t: 1587693260791, v: 9763}, {t: 1587693275791, v: 9974}, {t: 1587693290791, v: 10242}, {t: 1587693305791, v: 10464}, {t: 1587693320803, v: 10716}, {t: 1587693335791, v: 10975}, {t: 1587693350791, v: 11232}, {t: 1587693365791, v: 11459}, {t: 1587693380791, v: 11778}, {t: 1587693395804, v: 12007}, {t: 1587693410791, v: 12206}, 219 {t: 1587693425791, v: 12450}, {t: 1587693440791, v: 12693}, {t: 1587693455791, v: 12908}, {t: 1587693470791, v: 13158}, {t: 1587693485791, v: 13427}, {t: 1587693500791, v: 13603}, {t: 1587693515791, v: 13927}, {t: 1587693530816, v: 14122}, {t: 1587693545791, v: 14327}, {t: 1587693560791, v: 14579}, {t: 1587693575791, v: 14759}, {t: 1587693590791, v: 14956}, 220 } 221 expectedRealSeriesWithStaleMarkerDeduplicated = []sample{ 222 {t: 1587690005791, v: 461968}, {t: 1587690020791, v: 462151}, {t: 1587690035797, v: 462336}, {t: 1587690050791, v: 462650}, {t: 1587690065791, v: 462813}, {t: 1587690080791, v: 462987}, {t: 1587690095791, v: 463095}, {t: 1587690110791, v: 463247}, {t: 1587690125791, v: 463440}, {t: 1587690140791, v: 463642}, {t: 1587690155791, v: 463811}, 223 {t: 1587690170791, v: 464027}, {t: 1587690185791, v: 464308}, {t: 1587690200791, v: 464514}, {t: 1587690215791, v: 464798}, {t: 1587690230791, v: 465018}, {t: 1587690245791, v: 465215}, {t: 1587690260813, v: 465431}, {t: 1587690275791, v: 465651}, {t: 1587690290791, v: 465870}, {t: 1587690305791, v: 466070}, {t: 1587690320792, v: 466248}, 224 {t: 1587690335791, v: 466506}, {t: 1587690350791, v: 466766}, {t: 1587690365791, v: 466970}, {t: 1587690380791, v: 467123}, {t: 1587690395791, v: 467265}, {t: 1587690410791, v: 467383}, {t: 1587690425791, v: 467629}, {t: 1587690440791, v: 467931}, {t: 1587690455791, v: 468097}, {t: 1587690470791, v: 468281}, {t: 1587690485791, v: 468477}, 225 {t: 1587690500791, v: 468649}, {t: 1587690515791, v: 468867}, {t: 1587690530791, v: 469150}, {t: 1587690545791, v: 469268}, {t: 1587690560791, v: 469488}, {t: 1587690575791, v: 469742}, {t: 1587690590791, v: 469951}, {t: 1587690605791, v: 470131}, {t: 1587690620791, v: 470337}, {t: 1587690635791, v: 470631}, {t: 1587690650791, v: 470832}, 226 {t: 1587690665791, v: 471077}, {t: 1587690680791, v: 471311}, {t: 1587690695791, v: 471473}, {t: 1587690710791, v: 471728}, {t: 1587690725791, v: 472002}, {t: 1587690740791, v: 472158}, {t: 1587690755791, v: 472329}, {t: 1587690770791, v: 472722}, {t: 1587690785791, v: 472925}, {t: 1587690800791, v: 473220}, {t: 1587690815791, v: 473460}, 227 {t: 1587690830791, v: 473748}, {t: 1587690845791, v: 473968}, {t: 1587690860791, v: 474261}, {t: 1587690875791, v: 474418}, {t: 1587690890791, v: 474726}, {t: 1587690905791, v: 474913}, {t: 1587690920791, v: 475031}, {t: 1587690935791, v: 475284}, {t: 1587690950791, v: 475563}, {t: 1587690965791, v: 475762}, {t: 1587690980791, v: 475945}, 228 {t: 1587690995791, v: 476302}, {t: 1587691010791, v: 476501}, {t: 1587691025791, v: 476849}, {t: 1587691040800, v: 477020}, {t: 1587691055791, v: 477280}, {t: 1587691070791, v: 477549}, {t: 1587691085791, v: 477758}, {t: 1587691100817, v: 477960}, {t: 1587691115791, v: 478261}, {t: 1587691130791, v: 478559}, {t: 1587691145791, v: 478704}, 229 {t: 1587691160804, v: 478950}, {t: 1587691175791, v: 479173}, {t: 1587691190791, v: 479368}, {t: 1587691205791, v: 479625}, {t: 1587691220805, v: 479866}, {t: 1587691235791, v: 480008}, {t: 1587691250791, v: 480155}, {t: 1587691265791, v: 480472}, {t: 1587691280811, v: 480598}, {t: 1587691295791, v: 480771}, {t: 1587691310791, v: 480996}, 230 {t: 1587691325791, v: 481200}, {t: 1587691340803, v: 481381}, {t: 1587691355791, v: 481584}, {t: 1587691370791, v: 481759}, {t: 1587691385791, v: 482003}, {t: 1587691400803, v: 482189}, {t: 1587691415791, v: 482457}, {t: 1587691430791, v: 482623}, {t: 1587691445791, v: 482768}, {t: 1587691460804, v: 483036}, {t: 1587691475791, v: 483322}, 231 {t: 1587691490791, v: 483566}, {t: 1587691505791, v: 483709}, {t: 1587691520807, v: 483838}, {t: 1587691535791, v: 484091}, {t: 1587691550791, v: 484236}, {t: 1587691565791, v: 484454}, {t: 1587691580816, v: 484710}, {t: 1587691595791, v: 484978}, {t: 1587691610791, v: 485271}, {t: 1587691625791, v: 485476}, {t: 1587691640792, v: 485640}, 232 {t: 1587691655791, v: 485921}, {t: 1587691670791, v: 486201}, {t: 1587691685791, v: 486555}, {t: 1587691700791, v: 486691}, {t: 1587691715791, v: 486831}, {t: 1587691730791, v: 487033}, {t: 1587691745791, v: 487268}, {t: 1587691760803, v: 487370}, {t: 1587691775791, v: 487571}, {t: 1587691790791, v: 487787}, {t: 1587691805791, v: 488036}, 233 {t: 1587691820791, v: 488241}, {t: 1587691835791, v: 488411}, {t: 1587691850791, v: 488625}, {t: 1587691865791, v: 488868}, {t: 1587691880791, v: 489005}, {t: 1587691895791, v: 489237}, {t: 1587691910791, v: 489545}, {t: 1587691925791, v: 489750}, {t: 1587691940791, v: 489899}, {t: 1587691955791, v: 490048}, {t: 1587691970791, v: 490364}, 234 {t: 1587691985791, v: 490485}, {t: 1587692000791, v: 490722}, {t: 1587692015791, v: 490866}, {t: 1587692030791, v: 491025}, {t: 1587692045791, v: 491286}, {t: 1587692060816, v: 491543}, {t: 1587692075791, v: 491787}, {t: 1587692090791, v: 492065}, {t: 1587692105791, v: 492223}, {t: 1587692120816, v: 492501}, {t: 1587692135791, v: 492767}, 235 {t: 1587692150791, v: 492955}, {t: 1587692165791, v: 493194}, {t: 1587692180792, v: 493402}, {t: 1587692195791, v: 493647}, {t: 1587692210791, v: 493897}, {t: 1587692225791, v: 494117}, {t: 1587692240805, v: 494356}, {t: 1587692255791, v: 494620}, {t: 1587692270791, v: 494762}, {t: 1587692285791, v: 495001}, {t: 1587692300805, v: 495222}, 236 {t: 1587692315791, v: 495393}, {t: 1587692330791, v: 495662}, {t: 1587692345791, v: 495875}, {t: 1587692360801, v: 496082}, {t: 1587692375791, v: 496196}, {t: 1587692390791, v: 496245}, {t: 1587692405791, v: 496295}, {t: 1587692420791, v: 496365}, {t: 1587692435791, v: 496401}, {t: 1587692450791, v: 496452}, {t: 1587692465791, v: 496491}, 237 {t: 1587692480791, v: 496544}, {t: 1587692495791, v: math.Float64frombits(value.StaleNaN)}, {t: 1587692542149, v: 5}, {t: 1587692557139, v: 101}, {t: 1587692572139, v: 312}, {t: 1587692587139, v: 508}, {t: 1587692602144, v: 725}, {t: 1587692617139, v: 990}, {t: 1587692632139, v: 1178}, {t: 1587692647139, v: 1406}, {t: 1587692662154, v: 1640}, {t: 1587692677139, v: 1927}, 238 {t: 1587692692139, v: 2103}, {t: 1587692707139, v: 2300}, {t: 1587692722139, v: 2482}, {t: 1587692737139, v: 2638}, {t: 1587692752139, v: 2806}, {t: 1587692767139, v: 2979}, {t: 1587692782149, v: 3187}, {t: 1587692797139, v: 3441}, {t: 1587692812139, v: 3657}, {t: 1587692827139, v: 3827}, {t: 1587692842139, v: 3985}, {t: 1587692857139, v: 4195}, 239 {t: 1587692872139, v: 4427}, {t: 1587692887139, v: 4646}, {t: 1587692902139, v: 4714}, {t: 1587692917153, v: 4872}, {t: 1587692932139, v: 5131}, {t: 1587692947139, v: 5318}, {t: 1587692962139, v: 5571}, {t: 1587692977155, v: 5748}, {t: 1587692992139, v: 6030}, {t: 1587693007139, v: 6210}, {t: 1587693022139, v: 6399}, {t: 1587693037139, v: 6658}, 240 {t: 1587693052139, v: 6896}, {t: 1587693067139, v: 7098}, {t: 1587693082139, v: 7341}, {t: 1587693097139, v: 7495}, {t: 1587693112139, v: 7647}, {t: 1587693127139, v: 7830}, {t: 1587693142139, v: 8058}, {t: 1587693157139, v: 8209}, {t: 1587693172139, v: 8524}, {t: 1587693187139, v: 8712}, {t: 1587693202139, v: 8904}, {t: 1587693217139, v: 9103}, 241 {t: 1587693232139, v: 9404}, {t: 1587693247155, v: 9556}, {t: 1587693262139, v: 9777}, {t: 1587693277139, v: 9992}, {t: 1587693292139, v: 10268}, {t: 1587693307139, v: 10478}, {t: 1587693322139, v: 10754}, {t: 1587693337139, v: 10998}, {t: 1587693352139, v: 11249}, {t: 1587693367139, v: 11459}, {t: 1587693382139, v: 11778}, {t: 1587693397139, v: 12038}, 242 {t: 1587693412139, v: 12238}, {t: 1587693427139, v: 12450}, {t: 1587693442163, v: 12742}, {t: 1587693457139, v: 12945}, {t: 1587693472139, v: 13181}, {t: 1587693487139, v: 13440}, {t: 1587693502139, v: 13650}, {t: 1587693517139, v: 13966}, {t: 1587693532139, v: 14122}, {t: 1587693547139, v: 14327}, {t: 1587693562139, v: 14592}, 243 {t: 1587693577139, v: 14782}, {t: 1587693592139, v: 14956}, 244 } 245 246 // For rate means that hints.func = rate. 247 expectedRealSeriesWithStaleMarkerReplica0ForRate = []sample{ 248 {t: 1587690007139, v: 461993}, {t: 1587690022139, v: 462164}, {t: 1587690037139, v: 462409}, {t: 1587690052139, v: 462662}, {t: 1587690067139, v: 462824}, {t: 1587690082139, v: 462987}, {t: 1587690097155, v: 463108}, {t: 1587690112139, v: 463261}, {t: 1587690127139, v: 463465}, {t: 1587690142139, v: 463642}, {t: 1587690157139, v: 463823}, 249 {t: 1587690172139, v: 464065}, {t: 1587690187139, v: 464333}, {t: 1587690202139, v: 464566}, {t: 1587690217139, v: 464811}, {t: 1587690232140, v: 465032}, {t: 1587690247139, v: 465229}, {t: 1587690262139, v: 465445}, {t: 1587690277139, v: 465700}, {t: 1587690292139, v: 465884}, {t: 1587690307139, v: 466083}, {t: 1587690322139, v: 466250}, 250 {t: 1587690337150, v: 466534}, {t: 1587690352139, v: 466791}, {t: 1587690367139, v: 466970}, {t: 1587690382139, v: 467149}, {t: 1587690397139, v: 467265}, {t: 1587690412139, v: 467383}, {t: 1587690427139, v: 467647}, {t: 1587690442139, v: 467943}, {t: 1587690457139, v: 468121}, {t: 1587690472139, v: 468294}, {t: 1587690487139, v: 468545}, 251 {t: 1587690502139, v: 468676}, {t: 1587690517139, v: 468879}, {t: 1587690532139, v: 469154}, {t: 1587690547139, v: 469281}, {t: 1587690562139, v: 469512}, {t: 1587690577139, v: 469783}, {t: 1587690592139, v: 469964}, {t: 1587690607139, v: 470171}, {t: 1587690622139, v: 470355}, {t: 1587690637139, v: 470656}, {t: 1587690652139, v: 470845}, 252 {t: 1587690667139, v: 471077}, {t: 1587690682139, v: 471315}, {t: 1587690697139, v: 471535}, {t: 1587690712139, v: 471766}, {t: 1587690727139, v: 472002}, {t: 1587690742139, v: 472171}, {t: 1587690757139, v: 472354}, {t: 1587690772139, v: 472736}, {t: 1587690787139, v: 472948}, {t: 1587690802139, v: 473259}, {t: 1587690817139, v: 473460}, 253 {t: 1587690832139, v: 473753}, {t: 1587690847139, v: 474007}, {t: 1587690862139, v: 474286}, {t: 1587690877139, v: 474423}, {t: 1587690892139, v: 474788}, {t: 1587690907139, v: 474925}, {t: 1587690922139, v: 475031}, {t: 1587690937139, v: 475316}, {t: 1587690952139, v: 475573}, {t: 1587690967139, v: 475784}, {t: 1587690982139, v: 475992}, 254 {t: 1587690997139, v: 476341}, {t: 1587691012139, v: 476541}, {t: 1587691027139, v: 476890}, {t: 1587691042139, v: 477033}, {t: 1587691057139, v: 477305}, {t: 1587691072139, v: 477577}, {t: 1587691087139, v: 477771}, {t: 1587691102139, v: 478012}, {t: 1587691117139, v: 478296}, {t: 1587691132139, v: 478559}, {t: 1587691147139, v: 478744}, 255 {t: 1587691162139, v: 478950}, {t: 1587691177139, v: 479201}, {t: 1587691192139, v: 479388}, {t: 1587691207139, v: 479638}, {t: 1587691222154, v: 479907}, {t: 1587691237139, v: 480008}, {t: 1587691252139, v: 480167}, {t: 1587691267139, v: 480472}, {t: 1587691282157, v: 480615}, {t: 1587691297139, v: 480771}, {t: 1587691312139, v: 481027}, 256 {t: 1587691327139, v: 481212}, {t: 1587691342159, v: 481395}, {t: 1587691357139, v: 481598}, {t: 1587691372139, v: 481786}, {t: 1587691387139, v: 482003}, {t: 1587691402141, v: 482236}, {t: 1587691417139, v: 482508}, {t: 1587691432139, v: 482636}, {t: 1587691447139, v: 482780}, {t: 1587691462139, v: 483059}, {t: 1587691477139, v: 483357}, 257 {t: 1587691492139, v: 483566}, {t: 1587691507139, v: 483711}, {t: 1587691522139, v: 483838}, {t: 1587691537139, v: 484091}, {t: 1587691552139, v: 484254}, {t: 1587691567139, v: 484479}, {t: 1587691582139, v: 484748}, {t: 1587691597139, v: 484978}, {t: 1587691612139, v: 485271}, {t: 1587691627139, v: 485488}, {t: 1587691642139, v: 485700}, 258 {t: 1587691657139, v: 485945}, {t: 1587691672139, v: 486228}, {t: 1587691687139, v: 486588}, {t: 1587691702139, v: 486691}, {t: 1587691717139, v: 486881}, {t: 1587691732139, v: 487046}, {t: 1587691747139, v: 487291}, {t: 1587691762177, v: 487410}, {t: 1587691777139, v: 487571}, {t: 1587691792139, v: 487799}, {t: 1587691807139, v: 488050}, 259 {t: 1587691822139, v: 488241}, {t: 1587691837139, v: 488424}, {t: 1587691852139, v: 488629}, {t: 1587691867139, v: 488875}, {t: 1587691882139, v: 489017}, {t: 1587691897139, v: 489254}, {t: 1587691912139, v: 489545}, {t: 1587691927139, v: 489778}, {t: 1587691942139, v: 489912}, {t: 1587691957139, v: 490084}, {t: 1587691972139, v: 490364}, 260 {t: 1587691987139, v: 490510}, {t: 1587692002139, v: 490744}, {t: 1587692017139, v: 490880}, {t: 1587692032139, v: 491025}, {t: 1587692047139, v: 491297}, {t: 1587692062155, v: 491557}, {t: 1587692077139, v: 491839}, {t: 1587692092139, v: 492065}, {t: 1587692107139, v: 492234}, {t: 1587692122139, v: 492526}, {t: 1587692137139, v: 492767}, 261 {t: 1587692152139, v: 492967}, {t: 1587692167139, v: 493218}, {t: 1587692182139, v: 493442}, {t: 1587692197139, v: 493647}, {t: 1587692212139, v: 493920}, {t: 1587692227139, v: 494170}, {t: 1587692242139, v: 494358}, {t: 1587692257139, v: 494632}, {t: 1587692272139, v: 494800}, {t: 1587692287139, v: 495026}, {t: 1587692302139, v: 495222}, 262 {t: 1587692317139, v: 495433}, {t: 1587692332139, v: 495677}, {t: 1587692347139, v: 495901}, {t: 1587692362139, v: 496107}, {t: 1587692377139, v: 496196}, {t: 1587692392139, v: 496245}, {t: 1587692407139, v: 496300}, {t: 1587692422159, v: 496365}, {t: 1587692437139, v: 496401}, {t: 1587692452139, v: 496452}, {t: 1587692467139, v: 496532}, 263 {t: 1587692542149, v: 496537}, {t: 1587692557139, v: 496633}, {t: 1587692572139, v: 496844}, {t: 1587692587139, v: 497040}, {t: 1587692602144, v: 497257}, {t: 1587692617139, v: 497522}, {t: 1587692632139, v: 497710}, {t: 1587692647139, v: 497938}, {t: 1587692662154, v: 498172}, {t: 1587692677139, v: 498459}, {t: 1587692692139, v: 498635}, 264 {t: 1587692707139, v: 498832}, {t: 1587692722139, v: 499014}, {t: 1587692737139, v: 499170}, {t: 1587692752139, v: 499338}, {t: 1587692767139, v: 499511}, {t: 1587692782149, v: 499719}, {t: 1587692797139, v: 499973}, {t: 1587692812139, v: 500189}, {t: 1587692827139, v: 500359}, {t: 1587692842139, v: 500517}, {t: 1587692857139, v: 500727}, 265 {t: 1587692872139, v: 500959}, {t: 1587692887139, v: 501178}, {t: 1587692902139, v: 501246}, {t: 1587692917153, v: 501404}, {t: 1587692932139, v: 501663}, {t: 1587692947139, v: 501850}, {t: 1587692962139, v: 502103}, {t: 1587692977155, v: 502280}, {t: 1587692992139, v: 502562}, {t: 1587693007139, v: 502742}, {t: 1587693022139, v: 502931}, 266 {t: 1587693037139, v: 503190}, {t: 1587693052139, v: 503428}, {t: 1587693067139, v: 503630}, {t: 1587693082139, v: 503873}, {t: 1587693097139, v: 504027}, {t: 1587693112139, v: 504179}, {t: 1587693127139, v: 504362}, {t: 1587693142139, v: 504590}, {t: 1587693157139, v: 504741}, {t: 1587693172139, v: 505056}, {t: 1587693187139, v: 505244}, 267 {t: 1587693202139, v: 505436}, {t: 1587693217139, v: 505635}, {t: 1587693232139, v: 505936}, {t: 1587693247155, v: 506088}, {t: 1587693262139, v: 506309}, {t: 1587693277139, v: 506524}, {t: 1587693292139, v: 506800}, {t: 1587693307139, v: 507010}, {t: 1587693322139, v: 507286}, {t: 1587693337139, v: 507530}, {t: 1587693352139, v: 507781}, 268 {t: 1587693367139, v: 507991}, {t: 1587693382139, v: 508310}, {t: 1587693397139, v: 508570}, {t: 1587693412139, v: 508770}, {t: 1587693427139, v: 508982}, {t: 1587693442163, v: 509274}, {t: 1587693457139, v: 509477}, {t: 1587693472139, v: 509713}, {t: 1587693487139, v: 509972}, {t: 1587693502139, v: 510182}, {t: 1587693517139, v: 510498}, 269 {t: 1587693532139, v: 510654}, {t: 1587693547139, v: 510859}, {t: 1587693562139, v: 511124}, {t: 1587693577139, v: 511314}, {t: 1587693592139, v: 511488}, 270 } 271 expectedRealSeriesWithStaleMarkerReplica1ForRate = []sample{ 272 {t: 1587690005791, v: 461968}, {t: 1587690020791, v: 462151}, {t: 1587690035797, v: 462336}, {t: 1587690050791, v: 462650}, {t: 1587690065791, v: 462813}, {t: 1587690080791, v: 462987}, {t: 1587690095791, v: 463095}, {t: 1587690110791, v: 463247}, {t: 1587690125791, v: 463440}, {t: 1587690140791, v: 463642}, {t: 1587690155791, v: 463811}, {t: 1587690170791, v: 464027}, 273 {t: 1587690185791, v: 464308}, {t: 1587690200791, v: 464514}, {t: 1587690215791, v: 464798}, {t: 1587690230791, v: 465018}, {t: 1587690245791, v: 465215}, {t: 1587690260813, v: 465431}, {t: 1587690275791, v: 465651}, {t: 1587690290791, v: 465870}, {t: 1587690305791, v: 466070}, {t: 1587690320792, v: 466248}, {t: 1587690335791, v: 466506}, {t: 1587690350791, v: 466766}, 274 {t: 1587690365791, v: 466970}, {t: 1587690380791, v: 467123}, {t: 1587690395791, v: 467265}, {t: 1587690410791, v: 467383}, {t: 1587690425791, v: 467629}, {t: 1587690440791, v: 467931}, {t: 1587690455791, v: 468097}, {t: 1587690470791, v: 468281}, {t: 1587690485791, v: 468477}, {t: 1587690500791, v: 468649}, {t: 1587690515791, v: 468867}, {t: 1587690530791, v: 469150}, 275 {t: 1587690545791, v: 469268}, {t: 1587690560791, v: 469488}, {t: 1587690575791, v: 469742}, {t: 1587690590791, v: 469951}, {t: 1587690605791, v: 470131}, {t: 1587690620791, v: 470337}, {t: 1587690635791, v: 470631}, {t: 1587690650791, v: 470832}, {t: 1587690665791, v: 471077}, {t: 1587690680791, v: 471311}, {t: 1587690695791, v: 471473}, {t: 1587690710791, v: 471728}, 276 {t: 1587690725791, v: 472002}, {t: 1587690740791, v: 472158}, {t: 1587690755791, v: 472329}, {t: 1587690770791, v: 472722}, {t: 1587690785791, v: 472925}, {t: 1587690800791, v: 473220}, {t: 1587690815791, v: 473460}, {t: 1587690830791, v: 473748}, {t: 1587690845791, v: 473968}, {t: 1587690860791, v: 474261}, {t: 1587690875791, v: 474418}, {t: 1587690890791, v: 474726}, 277 {t: 1587690905791, v: 474913}, {t: 1587690920791, v: 475031}, {t: 1587690935791, v: 475284}, {t: 1587690950791, v: 475563}, {t: 1587690965791, v: 475762}, {t: 1587690980791, v: 475945}, {t: 1587690995791, v: 476302}, {t: 1587691010791, v: 476501}, {t: 1587691025791, v: 476849}, {t: 1587691040800, v: 477020}, {t: 1587691055791, v: 477280}, {t: 1587691070791, v: 477549}, 278 {t: 1587691085791, v: 477758}, {t: 1587691100817, v: 477960}, {t: 1587691115791, v: 478261}, {t: 1587691130791, v: 478559}, {t: 1587691145791, v: 478704}, {t: 1587691160804, v: 478950}, {t: 1587691175791, v: 479173}, {t: 1587691190791, v: 479368}, {t: 1587691205791, v: 479625}, {t: 1587691220805, v: 479866}, {t: 1587691235791, v: 480008}, {t: 1587691250791, v: 480155}, 279 {t: 1587691265791, v: 480472}, {t: 1587691280811, v: 480598}, {t: 1587691295791, v: 480771}, {t: 1587691310791, v: 480996}, {t: 1587691325791, v: 481200}, {t: 1587691340803, v: 481381}, {t: 1587691355791, v: 481584}, {t: 1587691370791, v: 481759}, {t: 1587691385791, v: 482003}, {t: 1587691400803, v: 482189}, {t: 1587691415791, v: 482457}, {t: 1587691430791, v: 482623}, 280 {t: 1587691445791, v: 482768}, {t: 1587691460804, v: 483036}, {t: 1587691475791, v: 483322}, {t: 1587691490791, v: 483566}, {t: 1587691505791, v: 483709}, {t: 1587691520807, v: 483838}, {t: 1587691535791, v: 484091}, {t: 1587691550791, v: 484236}, {t: 1587691565791, v: 484454}, {t: 1587691580816, v: 484710}, {t: 1587691595791, v: 484978}, {t: 1587691610791, v: 485271}, 281 {t: 1587691625791, v: 485476}, {t: 1587691640792, v: 485640}, {t: 1587691655791, v: 485921}, {t: 1587691670791, v: 486201}, {t: 1587691685791, v: 486555}, {t: 1587691700791, v: 486691}, {t: 1587691715791, v: 486831}, {t: 1587691730791, v: 487033}, {t: 1587691745791, v: 487268}, {t: 1587691760803, v: 487370}, {t: 1587691775791, v: 487571}, {t: 1587691790791, v: 487787}, 282 {t: 1587691805791, v: 488036}, {t: 1587691820791, v: 488241}, {t: 1587691835791, v: 488411}, {t: 1587691850791, v: 488625}, {t: 1587691865791, v: 488868}, {t: 1587691880791, v: 489005}, {t: 1587691895791, v: 489237}, {t: 1587691910791, v: 489545}, {t: 1587691925791, v: 489750}, {t: 1587691940791, v: 489899}, {t: 1587691955791, v: 490048}, {t: 1587691970791, v: 490364}, 283 {t: 1587691985791, v: 490485}, {t: 1587692000791, v: 490722}, {t: 1587692015791, v: 490866}, {t: 1587692030791, v: 491025}, {t: 1587692045791, v: 491286}, {t: 1587692060816, v: 491543}, {t: 1587692075791, v: 491787}, {t: 1587692090791, v: 492065}, {t: 1587692105791, v: 492223}, {t: 1587692120816, v: 492501}, {t: 1587692135791, v: 492767}, {t: 1587692150791, v: 492955}, 284 {t: 1587692165791, v: 493194}, {t: 1587692180792, v: 493402}, {t: 1587692195791, v: 493647}, {t: 1587692210791, v: 493897}, {t: 1587692225791, v: 494117}, {t: 1587692240805, v: 494356}, {t: 1587692255791, v: 494620}, {t: 1587692270791, v: 494762}, {t: 1587692285791, v: 495001}, {t: 1587692300805, v: 495222}, {t: 1587692315791, v: 495393}, {t: 1587692330791, v: 495662}, 285 {t: 1587692345791, v: 495875}, {t: 1587692360801, v: 496082}, {t: 1587692375791, v: 496196}, {t: 1587692390791, v: 496245}, {t: 1587692405791, v: 496295}, {t: 1587692420791, v: 496365}, {t: 1587692435791, v: 496401}, {t: 1587692450791, v: 496452}, {t: 1587692465791, v: 496491}, {t: 1587692480791, v: 496544}, {t: 1587692555791, v: 496619}, {t: 1587692570791, v: 496852}, 286 {t: 1587692585791, v: 497052}, {t: 1587692600791, v: 497245}, {t: 1587692615791, v: 497529}, {t: 1587692630791, v: 497697}, {t: 1587692645791, v: 497909}, {t: 1587692660791, v: 498156}, {t: 1587692675803, v: 498466}, {t: 1587692690791, v: 498647}, {t: 1587692705791, v: 498805}, {t: 1587692720791, v: 499013}, {t: 1587692735805, v: 499169}, {t: 1587692750791, v: 499345}, 287 {t: 1587692765791, v: 499499}, {t: 1587692780791, v: 499731}, {t: 1587692795806, v: 499972}, {t: 1587692810791, v: 500201}, {t: 1587692825791, v: 500354}, {t: 1587692840791, v: 500512}, {t: 1587692855791, v: 500739}, {t: 1587692870791, v: 500958}, {t: 1587692885791, v: 501190}, {t: 1587692900791, v: 501233}, {t: 1587692915791, v: 501391}, {t: 1587692930791, v: 501649}, 288 {t: 1587692945791, v: 501853}, {t: 1587692960791, v: 502065}, {t: 1587692975791, v: 502239}, {t: 1587692990810, v: 502554}, {t: 1587693005791, v: 502754}, {t: 1587693020791, v: 502938}, {t: 1587693035791, v: 503141}, {t: 1587693050791, v: 503416}, {t: 1587693065791, v: 503642}, {t: 1587693080791, v: 503873}, {t: 1587693095791, v: 504014}, {t: 1587693110791, v: 504178}, 289 {t: 1587693125821, v: 504374}, {t: 1587693140791, v: 504578}, {t: 1587693155791, v: 504753}, {t: 1587693170791, v: 505043}, {t: 1587693185791, v: 505232}, {t: 1587693200791, v: 505437}, {t: 1587693215791, v: 505596}, {t: 1587693230791, v: 505923}, {t: 1587693245791, v: 506088}, {t: 1587693260791, v: 506307}, {t: 1587693275791, v: 506518}, {t: 1587693290791, v: 506786}, 290 {t: 1587693305791, v: 507008}, {t: 1587693320803, v: 507260}, {t: 1587693335791, v: 507519}, {t: 1587693350791, v: 507776}, {t: 1587693365791, v: 508003}, {t: 1587693380791, v: 508322}, {t: 1587693395804, v: 508551}, {t: 1587693410791, v: 508750}, {t: 1587693425791, v: 508994}, {t: 1587693440791, v: 509237}, {t: 1587693455791, v: 509452}, {t: 1587693470791, v: 509702}, 291 {t: 1587693485791, v: 509971}, {t: 1587693500791, v: 510147}, {t: 1587693515791, v: 510471}, {t: 1587693530816, v: 510666}, {t: 1587693545791, v: 510871}, {t: 1587693560791, v: 511123}, {t: 1587693575791, v: 511303}, {t: 1587693590791, v: 511500}, 292 } 293 expectedRealSeriesWithStaleMarkerDeduplicatedForRate = []sample{ 294 {t: 1587690005791, v: 461968}, {t: 1587690020791, v: 462151}, {t: 1587690035797, v: 462336}, {t: 1587690050791, v: 462650}, {t: 1587690065791, v: 462813}, {t: 1587690080791, v: 462987}, {t: 1587690095791, v: 463095}, {t: 1587690110791, v: 463247}, {t: 1587690125791, v: 463440}, {t: 1587690140791, v: 463642}, {t: 1587690155791, v: 463811}, {t: 1587690170791, v: 464027}, 295 {t: 1587690185791, v: 464308}, {t: 1587690200791, v: 464514}, {t: 1587690215791, v: 464798}, {t: 1587690230791, v: 465018}, {t: 1587690245791, v: 465215}, {t: 1587690260813, v: 465431}, {t: 1587690275791, v: 465651}, {t: 1587690290791, v: 465870}, {t: 1587690305791, v: 466070}, {t: 1587690320792, v: 466248}, {t: 1587690335791, v: 466506}, {t: 1587690350791, v: 466766}, 296 {t: 1587690365791, v: 466970}, {t: 1587690380791, v: 467123}, {t: 1587690395791, v: 467265}, {t: 1587690410791, v: 467383}, {t: 1587690425791, v: 467629}, {t: 1587690440791, v: 467931}, {t: 1587690455791, v: 468097}, {t: 1587690470791, v: 468281}, {t: 1587690485791, v: 468477}, {t: 1587690500791, v: 468649}, {t: 1587690515791, v: 468867}, {t: 1587690530791, v: 469150}, 297 {t: 1587690545791, v: 469268}, {t: 1587690560791, v: 469488}, {t: 1587690575791, v: 469742}, {t: 1587690590791, v: 469951}, {t: 1587690605791, v: 470131}, {t: 1587690620791, v: 470337}, {t: 1587690635791, v: 470631}, {t: 1587690650791, v: 470832}, {t: 1587690665791, v: 471077}, {t: 1587690680791, v: 471311}, {t: 1587690695791, v: 471473}, {t: 1587690710791, v: 471728}, 298 {t: 1587690725791, v: 472002}, {t: 1587690740791, v: 472158}, {t: 1587690755791, v: 472329}, {t: 1587690770791, v: 472722}, {t: 1587690785791, v: 472925}, {t: 1587690800791, v: 473220}, {t: 1587690815791, v: 473460}, {t: 1587690830791, v: 473748}, {t: 1587690845791, v: 473968}, {t: 1587690860791, v: 474261}, {t: 1587690875791, v: 474418}, {t: 1587690890791, v: 474726}, 299 {t: 1587690905791, v: 474913}, {t: 1587690920791, v: 475031}, {t: 1587690935791, v: 475284}, {t: 1587690950791, v: 475563}, {t: 1587690965791, v: 475762}, {t: 1587690980791, v: 475945}, {t: 1587690995791, v: 476302}, {t: 1587691010791, v: 476501}, {t: 1587691025791, v: 476849}, {t: 1587691040800, v: 477020}, {t: 1587691055791, v: 477280}, {t: 1587691070791, v: 477549}, 300 {t: 1587691085791, v: 477758}, {t: 1587691100817, v: 477960}, {t: 1587691115791, v: 478261}, {t: 1587691130791, v: 478559}, {t: 1587691145791, v: 478704}, {t: 1587691160804, v: 478950}, {t: 1587691175791, v: 479173}, {t: 1587691190791, v: 479368}, {t: 1587691205791, v: 479625}, {t: 1587691220805, v: 479866}, {t: 1587691235791, v: 480008}, {t: 1587691250791, v: 480155}, 301 {t: 1587691265791, v: 480472}, {t: 1587691280811, v: 480598}, {t: 1587691295791, v: 480771}, {t: 1587691310791, v: 480996}, {t: 1587691325791, v: 481200}, {t: 1587691340803, v: 481381}, {t: 1587691355791, v: 481584}, {t: 1587691370791, v: 481759}, {t: 1587691385791, v: 482003}, {t: 1587691400803, v: 482189}, {t: 1587691415791, v: 482457}, {t: 1587691430791, v: 482623}, 302 {t: 1587691445791, v: 482768}, {t: 1587691460804, v: 483036}, {t: 1587691475791, v: 483322}, {t: 1587691490791, v: 483566}, {t: 1587691505791, v: 483709}, {t: 1587691520807, v: 483838}, {t: 1587691535791, v: 484091}, {t: 1587691550791, v: 484236}, {t: 1587691565791, v: 484454}, {t: 1587691580816, v: 484710}, {t: 1587691595791, v: 484978}, {t: 1587691610791, v: 485271}, 303 {t: 1587691625791, v: 485476}, {t: 1587691640792, v: 485640}, {t: 1587691655791, v: 485921}, {t: 1587691670791, v: 486201}, {t: 1587691685791, v: 486555}, {t: 1587691700791, v: 486691}, {t: 1587691715791, v: 486831}, {t: 1587691730791, v: 487033}, {t: 1587691745791, v: 487268}, {t: 1587691760803, v: 487370}, {t: 1587691775791, v: 487571}, {t: 1587691790791, v: 487787}, 304 {t: 1587691805791, v: 488036}, {t: 1587691820791, v: 488241}, {t: 1587691835791, v: 488411}, {t: 1587691850791, v: 488625}, {t: 1587691865791, v: 488868}, {t: 1587691880791, v: 489005}, {t: 1587691895791, v: 489237}, {t: 1587691910791, v: 489545}, {t: 1587691925791, v: 489750}, {t: 1587691940791, v: 489899}, {t: 1587691955791, v: 490048}, {t: 1587691970791, v: 490364}, 305 {t: 1587691985791, v: 490485}, {t: 1587692000791, v: 490722}, {t: 1587692015791, v: 490866}, {t: 1587692030791, v: 491025}, {t: 1587692045791, v: 491286}, {t: 1587692060816, v: 491543}, {t: 1587692075791, v: 491787}, {t: 1587692090791, v: 492065}, {t: 1587692105791, v: 492223}, {t: 1587692120816, v: 492501}, {t: 1587692135791, v: 492767}, {t: 1587692150791, v: 492955}, 306 {t: 1587692165791, v: 493194}, {t: 1587692180792, v: 493402}, {t: 1587692195791, v: 493647}, {t: 1587692210791, v: 493897}, {t: 1587692225791, v: 494117}, {t: 1587692240805, v: 494356}, {t: 1587692255791, v: 494620}, {t: 1587692270791, v: 494762}, {t: 1587692285791, v: 495001}, {t: 1587692300805, v: 495222}, {t: 1587692315791, v: 495393}, {t: 1587692330791, v: 495662}, 307 {t: 1587692345791, v: 495875}, {t: 1587692360801, v: 496082}, {t: 1587692375791, v: 496196}, {t: 1587692390791, v: 496245}, {t: 1587692405791, v: 496295}, {t: 1587692420791, v: 496365}, {t: 1587692435791, v: 496401}, {t: 1587692450791, v: 496452}, {t: 1587692465791, v: 496491}, {t: 1587692480791, v: 496544}, {t: 1587692542149, v: 496544}, {t: 1587692557139, v: 496640}, 308 {t: 1587692572139, v: 496851}, {t: 1587692587139, v: 497047}, {t: 1587692602144, v: 497264}, {t: 1587692617139, v: 497529}, {t: 1587692632139, v: 497717}, {t: 1587692647139, v: 497945}, {t: 1587692662154, v: 498179}, {t: 1587692677139, v: 498466}, {t: 1587692692139, v: 498642}, {t: 1587692707139, v: 498839}, {t: 1587692722139, v: 499021}, {t: 1587692737139, v: 499177}, 309 {t: 1587692752139, v: 499345}, {t: 1587692767139, v: 499518}, {t: 1587692782149, v: 499726}, {t: 1587692797139, v: 499980}, {t: 1587692812139, v: 500196}, {t: 1587692827139, v: 500366}, {t: 1587692842139, v: 500524}, {t: 1587692857139, v: 500734}, {t: 1587692872139, v: 500966}, {t: 1587692887139, v: 501185}, {t: 1587692902139, v: 501253}, {t: 1587692917153, v: 501411}, 310 {t: 1587692932139, v: 501670}, {t: 1587692947139, v: 501857}, {t: 1587692962139, v: 502110}, {t: 1587692977155, v: 502287}, {t: 1587692992139, v: 502569}, {t: 1587693007139, v: 502749}, {t: 1587693022139, v: 502938}, {t: 1587693037139, v: 503197}, {t: 1587693052139, v: 503435}, {t: 1587693067139, v: 503637}, {t: 1587693082139, v: 503880}, {t: 1587693097139, v: 504034}, 311 {t: 1587693112139, v: 504186}, {t: 1587693127139, v: 504369}, {t: 1587693142139, v: 504597}, {t: 1587693157139, v: 504748}, {t: 1587693172139, v: 505063}, {t: 1587693187139, v: 505251}, {t: 1587693202139, v: 505443}, {t: 1587693217139, v: 505642}, {t: 1587693232139, v: 505943}, {t: 1587693247155, v: 506095}, {t: 1587693262139, v: 506316}, {t: 1587693277139, v: 506531}, 312 {t: 1587693292139, v: 506807}, {t: 1587693307139, v: 507017}, {t: 1587693322139, v: 507293}, {t: 1587693337139, v: 507537}, {t: 1587693352139, v: 507788}, {t: 1587693367139, v: 507998}, {t: 1587693382139, v: 508317}, {t: 1587693397139, v: 508577}, {t: 1587693412139, v: 508777}, {t: 1587693427139, v: 508989}, {t: 1587693442163, v: 509281}, {t: 1587693457139, v: 509484}, 313 {t: 1587693472139, v: 509720}, {t: 1587693487139, v: 509979}, {t: 1587693502139, v: 510189}, {t: 1587693517139, v: 510505}, {t: 1587693532139, v: 510661}, {t: 1587693547139, v: 510866}, {t: 1587693562139, v: 511131}, {t: 1587693577139, v: 511321}, {t: 1587693592139, v: 511495}, 314 } 315 ) 316 317 type series struct { 318 lset labels.Labels 319 samples []sample 320 } 321 322 func (s series) Labels() labels.Labels { return s.lset } 323 func (s series) Iterator() chunkenc.Iterator { 324 return newMockedSeriesIterator(s.samples) 325 } 326 327 // TestQuerier_Select_AfterPromQL tests expected results with and without deduplication after passing all data to promql. 328 // To test with real data: 329 // Collect the expected results from Prometheus or Thanos through "/api/v1/query_range" and save to a file. 330 // Collect raw data to be used for local storage: 331 // 332 // scripts/insecure_grpcurl_series.sh querierGrpcIP:port '[{"name":"type","value":"current"},{"name":"_id","value":"xxx"}]' 1597823000000 1597824600000 > localStorage.json 333 // Remove all white space from the file and put each series in a new line. 334 // When collecting the raw data mint should be Prometheus query time minus the default look back delta(default is 5min or 300000ms) 335 // For example if the Prometheus query mint is 1597823700000 the grpccurl query mint should be 1597823400000. 336 // 337 // This is because when promql displays data for a given range it looks back 5min before the requested time window. 338 func TestQuerier_Select_AfterPromQL(t *testing.T) { 339 logger := log.NewLogfmtLogger(os.Stderr) 340 341 for _, tcase := range []struct { 342 name string 343 storeAPI *store.ProxyStore 344 replicaLabels []string // Replica label groups chunks by the label value and strips it from the final result. 345 hints *storage.SelectHints 346 equivalentQuery string 347 lookbackDelta time.Duration 348 expected []series 349 expectedAfterDedup series 350 expectedWarning string 351 }{ 352 { 353 // Regression test 1 against https://github.com/thanos-io/thanos/issues/2890. 354 name: "when switching replicas don't miss samples when set with a big enough lookback delta", 355 storeAPI: newProxyStore(func() storepb.StoreServer { 356 s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2890-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) 357 testutil.Ok(t, err) 358 return s 359 }()), 360 equivalentQuery: `cluster_version{}`, 361 replicaLabels: []string{"replica"}, 362 hints: &storage.SelectHints{ 363 Start: 1598471700000, 364 End: 1598472600000, 365 Step: 3000, 366 }, 367 lookbackDelta: 15 * time.Minute, 368 expected: jsonToSeries(t, "testdata/issue2890-expected.json"), 369 expectedAfterDedup: jsonToSeries(t, "testdata/issue2890-expected-dedup.json")[0], 370 }, 371 } { 372 373 t.Run(tcase.name, func(t *testing.T) { 374 timeout := 5 * time.Minute 375 e := promql.NewEngine(promql.EngineOpts{ 376 Logger: logger, 377 Timeout: timeout, 378 MaxSamples: math.MaxInt64, 379 LookbackDelta: tcase.lookbackDelta, 380 }) 381 for _, sc := range []struct { 382 dedup bool 383 expected []series 384 }{ 385 {dedup: false, expected: tcase.expected}, 386 {dedup: true, expected: []series{tcase.expectedAfterDedup}}, 387 } { 388 389 resolution := time.Duration(tcase.hints.Step) * time.Millisecond 390 t.Run(fmt.Sprintf("dedup=%v, resolution=%v", sc.dedup, resolution.String()), func(t *testing.T) { 391 var actual []series 392 // Boostrap a local store and pass the data through promql. 393 { 394 g := gate.New(2) 395 mq := &mockedQueryable{ 396 Creator: func(mint, maxt int64) storage.Querier { 397 return newQuerier(context.Background(), nil, mint, maxt, tcase.replicaLabels, nil, tcase.storeAPI, sc.dedup, 0, true, false, false, g, timeout, nil, NoopSeriesStatsReporter) 398 }, 399 } 400 t.Cleanup(func() { 401 testutil.Ok(t, mq.Close()) 402 }) 403 q, err := e.NewRangeQuery(context.Background(), mq, promql.NewPrometheusQueryOpts(false, 0), tcase.equivalentQuery, timestamp.Time(tcase.hints.Start), timestamp.Time(tcase.hints.End), resolution) 404 testutil.Ok(t, err) 405 t.Cleanup(q.Close) 406 res := q.Exec(context.Background()) 407 testutil.Ok(t, res.Err) 408 actual = promqlResToSeries(res) 409 if tcase.expectedWarning != "" { 410 warns := res.Warnings 411 testutil.Assert(t, len(warns) == 1, "expected only single warnings") 412 testutil.Equals(t, tcase.expectedWarning, warns[0].Error()) 413 } 414 } 415 416 testutil.Equals(t, sc.expected, actual, "promql result doesn't match the expected output") 417 if sc.dedup { 418 testutil.Assert(t, len(actual) == 1, "expected only single response, subqueries?") 419 } 420 }) 421 } 422 }) 423 } 424 } 425 426 func TestQuerier_Select(t *testing.T) { 427 logger := log.NewLogfmtLogger(os.Stderr) 428 429 for _, tcase := range []struct { 430 name string 431 storeEndpoints []storepb.StoreServer 432 433 mint, maxt int64 434 matchers []*labels.Matcher 435 replicaLabels []string 436 hints *storage.SelectHints 437 equivalentQuery string 438 439 expected []series 440 expectedAfterDedup []series 441 expectedWarning string 442 }{ 443 { 444 name: "select overlapping data with partial error", 445 storeEndpoints: []storepb.StoreServer{ 446 &testStoreServer{ 447 resps: []*storepb.SeriesResponse{ 448 storeSeriesResponse(t, labels.FromStrings("a", "a"), []sample{{0, 0}, {2, 1}, {3, 2}}), 449 storepb.NewWarnSeriesResponse(errors.New("partial error")), 450 storeSeriesResponse(t, labels.FromStrings("a", "a"), []sample{{5, 5}, {6, 6}, {7, 7}}), 451 storeSeriesResponse(t, labels.FromStrings("a", "a"), []sample{{5, 5}, {6, 66}}), 452 storeSeriesResponse(t, labels.FromStrings("a", "b"), []sample{{2, 2}, {3, 3}, {4, 4}}, []sample{{1, 1}, {2, 2}, {3, 3}}), 453 storeSeriesResponse(t, labels.FromStrings("a", "c"), []sample{{100, 1}, {300, 3}, {400, 4}}), 454 }, 455 }, 456 }, 457 mint: 1, maxt: 300, 458 replicaLabels: []string{"a"}, 459 equivalentQuery: `{a=~"a|b|c"}`, 460 matchers: []*labels.Matcher{{ 461 Value: "a|b|c", 462 Name: "a", 463 Type: labels.MatchRegexp, 464 }}, 465 expected: []series{ 466 { 467 lset: labels.FromStrings("a", "a"), 468 samples: []sample{{2, 1}, {3, 2}, {5, 5}, {6, 66}, {7, 7}}, 469 }, 470 { 471 lset: labels.FromStrings("a", "b"), 472 samples: []sample{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, 473 }, 474 { 475 lset: labels.FromStrings("a", "c"), 476 samples: []sample{{100, 1}, {300, 3}}, 477 }, 478 }, 479 expectedAfterDedup: []series{{ 480 lset: nil, 481 // We don't expect correctness here, it's just random non-replica data. 482 samples: []sample{{1, 1}, {2, 2}, {3, 3}, {5, 5}, {6, 6}, {7, 7}}, 483 }}, 484 expectedWarning: "partial error", 485 }, 486 { 487 name: "realistic data with stale marker", 488 storeEndpoints: []storepb.StoreServer{func() storepb.StoreServer { 489 s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) 490 testutil.Ok(t, err) 491 return s 492 }()}, 493 mint: realSeriesWithStaleMarkerMint, maxt: realSeriesWithStaleMarkerMaxt, 494 replicaLabels: []string{"replica"}, 495 matchers: []*labels.Matcher{{ 496 Value: "gitlab_transaction_cache_read_hit_count_total", 497 Name: "__name__", 498 Type: labels.MatchEqual, 499 }}, 500 equivalentQuery: `gitlab_transaction_cache_read_hit_count_total{}`, 501 502 expected: []series{ 503 { 504 lset: labels.FromStrings( 505 "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", 506 "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", 507 "gcp", "region", "us-east", "replica", "01", "shard", "default", "stage", "main", "tier", "sv", "type", "web", 508 ), 509 samples: expectedRealSeriesWithStaleMarkerReplica0, 510 }, 511 { 512 lset: labels.FromStrings( 513 "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", 514 "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", 515 "gcp", "region", "us-east", "replica", "02", "shard", "default", "stage", "main", "tier", "sv", "type", "web", 516 ), 517 samples: expectedRealSeriesWithStaleMarkerReplica1, 518 }, 519 }, 520 expectedAfterDedup: []series{{ 521 lset: labels.FromStrings( 522 // No replica label anymore. 523 "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", 524 "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", 525 "gcp", "region", "us-east", "shard", "default", "stage", "main", "tier", "sv", "type", "web", 526 ), 527 samples: expectedRealSeriesWithStaleMarkerDeduplicated, 528 }}, 529 }, 530 { 531 name: "realistic data with stale marker with 100000 step", 532 storeEndpoints: []storepb.StoreServer{func() storepb.StoreServer { 533 s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) 534 testutil.Ok(t, err) 535 return s 536 }()}, 537 mint: realSeriesWithStaleMarkerMint, maxt: realSeriesWithStaleMarkerMaxt, 538 replicaLabels: []string{"replica"}, 539 matchers: []*labels.Matcher{{ 540 Value: "gitlab_transaction_cache_read_hit_count_total", 541 Name: "__name__", 542 Type: labels.MatchEqual, 543 }}, 544 hints: &storage.SelectHints{ 545 Start: realSeriesWithStaleMarkerMint, 546 End: realSeriesWithStaleMarkerMaxt, 547 Step: 100000, // Should not matter. 548 }, 549 equivalentQuery: `gitlab_transaction_cache_read_hit_count_total{}`, 550 551 expected: []series{ 552 { 553 lset: labels.FromStrings( 554 "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", 555 "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", 556 "gcp", "region", "us-east", "replica", "01", "shard", "default", "stage", "main", "tier", "sv", "type", "web", 557 ), 558 samples: expectedRealSeriesWithStaleMarkerReplica0, 559 }, 560 { 561 lset: labels.FromStrings( 562 "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", 563 "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", 564 "gcp", "region", "us-east", "replica", "02", "shard", "default", "stage", "main", "tier", "sv", "type", "web", 565 ), 566 samples: expectedRealSeriesWithStaleMarkerReplica1, 567 }, 568 }, 569 expectedAfterDedup: []series{{ 570 lset: labels.FromStrings( 571 // No replica label anymore. 572 "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", 573 "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", 574 "gcp", "region", "us-east", "shard", "default", "stage", "main", "tier", "sv", "type", "web", 575 ), 576 samples: expectedRealSeriesWithStaleMarkerDeduplicated, 577 }}, 578 }, 579 { 580 // Regression test against https://github.com/thanos-io/thanos/issues/2401. 581 // Thanks to @Superq and GitLab for real data reproducing this. 582 name: "realistic data with stale marker with hints rate function", 583 storeEndpoints: []storepb.StoreServer{func() storepb.StoreServer { 584 s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) 585 testutil.Ok(t, err) 586 return s 587 }()}, 588 mint: realSeriesWithStaleMarkerMint, maxt: realSeriesWithStaleMarkerMaxt, 589 replicaLabels: []string{"replica"}, 590 matchers: []*labels.Matcher{{ 591 Value: "gitlab_transaction_cache_read_hit_count_total", 592 Name: "__name__", 593 Type: labels.MatchEqual, 594 }}, 595 hints: &storage.SelectHints{ 596 Start: realSeriesWithStaleMarkerMint, 597 End: realSeriesWithStaleMarkerMaxt, 598 // Rate triggers special case of extra downsample.CounterSeriesIterator. 599 Func: "rate", 600 }, 601 equivalentQuery: `rate(gitlab_transaction_cache_read_hit_count_total[5m])`, 602 603 expected: []series{ 604 { 605 lset: labels.FromStrings( 606 "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", 607 "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", 608 "gcp", "region", "us-east", "replica", "01", "shard", "default", "stage", "main", "tier", "sv", "type", "web", 609 ), 610 samples: expectedRealSeriesWithStaleMarkerReplica0ForRate, 611 }, 612 { 613 lset: labels.FromStrings( 614 "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", 615 "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", 616 "gcp", "region", "us-east", "replica", "02", "shard", "default", "stage", "main", "tier", "sv", "type", "web", 617 ), 618 samples: expectedRealSeriesWithStaleMarkerReplica1ForRate, 619 }, 620 }, 621 expectedAfterDedup: []series{{ 622 lset: labels.FromStrings( 623 "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", 624 "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", 625 "gcp", "region", "us-east", "shard", "default", "stage", "main", "tier", "sv", "type", "web", 626 ), 627 samples: expectedRealSeriesWithStaleMarkerDeduplicatedForRate, 628 }}, 629 }, 630 // Tests with proxy (integration test with store.ProxyStore). 631 { 632 name: "select with proxied Store APIs that does not support without replica label", 633 storeEndpoints: []storepb.StoreServer{ 634 &testStoreServer{ 635 resps: []*storepb.SeriesResponse{ 636 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "1", "w", "1"), []sample{{0, 0}, {2, 1}, {3, 2}}), 637 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "1", "w", "1"), []sample{{5, 5}, {6, 6}, {7, 7}}), 638 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "1", "x", "1"), []sample{{2, 2}, {3, 3}, {4, 4}}, []sample{{1, 1}, {2, 2}, {3, 3}}), 639 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "1", "x", "1"), []sample{{100, 1}, {300, 3}, {400, 4}}), 640 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "2", "w", "1"), []sample{{5, 5}, {7, 7}}), 641 }, 642 }, 643 &testStoreServer{ 644 resps: []*storepb.SeriesResponse{ 645 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "2", "w", "1"), []sample{{2, 1}}), 646 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "2", "w", "1"), []sample{{5, 5}, {6, 6}, {7, 7}}), 647 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "2", "x", "2"), []sample{{10, 10}, {30, 30}, {40, 40}}), 648 }, 649 }, 650 }, 651 mint: 1, maxt: 300, 652 replicaLabels: []string{"r"}, 653 equivalentQuery: `{a=~"1"}`, 654 matchers: []*labels.Matcher{{Name: "a", Value: "1", Type: labels.MatchRegexp}}, 655 expected: []series{ 656 { 657 lset: labels.FromStrings("a", "1", "r", "1", "w", "1"), 658 samples: []sample{{2, 1}, {3, 2}, {5, 5}, {6, 6}, {7, 7}}, 659 }, 660 { 661 lset: labels.FromStrings("a", "1", "r", "1", "x", "1"), 662 samples: []sample{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {100, 1}, {300, 3}}, 663 }, 664 { 665 lset: labels.FromStrings("a", "1", "r", "2", "w", "1"), 666 samples: []sample{{2, 1}, {5, 5}, {6, 6}, {7, 7}}, 667 }, 668 { 669 lset: labels.FromStrings("a", "1", "r", "2", "x", "2"), 670 samples: []sample{{10, 10}, {30, 30}, {40, 40}}, 671 }, 672 }, 673 expectedAfterDedup: []series{ 674 { 675 lset: labels.FromStrings("a", "1", "w", "1"), 676 // We don't expect correctness here, it's just random non-replica data. 677 samples: []sample{{2, 1}, {3, 2}, {5, 5}, {6, 6}, {7, 7}}, 678 }, 679 { 680 lset: labels.FromStrings("a", "1", "x", "1"), 681 // We don't expect correctness here, it's just random non-replica data. 682 samples: []sample{{1, 1}, {2, 2}, {3, 3}, {100, 1}, {300, 3}}, 683 }, 684 { 685 lset: labels.FromStrings("a", "1", "x", "2"), 686 // We don't expect correctness here, it's just random non-replica data. 687 samples: []sample{{10, 10}, {30, 30}, {40, 40}}, 688 }, 689 }, 690 }, 691 { 692 name: "select with proxied Store APIs with some stores supporting without replica labels feature", 693 storeEndpoints: []storepb.StoreServer{ 694 &testStoreServer{ 695 resps: []*storepb.SeriesResponse{ 696 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "1", "w", "1"), []sample{{0, 0}, {2, 1}, {3, 2}}), 697 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "1", "w", "1"), []sample{{5, 5}, {6, 6}, {7, 7}}), 698 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "1", "x", "1"), []sample{{2, 2}, {3, 3}, {4, 4}}, []sample{{1, 1}, {2, 2}, {3, 3}}), 699 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "1", "x", "1"), []sample{{100, 1}, {300, 3}, {400, 4}}), 700 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "2", "w", "1"), []sample{{5, 5}, {7, 7}}), 701 }, 702 respsWithoutReplicaLabels: []*storepb.SeriesResponse{ 703 storeSeriesResponse(t, labels.FromStrings("a", "1", "w", "1"), []sample{{5, 5}, {7, 7}}), 704 storeSeriesResponse(t, labels.FromStrings("a", "1", "w", "1"), []sample{{0, 0}, {2, 1}, {3, 2}}), 705 storeSeriesResponse(t, labels.FromStrings("a", "1", "w", "1"), []sample{{5, 5}, {6, 6}, {7, 7}}), 706 storeSeriesResponse(t, labels.FromStrings("a", "1", "x", "1"), []sample{{2, 2}, {3, 3}, {4, 4}}, []sample{{1, 1}, {2, 2}, {3, 3}}), 707 storeSeriesResponse(t, labels.FromStrings("a", "1", "x", "1"), []sample{{100, 1}, {300, 3}, {400, 4}}), 708 }, 709 }, 710 &testStoreServer{ 711 resps: []*storepb.SeriesResponse{ 712 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "2", "w", "1"), []sample{{2, 1}}), 713 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "2", "w", "1"), []sample{{5, 5}, {6, 6}, {7, 7}}), 714 storeSeriesResponse(t, labels.FromStrings("a", "1", "r", "2", "x", "2"), []sample{{10, 10}, {30, 30}, {40, 40}}), 715 }, 716 }, 717 }, 718 mint: 1, maxt: 300, 719 replicaLabels: []string{"r"}, 720 equivalentQuery: `{a=~"1"}`, 721 matchers: []*labels.Matcher{{Name: "a", Value: "1", Type: labels.MatchRegexp}}, 722 expected: []series{ 723 { 724 lset: labels.FromStrings("a", "1", "r", "1", "w", "1"), 725 samples: []sample{{2, 1}, {3, 2}, {5, 5}, {6, 6}, {7, 7}}, 726 }, 727 { 728 lset: labels.FromStrings("a", "1", "r", "1", "x", "1"), 729 samples: []sample{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {100, 1}, {300, 3}}, 730 }, 731 { 732 lset: labels.FromStrings("a", "1", "r", "2", "w", "1"), 733 samples: []sample{{2, 1}, {5, 5}, {6, 6}, {7, 7}}, 734 }, 735 { 736 lset: labels.FromStrings("a", "1", "r", "2", "x", "2"), 737 samples: []sample{{10, 10}, {30, 30}, {40, 40}}, 738 }, 739 }, 740 expectedAfterDedup: []series{ 741 { 742 lset: labels.FromStrings("a", "1", "w", "1"), 743 // We don't expect correctness here, it's just random non-replica data. 744 samples: []sample{{2, 1}, {3, 2}, {5, 5}, {6, 6}, {7, 7}}, 745 }, 746 { 747 lset: labels.FromStrings("a", "1", "x", "1"), 748 // We don't expect correctness here, it's just random non-replica data. 749 samples: []sample{{1, 1}, {2, 2}, {3, 3}, {100, 1}, {300, 3}}, 750 }, 751 { 752 lset: labels.FromStrings("a", "1", "x", "2"), 753 // We don't expect correctness here, it's just random non-replica data. 754 samples: []sample{{10, 10}, {30, 30}, {40, 40}}, 755 }, 756 }, 757 }, 758 } { 759 timeout := 5 * time.Second 760 e := promql.NewEngine(promql.EngineOpts{ 761 Logger: logger, 762 Timeout: timeout, 763 MaxSamples: math.MaxInt64, 764 }) 765 766 t.Run(tcase.name, func(t *testing.T) { 767 for _, sc := range []struct { 768 dedup bool 769 expected []series 770 }{ 771 {dedup: false, expected: tcase.expected}, 772 {dedup: true, expected: tcase.expectedAfterDedup}, 773 } { 774 g := gate.New(2) 775 q := newQuerier( 776 context.Background(), 777 nil, 778 tcase.mint, 779 tcase.maxt, 780 tcase.replicaLabels, 781 nil, 782 newProxyStore(tcase.storeEndpoints...), 783 sc.dedup, 784 0, 785 true, 786 false, 787 false, 788 g, 789 timeout, 790 nil, 791 NoopSeriesStatsReporter, 792 ) 793 t.Cleanup(func() { testutil.Ok(t, q.Close()) }) 794 795 t.Run(fmt.Sprintf("dedup=%v", sc.dedup), func(t *testing.T) { 796 t.Run("querier.Select", func(t *testing.T) { 797 res := q.Select(false, tcase.hints, tcase.matchers...) 798 testSelectResponse(t, sc.expected, res) 799 800 if tcase.expectedWarning != "" { 801 w := res.Warnings() 802 testutil.Equals(t, 1, len(w)) 803 testutil.Equals(t, tcase.expectedWarning, w[0].Error()) 804 } 805 }) 806 // Integration test: Make sure the PromQL would select exactly the same. 807 t.Run("through PromQL with 100s step", func(t *testing.T) { 808 catcher := &querierResponseCatcher{t: t, Querier: q} 809 q, err := e.NewRangeQuery(context.Background(), &mockedQueryable{querier: catcher}, promql.NewPrometheusQueryOpts(false, 0), tcase.equivalentQuery, timestamp.Time(tcase.mint), timestamp.Time(tcase.maxt), 100*time.Second) 810 testutil.Ok(t, err) 811 t.Cleanup(q.Close) 812 813 r := q.Exec(context.Background()) 814 testutil.Ok(t, r.Err) 815 816 testSelectResponse(t, sc.expected, catcher.resp[0]) 817 818 warns := catcher.warns() 819 // We don't care about anything else, all should be recorded. 820 testutil.Assert(t, len(warns) == 1, "expected only single warnings") 821 testutil.Assert(t, len(catcher.resp) == 1, "expected only single response, subqueries?") 822 823 w := warns[0] 824 if tcase.expectedWarning != "" { 825 testutil.Equals(t, 1, len(w)) 826 testutil.Equals(t, tcase.expectedWarning, w[0].Error()) 827 } 828 }) 829 }) 830 } 831 }) 832 } 833 } 834 835 func newProxyStore(storeAPIs ...storepb.StoreServer) *store.ProxyStore { 836 cls := make([]store.Client, len(storeAPIs)) 837 for i, s := range storeAPIs { 838 var withoutReplicaLabelsEnabled bool 839 if srv, ok := s.(*testStoreServer); ok { 840 withoutReplicaLabelsEnabled = len(srv.respsWithoutReplicaLabels) > 0 841 } 842 cls[i] = &storetestutil.TestClient{ 843 Name: fmt.Sprintf("%v", i), 844 StoreClient: storepb.ServerAsClient(s, 0), 845 MinTime: math.MinInt64, MaxTime: math.MaxInt64, 846 WithoutReplicaLabelsEnabled: withoutReplicaLabelsEnabled, 847 } 848 } 849 850 return store.NewProxyStore( 851 nil, 852 nil, 853 func() []store.Client { return cls }, 854 component.Query, 855 nil, 856 0, 857 store.EagerRetrieval, 858 ) 859 } 860 861 var emptyLabelsSameAsNotAllocatedLabels = cmp.Transformer("", func(l labels.Labels) labels.Labels { 862 if len(l) == 0 { 863 return labels.Labels(nil) 864 } 865 return l 866 }) 867 868 func testSelectResponse(t *testing.T, expected []series, res storage.SeriesSet) { 869 var series []storage.Series 870 // Use it as PromQL would do, first gather all series. 871 for res.Next() { 872 series = append(series, res.At()) 873 } 874 testutil.Ok(t, res.Err()) 875 testutil.Equals(t, len(expected), len(series), "got %v series", func() string { 876 var ret []string 877 for _, s := range series { 878 ret = append(ret, s.Labels().String()) 879 } 880 return strings.Join(ret, ",") 881 }()) 882 883 for i, s := range series { 884 testutil.WithGoCmp(emptyLabelsSameAsNotAllocatedLabels).Equals(t, expected[i].lset, s.Labels()) 885 samples := expandSeries(t, s.Iterator(nil)) 886 expectedCpy := make([]sample, 0, len(expected[i].samples)) 887 for _, s := range expected[i].samples { 888 v := s.v 889 if value.IsStaleNaN(v) { 890 // Nan != Nan, so substitute for another value. 891 // This is required for testutil.Equals to work deterministically. 892 v = hackyStaleMarker 893 } 894 expectedCpy = append(expectedCpy, sample{t: s.t, v: v}) 895 } 896 testutil.Equals(t, expectedCpy, samples, "samples for series %v does not match", s.Labels()) 897 } 898 } 899 900 func jsonToSeries(t *testing.T, filename string) []series { 901 file, err := os.ReadFile(filename) 902 testutil.Ok(t, err) 903 904 data := Response{} 905 testutil.Ok(t, json.Unmarshal(file, &data), filename) 906 907 var ss []series 908 for _, ser := range data.Data.Results { 909 var lbls labels.Labels 910 for n, v := range ser.Metric { 911 lbls = append(lbls, labels.Label{ 912 Name: string(n), 913 Value: string(v), 914 }) 915 } 916 // Label names need to be sorted. 917 sort.Sort(lbls) 918 919 var smpls []sample 920 for _, smp := range ser.Values { 921 smpls = append(smpls, sample{ 922 t: int64(smp.Timestamp), 923 v: float64(smp.Value), 924 }) 925 } 926 927 ss = append(ss, series{ 928 lset: lbls, 929 samples: smpls, 930 }) 931 } 932 933 // Sort the series by their labels. 934 sort.Slice(ss, func(i, j int) bool { 935 return labels.Compare(ss[i].lset, ss[j].lset) <= 0 936 }) 937 938 return ss 939 } 940 941 type Response struct { 942 Status string `json:"status"` 943 Data struct { 944 ResultType string `json:"resultType"` 945 Results model.Matrix `json:"result"` 946 } `json:"data"` 947 } 948 949 func promqlResToSeries(res *promql.Result) []series { 950 matrix := res.Value.(promql.Matrix) 951 series := make([]series, len(matrix)) 952 953 for i, ser := range matrix { 954 series[i].lset = ser.Metric 955 for _, point := range ser.Floats { 956 series[i].samples = append(series[i].samples, sample{t: point.T, v: point.F}) 957 } 958 } 959 return series 960 } 961 962 type mockedQueryable struct { 963 Creator func(int64, int64) storage.Querier 964 querier storage.Querier 965 } 966 967 // Querier creates a querier with the provided min and max time. 968 // The promQL engine sets mint and it is calculated based on the default lookback delta. 969 func (q *mockedQueryable) Querier(_ context.Context, mint, maxt int64) (storage.Querier, error) { 970 if q.Creator == nil { 971 return q.querier, nil 972 } 973 qq := q.Creator(mint, maxt) 974 q.querier = qq 975 return q.querier, nil 976 } 977 978 func (q *mockedQueryable) Close() error { 979 defer func() { 980 q.querier = nil 981 }() 982 983 if q.querier != nil { 984 return q.querier.Close() 985 } 986 return nil 987 } 988 989 type querierResponseCatcher struct { 990 storage.Querier 991 t testing.TB 992 993 resp []storage.SeriesSet 994 } 995 996 func (q *querierResponseCatcher) Select(selectSorted bool, p *storage.SelectHints, m ...*labels.Matcher) storage.SeriesSet { 997 s := q.Querier.Select(selectSorted, p, m...) 998 q.resp = append(q.resp, s) 999 return storage.NoopSeriesSet() 1000 } 1001 1002 func (q querierResponseCatcher) Close() error { return nil } 1003 1004 func (q *querierResponseCatcher) warns() []storage.Warnings { 1005 var warns []storage.Warnings 1006 for _, r := range q.resp { 1007 warns = append(warns, r.Warnings()) 1008 } 1009 return warns 1010 } 1011 1012 type mockedSeriesIterator struct { 1013 cur int 1014 samples []sample 1015 } 1016 1017 func newMockedSeriesIterator(samples []sample) *mockedSeriesIterator { 1018 return &mockedSeriesIterator{samples: samples, cur: -1} 1019 } 1020 1021 // TODO(rabenhorst): Native histogram support needs to be implemented, currently float type is hardcoded. 1022 func (s *mockedSeriesIterator) Seek(t int64) chunkenc.ValueType { 1023 s.cur = sort.Search(len(s.samples), func(n int) bool { 1024 return s.samples[n].t >= t 1025 }) 1026 1027 if s.cur < len(s.samples) { 1028 return chunkenc.ValFloat 1029 } 1030 1031 return chunkenc.ValNone 1032 } 1033 1034 func (s *mockedSeriesIterator) At() (t int64, v float64) { 1035 sample := s.samples[s.cur] 1036 return sample.t, sample.v 1037 } 1038 1039 // TODO(rabenhorst): Needs to be implemented for native histogram support. 1040 func (s *mockedSeriesIterator) AtHistogram() (int64, *histogram.Histogram) { 1041 panic("not implemented") 1042 } 1043 1044 func (s *mockedSeriesIterator) AtFloatHistogram() (int64, *histogram.FloatHistogram) { 1045 panic("not implemented") 1046 } 1047 1048 func (s *mockedSeriesIterator) AtT() int64 { 1049 return s.samples[s.cur].t 1050 } 1051 1052 func (s *mockedSeriesIterator) Next() chunkenc.ValueType { 1053 s.cur++ 1054 if s.cur < len(s.samples) { 1055 return chunkenc.ValFloat 1056 } 1057 1058 return chunkenc.ValNone 1059 } 1060 1061 func (s *mockedSeriesIterator) Err() error { return nil } 1062 1063 func TestQuerierWithDedupUnderstoodByPromQL_Rate(t *testing.T) { 1064 logger := log.NewLogfmtLogger(os.Stderr) 1065 1066 s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) 1067 testutil.Ok(t, err) 1068 1069 t.Run("dedup=false", func(t *testing.T) { 1070 expectedLset1 := labels.FromStrings( 1071 "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", 1072 "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", 1073 "gcp", "region", "us-east", "replica", "01", "shard", "default", "stage", "main", "tier", "sv", "type", "web", 1074 ) 1075 expectedLset2 := labels.FromStrings( 1076 "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", 1077 "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", 1078 "gcp", "region", "us-east", "replica", "02", "shard", "default", "stage", "main", "tier", "sv", "type", "web", 1079 ) 1080 1081 timeout := 100 * time.Second 1082 g := gate.New(2) 1083 q := newQuerier(context.Background(), logger, realSeriesWithStaleMarkerMint, realSeriesWithStaleMarkerMaxt, []string{"replica"}, nil, newProxyStore(s), false, 0, true, false, false, g, timeout, nil, NoopSeriesStatsReporter) 1084 t.Cleanup(func() { 1085 testutil.Ok(t, q.Close()) 1086 }) 1087 1088 e := promql.NewEngine(promql.EngineOpts{ 1089 Logger: logger, 1090 Timeout: timeout, 1091 MaxSamples: math.MaxInt64, 1092 }) 1093 t.Run("Rate=5mStep=100s", func(t *testing.T) { 1094 q, err := e.NewRangeQuery(context.Background(), &mockedQueryable{querier: q}, promql.NewPrometheusQueryOpts(false, 0), `rate(gitlab_transaction_cache_read_hit_count_total[5m])`, timestamp.Time(realSeriesWithStaleMarkerMint).Add(5*time.Minute), timestamp.Time(realSeriesWithStaleMarkerMaxt), 100*time.Second) 1095 testutil.Ok(t, err) 1096 1097 r := q.Exec(context.Background()) 1098 testutil.Ok(t, r.Err) 1099 testutil.Assert(t, len(r.Warnings) == 0) 1100 1101 vec, err := r.Matrix() 1102 testutil.Ok(t, err) 1103 testutil.Equals(t, promql.Matrix{ 1104 {Metric: expectedLset1, Floats: []promql.FPoint{ 1105 {T: 1587690300000, F: 13.652631578947368}, {T: 1587690400000, F: 14.049122807017543}, {T: 1587690500000, F: 13.961403508771928}, {T: 1587690600000, F: 13.617543859649121}, {T: 1587690700000, F: 14.568421052631578}, {T: 1587690800000, F: 14.989473684210525}, 1106 {T: 1587690900000, F: 16.2}, {T: 1587691000000, F: 16.052631578947366}, {T: 1587691100000, F: 15.831578947368419}, {T: 1587691200000, F: 15.659649122807016}, {T: 1587691300000, F: 14.842105263157894}, {T: 1587691400000, F: 14.003508771929823}, 1107 {T: 1587691500000, F: 13.782456140350876}, {T: 1587691600000, F: 13.86315789473684}, {T: 1587691700000, F: 15.270282598474376}, {T: 1587691800000, F: 14.343859649122805}, {T: 1587691900000, F: 13.975438596491227}, {T: 1587692000000, F: 13.399999999999999}, 1108 {T: 1587692100000, F: 14.087719298245613}, {T: 1587692200000, F: 14.392982456140349}, {T: 1587692300000, F: 15.02456140350877}, {T: 1587692400000, F: 14.073684210526315}, {T: 1587692500000, F: 9.3772165751634}, {T: 1587692600000, F: 6.378947368421052}, 1109 {T: 1587692700000, F: 8.19298245614035}, {T: 1587692800000, F: 11.91870302641626}, {T: 1587692900000, F: 13.75813610765101}, {T: 1587693000000, F: 13.087719298245613}, {T: 1587693100000, F: 13.466666666666665}, {T: 1587693200000, F: 14.028070175438595}, 1110 {T: 1587693300000, F: 14.23859649122807}, {T: 1587693400000, F: 15.407017543859647}, {T: 1587693500000, F: 15.915789473684208}, {T: 1587693600000, F: 15.712280701754384}, 1111 }}, 1112 {Metric: expectedLset2, Floats: []promql.FPoint{ 1113 {T: 1587690300000, F: 13.691228070175438}, {T: 1587690400000, F: 14.098245614035086}, {T: 1587690500000, F: 13.905263157894735}, {T: 1587690600000, F: 13.617543859649121}, {T: 1587690700000, F: 14.350877192982455}, {T: 1587690800000, F: 15.003508771929823}, 1114 {T: 1587690900000, F: 16.12280701754386}, {T: 1587691000000, F: 16.049122807017543}, {T: 1587691100000, F: 15.922807017543859}, {T: 1587691200000, F: 15.63157894736842}, {T: 1587691300000, F: 14.982456140350875}, {T: 1587691400000, F: 14.187259188557553}, 1115 {T: 1587691500000, F: 13.828070175438596}, {T: 1587691600000, F: 13.971929824561402}, {T: 1587691700000, F: 15.31994329585807}, {T: 1587691800000, F: 14.30877192982456}, {T: 1587691900000, F: 13.915789473684208}, {T: 1587692000000, F: 13.312280701754384}, 1116 {T: 1587692100000, F: 14.136842105263156}, {T: 1587692200000, F: 14.392982456140349}, {T: 1587692300000, F: 15.014035087719297}, {T: 1587692400000, F: 14.112280701754385}, {T: 1587692500000, F: 9.421065148148148}, {T: 1587692600000, F: 6.421368067203301}, 1117 {T: 1587692700000, F: 8.252631578947367}, {T: 1587692800000, F: 11.721237543747266}, {T: 1587692900000, F: 13.842105263157894}, {T: 1587693000000, F: 13.153509064307993}, {T: 1587693100000, F: 13.378947368421052}, {T: 1587693200000, F: 14.03157894736842}, 1118 {T: 1587693300000, F: 14.14736842105263}, {T: 1587693400000, F: 15.343159785693986}, {T: 1587693500000, F: 15.90877192982456}, {T: 1587693600000, F: 15.761403508771927}, 1119 }}, 1120 }, vec) 1121 }) 1122 t.Run("Rate=30mStep=500s", func(t *testing.T) { 1123 q, err := e.NewRangeQuery(context.Background(), &mockedQueryable{querier: q}, promql.NewPrometheusQueryOpts(false, 0), `rate(gitlab_transaction_cache_read_hit_count_total[30m])`, timestamp.Time(realSeriesWithStaleMarkerMint).Add(30*time.Minute), timestamp.Time(realSeriesWithStaleMarkerMaxt), 500*time.Second) 1124 testutil.Ok(t, err) 1125 1126 r := q.Exec(context.Background()) 1127 testutil.Ok(t, r.Err) 1128 testutil.Assert(t, len(r.Warnings) == 0) 1129 1130 vec, err := r.Matrix() 1131 testutil.Ok(t, err) 1132 testutil.Equals(t, promql.Matrix{ 1133 {Metric: expectedLset1, Floats: []promql.FPoint{ 1134 {T: 1587691800000, F: 14.457142857142856}, {T: 1587692300000, F: 14.761904761904761}, {T: 1587692800000, F: 13.127170868347338}, {T: 1587693300000, F: 12.93501400560224}, 1135 }}, 1136 {Metric: expectedLset2, Floats: []promql.FPoint{ 1137 {T: 1587691800000, F: 14.464425770308122}, {T: 1587692300000, F: 14.763025210084033}, {T: 1587692800000, F: 13.148909112808576}, {T: 1587693300000, F: 12.92829131652661}, 1138 }}, 1139 }, vec) 1140 }) 1141 }) 1142 // Regression test against https://github.com/thanos-io/thanos/issues/2401. 1143 // Rate + dedup can cause incorrectness. 1144 t.Run("dedup=true", func(t *testing.T) { 1145 expectedLset := labels.FromStrings( 1146 "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", 1147 "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", 1148 "gcp", "region", "us-east", "shard", "default", "stage", "main", "tier", "sv", "type", "web", 1149 ) 1150 1151 timeout := 5 * time.Second 1152 g := gate.New(2) 1153 q := newQuerier(context.Background(), logger, realSeriesWithStaleMarkerMint, realSeriesWithStaleMarkerMaxt, []string{"replica"}, nil, newProxyStore(s), true, 0, true, false, false, g, timeout, nil, NoopSeriesStatsReporter) 1154 t.Cleanup(func() { 1155 testutil.Ok(t, q.Close()) 1156 }) 1157 1158 e := promql.NewEngine(promql.EngineOpts{ 1159 Logger: logger, 1160 Timeout: timeout, 1161 MaxSamples: math.MaxInt64, 1162 }) 1163 t.Run("Rate=5mStep=100s", func(t *testing.T) { 1164 q, err := e.NewRangeQuery(context.Background(), &mockedQueryable{querier: q}, promql.NewPrometheusQueryOpts(false, 0), `rate(gitlab_transaction_cache_read_hit_count_total[5m])`, timestamp.Time(realSeriesWithStaleMarkerMint).Add(5*time.Minute), timestamp.Time(realSeriesWithStaleMarkerMaxt), 100*time.Second) 1165 testutil.Ok(t, err) 1166 1167 r := q.Exec(context.Background()) 1168 testutil.Ok(t, r.Err) 1169 testutil.Assert(t, len(r.Warnings) == 0) 1170 1171 vec, err := r.Matrix() 1172 testutil.Ok(t, err) 1173 testutil.Equals(t, promql.Matrix{ 1174 {Metric: expectedLset, Floats: []promql.FPoint{ 1175 {T: 1587690300000, F: 13.691228070175438}, {T: 1587690400000, F: 14.098245614035086}, {T: 1587690500000, F: 13.905263157894735}, {T: 1587690600000, F: 13.617543859649121}, 1176 {T: 1587690700000, F: 14.350877192982455}, {T: 1587690800000, F: 15.003508771929823}, {T: 1587690900000, F: 16.12280701754386}, {T: 1587691000000, F: 16.049122807017543}, 1177 {T: 1587691100000, F: 15.922807017543859}, {T: 1587691200000, F: 15.63157894736842}, {T: 1587691300000, F: 14.982456140350875}, {T: 1587691400000, F: 14.187259188557553}, 1178 {T: 1587691500000, F: 13.828070175438596}, {T: 1587691600000, F: 13.971929824561402}, {T: 1587691700000, F: 15.31994329585807}, {T: 1587691800000, F: 14.30877192982456}, 1179 {T: 1587691900000, F: 13.915789473684208}, {T: 1587692000000, F: 13.312280701754384}, {T: 1587692100000, F: 14.136842105263156}, {T: 1587692200000, F: 14.392982456140349}, 1180 {T: 1587692300000, F: 15.014035087719297}, {T: 1587692400000, F: 14.112280701754385}, {T: 1587692500000, F: 9.421065148148148}, {T: 1587692600000, F: 6.3736754978451735}, 1181 {T: 1587692700000, F: 8.19632056099571}, {T: 1587692800000, F: 11.91870302641626}, {T: 1587692900000, F: 13.75813610765101}, {T: 1587693000000, F: 13.087719298245613}, 1182 {T: 1587693100000, F: 13.466666666666665}, {T: 1587693200000, F: 14.028070175438595}, {T: 1587693300000, F: 14.23859649122807}, {T: 1587693400000, F: 15.407017543859647}, 1183 {T: 1587693500000, F: 15.915789473684208}, {T: 1587693600000, F: 15.712280701754384}, 1184 }}, 1185 }, vec) 1186 }) 1187 t.Run("Rate=30mStep=500s", func(t *testing.T) { 1188 q, err := e.NewRangeQuery(context.Background(), &mockedQueryable{querier: q}, promql.NewPrometheusQueryOpts(false, 0), `rate(gitlab_transaction_cache_read_hit_count_total[30m])`, timestamp.Time(realSeriesWithStaleMarkerMint).Add(30*time.Minute), timestamp.Time(realSeriesWithStaleMarkerMaxt), 500*time.Second) 1189 testutil.Ok(t, err) 1190 1191 r := q.Exec(context.Background()) 1192 testutil.Ok(t, r.Err) 1193 testutil.Assert(t, len(r.Warnings) == 0) 1194 1195 vec, err := r.Matrix() 1196 testutil.Ok(t, err) 1197 testutil.Equals(t, promql.Matrix{ 1198 {Metric: expectedLset, Floats: []promql.FPoint{ 1199 {T: 1587691800000, F: 14.464425770308122}, 1200 {T: 1587692300000, F: 14.763025210084033}, 1201 {T: 1587692800000, F: 13.143575607888273}, 1202 {T: 1587693300000, F: 12.930291298224088}, 1203 }}, 1204 }, vec) 1205 }) 1206 }) 1207 } 1208 1209 const hackyStaleMarker = float64(-99999999) 1210 1211 func expandSeries(t testing.TB, it chunkenc.Iterator) (res []sample) { 1212 for it.Next() != chunkenc.ValNone { 1213 t, v := it.At() 1214 // Nan != Nan, so substitute for another value. 1215 // This is required for testutil.Equals to work deterministically. 1216 if math.IsNaN(v) { 1217 v = hackyStaleMarker 1218 } 1219 res = append(res, sample{t, v}) 1220 } 1221 testutil.Ok(t, it.Err()) 1222 return res 1223 } 1224 1225 type testStoreServer struct { 1226 // This field just exist to pseudo-implement the unused methods of the interface. 1227 storepb.StoreServer 1228 1229 resps []*storepb.SeriesResponse 1230 respsWithoutReplicaLabels []*storepb.SeriesResponse 1231 } 1232 1233 func (s *testStoreServer) Series(r *storepb.SeriesRequest, srv storepb.Store_SeriesServer) error { 1234 resps := s.resps 1235 1236 if len(r.WithoutReplicaLabels) > 0 && len(s.respsWithoutReplicaLabels) > 0 { 1237 // If `respsWithoutReplicaLabels` is present, we simulate server that supports without replica label feature. 1238 resps = s.respsWithoutReplicaLabels 1239 } 1240 for _, resp := range resps { 1241 err := srv.Send(resp) 1242 if err != nil { 1243 return err 1244 } 1245 } 1246 return nil 1247 } 1248 1249 // storeSeriesResponse creates test storepb.SeriesResponse that includes series with single chunk that stores all the given samples. 1250 func storeSeriesResponse(t testing.TB, lset labels.Labels, smplChunks ...[]sample) *storepb.SeriesResponse { 1251 var s storepb.Series 1252 1253 for _, l := range lset { 1254 s.Labels = append(s.Labels, labelpb.ZLabel{Name: l.Name, Value: l.Value}) 1255 } 1256 1257 for _, smpls := range smplChunks { 1258 c := chunkenc.NewXORChunk() 1259 a, err := c.Appender() 1260 testutil.Ok(t, err) 1261 1262 for _, smpl := range smpls { 1263 a.Append(smpl.t, smpl.v) 1264 } 1265 1266 ch := storepb.AggrChunk{ 1267 MinTime: smpls[0].t, 1268 MaxTime: smpls[len(smpls)-1].t, 1269 Raw: &storepb.Chunk{Type: storepb.Chunk_XOR, Data: c.Bytes()}, 1270 } 1271 1272 s.Chunks = append(s.Chunks, ch) 1273 } 1274 return storepb.NewSeriesResponse(&s) 1275 }