@@ -27,6 +27,7 @@ import (
27
27
"github.com/optimizely/go-sdk/v2/pkg/decide"
28
28
"github.com/optimizely/go-sdk/v2/pkg/entities"
29
29
"github.com/optimizely/go-sdk/v2/pkg/logging"
30
+ "github.com/stretchr/testify/assert"
30
31
"github.com/stretchr/testify/mock"
31
32
"github.com/stretchr/testify/suite"
32
33
"github.com/twmb/murmur3"
@@ -843,3 +844,54 @@ func (s *CmabServiceTestSuite) TestGetDecisionApiError() {
843
844
s .mockCache .AssertExpectations (s .T ())
844
845
s .mockClient .AssertExpectations (s .T ())
845
846
}
847
+
848
+
849
+ // TestLockStripingDistribution verifies that different user/rule combinations
850
+ // use different locks to allow for better concurrency
851
+ func TestLockStripingDistribution (t * testing.T ) {
852
+ service := & DefaultCmabService {}
853
+
854
+ // Test different combinations to ensure they get different lock indices
855
+ testCases := []struct {
856
+ userID string
857
+ ruleID string
858
+ }{
859
+ {"user1" , "rule1" },
860
+ {"user2" , "rule1" },
861
+ {"user1" , "rule2" },
862
+ {"user3" , "rule3" },
863
+ {"user4" , "rule4" },
864
+ }
865
+
866
+ lockIndices := make (map [int ]bool )
867
+ for _ , tc := range testCases {
868
+ index := service .getLockIndex (tc .userID , tc .ruleID )
869
+
870
+ // Verify index is within expected range
871
+ assert .GreaterOrEqual (t , index , 0 , "Lock index should be non-negative" )
872
+ assert .Less (t , index , NumLockStripes , "Lock index should be less than NumLockStripes" )
873
+
874
+ lockIndices [index ] = true
875
+ }
876
+
877
+ // We should have multiple different lock indices (though not necessarily all unique due to hash collisions)
878
+ assert .Greater (t , len (lockIndices ), 1 , "Different user/rule combinations should generally use different locks" )
879
+ }
880
+
881
+ // TestSameUserRuleCombinationUsesConsistentLock verifies that the same user/rule combination
882
+ // always uses the same lock index
883
+ func TestSameUserRuleCombinationUsesConsistentLock (t * testing.T ) {
884
+ service := & DefaultCmabService {}
885
+
886
+ userID := "test_user"
887
+ ruleID := "test_rule"
888
+
889
+ // Get lock index multiple times
890
+ index1 := service .getLockIndex (userID , ruleID )
891
+ index2 := service .getLockIndex (userID , ruleID )
892
+ index3 := service .getLockIndex (userID , ruleID )
893
+
894
+ // All should be the same
895
+ assert .Equal (t , index1 , index2 , "Same user/rule should always use same lock" )
896
+ assert .Equal (t , index2 , index3 , "Same user/rule should always use same lock" )
897
+ }
0 commit comments