diff --git a/core-api/src/main/java/com/optimizely/ab/Optimizely.java b/core-api/src/main/java/com/optimizely/ab/Optimizely.java index 1ee6d498e..08a527a62 100644 --- a/core-api/src/main/java/com/optimizely/ab/Optimizely.java +++ b/core-api/src/main/java/com/optimizely/ab/Optimizely.java @@ -556,7 +556,12 @@ else if (!variable.getType().equals(variableType)) { if (variation != null) { LiveVariableUsageInstance liveVariableUsageInstance = variation.getVariableIdToLiveVariableUsageInstanceMap().get(variable.getId()); - variableValue = liveVariableUsageInstance.getValue(); + if (liveVariableUsageInstance != null) { + variableValue = liveVariableUsageInstance.getValue(); + } + else { + variableValue = variable.getDefaultValue(); + } } else { logger.info("User \"" + userId + diff --git a/core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java b/core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java index e40e5eb1c..2bef5266e 100644 --- a/core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java +++ b/core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java @@ -80,9 +80,11 @@ import static com.optimizely.ab.config.ValidProjectConfigV4.EXPERIMENT_PAUSED_EXPERIMENT_KEY; import static com.optimizely.ab.config.ValidProjectConfigV4.FEATURE_FLAG_MULTI_VARIATE_FEATURE; import static com.optimizely.ab.config.ValidProjectConfigV4.FEATURE_FLAG_SINGLE_VARIABLE_DOUBLE; +import static com.optimizely.ab.config.ValidProjectConfigV4.FEATURE_FLAG_SINGLE_VARIABLE_INTEGER; import static com.optimizely.ab.config.ValidProjectConfigV4.FEATURE_MULTI_VARIATE_FEATURE_KEY; import static com.optimizely.ab.config.ValidProjectConfigV4.FEATURE_SINGLE_VARIABLE_BOOLEAN_KEY; import static com.optimizely.ab.config.ValidProjectConfigV4.FEATURE_SINGLE_VARIABLE_DOUBLE_KEY; +import static com.optimizely.ab.config.ValidProjectConfigV4.FEATURE_SINGLE_VARIABLE_INTEGER_KEY; import static com.optimizely.ab.config.ValidProjectConfigV4.MULTIVARIATE_EXPERIMENT_FORCED_VARIATION_USER_ID_GRED; import static com.optimizely.ab.config.ValidProjectConfigV4.PAUSED_EXPERIMENT_FORCED_VARIATION_USER_ID_CONTROL; import static com.optimizely.ab.config.ValidProjectConfigV4.VARIABLE_BOOLEAN_VARIABLE_DEFAULT_VALUE; @@ -90,6 +92,7 @@ import static com.optimizely.ab.config.ValidProjectConfigV4.VARIABLE_DOUBLE_DEFAULT_VALUE; import static com.optimizely.ab.config.ValidProjectConfigV4.VARIABLE_DOUBLE_VARIABLE_KEY; import static com.optimizely.ab.config.ValidProjectConfigV4.VARIABLE_FIRST_LETTER_KEY; +import static com.optimizely.ab.config.ValidProjectConfigV4.VARIABLE_INTEGER_VARIABLE_KEY; import static com.optimizely.ab.config.ValidProjectConfigV4.VARIATION_MULTIVARIATE_EXPERIMENT_GRED; import static com.optimizely.ab.config.ValidProjectConfigV4.VARIATION_MULTIVARIATE_EXPERIMENT_GRED_KEY; import static com.optimizely.ab.event.LogEvent.RequestMethod; @@ -2631,6 +2634,36 @@ public void getFeatureVariableValueReturnsVariationValueWhenUserGetsBucketedToVa assertEquals(expectedValue, value); } + /** + * Verify {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, LiveVariable.VariableType)} + * returns the default value for the feature variable + * when there is no variable usage present for the variation the user is bucketed into. + * @throws ConfigParseException + */ + @Test + public void getFeatureVariableValueReturnsDefaultValueWhenNoVariationUsageIsPresent() throws ConfigParseException { + assumeTrue(datafileVersion >= Integer.parseInt(ProjectConfig.Version.V4.toString())); + + String validFeatureKey = FEATURE_SINGLE_VARIABLE_INTEGER_KEY; + String validVariableKey = VARIABLE_INTEGER_VARIABLE_KEY; + LiveVariable variable = FEATURE_FLAG_SINGLE_VARIABLE_INTEGER.getVariableKeyToLiveVariableMap().get(validVariableKey); + String expectedValue = variable.getDefaultValue(); + + Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler) + .withConfig(validProjectConfig) + .build(); + + String value = optimizely.getFeatureVariableValueForType( + validFeatureKey, + validVariableKey, + genericUserId, + Collections.emptyMap(), + LiveVariable.VariableType.INTEGER + ); + + assertEquals(expectedValue, value); + } + /** * Verify {@link Optimizely#isFeatureEnabled(String, String)} calls into * {@link Optimizely#isFeatureEnabled(String, String, Map)} and they both diff --git a/core-api/src/test/java/com/optimizely/ab/config/ValidProjectConfigV4.java b/core-api/src/test/java/com/optimizely/ab/config/ValidProjectConfigV4.java index bc0dab271..d8932db01 100644 --- a/core-api/src/test/java/com/optimizely/ab/config/ValidProjectConfigV4.java +++ b/core-api/src/test/java/com/optimizely/ab/config/ValidProjectConfigV4.java @@ -107,9 +107,9 @@ public class ValidProjectConfigV4 { LiveVariable.VariableType.DOUBLE ); private static final String FEATURE_SINGLE_VARIABLE_INTEGER_ID = "3281420120"; - private static final String FEATURE_SINGLE_VARIABLE_INTEGER_KEY = "integer_single_variable_feature"; + public static final String FEATURE_SINGLE_VARIABLE_INTEGER_KEY = "integer_single_variable_feature"; private static final String VARIABLE_INTEGER_VARIABLE_ID = "593964691"; - private static final String VARIABLE_INTEGER_VARIABLE_KEY = "integer_variable"; + public static final String VARIABLE_INTEGER_VARIABLE_KEY = "integer_variable"; private static final String VARIABLE_INTEGER_DEFAULT_VALUE = "7"; private static final LiveVariable VARIABLE_INTEGER_VARIABLE = new LiveVariable( VARIABLE_INTEGER_VARIABLE_ID, @@ -118,15 +118,6 @@ public class ValidProjectConfigV4 { null, LiveVariable.VariableType.INTEGER ); - private static final FeatureFlag FEATURE_FLAG_SINGLE_VARIABLE_INTEGER = new FeatureFlag( - FEATURE_SINGLE_VARIABLE_INTEGER_ID, - FEATURE_SINGLE_VARIABLE_INTEGER_KEY, - "", - Collections.emptyList(), - Collections.singletonList( - VARIABLE_INTEGER_VARIABLE - ) - ); private static final String FEATURE_SINGLE_VARIABLE_BOOLEAN_ID = "2591051011"; public static final String FEATURE_SINGLE_VARIABLE_BOOLEAN_KEY = "boolean_single_variable_feature"; private static final String VARIABLE_BOOLEAN_VARIABLE_ID = "3974680341"; @@ -206,6 +197,38 @@ public class ValidProjectConfigV4 { VARIABLE_STRING_VARIABLE ) ); + private static final String ROLLOUT_3_ID = "2048875663"; + private static final String ROLLOUT_3_EVERYONE_ELSE_EXPERIMENT_ID = "3794675122"; + private static final String ROLLOUT_3_EVERYONE_ELSE_RULE_ENABLED_VARIATION_ID = "589640735"; + private static final Variation ROLLOUT_3_EVERYONE_ELSE_RULE_ENABLED_VARIATION = new Variation( + ROLLOUT_3_EVERYONE_ELSE_RULE_ENABLED_VARIATION_ID, + ROLLOUT_3_EVERYONE_ELSE_RULE_ENABLED_VARIATION_ID, + Collections.emptyList() + ); + private static final Experiment ROLLOUT_3_EVERYONE_ELSE_RULE = new Experiment( + ROLLOUT_3_EVERYONE_ELSE_EXPERIMENT_ID, + ROLLOUT_3_EVERYONE_ELSE_EXPERIMENT_ID, + Experiment.ExperimentStatus.RUNNING.toString(), + ROLLOUT_3_ID, + Collections.emptyList(), + Collections.singletonList( + ROLLOUT_3_EVERYONE_ELSE_RULE_ENABLED_VARIATION + ), + Collections.emptyMap(), + Collections.singletonList( + new TrafficAllocation( + ROLLOUT_3_EVERYONE_ELSE_RULE_ENABLED_VARIATION_ID, + 10000 + ) + ) + ); + public static final Rollout ROLLOUT_3 = new Rollout( + ROLLOUT_3_ID, + Collections.singletonList( + ROLLOUT_3_EVERYONE_ELSE_RULE + ) + ); + private static final String FEATURE_MULTI_VARIATE_FEATURE_ID = "3263342226"; public static final String FEATURE_MULTI_VARIATE_FEATURE_KEY = "multi_variate_feature"; private static final String VARIABLE_FIRST_LETTER_ID = "675244127"; @@ -917,7 +940,15 @@ public class ValidProjectConfigV4 { VARIABLE_DOUBLE_VARIABLE ) ); - + public static final FeatureFlag FEATURE_FLAG_SINGLE_VARIABLE_INTEGER = new FeatureFlag( + FEATURE_SINGLE_VARIABLE_INTEGER_ID, + FEATURE_SINGLE_VARIABLE_INTEGER_KEY, + ROLLOUT_3_ID, + Collections.emptyList(), + Collections.singletonList( + VARIABLE_INTEGER_VARIABLE + ) + ); public static ProjectConfig generateValidProjectConfigV4() { @@ -964,6 +995,7 @@ public static ProjectConfig generateValidProjectConfigV4() { List rollouts = new ArrayList(); rollouts.add(ROLLOUT_1); rollouts.add(ROLLOUT_2); + rollouts.add(ROLLOUT_3); return new ProjectConfig( ACCOUNT_ID, diff --git a/core-api/src/test/resources/config/valid-project-config-v4.json b/core-api/src/test/resources/config/valid-project-config-v4.json index 9ef2e682f..fed802474 100644 --- a/core-api/src/test/resources/config/valid-project-config-v4.json +++ b/core-api/src/test/resources/config/valid-project-config-v4.json @@ -449,7 +449,7 @@ { "id": "3281420120", "key": "integer_single_variable_feature", - "rolloutId": "", + "rolloutId": "2048875663", "experimentIds": [], "variables": [ { @@ -679,6 +679,32 @@ ] } ] + }, + { + "id": "2048875663", + "experiments": [ + { + "id": "3794675122", + "key": "3794675122", + "status": "Running", + "layerId": "2048875663", + "audienceIds": [], + "forcedVariations": {}, + "variations": [ + { + "id": "589640735", + "key": "589640735", + "variables": [] + } + ], + "trafficAllocation": [ + { + "entityId": "589640735", + "endOfRange": 10000 + } + ] + } + ] } ], "variables": []