1818package decision
1919
2020import (
21+ "sync"
2122 "testing"
2223
2324 "github.com/optimizely/go-sdk/pkg/decision/reasons"
@@ -28,16 +29,16 @@ import (
2829type ExperimentOverrideServiceTestSuite struct {
2930 suite.Suite
3031 mockConfig * mockProjectConfig
31- overrides map [ ExperimentOverrideKey ] string
32+ overrides * MapExperimentOverridesStore
3233 overrideService * ExperimentOverrideService
3334}
3435
3536func (s * ExperimentOverrideServiceTestSuite ) SetupTest () {
3637 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 )
4142}
4243
4344func (s * ExperimentOverrideServiceTestSuite ) TestOverridesIncludeVariation () {
@@ -48,7 +49,7 @@ func (s *ExperimentOverrideServiceTestSuite) TestOverridesIncludeVariation() {
4849 testUserContext := entities.UserContext {
4950 ID : "test_user_1" ,
5051 }
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 )
5253 decision , err := s .overrideService .GetDecision (testDecisionContext , testUserContext )
5354 s .NoError (err )
5455 s .NotNil (decision .Variation )
@@ -77,7 +78,7 @@ func (s *ExperimentOverrideServiceTestSuite) TestNoOverrideForExperiment() {
7778 ID : "test_user_1" ,
7879 }
7980 // 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 )
8182 decision , err := s .overrideService .GetDecision (testDecisionContext , testUserContext )
8283 s .NoError (err )
8384 s .Nil (decision .Variation )
@@ -93,7 +94,7 @@ func (s *ExperimentOverrideServiceTestSuite) TestNoOverrideForUser() {
9394 ID : "test_user_1" ,
9495 }
9596 // 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 )
9798 decision , err := s .overrideService .GetDecision (testDecisionContext , testUserContext )
9899 s .NoError (err )
99100 s .Nil (decision .Variation )
@@ -109,7 +110,7 @@ func (s *ExperimentOverrideServiceTestSuite) TestNoOverrideForUserOrExperiment()
109110 ID : "test_user_1" ,
110111 }
111112 // 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 )
113114 decision , err := s .overrideService .GetDecision (testDecisionContext , testUserContext )
114115 s .NoError (err )
115116 s .Nil (decision .Variation )
@@ -125,13 +126,69 @@ func (s *ExperimentOverrideServiceTestSuite) TestInvalidVariationInOverride() {
125126 ID : "test_user_1" ,
126127 }
127128 // 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" )
129130 decision , err := s .overrideService .GetDecision (testDecisionContext , testUserContext )
130131 s .NoError (err )
131132 s .Nil (decision .Variation )
132133 s .Exactly (reasons .InvalidOverrideVariationAssignment , decision .Reason )
133134}
134135
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+
135192func TestExperimentOverridesTestSuite (t * testing.T ) {
136193 suite .Run (t , new (ExperimentOverrideServiceTestSuite ))
137194}
0 commit comments