summaryrefslogtreecommitdiff
path: root/src/bin/pg_verifybackup/t/008_untar.pl
blob: bc3d6b352ad503c1cc9f3d61def5f27f7d5be7fe (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
# Copyright (c) 2021-2025, PostgreSQL Global Development Group

# This test case aims to verify that server-side backups and server-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 FATAL => 'all';
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;

# Create file with some random data and an arbitrary size, useful to check
# the solidity of the compression and decompression logic.  The size of the
# file is chosen to be around 640kB.  This has proven to be large enough to
# detect some issues related to LZ4, and low enough to not impact the runtime
# of the test significantly.
my $junk_data = $primary->safe_psql(
	'postgres', qq(
		SELECT string_agg(encode(sha256(i::bytea), 'hex'), '')
		FROM generate_series(1, 10240) s(i);));
my $data_dir = $primary->data_dir;
my $junk_file = "$data_dir/junk";
open my $jf, '>', $junk_file
  or die "Could not create junk file: $!";
print $jf $junk_data;
close $jf;

# Create a tablespace directory.
my $source_ts_path = PostgreSQL::Test::Utils::tempdir_short();

# Create a tablespace with table in it.
$primary->safe_psql(
	'postgres', qq(
		CREATE TABLESPACE regress_ts1 LOCATION '$source_ts_path';
		SELECT oid FROM pg_tablespace WHERE spcname = 'regress_ts1';
		CREATE TABLE regress_tbl1(i int) TABLESPACE regress_ts1;
		INSERT INTO regress_tbl1 VALUES(generate_series(1,5));));
my $tsoid = $primary->safe_psql(
	'postgres', qq(
		SELECT oid FROM pg_tablespace WHERE spcname = 'regress_ts1'));

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

my @test_configuration = (
	{
		'compression_method' => 'none',
		'backup_flags' => [],
		'backup_archive' => [ 'base.tar', "$tsoid.tar" ],
		'enabled' => 1
	},
	{
		'compression_method' => 'gzip',
		'backup_flags' => [ '--compress', 'server-gzip' ],
		'backup_archive' => [ 'base.tar.gz', "$tsoid.tar.gz" ],
		'enabled' => check_pg_config("#define HAVE_LIBZ 1")
	},
	{
		'compression_method' => 'lz4',
		'backup_flags' => [ '--compress', 'server-lz4' ],
		'backup_archive' => [ 'base.tar.lz4', "$tsoid.tar.lz4" ],
		'enabled' => check_pg_config("#define USE_LZ4 1")
	},
	{
		'compression_method' => 'lz4',
		'backup_flags' => [ '--compress', 'server-lz4:5' ],
		'backup_archive' => [ 'base.tar.lz4', "$tsoid.tar.lz4" ],
		'enabled' => check_pg_config("#define USE_LZ4 1")
	},
	{
		'compression_method' => 'zstd',
		'backup_flags' => [ '--compress', 'server-zstd' ],
		'backup_archive' => [ 'base.tar.zst', "$tsoid.tar.zst" ],
		'enabled' => check_pg_config("#define USE_ZSTD 1")
	},
	{
		'compression_method' => 'zstd',
		'backup_flags' => [ '--compress', 'server-zstd:level=1,long' ],
		'backup_archive' => [ 'base.tar.zst', "$tsoid.tar.zst" ],
		'enabled' => check_pg_config("#define USE_ZSTD 1")
	});

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 server-side backup.
		$primary->command_ok(
			[
				'pg_basebackup', '--no-sync',
				'--checkpoint' => 'fast',
				'--target' => "server:$backup_path",
				'--wal-method' => 'fetch',
				@{ $tc->{'backup_flags'} },
			],
			"server 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");

		# Verify tar backup.
		$primary->command_ok(
			[
				'pg_verifybackup', '--no-parse-wal',
				'--exit-on-error', $backup_path,
			],
			"verify backup, compression $method");

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

done_testing();