@@ -2358,4 +2358,30 @@ public void isFeatureEnabled_skipsLocallyHeldOutRuleWithoutHoldoutEvent() throws
23582358 expectRuleImpression ("5200000002" , "5200000012" , "lh_flag" , "exp_rule_2" , "feature-test" , "exp_2_on" , attrs );
23592359 }
23602360
2361+ @ Test
2362+ public void decideForKeys_localHoldoutHitThenCmabError_returnsErrorAndSendsNoEventsForFlag () throws Exception {
2363+ String datafile = Resources .toString (Resources .getResource ("config/local-holdouts-project-config.json" ), Charsets .UTF_8 );
2364+ com .optimizely .ab .cmab .service .CmabService mockCmabService = mock (com .optimizely .ab .cmab .service .CmabService .class );
2365+ when (mockCmabService .getDecision (any (), any (), any (), any ())).thenThrow (new RuntimeException ("CMAB fetch failed" ));
2366+ Optimizely opt = new Optimizely .Builder ()
2367+ .withDatafile (datafile )
2368+ .withEventProcessor (new ForwardingEventProcessor (eventHandler , null ))
2369+ .withCmabService (mockCmabService )
2370+ .build ();
2371+ Map <String , Object > attrs = Collections .singletonMap ("lh" , "exp1" );
2372+
2373+ Map <String , OptimizelyDecision > decisions = opt .createUserContext (userId , attrs )
2374+ .decideForKeys (Arrays .asList ("lh_cmab_flag" , "lh_flag" ));
2375+
2376+ OptimizelyDecision cmabDecision = decisions .get ("lh_cmab_flag" );
2377+ assertNull (cmabDecision .getVariationKey ());
2378+ assertFalse (cmabDecision .getEnabled ());
2379+ assertNull (cmabDecision .getRuleKey ());
2380+ assertTrue (cmabDecision .getReasons ().contains ("Failed to fetch CMAB data for experiment cmab_rule." ));
2381+
2382+ assertEquals ("exp_2_on" , decisions .get ("lh_flag" ).getVariationKey ());
2383+ expectRuleImpression ("5200000002" , "5200000012" , "lh_flag" , "exp_rule_2" , "feature-test" , "exp_2_on" , attrs );
2384+ expectLocalHoldoutImpression ("5300000001" , "lh_exp_rule_1" , "lh_flag" , attrs );
2385+ }
2386+
23612387}
0 commit comments