Skip to content

Commit 714de6d

Browse files
Json simple config parser test cases add for holdout
1 parent e3a596e commit 714de6d

File tree

12 files changed

+1222
-62
lines changed

12 files changed

+1222
-62
lines changed

core-api/src/main/java/com/optimizely/ab/config/DatafileProjectConfig.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ public class DatafileProjectConfig implements ProjectConfig {
7070
private final List<Audience> typedAudiences;
7171
private final List<EventType> events;
7272
private final List<Experiment> experiments;
73-
private final List<Holdout> holdouts;
7473
private final List<FeatureFlag> featureFlags;
7574
private final List<Group> groups;
7675
private final List<Rollout> rollouts;
@@ -218,12 +217,12 @@ public DatafileProjectConfig(String accountId,
218217
allExperiments.addAll(experiments);
219218
allExperiments.addAll(aggregateGroupExperiments(groups));
220219
this.experiments = Collections.unmodifiableList(allExperiments);
220+
221221
if (holdouts == null) {
222-
this.holdouts = Collections.emptyList();
222+
this.holdoutConfig = new HoldoutConfig();
223223
} else {
224-
this.holdouts = Collections.unmodifiableList(holdouts);
224+
this.holdoutConfig = new HoldoutConfig(holdouts);
225225
}
226-
this.holdoutConfig = new HoldoutConfig(this.holdouts);
227226

228227
String publicKeyForODP = "";
229228
String hostForODP = "";
@@ -473,8 +472,7 @@ public List<Experiment> getExperiments() {
473472
}
474473

475474
@Override
476-
public List<Holdout> getHoldouts() {
477-
return holdoutConfig.getAllHoldouts(); }
475+
public List<Holdout> getHoldouts() { return holdoutConfig.getAllHoldouts(); }
478476

479477
@Override
480478
public Set<String> getAllSegments() {

core-api/src/main/java/com/optimizely/ab/config/Holdout.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ public class Holdout implements ExperimentCore {
5454

5555
private final Map<String, Variation> variationKeyToVariationMap;
5656
private final Map<String, Variation> variationIdToVariationMap;
57-
private final Map<String, String> userIdToVariationKeyMap;
5857
// Not necessary for HO
5958
private final String layerId = "";
6059

@@ -78,7 +77,7 @@ public String toString() {
7877

7978
@VisibleForTesting
8079
public Holdout(String id, String key) {
81-
this(id, key, null, Collections.emptyList(), null, Collections.emptyList(), Collections.emptyMap(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), "");
80+
this(id, key, null, Collections.emptyList(), null, Collections.emptyList(), Collections.emptyList(), null, null, "");
8281
}
8382

8483
@JsonCreator
@@ -88,11 +87,10 @@ public Holdout(@JsonProperty("id") String id,
8887
@JsonProperty("audienceIds") List<String> audienceIds,
8988
@JsonProperty("audienceConditions") Condition audienceConditions,
9089
@JsonProperty("variations") List<Variation> variations,
91-
@JsonProperty("forcedVariations") Map<String, String> userIdToVariationKeyMap,
9290
@JsonProperty("trafficAllocation") List<TrafficAllocation> trafficAllocation,
9391
@JsonProperty("includedFlags") List<String> includedFlags,
9492
@JsonProperty("excludedFlags") List<String> excludedFlags) {
95-
this(id, key, status, audienceIds, audienceConditions, variations, userIdToVariationKeyMap, trafficAllocation, includedFlags, excludedFlags, "");
93+
this(id, key, status, audienceIds, audienceConditions, variations, trafficAllocation, includedFlags, excludedFlags, "");
9694
}
9795

9896
public Holdout(@Nonnull String id,
@@ -101,7 +99,6 @@ public Holdout(@Nonnull String id,
10199
@Nonnull List<String> audienceIds,
102100
@Nullable Condition audienceConditions,
103101
@Nonnull List<Variation> variations,
104-
@Nonnull Map<String, String> userIdToVariationKeyMap,
105102
@Nonnull List<TrafficAllocation> trafficAllocation,
106103
@Nullable List<String> includedFlags,
107104
@Nullable List<String> excludedFlags,
@@ -116,7 +113,6 @@ public Holdout(@Nonnull String id,
116113
this.includedFlags = includedFlags == null ? Collections.emptyList() : Collections.unmodifiableList(includedFlags);
117114
this.excludedFlags = excludedFlags == null ? Collections.emptyList() : Collections.unmodifiableList(excludedFlags);
118115
this.groupId = groupId;
119-
this.userIdToVariationKeyMap = userIdToVariationKeyMap;
120116
this.variationKeyToVariationMap = ProjectConfigUtils.generateNameMapping(variations);
121117
this.variationIdToVariationMap = ProjectConfigUtils.generateIdMapping(variations);
122118
}
@@ -157,10 +153,6 @@ public Map<String, Variation> getVariationIdToVariationMap() {
157153
return variationIdToVariationMap;
158154
}
159155

160-
public Map<String, String> getUserIdToVariationKeyMap() {
161-
return userIdToVariationKeyMap;
162-
}
163-
164156
public List<TrafficAllocation> getTrafficAllocation() {
165157
return trafficAllocation;
166158
}
@@ -192,7 +184,6 @@ public String toString() {
192184
", audienceConditions=" + audienceConditions +
193185
", variations=" + variations +
194186
", variationKeyToVariationMap=" + variationKeyToVariationMap +
195-
", userIdToVariationKeyMap=" + userIdToVariationKeyMap +
196187
", trafficAllocation=" + trafficAllocation +
197188
'}';
198189
}

core-api/src/main/java/com/optimizely/ab/config/Variation.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class Variation implements IdKeyMapped {
4242
private final Map<String, FeatureVariableUsageInstance> variableIdToFeatureVariableUsageInstanceMap;
4343

4444
public Variation(String id, String key) {
45-
this(id, key, null);
45+
this(id, key, false, null);
4646
}
4747

4848
public Variation(String id,
@@ -51,6 +51,13 @@ public Variation(String id,
5151
this(id, key, false, featureVariableUsageInstances);
5252
}
5353

54+
public Variation(String id,
55+
String key,
56+
Boolean featureEnabled) {
57+
this(id, key, featureEnabled, null);
58+
}
59+
60+
5461
@JsonCreator
5562
public Variation(@JsonProperty("id") String id,
5663
@JsonProperty("key") String key,

core-api/src/main/java/com/optimizely/ab/config/parser/GsonHelpers.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,6 @@ static Holdout parseHoldout(JsonObject holdoutJson, String groupId, JsonDeserial
169169

170170
// parse the child objects
171171
List<Variation> variations = parseVariations(holdoutJson.getAsJsonArray("variations"), context);
172-
Map<String, String> userIdToVariationKeyMap =
173-
parseForcedVariations(holdoutJson.getAsJsonObject("forcedVariations"));
174172
List<TrafficAllocation> trafficAllocations =
175173
parseTrafficAllocation(holdoutJson.getAsJsonArray("trafficAllocation"));
176174

@@ -190,8 +188,7 @@ static Holdout parseHoldout(JsonObject holdoutJson, String groupId, JsonDeserial
190188
}
191189
}
192190

193-
return new Holdout(id, key, status, audienceIds, conditions, variations, userIdToVariationKeyMap,
194-
trafficAllocations, includedFlags, excludedFlags, groupId);
191+
return new Holdout(id, key, status, audienceIds, conditions, variations, trafficAllocations, includedFlags, excludedFlags, groupId);
195192
}
196193

197194
static Holdout parseHoldout(JsonObject holdoutJson, JsonDeserializationContext context) {

core-api/src/main/java/com/optimizely/ab/config/parser/JsonConfigParser.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,7 @@ private List<Holdout> parseHoldouts(JSONArray holdoutJson, String groupId) {
204204

205205
// parse the child objects
206206
List<Variation> variations = parseVariations(holdoutObject.getJSONArray("variations"));
207-
Map<String, String> userIdToVariationKeyMap =
208-
parseForcedVariations(holdoutObject.getJSONObject("forcedVariations"));
207+
209208
List<TrafficAllocation> trafficAllocations =
210209
parseTrafficAllocation(holdoutObject.getJSONArray("trafficAllocation"));
211210

@@ -235,7 +234,7 @@ private List<Holdout> parseHoldouts(JSONArray holdoutJson, String groupId) {
235234
excludedFlags = Collections.emptyList();
236235
}
237236

238-
holdouts.add(new Holdout(id, key, status, audienceIds, conditions, variations, userIdToVariationKeyMap,
237+
holdouts.add(new Holdout(id, key, status, audienceIds, conditions, variations,
239238
trafficAllocations, includedFlags, excludedFlags, groupId));
240239
}
241240

core-api/src/main/java/com/optimizely/ab/config/parser/JsonSimpleConfigParser.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,7 @@ private List<Holdout> parseHoldouts(JSONArray holdoutJson, String groupId) {
214214
}
215215
// parse the child objects
216216
List<Variation> variations = parseVariations((JSONArray) hoObject.get("variations"));
217-
Map<String, String> userIdToVariationKeyMap =
218-
parseForcedVariations((JSONObject) hoObject.get("forcedVariations"));
217+
219218
List<TrafficAllocation> trafficAllocations =
220219
parseTrafficAllocation((JSONArray) hoObject.get("trafficAllocation"));
221220

@@ -233,7 +232,7 @@ private List<Holdout> parseHoldouts(JSONArray holdoutJson, String groupId) {
233232
excludedFlags = Collections.emptyList();
234233
}
235234

236-
holdouts.add(new Holdout(id, key, status, audienceIds, conditions, variations, userIdToVariationKeyMap,
235+
holdouts.add(new Holdout(id, key, status, audienceIds, conditions, variations,
237236
trafficAllocations, includedFlags, excludedFlags, groupId));
238237
}
239238

core-api/src/test/java/com/optimizely/ab/config/DatafileProjectConfigTestUtils.java

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,35 @@
1616
*/
1717
package com.optimizely.ab.config;
1818

19-
import com.google.common.base.Charsets;
20-
import com.google.common.io.Resources;
21-
import com.optimizely.ab.config.audience.AndCondition;
22-
import com.optimizely.ab.config.audience.Audience;
23-
import com.optimizely.ab.config.audience.Condition;
24-
import com.optimizely.ab.config.audience.NotCondition;
25-
import com.optimizely.ab.config.audience.OrCondition;
26-
import com.optimizely.ab.config.audience.UserAttribute;
27-
28-
import javax.annotation.CheckForNull;
29-
import javax.annotation.Nonnull;
3019
import java.io.IOException;
3120
import java.util.ArrayList;
3221
import java.util.Arrays;
22+
import static java.util.Arrays.asList;
3323
import java.util.Collections;
24+
import static java.util.Collections.singletonList;
3425
import java.util.HashMap;
3526
import java.util.Iterator;
3627
import java.util.List;
3728
import java.util.Map;
3829

39-
import static java.util.Arrays.asList;
40-
import static java.util.Collections.singletonList;
30+
import javax.annotation.CheckForNull;
31+
import javax.annotation.Nonnull;
32+
4133
import static org.hamcrest.CoreMatchers.is;
4234
import static org.junit.Assert.assertEquals;
4335
import static org.junit.Assert.assertNotNull;
4436
import static org.junit.Assert.assertNull;
4537
import static org.junit.Assert.assertThat;
4638

39+
import com.google.common.base.Charsets;
40+
import com.google.common.io.Resources;
41+
import com.optimizely.ab.config.audience.AndCondition;
42+
import com.optimizely.ab.config.audience.Audience;
43+
import com.optimizely.ab.config.audience.Condition;
44+
import com.optimizely.ab.config.audience.NotCondition;
45+
import com.optimizely.ab.config.audience.OrCondition;
46+
import com.optimizely.ab.config.audience.UserAttribute;
47+
4748
/**
4849
* Helper class that provides common functionality and resources for testing {@link DatafileProjectConfig}.
4950
*/
@@ -382,11 +383,16 @@ private static ProjectConfig generateNoAudienceProjectConfigV3() {
382383
}
383384

384385
private static final ProjectConfig VALID_PROJECT_CONFIG_V4 = generateValidProjectConfigV4();
386+
private static final ProjectConfig VALID_PROJECT_CONFIG_V4_HOLDOUT = generateValidProjectConfigV4_holdout();
385387

386388
private static ProjectConfig generateValidProjectConfigV4() {
387389
return ValidProjectConfigV4.generateValidProjectConfigV4();
388390
}
389391

392+
private static ProjectConfig generateValidProjectConfigV4_holdout() {
393+
return ValidProjectConfigV4.generateValidProjectConfigV4_holdout();
394+
}
395+
390396
private DatafileProjectConfigTestUtils() {
391397
}
392398

@@ -410,6 +416,10 @@ public static String validConfigJsonV4() throws IOException {
410416
return Resources.toString(Resources.getResource("config/valid-project-config-v4.json"), Charsets.UTF_8);
411417
}
412418

419+
public static String validConfigHoldoutJsonV4() throws IOException {
420+
return Resources.toString(Resources.getResource("config/holdouts-project-config.json"), Charsets.UTF_8);
421+
}
422+
413423
public static String nullFeatureEnabledConfigJsonV4() throws IOException {
414424
return Resources.toString(Resources.getResource("config/null-featureEnabled-config-v4.json"), Charsets.UTF_8);
415425
}
@@ -446,6 +456,10 @@ public static ProjectConfig validProjectConfigV4() {
446456
return VALID_PROJECT_CONFIG_V4;
447457
}
448458

459+
public static ProjectConfig validProjectConfigV4_holdout() {
460+
return VALID_PROJECT_CONFIG_V4_HOLDOUT;
461+
}
462+
449463
/**
450464
* @return the expected {@link DatafileProjectConfig} for the json produced by {@link #invalidProjectConfigV5()}
451465
*/
@@ -471,6 +485,7 @@ public static void verifyProjectConfig(@CheckForNull ProjectConfig actual, @Nonn
471485
verifyAudiences(actual.getTypedAudiences(), expected.getTypedAudiences());
472486
verifyEvents(actual.getEventTypes(), expected.getEventTypes());
473487
verifyExperiments(actual.getExperiments(), expected.getExperiments());
488+
verifyHoldouts(actual.getHoldouts(), expected.getHoldouts());
474489
verifyFeatureFlags(actual.getFeatureFlags(), expected.getFeatureFlags());
475490
verifyGroups(actual.getGroups(), expected.getGroups());
476491
verifyRollouts(actual.getRollouts(), expected.getRollouts());
@@ -502,6 +517,37 @@ private static void verifyExperiments(List<Experiment> actual, List<Experiment>
502517
}
503518
}
504519

520+
private static void verifyHoldouts(List<Holdout> actual, List<Holdout> expected) {
521+
// print the holdouts for debugging BEFORE assertion
522+
// System.out.println("Actual holdouts: " + actual);
523+
// System.out.println("Expected holdouts: " + expected);
524+
// System.out.println("Actual size: " + actual.size());
525+
// System.out.println("Expected size: " + expected.size());
526+
527+
assertThat(actual.size(), is(expected.size()));
528+
529+
530+
for (int i = 0; i < actual.size(); i++) {
531+
Holdout actualHoldout = actual.get(i);
532+
Holdout expectedHoldout = expected.get(i);
533+
534+
assertThat(actualHoldout.getId(), is(expectedHoldout.getId()));
535+
assertThat(actualHoldout.getKey(), is(expectedHoldout.getKey()));
536+
assertThat(actualHoldout.getGroupId(), is(expectedHoldout.getGroupId()));
537+
assertThat(actualHoldout.getStatus(), is(expectedHoldout.getStatus()));
538+
assertThat(actualHoldout.getAudienceIds(), is(expectedHoldout.getAudienceIds()));
539+
/// debug print audience conditions
540+
// System.out.println("Actual audience conditions: " + actualHoldout.getAudienceConditions());
541+
// System.out.println("Expected audience conditions: " + expectedHoldout.getAudienceConditions());
542+
assertThat(actualHoldout.getAudienceConditions(), is(expectedHoldout.getAudienceConditions()));
543+
assertThat(actualHoldout.getIncludedFlags(), is(expectedHoldout.getIncludedFlags()));
544+
assertThat(actualHoldout.getExcludedFlags(), is(expectedHoldout.getExcludedFlags()));
545+
verifyVariations(actualHoldout.getVariations(), expectedHoldout.getVariations());
546+
verifyTrafficAllocations(actualHoldout.getTrafficAllocation(),
547+
expectedHoldout.getTrafficAllocation());
548+
}
549+
}
550+
505551
private static void verifyFeatureFlags(List<FeatureFlag> actual, List<FeatureFlag> expected) {
506552
assertEquals(expected.size(), actual.size());
507553
for (int i = 0; i < actual.size(); i++) {

core-api/src/test/java/com/optimizely/ab/config/HoldoutTest.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,21 @@
1616
*/
1717
package com.optimizely.ab.config;
1818

19-
import com.optimizely.ab.config.audience.*;
19+
import java.util.ArrayList;
20+
import java.util.Collections;
21+
import java.util.HashMap;
22+
import java.util.List;
23+
import java.util.Map;
24+
25+
import static org.junit.Assert.assertEquals;
2026
import org.junit.Test;
21-
import static org.junit.Assert.*;
2227

23-
import java.io.IOException;
24-
import java.util.*;
28+
import com.optimizely.ab.config.audience.AndCondition;
29+
import com.optimizely.ab.config.audience.AudienceIdCondition;
30+
import com.optimizely.ab.config.audience.Condition;
31+
import com.optimizely.ab.config.audience.EmptyCondition;
32+
import com.optimizely.ab.config.audience.NotCondition;
33+
import com.optimizely.ab.config.audience.OrCondition;
2534

2635
public class HoldoutTest {
2736

@@ -194,7 +203,6 @@ private Holdout makeMockHoldoutWithStatus(Holdout.HoldoutStatus status, Conditio
194203
Collections.<String>emptyList(),
195204
audienceConditions,
196205
Collections.<Variation>emptyList(),
197-
Collections.<String, String>emptyMap(),
198206
Collections.<TrafficAllocation>emptyList(),
199207
Collections.<String>emptyList(),
200208
Collections.<String>emptyList()

0 commit comments

Comments
 (0)