github.com/thanos-io/thanos@v0.32.5/pkg/query/query_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 "fmt" 9 "os" 10 "path/filepath" 11 "testing" 12 "time" 13 14 "github.com/efficientgo/core/testutil" 15 "github.com/go-kit/log" 16 "github.com/prometheus/prometheus/storage" 17 "github.com/thanos-io/thanos/pkg/component" 18 "github.com/thanos-io/thanos/pkg/store" 19 "github.com/thanos-io/thanos/pkg/store/storepb" 20 storetestutil "github.com/thanos-io/thanos/pkg/store/storepb/testutil" 21 "github.com/thanos-io/thanos/pkg/testutil/custom" 22 ) 23 24 func TestMain(m *testing.M) { 25 custom.TolerantVerifyLeakMain(m) 26 } 27 28 func TestQuerier_Proxy(t *testing.T) { 29 files, err := filepath.Glob("testdata/promql/**/*.test") 30 testutil.Ok(t, err) 31 testutil.Equals(t, 10, len(files), "%v", files) 32 33 logger := log.NewLogfmtLogger(os.Stderr) 34 t.Run("proxy", func(t *testing.T) { 35 var clients []store.Client 36 q := NewQueryableCreator( 37 logger, 38 nil, 39 store.NewProxyStore(logger, nil, func() []store.Client { return clients }, 40 component.Debug, nil, 5*time.Minute, store.EagerRetrieval), 41 1000000, 42 5*time.Minute, 43 ) 44 45 createQueryableFn := func(stores []*testStore) storage.Queryable { 46 clients = clients[:0] 47 for i, st := range stores { 48 m, err := storepb.PromMatchersToMatchers(st.matchers...) 49 testutil.Ok(t, err) 50 51 // TODO(bwplotka): Parse external labels. 52 clients = append(clients, &storetestutil.TestClient{ 53 Name: fmt.Sprintf("store number %v", i), 54 StoreClient: storepb.ServerAsClient(selectedStore(store.NewTSDBStore(logger, st.storage.DB, component.Debug, nil), m, st.mint, st.maxt), 0), 55 MinTime: st.mint, 56 MaxTime: st.maxt, 57 }) 58 } 59 return q(true, 60 nil, 61 nil, 62 0, 63 false, 64 false, 65 false, 66 nil, 67 NoopSeriesStatsReporter, 68 ) 69 } 70 71 for _, fn := range files { 72 t.Run(fn, func(t *testing.T) { 73 te, err := newTestFromFile(t, fn) 74 testutil.Ok(t, err) 75 testutil.Ok(t, te.run(createQueryableFn)) 76 te.close() 77 }) 78 } 79 }) 80 } 81 82 // selectStore allows wrapping another storeEndpoints with additional time and matcher selection. 83 type selectStore struct { 84 matchers []storepb.LabelMatcher 85 86 storepb.StoreServer 87 mint, maxt int64 88 } 89 90 // selectedStore wraps given store with selectStore. 91 func selectedStore(wrapped storepb.StoreServer, matchers []storepb.LabelMatcher, mint, maxt int64) *selectStore { 92 return &selectStore{ 93 StoreServer: wrapped, 94 matchers: matchers, 95 mint: mint, 96 maxt: maxt, 97 } 98 } 99 100 func (s *selectStore) Info(ctx context.Context, r *storepb.InfoRequest) (*storepb.InfoResponse, error) { 101 resp, err := s.StoreServer.Info(ctx, r) 102 if err != nil { 103 return nil, err 104 } 105 if resp.MinTime < s.mint { 106 resp.MinTime = s.mint 107 } 108 if resp.MaxTime > s.maxt { 109 resp.MaxTime = s.maxt 110 } 111 // TODO(bwplotka): Match labelsets and expose only those? 112 return resp, nil 113 } 114 115 func (s *selectStore) Series(r *storepb.SeriesRequest, srv storepb.Store_SeriesServer) error { 116 if r.MinTime < s.mint { 117 r.MinTime = s.mint 118 } 119 if r.MaxTime > s.maxt { 120 r.MaxTime = s.maxt 121 } 122 r.Matchers = append(r.Matchers, s.matchers...) 123 return s.StoreServer.Series(r, srv) 124 }