11/****************************************************************************
2- * Copyright 2020-2021 , Optimizely, Inc. and contributors *
2+ * Copyright 2020-2022 , Optimizely, Inc. and contributors *
33 * *
44 * Licensed under the Apache License, Version 2.0 (the "License"); *
55 * you may not use this file except in compliance with the License. *
66 * You may obtain a copy of the License at *
77 * *
8- * http ://www.apache.org/licenses/LICENSE-2.0 *
8+ * https ://www.apache.org/licenses/LICENSE-2.0 *
99 * *
1010 * Unless required by applicable law or agreed to in writing, software *
1111 * distributed under the License is distributed on an "AS IS" BASIS, *
@@ -55,65 +55,83 @@ func (s *OptimizelyUserContextTestSuite) SetupTest() {
5555 s .userID = "tester"
5656}
5757
58- func (s * OptimizelyUserContextTestSuite ) TestOptimizelyUserContextWithAttributes () {
58+ func (s * OptimizelyUserContextTestSuite ) TestOptimizelyUserContextWithAttributesAndSegments () {
5959 attributes := map [string ]interface {}{"key1" : 1212 , "key2" : 1213 }
60- optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , s .userID , attributes , nil )
60+ segments := []string {"123" }
61+ optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , s .userID , attributes , segments , nil )
6162
6263 s .Equal (s .OptimizelyClient , optimizelyUserContext .GetOptimizely ())
6364 s .Equal (s .userID , optimizelyUserContext .GetUserID ())
6465 s .Equal (attributes , optimizelyUserContext .GetUserAttributes ())
66+ s .Equal (segments , optimizelyUserContext .GetQualifiedSegments ())
6567 s .Nil (optimizelyUserContext .forcedDecisionService )
6668}
6769
68- func (s * OptimizelyUserContextTestSuite ) TestOptimizelyUserContextNoAttributes () {
70+ func (s * OptimizelyUserContextTestSuite ) TestOptimizelyUserContextNoAttributesAndNilSegments () {
6971 attributes := map [string ]interface {}{}
70- optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , s .userID , attributes , nil )
72+ optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , s .userID , attributes , nil , nil )
7173
7274 s .Equal (s .OptimizelyClient , optimizelyUserContext .GetOptimizely ())
7375 s .Equal (s .userID , optimizelyUserContext .GetUserID ())
7476 s .Equal (attributes , optimizelyUserContext .GetUserAttributes ())
77+ s .Nil (optimizelyUserContext .GetQualifiedSegments ())
7578}
7679
7780func (s * OptimizelyUserContextTestSuite ) TestUpatingProvidedUserContextHasNoImpactOnOptimizelyUserContext () {
7881 attributes := map [string ]interface {}{"k1" : "v1" , "k2" : false }
79- optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , s .userID , attributes , nil )
82+ segments := []string {"123" }
83+ optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , s .userID , attributes , segments , nil )
8084
8185 s .Equal (s .OptimizelyClient , optimizelyUserContext .GetOptimizely ())
8286 s .Equal (s .userID , optimizelyUserContext .GetUserID ())
8387 s .Equal (attributes , optimizelyUserContext .GetUserAttributes ())
88+ s .Equal (segments , optimizelyUserContext .GetQualifiedSegments ())
8489
8590 attributes ["k1" ] = "v2"
8691 attributes ["k2" ] = true
92+ segments [0 ] = "456"
8793
8894 s .Equal ("v1" , optimizelyUserContext .GetUserAttributes ()["k1" ])
8995 s .Equal (false , optimizelyUserContext .GetUserAttributes ()["k2" ])
96+ s .Equal ([]string {"123" }, optimizelyUserContext .GetQualifiedSegments ())
9097
9198 attributes = optimizelyUserContext .GetUserAttributes ()
99+ segments = optimizelyUserContext .GetQualifiedSegments ()
92100 attributes ["k1" ] = "v2"
93101 attributes ["k2" ] = true
102+ segments [0 ] = "456"
94103
95104 s .Equal ("v1" , optimizelyUserContext .GetUserAttributes ()["k1" ])
96105 s .Equal (false , optimizelyUserContext .GetUserAttributes ()["k2" ])
106+ s .Equal ([]string {"123" }, optimizelyUserContext .GetQualifiedSegments ())
97107}
98108
99- func (s * OptimizelyUserContextTestSuite ) TestSetAttribute () {
109+ func (s * OptimizelyUserContextTestSuite ) TestSetAndGetUserAttributesRaceCondition () {
100110 userID := "1212121"
101111 var attributes map [string ]interface {}
102112
103- optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , userID , attributes , nil )
113+ optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , userID , attributes , nil , nil )
104114 s .Equal (s .OptimizelyClient , optimizelyUserContext .GetOptimizely ())
105115
106116 var wg sync.WaitGroup
107- wg .Add (4 )
117+ wg .Add (8 )
108118 addInsideGoRoutine := func (key string , value interface {}, wg * sync.WaitGroup ) {
109119 optimizelyUserContext .SetAttribute (key , value )
110120 wg .Done ()
111121 }
122+ getInsideGoRoutine := func (wg * sync.WaitGroup ) {
123+ optimizelyUserContext .GetUserAttributes ()
124+ wg .Done ()
125+ }
112126
113127 go addInsideGoRoutine ("k1" , "v1" , & wg )
114128 go addInsideGoRoutine ("k2" , true , & wg )
115129 go addInsideGoRoutine ("k3" , 100 , & wg )
116130 go addInsideGoRoutine ("k4" , 3.5 , & wg )
131+ go getInsideGoRoutine (& wg )
132+ go getInsideGoRoutine (& wg )
133+ go getInsideGoRoutine (& wg )
134+ go getInsideGoRoutine (& wg )
117135 wg .Wait ()
118136
119137 s .Equal (userID , optimizelyUserContext .GetUserID ())
@@ -126,7 +144,7 @@ func (s *OptimizelyUserContextTestSuite) TestSetAttribute() {
126144func (s * OptimizelyUserContextTestSuite ) TestSetAttributeOverride () {
127145 userID := "1212121"
128146 attributes := map [string ]interface {}{"k1" : "v1" , "k2" : false }
129- optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , userID , attributes , nil )
147+ optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , userID , attributes , nil , nil )
130148
131149 s .Equal (s .OptimizelyClient , optimizelyUserContext .GetOptimizely ())
132150 s .Equal (userID , optimizelyUserContext .GetUserID ())
@@ -142,7 +160,7 @@ func (s *OptimizelyUserContextTestSuite) TestSetAttributeOverride() {
142160func (s * OptimizelyUserContextTestSuite ) TestSetAttributeNullValue () {
143161 userID := "1212121"
144162 attributes := map [string ]interface {}{"k1" : nil }
145- optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , userID , attributes , nil )
163+ optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , userID , attributes , nil , nil )
146164
147165 s .Equal (s .OptimizelyClient , optimizelyUserContext .GetOptimizely ())
148166 s .Equal (userID , optimizelyUserContext .GetUserID ())
@@ -155,6 +173,87 @@ func (s *OptimizelyUserContextTestSuite) TestSetAttributeNullValue() {
155173 s .Equal (nil , optimizelyUserContext .GetUserAttributes ()["k1" ])
156174}
157175
176+ func (s * OptimizelyUserContextTestSuite ) TestSetAndGetQualifiedSegments () {
177+ userID := "1212121"
178+ var attributes map [string ]interface {}
179+ qualifiedSegments := []string {"1" , "2" , "3" }
180+ optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , userID , attributes , []string {}, nil )
181+ s .Len (optimizelyUserContext .GetQualifiedSegments (), 0 )
182+
183+ optimizelyUserContext .SetQualifiedSegments (nil )
184+ s .Nil (optimizelyUserContext .GetQualifiedSegments ())
185+
186+ optimizelyUserContext .SetQualifiedSegments (qualifiedSegments )
187+ s .Equal (qualifiedSegments , optimizelyUserContext .GetQualifiedSegments ())
188+ }
189+
190+ func (s * OptimizelyUserContextTestSuite ) TestQualifiedSegmentsRaceCondition () {
191+ userID := "1212121"
192+ qualifiedSegments := []string {"1" , "2" , "3" }
193+ segment := "1"
194+ var attributes map [string ]interface {}
195+
196+ optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , userID , attributes , nil , nil )
197+ s .Nil (optimizelyUserContext .GetQualifiedSegments ())
198+ var wg sync.WaitGroup
199+ wg .Add (9 )
200+
201+ setQualifiedSegments := func (value []string , wg * sync.WaitGroup ) {
202+ optimizelyUserContext .SetQualifiedSegments (value )
203+ wg .Done ()
204+ }
205+ getQualifiedSegments := func (wg * sync.WaitGroup ) {
206+ optimizelyUserContext .GetQualifiedSegments ()
207+ wg .Done ()
208+ }
209+
210+ IsQualifiedFor := func (segment string , wg * sync.WaitGroup ) {
211+ optimizelyUserContext .IsQualifiedFor (segment )
212+ wg .Done ()
213+ }
214+
215+ go setQualifiedSegments (qualifiedSegments , & wg )
216+ go setQualifiedSegments (qualifiedSegments , & wg )
217+ go setQualifiedSegments (qualifiedSegments , & wg )
218+ go getQualifiedSegments (& wg )
219+ go getQualifiedSegments (& wg )
220+ go getQualifiedSegments (& wg )
221+ go IsQualifiedFor (segment , & wg )
222+ go IsQualifiedFor (segment , & wg )
223+ go IsQualifiedFor (segment , & wg )
224+
225+ wg .Wait ()
226+
227+ s .Equal (qualifiedSegments , optimizelyUserContext .GetQualifiedSegments ())
228+ s .Equal (true , optimizelyUserContext .IsQualifiedFor (segment ))
229+ }
230+
231+ func (s * OptimizelyUserContextTestSuite ) TestIsQualifiedFor () {
232+ userID := "1212121"
233+ qualifiedSegments := []string {"1" , "2" , "3" }
234+ var attributes map [string ]interface {}
235+
236+ optimizelyUserContext := newOptimizelyUserContext (s .OptimizelyClient , userID , attributes , nil , nil )
237+ s .False (optimizelyUserContext .IsQualifiedFor ("1" ))
238+ optimizelyUserContext .SetQualifiedSegments (qualifiedSegments )
239+
240+ var wg sync.WaitGroup
241+ wg .Add (6 )
242+ testInsideGoRoutine := func (value string , result bool , wg * sync.WaitGroup ) {
243+ s .Equal (result , optimizelyUserContext .IsQualifiedFor (value ))
244+ wg .Done ()
245+ }
246+
247+ go testInsideGoRoutine ("1" , true , & wg )
248+ go testInsideGoRoutine ("2" , true , & wg )
249+ go testInsideGoRoutine ("3" , true , & wg )
250+ go testInsideGoRoutine ("4" , false , & wg )
251+ go testInsideGoRoutine ("5" , false , & wg )
252+ go testInsideGoRoutine ("6" , false , & wg )
253+
254+ wg .Wait ()
255+ }
256+
158257func (s * OptimizelyUserContextTestSuite ) TestDecideResponseContainsUserContextCopy () {
159258 flagKey := "feature_2"
160259 userContext := s .OptimizelyClient .CreateUserContext (s .userID , nil )
@@ -163,8 +262,11 @@ func (s *OptimizelyUserContextTestSuite) TestDecideResponseContainsUserContextCo
163262
164263 // Change attributes for user context
165264 userContext .SetAttribute ("test" , 123 )
166- // Attributes should not update for the userContext returned inside decision
265+ // Change qualifiedSegments for user context
266+ userContext .SetQualifiedSegments ([]string {"123" })
267+ // Attributes and qualifiedSegments should not update for the userContext returned inside decision
167268 s .Nil (decisionUserContext .Attributes ["test" ])
269+ s .Len (decisionUserContext .qualifiedSegments , 0 )
168270}
169271
170272func (s * OptimizelyUserContextTestSuite ) TestDecideFeatureTest () {
0 commit comments