mirror of https://github.com/postgres/postgres
Per gripe from Andres Freund. Thanks to Andres Freund, Thomas Munro, and Andrew Dunstan for advice on how to make this test work even on Windows. Discussion: https://postgr.es/m/CA+Tgmoat+zbzzZQJ7poXyUwiqxQxTaUid=auB4FejZ15VvDh4Q@mail.gmail.compull/81/head
parent
26a0c025e2
commit
027fa0fd72
@ -0,0 +1,129 @@ |
|||||||
|
# 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'; |
||||||
|
} |
||||||
|
|
||||||
|
my $node = PostgreSQL::Test::Cluster->new('primary'); |
||||||
|
$node->init('allows_streaming' => 1); |
||||||
|
$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"); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue