From 3a5018870916f0be07797127c628e152b3c920bd Mon Sep 17 00:00:00 2001 From: Hayato Kuroda Date: Wed, 17 Sep 2025 15:20:45 +0900 Subject: [PATCH v7 2/3] add test --- contrib/test_decoding/meson.build | 1 + contrib/test_decoding/t/002_repl_origin.pl | 73 ++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 contrib/test_decoding/t/002_repl_origin.pl diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build index 25f6b8a9082..e00e03ba08d 100644 --- a/contrib/test_decoding/meson.build +++ b/contrib/test_decoding/meson.build @@ -74,6 +74,7 @@ tests += { 'tap': { 'tests': [ 't/001_repl_stats.pl', + 't/002_repl_origin.pl', ], }, } diff --git a/contrib/test_decoding/t/002_repl_origin.pl b/contrib/test_decoding/t/002_repl_origin.pl new file mode 100644 index 00000000000..e1aa57b0995 --- /dev/null +++ b/contrib/test_decoding/t/002_repl_origin.pl @@ -0,0 +1,73 @@ +# Copyright (c) 2025, PostgreSQL Global Development Group + +# Test session replication origin setup, especially by the multiple sessions +use strict; +use warnings FATAL => 'all'; +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +# Test set-up +my $node = PostgreSQL::Test::Cluster->new('test'); +$node->init(allows_streaming => 'logical'); +$node->append_conf('postgresql.conf', 'autovacuum = off'); +$node->start; + +# Create a replication origin +$node->safe_psql('postgres', + "SELECT pg_replication_origin_create('origin');"); + +# Bump the query timeout to avoid false negatives on slow test systems. +my $psql_timeout_secs = 4 * $PostgreSQL::Test::Utils::timeout_default; + +# Start a background session +my $session1 = $node->background_psql( + 'postgres', + on_error_stop => 0, + timeout => $psql_timeout_secs); + +# Setup the replication origin to the session +my $pid = $session1->query_safe( + qq(SELECT pg_replication_origin_session_setup('origin'); + SELECT pg_backend_pid();)); + +is( $session1->query_safe( + qq(SELECT pg_replication_origin_session_is_setup();)), + 't', + "A replication origin is assigned to the session"); + +# Start another session +my $session2 = $node->background_psql( + 'postgres', + on_error_stop => 0, + timeout => $psql_timeout_secs); + +# Attach to the same replication origin +$session2->query_safe( + qq(SELECT pg_replication_origin_session_setup('origin', $pid);)); + +is( $session2->query_safe( + qq(SELECT pg_replication_origin_session_is_setup();)), + 't', + "Replication origin can accept multiple assignment"); + +# Emit a transactional message to update the local_lsn and store the current +# value. +$session1->query_safe( + qq(SELECT pg_logical_emit_message(true, 'prefix', 'message on session1');) +); +my $old_lsn = $session1->query_safe( + qq(SELECT local_lsn FROM pg_replication_origin_status;)); + +# Emit a transactional message from another session +$session2->query_safe( + qq(SELECT pg_logical_emit_message(true, 'prefix', 'message on session2');) +); + +# Confirm local_lsn can be updated by concurrent processes +my $new_lsn = $session1->query_safe( + qq(SELECT local_lsn FROM pg_replication_origin_status;)); +is($session1->query_safe(qq(SELECT '$old_lsn' < '$new_lsn')), + 't', "Replication origin can be advanced by both sessions"); + +done_testing(); -- 2.47.3