18
18
package decision
19
19
20
20
import (
21
+ "sync"
21
22
"testing"
22
23
23
24
"github.com/optimizely/go-sdk/pkg/decision/reasons"
@@ -28,16 +29,16 @@ import (
28
29
type ExperimentOverrideServiceTestSuite struct {
29
30
suite.Suite
30
31
mockConfig * mockProjectConfig
31
- overrides map [ ExperimentOverrideKey ] string
32
+ overrides * MapExperimentOverridesStore
32
33
overrideService * ExperimentOverrideService
33
34
}
34
35
35
36
func (s * ExperimentOverrideServiceTestSuite ) SetupTest () {
36
37
s .mockConfig = new (mockProjectConfig )
37
- s .overrides = make ( map [ ExperimentOverrideKey ] string )
38
- s . overrideService = NewExperimentOverrideService ( & MapOverridesStore {
39
- overridesMap : s . overrides ,
40
- } )
38
+ s .overrides = & MapExperimentOverridesStore {
39
+ overridesMap : make ( map [ ExperimentOverrideKey ] string ),
40
+ }
41
+ s . overrideService = NewExperimentOverrideService ( s . overrides )
41
42
}
42
43
43
44
func (s * ExperimentOverrideServiceTestSuite ) TestOverridesIncludeVariation () {
@@ -48,7 +49,7 @@ func (s *ExperimentOverrideServiceTestSuite) TestOverridesIncludeVariation() {
48
49
testUserContext := entities.UserContext {
49
50
ID : "test_user_1" ,
50
51
}
51
- s .overrides [ ExperimentOverrideKey {ExperimentKey : testExp1111 .Key , UserID : "test_user_1" }] = testExp1111Var2222 .Key
52
+ s .overrides . SetVariation ( ExperimentOverrideKey {ExperimentKey : testExp1111 .Key , UserID : "test_user_1" }, testExp1111Var2222 .Key )
52
53
decision , err := s .overrideService .GetDecision (testDecisionContext , testUserContext )
53
54
s .NoError (err )
54
55
s .NotNil (decision .Variation )
@@ -77,7 +78,7 @@ func (s *ExperimentOverrideServiceTestSuite) TestNoOverrideForExperiment() {
77
78
ID : "test_user_1" ,
78
79
}
79
80
// The decision context refers to testExp1111, but this override is for another experiment
80
- s .overrides [ ExperimentOverrideKey {ExperimentKey : testExp1113 .Key , UserID : "test_user_1" }] = testExp1113Var2224 .Key
81
+ s .overrides . SetVariation ( ExperimentOverrideKey {ExperimentKey : testExp1113 .Key , UserID : "test_user_1" }, testExp1113Var2224 .Key )
81
82
decision , err := s .overrideService .GetDecision (testDecisionContext , testUserContext )
82
83
s .NoError (err )
83
84
s .Nil (decision .Variation )
@@ -93,7 +94,7 @@ func (s *ExperimentOverrideServiceTestSuite) TestNoOverrideForUser() {
93
94
ID : "test_user_1" ,
94
95
}
95
96
// The user context refers to "test_user_1", but this override is for another user
96
- s .overrides [ ExperimentOverrideKey {ExperimentKey : testExp1111 .Key , UserID : "test_user_2" }] = testExp1111Var2222 .Key
97
+ s .overrides . SetVariation ( ExperimentOverrideKey {ExperimentKey : testExp1111 .Key , UserID : "test_user_2" }, testExp1111Var2222 .Key )
97
98
decision , err := s .overrideService .GetDecision (testDecisionContext , testUserContext )
98
99
s .NoError (err )
99
100
s .Nil (decision .Variation )
@@ -109,7 +110,7 @@ func (s *ExperimentOverrideServiceTestSuite) TestNoOverrideForUserOrExperiment()
109
110
ID : "test_user_1" ,
110
111
}
111
112
// This override is for both a different user and a different experiment than the ones in the contexts above
112
- s .overrides [ ExperimentOverrideKey {ExperimentKey : testExp1113 .Key , UserID : "test_user_3" }] = testExp1111Var2222 .Key
113
+ s .overrides . SetVariation ( ExperimentOverrideKey {ExperimentKey : testExp1113 .Key , UserID : "test_user_3" }, testExp1111Var2222 .Key )
113
114
decision , err := s .overrideService .GetDecision (testDecisionContext , testUserContext )
114
115
s .NoError (err )
115
116
s .Nil (decision .Variation )
@@ -125,13 +126,69 @@ func (s *ExperimentOverrideServiceTestSuite) TestInvalidVariationInOverride() {
125
126
ID : "test_user_1" ,
126
127
}
127
128
// This override variation key does not exist in the experiment
128
- s .overrides [ ExperimentOverrideKey {ExperimentKey : testExp1111 .Key , UserID : "test_user_1" }] = "invalid_variation_key"
129
+ s .overrides . SetVariation ( ExperimentOverrideKey {ExperimentKey : testExp1111 .Key , UserID : "test_user_1" }, "invalid_variation_key" )
129
130
decision , err := s .overrideService .GetDecision (testDecisionContext , testUserContext )
130
131
s .NoError (err )
131
132
s .Nil (decision .Variation )
132
133
s .Exactly (reasons .InvalidOverrideVariationAssignment , decision .Reason )
133
134
}
134
135
136
+ // Test concurrent use of the MapExperimentOverrideStore
137
+ // Create 3 goroutines that set and get variations, and assert that all their sets take effect at the end
138
+ func (s * ExperimentOverrideServiceTestSuite ) TestMapExperimentOverridesStoreConcurrent () {
139
+ testDecisionContext := ExperimentDecisionContext {
140
+ Experiment : & testExp1111 ,
141
+ ProjectConfig : s .mockConfig ,
142
+ }
143
+ var wg sync.WaitGroup
144
+ wg .Add (1 )
145
+ go func () {
146
+ s .overrides .SetVariation (ExperimentOverrideKey {ExperimentKey : testExp1111 .Key , UserID : "test_user_1" }, testExp1111Var2222 .Key )
147
+ user1Decision , _ := s .overrideService .GetDecision (testDecisionContext , entities.UserContext {
148
+ ID : "test_user_1" ,
149
+ })
150
+ s .NotNil (user1Decision .Variation )
151
+ s .Exactly (testExp1111Var2222 .Key , user1Decision .Variation .Key )
152
+ wg .Done ()
153
+ }()
154
+ wg .Add (1 )
155
+ go func () {
156
+ s .overrides .SetVariation (ExperimentOverrideKey {ExperimentKey : testExp1111 .Key , UserID : "test_user_2" }, testExp1111Var2222 .Key )
157
+ user2Decision , _ := s .overrideService .GetDecision (testDecisionContext , entities.UserContext {
158
+ ID : "test_user_2" ,
159
+ })
160
+ s .NotNil (user2Decision .Variation )
161
+ s .Exactly (testExp1111Var2222 .Key , user2Decision .Variation .Key )
162
+ wg .Done ()
163
+ }()
164
+ wg .Add (1 )
165
+ go func () {
166
+ s .overrides .SetVariation (ExperimentOverrideKey {ExperimentKey : testExp1111 .Key , UserID : "test_user_3" }, testExp1111Var2222 .Key )
167
+ user3Decision , _ := s .overrideService .GetDecision (testDecisionContext , entities.UserContext {
168
+ ID : "test_user_3" ,
169
+ })
170
+ s .NotNil (user3Decision .Variation )
171
+ s .Exactly (testExp1111Var2222 .Key , user3Decision .Variation .Key )
172
+ wg .Done ()
173
+ }()
174
+ wg .Wait ()
175
+ user1Decision , _ := s .overrideService .GetDecision (testDecisionContext , entities.UserContext {
176
+ ID : "test_user_1" ,
177
+ })
178
+ user2Decision , _ := s .overrideService .GetDecision (testDecisionContext , entities.UserContext {
179
+ ID : "test_user_2" ,
180
+ })
181
+ user3Decision , _ := s .overrideService .GetDecision (testDecisionContext , entities.UserContext {
182
+ ID : "test_user_3" ,
183
+ })
184
+ s .NotNil (user1Decision .Variation )
185
+ s .Exactly (testExp1111Var2222 .Key , user1Decision .Variation .Key )
186
+ s .NotNil (user2Decision .Variation )
187
+ s .Exactly (testExp1111Var2222 .Key , user2Decision .Variation .Key )
188
+ s .NotNil (user3Decision .Variation )
189
+ s .Exactly (testExp1111Var2222 .Key , user3Decision .Variation .Key )
190
+ }
191
+
135
192
func TestExperimentOverridesTestSuite (t * testing.T ) {
136
193
suite .Run (t , new (ExperimentOverrideServiceTestSuite ))
137
194
}
0 commit comments