use of org.apache.curator.framework.api.Pathable in project flink by apache.
the class ZooKeeperCompletedCheckpointStoreTest method testCheckpointRecovery.
/**
* Tests that the completed checkpoint store can retrieve all checkpoints stored in ZooKeeper
* and ignores those which cannot be retrieved via their state handles.
*/
@Test
public void testCheckpointRecovery() throws Exception {
final List<Tuple2<RetrievableStateHandle<CompletedCheckpoint>, String>> checkpointsInZooKeeper = new ArrayList<>(4);
final CompletedCheckpoint completedCheckpoint1 = mock(CompletedCheckpoint.class);
when(completedCheckpoint1.getCheckpointID()).thenReturn(1L);
final CompletedCheckpoint completedCheckpoint2 = mock(CompletedCheckpoint.class);
when(completedCheckpoint2.getCheckpointID()).thenReturn(2L);
final Collection<Long> expectedCheckpointIds = new HashSet<>(2);
expectedCheckpointIds.add(1L);
expectedCheckpointIds.add(2L);
final RetrievableStateHandle<CompletedCheckpoint> failingRetrievableStateHandle = mock(RetrievableStateHandle.class);
when(failingRetrievableStateHandle.retrieveState()).thenThrow(new Exception("Test exception"));
final RetrievableStateHandle<CompletedCheckpoint> retrievableStateHandle1 = mock(RetrievableStateHandle.class);
when(retrievableStateHandle1.retrieveState()).thenReturn(completedCheckpoint1);
final RetrievableStateHandle<CompletedCheckpoint> retrievableStateHandle2 = mock(RetrievableStateHandle.class);
when(retrievableStateHandle2.retrieveState()).thenReturn(completedCheckpoint2);
checkpointsInZooKeeper.add(Tuple2.of(retrievableStateHandle1, "/foobar1"));
checkpointsInZooKeeper.add(Tuple2.of(failingRetrievableStateHandle, "/failing1"));
checkpointsInZooKeeper.add(Tuple2.of(retrievableStateHandle2, "/foobar2"));
checkpointsInZooKeeper.add(Tuple2.of(failingRetrievableStateHandle, "/failing2"));
final CuratorFramework client = mock(CuratorFramework.class, Mockito.RETURNS_DEEP_STUBS);
final RetrievableStateStorageHelper<CompletedCheckpoint> storageHelperMock = mock(RetrievableStateStorageHelper.class);
ZooKeeperStateHandleStore<CompletedCheckpoint> zooKeeperStateHandleStoreMock = spy(new ZooKeeperStateHandleStore<>(client, storageHelperMock, Executors.directExecutor()));
whenNew(ZooKeeperStateHandleStore.class).withAnyArguments().thenReturn(zooKeeperStateHandleStoreMock);
doReturn(checkpointsInZooKeeper).when(zooKeeperStateHandleStoreMock).getAllSortedByName();
final int numCheckpointsToRetain = 1;
// Mocking for the delete operation on the CuratorFramework client
// It assures that the callback is executed synchronously
final EnsurePath ensurePathMock = mock(EnsurePath.class);
final CuratorEvent curatorEventMock = mock(CuratorEvent.class);
when(curatorEventMock.getType()).thenReturn(CuratorEventType.DELETE);
when(curatorEventMock.getResultCode()).thenReturn(0);
when(client.newNamespaceAwareEnsurePath(anyString())).thenReturn(ensurePathMock);
when(client.delete().deletingChildrenIfNeeded().inBackground(any(BackgroundCallback.class), any(Executor.class))).thenAnswer(new Answer<Pathable<Void>>() {
@Override
public Pathable<Void> answer(InvocationOnMock invocation) throws Throwable {
final BackgroundCallback callback = (BackgroundCallback) invocation.getArguments()[0];
Pathable<Void> result = mock(Pathable.class);
when(result.forPath(anyString())).thenAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
callback.processResult(client, curatorEventMock);
return null;
}
});
return result;
}
});
final String checkpointsPath = "foobar";
final RetrievableStateStorageHelper<CompletedCheckpoint> stateSotrage = mock(RetrievableStateStorageHelper.class);
ZooKeeperCompletedCheckpointStore zooKeeperCompletedCheckpointStore = new ZooKeeperCompletedCheckpointStore(numCheckpointsToRetain, client, checkpointsPath, stateSotrage, Executors.directExecutor());
zooKeeperCompletedCheckpointStore.recover();
CompletedCheckpoint latestCompletedCheckpoint = zooKeeperCompletedCheckpointStore.getLatestCheckpoint();
// check that we return the latest retrievable checkpoint
// this should remove the latest checkpoint because it is broken
assertEquals(completedCheckpoint2.getCheckpointID(), latestCompletedCheckpoint.getCheckpointID());
// this should remove the second broken checkpoint because we're iterating over all checkpoints
List<CompletedCheckpoint> completedCheckpoints = zooKeeperCompletedCheckpointStore.getAllCheckpoints();
Collection<Long> actualCheckpointIds = new HashSet<>(completedCheckpoints.size());
for (CompletedCheckpoint completedCheckpoint : completedCheckpoints) {
actualCheckpointIds.add(completedCheckpoint.getCheckpointID());
}
assertEquals(expectedCheckpointIds, actualCheckpointIds);
// check that we did not discard any of the state handles which were retrieved
verify(retrievableStateHandle1, never()).discardState();
verify(retrievableStateHandle2, never()).discardState();
// check that we have discarded the state handles which could not be retrieved
verify(failingRetrievableStateHandle, times(2)).discardState();
}
Aggregations