Skip to content

Commit 36d2b4c

Browse files
update: add test to verify error handling in getVariation for CMAB service failures
1 parent 5e0808f commit 36d2b4c

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

core-api/src/test/java/com/optimizely/ab/bucketing/DecisionServiceTest.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,6 +1500,66 @@ public void getVariationCmabExperimentForcedPrecedesCmabService() {
15001500
verify(mockCmabService, never()).getDecision(any(), any(), any(), any());
15011501
}
15021502

1503+
/**
1504+
* Verify that getVariation handles CMAB service errors gracefully
1505+
* and falls back appropriately when CmabService throws an exception.
1506+
*/
1507+
@Test
1508+
public void getVariationCmabExperimentServiceError() {
1509+
// Create a CMAB experiment
1510+
Experiment cmabExperiment = createMockCmabExperiment();
1511+
1512+
// Create mock Cmab object
1513+
Cmab mockCmab = mock(Cmab.class);
1514+
when(mockCmab.getTrafficAllocation()).thenReturn(10000);
1515+
1516+
// Create experiment with CMAB config (no whitelisting, no forced variations)
1517+
Experiment experiment = new Experiment(
1518+
cmabExperiment.getId(),
1519+
cmabExperiment.getKey(),
1520+
cmabExperiment.getStatus(),
1521+
cmabExperiment.getLayerId(),
1522+
cmabExperiment.getAudienceIds(),
1523+
cmabExperiment.getAudienceConditions(),
1524+
cmabExperiment.getVariations(),
1525+
Collections.emptyMap(), // No whitelisting
1526+
cmabExperiment.getTrafficAllocation(),
1527+
mockCmab // This makes it a CMAB experiment
1528+
);
1529+
1530+
Bucketer bucketer = new Bucketer();
1531+
DecisionService decisionServiceWithMockCmabService = new DecisionService(
1532+
bucketer,
1533+
mockErrorHandler,
1534+
null,
1535+
mockCmabService
1536+
);
1537+
1538+
// Mock CmabService.getDecision to throw an exception
1539+
RuntimeException cmabException = new RuntimeException("CMAB service unavailable");
1540+
when(mockCmabService.getDecision(any(), any(), any(), any()))
1541+
.thenThrow(cmabException);
1542+
1543+
// Call getVariation
1544+
DecisionResponse<Variation> result = decisionServiceWithMockCmabService.getVariation(
1545+
experiment,
1546+
optimizely.createUserContext(genericUserId, Collections.emptyMap()),
1547+
v4ProjectConfig
1548+
);
1549+
1550+
// Verify that the method handles the error gracefully
1551+
// The result depends on whether the real bucketer allocates the user to CMAB traffic or not
1552+
// If user is not in CMAB traffic: result should be null
1553+
// If user is in CMAB traffic but CMAB service fails: result should be null
1554+
assertNull(result.getResult());
1555+
1556+
// Verify that the error is not propagated (no exception thrown)
1557+
assertFalse(result.isError());
1558+
1559+
// Assert that CmabService.getDecision was called exactly once
1560+
verify(mockCmabService, times(1)).getDecision(any(), any(), any(), any());
1561+
}
1562+
15031563
private Experiment createMockCmabExperiment() {
15041564
List<Variation> variations = Arrays.asList(
15051565
new Variation("111151", "variation_1"),

0 commit comments

Comments
 (0)