@@ -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+
21172233func 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+ }
0 commit comments