summaryrefslogtreecommitdiffstats
path: root/src/bin/pg_verifybackup/t/010_client_untar.pl
blob: 77cb503784c189996fff429d18054e9c36c1d677 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# Copyright (c) 2021-2022, PostgreSQL Global Development Group

# This test case aims to verify that client-side backup compression work
# properly, and it also aims to verify that pg_verifybackup can verify a base
# backup that didn't start out in plain format.

use strict;
use warnings;
use File::Path qw(rmtree);
use PostgreSQL::Test::Cluster;
use PostgreSQL::Test::Utils;
use Test::More;

my $primary = PostgreSQL::Test::Cluster->new('primary');
$primary->init(allows_streaming => 1);
$primary->start;

my $backup_path  = $primary->backup_dir . '/client-backup';
my $extract_path = $primary->backup_dir . '/extracted-backup';

my @test_configuration = (
	{
		'compression_method' => 'none',
		'backup_flags'       => [],
		'backup_archive'     => 'base.tar',
		'enabled'            => 1
	},
	{
		'compression_method' => 'gzip',
		'backup_flags'       => [ '--compress', 'client-gzip:5' ],
		'backup_archive'     => 'base.tar.gz',
		'decompress_program' => $ENV{'GZIP_PROGRAM'},
		'decompress_flags'   => ['-d'],
		'enabled'            => check_pg_config("#define HAVE_LIBZ 1")
	},
	{
		'compression_method' => 'lz4',
		'backup_flags'       => [ '--compress', 'client-lz4:5' ],
		'backup_archive'     => 'base.tar.lz4',
		'decompress_program' => $ENV{'LZ4'},
		'decompress_flags'   => ['-d'],
		'output_file'        => 'base.tar',
		'enabled'            => check_pg_config("#define USE_LZ4 1")
	},
	{
		'compression_method' => 'zstd',
		'backup_flags'       => [ '--compress', 'client-zstd:5' ],
		'backup_archive'     => 'base.tar.zst',
		'decompress_program' => $ENV{'ZSTD'},
		'decompress_flags'   => ['-d'],
		'enabled'            => check_pg_config("#define USE_ZSTD 1")
	},
	{
		'compression_method' => 'parallel zstd',
		'backup_flags'       => [ '--compress', 'client-zstd:workers=3' ],
		'backup_archive'     => 'base.tar.zst',
		'decompress_program' => $ENV{'ZSTD'},
		'decompress_flags'   => ['-d'],
		'enabled'            => check_pg_config("#define USE_ZSTD 1"),
		'possibly_unsupported' =>
		  qr/could not set compression worker count to 3: Unsupported parameter/
	});

for my $tc (@test_configuration)
{
	my $method = $tc->{'compression_method'};

  SKIP:
	{
		skip "$method compression not supported by this build", 3
		  if !$tc->{'enabled'};
		skip "no decompressor available for $method", 3
		  if exists $tc->{'decompress_program'}
		  && (!defined $tc->{'decompress_program'}
			|| $tc->{'decompress_program'} eq '');

		# Take a client-side backup.
		my @backup = (
			'pg_basebackup', '-D', $backup_path,
			'-Xfetch', '--no-sync', '-cfast', '-Ft');
		push @backup, @{ $tc->{'backup_flags'} };
		my $backup_stdout = '';
		my $backup_stderr = '';
		my $backup_result = $primary->run_log(\@backup, '>', \$backup_stdout,
			'2>', \$backup_stderr);
		if ($backup_stdout ne '')
		{
			print "# standard output was:\n$backup_stdout";
		}
		if ($backup_stderr ne '')
		{
			print "# standard error was:\n$backup_stderr";
		}
		if (  !$backup_result
			&& $tc->{'possibly_unsupported'}
			&& $backup_stderr =~ /$tc->{'possibly_unsupported'}/)
		{
			skip "compression with $method not supported by this build", 3;
		}
		else
		{
			ok($backup_result, "client side backup, compression $method");
		}

		# Verify that the we got the files we expected.
		my $backup_files = join(',',
			sort grep { $_ ne '.' && $_ ne '..' } slurp_dir($backup_path));
		my $expected_backup_files =
		  join(',', sort ('backup_manifest', $tc->{'backup_archive'}));
		is($backup_files, $expected_backup_files,
			"found expected backup files, compression $method");

		# Decompress.
		if (exists $tc->{'decompress_program'})
		{
			my @decompress = ($tc->{'decompress_program'});
			push @decompress, @{ $tc->{'decompress_flags'} }
			  if $tc->{'decompress_flags'};
			push @decompress, $backup_path . '/' . $tc->{'backup_archive'};
			push @decompress, $backup_path . '/' . $tc->{'output_file'}
			  if $tc->{'output_file'};
			system_or_bail(@decompress);
		}

	  SKIP:
		{
			my $tar = $ENV{TAR};
			# don't check for a working tar here, to accommodate various odd
			# cases such as AIX. If tar doesn't work the init_from_backup below
			# will fail.
			skip "no tar program available", 1
			  if (!defined $tar || $tar eq '');

			# Untar.
			mkdir($extract_path);
			system_or_bail($tar, 'xf', $backup_path . '/base.tar',
				'-C', $extract_path);

			# Verify.
			$primary->command_ok(
				[
					'pg_verifybackup', '-n',
					'-m', "$backup_path/backup_manifest",
					'-e', $extract_path
				],
				"verify backup, compression $method");
		}

		# Cleanup.
		rmtree($extract_path);
		rmtree($backup_path);
	}
}

done_testing();