From aeaa4ba4629d1b48bbf13fd7512a9f1171631d70 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Tue, 18 Jan 2022 12:38:10 -0500
Subject: [PATCH v1] Split 010_pg_basebackup.pl.

---
 .../t/010_pg_basebackup_basic.pl              |  15 +
 ...ckup.pl => 011_pg_basebackup_integrity.pl} | 287 +---------------
 .../t/012_pg_basebackup_options.pl            | 318 ++++++++++++++++++
 3 files changed, 334 insertions(+), 286 deletions(-)
 create mode 100644 src/bin/pg_basebackup/t/010_pg_basebackup_basic.pl
 rename src/bin/pg_basebackup/t/{010_pg_basebackup.pl => 011_pg_basebackup_integrity.pl} (58%)
 create mode 100644 src/bin/pg_basebackup/t/012_pg_basebackup_options.pl

diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup_basic.pl b/src/bin/pg_basebackup/t/010_pg_basebackup_basic.pl
new file mode 100644
index 0000000000..48863dc213
--- /dev/null
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup_basic.pl
@@ -0,0 +1,15 @@
+
+# Copyright (c) 2021-2022, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+use PostgreSQL::Test::Cluster;
+use PostgreSQL::Test::Utils;
+use Test::More tests => 9;
+
+program_help_ok('pg_basebackup');
+program_version_ok('pg_basebackup');
+program_options_handling_ok('pg_basebackup');
+
+command_fails(['pg_basebackup'],
+			  'pg_basebackup needs target directory specified');
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/011_pg_basebackup_integrity.pl
similarity index 58%
rename from src/bin/pg_basebackup/t/010_pg_basebackup.pl
rename to src/bin/pg_basebackup/t/011_pg_basebackup_integrity.pl
index f0243f28d4..68332931ac 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/011_pg_basebackup_integrity.pl
@@ -10,11 +10,7 @@ use File::Path qw(rmtree);
 use Fcntl qw(:seek);
 use PostgreSQL::Test::Cluster;
 use PostgreSQL::Test::Utils;
-use Test::More tests => 115;
-
-program_help_ok('pg_basebackup');
-program_version_ok('pg_basebackup');
-program_options_handling_ok('pg_basebackup');
+use Test::More tests => 61;
 
 my $tempdir = PostgreSQL::Test::Utils::tempdir;
 
@@ -35,9 +31,6 @@ $node->init(extra => ['--data-checksums']);
 $node->start;
 my $pgdata = $node->data_dir;
 
-$node->command_fails(['pg_basebackup'],
-	'pg_basebackup needs target directory specified');
-
 # Some Windows ANSI code pages may reject this filename, in which case we
 # quietly proceed without this bit of test coverage.
 if (open my $badchars, '>>', "$tempdir/pgdata/FOO\xe0\xe0\xe0BAR")
@@ -400,281 +393,3 @@ foreach my $filename (@tempRelationFiles)
 ok( -d "$tempdir/backup1/pg_replslot",
 	'pg_replslot symlink copied as directory');
 rmtree("$tempdir/backup1");
-
-mkdir "$tempdir/tbl=spc2";
-$realTsDir = "$real_sys_tempdir/tbl=spc2";
-$node->safe_psql('postgres', "DROP TABLE test1;");
-$node->safe_psql('postgres', "DROP TABLE tblspc1_unlogged;");
-$node->safe_psql('postgres', "DROP TABLESPACE tblspc1;");
-$node->safe_psql('postgres',
-	"CREATE TABLESPACE tblspc2 LOCATION '$realTsDir';");
-$realTsDir =~ s/=/\\=/;
-$node->command_ok(
-	[
-		@pg_basebackup_defs, '-D',
-		"$tempdir/backup3",  '-Fp',
-		"-T$realTsDir=$real_tempdir/tbackup/tbl\\=spc2",
-	],
-	'mapping tablespace with = sign in path');
-ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
-$node->safe_psql('postgres', "DROP TABLESPACE tblspc2;");
-rmtree("$tempdir/backup3");
-
-mkdir "$tempdir/$superlongname";
-$realTsDir = "$real_sys_tempdir/$superlongname";
-$node->safe_psql('postgres',
-	"CREATE TABLESPACE tblspc3 LOCATION '$realTsDir';");
-$node->command_ok([ @pg_basebackup_defs, '-D', "$tempdir/tarbackup_l3", '-Ft' ],
-	'pg_basebackup tar with long symlink target');
-$node->safe_psql('postgres', "DROP TABLESPACE tblspc3;");
-rmtree("$tempdir/tarbackup_l3");
-
-$node->command_ok([ @pg_basebackup_defs, '-D', "$tempdir/backupR", '-R' ],
-	'pg_basebackup -R runs');
-ok(-f "$tempdir/backupR/postgresql.auto.conf", 'postgresql.auto.conf exists');
-ok(-f "$tempdir/backupR/standby.signal",       'standby.signal was created');
-my $recovery_conf = slurp_file "$tempdir/backupR/postgresql.auto.conf";
-rmtree("$tempdir/backupR");
-
-my $port = $node->port;
-like(
-	$recovery_conf,
-	qr/^primary_conninfo = '.*port=$port.*'\n/m,
-	'postgresql.auto.conf sets primary_conninfo');
-
-$node->command_ok(
-	[ @pg_basebackup_defs, '-D', "$tempdir/backupxd" ],
-	'pg_basebackup runs in default xlog mode');
-ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxd/pg_wal")),
-	'WAL files copied');
-rmtree("$tempdir/backupxd");
-
-$node->command_ok(
-	[ @pg_basebackup_defs, '-D', "$tempdir/backupxf", '-X', 'fetch' ],
-	'pg_basebackup -X fetch runs');
-ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxf/pg_wal")),
-	'WAL files copied');
-rmtree("$tempdir/backupxf");
-$node->command_ok(
-	[ @pg_basebackup_defs, '-D', "$tempdir/backupxs", '-X', 'stream' ],
-	'pg_basebackup -X stream runs');
-ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxs/pg_wal")),
-	'WAL files copied');
-rmtree("$tempdir/backupxs");
-$node->command_ok(
-	[ @pg_basebackup_defs, '-D', "$tempdir/backupxst", '-X', 'stream', '-Ft' ],
-	'pg_basebackup -X stream runs in tar mode');
-ok(-f "$tempdir/backupxst/pg_wal.tar", "tar file was created");
-rmtree("$tempdir/backupxst");
-$node->command_ok(
-	[
-		@pg_basebackup_defs,     '-D',
-		"$tempdir/backupnoslot", '-X',
-		'stream',                '--no-slot'
-	],
-	'pg_basebackup -X stream runs with --no-slot');
-rmtree("$tempdir/backupnoslot");
-
-$node->command_fails(
-	[
-		@pg_basebackup_defs,         '-D',
-		"$tempdir/backupxs_sl_fail", '-X',
-		'stream',                    '-S',
-		'slot0'
-	],
-	'pg_basebackup fails with nonexistent replication slot');
-
-$node->command_fails(
-	[ @pg_basebackup_defs, '-D', "$tempdir/backupxs_slot", '-C' ],
-	'pg_basebackup -C fails without slot name');
-
-$node->command_fails(
-	[
-		@pg_basebackup_defs,      '-D',
-		"$tempdir/backupxs_slot", '-C',
-		'-S',                     'slot0',
-		'--no-slot'
-	],
-	'pg_basebackup fails with -C -S --no-slot');
-
-$node->command_ok(
-	[ @pg_basebackup_defs, '-D', "$tempdir/backupxs_slot", '-C', '-S', 'slot0' ],
-	'pg_basebackup -C runs');
-rmtree("$tempdir/backupxs_slot");
-
-is( $node->safe_psql(
-		'postgres',
-		q{SELECT slot_name FROM pg_replication_slots WHERE slot_name = 'slot0'}
-	),
-	'slot0',
-	'replication slot was created');
-isnt(
-	$node->safe_psql(
-		'postgres',
-		q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot0'}
-	),
-	'',
-	'restart LSN of new slot is not null');
-
-$node->command_fails(
-	[ @pg_basebackup_defs, '-D', "$tempdir/backupxs_slot1", '-C', '-S', 'slot0' ],
-	'pg_basebackup fails with -C -S and a previously existing slot');
-
-$node->safe_psql('postgres',
-	q{SELECT * FROM pg_create_physical_replication_slot('slot1')});
-my $lsn = $node->safe_psql('postgres',
-	q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'}
-);
-is($lsn, '', 'restart LSN of new slot is null');
-$node->command_fails(
-	[ @pg_basebackup_defs, '-D', "$tempdir/fail", '-S', 'slot1', '-X', 'none' ],
-	'pg_basebackup with replication slot fails without WAL streaming');
-$node->command_ok(
-	[
-		@pg_basebackup_defs, '-D', "$tempdir/backupxs_sl", '-X',
-		'stream',            '-S', 'slot1'
-	],
-	'pg_basebackup -X stream with replication slot runs');
-$lsn = $node->safe_psql('postgres',
-	q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'}
-);
-like($lsn, qr!^0/[0-9A-Z]{7,8}$!, 'restart LSN of slot has advanced');
-rmtree("$tempdir/backupxs_sl");
-
-$node->command_ok(
-	[
-		@pg_basebackup_defs, '-D', "$tempdir/backupxs_sl_R", '-X',
-		'stream',            '-S', 'slot1',                  '-R',
-	],
-	'pg_basebackup with replication slot and -R runs');
-like(
-	slurp_file("$tempdir/backupxs_sl_R/postgresql.auto.conf"),
-	qr/^primary_slot_name = 'slot1'\n/m,
-	'recovery conf file sets primary_slot_name');
-
-my $checksum = $node->safe_psql('postgres', 'SHOW data_checksums;');
-is($checksum, 'on', 'checksums are enabled');
-rmtree("$tempdir/backupxs_sl_R");
-
-# create tables to corrupt and get their relfilenodes
-my $file_corrupt1 = $node->safe_psql('postgres',
-	q{CREATE TABLE corrupt1 AS SELECT a FROM generate_series(1,10000) AS a; ALTER TABLE corrupt1 SET (autovacuum_enabled=false); SELECT pg_relation_filepath('corrupt1')}
-);
-my $file_corrupt2 = $node->safe_psql('postgres',
-	q{CREATE TABLE corrupt2 AS SELECT b FROM generate_series(1,2) AS b; ALTER TABLE corrupt2 SET (autovacuum_enabled=false); SELECT pg_relation_filepath('corrupt2')}
-);
-
-# set page header and block sizes
-my $pageheader_size = 24;
-my $block_size = $node->safe_psql('postgres', 'SHOW block_size;');
-
-# induce corruption
-system_or_bail 'pg_ctl', '-D', $pgdata, 'stop';
-open $file, '+<', "$pgdata/$file_corrupt1";
-seek($file, $pageheader_size, SEEK_SET);
-syswrite($file, "\0\0\0\0\0\0\0\0\0");
-close $file;
-system_or_bail 'pg_ctl', '-D', $pgdata, 'start';
-
-$node->command_checks_all(
-	[ @pg_basebackup_defs, '-D', "$tempdir/backup_corrupt" ],
-	1,
-	[qr{^$}],
-	[qr/^WARNING.*checksum verification failed/s],
-	'pg_basebackup reports checksum mismatch');
-rmtree("$tempdir/backup_corrupt");
-
-# induce further corruption in 5 more blocks
-system_or_bail 'pg_ctl', '-D', $pgdata, 'stop';
-open $file, '+<', "$pgdata/$file_corrupt1";
-for my $i (1 .. 5)
-{
-	my $offset = $pageheader_size + $i * $block_size;
-	seek($file, $offset, SEEK_SET);
-	syswrite($file, "\0\0\0\0\0\0\0\0\0");
-}
-close $file;
-system_or_bail 'pg_ctl', '-D', $pgdata, 'start';
-
-$node->command_checks_all(
-	[ @pg_basebackup_defs, '-D', "$tempdir/backup_corrupt2" ],
-	1,
-	[qr{^$}],
-	[qr/^WARNING.*further.*failures.*will.not.be.reported/s],
-	'pg_basebackup does not report more than 5 checksum mismatches');
-rmtree("$tempdir/backup_corrupt2");
-
-# induce corruption in a second file
-system_or_bail 'pg_ctl', '-D', $pgdata, 'stop';
-open $file, '+<', "$pgdata/$file_corrupt2";
-seek($file, $pageheader_size, SEEK_SET);
-syswrite($file, "\0\0\0\0\0\0\0\0\0");
-close $file;
-system_or_bail 'pg_ctl', '-D', $pgdata, 'start';
-
-$node->command_checks_all(
-	[ @pg_basebackup_defs, '-D', "$tempdir/backup_corrupt3" ],
-	1,
-	[qr{^$}],
-	[qr/^WARNING.*7 total checksum verification failures/s],
-	'pg_basebackup correctly report the total number of checksum mismatches');
-rmtree("$tempdir/backup_corrupt3");
-
-# do not verify checksums, should return ok
-$node->command_ok(
-	[
-		@pg_basebackup_defs,        '-D',
-		"$tempdir/backup_corrupt4", '--no-verify-checksums',
-	],
-	'pg_basebackup with -k does not report checksum mismatch');
-rmtree("$tempdir/backup_corrupt4");
-
-$node->safe_psql('postgres', "DROP TABLE corrupt1;");
-$node->safe_psql('postgres', "DROP TABLE corrupt2;");
-
-note "Testing pg_basebackup with compression methods";
-
-# Check ZLIB compression if available.
-SKIP:
-{
-	skip "postgres was not built with ZLIB support", 5
-	  if (!check_pg_config("#define HAVE_LIBZ 1"));
-
-	$node->command_ok(
-		[
-			@pg_basebackup_defs,    '-D',
-			"$tempdir/backup_gzip", '--compress',
-			'1',                    '--format',
-			't'
-		],
-		'pg_basebackup with --compress');
-	$node->command_ok(
-		[
-			@pg_basebackup_defs,     '-D',
-			"$tempdir/backup_gzip2", '--gzip',
-			'--format',              't'
-		],
-		'pg_basebackup with --gzip');
-
-	# Verify that the stored files are generated with their expected
-	# names.
-	my @zlib_files = glob "$tempdir/backup_gzip/*.tar.gz";
-	is(scalar(@zlib_files), 2,
-		"two files created with --compress (base.tar.gz and pg_wal.tar.gz)");
-	my @zlib_files2 = glob "$tempdir/backup_gzip2/*.tar.gz";
-	is(scalar(@zlib_files2), 2,
-		"two files created with --gzip (base.tar.gz and pg_wal.tar.gz)");
-
-	# Check the integrity of the files generated.
-	my $gzip = $ENV{GZIP_PROGRAM};
-	skip "program gzip is not found in your system", 1
-	  if ( !defined $gzip
-		|| $gzip eq ''
-		|| system_log($gzip, '--version') != 0);
-
-	my $gzip_is_valid =
-	  system_log($gzip, '--test', @zlib_files, @zlib_files2);
-	is($gzip_is_valid, 0, "gzip verified the integrity of compressed data");
-	rmtree("$tempdir/backup_gzip");
-	rmtree("$tempdir/backup_gzip2");
-}
diff --git a/src/bin/pg_basebackup/t/012_pg_basebackup_options.pl b/src/bin/pg_basebackup/t/012_pg_basebackup_options.pl
new file mode 100644
index 0000000000..35c13f9e97
--- /dev/null
+++ b/src/bin/pg_basebackup/t/012_pg_basebackup_options.pl
@@ -0,0 +1,318 @@
+
+# Copyright (c) 2021-2022, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+use Cwd;
+use Config;
+use File::Basename qw(basename dirname);
+use File::Path qw(rmtree);
+use Fcntl qw(:seek);
+use PostgreSQL::Test::Cluster;
+use PostgreSQL::Test::Utils;
+use Test::More tests => 45;
+
+my $tempdir = PostgreSQL::Test::Utils::tempdir;
+my $real_tempdir = PostgreSQL::Test::Utils::perl2host($tempdir);
+
+my $node = PostgreSQL::Test::Cluster->new('main');
+
+# For nearly all pg_basebackup invocations some options should be specified,
+# to keep test times reasonable. Using @pg_basebackup_defs as the first
+# element of the array passed to to IPC::Run interpolate the array (as it is
+# not a reference to an array)...
+my @pg_basebackup_defs = ('pg_basebackup', '--no-sync', '-cfast');
+
+
+# Set umask so test directories and files are created with default permissions
+umask(0077);
+
+# Initialize node
+$node->init(allows_streaming => 1, extra => ['--data-checksums']);
+$node->start;
+my $pgdata = $node->data_dir;
+
+# Create a temporary directory in the system location and symlink it
+# to our physical temp location.  That way we can use shorter names
+# for the tablespace directories, which hopefully won't run afoul of
+# the 99 character length limit.
+my $sys_tempdir = PostgreSQL::Test::Utils::tempdir_short;
+my $real_sys_tempdir = PostgreSQL::Test::Utils::perl2host($sys_tempdir) . "/tempdir";
+my $shorter_tempdir =  $sys_tempdir . "/tempdir";
+dir_symlink "$tempdir", $shorter_tempdir;
+
+mkdir "$tempdir/tbl=spc2";
+my $realTsDir = "$real_sys_tempdir/tbl=spc2";
+$node->safe_psql('postgres',
+	"CREATE TABLESPACE tblspc2 LOCATION '$realTsDir';");
+$realTsDir =~ s/=/\\=/;
+$node->command_ok(
+	[
+		@pg_basebackup_defs, '-D',
+		"$tempdir/backup3",  '-Fp',
+		"-T$realTsDir=$real_tempdir/tbackup/tbl\\=spc2",
+	],
+	'mapping tablespace with = sign in path');
+ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
+$node->safe_psql('postgres', "DROP TABLESPACE tblspc2;");
+rmtree("$tempdir/backup3");
+
+my $superlongname = "superlongname_" . ("x" x 100);
+mkdir "$tempdir/$superlongname";
+$realTsDir = "$real_sys_tempdir/$superlongname";
+$node->safe_psql('postgres',
+	"CREATE TABLESPACE tblspc3 LOCATION '$realTsDir';");
+$node->command_ok([ @pg_basebackup_defs, '-D', "$tempdir/tarbackup_l3", '-Ft' ],
+	'pg_basebackup tar with long symlink target');
+$node->safe_psql('postgres', "DROP TABLESPACE tblspc3;");
+rmtree("$tempdir/tarbackup_l3");
+
+$node->command_ok([ @pg_basebackup_defs, '-D', "$tempdir/backupR", '-R' ],
+	'pg_basebackup -R runs');
+ok(-f "$tempdir/backupR/postgresql.auto.conf", 'postgresql.auto.conf exists');
+ok(-f "$tempdir/backupR/standby.signal",       'standby.signal was created');
+my $recovery_conf = slurp_file "$tempdir/backupR/postgresql.auto.conf";
+rmtree("$tempdir/backupR");
+
+my $port = $node->port;
+like(
+	$recovery_conf,
+	qr/^primary_conninfo = '.*port=$port.*'\n/m,
+	'postgresql.auto.conf sets primary_conninfo');
+
+$node->command_ok(
+	[ @pg_basebackup_defs, '-D', "$tempdir/backupxd" ],
+	'pg_basebackup runs in default xlog mode');
+ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxd/pg_wal")),
+	'WAL files copied');
+rmtree("$tempdir/backupxd");
+
+$node->command_ok(
+	[ @pg_basebackup_defs, '-D', "$tempdir/backupxf", '-X', 'fetch' ],
+	'pg_basebackup -X fetch runs');
+ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxf/pg_wal")),
+	'WAL files copied');
+rmtree("$tempdir/backupxf");
+$node->command_ok(
+	[ @pg_basebackup_defs, '-D', "$tempdir/backupxs", '-X', 'stream' ],
+	'pg_basebackup -X stream runs');
+ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxs/pg_wal")),
+	'WAL files copied');
+rmtree("$tempdir/backupxs");
+$node->command_ok(
+	[ @pg_basebackup_defs, '-D', "$tempdir/backupxst", '-X', 'stream', '-Ft' ],
+	'pg_basebackup -X stream runs in tar mode');
+ok(-f "$tempdir/backupxst/pg_wal.tar", "tar file was created");
+rmtree("$tempdir/backupxst");
+$node->command_ok(
+	[
+		@pg_basebackup_defs,     '-D',
+		"$tempdir/backupnoslot", '-X',
+		'stream',                '--no-slot'
+	],
+	'pg_basebackup -X stream runs with --no-slot');
+rmtree("$tempdir/backupnoslot");
+
+$node->command_fails(
+	[
+		@pg_basebackup_defs,         '-D',
+		"$tempdir/backupxs_sl_fail", '-X',
+		'stream',                    '-S',
+		'slot0'
+	],
+	'pg_basebackup fails with nonexistent replication slot');
+
+$node->command_fails(
+	[ @pg_basebackup_defs, '-D', "$tempdir/backupxs_slot", '-C' ],
+	'pg_basebackup -C fails without slot name');
+
+$node->command_fails(
+	[
+		@pg_basebackup_defs,      '-D',
+		"$tempdir/backupxs_slot", '-C',
+		'-S',                     'slot0',
+		'--no-slot'
+	],
+	'pg_basebackup fails with -C -S --no-slot');
+
+$node->command_ok(
+	[ @pg_basebackup_defs, '-D', "$tempdir/backupxs_slot", '-C', '-S', 'slot0' ],
+	'pg_basebackup -C runs');
+rmtree("$tempdir/backupxs_slot");
+
+is( $node->safe_psql(
+		'postgres',
+		q{SELECT slot_name FROM pg_replication_slots WHERE slot_name = 'slot0'}
+	),
+	'slot0',
+	'replication slot was created');
+isnt(
+	$node->safe_psql(
+		'postgres',
+		q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot0'}
+	),
+	'',
+	'restart LSN of new slot is not null');
+
+$node->command_fails(
+	[ @pg_basebackup_defs, '-D', "$tempdir/backupxs_slot1", '-C', '-S', 'slot0' ],
+	'pg_basebackup fails with -C -S and a previously existing slot');
+
+$node->safe_psql('postgres',
+	q{SELECT * FROM pg_create_physical_replication_slot('slot1')});
+my $lsn = $node->safe_psql('postgres',
+	q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'}
+);
+is($lsn, '', 'restart LSN of new slot is null');
+$node->command_fails(
+	[ @pg_basebackup_defs, '-D', "$tempdir/fail", '-S', 'slot1', '-X', 'none' ],
+	'pg_basebackup with replication slot fails without WAL streaming');
+$node->command_ok(
+	[
+		@pg_basebackup_defs, '-D', "$tempdir/backupxs_sl", '-X',
+		'stream',            '-S', 'slot1'
+	],
+	'pg_basebackup -X stream with replication slot runs');
+$lsn = $node->safe_psql('postgres',
+	q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'}
+);
+like($lsn, qr!^0/[0-9A-Z]{7,8}$!, 'restart LSN of slot has advanced');
+rmtree("$tempdir/backupxs_sl");
+
+$node->command_ok(
+	[
+		@pg_basebackup_defs, '-D', "$tempdir/backupxs_sl_R", '-X',
+		'stream',            '-S', 'slot1',                  '-R',
+	],
+	'pg_basebackup with replication slot and -R runs');
+like(
+	slurp_file("$tempdir/backupxs_sl_R/postgresql.auto.conf"),
+	qr/^primary_slot_name = 'slot1'\n/m,
+	'recovery conf file sets primary_slot_name');
+
+my $checksum = $node->safe_psql('postgres', 'SHOW data_checksums;');
+is($checksum, 'on', 'checksums are enabled');
+rmtree("$tempdir/backupxs_sl_R");
+
+# create tables to corrupt and get their relfilenodes
+my $file_corrupt1 = $node->safe_psql('postgres',
+	q{CREATE TABLE corrupt1 AS SELECT a FROM generate_series(1,10000) AS a; ALTER TABLE corrupt1 SET (autovacuum_enabled=false); SELECT pg_relation_filepath('corrupt1')}
+);
+my $file_corrupt2 = $node->safe_psql('postgres',
+	q{CREATE TABLE corrupt2 AS SELECT b FROM generate_series(1,2) AS b; ALTER TABLE corrupt2 SET (autovacuum_enabled=false); SELECT pg_relation_filepath('corrupt2')}
+);
+
+# set page header and block sizes
+my $pageheader_size = 24;
+my $block_size = $node->safe_psql('postgres', 'SHOW block_size;');
+
+# induce corruption
+system_or_bail 'pg_ctl', '-D', $pgdata, 'stop';
+open my $file, '+<', "$pgdata/$file_corrupt1";
+seek($file, $pageheader_size, SEEK_SET);
+syswrite($file, "\0\0\0\0\0\0\0\0\0");
+close $file;
+system_or_bail 'pg_ctl', '-D', $pgdata, 'start';
+
+$node->command_checks_all(
+	[ @pg_basebackup_defs, '-D', "$tempdir/backup_corrupt" ],
+	1,
+	[qr{^$}],
+	[qr/^WARNING.*checksum verification failed/s],
+	'pg_basebackup reports checksum mismatch');
+rmtree("$tempdir/backup_corrupt");
+
+# induce further corruption in 5 more blocks
+system_or_bail 'pg_ctl', '-D', $pgdata, 'stop';
+open $file, '+<', "$pgdata/$file_corrupt1";
+for my $i (1 .. 5)
+{
+	my $offset = $pageheader_size + $i * $block_size;
+	seek($file, $offset, SEEK_SET);
+	syswrite($file, "\0\0\0\0\0\0\0\0\0");
+}
+close $file;
+system_or_bail 'pg_ctl', '-D', $pgdata, 'start';
+
+$node->command_checks_all(
+	[ @pg_basebackup_defs, '-D', "$tempdir/backup_corrupt2" ],
+	1,
+	[qr{^$}],
+	[qr/^WARNING.*further.*failures.*will.not.be.reported/s],
+	'pg_basebackup does not report more than 5 checksum mismatches');
+rmtree("$tempdir/backup_corrupt2");
+
+# induce corruption in a second file
+system_or_bail 'pg_ctl', '-D', $pgdata, 'stop';
+open $file, '+<', "$pgdata/$file_corrupt2";
+seek($file, $pageheader_size, SEEK_SET);
+syswrite($file, "\0\0\0\0\0\0\0\0\0");
+close $file;
+system_or_bail 'pg_ctl', '-D', $pgdata, 'start';
+
+$node->command_checks_all(
+	[ @pg_basebackup_defs, '-D', "$tempdir/backup_corrupt3" ],
+	1,
+	[qr{^$}],
+	[qr/^WARNING.*7 total checksum verification failures/s],
+	'pg_basebackup correctly report the total number of checksum mismatches');
+rmtree("$tempdir/backup_corrupt3");
+
+# do not verify checksums, should return ok
+$node->command_ok(
+	[
+		@pg_basebackup_defs,        '-D',
+		"$tempdir/backup_corrupt4", '--no-verify-checksums',
+	],
+	'pg_basebackup with -k does not report checksum mismatch');
+rmtree("$tempdir/backup_corrupt4");
+
+$node->safe_psql('postgres', "DROP TABLE corrupt1;");
+$node->safe_psql('postgres', "DROP TABLE corrupt2;");
+
+note "Testing pg_basebackup with compression methods";
+
+# Check ZLIB compression if available.
+SKIP:
+{
+	skip "postgres was not built with ZLIB support", 5
+	  if (!check_pg_config("#define HAVE_LIBZ 1"));
+
+	$node->command_ok(
+		[
+			@pg_basebackup_defs,    '-D',
+			"$tempdir/backup_gzip", '--compress',
+			'1',                    '--format',
+			't'
+		],
+		'pg_basebackup with --compress');
+	$node->command_ok(
+		[
+			@pg_basebackup_defs,     '-D',
+			"$tempdir/backup_gzip2", '--gzip',
+			'--format',              't'
+		],
+		'pg_basebackup with --gzip');
+
+	# Verify that the stored files are generated with their expected
+	# names.
+	my @zlib_files = glob "$tempdir/backup_gzip/*.tar.gz";
+	is(scalar(@zlib_files), 2,
+		"two files created with --compress (base.tar.gz and pg_wal.tar.gz)");
+	my @zlib_files2 = glob "$tempdir/backup_gzip2/*.tar.gz";
+	is(scalar(@zlib_files2), 2,
+		"two files created with --gzip (base.tar.gz and pg_wal.tar.gz)");
+
+	# Check the integrity of the files generated.
+	my $gzip = $ENV{GZIP_PROGRAM};
+	skip "program gzip is not found in your system", 1
+	  if ( !defined $gzip
+		|| $gzip eq ''
+		|| system_log($gzip, '--version') != 0);
+
+	my $gzip_is_valid =
+	  system_log($gzip, '--test', @zlib_files, @zlib_files2);
+	is($gzip_is_valid, 0, "gzip verified the integrity of compressed data");
+	rmtree("$tempdir/backup_gzip");
+	rmtree("$tempdir/backup_gzip2");
+}
-- 
2.24.3 (Apple Git-128)

