@@ -149,6 +149,15 @@ async fn publication_changes_are_correctly_handled() {
149
149
150
150
let database = spawn_source_database ( ) . await ;
151
151
152
+ if let Some ( server_version) = database. server_version ( )
153
+ && server_version. get ( ) <= 150000
154
+ {
155
+ println ! (
156
+ "Skipping test for PostgreSQL version <= 15, CREATE PUBLICATION FOR TABLES IN SCHEMA is not supported"
157
+ ) ;
158
+ return ;
159
+ }
160
+
152
161
// Create two tables in the test schema and a publication for that schema.
153
162
let table_1 = test_table_name ( "table_1" ) ;
154
163
let table_1_id = database
@@ -192,15 +201,6 @@ async fn publication_changes_are_correctly_handled() {
192
201
table_1_done. notified ( ) . await ;
193
202
table_2_done. notified ( ) . await ;
194
203
195
- if let Some ( server_version) = database. server_version ( )
196
- && server_version. get ( ) <= 150000
197
- {
198
- println ! (
199
- "Skipping test for PostgreSQL version <= 15, CREATE PUBLICATION FOR TABLES IN SCHEMA is not supported"
200
- ) ;
201
- return ;
202
- }
203
-
204
204
// Insert one row in each table and wait for two insert events.
205
205
let inserts_notify = destination
206
206
. wait_for_events_count ( vec ! [ ( EventType :: Insert , 2 ) ] )
@@ -215,10 +215,7 @@ async fn publication_changes_are_correctly_handled() {
215
215
. unwrap ( ) ;
216
216
inserts_notify. notified ( ) . await ;
217
217
218
- // Shutdown pipeline before altering publication (by dropping one table)
219
- pipeline. shutdown_and_wait ( ) . await . unwrap ( ) ;
220
-
221
- // Drop table_2 so it's no longer part of the publication
218
+ // Drop table_2 so it's no longer part of the publication.
222
219
database
223
220
. client
224
221
. as_ref ( )
@@ -230,6 +227,10 @@ async fn publication_changes_are_correctly_handled() {
230
227
. await
231
228
. unwrap ( ) ;
232
229
230
+ // Shutdown pipeline after the table was dropped. We do this to show that the dropping of a table
231
+ // doesn't cause issues with the pipeline since the change is picked up on pipeline restart.
232
+ pipeline. shutdown_and_wait ( ) . await . unwrap ( ) ;
233
+
233
234
// Create table_3 which is going to be added to the publication.
234
235
let table_3 = test_table_name ( "table_3" ) ;
235
236
let table_3_id = database
@@ -258,7 +259,7 @@ async fn publication_changes_are_correctly_handled() {
258
259
// Insert one row in table_1 and wait for it. (We wait for 4 inserts since it keeps the previous
259
260
// ones).
260
261
let inserts_notify = destination
261
- . wait_for_events_count ( vec ! [ ( EventType :: Insert , 4 ) ] )
262
+ . wait_for_events_count_deduped ( vec ! [ ( EventType :: Insert , 4 ) ] )
262
263
. await ;
263
264
264
265
database
@@ -274,30 +275,32 @@ async fn publication_changes_are_correctly_handled() {
274
275
275
276
pipeline. shutdown_and_wait ( ) . await . unwrap ( ) ;
276
277
277
- // Assert that table_2 state is gone but destination data remains
278
+ // Assert that table_2 state is gone but destination data remains.
278
279
let states = store. get_table_replication_states ( ) . await ;
279
280
assert ! ( states. contains_key( & table_1_id) ) ;
280
281
assert ! ( !states. contains_key( & table_2_id) ) ;
281
282
assert ! ( states. contains_key( & table_3_id) ) ;
282
283
283
284
// The destination should have the 2 events of the first table, the 1 event of the removed table
284
285
// and the 1 event of the new table.
285
- let events = destination. get_events ( ) . await ;
286
+ // Use de-duplicated events for assertions to be robust to potential duplicates
287
+ // on restart where confirmed_flush_lsn may not have been stored.
288
+ let events = destination. get_events_deduped ( ) . await ;
286
289
let grouped = group_events_by_type_and_table_id ( & events) ;
287
290
let table_1_inserts = grouped
288
291
. get ( & ( EventType :: Insert , table_1_id) )
289
292
. cloned ( )
290
- . unwrap_or_default ( ) ;
293
+ . unwrap ( ) ;
291
294
assert_eq ! ( table_1_inserts. len( ) , 2 ) ;
292
295
let table_2_inserts = grouped
293
296
. get ( & ( EventType :: Insert , table_2_id) )
294
297
. cloned ( )
295
- . unwrap_or_default ( ) ;
298
+ . unwrap ( ) ;
296
299
assert_eq ! ( table_2_inserts. len( ) , 1 ) ;
297
300
let table_3_inserts = grouped
298
301
. get ( & ( EventType :: Insert , table_3_id) )
299
302
. cloned ( )
300
- . unwrap_or_default ( ) ;
303
+ . unwrap ( ) ;
301
304
assert_eq ! ( table_3_inserts. len( ) , 1 ) ;
302
305
}
303
306
@@ -307,6 +310,15 @@ async fn publication_for_all_tables_in_schema_ignores_new_tables_until_restart()
307
310
308
311
let database = spawn_source_database ( ) . await ;
309
312
313
+ if let Some ( server_version) = database. server_version ( )
314
+ && server_version. get ( ) <= 150000
315
+ {
316
+ println ! (
317
+ "Skipping test for PostgreSQL version <= 15, CREATE PUBLICATION FOR TABLES IN SCHEMA is not supported"
318
+ ) ;
319
+ return ;
320
+ }
321
+
310
322
// Create first table.
311
323
let table_1 = test_table_name ( "table_1" ) ;
312
324
let table_1_id = database
@@ -364,15 +376,6 @@ async fn publication_for_all_tables_in_schema_ignores_new_tables_until_restart()
364
376
assert ! ( table_schemas. contains_key( & table_1_id) ) ;
365
377
assert ! ( !table_schemas. contains_key( & table_2_id) ) ;
366
378
367
- if let Some ( server_version) = database. server_version ( )
368
- && server_version. get ( ) <= 150000
369
- {
370
- println ! (
371
- "Skipping test for PostgreSQL version <= 15, CREATE PUBLICATION FOR TABLES IN SCHEMA is not supported"
372
- ) ;
373
- return ;
374
- }
375
-
376
379
// We restart the pipeline and verify that the new table is now processed.
377
380
let mut pipeline = create_pipeline (
378
381
& database. config ,
0 commit comments