Repository: Unleash/unleash-client-go
Pull request #149 (2023-11-20 12:24:30)

chore: Revert breaking changes on v3
## About the changes
Revert changes on v3 that are major changes. They're already in v4 branch


Patch:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index a9f1f2c..802b75a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -15,7 +15,7 @@ jobs:
         name: Checkout client specifications
         with:
           repository: Unleash/client-specification
-          ref: refs/tags/v5.0.2
+          ref: refs/tags/v4.5.2
           path: testdata/client-specification
       - uses: actions/setup-go@v2
         name: Setup go
@@ -26,6 +26,7 @@ jobs:
       - name: Go vet
         run: go vet ./...
       - name: Run all tests
+        timeout-minutes: 1
         run: go test -race -covermode atomic -coverprofile=profile.cov -v ./...
       - name: Send coverage
         uses: shogo82148/actions-goveralls@v1
diff --git a/api/feature.go b/api/feature.go
index 58cbbfa..085d4bb 100644
--- a/api/feature.go
+++ b/api/feature.go
@@ -1,12 +1,13 @@
 package api
 
 import (
+	"fmt"
 	"math/rand"
 	"strconv"
 	"time"
 
 	"github.com/Unleash/unleash-client-go/v3/context"
-	"github.com/Unleash/unleash-client-go/v3/internal/strategies"
+	"github.com/twmb/murmur3"
 )
 
 type ParameterMap map[string]interface{}
@@ -104,7 +105,7 @@ func (vc VariantCollection) getVariantFromWeights(ctx *context.Context) *Variant
 	}
 	stickiness := vc.Variants[0].Stickiness
 
-	target := strategies.NormalizedVariantValue(getSeed(ctx, stickiness), vc.GroupId, totalWeight, strategies.VariantNormalizationSeed)
+	target := getNormalizedNumber(getSeed(ctx, stickiness), vc.GroupId, totalWeight)
 	counter := uint32(0)
 	for _, variant := range vc.Variants {
 		counter += uint32(variant.Weight)
@@ -147,3 +148,7 @@ func getSeed(ctx *context.Context, stickiness string) string {
 	}
 	return strconv.Itoa(rand.Intn(10000))
 }
+
+func getNormalizedNumber(identifier, groupId string, normalizer int) uint32 {
+	return (murmur3.Sum32([]byte(fmt.Sprintf("%s:%s", groupId, identifier))) % uint32(normalizer)) + 1
+}
diff --git a/client.go b/client.go
index 837cae6..7e6160e 100644
--- a/client.go
+++ b/client.go
@@ -17,7 +17,7 @@ import (
 const (
 	deprecatedSuffix = "/features"
 	clientName       = "unleash-client-go"
-	clientVersion    = "4.0.0"
+	clientVersion    = "3.9.1"
 )
 
 var defaultStrategies = []strategy.Strategy{
diff --git a/internal/strategies/flexible_rollout.go b/internal/strategies/flexible_rollout.go
index e07ad90..5d2cebb 100644
--- a/internal/strategies/flexible_rollout.go
+++ b/internal/strategies/flexible_rollout.go
@@ -62,6 +62,6 @@ func (s flexibleRolloutStrategy) IsEnabled(params map[string]interface{}, ctx *c
 		return false
 	}
 
-	normalizedID := normalizedRolloutValue(stickinessID, groupID)
+	normalizedID := normalizedValue(stickinessID, groupID)
 	return percentage > 0 && float64(normalizedID) <= percentage
 }
diff --git a/internal/strategies/gradual_rollout_session_id.go b/internal/strategies/gradual_rollout_session_id.go
index 66536bc..18541d9 100644
--- a/internal/strategies/gradual_rollout_session_id.go
+++ b/internal/strategies/gradual_rollout_session_id.go
@@ -38,7 +38,7 @@ func (s gradualRolloutSessionId) IsEnabled(params map[string]interface{}, ctx *c
 		return false
 	}
 
-	normalizedId := normalizedRolloutValue(ctx.SessionId, groupId)
+	normalizedId := normalizedValue(ctx.SessionId, groupId)
 
 	return percentage > 0.0 && float64(normalizedId) <= percentage
 }
diff --git a/internal/strategies/gradual_rollout_user_id.go b/internal/strategies/gradual_rollout_user_id.go
index 852fc2b..02c649e 100644
--- a/internal/strategies/gradual_rollout_user_id.go
+++ b/internal/strategies/gradual_rollout_user_id.go
@@ -38,7 +38,7 @@ func (s gradualRolloutUserId) IsEnabled(params map[string]interface{}, ctx *cont
 		return false
 	}
 
-	normalizedId := normalizedRolloutValue(ctx.UserId, groupId)
+	normalizedId := normalizedValue(ctx.UserId, groupId)
 
 	return percentage > 0.0 && float64(normalizedId) <= percentage
 }
diff --git a/internal/strategies/helpers.go b/internal/strategies/helpers.go
index cd541e8..236281c 100644
--- a/internal/strategies/helpers.go
+++ b/internal/strategies/helpers.go
@@ -10,8 +10,6 @@ import (
 	"github.com/twmb/murmur3"
 )
 
-var VariantNormalizationSeed uint32 = 86028157
-
 func round(f float64) int {
 	if f < -0.5 {
 		return int(f - 0.5)
@@ -52,15 +50,11 @@ func parameterAsFloat64(param interface{}) (result float64, ok bool) {
 	return
 }
 
-func normalizedRolloutValue(id string, groupId string) uint32 {
-	return NormalizedVariantValue(id, groupId, 100, 0)
-}
-
-func NormalizedVariantValue(id string, groupId string, normalizer int, seed uint32) uint32 {
-	hash := murmur3.SeedNew32(seed)
+func normalizedValue(id string, groupId string) uint32 {
+	hash := murmur3.New32()
 	hash.Write([]byte(groupId + ":" + id))
 	hashCode := hash.Sum32()
-	return hashCode%uint32(normalizer) + 1
+	return hashCode%uint32(100) + 1
 }
 
 // coalesce returns the first non-empty string in the list of arguments


Test patch:
diff --git a/api/variant_test.go b/api/variant_test.go
index 2bce29d..47c6761 100644
--- a/api/variant_test.go
+++ b/api/variant_test.go
@@ -221,7 +221,7 @@ func (suite *VariantTestSuite) TestGetVariant_ShouldReturnVarD() {
 		GroupId:  mockFeature.Name,
 		Variants: mockFeature.Variants,
 	}.GetVariant(mockContext)
-	suite.Equal("VarE", variantSetup.Name, "Should return VarE")
+	suite.Equal("VarD", variantSetup.Name, "Should return VarD")
 	suite.Equal(true, variantSetup.Enabled, "Should be equal")
 }
 
@@ -238,7 +238,7 @@ func (suite *VariantTestSuite) TestGetVariant_ShouldReturnVarE() {
 		GroupId:  mockFeature.Name,
 		Variants: mockFeature.Variants,
 	}.GetVariant(mockContext)
-	suite.Equal("VarF", variantSetup.Name, "Should return VarF")
+	suite.Equal("VarE", variantSetup.Name, "Should return VarE")
 	suite.Equal(true, variantSetup.Enabled, "Should be equal")
 }
 
@@ -255,7 +255,7 @@ func (suite *VariantTestSuite) TestGetVariant_ShouldReturnVarF() {
 		GroupId:  mockFeature.Name,
 		Variants: mockFeature.Variants,
 	}.GetVariant(mockContext)
-	suite.Equal("VarE", variantSetup.Name, "Should return VarE")
+	suite.Equal("VarF", variantSetup.Name, "Should return VarF")
 	suite.Equal(true, variantSetup.Enabled, "Should be equal")
 }
 
diff --git a/internal/strategies/gradual_rollout_session_id_test.go b/internal/strategies/gradual_rollout_session_id_test.go
index 6cc9744..b402872 100644
--- a/internal/strategies/gradual_rollout_session_id_test.go
+++ b/internal/strategies/gradual_rollout_session_id_test.go
@@ -42,7 +42,7 @@ func TestGradualRolloutSessionId_IsEnabled(t *testing.T) {
 	t.Run("p1=p2", func(t *testing.T) {
 		sessionId := "123123"
 		groupId := "group1"
-		percentage := normalizedRolloutValue(sessionId, groupId)
+		percentage := normalizedValue(sessionId, groupId)
 
 		params := map[string]interface{}{
 			strategy.ParamPercentage: percentage,
@@ -57,7 +57,7 @@ func TestGradualRolloutSessionId_IsEnabled(t *testing.T) {
 	t.Run("p1<p2", func(t *testing.T) {
 		sessionId := "123123"
 		groupId := "group1"
-		percentage := normalizedRolloutValue(sessionId, groupId) - 1
+		percentage := normalizedValue(sessionId, groupId) - 1
 
 		params := map[string]interface{}{
 			strategy.ParamPercentage: percentage,
diff --git a/internal/strategies/gradual_rollout_user_id_test.go b/internal/strategies/gradual_rollout_user_id_test.go
index 8674796..ac8cadf 100644
--- a/internal/strategies/gradual_rollout_user_id_test.go
+++ b/internal/strategies/gradual_rollout_user_id_test.go
@@ -43,7 +43,7 @@ func TestGradualRolloutUserId_IsEnabled(t *testing.T) {
 	t.Run("p1=p2", func(t *testing.T) {
 		userId := "123123"
 		groupId := "group1"
-		percentage := normalizedRolloutValue(userId, groupId)
+		percentage := normalizedValue(userId, groupId)
 
 		params := map[string]interface{}{
 			strategy.ParamPercentage: percentage,
@@ -58,7 +58,7 @@ func TestGradualRolloutUserId_IsEnabled(t *testing.T) {
 	t.Run("p1<p2", func(t *testing.T) {
 		userId := "123123"
 		groupId := "group1"
-		percentage := normalizedRolloutValue(userId, groupId) - 1
+		percentage := normalizedValue(userId, groupId) - 1
 
 		params := map[string]interface{}{
 			strategy.ParamPercentage: percentage,
diff --git a/internal/strategies/helpers_test.go b/internal/strategies/helpers_test.go
index fe24e38..da7e395 100644
--- a/internal/strategies/helpers_test.go
+++ b/internal/strategies/helpers_test.go
@@ -53,14 +53,9 @@ func TestParameterAsFloat64(t *testing.T) {
 	}
 }
 
-func TestNormalizedRolloutValue(t *testing.T) {
-	assert.Equal(t, uint32(73), normalizedRolloutValue("123", "gr1"))
-	assert.Equal(t, uint32(25), normalizedRolloutValue("999", "groupX"))
-}
-
-func TestNormalizedVariantValue(t *testing.T) {
-	assert.Equal(t, uint32(96), NormalizedVariantValue("123", "gr1", 100, VariantNormalizationSeed))
-	assert.Equal(t, uint32(60), NormalizedVariantValue("999", "groupX", 100, VariantNormalizationSeed))
+func TestNormalizedValue(t *testing.T) {
+	assert.Equal(t, uint32(73), normalizedValue("123", "gr1"))
+	assert.Equal(t, uint32(25), normalizedValue("999", "groupX"))
 }
 
 func TestCoalesce(t *testing.T) {
@@ -114,14 +109,14 @@ func BenchmarkNormalizedValue(b *testing.B) {
 	b.Run("value less than 32 bytes", func(b *testing.B) {
 		b.ReportAllocs()
 		for i := 0; i < b.N; i++ {
-			_ = normalizedRolloutValue(smallId, smallGroup)
+			_ = normalizedValue(smallId, smallGroup)
 		}
 	})
 
 	b.Run("value greater than 32 bytes", func(b *testing.B) {
 		b.ReportAllocs()
 		for i := 0; i < b.N; i++ {
-			_ = normalizedRolloutValue(largeId, largeGroup)
+			_ = normalizedValue(largeId, largeGroup)
 		}
 	})
 }