ExecutorHealthChecker { @VisibleForTesting void finalizeFlows(List<ExecutableFlow> flows, String finalizeReason) { for (ExecutableFlow flow: flows) { logger.warn( String.format("Finalizing execution %s, %s", flow.getExecutionId(), finalizeReason)); try { ExecutionControllerUtils .finalizeFlow(this.executorLoader, this.alerterHolder, flow, finalizeReason, null); } catch (RuntimeException e) { logger.error("Unchecked exception while finalizing execution: " + flow.getExecutionId(), e); } } } @Inject  ExecutorHealthChecker(final Props azkProps, final ExecutorLoader executorLoader,
      final ExecutorApiGateway apiGateway, final AlerterHolder alerterHolder); void start(); void shutdown(); void checkExecutorHealthQuietly();  }
@Test public void testFailureDuringFinalization() throws Exception { this.activeFlows.put(EXECUTION_ID_11, new Pair<>( new ExecutionReference(EXECUTION_ID_11, this.executor1), this.flow1)); this.activeFlows.put(EXECUTION_ID_12, new Pair<>( new ExecutionReference(EXECUTION_ID_12, this.executor1), this.flow2)); when(this.loader.fetchExecutableFlow(EXECUTION_ID_11)).thenThrow(new RuntimeException( "test runtime exception")); when(this.loader.fetchExecutableFlow(EXECUTION_ID_12)).thenThrow(new RuntimeException( "test runtime exception")); this.executorHealthChecker.finalizeFlows(ImmutableList.of(this.flow1, flow2), "test finalize reason"); verify(this.loader).fetchExecutableFlow(flow1.getExecutionId()); verify(this.loader).fetchExecutableFlow(flow2.getExecutionId()); }