github.com/thanos-io/thanos@v0.32.5/pkg/metadata/proxy_test.go (about)

     1  // Copyright (c) The Thanos Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package metadata
     5  
     6  import (
     7  	"context"
     8  	"io"
     9  	"os"
    10  	"testing"
    11  
    12  	"github.com/go-kit/log"
    13  	"github.com/pkg/errors"
    14  	"go.uber.org/atomic"
    15  	"google.golang.org/grpc"
    16  
    17  	"github.com/thanos-io/thanos/pkg/metadata/metadatapb"
    18  	"github.com/thanos-io/thanos/pkg/store/storepb"
    19  )
    20  
    21  type testMetadataClient struct {
    22  	grpc.ClientStream
    23  	metadataErr, recvErr error
    24  	response             *metadatapb.MetricMetadataResponse
    25  	sentResponse         atomic.Bool
    26  }
    27  
    28  func (t *testMetadataClient) String() string {
    29  	return "test"
    30  }
    31  
    32  func (t *testMetadataClient) Recv() (*metadatapb.MetricMetadataResponse, error) {
    33  	if t.recvErr != nil {
    34  		return nil, t.recvErr
    35  	}
    36  
    37  	if t.sentResponse.Load() {
    38  		return nil, io.EOF
    39  	}
    40  	t.sentResponse.Store(true)
    41  
    42  	return t.response, nil
    43  }
    44  
    45  func (t *testMetadataClient) MetricMetadata(ctx context.Context, in *metadatapb.MetricMetadataRequest, opts ...grpc.CallOption) (metadatapb.Metadata_MetricMetadataClient, error) {
    46  	return t, t.metadataErr
    47  }
    48  
    49  var _ metadatapb.MetadataClient = &testMetadataClient{}
    50  
    51  // TestProxyDataRace find the concurrent data race bug ( go test -race -run TestProxyDataRace -v ).
    52  func TestProxyDataRace(t *testing.T) {
    53  	logger := log.NewLogfmtLogger(os.Stderr)
    54  	p := NewProxy(logger, func() []metadatapb.MetadataClient {
    55  		es := &testMetadataClient{
    56  			recvErr: errors.New("err"),
    57  		}
    58  		size := 100
    59  		endpoints := make([]metadatapb.MetadataClient, 0, size)
    60  		for i := 0; i < size; i++ {
    61  			endpoints = append(endpoints, es)
    62  		}
    63  		return endpoints
    64  	})
    65  	req := &metadatapb.MetricMetadataRequest{
    66  		Metric:                  `http_request_duration_bucket`,
    67  		PartialResponseStrategy: storepb.PartialResponseStrategy_WARN,
    68  	}
    69  	s := &metadataServer{
    70  		ctx: context.Background(),
    71  	}
    72  	_ = p.MetricMetadata(req, s)
    73  }