1717
1818package org .apache .flink .cdc .pipeline .tests ;
1919
20+ import org .apache .flink .api .common .JobID ;
21+ import org .apache .flink .api .common .time .Deadline ;
2022import org .apache .flink .cdc .common .test .utils .TestUtils ;
2123import org .apache .flink .cdc .pipeline .tests .utils .PipelineTestEnvironment ;
24+ import org .apache .flink .core .execution .CheckpointType ;
2225
2326import org .assertj .core .api .Assertions ;
2427import org .junit .jupiter .api .AfterEach ;
2528import org .junit .jupiter .api .BeforeEach ;
2629import org .junit .jupiter .api .Test ;
2730import org .slf4j .Logger ;
2831import org .slf4j .LoggerFactory ;
32+ import org .testcontainers .containers .Container .ExecResult ;
2933import org .testcontainers .containers .MSSQLServerContainer ;
3034import org .testcontainers .containers .output .Slf4jLogConsumer ;
3135import org .testcontainers .junit .jupiter .Container ;
4246import java .time .Duration ;
4347import java .util .Arrays ;
4448import java .util .List ;
49+ import java .util .concurrent .TimeUnit ;
50+ import java .util .concurrent .TimeoutException ;
4551import java .util .regex .Matcher ;
4652import java .util .regex .Pattern ;
4753import java .util .stream .Collectors ;
@@ -108,8 +114,8 @@ void testSyncWholeDatabase() throws Exception {
108114 SQL_SERVER_CONTAINER .getPassword (),
109115 parallelism );
110116 Path sqlServerCdcJar = TestUtils .getResource ("sqlserver-cdc-pipeline-connector.jar" );
111- submitPipelineJob (pipelineJob , sqlServerCdcJar );
112- waitUntilJobRunning ( Duration .ofSeconds (30 ));
117+ JobID jobId = submitPipelineJob (pipelineJob , sqlServerCdcJar );
118+ waitUntilJobRunningFromClusterCli ( jobId , Duration .ofSeconds (30 ));
113119 LOG .info ("Pipeline job is running" );
114120
115121 validateResult (
@@ -126,11 +132,24 @@ void testSyncWholeDatabase() throws Exception {
126132
127133 LOG .info ("Begin incremental reading stage." );
128134
135+ waitUntilStreamSplitReady (jobId , parallelism );
136+
129137 try (Connection conn = getSqlServerJdbcConnection ();
130138 Statement stat = conn .createStatement ()) {
131139 stat .execute ("USE inventory;" );
132140 stat .execute (
133141 "INSERT INTO dbo.products(id,name,description,weight) VALUES (110,'jacket','water resistent white wind breaker',0.2);" );
142+ } catch (SQLException e ) {
143+ LOG .error ("Insert row for CDC failed." , e );
144+ throw e ;
145+ }
146+
147+ waitUntilSpecificEvent (
148+ "DataChangeEvent{tableId=inventory.dbo.products, before=[], after=[110, jacket, water resistent white wind breaker, 0.2], op=INSERT, meta=()}" );
149+
150+ try (Connection conn = getSqlServerJdbcConnection ();
151+ Statement stat = conn .createStatement ()) {
152+ stat .execute ("USE inventory;" );
134153 stat .execute (
135154 "UPDATE dbo.products SET description='18oz carpenter hammer' WHERE id=106;" );
136155 stat .execute ("UPDATE dbo.products SET weight=5.1 WHERE id=107;" );
@@ -139,9 +158,6 @@ void testSyncWholeDatabase() throws Exception {
139158 LOG .error ("Update table for CDC failed." , e );
140159 throw e ;
141160 }
142-
143- waitUntilSpecificEvent (
144- "DataChangeEvent{tableId=inventory.dbo.products, before=[], after=[110, jacket, water resistent white wind breaker, 0.2], op=INSERT, meta=()}" );
145161 waitUntilSpecificEvent (
146162 "DataChangeEvent{tableId=inventory.dbo.products, before=[106, hammer, 16oz carpenter's hammer, 1.0], after=[106, hammer, 18oz carpenter hammer, 1.0], op=UPDATE, meta=()}" );
147163 waitUntilSpecificEvent (
@@ -184,4 +200,36 @@ private Connection getSqlServerJdbcConnection() throws SQLException {
184200 SQL_SERVER_CONTAINER .getUsername (),
185201 SQL_SERVER_CONTAINER .getPassword ());
186202 }
203+
204+ private void waitUntilStreamSplitReady (JobID jobId , int parallelism ) throws Exception {
205+ if (parallelism == 1 ) {
206+ return ;
207+ }
208+
209+ waitUntilSpecificEvent (
210+ jobManagerConsumer ,
211+ "Snapshot split assigner received all splits finished, waiting for a complete checkpoint to mark the assigner finished." );
212+ getRestClusterClient ().triggerCheckpoint (jobId , CheckpointType .CONFIGURED ).get ();
213+ waitUntilSpecificEvent (
214+ jobManagerConsumer , "Snapshot split assigner is turn into finished status." );
215+ waitUntilSpecificEvent (
216+ jobManagerConsumer , "Assign split StreamSplit{splitId='stream-split'" );
217+ waitUntilSpecificEvent (
218+ taskManagerConsumer ,
219+ "Adding split(s) to reader: [StreamSplit{splitId='stream-split'" );
220+ }
221+
222+ private void waitUntilJobRunningFromClusterCli (JobID jobId , Duration timeout ) throws Exception {
223+ Deadline deadline = Deadline .fromNow (timeout );
224+ String jobIdHex = jobId .toHexString ();
225+ while (deadline .hasTimeLeft ()) {
226+ ExecResult execResult = jobManager .execInContainer ("bash" , "-lc" , "flink list" );
227+ if (execResult .getExitCode () == 0 && execResult .getStdout ().contains (jobIdHex )) {
228+ return ;
229+ }
230+ TimeUnit .SECONDS .sleep (1 );
231+ }
232+ throw new TimeoutException (
233+ String .format ("Timed out waiting for job %s to appear in `flink list`." , jobIdHex ));
234+ }
187235}
0 commit comments