From 0c9235f77fa9c75b1957810aa88a2572ed4ac1dc Mon Sep 17 00:00:00 2001
From: Dilip Kumar <dilipkumar@localhost.localdomain>
Date: Sun, 23 May 2021 21:27:58 +0530
Subject: [PATCH v2] Test for new standby not following promoted standby

---
 src/test/recovery/t/025_timeline_issue.pl | 84 +++++++++++++++++++++++++++++++
 src/test/recovery/t/cp_history_files      |  8 +++
 2 files changed, 92 insertions(+)
 create mode 100644 src/test/recovery/t/025_timeline_issue.pl
 create mode 100755 src/test/recovery/t/cp_history_files

diff --git a/src/test/recovery/t/025_timeline_issue.pl b/src/test/recovery/t/025_timeline_issue.pl
new file mode 100644
index 0000000..9031354
--- /dev/null
+++ b/src/test/recovery/t/025_timeline_issue.pl
@@ -0,0 +1,84 @@
+
+# Copyright (c) 2021, PostgreSQL Global Development Group
+
+# Testing streaming replication where standby is promoted and a new cascade
+# standby (without WAL) is connected to the promoted standby.  Both archiving
+# and streaming are enabled but it should only get the history files from the
+# archive but not the WAL files so that it has to get the checkpoint record
+# from the promoted standby through streaming.  Test that the cascade standby
+# should be able to follow the new primary (promoted standby).
+use strict;
+use warnings;
+use PostgresNode;
+use TestLib;
+use FindBin;
+use Test::More tests => 1;
+
+# Initialize primary node
+my $node_primary = get_new_node('primary');
+
+# Set archive command using 'cp_history_files' (custom command).  The command
+# will only copy the history file and ignore all other WAL files.  This is
+# required to reproduce the scenario where history files reach the archive
+# but not the WAL files when standby try to restore it from the archive so that
+# it needs to stream the checkpoint record from the primary.
+$node_primary->init(allows_streaming => 1, has_archiving => 1);
+my $archivedir_primary = $node_primary->archive_dir;
+$node_primary->append_conf(
+	'postgresql.conf', qq(
+archive_command = '"$FindBin::RealBin/cp_history_files" "%p" "$archivedir_primary/%f"'
+));
+$node_primary->start;
+
+my $backup_name = 'my_backup';
+
+# Take backup from primary
+$node_primary->backup($backup_name);
+
+# Create streaming standby linking to primary
+my $node_standby = get_new_node('standby');
+$node_standby->init_from_backup($node_primary, $backup_name,
+	allows_streaming => 1, has_streaming => 1, has_archiving => 1);
+$node_standby->start;
+
+# Take backup of standby, use -Xnone so that pg_wal is empty.
+$node_standby->backup($backup_name, backup_options => ['-Xnone']);
+
+# Create cascading standby but don't start it yet.
+# Must set up both streaming and archiving.
+my $node_cascade = get_new_node('cascade');
+$node_cascade->init_from_backup($node_standby, $backup_name,
+	has_streaming => 1);
+
+# Setup restore command
+my $copy_command =
+  $TestLib::windows_os ? 'copy' : 'cp';
+
+$node_cascade->append_conf(
+	'postgresql.conf', qq(
+restore_command = '$copy_command "$archivedir_primary/%f" "%p"'
+));
+
+# Promote the standby.
+$node_standby->psql('postgres', 'SELECT pg_promote()');
+
+# Start cascade node
+$node_cascade->start;
+
+# Create some content on promoted standby and check its presence in cascade standby
+$node_standby->safe_psql('postgres', "CREATE TABLE tab_int AS SELECT 1 AS a");
+
+# Wait for standbys to catch up
+$node_standby->wait_for_catchup($node_cascade, 'replay',
+	$node_standby->lsn('replay'));
+
+# Check cascade standby is able to follow the new primary
+my $result =
+  $node_cascade->safe_psql('postgres', "SELECT count(*) FROM tab_int");
+print "cascade: $result\n";
+is($result, qq(1), 'check streamed content on cascade standby');
+
+# clean up
+$node_primary->teardown_node;
+$node_standby->teardown_node;
+$node_cascade->teardown_node;
diff --git a/src/test/recovery/t/cp_history_files b/src/test/recovery/t/cp_history_files
new file mode 100755
index 0000000..8dfe019
--- /dev/null
+++ b/src/test/recovery/t/cp_history_files
@@ -0,0 +1,8 @@
+#!/usr/bin/perl
+
+use File::Copy;
+
+die "wrong number of arguments" if @ARGV != 2;
+my ($source, $target) = @ARGV;
+return if $source !~ /history/;
+copy($source, $target) or die "couldn't copy $source to $target: $!";
-- 
1.8.3.1

