From 3fbdec10a50d7b358b20f59892458f6ae49e7c93 Mon Sep 17 00:00:00 2001
From: Shlok Kyal <shlok.kyal.oss@gmail.com>
Date: Thu, 7 Mar 2024 18:00:29 +0530
Subject: [PATCH v27 4/5] Add additional testcases

Add additional testcases to test on pg_createsubscriber
---
 src/bin/pg_basebackup/t/041_tests.pl | 285 +++++++++++++++++++++++++++
 1 file changed, 285 insertions(+)
 create mode 100644 src/bin/pg_basebackup/t/041_tests.pl

diff --git a/src/bin/pg_basebackup/t/041_tests.pl b/src/bin/pg_basebackup/t/041_tests.pl
new file mode 100644
index 0000000000..2889d60d54
--- /dev/null
+++ b/src/bin/pg_basebackup/t/041_tests.pl
@@ -0,0 +1,285 @@
+# Copyright (c) 2024, PostgreSQL Global Development Group
+
+#
+# Test using a standby server as the subscriber.
+
+use strict;
+use warnings FATAL => 'all';
+use PostgreSQL::Test::Cluster;
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+my $datadir = PostgreSQL::Test::Utils::tempdir;
+
+# Set up node P as primary
+my $node_p = PostgreSQL::Test::Cluster->new('node_p');
+$node_p->init(allows_streaming => 'logical');
+$node_p->start;
+
+# On node P
+# - create databases
+# - create test tables
+# - insert a row
+# - create a physical replication slot
+$node_p->safe_psql(
+	'postgres', q(
+	CREATE DATABASE pg1;
+	CREATE DATABASE pg2;
+));
+$node_p->safe_psql('pg1', 'CREATE TABLE tbl1 (a text)');
+$node_p->safe_psql('pg1', "INSERT INTO tbl1 VALUES('first row')");
+$node_p->safe_psql('pg2', 'CREATE TABLE tbl2 (a text)');
+my $slotname = 'physical_slot';
+$node_p->safe_psql('pg2',
+	"SELECT pg_create_physical_replication_slot('$slotname')");
+
+# Set up node S as standby linking to node P
+$node_p->backup('backup_1');
+my $node_s = PostgreSQL::Test::Cluster->new('node_s');
+$node_s->init_from_backup($node_p, 'backup_1', has_streaming => 1);
+$node_s->append_conf(
+	'postgresql.conf', qq[
+primary_slot_name = '$slotname'
+]);
+$node_s->set_standby_mode();
+$node_s->start;
+
+# Set different parameters in postgresql.conf
+
+# set max_replication_slots
+$node_p->append_conf('postgresql.conf', 'max_replication_slots = 3');
+$node_p->restart;
+command_fails(
+	[
+		'pg_createsubscriber', '--verbose',
+		'--dry-run', '--pgdata',
+		$node_s->data_dir, '--publisher-server',
+		$node_p->connstr('pg1'), '--socket-directory',
+		$node_s->host, '--subscriber-port',
+		$node_s->port, '--database',
+		'pg1', '--database',
+		'pg2',
+	],
+	'max_replication_slots are less in number in publisher');
+
+$node_p->append_conf('postgresql.conf', 'max_replication_slots = 4');
+$node_p->restart;
+command_ok(
+	[
+		'pg_createsubscriber', '--verbose',
+		'--dry-run', '--pgdata',
+		$node_s->data_dir, '--publisher-server',
+		$node_p->connstr('pg1'), '--socket-directory',
+		$node_s->host, '--subscriber-port',
+		$node_s->port, '--database',
+		'pg1', '--database',
+		'pg2',
+	],
+	'max_replication_slots are accurate on publisher');
+
+$node_s->append_conf('postgresql.conf', 'max_replication_slots = 1');
+$node_s->restart;
+command_fails(
+	[
+		'pg_createsubscriber', '--verbose',
+		'--dry-run', '--pgdata',
+		$node_s->data_dir, '--publisher-server',
+		$node_p->connstr('pg1'), '--socket-directory',
+		$node_s->host, '--subscriber-port',
+		$node_s->port, '--database',
+		'pg1', '--database',
+		'pg2',
+	],
+	'max_replication_slots are less in number in subscriber');
+
+$node_s->append_conf('postgresql.conf', 'max_replication_slots = 2');
+$node_s->restart;
+command_ok(
+	[
+		'pg_createsubscriber', '--verbose',
+		'--dry-run', '--pgdata',
+		$node_s->data_dir, '--publisher-server',
+		$node_p->connstr('pg1'), '--socket-directory',
+		$node_s->host, '--subscriber-port',
+		$node_s->port, '--database',
+		'pg1', '--database',
+		'pg2',
+	],
+	'max_replication_slots are less in number in subscriber');
+
+# set wal_level on publisher
+$node_p->append_conf('postgresql.conf', 'wal_level = \'replica\'');
+$node_p->restart;
+command_fails(
+	[
+		'pg_createsubscriber', '--verbose',
+		'--dry-run', '--pgdata',
+		$node_s->data_dir, '--publisher-server',
+		$node_p->connstr('pg1'), '--socket-directory',
+		$node_s->host, '--subscriber-port',
+		$node_s->port, '--database',
+		'pg1', '--database',
+		'pg2',
+	],
+	'wal_level must be logical');
+
+$node_p->append_conf('postgresql.conf', 'wal_level = \'logical\'');
+$node_p->restart;
+command_ok(
+	[
+		'pg_createsubscriber', '--verbose',
+		'--dry-run', '--pgdata',
+		$node_s->data_dir, '--publisher-server',
+		$node_p->connstr('pg1'), '--socket-directory',
+		$node_s->host, '--subscriber-port',
+		$node_s->port, '--database',
+		'pg1', '--database',
+		'pg2',
+	],
+	'wal_level is logical');
+
+# set max_wal_senders on publisher
+$node_p->append_conf('postgresql.conf', 'max_wal_senders = 2');
+$node_p->restart;
+command_fails(
+	[
+		'pg_createsubscriber', '--verbose',
+		'--dry-run', '--pgdata',
+		$node_s->data_dir, '--publisher-server',
+		$node_p->connstr('pg1'), '--socket-directory',
+		$node_s->host, '--subscriber-port',
+		$node_s->port, '--database',
+		'pg1', '--database',
+		'pg2',
+	],
+	'max_wal_senders is not sufficient');
+
+$node_p->append_conf('postgresql.conf', 'max_wal_senders = 3');
+$node_p->restart;
+command_ok(
+	[
+		'pg_createsubscriber', '--verbose',
+		'--dry-run', '--pgdata',
+		$node_s->data_dir, '--publisher-server',
+		$node_p->connstr('pg1'), '--socket-directory',
+		$node_s->host, '--subscriber-port',
+		$node_s->port, '--database',
+		'pg1', '--database',
+		'pg2',
+	],
+	'max_wal_senders is sufficient');
+
+# set max_logical_replication_workers on subscriber
+$node_s->append_conf('postgresql.conf',
+	'max_logical_replication_workers = 1');
+$node_s->restart;
+command_fails(
+	[
+		'pg_createsubscriber', '--verbose',
+		'--dry-run', '--pgdata',
+		$node_s->data_dir, '--publisher-server',
+		$node_p->connstr('pg1'), '--socket-directory',
+		$node_s->host, '--subscriber-port',
+		$node_s->port, '--database',
+		'pg1', '--database',
+		'pg2',
+	],
+	'max_logical_replication_workers is not sufficient');
+
+$node_s->append_conf('postgresql.conf',
+	'max_logical_replication_workers = 2');
+$node_s->restart;
+command_ok(
+	[
+		'pg_createsubscriber', '--verbose',
+		'--dry-run', '--pgdata',
+		$node_s->data_dir, '--publisher-server',
+		$node_p->connstr('pg1'), '--socket-directory',
+		$node_s->host, '--subscriber-port',
+		$node_s->port, '--database',
+		'pg1', '--database',
+		'pg2',
+	],
+	'max_logical_replication_workers is sufficient');
+
+# max_worker_processes on subscriber
+$node_p->append_conf('postgresql.conf', 'max_worker_processes = 2');
+$node_p->restart;
+sleep 1;
+$node_s->append_conf('postgresql.conf', 'max_worker_processes = 2');
+$node_s->restart;
+command_fails(
+	[
+		'pg_createsubscriber', '--verbose',
+		'--dry-run', '--pgdata',
+		$node_s->data_dir, '--publisher-server',
+		$node_p->connstr('pg1'), '--socket-directory',
+		$node_s->host, '--subscriber-port',
+		$node_s->port, '--database',
+		'pg1', '--database',
+		'pg2',
+	],
+	'max_worker_processes is not sufficient');
+
+$node_p->append_conf('postgresql.conf', 'max_worker_processes = 3');
+$node_p->restart;
+sleep 1;
+$node_s->append_conf('postgresql.conf', 'max_worker_processes = 3');
+$node_s->restart;
+command_ok(
+	[
+		'pg_createsubscriber', '--verbose',
+		'--dry-run', '--pgdata',
+		$node_s->data_dir, '--publisher-server',
+		$node_p->connstr('pg1'), '--socket-directory',
+		$node_s->host, '--subscriber-port',
+		$node_s->port, '--database',
+		'pg1', '--database',
+		'pg2',
+	],
+	'max_worker_processes is sufficient');
+
+# Set up node C as standby linking to node S
+$node_s->backup('backup_2');
+my $node_c = PostgreSQL::Test::Cluster->new('node_c');
+$node_c->init_from_backup($node_s, 'backup_2', has_streaming => 1);
+$node_c->set_standby_mode();
+$node_c->start;
+
+# Cascade Streaming Replication
+
+# Run pg_createsubscriber on node S (P -> S -> C)
+command_fails(
+	[
+		'pg_createsubscriber', '--verbose',
+		'--dry-run', '--pgdata',
+		$node_s->data_dir, '--publisher-server',
+		$node_p->connstr('pg1'), '--socket-directory',
+		$node_s->host, '--subscriber-port',
+		$node_s->port, '--database',
+		'pg1', '--database',
+		'pg2'
+	],
+	'standby server is primary to other node');
+
+# Run pg_createsubscriber on node C (P -> S -> C)
+# Specify P as the publisher and C as standby
+command_fails(
+	[
+		'pg_createsubscriber', '--verbose',
+		'--dry-run', '--pgdata',
+		$node_c->data_dir, '--publisher-server',
+		$node_p->connstr('pg1'), '--socket-directory',
+		$node_c->host, '--subscriber-port',
+		$node_c->port, '--database',
+		'pg1', '--database',
+		'pg2'
+	],
+	'standby server is not direct standby of publisher');
+
+# clean up
+$node_p->teardown_node;
+$node_s->teardown_node;
+$node_c->teardown_node;
+
+done_testing();
-- 
2.41.0.windows.3

