@@ -42,19 +42,19 @@ public class BucketerHoldoutTest
42
42
public void Initialize ( )
43
43
{
44
44
LoggerMock = new Mock < ILogger > ( ) ;
45
-
45
+
46
46
// Load holdout test data
47
47
var testDataPath = Path . Combine ( TestContext . CurrentContext . TestDirectory ,
48
48
"TestData" , "HoldoutTestData.json" ) ;
49
49
var jsonContent = File . ReadAllText ( testDataPath ) ;
50
50
TestData = JObject . Parse ( jsonContent ) ;
51
-
51
+
52
52
// Use datafile with holdouts for proper config setup
53
53
var datafileWithHoldouts = TestData [ "datafileWithHoldouts" ] . ToString ( ) ;
54
54
Config = DatafileProjectConfig . Create ( datafileWithHoldouts , LoggerMock . Object ,
55
55
new ErrorHandler . NoOpErrorHandler ( ) ) ;
56
56
TestBucketer = new TestBucketer ( LoggerMock . Object ) ;
57
-
57
+
58
58
// Verify that the config contains holdouts
59
59
Assert . IsNotNull ( Config . Holdouts , "Config should have holdouts" ) ;
60
60
Assert . IsTrue ( Config . Holdouts . Length > 0 , "Config should contain holdouts" ) ;
@@ -76,10 +76,10 @@ public void TestBucketHoldout_ValidTrafficAllocation()
76
76
Assert . IsNotNull ( result . ResultObject ) ;
77
77
Assert . AreEqual ( "var_1" , result . ResultObject . Id ) ;
78
78
Assert . AreEqual ( "control" , result . ResultObject . Key ) ;
79
-
79
+
80
80
// Verify logging
81
- LoggerMock . Verify ( l => l . Log ( LogLevel . DEBUG ,
82
- It . Is < string > ( s => s . Contains ( $ "Assigned bucket [2500] to user [{ TestUserId } ]") ) ) ,
81
+ LoggerMock . Verify ( l => l . Log ( LogLevel . DEBUG ,
82
+ It . Is < string > ( s => s . Contains ( $ "Assigned bucket [2500] to user [{ TestUserId } ]") ) ) ,
83
83
Times . Once ) ;
84
84
}
85
85
@@ -89,7 +89,7 @@ public void TestBucketHoldout_UserOutsideAllocation()
89
89
// Test user not bucketed when outside traffic allocation range
90
90
var holdoutJson = TestData [ "globalHoldout" ] . ToString ( ) ;
91
91
var holdout = JsonConvert . DeserializeObject < Holdout > ( holdoutJson ) ;
92
-
92
+
93
93
// Modify traffic allocation to be smaller (0-1000 range = 10%)
94
94
holdout . TrafficAllocation [ 0 ] . EndOfRange = 1000 ;
95
95
@@ -100,10 +100,10 @@ public void TestBucketHoldout_UserOutsideAllocation()
100
100
101
101
Assert . IsNull ( result . ResultObject . Id ) ;
102
102
Assert . IsNull ( result . ResultObject . Key ) ;
103
-
103
+
104
104
// Verify user was assigned bucket value but no variation was found
105
- LoggerMock . Verify ( l => l . Log ( LogLevel . DEBUG ,
106
- It . Is < string > ( s => s . Contains ( $ "Assigned bucket [1500] to user [{ TestUserId } ]") ) ) ,
105
+ LoggerMock . Verify ( l => l . Log ( LogLevel . DEBUG ,
106
+ It . Is < string > ( s => s . Contains ( $ "Assigned bucket [1500] to user [{ TestUserId } ]") ) ) ,
107
107
Times . Once ) ;
108
108
}
109
109
@@ -113,7 +113,7 @@ public void TestBucketHoldout_NoTrafficAllocation()
113
113
// Test holdout with empty traffic allocation
114
114
var holdoutJson = TestData [ "globalHoldout" ] . ToString ( ) ;
115
115
var holdout = JsonConvert . DeserializeObject < Holdout > ( holdoutJson ) ;
116
-
116
+
117
117
// Clear traffic allocation
118
118
holdout . TrafficAllocation = new TrafficAllocation [ 0 ] ;
119
119
@@ -123,10 +123,10 @@ public void TestBucketHoldout_NoTrafficAllocation()
123
123
124
124
Assert . IsNull ( result . ResultObject . Id ) ;
125
125
Assert . IsNull ( result . ResultObject . Key ) ;
126
-
126
+
127
127
// Verify bucket was assigned but no variation found
128
- LoggerMock . Verify ( l => l . Log ( LogLevel . DEBUG ,
129
- It . Is < string > ( s => s . Contains ( $ "Assigned bucket [5000] to user [{ TestUserId } ]") ) ) ,
128
+ LoggerMock . Verify ( l => l . Log ( LogLevel . DEBUG ,
129
+ It . Is < string > ( s => s . Contains ( $ "Assigned bucket [5000] to user [{ TestUserId } ]") ) ) ,
130
130
Times . Once ) ;
131
131
}
132
132
@@ -136,7 +136,7 @@ public void TestBucketHoldout_InvalidVariationId()
136
136
// Test holdout with invalid variation ID in traffic allocation
137
137
var holdoutJson = TestData [ "globalHoldout" ] . ToString ( ) ;
138
138
var holdout = JsonConvert . DeserializeObject < Holdout > ( holdoutJson ) ;
139
-
139
+
140
140
// Set traffic allocation to point to non-existent variation
141
141
holdout . TrafficAllocation [ 0 ] . EntityId = "invalid_variation_id" ;
142
142
@@ -146,10 +146,10 @@ public void TestBucketHoldout_InvalidVariationId()
146
146
147
147
Assert . IsNull ( result . ResultObject . Id ) ;
148
148
Assert . IsNull ( result . ResultObject . Key ) ;
149
-
149
+
150
150
// Verify bucket was assigned
151
- LoggerMock . Verify ( l => l . Log ( LogLevel . DEBUG ,
152
- It . Is < string > ( s => s . Contains ( $ "Assigned bucket [5000] to user [{ TestUserId } ]") ) ) ,
151
+ LoggerMock . Verify ( l => l . Log ( LogLevel . DEBUG ,
152
+ It . Is < string > ( s => s . Contains ( $ "Assigned bucket [5000] to user [{ TestUserId } ]") ) ) ,
153
153
Times . Once ) ;
154
154
}
155
155
@@ -167,10 +167,10 @@ public void TestBucketHoldout_EmptyVariations()
167
167
168
168
Assert . IsNull ( result . ResultObject . Id ) ;
169
169
Assert . IsNull ( result . ResultObject . Key ) ;
170
-
170
+
171
171
// Verify bucket was assigned
172
- LoggerMock . Verify ( l => l . Log ( LogLevel . DEBUG ,
173
- It . Is < string > ( s => s . Contains ( $ "Assigned bucket [5000] to user [{ TestUserId } ]") ) ) ,
172
+ LoggerMock . Verify ( l => l . Log ( LogLevel . DEBUG ,
173
+ It . Is < string > ( s => s . Contains ( $ "Assigned bucket [5000] to user [{ TestUserId } ]") ) ) ,
174
174
Times . Once ) ;
175
175
}
176
176
@@ -180,7 +180,7 @@ public void TestBucketHoldout_EmptyExperimentKey()
180
180
// Test holdout with empty key
181
181
var holdoutJson = TestData [ "globalHoldout" ] . ToString ( ) ;
182
182
var holdout = JsonConvert . DeserializeObject < Holdout > ( holdoutJson ) ;
183
-
183
+
184
184
// Clear holdout key
185
185
holdout . Key = "" ;
186
186
@@ -200,7 +200,7 @@ public void TestBucketHoldout_NullExperimentKey()
200
200
// Test holdout with null key
201
201
var holdoutJson = TestData [ "globalHoldout" ] . ToString ( ) ;
202
202
var holdout = JsonConvert . DeserializeObject < Holdout > ( holdoutJson ) ;
203
-
203
+
204
204
// Set holdout key to null
205
205
holdout . Key = null ;
206
206
@@ -220,7 +220,7 @@ public void TestBucketHoldout_MultipleVariationsInRange()
220
220
// Test holdout with multiple variations and user buckets into first one
221
221
var holdoutJson = TestData [ "globalHoldout" ] . ToString ( ) ;
222
222
var holdout = JsonConvert . DeserializeObject < Holdout > ( holdoutJson ) ;
223
-
223
+
224
224
// Add a second variation
225
225
var variation2 = new Variation
226
226
{
@@ -229,7 +229,7 @@ public void TestBucketHoldout_MultipleVariationsInRange()
229
229
FeatureEnabled = true
230
230
} ;
231
231
holdout . Variations = new [ ] { holdout . Variations [ 0 ] , variation2 } ;
232
-
232
+
233
233
// Set traffic allocation for first variation (0-5000) and second (5000-10000)
234
234
holdout . TrafficAllocation = new [ ]
235
235
{
@@ -253,7 +253,7 @@ public void TestBucketHoldout_MultipleVariationsInSecondRange()
253
253
// Use the global holdout from config which now has multiple variations
254
254
var holdout = Config . GetHoldout ( "holdout_global_1" ) ;
255
255
Assert . IsNotNull ( holdout , "Holdout should exist in config" ) ;
256
-
256
+
257
257
// Verify holdout has multiple variations
258
258
Assert . IsTrue ( holdout . Variations . Length >= 2 , "Holdout should have multiple variations" ) ;
259
259
Assert . AreEqual ( "var_1" , holdout . Variations [ 0 ] . Id ) ;
@@ -274,7 +274,7 @@ public void TestBucketHoldout_EdgeCaseBoundaryValues()
274
274
// Test edge cases at traffic allocation boundaries
275
275
var holdoutJson = TestData [ "globalHoldout" ] . ToString ( ) ;
276
276
var holdout = JsonConvert . DeserializeObject < Holdout > ( holdoutJson ) ;
277
-
277
+
278
278
// Set traffic allocation to 5000 (50%)
279
279
holdout . TrafficAllocation [ 0 ] . EndOfRange = 5000 ;
280
280
@@ -308,7 +308,7 @@ public void TestBucketHoldout_ConsistentBucketingWithSameInputs()
308
308
// Results should be identical
309
309
Assert . IsNotNull ( result1 ) ;
310
310
Assert . IsNotNull ( result2 ) ;
311
-
311
+
312
312
if ( result1 . ResultObject ? . Id != null )
313
313
{
314
314
Assert . AreEqual ( result1 . ResultObject . Id , result2 . ResultObject . Id ) ;
0 commit comments