github.com/thanos-io/thanos@v0.32.5/pkg/query/internal/test-storeset-pre-v0.8.0/storeset_test.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package testoldstoreset 5 6 import ( 7 "context" 8 "fmt" 9 "math" 10 "net" 11 "os" 12 "sort" 13 "testing" 14 "time" 15 16 "github.com/go-kit/log" 17 "github.com/go-kit/log/level" 18 "github.com/prometheus/prometheus/model/labels" 19 "google.golang.org/grpc" 20 "google.golang.org/grpc/codes" 21 "google.golang.org/grpc/credentials/insecure" 22 "google.golang.org/grpc/status" 23 24 "github.com/efficientgo/core/testutil" 25 "github.com/thanos-io/thanos/pkg/component" 26 "github.com/thanos-io/thanos/pkg/store" 27 "github.com/thanos-io/thanos/pkg/store/labelpb" 28 "github.com/thanos-io/thanos/pkg/store/storepb" 29 "github.com/thanos-io/thanos/pkg/testutil/custom" 30 ) 31 32 var testGRPCOpts = []grpc.DialOption{ 33 grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(math.MaxInt32)), 34 grpc.WithTransportCredentials(insecure.NewCredentials()), 35 } 36 37 type testStore struct { 38 info storepb.InfoResponse 39 } 40 41 func (s *testStore) Info(ctx context.Context, r *storepb.InfoRequest) (*storepb.InfoResponse, error) { 42 return &s.info, nil 43 } 44 45 func (s *testStore) Series(r *storepb.SeriesRequest, srv storepb.Store_SeriesServer) error { 46 return status.Error(codes.Unimplemented, "not implemented") 47 } 48 49 func (s *testStore) LabelNames(ctx context.Context, r *storepb.LabelNamesRequest) ( 50 *storepb.LabelNamesResponse, error, 51 ) { 52 return nil, status.Error(codes.Unimplemented, "not implemented") 53 } 54 55 func (s *testStore) LabelValues(ctx context.Context, r *storepb.LabelValuesRequest) ( 56 *storepb.LabelValuesResponse, error, 57 ) { 58 return nil, status.Error(codes.Unimplemented, "not implemented") 59 } 60 61 type testStoreMeta struct { 62 extlsetFn func(addr string) []labelpb.ZLabelSet 63 storeType component.StoreAPI 64 } 65 66 type testStores struct { 67 srvs map[string]*grpc.Server 68 } 69 70 func startTestStores(stores []testStoreMeta) (*testStores, error) { 71 st := &testStores{ 72 srvs: map[string]*grpc.Server{}, 73 } 74 75 for _, store := range stores { 76 listener, err := net.Listen("tcp", "127.0.0.1:0") 77 if err != nil { 78 // Close so far started servers. 79 st.Close() 80 return nil, err 81 } 82 83 srv := grpc.NewServer() 84 storepb.RegisterStoreServer(srv, &testStore{info: storepb.InfoResponse{LabelSets: store.extlsetFn(listener.Addr().String()), StoreType: store.storeType.ToProto()}}) 85 go func() { 86 _ = srv.Serve(listener) 87 }() 88 89 st.srvs[listener.Addr().String()] = srv 90 } 91 92 return st, nil 93 } 94 95 func (s *testStores) StoreAddresses() []string { 96 var stores []string 97 for addr := range s.srvs { 98 stores = append(stores, addr) 99 } 100 return stores 101 } 102 103 func (s *testStores) Close() { 104 for _, srv := range s.srvs { 105 srv.Stop() 106 } 107 s.srvs = nil 108 } 109 110 func (s *testStores) CloseOne(addr string) { 111 srv, ok := s.srvs[addr] 112 if !ok { 113 return 114 } 115 116 srv.Stop() 117 delete(s.srvs, addr) 118 } 119 120 func specsFromAddrFunc(addrs []string) func() []StoreSpec { 121 return func() (specs []StoreSpec) { 122 for _, addr := range addrs { 123 specs = append(specs, NewGRPCStoreSpec(addr)) 124 } 125 return specs 126 } 127 } 128 129 func TestMain(m *testing.M) { 130 custom.TolerantVerifyLeakMain(m) 131 } 132 133 func TestPre0_8_0_StoreSet_AgainstNewStoreGW(t *testing.T) { 134 st, err := startTestStores([]testStoreMeta{ 135 { 136 storeType: component.Sidecar, 137 extlsetFn: func(addr string) []labelpb.ZLabelSet { 138 return []labelpb.ZLabelSet{ 139 { 140 Labels: []labelpb.ZLabel{ 141 {Name: "l1", Value: "v2"}, 142 {Name: "l2", Value: "v3"}, 143 }, 144 }, 145 } 146 }, 147 }, 148 { 149 storeType: component.Store, 150 extlsetFn: func(addr string) []labelpb.ZLabelSet { 151 return []labelpb.ZLabelSet{ 152 { 153 Labels: []labelpb.ZLabel{ 154 // This is the labelset exposed by store when having only one sidecar's data. 155 {Name: "l1", Value: "v2"}, 156 {Name: "l2", Value: "v3"}, 157 }, 158 }, 159 { 160 Labels: []labelpb.ZLabel{{Name: store.CompatibilityTypeLabelName, Value: "store"}}, 161 }, 162 } 163 }, 164 }, 165 // We expect this to be duplicated. 166 { 167 storeType: component.Store, 168 extlsetFn: func(addr string) []labelpb.ZLabelSet { 169 return []labelpb.ZLabelSet{ 170 { 171 Labels: []labelpb.ZLabel{ 172 {Name: "l1", Value: "v2"}, 173 {Name: "l2", Value: "v3"}, 174 }, 175 }, 176 { 177 Labels: []labelpb.ZLabel{{Name: store.CompatibilityTypeLabelName, Value: "store"}}, 178 }, 179 } 180 }, 181 }, 182 }) 183 testutil.Ok(t, err) 184 defer st.Close() 185 186 logger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) 187 logger = level.NewFilter(logger, level.AllowDebug()) 188 logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) 189 storeSet := NewStoreSet(logger, nil, specsFromAddrFunc(st.StoreAddresses()), testGRPCOpts, time.Minute) 190 storeSet.gRPCInfoCallTimeout = 2 * time.Second 191 defer storeSet.Close() 192 193 // Should not matter how many of these we run. 194 storeSet.Update(context.Background()) 195 storeSet.Update(context.Background()) 196 storeSet.Update(context.Background()) 197 storeSet.Update(context.Background()) 198 199 testutil.Assert(t, len(storeSet.stores) == 2, fmt.Sprintf("all services should respond just fine, but we expect duplicates being blocked. Expected %d stores, got %d", 5, len(storeSet.stores))) 200 201 // Sort result to be able to compare. 202 var existingStoreLabels [][]labels.Labels 203 for _, store := range storeSet.stores { 204 lset := append([]labels.Labels{}, store.LabelSets()...) 205 existingStoreLabels = append(existingStoreLabels, lset) 206 } 207 sort.Slice(existingStoreLabels, func(i, j int) bool { 208 return len(existingStoreLabels[i]) > len(existingStoreLabels[j]) 209 }) 210 211 testutil.Equals(t, [][]labels.Labels{ 212 { 213 { 214 {Name: "l1", Value: "v2"}, 215 {Name: "l2", Value: "v3"}, 216 }, 217 { 218 {Name: store.CompatibilityTypeLabelName, Value: "store"}, 219 }, 220 }, 221 { 222 { 223 {Name: "l1", Value: "v2"}, 224 {Name: "l2", Value: "v3"}, 225 }, 226 }, 227 }, existingStoreLabels) 228 }