private void doTestGet(boolean sync, boolean error, boolean retry) throws Exception {
String tableId = "testGet-" + sync + error + retry;
TableReadFunction<String, String> readFn = mock(TableReadFunction.class);
CompletableFuture<String> future;
if (error) {
future = new CompletableFuture();
future.completeExceptionally(new RuntimeException("Test exception"));
if (!retry) {
doReturn(future).when(readFn).getAsync(anyString());
} else {
final int [] times = new int[] {0};
doAnswer(args -> times[0]++ == 0 ? future : CompletableFuture.completedFuture("bar"))
.when(readFn).getAsync(anyString());
}
} else {
future = CompletableFuture.completedFuture("bar");
doReturn(future).when(readFn).getAsync(anyString());
}
if (retry) {
doReturn(true).when(readFn).isRetriable(any());
}
RemoteTable<String, String> table = getTable(tableId, readFn, null, retry);
Assert.assertEquals("bar", sync ? table.get("foo") : table.getAsync("foo").get());
verify(table.readRateLimiter, times(error && retry ? 2 : 1)).throttle(anyString());
}