mirror of
https://github.com/postgres/postgres.git
synced 2025-06-29 10:41:53 +03:00
Add test for pg_upgrade file transfer modes.
This new test checks all of pg_upgrade's file transfer modes. For each mode, we verify that pg_upgrade either succeeds (and some test objects successfully reach the new version) or fails with an error that indicates the mode is not supported on the current platform. For cross-version tests, we also check that pg_upgrade transfers non-default tablespaces. (Tablespaces can't be tested on same version upgrades because of the version-specific subdirectory conflict, but we might be able to enable such tests once we teach pg_upgrade how to handle in-place tablespaces.) Suggested-by: Robert Haas <robertmhaas@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/Zyvop-LxLXBLrZil%40nathan
This commit is contained in:
@ -46,6 +46,7 @@ tests += {
|
||||
't/003_logical_slots.pl',
|
||||
't/004_subscription.pl',
|
||||
't/005_char_signedness.pl',
|
||||
't/006_transfer_modes.pl',
|
||||
],
|
||||
'test_kwargs': {'priority': 40}, # pg_upgrade tests are slow
|
||||
},
|
||||
|
101
src/bin/pg_upgrade/t/006_transfer_modes.pl
Normal file
101
src/bin/pg_upgrade/t/006_transfer_modes.pl
Normal file
@ -0,0 +1,101 @@
|
||||
# Copyright (c) 2025, PostgreSQL Global Development Group
|
||||
|
||||
# Tests for file transfer modes
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
|
||||
sub test_mode
|
||||
{
|
||||
my ($mode) = @_;
|
||||
|
||||
my $old = PostgreSQL::Test::Cluster->new('old', install_path => $ENV{oldinstall});
|
||||
my $new = PostgreSQL::Test::Cluster->new('new');
|
||||
|
||||
if (defined($ENV{oldinstall}))
|
||||
{
|
||||
# Checksums are now enabled by default, but weren't before 18, so pass
|
||||
# '-k' to initdb on older versions so that upgrades work.
|
||||
$old->init(extra => ['-k']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$old->init();
|
||||
}
|
||||
$new->init();
|
||||
|
||||
# Create a small variety of simple test objects on the old cluster. We'll
|
||||
# check that these reach the new version after upgrading.
|
||||
$old->start;
|
||||
$old->safe_psql('postgres', "CREATE TABLE test1 AS SELECT generate_series(1, 100)");
|
||||
$old->safe_psql('postgres', "CREATE DATABASE testdb1");
|
||||
$old->safe_psql('testdb1', "CREATE TABLE test2 AS SELECT generate_series(200, 300)");
|
||||
$old->safe_psql('testdb1', "VACUUM FULL test2");
|
||||
$old->safe_psql('testdb1', "CREATE SEQUENCE testseq START 5432");
|
||||
|
||||
# For cross-version tests, we can also check that pg_upgrade handles
|
||||
# tablespaces.
|
||||
if (defined($ENV{oldinstall}))
|
||||
{
|
||||
my $tblspc = PostgreSQL::Test::Utils::tempdir_short();
|
||||
$old->safe_psql('postgres', "CREATE TABLESPACE test_tblspc LOCATION '$tblspc'");
|
||||
$old->safe_psql('postgres', "CREATE DATABASE testdb2 TABLESPACE test_tblspc");
|
||||
$old->safe_psql('postgres', "CREATE TABLE test3 TABLESPACE test_tblspc AS SELECT generate_series(300, 401)");
|
||||
$old->safe_psql('testdb2', "CREATE TABLE test4 AS SELECT generate_series(400, 502)");
|
||||
}
|
||||
$old->stop;
|
||||
|
||||
my $result = command_ok_or_fails_like(
|
||||
[
|
||||
'pg_upgrade', '--no-sync',
|
||||
'--old-datadir' => $old->data_dir,
|
||||
'--new-datadir' => $new->data_dir,
|
||||
'--old-bindir' => $old->config_data('--bindir'),
|
||||
'--new-bindir' => $new->config_data('--bindir'),
|
||||
'--socketdir' => $new->host,
|
||||
'--old-port' => $old->port,
|
||||
'--new-port' => $new->port,
|
||||
$mode
|
||||
],
|
||||
qr/.* not supported on this platform|could not .* between old and new data directories: .*/,
|
||||
qr/^$/,
|
||||
"pg_upgrade with transfer mode $mode");
|
||||
|
||||
# If pg_upgrade was successful, check that all of our test objects reached
|
||||
# the new version.
|
||||
if ($result)
|
||||
{
|
||||
$new->start;
|
||||
$result = $new->safe_psql('postgres', "SELECT COUNT(*) FROM test1");
|
||||
is($result, '100', "test1 data after pg_upgrade $mode");
|
||||
$result = $new->safe_psql('testdb1', "SELECT COUNT(*) FROM test2");
|
||||
is($result, '101', "test2 data after pg_upgrade $mode");
|
||||
$result = $new->safe_psql('testdb1', "SELECT nextval('testseq')");
|
||||
is($result, '5432', "sequence data after pg_upgrade $mode");
|
||||
|
||||
# For cross-version tests, we should have some objects in a non-default
|
||||
# tablespace.
|
||||
if (defined($ENV{oldinstall}))
|
||||
{
|
||||
$result = $new->safe_psql('postgres', "SELECT COUNT(*) FROM test3");
|
||||
is($result, '102', "test3 data after pg_upgrade $mode");
|
||||
$result = $new->safe_psql('testdb2', "SELECT COUNT(*) FROM test4");
|
||||
is($result, '103', "test4 data after pg_upgrade $mode");
|
||||
}
|
||||
$new->stop;
|
||||
}
|
||||
|
||||
$old->clean_node();
|
||||
$new->clean_node();
|
||||
}
|
||||
|
||||
test_mode('--clone');
|
||||
test_mode('--copy');
|
||||
test_mode('--copy-file-range');
|
||||
test_mode('--link');
|
||||
|
||||
done_testing();
|
@ -2801,6 +2801,25 @@ sub command_fails_like
|
||||
|
||||
=pod
|
||||
|
||||
=item $node->command_ok_or_fails_like(...)
|
||||
|
||||
PostgreSQL::Test::Utils::command_ok_or_fails_like with our connection parameters. See command_ok(...)
|
||||
|
||||
=cut
|
||||
|
||||
sub command_ok_or_fails_like
|
||||
{
|
||||
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
||||
|
||||
my $self = shift;
|
||||
|
||||
local %ENV = $self->_get_env();
|
||||
|
||||
return PostgreSQL::Test::Utils::command_ok_or_fails_like(@_);
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item $node->command_checks_all(...)
|
||||
|
||||
PostgreSQL::Test::Utils::command_checks_all with our connection parameters. See
|
||||
|
@ -89,6 +89,7 @@ our @EXPORT = qw(
|
||||
command_like
|
||||
command_like_safe
|
||||
command_fails_like
|
||||
command_ok_or_fails_like
|
||||
command_checks_all
|
||||
|
||||
$windows_os
|
||||
@ -1067,6 +1068,30 @@ sub command_fails_like
|
||||
|
||||
=pod
|
||||
|
||||
=item command_ok_or_fails_like(cmd, expected_stdout, expected_stderr, test_name)
|
||||
|
||||
Check that the command either succeeds or fails with an error that matches the
|
||||
given regular expressions.
|
||||
|
||||
=cut
|
||||
|
||||
sub command_ok_or_fails_like
|
||||
{
|
||||
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
||||
my ($cmd, $expected_stdout, $expected_stderr, $test_name) = @_;
|
||||
my ($stdout, $stderr);
|
||||
print("# Running: " . join(" ", @{$cmd}) . "\n");
|
||||
my $result = IPC::Run::run $cmd, '>' => \$stdout, '2>' => \$stderr;
|
||||
if (!$result)
|
||||
{
|
||||
like($stdout, $expected_stdout, "$test_name: stdout matches");
|
||||
like($stderr, $expected_stderr, "$test_name: stderr matches");
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item command_checks_all(cmd, ret, out, err, test_name)
|
||||
|
||||
Run a command and check its status and outputs.
|
||||
|
Reference in New Issue
Block a user