Skip to content

Commit 794bb44

Browse files
committed
tests for respecting graceful mode
1 parent feb8bc0 commit 794bb44

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

src/test/java/cloud/eppo/EppoClientTest.java

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import static cloud.eppo.helpers.AssignmentTestCase.runTestCase;
55
import static cloud.eppo.helpers.BanditTestCase.parseBanditTestCaseFile;
66
import static cloud.eppo.helpers.BanditTestCase.runBanditTestCase;
7+
import static cloud.eppo.helpers.TestUtils.mockHttpError;
78
import static org.junit.jupiter.api.Assertions.*;
89
import static org.junit.jupiter.api.Assertions.assertThrows;
910
import static org.mockito.Mockito.*;
@@ -23,6 +24,7 @@
2324
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
2425
import java.io.File;
2526
import java.lang.reflect.Field;
27+
import java.util.concurrent.CompletableFuture;
2628
import java.util.stream.Stream;
2729
import org.apache.commons.io.FileUtils;
2830
import org.junit.jupiter.api.AfterAll;
@@ -238,6 +240,71 @@ public void testPolling() {
238240
verify(httpClientSpy, times(2)).get(anyString());
239241
}
240242

243+
@Test
244+
public void testGracefulInitializationFailure() {
245+
// Set up bad HTTP response
246+
mockHttpError();
247+
248+
// Initialize and no exception should be thrown.
249+
assertDoesNotThrow(() -> initFailingGracefulClient(true));
250+
}
251+
252+
@Test
253+
public void testClientMakesDefaultAssignmentsAfterFailingToInitialize() {
254+
// Set up bad HTTP response
255+
mockHttpError();
256+
257+
// Initialize and no exception should be thrown.
258+
try {
259+
EppoClient eppoClient = initFailingGracefulClient(true);
260+
assertEquals("default", eppoClient.getStringAssignment("experiment1", "subject1", "default"));
261+
} catch (Exception e) {
262+
fail("Unexpected exception: " + e);
263+
}
264+
}
265+
266+
@Test
267+
public void testClientMakesDefaultAssignmentsAfterFailingToInitializeNonGracefulMode() {
268+
// Set up bad HTTP response
269+
mockHttpError();
270+
271+
// Initialize and the exception should be thrown.
272+
try {
273+
initFailingGracefulClient(false);
274+
} catch (RuntimeException e) {
275+
// Expected
276+
assertEquals("Intentional Error", e.getMessage());
277+
} finally {
278+
assertEquals(
279+
"default",
280+
EppoClient.getInstance().getStringAssignment("experiment1", "subject1", "default"));
281+
}
282+
}
283+
284+
@Test
285+
public void testNonGracefulInitializationFailure() {
286+
// Set up bad HTTP response
287+
mockHttpError();
288+
289+
// Initialize and assert exception thrown
290+
assertThrows(Exception.class, () -> initFailingGracefulClient(false));
291+
}
292+
293+
public static void mockHttpError() {
294+
// Create a mock instance of EppoHttpClient
295+
EppoHttpClient mockHttpClient = mock(EppoHttpClient.class);
296+
297+
// Mock sync get
298+
when(mockHttpClient.get(anyString())).thenThrow(new RuntimeException("Intentional Error"));
299+
300+
// Mock async get
301+
CompletableFuture<byte[]> mockAsyncResponse = new CompletableFuture<>();
302+
when(mockHttpClient.getAsync(anyString())).thenReturn(mockAsyncResponse);
303+
mockAsyncResponse.completeExceptionally(new RuntimeException("Intentional Error"));
304+
305+
setBaseClientHttpClientOverrideField(mockHttpClient);
306+
}
307+
241308
@SuppressWarnings("SameParameterValue")
242309
private void sleepUninterruptedly(long sleepMs) {
243310
try {
@@ -261,6 +328,20 @@ private EppoClient initClient(String apiKey) {
261328
.buildAndInit();
262329
}
263330

331+
private EppoClient initFailingGracefulClient(boolean isGracefulMode) {
332+
mockAssignmentLogger = mock(AssignmentLogger.class);
333+
mockBanditLogger = mock(BanditLogger.class);
334+
335+
return new EppoClient.Builder()
336+
.apiKey(DUMMY_FLAG_API_KEY)
337+
.host("blag")
338+
.assignmentLogger(mockAssignmentLogger)
339+
.banditLogger(mockBanditLogger)
340+
.isGracefulMode(isGracefulMode)
341+
.forceReinitialize(true) // Useful for tests
342+
.buildAndInit();
343+
}
344+
264345
private void uninitClient() {
265346
try {
266347
Field httpClientOverrideField = EppoClient.class.getDeclaredField("instance");
@@ -281,4 +362,16 @@ private void initBuggyClient() {
281362
throw new RuntimeException(e);
282363
}
283364
}
365+
366+
public static void setBaseClientHttpClientOverrideField(EppoHttpClient httpClient) {
367+
// Uses reflection to set a static override field used for tests (e.g., httpClientOverride)
368+
try {
369+
Field httpClientOverrideField = BaseEppoClient.class.getDeclaredField("httpClientOverride");
370+
httpClientOverrideField.setAccessible(true);
371+
httpClientOverrideField.set(null, httpClient);
372+
httpClientOverrideField.setAccessible(false);
373+
} catch (NoSuchFieldException | IllegalAccessException e) {
374+
throw new RuntimeException(e);
375+
}
376+
}
284377
}

0 commit comments

Comments
 (0)