Skip to content

Commit 6e3ad55

Browse files
authored
Merge pull request #218 from splitio/SDKS-8369
Add test cases for semver and unsupported matcher
2 parents 21cbbf8 + 680f920 commit 6e3ad55

File tree

5 files changed

+593
-2
lines changed

5 files changed

+593
-2
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/splitio/go-client/v6
33
go 1.18
44

55
require (
6-
github.com/splitio/go-split-commons/v5 v5.2.2-0.20240510211202-3c3300ae55ce
6+
github.com/splitio/go-split-commons/v5 v5.2.2-0.20240513192200-9e60c1ddc0f3
77
github.com/splitio/go-toolkit/v5 v5.4.0
88
)
99

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ github.com/redis/go-redis/v9 v9.0.4 h1:FC82T+CHJ/Q/PdyLW++GeCO+Ol59Y4T7R4jbgjvkt
1212
github.com/redis/go-redis/v9 v9.0.4/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=
1313
github.com/splitio/go-split-commons/v5 v5.2.2-0.20240510211202-3c3300ae55ce h1:aZ+p/vi2sOD0NsWCny93qQl1uJC30b/wnpMcUVt7WEI=
1414
github.com/splitio/go-split-commons/v5 v5.2.2-0.20240510211202-3c3300ae55ce/go.mod h1:344KP05ULARzjRfnC4VtGSyu5l3kmIM375WUIzrURs0=
15+
github.com/splitio/go-split-commons/v5 v5.2.2-0.20240513192200-9e60c1ddc0f3 h1:ARgFL9kuUOYX5U1afUbWSMp3fvB7LeWsTDNWWDT9Hl8=
16+
github.com/splitio/go-split-commons/v5 v5.2.2-0.20240513192200-9e60c1ddc0f3/go.mod h1:344KP05ULARzjRfnC4VtGSyu5l3kmIM375WUIzrURs0=
1517
github.com/splitio/go-toolkit/v5 v5.4.0 h1:g5WFpRhQomnXCmvfsNOWV4s5AuUrWIZ+amM68G8NBKM=
1618
github.com/splitio/go-toolkit/v5 v5.4.0/go.mod h1:xYhUvV1gga9/1029Wbp5pjnR6Cy8nvBpjw99wAbsMko=
1719
github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg=

splitio/client/client_test.go

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2114,6 +2114,122 @@ func TestClientDebug(t *testing.T) {
21142114
}
21152115
}
21162116

2117+
func TestUnsupportedMatcherAndSemver(t *testing.T) {
2118+
var isDestroyCalled = false
2119+
var splitsMock, _ = ioutil.ReadFile("../../testdata/splits_mock_3.json")
2120+
2121+
postChannel := make(chan string, 1)
2122+
2123+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2124+
switch r.URL.Path {
2125+
case "/api/v2/auth":
2126+
if r.URL.Query().Get("s") != "1.1" {
2127+
t.Error("should be parameter s, for flags spec")
2128+
}
2129+
fmt.Fprintln(w, "{\"pushEnabled\": false, \"token\": \"token\"}")
2130+
return
2131+
case "/splitChanges":
2132+
fmt.Fprintln(w, string(splitsMock))
2133+
return
2134+
case "/testImpressions/bulk":
2135+
if r.Header.Get("SplitSDKImpressionsMode") != commonsCfg.ImpressionsModeOptimized {
2136+
t.Error("Wrong header")
2137+
}
2138+
2139+
if isDestroyCalled {
2140+
rBody, _ := ioutil.ReadAll(r.Body)
2141+
var dataInPost []map[string]interface{}
2142+
err := json.Unmarshal(rBody, &dataInPost)
2143+
if err != nil {
2144+
t.Error(err)
2145+
return
2146+
}
2147+
if len(dataInPost) != 6 {
2148+
t.Error("It should send two impressions in optimized mode")
2149+
}
2150+
for _, ki := range dataInPost {
2151+
if asISlice, ok := ki["i"].([]interface{}); !ok || len(asISlice) != 1 {
2152+
t.Error("It should send only one impression per featureName", dataInPost)
2153+
}
2154+
if ki["f"] == "unsupported" {
2155+
message := ki["i"].([]interface{})[0].(map[string]interface{})["r"]
2156+
if message != "targeting rule type unsupported by sdk" {
2157+
t.Error("message sould be: targeting rule type unsupported by sdk")
2158+
}
2159+
}
2160+
}
2161+
}
2162+
2163+
fmt.Fprintln(w, "ok")
2164+
postChannel <- "finished"
2165+
case "/testImpressions/count":
2166+
fallthrough
2167+
case "/keys/ss":
2168+
fallthrough
2169+
case "/events/bulk":
2170+
fallthrough
2171+
case "/segmentChanges":
2172+
fallthrough
2173+
default:
2174+
fmt.Fprintln(w, "ok")
2175+
}
2176+
}))
2177+
defer ts.Close()
2178+
2179+
cfg := conf.Default()
2180+
cfg.Advanced.AuthServiceURL = ts.URL
2181+
cfg.Advanced.EventsURL = ts.URL
2182+
cfg.Advanced.SdkURL = ts.URL
2183+
cfg.Advanced.TelemetryServiceURL = ts.URL
2184+
2185+
factory, _ := NewSplitFactory("test", cfg)
2186+
client := factory.Client()
2187+
client.BlockUntilReady(2)
2188+
2189+
// Calls treatments to generate one valid impression
2190+
time.Sleep(300 * time.Millisecond) // Let's wait until first call of recorders have finished
2191+
attributes := make(map[string]interface{})
2192+
attributes["version"] = "1.22.9"
2193+
evaluation := client.Treatment("user1", "semver", attributes)
2194+
if evaluation != "on" {
2195+
t.Error("evaluation for semver should be on")
2196+
}
2197+
attributes["version"] = "2.0.0"
2198+
evaluation = client.Treatment("user1", "semver1", attributes)
2199+
if evaluation != "on" {
2200+
t.Error("evaluation for semver should be on")
2201+
}
2202+
evaluation = client.Treatment("user1", "semver2", attributes)
2203+
if evaluation != "on" {
2204+
t.Error("evaluation for semver should be on")
2205+
}
2206+
attributes["version"] = "1.0.0"
2207+
evaluation = client.Treatment("user1", "semver3", attributes)
2208+
if evaluation != "on" {
2209+
t.Error("evaluation for semver should be on")
2210+
}
2211+
attributes["version"] = "2.1.0"
2212+
evaluation = client.Treatment("user1", "semver4", attributes)
2213+
if evaluation != "on" {
2214+
t.Error("evaluation for semver should be on")
2215+
}
2216+
evaluation = client.Treatment("user1", "unsupported", nil)
2217+
if evaluation != "control" {
2218+
t.Error("evaluation for unsupported should be control")
2219+
}
2220+
2221+
isDestroyCalled = true
2222+
client.Destroy()
2223+
2224+
select {
2225+
case <-postChannel:
2226+
return
2227+
case <-time.After(4 * time.Second):
2228+
t.Error("The test couldn't send impressions to check headers")
2229+
return
2230+
}
2231+
}
2232+
21172233
func TestTelemetryMemory(t *testing.T) {
21182234
factoryInstances = make(map[string]int64)
21192235
var metricsInitCalled int64
@@ -2633,3 +2749,157 @@ func TestClientDebugRedis(t *testing.T) {
26332749
prefixedClient.Del(k)
26342750
}
26352751
}
2752+
2753+
var semver string = "3.4.5"
2754+
var attribute string = "version"
2755+
2756+
var splitSemver = &dtos.SplitDTO{
2757+
Algo: 2,
2758+
ChangeNumber: 1494593336752,
2759+
DefaultTreatment: "off",
2760+
Killed: false,
2761+
Name: "semver",
2762+
Seed: -1992295819,
2763+
Status: "ACTIVE",
2764+
TrafficAllocation: 100,
2765+
TrafficAllocationSeed: -285565213,
2766+
TrafficTypeName: "user",
2767+
Configurations: map[string]string{"on": "{\"color\": \"blue\",\"size\": 13}"},
2768+
Conditions: []dtos.ConditionDTO{
2769+
{
2770+
ConditionType: "ROLLOUT",
2771+
Label: "default rule",
2772+
MatcherGroup: dtos.MatcherGroupDTO{
2773+
Combiner: "AND",
2774+
Matchers: []dtos.MatcherDTO{
2775+
{
2776+
KeySelector: &dtos.KeySelectorDTO{
2777+
TrafficType: "user",
2778+
Attribute: &attribute,
2779+
},
2780+
MatcherType: "EQUAL_TO_SEMVER",
2781+
String: &semver,
2782+
Whitelist: nil,
2783+
Negate: false,
2784+
},
2785+
},
2786+
},
2787+
Partitions: []dtos.PartitionDTO{
2788+
{
2789+
Size: 100,
2790+
Treatment: "on",
2791+
},
2792+
{
2793+
Size: 0,
2794+
Treatment: "off",
2795+
},
2796+
},
2797+
},
2798+
},
2799+
}
2800+
2801+
var splitUnsupported = &dtos.SplitDTO{
2802+
Algo: 2,
2803+
ChangeNumber: 1494593336752,
2804+
DefaultTreatment: "off",
2805+
Killed: false,
2806+
Name: "unsupported",
2807+
Seed: -1992295819,
2808+
Status: "ACTIVE",
2809+
TrafficAllocation: 100,
2810+
TrafficAllocationSeed: -285565213,
2811+
TrafficTypeName: "user",
2812+
Configurations: map[string]string{"on": "{\"color\": \"blue\",\"size\": 13}"},
2813+
Conditions: []dtos.ConditionDTO{
2814+
{
2815+
ConditionType: "ROLLOUT",
2816+
Label: "default rule",
2817+
MatcherGroup: dtos.MatcherGroupDTO{
2818+
Combiner: "AND",
2819+
Matchers: []dtos.MatcherDTO{
2820+
{
2821+
KeySelector: &dtos.KeySelectorDTO{
2822+
TrafficType: "user",
2823+
Attribute: nil,
2824+
},
2825+
MatcherType: "UNSUPPORTED",
2826+
Whitelist: nil,
2827+
Negate: false,
2828+
},
2829+
},
2830+
},
2831+
Partitions: []dtos.PartitionDTO{
2832+
{
2833+
Size: 100,
2834+
Treatment: "on",
2835+
},
2836+
},
2837+
},
2838+
},
2839+
}
2840+
2841+
func TestUnsupportedandSemverMatcherRedis(t *testing.T) {
2842+
redisConfig := &commonsCfg.RedisConfig{
2843+
Host: "localhost",
2844+
Port: 6379,
2845+
Password: "",
2846+
Prefix: "test-prefix-semver",
2847+
}
2848+
2849+
prefixedClient, _ := redis.NewRedisClient(redisConfig, logging.NewLogger(&logging.LoggerOptions{}))
2850+
raw, _ := json.Marshal(*splitSemver)
2851+
prefixedClient.Set("SPLITIO.split.semver", raw, 0)
2852+
raw, _ = json.Marshal(*splitUnsupported)
2853+
prefixedClient.Set("SPLITIO.split.unsupported", raw, 0)
2854+
2855+
impTest := &ImpressionListenerTest{}
2856+
cfg := conf.Default()
2857+
cfg.LabelsEnabled = true
2858+
cfg.Advanced.ImpressionListener = impTest
2859+
cfg.ImpressionsMode = commonsCfg.ImpressionsModeOptimized
2860+
cfg.OperationMode = conf.RedisConsumer
2861+
cfg.Redis = *redisConfig
2862+
2863+
factory, _ := NewSplitFactory("test", cfg)
2864+
client := factory.Client()
2865+
client.BlockUntilReady(2)
2866+
2867+
// Calls treatments to generate one valid impression
2868+
time.Sleep(300 * time.Millisecond) // Let's wait until first call of recorders have finished
2869+
attributes := make(map[string]interface{})
2870+
attributes["version"] = "3.4.5"
2871+
evaluation := client.Treatment("user1", "semver", attributes)
2872+
if evaluation != "on" {
2873+
t.Error("evaluation for semver should be on")
2874+
}
2875+
evaluation = client.Treatment("user2", "unsupported", nil)
2876+
if evaluation != "control" {
2877+
t.Error("evaluation for unsupported should be control")
2878+
}
2879+
client.Destroy()
2880+
2881+
// Validate impressions
2882+
impressions, _ := prefixedClient.LRange("SPLITIO.impressions", 0, -1)
2883+
2884+
if len(impressions) != 2 {
2885+
t.Error("Impression length shold be 2")
2886+
}
2887+
2888+
for _, imp := range impressions {
2889+
var imprObject dtos.ImpressionQueueObject
2890+
_ = json.Unmarshal([]byte(imp), &imprObject)
2891+
2892+
if imprObject.Impression.KeyName == "user1" && imprObject.Impression.FeatureName == "semver" && imprObject.Impression.Pt != 0 {
2893+
t.Error("Pt should be 0.")
2894+
}
2895+
if imprObject.Impression.KeyName == "user2" && imprObject.Impression.FeatureName == "unsupported" && imprObject.Impression.Pt != 0 {
2896+
t.Error("Pt should be 0.")
2897+
}
2898+
}
2899+
2900+
// Clean redis
2901+
keys, _ := prefixedClient.Keys("SPLITIO*")
2902+
for _, k := range keys {
2903+
prefixedClient.Del(k)
2904+
}
2905+
}

splitio/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
package splitio
22

33
// Version contains a string with the split sdk version
4-
const Version = "6.6.0-rc1"
4+
const Version = "6.6.0-rc2"

0 commit comments

Comments
 (0)