diff --git a/client/src/main/java/io/split/client/SplitClientImpl.java b/client/src/main/java/io/split/client/SplitClientImpl.java index 9f4b8ff9..32b68b09 100644 --- a/client/src/main/java/io/split/client/SplitClientImpl.java +++ b/client/src/main/java/io/split/client/SplitClientImpl.java @@ -3,9 +3,7 @@ import com.google.gson.GsonBuilder; import io.split.client.api.Key; import io.split.client.api.SplitResult; -import io.split.client.dtos.DecoratedImpression; -import io.split.client.dtos.EvaluationOptions; -import io.split.client.dtos.Event; +import io.split.client.dtos.*; import io.split.client.events.EventsStorageProducer; import io.split.client.impressions.Impression; import io.split.client.impressions.ImpressionsManager; @@ -14,7 +12,6 @@ import io.split.engine.evaluator.Evaluator; import io.split.engine.evaluator.EvaluatorImp; import io.split.engine.evaluator.Labels; -import io.split.grammar.Treatments; import io.split.inputValidation.EventsValidator; import io.split.inputValidation.KeyValidator; import io.split.inputValidation.SplitNameValidator; @@ -49,7 +46,6 @@ * @author adil */ public final class SplitClientImpl implements SplitClient { - public static final SplitResult SPLIT_RESULT_CONTROL = new SplitResult(Treatments.CONTROL, null); private static final String CLIENT_DESTROY = "Client has already been destroyed - no calls possible"; private static final String CATCHALL_EXCEPTION = "CatchAll Exception"; private static final String MATCHING_KEY = "matchingKey"; @@ -66,6 +62,7 @@ public final class SplitClientImpl implements SplitClient { private final TelemetryEvaluationProducer _telemetryEvaluationProducer; private final TelemetryConfigProducer _telemetryConfigProducer; private final FlagSetsFilter _flagSetsFilter; + private final FallbackTreatmentCalculator _fallbackTreatmentCalculator; public SplitClientImpl(SplitFactory container, SplitCacheConsumer splitCacheConsumer, @@ -76,7 +73,8 @@ public SplitClientImpl(SplitFactory container, Evaluator evaluator, TelemetryEvaluationProducer telemetryEvaluationProducer, TelemetryConfigProducer telemetryConfigProducer, - FlagSetsFilter flagSetsFilter) { + FlagSetsFilter flagSetsFilter, + FallbackTreatmentCalculator fallbackTreatmentCalculator) { _container = container; _splitCacheConsumer = checkNotNull(splitCacheConsumer); _impressionManager = checkNotNull(impressionManager); @@ -87,6 +85,7 @@ public SplitClientImpl(SplitFactory container, _telemetryEvaluationProducer = checkNotNull(telemetryEvaluationProducer); _telemetryConfigProducer = checkNotNull(telemetryConfigProducer); _flagSetsFilter = flagSetsFilter; + _fallbackTreatmentCalculator = fallbackTreatmentCalculator; } @Override @@ -492,31 +491,31 @@ private SplitResult getTreatmentWithConfigInternal(String matchingKey, String bu if (_container.isDestroyed()) { _log.error(CLIENT_DESTROY); - return SPLIT_RESULT_CONTROL; + return checkFallbackTreatment(featureFlag); } if (!KeyValidator.isValid(matchingKey, MATCHING_KEY, _config.maxStringLength(), methodEnum.getMethod())) { - return SPLIT_RESULT_CONTROL; + return checkFallbackTreatment(featureFlag); } if (!KeyValidator.bucketingKeyIsValid(bucketingKey, _config.maxStringLength(), methodEnum.getMethod())) { - return SPLIT_RESULT_CONTROL; + return checkFallbackTreatment(featureFlag); } Optional splitNameResult = SplitNameValidator.isValid(featureFlag, methodEnum.getMethod()); if (!splitNameResult.isPresent()) { - return SPLIT_RESULT_CONTROL; + return checkFallbackTreatment(featureFlag); } featureFlag = splitNameResult.get(); long start = System.currentTimeMillis(); EvaluatorImp.TreatmentLabelAndChangeNumber result = _evaluator.evaluateFeature(matchingKey, bucketingKey, featureFlag, attributes); - if (result.treatment.equals(Treatments.CONTROL) && result.label.equals(Labels.DEFINITION_NOT_FOUND) && _gates.isSDKReady()) { + if (result.label != null && result.label.contains(Labels.DEFINITION_NOT_FOUND) && _gates.isSDKReady()) { _log.warn(String.format( "%s: you passed \"%s\" that does not exist in this environment, " + "please double check what feature flags exist in the Split user interface.", methodEnum.getMethod(), featureFlag)); - return SPLIT_RESULT_CONTROL; + return checkFallbackTreatment(featureFlag); } recordStats( @@ -541,10 +540,19 @@ private SplitResult getTreatmentWithConfigInternal(String matchingKey, String bu } catch (Exception e1) { // ignore } - return SPLIT_RESULT_CONTROL; + return checkFallbackTreatment(featureFlag); } } + private SplitResult checkFallbackTreatment(String featureName) { + FallbackTreatment fallbackTreatment = _fallbackTreatmentCalculator.resolve(featureName, ""); + String config = null; + if (fallbackTreatment.getConfig() != null) { + config = fallbackTreatment.getConfig(); + } + return new SplitResult(fallbackTreatment.getTreatment(), config); + } + private String validateProperties(Map properties) { if (properties == null){ return null; @@ -563,6 +571,7 @@ private Map getTreatmentsWithConfigInternal(String matching _log.error(String.format("%s: featureFlagNames must be a non-empty array", methodEnum.getMethod())); return new HashMap<>(); } + try { checkSDKReady(methodEnum, featureFlagNames); Map result = validateBeforeEvaluate(featureFlagNames, matchingKey, methodEnum, bucketingKey); @@ -601,46 +610,43 @@ private Map getTreatmentsBySetsWithConfigInternal(String ma if (cleanFlagSets.isEmpty()) { return new HashMap<>(); } - List featureFlagNames = new ArrayList<>(); - try { - checkSDKReady(methodEnum); - Map result = validateBeforeEvaluateByFlagSets(matchingKey, methodEnum,bucketingKey); - if(result != null) { - return result; - } - Map evaluatorResult = _evaluator.evaluateFeaturesByFlagSets(matchingKey, - bucketingKey, new ArrayList<>(cleanFlagSets), attributes); + checkSDKReady(methodEnum); + Map result = validateBeforeEvaluateByFlagSets(matchingKey, methodEnum,bucketingKey); + if(result != null) { + return result; + } + Map evaluatorResult = _evaluator.evaluateFeaturesByFlagSets(matchingKey, + bucketingKey, new ArrayList<>(cleanFlagSets), attributes); - return processEvaluatorResult(evaluatorResult, methodEnum, matchingKey, bucketingKey, attributes, initTime, - validateProperties(evaluationOptions.getProperties())); - } catch (Exception e) { - try { + evaluatorResult.entrySet().forEach(flag -> { + if (flag.getValue().label != null && + flag.getValue().label.contains(io.split.engine.evaluator.Labels.EXCEPTION)) { _telemetryEvaluationProducer.recordException(methodEnum); - _log.error(CATCHALL_EXCEPTION, e); - } catch (Exception e1) { - // ignore } - return createMapControl(featureFlagNames); - } + }); + return processEvaluatorResult(evaluatorResult, methodEnum, matchingKey, bucketingKey, attributes, initTime, + validateProperties(evaluationOptions.getProperties())); } + private Map processEvaluatorResult(Map evaluatorResult, MethodEnum methodEnum, String matchingKey, String bucketingKey, Map attributes, long initTime, String properties){ List decoratedImpressions = new ArrayList<>(); Map result = new HashMap<>(); - evaluatorResult.keySet().forEach(t -> { - if (evaluatorResult.get(t).treatment.equals(Treatments.CONTROL) && evaluatorResult.get(t).label. - equals(Labels.DEFINITION_NOT_FOUND) && _gates.isSDKReady()) { + evaluatorResult.keySet().forEach(flag -> { + if (evaluatorResult.get(flag).label != null && + evaluatorResult.get(flag).label.contains(Labels.DEFINITION_NOT_FOUND) && + _gates.isSDKReady()) { _log.warn(String.format("%s: you passed \"%s\" that does not exist in this environment please double check " + - "what feature flags exist in the Split user interface.", methodEnum.getMethod(), t)); - result.put(t, SPLIT_RESULT_CONTROL); + "what feature flags exist in the Split user interface.", methodEnum.getMethod(), flag)); + result.put(flag, checkFallbackTreatment(flag)); } else { - result.put(t, new SplitResult(evaluatorResult.get(t).treatment, evaluatorResult.get(t).configurations)); + result.put(flag, new SplitResult(evaluatorResult.get(flag).treatment, evaluatorResult.get(flag).configurations)); decoratedImpressions.add( new DecoratedImpression( - new Impression(matchingKey, bucketingKey, t, evaluatorResult.get(t).treatment, System.currentTimeMillis(), - evaluatorResult.get(t).label, evaluatorResult.get(t).changeNumber, attributes, properties), - evaluatorResult.get(t).track)); + new Impression(matchingKey, bucketingKey, flag, evaluatorResult.get(flag).treatment, System.currentTimeMillis(), + evaluatorResult.get(flag).label, evaluatorResult.get(flag).changeNumber, attributes, properties), + evaluatorResult.get(flag).track)); } }); _telemetryEvaluationProducer.recordLatency(methodEnum, System.currentTimeMillis() - initTime); @@ -735,7 +741,7 @@ private void checkSDKReady(MethodEnum methodEnum) { private Map createMapControl(List featureFlags) { Map result = new HashMap<>(); - featureFlags.forEach(s -> result.put(s, SPLIT_RESULT_CONTROL)); + featureFlags.forEach(s -> result.put(s, checkFallbackTreatment(s))); return result; } } \ No newline at end of file diff --git a/client/src/main/java/io/split/client/SplitFactoryImpl.java b/client/src/main/java/io/split/client/SplitFactoryImpl.java index bcc1a967..5d868f3c 100644 --- a/client/src/main/java/io/split/client/SplitFactoryImpl.java +++ b/client/src/main/java/io/split/client/SplitFactoryImpl.java @@ -2,6 +2,7 @@ import com.google.common.io.Files; import io.split.client.dtos.BearerCredentialsProvider; +import io.split.client.dtos.FallbackTreatmentCalculatorImp; import io.split.client.dtos.Metadata; import io.split.client.events.EventsSender; import io.split.client.events.EventsStorage; @@ -256,8 +257,9 @@ public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyn _telemetrySyncTask = new TelemetrySyncTask(config.getTelemetryRefreshRate(), _telemetrySynchronizer, config.getThreadFactory()); + FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(null); // Evaluator - _evaluator = new EvaluatorImp(splitCache, segmentCache, ruleBasedSegmentCache, null); + _evaluator = new EvaluatorImp(splitCache, segmentCache, ruleBasedSegmentCache, fallbackTreatmentCalculatorImp); // SplitClient _client = new SplitClientImpl(this, @@ -269,7 +271,9 @@ public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyn _evaluator, _telemetryStorageProducer, // TelemetryEvaluation instance _telemetryStorageProducer, // TelemetryConfiguration instance - flagSetsFilter); + flagSetsFilter, + fallbackTreatmentCalculatorImp + ); // SplitManager _manager = new SplitManagerImpl(splitCache, config, _gates, _telemetryStorageProducer); @@ -348,8 +352,9 @@ protected SplitFactoryImpl(String apiToken, SplitClientConfig config, CustomStor _telemetrySynchronizer = new TelemetryConsumerSubmitter(customStorageWrapper, _sdkMetadata); UserCustomRuleBasedSegmentAdapterConsumer userCustomRuleBasedSegmentAdapterConsumer = new UserCustomRuleBasedSegmentAdapterConsumer(customStorageWrapper); + FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(null); _evaluator = new EvaluatorImp(userCustomSplitAdapterConsumer, userCustomSegmentAdapterConsumer, - userCustomRuleBasedSegmentAdapterConsumer, null); + userCustomRuleBasedSegmentAdapterConsumer, fallbackTreatmentCalculatorImp); _impressionsSender = PluggableImpressionSender.create(customStorageWrapper); _uniqueKeysTracker = createUniqueKeysTracker(config); _impressionsManager = buildImpressionsManager(config, userCustomImpressionAdapterConsumer, @@ -378,7 +383,9 @@ protected SplitFactoryImpl(String apiToken, SplitClientConfig config, CustomStor _evaluator, _telemetryStorageProducer, // TelemetryEvaluation instance _telemetryStorageProducer, // TelemetryConfiguration instance - flagSetsFilter); + flagSetsFilter, + fallbackTreatmentCalculatorImp + ); // SyncManager _syncManager = new ConsumerSyncManager(synchronizer); @@ -446,8 +453,9 @@ protected SplitFactoryImpl(SplitClientConfig config) { SplitTasks splitTasks = SplitTasks.build(_splitSynchronizationTask, _segmentSynchronizationTaskImp, _impressionsManager, null, null, null); + FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(null); // Evaluator - _evaluator = new EvaluatorImp(splitCache, segmentCache, ruleBasedSegmentCache, null); + _evaluator = new EvaluatorImp(splitCache, segmentCache, ruleBasedSegmentCache, fallbackTreatmentCalculatorImp); EventsStorage eventsStorage = new NoopEventsStorageImp(); @@ -461,7 +469,9 @@ protected SplitFactoryImpl(SplitClientConfig config) { _evaluator, _telemetryStorageProducer, // TelemetryEvaluation instance _telemetryStorageProducer, // TelemetryConfiguration instance - flagSetsFilter); + flagSetsFilter, + fallbackTreatmentCalculatorImp + ); // Synchronizer Synchronizer synchronizer = new LocalhostSynchronizer(splitTasks, _splitFetcher, diff --git a/client/src/main/java/io/split/client/dtos/FallbackTreatment.java b/client/src/main/java/io/split/client/dtos/FallbackTreatment.java index 542f9015..291db4f4 100644 --- a/client/src/main/java/io/split/client/dtos/FallbackTreatment.java +++ b/client/src/main/java/io/split/client/dtos/FallbackTreatment.java @@ -1,13 +1,11 @@ package io.split.client.dtos; -import java.util.Map; - public class FallbackTreatment { - private final Map _config; + private final String _config; private final String _treatment; private final String _label; - public FallbackTreatment(String treatment, Map config) { + public FallbackTreatment(String treatment, String config) { _treatment = treatment; _config = config; _label = null; @@ -19,13 +17,13 @@ public FallbackTreatment(String treatment) { _label = null; } - public FallbackTreatment(String treatment, Map config, String label) { + public FallbackTreatment(String treatment, String config, String label) { _treatment = treatment; _config = config; _label = label; } - public Map getConfig() { + public String getConfig() { return _config; } diff --git a/client/src/main/java/io/split/engine/evaluator/EvaluatorImp.java b/client/src/main/java/io/split/engine/evaluator/EvaluatorImp.java index 773413b2..f3b06f8f 100644 --- a/client/src/main/java/io/split/engine/evaluator/EvaluatorImp.java +++ b/client/src/main/java/io/split/engine/evaluator/EvaluatorImp.java @@ -3,12 +3,10 @@ import io.split.client.dtos.ConditionType; import io.split.client.dtos.FallbackTreatment; import io.split.client.dtos.FallbackTreatmentCalculator; -import io.split.client.dtos.FallbackTreatmentsConfiguration; import io.split.client.exceptions.ChangeNumberExceptionWrapper; import io.split.engine.experiments.ParsedCondition; import io.split.engine.experiments.ParsedSplit; import io.split.engine.splitter.Splitter; -import io.split.grammar.Treatments; import io.split.storages.RuleBasedSegmentCacheConsumer; import io.split.storages.SegmentCacheConsumer; import io.split.storages.SplitCacheConsumer; @@ -63,7 +61,27 @@ public Map evaluateFeatures(String matchi public Map evaluateFeaturesByFlagSets(String key, String bucketingKey, List flagSets, Map attributes) { List flagSetsWithNames = getFeatureFlagNamesByFlagSets(flagSets); - return evaluateFeatures(key, bucketingKey, flagSetsWithNames, attributes); + try { + return evaluateFeatures(key, bucketingKey, flagSetsWithNames, attributes); + } catch (Exception e) { + _log.error("Evaluator Exception", e); + return createMapControl(flagSetsWithNames, io.split.engine.evaluator.Labels.EXCEPTION); + } + } + + private Map createMapControl(List featureFlags, String label) { + Map result = new HashMap<>(); + featureFlags.forEach(s -> result.put(s, checkFallbackTreatment(s, label))); + return result; + } + + private EvaluatorImp.TreatmentLabelAndChangeNumber checkFallbackTreatment(String featureName, String label) { + FallbackTreatment fallbackTreatment = _fallbackTreatmentCalculator.resolve(featureName, label); + return new EvaluatorImp.TreatmentLabelAndChangeNumber(fallbackTreatment.getTreatment(), + fallbackTreatment.getLabel(), + null, + getFallbackConfig(fallbackTreatment), + false); } private List getFeatureFlagNamesByFlagSets(List flagSets) { @@ -177,13 +195,24 @@ private String getConfig(ParsedSplit parsedSplit, String returnedTreatment) { return parsedSplit.configurations() != null ? parsedSplit.configurations().get(returnedTreatment) : null; } + private String getFallbackConfig(FallbackTreatment fallbackTreatment) { + if (fallbackTreatment.getConfig() != null) { + return fallbackTreatment.getConfig(); + } + + return null; + } + private TreatmentLabelAndChangeNumber evaluateParsedSplit(String matchingKey, String bucketingKey, Map attributes, ParsedSplit parsedSplit, String featureName) { try { - if (parsedSplit == null) { FallbackTreatment fallbackTreatment = _fallbackTreatmentCalculator.resolve(featureName, Labels.DEFINITION_NOT_FOUND); - return new TreatmentLabelAndChangeNumber(fallbackTreatment.getTreatment(), fallbackTreatment.getLabel()); + return new TreatmentLabelAndChangeNumber(fallbackTreatment.getTreatment(), + fallbackTreatment.getLabel(), + null, + getFallbackConfig(fallbackTreatment), + false); } return getTreatment(matchingKey, bucketingKey, parsedSplit, attributes); } catch (ChangeNumberExceptionWrapper e) { diff --git a/client/src/test/java/io/split/client/SplitClientImplTest.java b/client/src/test/java/io/split/client/SplitClientImplTest.java index a5b55ed7..2556508c 100644 --- a/client/src/test/java/io/split/client/SplitClientImplTest.java +++ b/client/src/test/java/io/split/client/SplitClientImplTest.java @@ -100,7 +100,8 @@ public void nullKeyResultsInControl() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals(Treatments.CONTROL, client.getTreatment(null, "test1")); @@ -130,7 +131,8 @@ public void nullTestResultsInControl() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals(Treatments.CONTROL, client.getTreatment("adil@relateiq.com", null)); @@ -153,7 +155,8 @@ public void exceptionsResultInControl() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals(Treatments.CONTROL, client.getTreatment("adil@relateiq.com", "test1")); @@ -185,7 +188,8 @@ public void works() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); int numKeys = 5; @@ -223,7 +227,8 @@ public void worksNullConfig() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); String randomKey = RandomStringUtils.random(10); SplitResult result = client.getTreatmentWithConfig(randomKey, test); @@ -259,7 +264,8 @@ public void worksAndHasConfig() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); int numKeys = 5; @@ -296,7 +302,8 @@ public void lastConditionIsAlwaysDefault() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals(Treatments.OFF, client.getTreatment("pato@codigo.com", test)); @@ -336,7 +343,8 @@ public void lastConditionIsAlwaysDefaultButWithTreatment() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); SplitResult result = client.getTreatmentWithConfig("pato@codigo.com", test); @@ -372,7 +380,8 @@ public void multipleConditionsWork() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals("on", client.getTreatment("adil@codigo.com", test)); @@ -406,7 +415,8 @@ public void killedTestAlwaysGoesToDefault() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals(Treatments.OFF, client.getTreatment("adil@codigo.com", test)); @@ -446,7 +456,8 @@ public void killedTestAlwaysGoesToDefaultHasConfig() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); SplitResult result = client.getTreatmentWithConfig("adil@codigo.com", test); @@ -484,7 +495,8 @@ public void dependencyMatcherOn() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals(Treatments.ON, client.getTreatment("key", parent)); @@ -510,7 +522,7 @@ public void dependencyMatcherOff() { RuleBasedSegmentCacheConsumer ruleBasedSegmentCacheConsumer = mock(RuleBasedSegmentCacheConsumer.class); when(splitCacheConsumer.get(parent)).thenReturn(parentSplit); when(splitCacheConsumer.get(dependent)).thenReturn(dependentSplit); - + FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(null); SplitClientImpl client = new SplitClientImpl( mock(SplitFactory.class), splitCacheConsumer, @@ -518,8 +530,9 @@ public void dependencyMatcherOff() { NoopEventsStorageImp.create(), config, gates, - new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, fallbackTreatmentCalculatorImp), TELEMETRY_STORAGE, TELEMETRY_STORAGE, + flagSetsFilter, + fallbackTreatmentCalculatorImp ); assertEquals(Treatments.ON, client.getTreatment("key", parent)); @@ -539,6 +552,7 @@ public void dependencyMatcherControl() { SegmentCacheConsumer segmentCacheConsumer = mock(SegmentCacheConsumer.class); RuleBasedSegmentCacheConsumer ruleBasedSegmentCacheConsumer = mock(RuleBasedSegmentCacheConsumer.class); when(splitCacheConsumer.get(dependent)).thenReturn(dependentSplit); + FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(null); SplitClientImpl client = new SplitClientImpl( mock(SplitFactory.class), @@ -547,8 +561,9 @@ public void dependencyMatcherControl() { NoopEventsStorageImp.create(), config, gates, - new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, fallbackTreatmentCalculatorImp), TELEMETRY_STORAGE, TELEMETRY_STORAGE, + flagSetsFilter, + fallbackTreatmentCalculatorImp ); assertEquals(Treatments.ON, client.getTreatment("key", dependent)); @@ -578,7 +593,8 @@ public void attributesWork() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals("on", client.getTreatment("adil@codigo.com", test)); @@ -613,7 +629,8 @@ public void attributesWork2() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals("off", client.getTreatment("adil@codigo.com", test)); @@ -649,7 +666,8 @@ public void attributesGreaterThanNegativeNumber() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals("off", client.getTreatment("adil@codigo.com", test)); @@ -687,7 +705,8 @@ public void attributesForSets() { config, gates, new EvaluatorImp(splitCacheConsumer ,segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals("off", client.getTreatment("adil@codigo.com", test)); @@ -732,7 +751,8 @@ public void labelsArePopulated() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); Map attributes = ImmutableMap.of("age", -20, "acv", "1000000"); @@ -835,7 +855,8 @@ private void trafficAllocation(String key, int trafficAllocation, int trafficAll config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals(expected_treatment_on_or_off, client.getTreatment(key, test)); @@ -889,7 +910,8 @@ public void notInTrafficAllocationDefaultConfig() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals(Treatments.OFF, client.getTreatment("pato@split.io", test)); @@ -933,7 +955,8 @@ public void matchingBucketingKeysWork() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); Key bad_key = new Key("adil", "aijaz"); @@ -976,7 +999,8 @@ public void matchingBucketingKeysByFlagSetWork() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); Key bad_key = new Key("adil", "aijaz"); @@ -1017,7 +1041,8 @@ public void matchingBucketingKeysByFlagSetsWork() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); Key bad_key = new Key("adil", "aijaz"); @@ -1055,7 +1080,8 @@ public void impressionMetadataIsPropagated() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); Map attributes = ImmutableMap.of("age", -20, "acv", "1000000"); @@ -1098,7 +1124,8 @@ public void blockUntilReadyDoesNotTimeWhenSdkIsReady() throws TimeoutException, config, ready, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); client.blockUntilReady(); @@ -1120,7 +1147,8 @@ public void blockUntilReadyTimesWhenSdkIsNotReady() throws TimeoutException, Int config, ready, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); client.blockUntilReady(); @@ -1141,7 +1169,8 @@ public void trackWithValidParameters() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertTrue(client.track("validKey", "valid_traffic_type", "valid_event")); @@ -1167,7 +1196,8 @@ public void trackWithInvalidEventTypeIds() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); Assert.assertFalse(client.track("validKey", "valid_traffic_type", "")); Assert.assertFalse(client.track("validKey", "valid_traffic_type", null)); @@ -1192,7 +1222,8 @@ public void trackWithInvalidTrafficTypeNames() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); Assert.assertFalse(client.track("validKey", "", "valid")); @@ -1214,7 +1245,8 @@ public void trackWithInvalidKeys() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); Assert.assertFalse(client.track("", "valid_traffic_type", "valid")); @@ -1246,7 +1278,8 @@ public void getTreatmentWithInvalidKeys() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); Assert.assertNotEquals(Treatments.CONTROL, client.getTreatment("valid", "split")); assertEquals(Treatments.CONTROL, client.getTreatment("", "split")); @@ -1297,7 +1330,8 @@ public void trackWithProperties() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); HashMap properties = new HashMap<>(); @@ -1421,7 +1455,8 @@ public void clientCannotPerformActionsWhenDestroyed() throws InterruptedExceptio config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals(Treatments.ON, client.getTreatment("valid", "split")); @@ -1462,7 +1497,8 @@ public void worksAndHasConfigTryKetTreatmentWithKey() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); int numKeys = 5; @@ -1513,7 +1549,8 @@ public void worksAndHasConfigByFlagSetTryKetTreatmentWithKey() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); int numKeys = 5; @@ -1562,7 +1599,8 @@ public void worksAndHasConfigByFlagSetsTryKetTreatmentWithKey() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); int numKeys = 5; @@ -1600,7 +1638,8 @@ public void blockUntilReadyException() throws TimeoutException, InterruptedExcep config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); client.blockUntilReady(); @@ -1630,7 +1669,8 @@ public void nullKeyResultsInControlGetTreatments() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals(Treatments.CONTROL, client.getTreatments(null, Collections.singletonList("test1")).get("test1")); @@ -1661,7 +1701,8 @@ public void nullSplitsResultsInEmptyGetTreatments() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertEquals(0, client.getTreatments("key", null).size()); @@ -1684,7 +1725,8 @@ public void exceptionsResultInControlGetTreatments() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); Map result = client.getTreatments("adil@relateiq.com", Arrays.asList("test1", "test2")); assertEquals(2, result.values().size()); @@ -1709,6 +1751,7 @@ public void getTreatmentsWorks() { RuleBasedSegmentCacheConsumer ruleBasedSegmentCacheConsumer = mock(RuleBasedSegmentCacheConsumer.class); when(splitCacheConsumer.fetchMany(anyList())).thenReturn(splits); when(gates.isSDKReady()).thenReturn(true); + FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(null); SplitClientImpl client = new SplitClientImpl( mock(SplitFactory.class), @@ -1717,8 +1760,9 @@ public void getTreatmentsWorks() { NoopEventsStorageImp.create(), config, gates, - new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, fallbackTreatmentCalculatorImp), TELEMETRY_STORAGE, TELEMETRY_STORAGE, + flagSetsFilter, + fallbackTreatmentCalculatorImp ); Map result = client.getTreatments("randomKey", Arrays.asList(test, "test2")); assertEquals("on", result.get(test)); @@ -1749,7 +1793,8 @@ public void emptySplitsResultsInNullGetTreatments() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); Map result = client.getTreatments("key", new ArrayList<>()); assertNotNull(result); @@ -1774,7 +1819,8 @@ public void exceptionsResultInControlTreatments() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); Map result = client.getTreatments("adil@relateiq.com", Arrays.asList("test1")); assertEquals(1, result.size()); @@ -1812,7 +1858,8 @@ public void worksTreatments() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); Map result = client.getTreatments("anyKey", Arrays.asList(test, test2)); assertNotNull(result); @@ -1841,6 +1888,7 @@ public void worksOneControlTreatments() { RuleBasedSegmentCacheConsumer ruleBasedSegmentCacheConsumer = mock(RuleBasedSegmentCacheConsumer.class); when(splitCacheConsumer.fetchMany(anyList())).thenReturn(parsedSplits); when(gates.isSDKReady()).thenReturn(true); + FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(null); SplitClientImpl client = new SplitClientImpl( mock(SplitFactory.class), @@ -1849,8 +1897,9 @@ public void worksOneControlTreatments() { NoopEventsStorageImp.create(), config, gates, - new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, fallbackTreatmentCalculatorImp), TELEMETRY_STORAGE, TELEMETRY_STORAGE, + flagSetsFilter, + fallbackTreatmentCalculatorImp ); Map result = client.getTreatments("anyKey", Arrays.asList(test, test2)); @@ -1886,6 +1935,7 @@ public void treatmentsWorksAndHasConfig() { SegmentCacheConsumer segmentCacheConsumer = mock(SegmentCacheConsumer.class); RuleBasedSegmentCacheConsumer ruleBasedSegmentCacheConsumer = mock(RuleBasedSegmentCacheConsumer.class); when(splitCacheConsumer.fetchMany(anyList())).thenReturn(parsedSplits); + FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(null); SplitClientImpl client = new SplitClientImpl( mock(SplitFactory.class), @@ -1894,8 +1944,9 @@ public void treatmentsWorksAndHasConfig() { NoopEventsStorageImp.create(), config, gates, - new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, fallbackTreatmentCalculatorImp), TELEMETRY_STORAGE, TELEMETRY_STORAGE, + flagSetsFilter, + fallbackTreatmentCalculatorImp ); Map attributes = new HashMap<>(); Map result = client.getTreatmentsWithConfig("randomKey", Arrays.asList(test, test2, "", null), attributes); @@ -1938,7 +1989,8 @@ public void testTreatmentsByFlagSet() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); int numKeys = 5; @@ -1979,7 +2031,8 @@ public void testTreatmentsByFlagSetInvalid() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); assertTrue(client.getTreatmentsByFlagSet(RandomStringUtils.random(10), "", new HashMap<>()).isEmpty()); } @@ -2023,7 +2076,8 @@ public void testTreatmentsByFlagSets() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + flagSetsFilter, + new FallbackTreatmentCalculatorImp(null) ); int numKeys = 5; Map getTreatmentResult; @@ -2070,6 +2124,7 @@ public void treatmentsWorksAndHasConfigFlagSet() { when(splitCacheConsumer.getNamesByFlagSets(sets)).thenReturn(flagsBySets); SDKReadinessGates gates = mock(SDKReadinessGates.class); + FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(null); SplitClientImpl client = new SplitClientImpl( mock(SplitFactory.class), @@ -2078,8 +2133,9 @@ public void treatmentsWorksAndHasConfigFlagSet() { NoopEventsStorageImp.create(), config, gates, - new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, fallbackTreatmentCalculatorImp), TELEMETRY_STORAGE, TELEMETRY_STORAGE, + flagSetsFilter, + fallbackTreatmentCalculatorImp ); Map attributes = new HashMap<>(); Map result = client.getTreatmentsWithConfigByFlagSet("randomKey", "set1", attributes); @@ -2127,6 +2183,7 @@ public void treatmentsWorksAndHasConfigFlagSets() { when(splitCacheConsumer.getNamesByFlagSets(sets)).thenReturn(flagsBySets); SDKReadinessGates gates = mock(SDKReadinessGates.class); + FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(null); SplitClientImpl client = new SplitClientImpl( mock(SplitFactory.class), @@ -2135,8 +2192,9 @@ public void treatmentsWorksAndHasConfigFlagSets() { NoopEventsStorageImp.create(), config, gates, - new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - flagSetsFilter + new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, fallbackTreatmentCalculatorImp), TELEMETRY_STORAGE, TELEMETRY_STORAGE, + flagSetsFilter, + fallbackTreatmentCalculatorImp ); Map attributes = new HashMap<>(); Map result = client.getTreatmentsWithConfigByFlagSets("randomKey", new ArrayList<>(Arrays.asList("set1")), attributes); @@ -2182,7 +2240,9 @@ public void impressionPropertiesTest() { config, gates, new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, null), TELEMETRY_STORAGE, TELEMETRY_STORAGE, - new FlagSetsFilterImpl(new HashSet<>()) + new FlagSetsFilterImpl(new HashSet<>()), + new FallbackTreatmentCalculatorImp(null) + ); Map attributes = ImmutableMap.of("age", -20, "acv", "1000000"); EvaluationOptions properties = new EvaluationOptions(new HashMap() @@ -2233,4 +2293,350 @@ public void impressionPropertiesTest() { assertEquals("{\"prop2\":\"val2\",\"prop1\":\"val1\"}", impression.impression().properties()); } } + + @Test + public void fallbackTreatmentWithExceptionsResult() { + SDKReadinessGates gates = mock(SDKReadinessGates.class); + SplitCacheConsumer splitCacheConsumer = mock(SplitCacheConsumer.class); + SegmentCacheConsumer segmentCacheConsumer = mock(SegmentCacheConsumer.class); + RuleBasedSegmentCacheConsumer ruleBasedSegmentCacheConsumer = mock(RuleBasedSegmentCacheConsumer.class); + when(splitCacheConsumer.get(anyString())).thenThrow(RuntimeException.class); + when(splitCacheConsumer.fetchMany(anyList())).thenThrow(RuntimeException.class); + HashMap> features = new HashMap<>(); + features.put("flag", new HashSet<>(Arrays.asList("test1"))); + when(splitCacheConsumer.getNamesByFlagSets(anyList())).thenReturn(features); + + String fallbcakConfigGlobal = "{\"prop1\", \"val1\"}"; + FallbackTreatmentsConfiguration fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration( + new FallbackTreatment("on", fallbcakConfigGlobal), + null); + FallbackTreatmentCalculator fallbackTreatmentCalculator = new FallbackTreatmentCalculatorImp(fallbackTreatmentsConfiguration); + + SplitClientImpl client = new SplitClientImpl( + mock(SplitFactory.class), + splitCacheConsumer, + new ImpressionsManager.NoOpImpressionsManager(), + NoopEventsStorageImp.create(), + config, + gates, + new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, fallbackTreatmentCalculator), + TELEMETRY_STORAGE, TELEMETRY_STORAGE, + new FlagSetsFilterImpl(new HashSet<>()), + fallbackTreatmentCalculator + ); + assertEquals("on", client.getTreatment("adil@relateiq.com", "test1")); + assertEquals("on", client.getTreatmentWithConfig("adil@relateiq.com", "test1").treatment()); + assertEquals(fallbcakConfigGlobal, client.getTreatmentWithConfig("adil@relateiq.com", "test1").config()); + assertEquals("on", client.getTreatments("adil@relateiq.com", Arrays.asList("test1")).get("test1")); + assertEquals("on", client.getTreatmentsWithConfig("adil@relateiq.com", Arrays.asList("test1")).get("test1").treatment()); + assertEquals(fallbcakConfigGlobal, client.getTreatmentsWithConfig("adil@relateiq.com", Arrays.asList("test1")).get("test1").config()); + + assertEquals("on", client.getTreatmentsByFlagSet("adil@relateiq.com", "flag").get("test1")); + assertEquals("on", client.getTreatmentsByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("test1")); + assertEquals("on", client.getTreatmentsWithConfigByFlagSet("adil@relateiq.com", "flag").get("test1").treatment()); + assertEquals(fallbcakConfigGlobal, client.getTreatmentsWithConfigByFlagSet("adil@relateiq.com", "flag").get("test1").config()); + assertEquals("on", client.getTreatmentsWithConfigByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("test1").treatment()); + assertEquals(fallbcakConfigGlobal, client.getTreatmentsWithConfigByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("test1").config()); + + String fallbcakConfigByFlag = "{\"prop2\", \"val2\"}"; + fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration(new FallbackTreatment("on", fallbcakConfigGlobal), + new HashMap() {{ put("feature", new FallbackTreatment("off", fallbcakConfigByFlag)); }}); + + features = new HashMap<>(); + features.put("flag", new HashSet<>(Arrays.asList("test", "feature"))); + when(splitCacheConsumer.getNamesByFlagSets(anyList())).thenReturn(features); + + fallbackTreatmentCalculator = new FallbackTreatmentCalculatorImp(fallbackTreatmentsConfiguration); + + client = new SplitClientImpl( + mock(SplitFactory.class), + splitCacheConsumer, + new ImpressionsManager.NoOpImpressionsManager(), + NoopEventsStorageImp.create(), + config, + gates, + new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, fallbackTreatmentCalculator), + TELEMETRY_STORAGE, TELEMETRY_STORAGE, + new FlagSetsFilterImpl(new HashSet<>()), + fallbackTreatmentCalculator + ); + assertEquals("on", client.getTreatment("adil@relateiq.com", "test")); + assertEquals("off", client.getTreatment("adil@relateiq.com", "feature")); + assertEquals("on", client.getTreatmentWithConfig("adil@relateiq.com", "test1").treatment()); + assertEquals(fallbcakConfigGlobal, client.getTreatmentWithConfig("adil@relateiq.com", "test1").config()); + assertEquals("off", client.getTreatmentWithConfig("adil@relateiq.com", "feature").treatment()); + assertEquals(fallbcakConfigByFlag, client.getTreatmentWithConfig("adil@relateiq.com", "feature").config()); + Map result = client.getTreatments("adil@relateiq.com", Arrays.asList("feature", "test")); + assertEquals("off", result.get("feature")); + assertEquals("on", result.get("test")); + Map results = client.getTreatmentsWithConfig("adil@relateiq.com", Arrays.asList("feature", "test")); + assertEquals("off", results.get("feature").treatment()); + assertEquals(fallbcakConfigByFlag, results.get("feature").config()); + assertEquals("on", results.get("test").treatment()); + assertEquals(fallbcakConfigGlobal, results.get("test").config()); + + assertEquals("on", client.getTreatmentsByFlagSet("adil@relateiq.com", "flag").get("test")); + assertEquals("off", client.getTreatmentsByFlagSet("adil@relateiq.com", "flag").get("feature")); + assertEquals("on", client.getTreatmentsByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("test")); + assertEquals("off", client.getTreatmentsByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("feature")); + assertEquals("on", client.getTreatmentsWithConfigByFlagSet("adil@relateiq.com", "flag").get("test").treatment()); + assertEquals(fallbcakConfigGlobal, client.getTreatmentsWithConfigByFlagSet("adil@relateiq.com", "flag").get("test").config()); + assertEquals("off", client.getTreatmentsWithConfigByFlagSet("adil@relateiq.com", "flag").get("feature").treatment()); + assertEquals(fallbcakConfigByFlag, client.getTreatmentsWithConfigByFlagSet("adil@relateiq.com", "flag").get("feature").config()); + assertEquals("on", client.getTreatmentsWithConfigByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("test").treatment()); + assertEquals(fallbcakConfigGlobal, client.getTreatmentsWithConfigByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("test").config()); + assertEquals("off", client.getTreatmentsWithConfigByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("feature").treatment()); + assertEquals(fallbcakConfigByFlag, client.getTreatmentsWithConfigByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("feature").config()); + + fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration(null, + new HashMap() {{ put("feature", new FallbackTreatment("off", fallbcakConfigByFlag)); }}); + + fallbackTreatmentCalculator = new FallbackTreatmentCalculatorImp(fallbackTreatmentsConfiguration); + + client = new SplitClientImpl( + mock(SplitFactory.class), + splitCacheConsumer, + new ImpressionsManager.NoOpImpressionsManager(), + NoopEventsStorageImp.create(), + config, + gates, + new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, fallbackTreatmentCalculator), TELEMETRY_STORAGE, TELEMETRY_STORAGE, + new FlagSetsFilterImpl(new HashSet<>()), + fallbackTreatmentCalculator + ); + assertEquals(Treatments.CONTROL, client.getTreatment("adil@relateiq.com", "test")); + assertEquals("off", client.getTreatment("adil@relateiq.com", "feature")); + assertEquals(Treatments.CONTROL, client.getTreatmentWithConfig("adil@relateiq.com", "test1").treatment()); + assertEquals(null, client.getTreatmentWithConfig("adil@relateiq.com", "test1").config()); + assertEquals("off", client.getTreatmentWithConfig("adil@relateiq.com", "feature").treatment()); + assertEquals(fallbcakConfigByFlag, client.getTreatmentWithConfig("adil@relateiq.com", "feature").config()); + result = client.getTreatments("adil@relateiq.com", Arrays.asList("feature", "test")); + assertEquals("off", result.get("feature")); + assertEquals(Treatments.CONTROL, result.get("test")); + results = client.getTreatmentsWithConfig("adil@relateiq.com", Arrays.asList("feature", "test")); + assertEquals("off", results.get("feature").treatment()); + assertEquals(fallbcakConfigByFlag, results.get("feature").config()); + assertEquals(Treatments.CONTROL, results.get("test").treatment()); + assertEquals(null, results.get("test").config()); + + assertEquals(Treatments.CONTROL, client.getTreatmentsByFlagSet("adil@relateiq.com", "flag").get("test")); + assertEquals("off", client.getTreatmentsByFlagSet("adil@relateiq.com", "flag").get("feature")); + assertEquals(Treatments.CONTROL, client.getTreatmentsByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("test")); + assertEquals("off", client.getTreatmentsByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("feature")); + assertEquals(Treatments.CONTROL, client.getTreatmentsWithConfigByFlagSet("adil@relateiq.com", "flag").get("test").treatment()); + assertEquals(null, client.getTreatmentsWithConfigByFlagSet("adil@relateiq.com", "flag").get("test").config()); + assertEquals("off", client.getTreatmentsWithConfigByFlagSet("adil@relateiq.com", "flag").get("feature").treatment()); + assertEquals(fallbcakConfigByFlag, client.getTreatmentsWithConfigByFlagSet("adil@relateiq.com", "flag").get("feature").config()); + assertEquals(Treatments.CONTROL, client.getTreatmentsWithConfigByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("test").treatment()); + assertEquals(null, client.getTreatmentsWithConfigByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("test").config()); + assertEquals("off", client.getTreatmentsWithConfigByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("feature").treatment()); + assertEquals(fallbcakConfigByFlag, client.getTreatmentsWithConfigByFlagSets("adil@relateiq.com", Arrays.asList("flag")).get("feature").config()); + } + + @Test + public void fallbackTreatmentWithSplitNotFoundResult() { + SDKReadinessGates gates = mock(SDKReadinessGates.class); + SplitCacheConsumer splitCacheConsumer = mock(SplitCacheConsumer.class); + SegmentCacheConsumer segmentCacheConsumer = mock(SegmentCacheConsumer.class); + RuleBasedSegmentCacheConsumer ruleBasedSegmentCacheConsumer = mock(RuleBasedSegmentCacheConsumer.class); + ParsedCondition rollOutToEveryone = ParsedCondition.createParsedConditionForTests(CombiningMatcher.of(new WhitelistMatcher(Lists.newArrayList("adil@codigo.com"))), Lists.newArrayList(partition("on", 100))); + List conditions = Lists.newArrayList(rollOutToEveryone); + ParsedSplit parsedSplit = ParsedSplit.createParsedSplitForTests("test", 123, false, Treatments.OFF, conditions, + null, 1, 1, new HashSet<>(), false, new PrerequisitesMatcher(null)); + + when(splitCacheConsumer.get("test1")).thenReturn(parsedSplit); + when(splitCacheConsumer.get("test2")).thenReturn(null); + when(splitCacheConsumer.get("test3")).thenReturn(null); + HashMap features = new HashMap<>(); + features.put("test1", parsedSplit); + features.put("test2", null); + features.put("test3", null); + when(splitCacheConsumer.fetchMany(anyList())).thenReturn(features); + HashMap> flagFeatures = new HashMap<>(); + flagFeatures.put("flag", new HashSet<>(Arrays.asList("test1", "test2", "test3"))); + when(splitCacheConsumer.getNamesByFlagSets(anyList())).thenReturn(flagFeatures); + + String fallbcakConfigGlobal = "{\"prop1\", \"val1\"}"; + FallbackTreatmentsConfiguration fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration( + new FallbackTreatment("on", fallbcakConfigGlobal), + null); + FallbackTreatmentCalculator fallbackTreatmentCalculator = new FallbackTreatmentCalculatorImp(fallbackTreatmentsConfiguration); + + SplitClientImpl client = new SplitClientImpl( + mock(SplitFactory.class), + splitCacheConsumer, + new ImpressionsManager.NoOpImpressionsManager(), + NoopEventsStorageImp.create(), + config, + gates, + new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, fallbackTreatmentCalculator), + TELEMETRY_STORAGE, TELEMETRY_STORAGE, + new FlagSetsFilterImpl(new HashSet<>()), + fallbackTreatmentCalculator + ); + assertEquals("off", client.getTreatment("adil@relateiq.com", "test1")); + assertEquals("on", client.getTreatment("adil@relateiq.com", "test2")); + assertEquals("on", client.getTreatmentWithConfig("adil@relateiq.com", "test2").treatment()); + assertEquals(fallbcakConfigGlobal, client.getTreatmentWithConfig("adil@relateiq.com", "test2").config()); + + Map result = client.getTreatments("adil@relateiq.com", Arrays.asList("test1", "test2")); + assertEquals("off", result.get("test1")); + assertEquals("on", result.get("test2")); + Map resultWithConfig = client.getTreatmentsWithConfig("adil@relateiq.com", Arrays.asList("test1", "test2")); + assertEquals("off", resultWithConfig.get("test1").treatment()); + assertEquals(null, resultWithConfig.get("test1").config()); + assertEquals("on", resultWithConfig.get("test2").treatment()); + assertEquals(fallbcakConfigGlobal, resultWithConfig.get("test2").config()); + + result = client.getTreatmentsByFlagSet("adil@relateiq.com", "flag"); + assertEquals("off", result.get("test1")); + assertEquals("on", result.get("test2")); + result = client.getTreatmentsByFlagSets("adil@relateiq.com", Arrays.asList("flag")); + assertEquals("off", result.get("test1")); + assertEquals("on", result.get("test2")); + resultWithConfig = client.getTreatmentsWithConfigByFlagSet("adil@relateiq.com", "flag"); + assertEquals("off", resultWithConfig.get("test1").treatment()); + assertEquals(null, resultWithConfig.get("test1").config()); + assertEquals("on", resultWithConfig.get("test2").treatment()); + assertEquals(fallbcakConfigGlobal, resultWithConfig.get("test2").config()); + resultWithConfig = client.getTreatmentsWithConfigByFlagSets("adil@relateiq.com", Arrays.asList("flag")); + assertEquals("off", resultWithConfig.get("test1").treatment()); + assertEquals(null, resultWithConfig.get("test1").config()); + assertEquals("on", resultWithConfig.get("test2").treatment()); + assertEquals(fallbcakConfigGlobal, resultWithConfig.get("test2").config()); + + String fallbcakConfigByFlag = "{\"prop2\", \"val2\"}"; + fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration(new FallbackTreatment("on", fallbcakConfigGlobal), + new HashMap() {{ put("test2", new FallbackTreatment("off-fallback", fallbcakConfigByFlag)); }}); + + fallbackTreatmentCalculator = new FallbackTreatmentCalculatorImp(fallbackTreatmentsConfiguration); + + client = new SplitClientImpl( + mock(SplitFactory.class), + splitCacheConsumer, + new ImpressionsManager.NoOpImpressionsManager(), + NoopEventsStorageImp.create(), + config, + gates, + new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, fallbackTreatmentCalculator), + TELEMETRY_STORAGE, TELEMETRY_STORAGE, + new FlagSetsFilterImpl(new HashSet<>()), + fallbackTreatmentCalculator + ); + assertEquals("off", client.getTreatment("adil@relateiq.com", "test1")); + assertEquals("off-fallback", client.getTreatment("adil@relateiq.com", "test2")); + assertEquals("on", client.getTreatment("adil@relateiq.com", "test3")); + + assertEquals("off", client.getTreatmentWithConfig("adil@relateiq.com", "test1").treatment()); + assertEquals(null, client.getTreatmentWithConfig("adil@relateiq.com", "test1").config()); + assertEquals("off-fallback", client.getTreatmentWithConfig("adil@relateiq.com", "test2").treatment()); + assertEquals(fallbcakConfigByFlag, client.getTreatmentWithConfig("adil@relateiq.com", "test2").config()); + assertEquals("on", client.getTreatmentWithConfig("adil@relateiq.com", "test3").treatment()); + assertEquals(fallbcakConfigGlobal, client.getTreatmentWithConfig("adil@relateiq.com", "test3").config()); + + result = client.getTreatments("adil@relateiq.com", Arrays.asList("test1", "test2", "test3")); + assertEquals("off", result.get("test1")); + assertEquals("off-fallback", result.get("test2")); + assertEquals("on", result.get("test3")); + + Map results = client.getTreatmentsWithConfig("adil@relateiq.com", Arrays.asList("test1", "test2", "test3")); + assertEquals("off", results.get("test1").treatment()); + assertEquals(null, results.get("test1").config()); + assertEquals("off-fallback", results.get("test2").treatment()); + assertEquals(fallbcakConfigByFlag, results.get("test2").config()); + assertEquals("on", results.get("test3").treatment()); + assertEquals(fallbcakConfigGlobal, results.get("test3").config()); + + result = client.getTreatmentsByFlagSet("adil@relateiq.com", "flag"); + assertEquals("off", result.get("test1")); + assertEquals("off-fallback", result.get("test2")); + assertEquals("on", result.get("test3")); + + result = client.getTreatmentsByFlagSets("adil@relateiq.com", Arrays.asList("flag")); + assertEquals("off", result.get("test1")); + assertEquals("off-fallback", result.get("test2")); + assertEquals("on", result.get("test3")); + + results = client.getTreatmentsWithConfigByFlagSet("adil@relateiq.com", "flag"); + assertEquals("off", results.get("test1").treatment()); + assertEquals(null, results.get("test1").config()); + assertEquals("off-fallback", results.get("test2").treatment()); + assertEquals(fallbcakConfigByFlag, results.get("test2").config()); + assertEquals("on", results.get("test3").treatment()); + assertEquals(fallbcakConfigGlobal, results.get("test3").config()); + + results = client.getTreatmentsWithConfigByFlagSets("adil@relateiq.com", Arrays.asList("flag")); + assertEquals("off", results.get("test1").treatment()); + assertEquals(null, results.get("test1").config()); + assertEquals("off-fallback", results.get("test2").treatment()); + assertEquals(fallbcakConfigByFlag, results.get("test2").config()); + assertEquals("on", results.get("test3").treatment()); + assertEquals(fallbcakConfigGlobal, results.get("test3").config()); + + fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration(null, + new HashMap() {{ put("test2", new FallbackTreatment("off-fallback", fallbcakConfigByFlag)); }}); + + fallbackTreatmentCalculator = new FallbackTreatmentCalculatorImp(fallbackTreatmentsConfiguration); + + client = new SplitClientImpl( + mock(SplitFactory.class), + splitCacheConsumer, + new ImpressionsManager.NoOpImpressionsManager(), + NoopEventsStorageImp.create(), + config, + gates, + new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer, ruleBasedSegmentCacheConsumer, fallbackTreatmentCalculator), TELEMETRY_STORAGE, TELEMETRY_STORAGE, + new FlagSetsFilterImpl(new HashSet<>()), + fallbackTreatmentCalculator + ); + assertEquals("off", client.getTreatment("adil@relateiq.com", "test1")); + assertEquals("off-fallback", client.getTreatment("adil@relateiq.com", "test2")); + assertEquals(Treatments.CONTROL, client.getTreatment("adil@relateiq.com", "test3")); + + assertEquals("off", client.getTreatmentWithConfig("adil@relateiq.com", "test1").treatment()); + assertEquals(null, client.getTreatmentWithConfig("adil@relateiq.com", "test1").config()); + assertEquals("off-fallback", client.getTreatmentWithConfig("adil@relateiq.com", "test2").treatment()); + assertEquals(fallbcakConfigByFlag, client.getTreatmentWithConfig("adil@relateiq.com", "test2").config()); + assertEquals(Treatments.CONTROL, client.getTreatmentWithConfig("adil@relateiq.com", "test3").treatment()); + assertEquals(null, client.getTreatmentWithConfig("adil@relateiq.com", "test3").config()); + + result = client.getTreatments("adil@relateiq.com", Arrays.asList("test1", "test2", "test3")); + assertEquals("off", result.get("test1")); + assertEquals("off-fallback", result.get("test2")); + assertEquals(Treatments.CONTROL, result.get("test3")); + + results = client.getTreatmentsWithConfig("adil@relateiq.com", Arrays.asList("test1", "test2", "test3")); + assertEquals("off", results.get("test1").treatment()); + assertEquals(null, results.get("test1").config()); + assertEquals("off-fallback", results.get("test2").treatment()); + assertEquals(fallbcakConfigByFlag, results.get("test2").config()); + assertEquals(Treatments.CONTROL, results.get("test3").treatment()); + assertEquals(null, results.get("test3").config()); + + result = client.getTreatmentsByFlagSet("adil@relateiq.com", "flag"); + assertEquals("off", result.get("test1")); + assertEquals("off-fallback", result.get("test2")); + assertEquals(Treatments.CONTROL, result.get("test3")); + + result = client.getTreatmentsByFlagSets("adil@relateiq.com", Arrays.asList("flag")); + assertEquals("off", result.get("test1")); + assertEquals("off-fallback", result.get("test2")); + assertEquals(Treatments.CONTROL, result.get("test3")); + + results = client.getTreatmentsWithConfigByFlagSet("adil@relateiq.com", "flag"); + assertEquals("off", results.get("test1").treatment()); + assertEquals(null, results.get("test1").config()); + assertEquals("off-fallback", results.get("test2").treatment()); + assertEquals(fallbcakConfigByFlag, results.get("test2").config()); + assertEquals(Treatments.CONTROL, results.get("test3").treatment()); + assertEquals(null, results.get("test3").config()); + + results = client.getTreatmentsWithConfigByFlagSets("adil@relateiq.com", Arrays.asList("flag")); + assertEquals("off", results.get("test1").treatment()); + assertEquals(null, results.get("test1").config()); + assertEquals("off-fallback", results.get("test2").treatment()); + assertEquals(fallbcakConfigByFlag, results.get("test2").config()); + assertEquals(Treatments.CONTROL, results.get("test3").treatment()); + assertEquals(null, results.get("test3").config()); + } } \ No newline at end of file diff --git a/client/src/test/java/io/split/engine/evaluator/EvaluatorIntegrationTest.java b/client/src/test/java/io/split/engine/evaluator/EvaluatorIntegrationTest.java index e686f530..5b0a024a 100644 --- a/client/src/test/java/io/split/engine/evaluator/EvaluatorIntegrationTest.java +++ b/client/src/test/java/io/split/engine/evaluator/EvaluatorIntegrationTest.java @@ -2,6 +2,7 @@ import com.google.common.collect.Lists; import io.split.client.dtos.ConditionType; +import io.split.client.dtos.FallbackTreatmentCalculatorImp; import io.split.client.dtos.MatcherCombiner; import io.split.client.dtos.Partition; import io.split.client.interceptors.FlagSetsFilter; @@ -174,7 +175,8 @@ private Evaluator buildEvaluatorAndLoadCache(boolean killed, int trafficAllocati SplitCache splitCache = new InMemoryCacheImp(flagSetsFilter); SegmentCache segmentCache = new SegmentCacheInMemoryImpl(); RuleBasedSegmentCache ruleBasedSegmentCache = new RuleBasedSegmentCacheInMemoryImp(); - Evaluator evaluator = new EvaluatorImp(splitCache, segmentCache, ruleBasedSegmentCache, null); + FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(null); + Evaluator evaluator = new EvaluatorImp(splitCache, segmentCache, ruleBasedSegmentCache, fallbackTreatmentCalculatorImp); Partition partition = new Partition(); partition.treatment = ON_TREATMENT; diff --git a/client/src/test/java/io/split/engine/evaluator/EvaluatorTest.java b/client/src/test/java/io/split/engine/evaluator/EvaluatorTest.java index 9ef7343a..05a87a61 100644 --- a/client/src/test/java/io/split/engine/evaluator/EvaluatorTest.java +++ b/client/src/test/java/io/split/engine/evaluator/EvaluatorTest.java @@ -48,7 +48,7 @@ public void before() { _splitCacheConsumer = Mockito.mock(SplitCacheConsumer.class); _segmentCacheConsumer = Mockito.mock(SegmentCacheConsumer.class); _ruleBasedSegmentCacheConsumer = Mockito.mock(RuleBasedSegmentCacheConsumer.class); - _evaluator = new EvaluatorImp(_splitCacheConsumer, _segmentCacheConsumer, _ruleBasedSegmentCacheConsumer, null); + _evaluator = new EvaluatorImp(_splitCacheConsumer, _segmentCacheConsumer, _ruleBasedSegmentCacheConsumer, new FallbackTreatmentCalculatorImp(null)); _matcher = Mockito.mock(CombiningMatcher.class); _evaluationContext = Mockito.mock(EvaluationContext.class);