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  }