private <K, V, T extends RemoteTable<K, V>> T getTable(String tableId, TableReadFunction<K, V> readFn, TableWriteFunction<K, V> writeFn, boolean retry) { return getTable(tableId, readFn, writeFn, null, retry); }
@Test public void testFlush() { TableWriteFunction<String, String> writeFn = mock(TableWriteFunction.class); RemoteTable<String, String> table = getTable("testFlush", mock(TableReadFunction.class), writeFn, false); table.flush(); verify(writeFn, times(1)).flush(); }
@Test public void testGetMultipleTables() { TableReadFunction<String, String> readFn1 = mock(TableReadFunction.class); TableReadFunction<String, String> readFn2 = mock(TableReadFunction.class); // Sync is backed by async so needs to mock the async method doReturn(CompletableFuture.completedFuture("bar1")).when(readFn1).getAsync(anyString()); doReturn(CompletableFuture.completedFuture("bar2")).when(readFn1).getAsync(anyString()); RemoteTable<String, String> table1 = getTable("testGetMultipleTables-1", readFn1, null, false); RemoteTable<String, String> table2 = getTable("testGetMultipleTables-2", readFn2, null, false); CompletableFuture<String> future1 = table1.getAsync("foo1"); CompletableFuture<String> future2 = table2.getAsync("foo2"); CompletableFuture.allOf(future1, future2) .thenAccept(u -> { Assert.assertEquals(future1.join(), "bar1"); Assert.assertEquals(future2.join(), "bar1"); }); }
@Test public void testGetWithCallbackExecutor() throws Exception { TableReadFunction<String, String> readFn = mock(TableReadFunction.class); // Sync is backed by async so needs to mock the async method doReturn(CompletableFuture.completedFuture("bar")).when(readFn).getAsync(anyString()); RemoteTable<String, String> table = getTable("testGetWithCallbackExecutor", readFn, null, Executors.newSingleThreadExecutor(), false); Thread testThread = Thread.currentThread(); table.getAsync("foo").thenAccept(result -> { Assert.assertEquals("bar", result); // Must be executed on the executor thread Assert.assertNotSame(testThread, Thread.currentThread()); }); } }
private void doTestGetAll(boolean sync, boolean error, boolean partial) throws Exception { TableReadFunction<String, String> readFn = mock(TableReadFunction.class); Map<String, String> res = new HashMap<>(); res.put("foo1", "bar1"); if (!partial) { res.put("foo2", "bar2"); } CompletableFuture<Map<String, String>> future; if (error) { future = new CompletableFuture(); future.completeExceptionally(new RuntimeException("Test exception")); } else { future = CompletableFuture.completedFuture(res); } // Sync is backed by async so needs to mock the async method doReturn(future).when(readFn).getAllAsync(any()); RemoteTable<String, String> table = getTable("testGetAll-" + sync + error + partial, readFn, null, false); Assert.assertEquals(res, sync ? table.getAll(Arrays.asList("foo1", "foo2")) : table.getAllAsync(Arrays.asList("foo1", "foo2")).get()); verify(table.readRateLimiter, times(1)).throttle(anyCollection()); }
private void doTestDelete(boolean sync, boolean error) throws Exception { TableWriteFunction<String, String> writeFn = mock(TableWriteFunction.class); RemoteTable<String, String> table = getTable("testDelete-" + sync + error, mock(TableReadFunction.class), writeFn, false); CompletableFuture<Void> future; if (error) { future = new CompletableFuture(); future.completeExceptionally(new RuntimeException("Test exception")); } else { future = CompletableFuture.completedFuture(null); } // Sync is backed by async so needs to mock the async method doReturn(future).when(writeFn).deleteAsync(any()); ArgumentCaptor<String> argCaptor = ArgumentCaptor.forClass(String.class); if (sync) { table.delete("foo"); } else { table.deleteAsync("foo").get(); } verify(writeFn, times(1)).deleteAsync(argCaptor.capture()); Assert.assertEquals("foo", argCaptor.getValue()); verify(table.writeRateLimiter, times(1)).throttle(anyString()); }
private void doTestGet(boolean sync, boolean error, boolean retry) throws Exception { String tableId = "testGet-" + sync + error + retry; TableReadFunction<String, String> readFn = mock(TableReadFunction.class); // Sync is backed by async so needs to mock the async method 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()); }
public void doTestDeleteAll(boolean sync, boolean error) throws Exception { TableWriteFunction<String, String> writeFn = mock(TableWriteFunction.class); RemoteTable<String, String> table = getTable("testDeleteAll-" + sync + error, mock(TableReadFunction.class), writeFn, false); CompletableFuture<Void> future; if (error) { future = new CompletableFuture(); future.completeExceptionally(new RuntimeException("Test exception")); } else { future = CompletableFuture.completedFuture(null); } // Sync is backed by async so needs to mock the async method doReturn(future).when(writeFn).deleteAllAsync(any()); List<String> keys = Arrays.asList("foo1", "foo2"); ArgumentCaptor<List> argCaptor = ArgumentCaptor.forClass(List.class); if (sync) { table.deleteAll(keys); } else { table.deleteAllAsync(keys).get(); } verify(writeFn, times(1)).deleteAllAsync(argCaptor.capture()); Assert.assertEquals(keys, argCaptor.getValue()); verify(table.writeRateLimiter, times(1)).throttle(anyCollection()); }
RemoteTable<String, String> table = getTable(tableId, mock(TableReadFunction.class), writeFn, retry); if (sync) { table.put("foo", isDelete ? null : "bar");
public void doTestPutAll(boolean sync, boolean error, boolean hasDelete) throws Exception { TableWriteFunction<String, String> writeFn = mock(TableWriteFunction.class); RemoteTable<String, String> table = getTable("testPutAll-" + sync + error + hasDelete, mock(TableReadFunction.class), writeFn, false); CompletableFuture<Void> future;