1919
2020import org .apache .flink .api .common .JobExecutionResult ;
2121import org .apache .flink .api .common .JobID ;
22+ import org .apache .flink .api .common .JobStatus ;
2223import org .apache .flink .api .common .JobSubmissionResult ;
2324import org .apache .flink .api .common .accumulators .IntCounter ;
2425import org .apache .flink .api .common .accumulators .LongCounter ;
5758import org .apache .flink .runtime .state .FunctionSnapshotContext ;
5859import org .apache .flink .runtime .testutils .CommonTestUtils ;
5960import org .apache .flink .runtime .testutils .MiniClusterResourceConfiguration ;
60- import org .apache .flink .runtime .throwable .ThrowableAnnotation ;
61- import org .apache .flink .runtime .throwable .ThrowableType ;
6261import org .apache .flink .streaming .api .checkpoint .CheckpointedFunction ;
6362import org .apache .flink .streaming .api .environment .StreamExecutionEnvironment ;
6463import org .apache .flink .streaming .api .functions .co .RichCoFlatMapFunction ;
6564import org .apache .flink .streaming .api .functions .sink .legacy .RichSinkFunction ;
6665import org .apache .flink .streaming .api .graph .StreamGraph ;
66+ import org .apache .flink .streaming .util .RestartStrategyUtils ;
6767import org .apache .flink .test .util .MiniClusterWithClientResource ;
6868import org .apache .flink .testutils .junit .FailsWithAdaptiveScheduler ;
6969import org .apache .flink .util .Collector ;
7373
7474import org .apache .flink .shaded .guava33 .com .google .common .collect .Iterables ;
7575
76+ import org .assertj .core .api .Fail ;
7677import org .junit .AfterClass ;
7778import org .junit .BeforeClass ;
7879import org .junit .Rule ;
103104
104105import static org .apache .flink .shaded .guava33 .com .google .common .collect .Iterables .getOnlyElement ;
105106import static org .apache .flink .util .Preconditions .checkState ;
107+ import static org .assertj .core .api .Assertions .assertThat ;
106108
107109/**
108110 * Base class for tests related to unaligned checkpoints.
@@ -150,7 +152,7 @@ public static void afterAll() {
150152 }
151153
152154 @ Nullable
153- protected File execute (UnalignedSettings settings ) throws Exception {
155+ protected String execute (UnalignedSettings settings ) throws Exception {
154156 final File checkpointDir = temp .newFolder ();
155157 Configuration conf = settings .getConfiguration (checkpointDir );
156158
@@ -179,32 +181,42 @@ protected File execute(UnalignedSettings settings) throws Exception {
179181 final StreamExecutionEnvironment env =
180182 StreamExecutionEnvironment .getExecutionEnvironment (conf );
181183 settings .configure (env );
184+ JobID jobID = null ;
182185 try {
183186 // print the test parameters to help debugging when the case is stuck
184187 System .out .println (
185188 "Starting " + getClass ().getCanonicalName () + "#" + name .getMethodName () + "." );
186189 final CompletableFuture <JobSubmissionResult > result =
187190 miniCluster .getMiniCluster ().submitJob (streamGraph .getJobGraph ());
188191
189- final JobID jobID = result .get ().getJobID ();
192+ jobID = result .get ().getJobID ();
190193 checkCounters (
191194 miniCluster
192195 .getMiniCluster ()
193196 .requestJobResult (jobID )
194197 .get ()
195198 .toJobExecutionResult (getClass ().getClassLoader ()));
199+ if (settings .expectedFinalJobStatus != null ) {
200+ assertThat (miniCluster .getMiniCluster ().getJobStatus (jobID ))
201+ .succeedsWithin (Duration .ofMinutes (1 ))
202+ .isEqualTo (settings .expectedFinalJobStatus );
203+ }
196204 System .out .println (
197205 "Finished " + getClass ().getCanonicalName () + "#" + name .getMethodName () + "." );
198206 if (settings .generateCheckpoint ) {
199207 return CommonTestUtils .getLatestCompletedCheckpointPath (
200208 jobID , miniCluster .getMiniCluster ())
201- .map (File ::new )
202- .orElseThrow (() -> new AssertionError ("Could not generate checkpoint" ));
209+ .orElseGet (() -> Fail .fail ("Could not generate checkpoint" ));
203210 }
204211 } catch (Exception e ) {
205212 if (ExceptionUtils .findThrowable (e , TestException .class ).isEmpty ()) {
206213 throw e ;
207214 }
215+ if (settings .generateCheckpoint ) {
216+ return CommonTestUtils .getLatestCompletedCheckpointPath (
217+ jobID , miniCluster .getMiniCluster ())
218+ .orElseGet (() -> Fail .fail ("Could not generate checkpoint" ));
219+ }
208220 } finally {
209221 miniCluster .after ();
210222 }
@@ -680,7 +692,7 @@ public String toString() {
680692 protected static class UnalignedSettings {
681693 private int parallelism ;
682694 private final int minCheckpoints = 10 ;
683- @ Nullable private File restoreCheckpoint ;
695+ @ Nullable private String restoreCheckpoint ;
684696 private boolean generateCheckpoint = false ;
685697 int expectedFailures = 0 ;
686698 int tolerableCheckpointFailures = 0 ;
@@ -691,6 +703,7 @@ protected static class UnalignedSettings {
691703 private int failuresAfterSourceFinishes = 0 ;
692704 private ChannelType channelType = ChannelType .MIXED ;
693705 private long sourceSleepMs = 0 ;
706+ @ Nullable private JobStatus expectedFinalJobStatus = null ;
694707
695708 public UnalignedSettings (DagCreator dagCreator ) {
696709 this .dagCreator = dagCreator ;
@@ -701,7 +714,7 @@ public UnalignedSettings setParallelism(int parallelism) {
701714 return this ;
702715 }
703716
704- public UnalignedSettings setRestoreCheckpoint (File restoreCheckpoint ) {
717+ public UnalignedSettings setRestoreCheckpoint (String restoreCheckpoint ) {
705718 this .restoreCheckpoint = restoreCheckpoint ;
706719 return this ;
707720 }
@@ -746,6 +759,11 @@ public UnalignedSettings setSourceSleepMs(long sourceSleepMs) {
746759 return this ;
747760 }
748761
762+ public UnalignedSettings setExpectedFinalJobStatus (JobStatus expectedFinalJobStatus ) {
763+ this .expectedFinalJobStatus = expectedFinalJobStatus ;
764+ return this ;
765+ }
766+
749767 public void configure (StreamExecutionEnvironment env ) {
750768 env .enableCheckpointing (Math .max (100L , parallelism * 50L ));
751769 env .getCheckpointConfig ()
@@ -754,6 +772,8 @@ public void configure(StreamExecutionEnvironment env) {
754772 env .getCheckpointConfig ()
755773 .setTolerableCheckpointFailureNumber (tolerableCheckpointFailures );
756774 env .setParallelism (parallelism );
775+ RestartStrategyUtils .configureFixedDelayRestartStrategy (
776+ env , generateCheckpoint ? expectedFailures / 2 : expectedFailures , 100L );
757777 env .getCheckpointConfig ().enableUnalignedCheckpoints (true );
758778 // for custom partitioner
759779 env .getCheckpointConfig ().setForceUnalignedCheckpoints (true );
@@ -772,7 +792,7 @@ public Configuration getConfiguration(File checkpointDir) {
772792 conf .set (StateBackendOptions .STATE_BACKEND , "hashmap" );
773793 conf .set (CheckpointingOptions .CHECKPOINTS_DIRECTORY , checkpointDir .toURI ().toString ());
774794 if (restoreCheckpoint != null ) {
775- conf .set (StateRecoveryOptions .SAVEPOINT_PATH , restoreCheckpoint . toURI (). toString () );
795+ conf .set (StateRecoveryOptions .SAVEPOINT_PATH , restoreCheckpoint );
776796 }
777797
778798 conf .set (
@@ -1132,7 +1152,6 @@ protected static long checkHeader(long value) {
11321152 return value ;
11331153 }
11341154
1135- @ ThrowableAnnotation (ThrowableType .NonRecoverableError )
11361155 static class TestException extends Exception {
11371156 public TestException (String s ) {
11381157 super (s );
0 commit comments