diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:17:33 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:17:33 +0000 |
commit | 5e45211a64149b3c659b90ff2de6fa982a5a93ed (patch) | |
tree | 739caf8c461053357daa9f162bef34516c7bf452 /contrib/basebackup_to_shell/t | |
parent | Initial commit. (diff) | |
download | postgresql-15-5e45211a64149b3c659b90ff2de6fa982a5a93ed.tar.xz postgresql-15-5e45211a64149b3c659b90ff2de6fa982a5a93ed.zip |
Adding upstream version 15.5.upstream/15.5
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'contrib/basebackup_to_shell/t')
-rw-r--r-- | contrib/basebackup_to_shell/t/001_basic.pl | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/contrib/basebackup_to_shell/t/001_basic.pl b/contrib/basebackup_to_shell/t/001_basic.pl new file mode 100644 index 0000000..5eb9609 --- /dev/null +++ b/contrib/basebackup_to_shell/t/001_basic.pl @@ -0,0 +1,142 @@ +# Copyright (c) 2021-2022, PostgreSQL Global Development Group + +use strict; +use warnings; + +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +# For testing purposes, we just want basebackup_to_shell to write standard +# input to a file. However, Windows doesn't have "cat" or any equivalent, so +# we use "gzip" for this purpose. +my $gzip = $ENV{'GZIP_PROGRAM'}; +if (!defined $gzip || $gzip eq '') +{ + plan skip_all => 'gzip not available'; +} + +# to ensure path can be embedded in postgresql.conf +$gzip =~ s{\\}{/}g if ($PostgreSQL::Test::Utils::windows_os); + +my $node = PostgreSQL::Test::Cluster->new('primary'); + +# Make sure pg_hba.conf is set up to allow connections from backupuser. +# This is only needed on Windows machines that don't use UNIX sockets. +$node->init( + 'allows_streaming' => 1, + 'auth_extra' => [ '--create-role', 'backupuser' ]); + +$node->append_conf('postgresql.conf', + "shared_preload_libraries = 'basebackup_to_shell'"); +$node->start; +$node->safe_psql('postgres', 'CREATE USER backupuser REPLICATION'); +$node->safe_psql('postgres', 'CREATE ROLE trustworthy'); + +# 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 IPC::Run interpolate the array (as it is +# not a reference to an array)... +my @pg_basebackup_defs = ('pg_basebackup', '--no-sync', '-cfast'); + +# This particular test module generally wants to run with -Xfetch, because +# -Xstream is not supported with a backup target, and with -U backupuser. +my @pg_basebackup_cmd = (@pg_basebackup_defs, '-U', 'backupuser', '-Xfetch'); + +# Can't use this module without setting basebackup_to_shell.command. +$node->command_fails_like( + [ @pg_basebackup_cmd, '--target', 'shell' ], + qr/shell command for backup is not configured/, + 'fails if basebackup_to_shell.command is not set'); + +# Configure basebackup_to_shell.command and reload the configuation file. +my $backup_path = PostgreSQL::Test::Utils::tempdir; +my $escaped_backup_path = $backup_path; +$escaped_backup_path =~ s{\\}{\\\\}g + if ($PostgreSQL::Test::Utils::windows_os); +my $shell_command = + $PostgreSQL::Test::Utils::windows_os + ? qq{"$gzip" --fast > "$escaped_backup_path\\\\%f.gz"} + : qq{"$gzip" --fast > "$escaped_backup_path/%f.gz"}; +$node->append_conf('postgresql.conf', + "basebackup_to_shell.command='$shell_command'"); +$node->reload(); + +# Should work now. +$node->command_ok( + [ @pg_basebackup_cmd, '--target', 'shell' ], + 'backup with no detail: pg_basebackup'); +verify_backup('', $backup_path, "backup with no detail"); + +# Should fail with a detail. +$node->command_fails_like( + [ @pg_basebackup_cmd, '--target', 'shell:foo' ], + qr/a target detail is not permitted because the configured command does not include %d/, + 'fails if detail provided without %d'); + +# Reconfigure to restrict access and require a detail. +$shell_command = + $PostgreSQL::Test::Utils::windows_os + ? qq{"$gzip" --fast > "$escaped_backup_path\\\\%d.%f.gz"} + : qq{"$gzip" --fast > "$escaped_backup_path/%d.%f.gz"}; +$node->append_conf('postgresql.conf', + "basebackup_to_shell.command='$shell_command'"); +$node->append_conf('postgresql.conf', + "basebackup_to_shell.required_role='trustworthy'"); +$node->reload(); + +# Should fail due to lack of permission. +$node->command_fails_like( + [ @pg_basebackup_cmd, '--target', 'shell' ], + qr/permission denied to use basebackup_to_shell/, + 'fails if required_role not granted'); + +# Should fail due to lack of a detail. +$node->safe_psql('postgres', 'GRANT trustworthy TO backupuser'); +$node->command_fails_like( + [ @pg_basebackup_cmd, '--target', 'shell' ], + qr/a target detail is required because the configured command includes %d/, + 'fails if %d is present and detail not given'); + +# Should work. +$node->command_ok([ @pg_basebackup_cmd, '--target', 'shell:bar' ], + 'backup with detail: pg_basebackup'); +verify_backup('bar.', $backup_path, "backup with detail"); + +done_testing(); + +sub verify_backup +{ + my ($prefix, $backup_dir, $test_name) = @_; + + ok( -f "$backup_dir/${prefix}backup_manifest.gz", + "$test_name: backup_manifest.gz was created"); + ok( -f "$backup_dir/${prefix}base.tar.gz", + "$test_name: base.tar.gz was created"); + + SKIP: + { + my $tar = $ENV{TAR}; + skip "no tar program available", 1 if (!defined $tar || $tar eq ''); + + # Decompress. + system_or_bail($gzip, '-d', + $backup_dir . '/' . $prefix . 'backup_manifest.gz'); + system_or_bail($gzip, '-d', + $backup_dir . '/' . $prefix . 'base.tar.gz'); + + # Untar. + my $extract_path = PostgreSQL::Test::Utils::tempdir; + system_or_bail($tar, 'xf', $backup_dir . '/' . $prefix . 'base.tar', + '-C', $extract_path); + + # Verify. + $node->command_ok( + [ + 'pg_verifybackup', '-n', + '-m', "${backup_dir}/${prefix}backup_manifest", + '-e', $extract_path + ], + "$test_name: backup verifies ok"); + } +} |