...

Source file src/github.com/launchdarkly/go-server-sdk/v6/ldclient_big_segments_test.go

Documentation: github.com/launchdarkly/go-server-sdk/v6

     1  package ldclient
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/launchdarkly/go-sdk-common/v3/ldlogtest"
     9  	"github.com/launchdarkly/go-sdk-common/v3/ldreason"
    10  	"github.com/launchdarkly/go-sdk-common/v3/ldvalue"
    11  	"github.com/launchdarkly/go-server-sdk-evaluation/v2/ldbuilders"
    12  	"github.com/launchdarkly/go-server-sdk-evaluation/v2/ldmodel"
    13  	"github.com/launchdarkly/go-server-sdk/v6/internal/bigsegments"
    14  	"github.com/launchdarkly/go-server-sdk/v6/internal/sharedtest/mocks"
    15  
    16  	"github.com/launchdarkly/go-server-sdk/v6/ldcomponents"
    17  	"github.com/launchdarkly/go-server-sdk/v6/subsystems"
    18  	"github.com/launchdarkly/go-server-sdk/v6/subsystems/ldstoreimpl"
    19  	"github.com/launchdarkly/go-server-sdk/v6/testhelpers/ldtestdata"
    20  
    21  	"github.com/stretchr/testify/assert"
    22  	"github.com/stretchr/testify/require"
    23  )
    24  
    25  const bigSegmentKey = "segmentkey"
    26  
    27  // The definition of this function has to be kept in sync with the equivalent function in
    28  // go-server-sdk-evaluation.
    29  func makeBigSegmentRef(segmentKey string, generation int) string {
    30  	return fmt.Sprintf("%s.g%d", segmentKey, generation)
    31  }
    32  
    33  func addBigSegmentAndFlag(testData *ldtestdata.TestDataSource) {
    34  	segment := ldbuilders.NewSegmentBuilder(bigSegmentKey).
    35  		Unbounded(true).
    36  		Generation(1).
    37  		Build()
    38  	flag := ldbuilders.NewFlagBuilder(evalFlagKey).On(true).
    39  		Variations(ldvalue.Bool(false), ldvalue.Bool(true)).
    40  		FallthroughVariation(0).
    41  		AddRule(ldbuilders.NewRuleBuilder().Variation(1).Clauses(
    42  			ldbuilders.Clause("", ldmodel.OperatorSegmentMatch, ldvalue.String(segment.Key)),
    43  		)).
    44  		Build()
    45  	testData.UsePreconfiguredSegment(segment)
    46  	testData.UsePreconfiguredFlag(flag)
    47  }
    48  
    49  func doBigSegmentsTest(
    50  	t *testing.T,
    51  	action func(client *LDClient, bsStore *mocks.MockBigSegmentStore),
    52  ) {
    53  	mockLog := ldlogtest.NewMockLog()
    54  	defer mockLog.DumpIfTestFailed(t)
    55  	testData := ldtestdata.DataSource()
    56  	bsStore := &mocks.MockBigSegmentStore{}
    57  	bsStore.TestSetMetadataToCurrentTime()
    58  
    59  	addBigSegmentAndFlag(testData)
    60  
    61  	client := makeTestClientWithConfig(func(c *Config) {
    62  		c.DataSource = testData
    63  		c.BigSegments = ldcomponents.BigSegments(
    64  			mocks.SingleComponentConfigurer[subsystems.BigSegmentStore]{Instance: bsStore},
    65  		)
    66  		c.Logging = ldcomponents.Logging().Loggers(mockLog.Loggers)
    67  	})
    68  	defer client.Close()
    69  
    70  	action(client, bsStore)
    71  }
    72  
    73  func TestEvalWithBigSegments(t *testing.T) {
    74  	t.Run("user not found", func(t *testing.T) {
    75  		doBigSegmentsTest(t, func(client *LDClient, bsStore *mocks.MockBigSegmentStore) {
    76  			value, detail, err := client.BoolVariationDetail(evalFlagKey, evalTestUser, false)
    77  			require.NoError(t, err)
    78  			assert.False(t, value)
    79  			assert.Equal(t, ldreason.BigSegmentsHealthy, detail.Reason.GetBigSegmentsStatus())
    80  		})
    81  	})
    82  
    83  	t.Run("user found", func(t *testing.T) {
    84  		doBigSegmentsTest(t, func(client *LDClient, bsStore *mocks.MockBigSegmentStore) {
    85  			membership := ldstoreimpl.NewBigSegmentMembershipFromSegmentRefs(
    86  				[]string{makeBigSegmentRef(bigSegmentKey, 1)}, nil)
    87  			bsStore.TestSetMembership(bigsegments.HashForContextKey(evalTestUser.Key()), membership)
    88  
    89  			value, detail, err := client.BoolVariationDetail(evalFlagKey, evalTestUser, false)
    90  			require.NoError(t, err)
    91  			assert.True(t, value)
    92  			assert.Equal(t, ldreason.BigSegmentsHealthy, detail.Reason.GetBigSegmentsStatus())
    93  		})
    94  	})
    95  
    96  	t.Run("store error", func(t *testing.T) {
    97  		doBigSegmentsTest(t, func(client *LDClient, bsStore *mocks.MockBigSegmentStore) {
    98  			bsStore.TestSetMembershipError(errors.New("sorry"))
    99  
   100  			value, detail, err := client.BoolVariationDetail(evalFlagKey, evalTestUser, false)
   101  			require.NoError(t, err)
   102  			assert.False(t, value)
   103  			assert.Equal(t, ldreason.BigSegmentsStoreError, detail.Reason.GetBigSegmentsStatus())
   104  		})
   105  	})
   106  
   107  	t.Run("store not configured", func(t *testing.T) {
   108  		// deliberately not using a configuration with a Big Segment store here
   109  		withClientEvalTestParams(func(p clientEvalTestParams) {
   110  			addBigSegmentAndFlag(p.data)
   111  
   112  			value, detail, err := p.client.BoolVariationDetail(evalFlagKey, evalTestUser, false)
   113  			require.NoError(t, err)
   114  			assert.False(t, value)
   115  			assert.Equal(t, ldreason.BigSegmentsNotConfigured, detail.Reason.GetBigSegmentsStatus())
   116  		})
   117  	})
   118  }
   119  

View as plain text