2016-03-03 17:20:46 +01:00
|
|
|
|
2023-01-02 21:00:37 +01:00
|
|
|
# Copyright (c) 2021-2023, PostgreSQL Global Development Group
|
2021-05-07 16:56:14 +02:00
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=head1 NAME
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Cluster - class representing PostgreSQL server instance
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
use PostgreSQL::Test::Cluster;
|
2016-02-26 01:31:52 +01:00
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
my $node = PostgreSQL::Test::Cluster->new('mynode');
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
# Create a data directory with initdb
|
|
|
|
$node->init();
|
|
|
|
|
|
|
|
# Start the PostgreSQL server
|
|
|
|
$node->start();
|
|
|
|
|
2021-07-29 11:58:07 +02:00
|
|
|
# Add a setting and restart
|
2016-02-26 01:31:52 +01:00
|
|
|
$node->append_conf('postgresql.conf', 'hot_standby = on');
|
2017-01-12 18:00:00 +01:00
|
|
|
$node->restart();
|
2016-02-26 01:31:52 +01:00
|
|
|
|
2021-07-29 11:58:07 +02:00
|
|
|
# Modify or delete an existing setting
|
|
|
|
$node->adjust_conf('postgresql.conf', 'max_wal_senders', '10');
|
|
|
|
|
2022-11-13 14:45:14 +01:00
|
|
|
# get pg_config settings
|
|
|
|
# all the settings in one string
|
|
|
|
$pgconfig = $node->config_data;
|
|
|
|
# all the settings as a map
|
|
|
|
%config_map = ($node->config_data);
|
|
|
|
# specified settings
|
|
|
|
($incdir, $sharedir) = $node->config_data(qw(--includedir --sharedir));
|
|
|
|
|
2016-03-03 21:58:30 +01:00
|
|
|
# run a query with psql, like:
|
|
|
|
# echo 'SELECT 1' | psql -qAXt postgres -v ON_ERROR_STOP=1
|
|
|
|
$psql_stdout = $node->safe_psql('postgres', 'SELECT 1');
|
|
|
|
|
|
|
|
# Run psql with a timeout, capturing stdout and stderr
|
|
|
|
# as well as the psql exit code. Pass some extra psql
|
|
|
|
# options. If there's an error from psql raise an exception.
|
|
|
|
my ($stdout, $stderr, $timed_out);
|
2021-05-31 09:29:58 +02:00
|
|
|
my $cmdret = $node->psql('postgres', 'SELECT pg_sleep(600)',
|
2016-03-03 21:58:30 +01:00
|
|
|
stdout => \$stdout, stderr => \$stderr,
|
2022-03-05 03:53:13 +01:00
|
|
|
timeout => $PostgreSQL::Test::Utils::timeout_default,
|
|
|
|
timed_out => \$timed_out,
|
2016-03-03 21:58:30 +01:00
|
|
|
extra_params => ['--single-transaction'],
|
|
|
|
on_error_die => 1)
|
|
|
|
print "Sleep timed out" if $timed_out;
|
|
|
|
|
|
|
|
# Similar thing, more convenient in common cases
|
|
|
|
my ($cmdret, $stdout, $stderr) =
|
|
|
|
$node->psql('postgres', 'SELECT 1');
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
# run query every second until it returns 't'
|
|
|
|
# or times out
|
|
|
|
$node->poll_query_until('postgres', q|SELECT random() < 0.1;|')
|
2017-07-01 20:25:09 +02:00
|
|
|
or die "timed out";
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
# Do an online pg_basebackup
|
2016-03-09 23:54:03 +01:00
|
|
|
my $ret = $node->backup('testbackup1');
|
|
|
|
|
|
|
|
# Take a backup of a running server
|
|
|
|
my $ret = $node->backup_fs_hot('testbackup2');
|
|
|
|
|
|
|
|
# Take a backup of a stopped server
|
|
|
|
$node->stop;
|
|
|
|
my $ret = $node->backup_fs_cold('testbackup3')
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
# Restore it to create a new independent node (not a replica)
|
2021-10-24 16:28:19 +02:00
|
|
|
my $other_node = PostgreSQL::Test::Cluster->new('mycopy');
|
2021-07-29 11:58:08 +02:00
|
|
|
$other_node->init_from_backup($node, 'testbackup');
|
|
|
|
$other_node->start;
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
# Stop the server
|
|
|
|
$node->stop('fast');
|
|
|
|
|
2019-08-04 19:07:12 +02:00
|
|
|
# Find a free, unprivileged TCP port to bind some other service to
|
2021-10-24 16:28:19 +02:00
|
|
|
my $port = PostgreSQL::Test::Cluster::get_free_port();
|
2019-08-04 19:07:12 +02:00
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=head1 DESCRIPTION
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Cluster contains a set of routines able to work on a PostgreSQL node,
|
2016-02-26 01:31:52 +01:00
|
|
|
allowing to start, stop, backup and initialize it with various options.
|
|
|
|
The set of nodes managed by a given test is also managed by this module.
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
In addition to node management, PostgreSQL::Test::Cluster instances have some wrappers
|
2016-02-26 17:24:22 +01:00
|
|
|
around Test::More functions to run commands with an environment set up to
|
2016-02-26 01:31:52 +01:00
|
|
|
point to the instance.
|
|
|
|
|
|
|
|
The IPC::Run module is required.
|
|
|
|
|
|
|
|
=cut
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
package PostgreSQL::Test::Cluster;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
|
2018-02-24 20:35:54 +01:00
|
|
|
use Carp;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
use Config;
|
2022-11-20 15:51:50 +01:00
|
|
|
use Fcntl qw(:mode :flock :seek :DEFAULT);
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
use File::Basename;
|
2022-11-20 15:51:50 +01:00
|
|
|
use File::Path qw(rmtree mkpath);
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
use File::Spec;
|
2018-04-07 23:45:39 +02:00
|
|
|
use File::stat qw(stat);
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
use File::Temp ();
|
|
|
|
use IPC::Run;
|
2021-10-24 16:28:19 +02:00
|
|
|
use PostgreSQL::Version;
|
|
|
|
use PostgreSQL::Test::RecursiveCopy;
|
Improve PostgresNode.pm's logic for detecting already-in-use ports.
Buildfarm members bowerbird and jacana have shown intermittent "could not
bind IPv4 socket" failures in the BinInstallCheck stage since mid-December,
shortly after commits 1caef31d9e550408 and 9821492ee417a591 changed the
logic for selecting which port to use in temporary installations. One
plausible explanation is that we are randomly selecting ports that are
already in use for some non-Postgres purpose. Although the code tried
to defend against already-in-use ports, it used pg_isready to probe
the port which is quite unhelpful: if some non-Postgres server responds
at the given address, pg_isready will generally say "no response",
leading to exactly the wrong conclusion about whether the port is free.
Instead, let's use a simple TCP connect() call to see if anything answers
without making assumptions about what it is. Note that this means there's
no direct check for a conflicting Unix socket, but that should be okay
because there should be no other Unix sockets in use in the temporary
socket directory created for a test run.
This is only a partial solution for the TCP case, since if the port number
is in use for an outgoing connection rather than a listening socket, we'll
fail to detect that. We could try to bind() to the proposed port as a
means of detecting that case, but that would introduce its own failure
modes, since the system might consider the address to remain reserved for
some period of time after we drop the bound socket. Close study of the
errors returned by bowerbird and jacana suggests that what we're seeing
there may be conflicts with listening not outgoing sockets, so let's try
this and see if it improves matters. It's certainly better than what's
there now, in any case.
Michael Paquier, adjusted by me to work on non-Windows as well as Windows
2016-04-24 21:31:36 +02:00
|
|
|
use Socket;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
use Test::More;
|
2021-10-24 16:28:19 +02:00
|
|
|
use PostgreSQL::Test::Utils ();
|
2023-04-07 22:14:20 +02:00
|
|
|
use PostgreSQL::Test::BackgroundPsql ();
|
2017-07-17 21:22:37 +02:00
|
|
|
use Time::HiRes qw(usleep);
|
2016-03-03 21:58:30 +01:00
|
|
|
use Scalar::Util qw(blessed);
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2019-04-13 07:36:38 +02:00
|
|
|
our ($use_tcp, $test_localhost, $test_pghost, $last_host_assigned,
|
2022-11-20 15:51:50 +01:00
|
|
|
$last_port_assigned, @all_nodes, $died, $portdir);
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2022-03-30 17:07:05 +02:00
|
|
|
# the minimum version we believe to be compatible with this package without
|
|
|
|
# subclassing.
|
|
|
|
our $min_compat = 12;
|
|
|
|
|
2022-11-20 15:51:50 +01:00
|
|
|
# list of file reservations made by get_free_port
|
|
|
|
my @port_reservation_files;
|
|
|
|
|
2015-12-07 23:25:31 +01:00
|
|
|
INIT
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
{
|
2016-06-12 10:19:56 +02:00
|
|
|
|
2019-04-13 07:36:38 +02:00
|
|
|
# Set PGHOST for backward compatibility. This doesn't work for own_host
|
|
|
|
# nodes, so prefer to not rely on this when writing new tests.
|
2021-10-24 16:28:19 +02:00
|
|
|
$use_tcp = !$PostgreSQL::Test::Utils::use_unix_sockets;
|
2019-04-13 07:36:38 +02:00
|
|
|
$test_localhost = "127.0.0.1";
|
|
|
|
$last_host_assigned = 1;
|
2021-12-13 20:17:41 +01:00
|
|
|
if ($use_tcp)
|
|
|
|
{
|
|
|
|
$test_pghost = $test_localhost;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
# On windows, replace windows-style \ path separators with / when
|
|
|
|
# putting socket directories either in postgresql.conf or libpq
|
|
|
|
# connection strings, otherwise they are interpreted as escapes.
|
|
|
|
$test_pghost = PostgreSQL::Test::Utils::tempdir_short;
|
|
|
|
$test_pghost =~ s!\\!/!g if $PostgreSQL::Test::Utils::windows_os;
|
|
|
|
}
|
2019-04-13 07:36:38 +02:00
|
|
|
$ENV{PGHOST} = $test_pghost;
|
|
|
|
$ENV{PGDATABASE} = 'postgres';
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
|
|
|
# Tracking of last port value assigned to accelerate free port lookup.
|
2015-12-07 23:25:31 +01:00
|
|
|
$last_port_assigned = int(rand() * 16384) + 49152;
|
2022-11-20 15:51:50 +01:00
|
|
|
|
|
|
|
# Set the port lock directory
|
|
|
|
|
|
|
|
# If we're told to use a directory (e.g. from a buildfarm client)
|
|
|
|
# explicitly, use that
|
|
|
|
$portdir = $ENV{PG_TEST_PORT_DIR};
|
|
|
|
# Otherwise, try to use a directory at the top of the build tree
|
|
|
|
# or as a last resort use the tmp_check directory
|
|
|
|
my $build_dir =
|
|
|
|
$ENV{MESON_BUILD_ROOT}
|
|
|
|
|| $ENV{top_builddir}
|
|
|
|
|| $PostgreSQL::Test::Utils::tmp_check;
|
|
|
|
$portdir ||= "$build_dir/portlock";
|
|
|
|
$portdir =~ s!\\!/!g;
|
|
|
|
# Make sure the directory exists
|
|
|
|
mkpath($portdir) unless -d $portdir;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=head1 METHODS
|
|
|
|
|
|
|
|
=over
|
|
|
|
|
|
|
|
=item $node->port()
|
|
|
|
|
|
|
|
Get the port number assigned to the host. This won't necessarily be a TCP port
|
|
|
|
open on the local host since we prefer to use unix sockets if possible.
|
|
|
|
|
|
|
|
Use $node->connstr() if you want a connection string.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub port
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
return $self->{_port};
|
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->host()
|
|
|
|
|
|
|
|
Return the host (like PGHOST) for this instance. May be a UNIX socket path.
|
|
|
|
|
|
|
|
Use $node->connstr() if you want a connection string.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub host
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
return $self->{_host};
|
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->basedir()
|
|
|
|
|
|
|
|
The directory all the node's files will be within - datadir, archive directory,
|
|
|
|
backups, etc.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub basedir
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
return $self->{_basedir};
|
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->name()
|
|
|
|
|
|
|
|
The name assigned to the node at creation time.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
2016-01-20 18:13:11 +01:00
|
|
|
sub name
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
{
|
|
|
|
my ($self) = @_;
|
2016-01-20 18:13:11 +01:00
|
|
|
return $self->{_name};
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->logfile()
|
|
|
|
|
|
|
|
Path to the PostgreSQL log file for this instance.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub logfile
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
return $self->{_logfile};
|
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->connstr()
|
|
|
|
|
|
|
|
Get a libpq connection string that will establish a connection to
|
|
|
|
this node. Suitable for passing to psql, DBD::Pg, etc.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub connstr
|
|
|
|
{
|
|
|
|
my ($self, $dbname) = @_;
|
|
|
|
my $pgport = $self->port;
|
|
|
|
my $pghost = $self->host;
|
|
|
|
if (!defined($dbname))
|
|
|
|
{
|
|
|
|
return "port=$pgport host=$pghost";
|
|
|
|
}
|
2016-08-04 20:44:23 +02:00
|
|
|
|
|
|
|
# Escape properly the database string before using it, only
|
|
|
|
# single quotes and backslashes need to be treated this way.
|
|
|
|
$dbname =~ s#\\#\\\\#g;
|
|
|
|
$dbname =~ s#\'#\\\'#g;
|
|
|
|
|
|
|
|
return "port=$pgport host=$pghost dbname='$dbname'";
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
2018-04-07 23:45:39 +02:00
|
|
|
=item $node->group_access()
|
|
|
|
|
|
|
|
Does the data dir allow group access?
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub group_access
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
|
|
|
|
my $dir_stat = stat($self->data_dir);
|
|
|
|
|
|
|
|
defined($dir_stat)
|
|
|
|
or die('unable to stat ' . $self->data_dir);
|
|
|
|
|
|
|
|
return (S_IMODE($dir_stat->mode) == 0750);
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=item $node->data_dir()
|
|
|
|
|
|
|
|
Returns the path to the data directory. postgresql.conf and pg_hba.conf are
|
|
|
|
always here.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub data_dir
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
my $res = $self->basedir;
|
|
|
|
return "$res/pgdata";
|
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->archive_dir()
|
|
|
|
|
|
|
|
If archiving is enabled, WAL files go here.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub archive_dir
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
my $basedir = $self->basedir;
|
|
|
|
return "$basedir/archives";
|
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->backup_dir()
|
|
|
|
|
|
|
|
The output path for backups taken with $node->backup()
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub backup_dir
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
my $basedir = $self->basedir;
|
|
|
|
return "$basedir/backup";
|
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
2021-07-29 11:58:08 +02:00
|
|
|
=item $node->install_path()
|
|
|
|
|
|
|
|
The configured install path (if any) for the node.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub install_path
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
return $self->{_install_path};
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2022-05-20 11:29:51 +02:00
|
|
|
=item $node->pg_version()
|
|
|
|
|
|
|
|
The version number for the node, from PostgreSQL::Version.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub pg_version
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
return $self->{_pg_version};
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2022-11-13 14:45:14 +01:00
|
|
|
=item $node->config_data( option ...)
|
|
|
|
|
|
|
|
Return configuration data from pg_config, using options (if supplied).
|
|
|
|
The options will be things like '--sharedir'.
|
|
|
|
|
|
|
|
If no options are supplied, return a string in scalar context or a map in
|
|
|
|
array context.
|
2022-02-08 02:35:27 +01:00
|
|
|
|
2022-11-13 14:45:14 +01:00
|
|
|
If options are supplied, return the list of values.
|
2022-02-08 02:35:27 +01:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub config_data
|
|
|
|
{
|
2022-11-13 14:45:14 +01:00
|
|
|
my ($self, @options) = @_;
|
2022-02-08 02:35:27 +01:00
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
|
|
|
my ($stdout, $stderr);
|
|
|
|
my $result =
|
2022-11-13 14:45:14 +01:00
|
|
|
IPC::Run::run [ $self->installed_command('pg_config'), @options ],
|
2022-02-08 02:35:27 +01:00
|
|
|
'>', \$stdout, '2>', \$stderr
|
|
|
|
or die "could not execute pg_config";
|
2022-11-13 14:45:14 +01:00
|
|
|
# standardize line endings
|
|
|
|
$stdout =~ s/\r(?=\n)//g;
|
|
|
|
# no options, scalar context: just hand back the output
|
|
|
|
return $stdout unless (wantarray || @options);
|
2022-02-08 02:35:27 +01:00
|
|
|
chomp($stdout);
|
2022-11-13 14:45:14 +01:00
|
|
|
# exactly one option: hand back the output (minus LF)
|
|
|
|
return $stdout if (@options == 1);
|
|
|
|
my @lines = split(/\n/, $stdout);
|
|
|
|
# more than one option: hand back the list of values;
|
|
|
|
return @lines if (@options);
|
|
|
|
# no options, array context: return a map
|
|
|
|
my @map;
|
|
|
|
foreach my $line (@lines)
|
|
|
|
{
|
|
|
|
my ($k, $v) = split(/ = /, $line, 2);
|
|
|
|
push(@map, $k, $v);
|
|
|
|
}
|
|
|
|
return @map;
|
2022-02-08 02:35:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=item $node->info()
|
|
|
|
|
|
|
|
Return a string containing human-readable diagnostic information (paths, etc)
|
|
|
|
about this node.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub info
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
my $_info = '';
|
|
|
|
open my $fh, '>', \$_info or die;
|
|
|
|
print $fh "Name: " . $self->name . "\n";
|
2021-04-22 16:56:28 +02:00
|
|
|
print $fh "Version: " . $self->{_pg_version} . "\n"
|
|
|
|
if $self->{_pg_version};
|
2016-02-26 01:31:52 +01:00
|
|
|
print $fh "Data directory: " . $self->data_dir . "\n";
|
|
|
|
print $fh "Backup directory: " . $self->backup_dir . "\n";
|
|
|
|
print $fh "Archive directory: " . $self->archive_dir . "\n";
|
|
|
|
print $fh "Connection string: " . $self->connstr . "\n";
|
|
|
|
print $fh "Log file: " . $self->logfile . "\n";
|
2021-03-24 23:52:25 +01:00
|
|
|
print $fh "Install Path: ", $self->{_install_path} . "\n"
|
|
|
|
if $self->{_install_path};
|
2016-02-26 01:31:52 +01:00
|
|
|
close $fh or die;
|
|
|
|
return $_info;
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->dump_info()
|
|
|
|
|
|
|
|
Print $node->info()
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub dump_info
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
2016-02-26 01:31:52 +01:00
|
|
|
print $self->info;
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
# Internal method to set up trusted pg_hba.conf for replication. Not
|
|
|
|
# documented because you shouldn't use it, it's called automatically if needed.
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub set_replication_conf
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
my $pgdata = $self->data_dir;
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
$self->host eq $test_pghost
|
2018-02-24 20:35:54 +01:00
|
|
|
or croak "set_replication_conf only works with the default host";
|
2016-02-26 01:31:52 +01:00
|
|
|
|
2017-03-27 04:24:13 +02:00
|
|
|
open my $hba, '>>', "$pgdata/pg_hba.conf";
|
2021-10-24 16:28:19 +02:00
|
|
|
print $hba
|
|
|
|
"\n# Allow replication (set up by PostgreSQL::Test::Cluster.pm)\n";
|
|
|
|
if ($PostgreSQL::Test::Utils::windows_os
|
|
|
|
&& !$PostgreSQL::Test::Utils::use_unix_sockets)
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
{
|
|
|
|
print $hba
|
2018-04-26 17:52:52 +02:00
|
|
|
"host replication all $test_localhost/32 sspi include_realm=1 map=regress\n";
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
close $hba;
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->init(...)
|
|
|
|
|
|
|
|
Initialize a new cluster for testing.
|
|
|
|
|
|
|
|
Authentication is set up so that only the current OS user can access the
|
|
|
|
cluster. On Unix, we use Unix domain socket connections, with the socket in
|
|
|
|
a directory that's only accessible to the current user to ensure that.
|
|
|
|
On Windows, we use SSPI authentication to ensure the same (by pg_regress
|
|
|
|
--config-auth).
|
|
|
|
|
2016-02-26 20:13:30 +01:00
|
|
|
WAL archiving can be enabled on this node by passing the keyword parameter
|
|
|
|
has_archiving => 1. This is disabled by default.
|
|
|
|
|
2016-02-26 17:24:22 +01:00
|
|
|
postgresql.conf can be set up for replication by passing the keyword
|
2017-01-19 18:00:00 +01:00
|
|
|
parameter allows_streaming => 'logical' or 'physical' (passing 1 will also
|
|
|
|
suffice for physical replication) depending on type of replication that
|
|
|
|
should be enabled. This is disabled by default.
|
2016-02-26 17:24:22 +01:00
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
The new node is set up in a fast but unsafe configuration where fsync is
|
|
|
|
disabled.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub init
|
|
|
|
{
|
|
|
|
my ($self, %params) = @_;
|
|
|
|
my $port = $self->port;
|
|
|
|
my $pgdata = $self->data_dir;
|
|
|
|
my $host = $self->host;
|
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
2016-02-26 17:24:22 +01:00
|
|
|
$params{allows_streaming} = 0 unless defined $params{allows_streaming};
|
2016-03-03 17:20:46 +01:00
|
|
|
$params{has_archiving} = 0 unless defined $params{has_archiving};
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
|
|
|
mkdir $self->backup_dir;
|
|
|
|
mkdir $self->archive_dir;
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::system_or_bail('initdb', '-D', $pgdata, '-A',
|
2016-08-04 20:44:23 +02:00
|
|
|
'trust', '-N', @{ $params{extra} });
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::system_or_bail($ENV{PG_REGRESS},
|
2019-04-14 11:47:51 +02:00
|
|
|
'--config-auth', $pgdata, @{ $params{auth_extra} });
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2017-03-27 04:24:13 +02:00
|
|
|
open my $conf, '>>', "$pgdata/postgresql.conf";
|
2021-10-24 16:28:19 +02:00
|
|
|
print $conf "\n# Added by PostgreSQL::Test::Cluster.pm\n";
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
print $conf "fsync = off\n";
|
Make PostgresNode.pm check server status more carefully.
PostgresNode blithely ignored the exit status of pg_ctl, and in general
made no effort to be sure that the server was running when it should be.
This caused it to miss server crashes, which is a serious shortcoming
in a test scaffold. Make it complain if pg_ctl fails, and modify the
start and stop logic to complain if the server doesn't start, or doesn't
stop, when expected.
Also, have it turn off the "restart_after_crash" configuration parameter
in created clusters, as bitter experience has shown that leaving that on
can mask crashes too.
We might at some point need variant functions that allow for, eg,
server start failure to be expected. But no existing test case appears
to want that, and it surely shouldn't be the default behavior.
Note that this *will* break the buildfarm, as it will expose known
bugs that the previous testing failed to. I'm committing it despite
that, to verify that we get the expected failures in the buildfarm
not just in manual testing.
Back-patch into 9.6 where PostgresNode was introduced. (The 9.6
branch is not expected to show any failures.)
Discussion: https://postgr.es/m/21432.1492886428@sss.pgh.pa.us
2017-04-23 00:18:25 +02:00
|
|
|
print $conf "restart_after_crash = off\n";
|
2016-09-30 18:00:00 +02:00
|
|
|
print $conf "log_line_prefix = '%m [%p] %q%a '\n";
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
print $conf "log_statement = all\n";
|
2017-09-26 21:00:05 +02:00
|
|
|
print $conf "log_replication_commands = on\n";
|
2017-06-27 01:01:26 +02:00
|
|
|
print $conf "wal_retrieve_retry_interval = '500ms'\n";
|
2019-05-11 09:22:38 +02:00
|
|
|
|
|
|
|
# If a setting tends to affect whether tests pass or fail, print it after
|
|
|
|
# TEMP_CONFIG. Otherwise, print it before TEMP_CONFIG, thereby permitting
|
|
|
|
# overrides. Settings that merely improve performance or ease debugging
|
|
|
|
# belong before TEMP_CONFIG.
|
2021-10-24 16:28:19 +02:00
|
|
|
print $conf PostgreSQL::Test::Utils::slurp_file($ENV{TEMP_CONFIG})
|
2019-05-11 09:22:38 +02:00
|
|
|
if defined $ENV{TEMP_CONFIG};
|
|
|
|
|
2016-02-26 17:24:22 +01:00
|
|
|
if ($params{allows_streaming})
|
|
|
|
{
|
2017-01-19 18:00:00 +01:00
|
|
|
if ($params{allows_streaming} eq "logical")
|
|
|
|
{
|
|
|
|
print $conf "wal_level = logical\n";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
print $conf "wal_level = replica\n";
|
|
|
|
}
|
2020-10-01 16:59:20 +02:00
|
|
|
print $conf "max_wal_senders = 10\n";
|
|
|
|
print $conf "max_replication_slots = 10\n";
|
2016-02-26 17:24:22 +01:00
|
|
|
print $conf "wal_log_hints = on\n";
|
|
|
|
print $conf "hot_standby = on\n";
|
Remove obsolete replication settings within TAP tests.
PostgresNode.pm set "max_wal_senders = 5" for replication testing,
but this seems to be slightly too low for our current test suite.
Slower buildfarm members frequently report "number of requested standby
connections exceeds max_wal_senders" failures, due to old walsenders
not exiting instantaneously. Usually, the test does not fail overall
because of automatic walreceiver restart, but sometimes the failure
becomes visible; and in any case such retries slow down the test.
That value came in with commit 89ac7004d, but was soon obsoleted by
f6d6d2920, which raised the built-in default from zero to 10; so that
PostgresNode.pm is actually setting it to less than the conservative
built-in default. That seems pretty pointless, so let's remove the
special setting and let the default prevail, in hopes of making
the TAP tests more robust.
Likewise, the setting "max_replication_slots = 5" is obsolete and
can be removed.
While here, reverse-engineer a comment about why we're choosing
less-than-default values for some other settings.
(Note: before v12, max_wal_senders counted against max_connections
so that the latter setting also needs some fiddling with.)
Back-patch to v10 where the subscription tests were added.
It's likely that the older branches aren't pushing the boundaries
of max_wal_senders, but I'm disinclined to spend time trying to
figure out exactly when it started to be a problem.
Discussion: https://postgr.es/m/723911.1601417626@sss.pgh.pa.us
2020-09-30 02:02:58 +02:00
|
|
|
# conservative settings to ensure we can run multiple postmasters:
|
|
|
|
print $conf "shared_buffers = 1MB\n";
|
2016-02-26 17:24:22 +01:00
|
|
|
print $conf "max_connections = 10\n";
|
2020-10-01 16:59:20 +02:00
|
|
|
# limit disk space consumption, too:
|
|
|
|
print $conf "max_wal_size = 128MB\n";
|
2016-02-26 17:24:22 +01:00
|
|
|
}
|
2017-01-14 17:14:56 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
print $conf "wal_level = minimal\n";
|
|
|
|
print $conf "max_wal_senders = 0\n";
|
|
|
|
}
|
2016-02-26 17:24:22 +01:00
|
|
|
|
2019-05-11 09:22:38 +02:00
|
|
|
print $conf "port = $port\n";
|
2019-04-13 07:36:38 +02:00
|
|
|
if ($use_tcp)
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
{
|
2019-04-13 07:36:38 +02:00
|
|
|
print $conf "unix_socket_directories = ''\n";
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
print $conf "listen_addresses = '$host'\n";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
print $conf "unix_socket_directories = '$host'\n";
|
|
|
|
print $conf "listen_addresses = ''\n";
|
|
|
|
}
|
|
|
|
close $conf;
|
|
|
|
|
2018-04-07 23:45:39 +02:00
|
|
|
chmod($self->group_access ? 0640 : 0600, "$pgdata/postgresql.conf")
|
|
|
|
or die("unable to set permissions for $pgdata/postgresql.conf");
|
|
|
|
|
2017-03-09 14:27:16 +01:00
|
|
|
$self->set_replication_conf if $params{allows_streaming};
|
2016-03-03 17:20:46 +01:00
|
|
|
$self->enable_archiving if $params{has_archiving};
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->append_conf(filename, str)
|
|
|
|
|
|
|
|
A shortcut method to append to files like pg_hba.conf and postgresql.conf.
|
|
|
|
|
|
|
|
Does no validation or sanity checking. Does not reload the configuration
|
|
|
|
after writing.
|
|
|
|
|
2017-04-22 22:58:15 +02:00
|
|
|
A newline is automatically appended to the string.
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub append_conf
|
|
|
|
{
|
|
|
|
my ($self, $filename, $str) = @_;
|
|
|
|
|
|
|
|
my $conffile = $self->data_dir . '/' . $filename;
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::append_to_file($conffile, $str . "\n");
|
2018-04-07 23:45:39 +02:00
|
|
|
|
2018-04-07 23:45:39 +02:00
|
|
|
chmod($self->group_access() ? 0640 : 0600, $conffile)
|
2018-04-07 23:45:39 +02:00
|
|
|
or die("unable to set permissions for $conffile");
|
2018-05-27 15:08:42 +02:00
|
|
|
|
|
|
|
return;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
2021-07-29 11:58:07 +02:00
|
|
|
=item $node->adjust_conf(filename, setting, value, skip_equals)
|
|
|
|
|
|
|
|
Modify the named config file setting with the value. If the value is undefined,
|
|
|
|
instead delete the setting. If the setting is not present no action is taken.
|
|
|
|
|
|
|
|
This will write "$setting = $value\n" in place of the existing line,
|
|
|
|
unless skip_equals is true, in which case it will write
|
|
|
|
"$setting $value\n". If the value needs to be quoted it is the caller's
|
|
|
|
responsibility to do that.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub adjust_conf
|
|
|
|
{
|
|
|
|
my ($self, $filename, $setting, $value, $skip_equals) = @_;
|
|
|
|
|
|
|
|
my $conffile = $self->data_dir . '/' . $filename;
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
my $contents = PostgreSQL::Test::Utils::slurp_file($conffile);
|
2021-07-29 11:58:07 +02:00
|
|
|
my @lines = split(/\n/, $contents);
|
|
|
|
my @result;
|
|
|
|
my $eq = $skip_equals ? '' : '= ';
|
|
|
|
foreach my $line (@lines)
|
|
|
|
{
|
|
|
|
if ($line !~ /^$setting\W/)
|
|
|
|
{
|
|
|
|
push(@result, "$line\n");
|
|
|
|
}
|
|
|
|
elsif (defined $value)
|
|
|
|
{
|
|
|
|
push(@result, "$setting $eq$value\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
open my $fh, ">", $conffile
|
|
|
|
or croak "could not write \"$conffile\": $!";
|
|
|
|
print $fh @result;
|
|
|
|
close $fh;
|
|
|
|
|
|
|
|
chmod($self->group_access() ? 0640 : 0600, $conffile)
|
|
|
|
or die("unable to set permissions for $conffile");
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=item $node->backup(backup_name)
|
|
|
|
|
2016-03-09 23:54:03 +01:00
|
|
|
Create a hot backup with B<pg_basebackup> in subdirectory B<backup_name> of
|
Add end-to-end testing of pg_basebackup's tar-format output.
The existing test script does run pg_basebackup with the -Ft option,
but it makes no real attempt to verify the sanity of the results.
We wouldn't know if the output is incompatible with standard "tar"
programs, nor if the server fails to start from the restored output.
Notably, this means that xlog.c's read_tablespace_map() is not being
meaningfully tested, since that code is used only in the tar-format
case. (We do have reasonable coverage of restoring from plain-format
output, though it's over in src/test/recovery not here.)
Hence, attempt to untar the output and start a server from it,
rather just hoping it's OK.
This test assumes that the local "tar" has the "-C directory"
switch. Although that's not promised by POSIX, my research
suggests that all non-extinct tar implementations have it.
Should the buildfarm's opinion differ, we can complicate the
test a bit to avoid requiring that.
Possibly this should be back-patched, but I'm unsure about
whether it could work on Windows before d66b23b03.
2021-03-17 19:52:55 +01:00
|
|
|
B<< $node->backup_dir >>, including the WAL.
|
|
|
|
|
|
|
|
By default, WAL files are fetched at the end of the backup, not streamed.
|
|
|
|
You can adjust that and other things by passing an array of additional
|
|
|
|
B<pg_basebackup> command line options in the keyword parameter backup_options.
|
2016-02-26 01:31:52 +01:00
|
|
|
|
2016-03-09 23:54:03 +01:00
|
|
|
You'll have to configure a suitable B<max_wal_senders> on the
|
2016-02-26 01:31:52 +01:00
|
|
|
target server since it isn't done by default.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub backup
|
|
|
|
{
|
Add end-to-end testing of pg_basebackup's tar-format output.
The existing test script does run pg_basebackup with the -Ft option,
but it makes no real attempt to verify the sanity of the results.
We wouldn't know if the output is incompatible with standard "tar"
programs, nor if the server fails to start from the restored output.
Notably, this means that xlog.c's read_tablespace_map() is not being
meaningfully tested, since that code is used only in the tar-format
case. (We do have reasonable coverage of restoring from plain-format
output, though it's over in src/test/recovery not here.)
Hence, attempt to untar the output and start a server from it,
rather just hoping it's OK.
This test assumes that the local "tar" has the "-C directory"
switch. Although that's not promised by POSIX, my research
suggests that all non-extinct tar implementations have it.
Should the buildfarm's opinion differ, we can complicate the
test a bit to avoid requiring that.
Possibly this should be back-patched, but I'm unsure about
whether it could work on Windows before d66b23b03.
2021-03-17 19:52:55 +01:00
|
|
|
my ($self, $backup_name, %params) = @_;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
my $backup_path = $self->backup_dir . '/' . $backup_name;
|
2016-01-20 18:13:11 +01:00
|
|
|
my $name = $self->name;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
2016-03-09 23:54:03 +01:00
|
|
|
print "# Taking pg_basebackup $backup_name from node \"$name\"\n";
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::system_or_bail(
|
2020-10-21 19:37:26 +02:00
|
|
|
'pg_basebackup', '-D',
|
|
|
|
$backup_path, '-h',
|
|
|
|
$self->host, '-p',
|
|
|
|
$self->port, '--checkpoint',
|
Add end-to-end testing of pg_basebackup's tar-format output.
The existing test script does run pg_basebackup with the -Ft option,
but it makes no real attempt to verify the sanity of the results.
We wouldn't know if the output is incompatible with standard "tar"
programs, nor if the server fails to start from the restored output.
Notably, this means that xlog.c's read_tablespace_map() is not being
meaningfully tested, since that code is used only in the tar-format
case. (We do have reasonable coverage of restoring from plain-format
output, though it's over in src/test/recovery not here.)
Hence, attempt to untar the output and start a server from it,
rather just hoping it's OK.
This test assumes that the local "tar" has the "-C directory"
switch. Although that's not promised by POSIX, my research
suggests that all non-extinct tar implementations have it.
Should the buildfarm's opinion differ, we can complicate the
test a bit to avoid requiring that.
Possibly this should be back-patched, but I'm unsure about
whether it could work on Windows before d66b23b03.
2021-03-17 19:52:55 +01:00
|
|
|
'fast', '--no-sync',
|
|
|
|
@{ $params{backup_options} });
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
print "# Backup finished\n";
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-03-09 23:54:03 +01:00
|
|
|
=item $node->backup_fs_cold(backup_name)
|
|
|
|
|
|
|
|
Create a backup with a filesystem level copy in subdirectory B<backup_name> of
|
2017-05-12 17:49:56 +02:00
|
|
|
B<< $node->backup_dir >>, including WAL. The server must be
|
2016-03-09 23:54:03 +01:00
|
|
|
stopped as no attempt to handle concurrent writes is made.
|
|
|
|
|
|
|
|
Use B<backup> or B<backup_fs_hot> if you want to back up a running server.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub backup_fs_cold
|
|
|
|
{
|
|
|
|
my ($self, $backup_name) = @_;
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::RecursiveCopy::copypath(
|
2016-03-09 23:54:03 +01:00
|
|
|
$self->data_dir,
|
2022-04-06 20:41:03 +02:00
|
|
|
$self->backup_dir . '/' . $backup_name,
|
2016-03-09 23:54:03 +01:00
|
|
|
filterfn => sub {
|
|
|
|
my $src = shift;
|
2017-03-27 16:34:33 +02:00
|
|
|
return ($src ne 'log' and $src ne 'postmaster.pid');
|
2016-03-09 23:54:03 +01:00
|
|
|
});
|
|
|
|
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
2016-03-09 23:54:03 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->init_from_backup(root_node, backup_name)
|
|
|
|
|
|
|
|
Initialize a node from a backup, which may come from this node or a different
|
2021-10-24 16:28:19 +02:00
|
|
|
node. root_node must be a PostgreSQL::Test::Cluster reference, backup_name the string name
|
2016-02-26 01:31:52 +01:00
|
|
|
of a backup previously created on that node with $node->backup.
|
|
|
|
|
2016-02-26 20:13:30 +01:00
|
|
|
Does not start the node after initializing it.
|
2016-02-26 01:31:52 +01:00
|
|
|
|
Add end-to-end testing of pg_basebackup's tar-format output.
The existing test script does run pg_basebackup with the -Ft option,
but it makes no real attempt to verify the sanity of the results.
We wouldn't know if the output is incompatible with standard "tar"
programs, nor if the server fails to start from the restored output.
Notably, this means that xlog.c's read_tablespace_map() is not being
meaningfully tested, since that code is used only in the tar-format
case. (We do have reasonable coverage of restoring from plain-format
output, though it's over in src/test/recovery not here.)
Hence, attempt to untar the output and start a server from it,
rather just hoping it's OK.
This test assumes that the local "tar" has the "-C directory"
switch. Although that's not promised by POSIX, my research
suggests that all non-extinct tar implementations have it.
Should the buildfarm's opinion differ, we can complicate the
test a bit to avoid requiring that.
Possibly this should be back-patched, but I'm unsure about
whether it could work on Windows before d66b23b03.
2021-03-17 19:52:55 +01:00
|
|
|
By default, the backup is assumed to be plain format. To restore from
|
|
|
|
a tar-format backup, pass the name of the tar program to use in the
|
|
|
|
keyword parameter tar_program. Note that tablespace tar files aren't
|
|
|
|
handled here.
|
|
|
|
|
2016-02-26 17:24:22 +01:00
|
|
|
Streaming replication can be enabled on this node by passing the keyword
|
|
|
|
parameter has_streaming => 1. This is disabled by default.
|
|
|
|
|
2016-02-26 20:13:30 +01:00
|
|
|
Restoring WAL segments from archives using restore_command can be enabled
|
2016-02-26 20:22:53 +01:00
|
|
|
by passing the keyword parameter has_restoring => 1. This is disabled by
|
2016-02-26 20:13:30 +01:00
|
|
|
default.
|
|
|
|
|
2020-01-29 15:43:32 +01:00
|
|
|
If has_restoring is used, standby mode is used by default. To use
|
|
|
|
recovery mode instead, pass the keyword parameter standby => 0.
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
The backup is copied, leaving the original unmodified. pg_hba.conf is
|
|
|
|
unconditionally set to enable replication connections.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub init_from_backup
|
|
|
|
{
|
2016-02-26 17:24:22 +01:00
|
|
|
my ($self, $root_node, $backup_name, %params) = @_;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
my $backup_path = $root_node->backup_dir . '/' . $backup_name;
|
2019-04-13 07:36:38 +02:00
|
|
|
my $host = $self->host;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
my $port = $self->port;
|
2016-01-20 18:13:11 +01:00
|
|
|
my $node_name = $self->name;
|
|
|
|
my $root_name = $root_node->name;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2016-02-26 17:24:22 +01:00
|
|
|
$params{has_streaming} = 0 unless defined $params{has_streaming};
|
2016-02-26 20:13:30 +01:00
|
|
|
$params{has_restoring} = 0 unless defined $params{has_restoring};
|
2020-01-29 15:43:32 +01:00
|
|
|
$params{standby} = 1 unless defined $params{standby};
|
2016-02-26 20:13:30 +01:00
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
print
|
2018-04-26 17:52:52 +02:00
|
|
|
"# Initializing node \"$node_name\" from backup \"$backup_name\" of node \"$root_name\"\n";
|
2018-02-24 20:35:54 +01:00
|
|
|
croak "Backup \"$backup_name\" does not exist at $backup_path"
|
2016-01-20 18:13:11 +01:00
|
|
|
unless -d $backup_path;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
|
|
|
mkdir $self->backup_dir;
|
|
|
|
mkdir $self->archive_dir;
|
|
|
|
|
|
|
|
my $data_path = $self->data_dir;
|
Add end-to-end testing of pg_basebackup's tar-format output.
The existing test script does run pg_basebackup with the -Ft option,
but it makes no real attempt to verify the sanity of the results.
We wouldn't know if the output is incompatible with standard "tar"
programs, nor if the server fails to start from the restored output.
Notably, this means that xlog.c's read_tablespace_map() is not being
meaningfully tested, since that code is used only in the tar-format
case. (We do have reasonable coverage of restoring from plain-format
output, though it's over in src/test/recovery not here.)
Hence, attempt to untar the output and start a server from it,
rather just hoping it's OK.
This test assumes that the local "tar" has the "-C directory"
switch. Although that's not promised by POSIX, my research
suggests that all non-extinct tar implementations have it.
Should the buildfarm's opinion differ, we can complicate the
test a bit to avoid requiring that.
Possibly this should be back-patched, but I'm unsure about
whether it could work on Windows before d66b23b03.
2021-03-17 19:52:55 +01:00
|
|
|
if (defined $params{tar_program})
|
|
|
|
{
|
|
|
|
mkdir($data_path);
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::system_or_bail($params{tar_program}, 'xf',
|
Add end-to-end testing of pg_basebackup's tar-format output.
The existing test script does run pg_basebackup with the -Ft option,
but it makes no real attempt to verify the sanity of the results.
We wouldn't know if the output is incompatible with standard "tar"
programs, nor if the server fails to start from the restored output.
Notably, this means that xlog.c's read_tablespace_map() is not being
meaningfully tested, since that code is used only in the tar-format
case. (We do have reasonable coverage of restoring from plain-format
output, though it's over in src/test/recovery not here.)
Hence, attempt to untar the output and start a server from it,
rather just hoping it's OK.
This test assumes that the local "tar" has the "-C directory"
switch. Although that's not promised by POSIX, my research
suggests that all non-extinct tar implementations have it.
Should the buildfarm's opinion differ, we can complicate the
test a bit to avoid requiring that.
Possibly this should be back-patched, but I'm unsure about
whether it could work on Windows before d66b23b03.
2021-03-17 19:52:55 +01:00
|
|
|
$backup_path . '/base.tar',
|
|
|
|
'-C', $data_path);
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::system_or_bail(
|
Add end-to-end testing of pg_basebackup's tar-format output.
The existing test script does run pg_basebackup with the -Ft option,
but it makes no real attempt to verify the sanity of the results.
We wouldn't know if the output is incompatible with standard "tar"
programs, nor if the server fails to start from the restored output.
Notably, this means that xlog.c's read_tablespace_map() is not being
meaningfully tested, since that code is used only in the tar-format
case. (We do have reasonable coverage of restoring from plain-format
output, though it's over in src/test/recovery not here.)
Hence, attempt to untar the output and start a server from it,
rather just hoping it's OK.
This test assumes that the local "tar" has the "-C directory"
switch. Although that's not promised by POSIX, my research
suggests that all non-extinct tar implementations have it.
Should the buildfarm's opinion differ, we can complicate the
test a bit to avoid requiring that.
Possibly this should be back-patched, but I'm unsure about
whether it could work on Windows before d66b23b03.
2021-03-17 19:52:55 +01:00
|
|
|
$params{tar_program}, 'xf',
|
|
|
|
$backup_path . '/pg_wal.tar', '-C',
|
|
|
|
$data_path . '/pg_wal');
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rmdir($data_path);
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::RecursiveCopy::copypath($backup_path, $data_path);
|
Add end-to-end testing of pg_basebackup's tar-format output.
The existing test script does run pg_basebackup with the -Ft option,
but it makes no real attempt to verify the sanity of the results.
We wouldn't know if the output is incompatible with standard "tar"
programs, nor if the server fails to start from the restored output.
Notably, this means that xlog.c's read_tablespace_map() is not being
meaningfully tested, since that code is used only in the tar-format
case. (We do have reasonable coverage of restoring from plain-format
output, though it's over in src/test/recovery not here.)
Hence, attempt to untar the output and start a server from it,
rather just hoping it's OK.
This test assumes that the local "tar" has the "-C directory"
switch. Although that's not promised by POSIX, my research
suggests that all non-extinct tar implementations have it.
Should the buildfarm's opinion differ, we can complicate the
test a bit to avoid requiring that.
Possibly this should be back-patched, but I'm unsure about
whether it could work on Windows before d66b23b03.
2021-03-17 19:52:55 +01:00
|
|
|
}
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
chmod(0700, $data_path);
|
|
|
|
|
|
|
|
# Base configuration for this node
|
|
|
|
$self->append_conf(
|
|
|
|
'postgresql.conf',
|
|
|
|
qq(
|
|
|
|
port = $port
|
|
|
|
));
|
2019-04-13 07:36:38 +02:00
|
|
|
if ($use_tcp)
|
|
|
|
{
|
|
|
|
$self->append_conf('postgresql.conf', "listen_addresses = '$host'");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$self->append_conf('postgresql.conf',
|
|
|
|
"unix_socket_directories = '$host'");
|
|
|
|
}
|
2016-02-26 17:24:22 +01:00
|
|
|
$self->enable_streaming($root_node) if $params{has_streaming};
|
2020-01-29 15:43:32 +01:00
|
|
|
$self->enable_restoring($root_node, $params{standby})
|
|
|
|
if $params{has_restoring};
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
2019-04-13 07:36:38 +02:00
|
|
|
=item $node->rotate_logfile()
|
|
|
|
|
|
|
|
Switch to a new PostgreSQL log file. This does not alter any running
|
|
|
|
PostgreSQL process. Subsequent method calls, including pg_ctl invocations,
|
|
|
|
will use the new name. Return the new name.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub rotate_logfile
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
$self->{_logfile} = sprintf('%s_%d.log',
|
|
|
|
$self->{_logfile_base},
|
|
|
|
++$self->{_logfile_generation});
|
|
|
|
return $self->{_logfile};
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->start(%params) => success_or_failure
|
2016-02-26 01:31:52 +01:00
|
|
|
|
2017-01-13 18:00:00 +01:00
|
|
|
Wrapper for pg_ctl start
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
Start the node and wait until it is ready to accept connections.
|
|
|
|
|
2019-04-13 07:36:38 +02:00
|
|
|
=over
|
|
|
|
|
|
|
|
=item fail_ok => 1
|
|
|
|
|
|
|
|
By default, failure terminates the entire F<prove> invocation. If given,
|
|
|
|
instead return a true or false value to indicate success or failure.
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub start
|
|
|
|
{
|
2019-04-13 07:36:38 +02:00
|
|
|
my ($self, %params) = @_;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
my $port = $self->port;
|
|
|
|
my $pgdata = $self->data_dir;
|
2016-01-20 18:13:11 +01:00
|
|
|
my $name = $self->name;
|
2019-03-15 21:24:05 +01:00
|
|
|
my $ret;
|
|
|
|
|
Make PostgresNode.pm check server status more carefully.
PostgresNode blithely ignored the exit status of pg_ctl, and in general
made no effort to be sure that the server was running when it should be.
This caused it to miss server crashes, which is a serious shortcoming
in a test scaffold. Make it complain if pg_ctl fails, and modify the
start and stop logic to complain if the server doesn't start, or doesn't
stop, when expected.
Also, have it turn off the "restart_after_crash" configuration parameter
in created clusters, as bitter experience has shown that leaving that on
can mask crashes too.
We might at some point need variant functions that allow for, eg,
server start failure to be expected. But no existing test case appears
to want that, and it surely shouldn't be the default behavior.
Note that this *will* break the buildfarm, as it will expose known
bugs that the previous testing failed to. I'm committing it despite
that, to verify that we get the expected failures in the buildfarm
not just in manual testing.
Back-patch into 9.6 where PostgresNode was introduced. (The 9.6
branch is not expected to show any failures.)
Discussion: https://postgr.es/m/21432.1492886428@sss.pgh.pa.us
2017-04-23 00:18:25 +02:00
|
|
|
BAIL_OUT("node \"$name\" is already running") if defined $self->{_pid};
|
2019-03-15 21:24:05 +01:00
|
|
|
|
2016-01-20 18:13:11 +01:00
|
|
|
print("### Starting node \"$name\"\n");
|
2019-03-15 21:24:05 +01:00
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
# Temporarily unset PGAPPNAME so that the server doesn't
|
|
|
|
# inherit it. Otherwise this could affect libpqwalreceiver
|
|
|
|
# connections in confusing ways.
|
|
|
|
local %ENV = $self->_get_env(PGAPPNAME => undef);
|
|
|
|
|
|
|
|
# Note: We set the cluster_name here, not in postgresql.conf (in
|
|
|
|
# sub init) so that it does not get copied to standbys.
|
2021-07-29 11:58:06 +02:00
|
|
|
# -w is now the default but having it here does no harm and helps
|
|
|
|
# compatibility with older versions.
|
2021-10-24 16:28:19 +02:00
|
|
|
$ret = PostgreSQL::Test::Utils::system_log(
|
|
|
|
'pg_ctl', '-w', '-D', $self->data_dir,
|
2021-03-24 23:52:25 +01:00
|
|
|
'-l', $self->logfile, '-o', "--cluster-name=$name",
|
|
|
|
'start');
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
|
|
|
if ($ret != 0)
|
|
|
|
{
|
Make PostgresNode.pm check server status more carefully.
PostgresNode blithely ignored the exit status of pg_ctl, and in general
made no effort to be sure that the server was running when it should be.
This caused it to miss server crashes, which is a serious shortcoming
in a test scaffold. Make it complain if pg_ctl fails, and modify the
start and stop logic to complain if the server doesn't start, or doesn't
stop, when expected.
Also, have it turn off the "restart_after_crash" configuration parameter
in created clusters, as bitter experience has shown that leaving that on
can mask crashes too.
We might at some point need variant functions that allow for, eg,
server start failure to be expected. But no existing test case appears
to want that, and it surely shouldn't be the default behavior.
Note that this *will* break the buildfarm, as it will expose known
bugs that the previous testing failed to. I'm committing it despite
that, to verify that we get the expected failures in the buildfarm
not just in manual testing.
Back-patch into 9.6 where PostgresNode was introduced. (The 9.6
branch is not expected to show any failures.)
Discussion: https://postgr.es/m/21432.1492886428@sss.pgh.pa.us
2017-04-23 00:18:25 +02:00
|
|
|
print "# pg_ctl start failed; logfile:\n";
|
2021-10-24 16:28:19 +02:00
|
|
|
print PostgreSQL::Test::Utils::slurp_file($self->logfile);
|
2022-01-19 22:29:09 +01:00
|
|
|
|
|
|
|
# pg_ctl could have timed out, so check to see if there's a pid file;
|
|
|
|
# otherwise our END block will fail to shut down the new postmaster.
|
|
|
|
$self->_update_pid(-1);
|
|
|
|
|
2019-04-13 07:36:38 +02:00
|
|
|
BAIL_OUT("pg_ctl start failed") unless $params{fail_ok};
|
|
|
|
return 0;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
Make PostgresNode.pm check server status more carefully.
PostgresNode blithely ignored the exit status of pg_ctl, and in general
made no effort to be sure that the server was running when it should be.
This caused it to miss server crashes, which is a serious shortcoming
in a test scaffold. Make it complain if pg_ctl fails, and modify the
start and stop logic to complain if the server doesn't start, or doesn't
stop, when expected.
Also, have it turn off the "restart_after_crash" configuration parameter
in created clusters, as bitter experience has shown that leaving that on
can mask crashes too.
We might at some point need variant functions that allow for, eg,
server start failure to be expected. But no existing test case appears
to want that, and it surely shouldn't be the default behavior.
Note that this *will* break the buildfarm, as it will expose known
bugs that the previous testing failed to. I'm committing it despite
that, to verify that we get the expected failures in the buildfarm
not just in manual testing.
Back-patch into 9.6 where PostgresNode was introduced. (The 9.6
branch is not expected to show any failures.)
Discussion: https://postgr.es/m/21432.1492886428@sss.pgh.pa.us
2017-04-23 00:18:25 +02:00
|
|
|
$self->_update_pid(1);
|
2019-04-13 07:36:38 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->kill9()
|
|
|
|
|
|
|
|
Send SIGKILL (signal 9) to the postmaster.
|
|
|
|
|
|
|
|
Note: if the node is already known stopped, this does nothing.
|
|
|
|
However, if we think it's running and it's not, it's important for
|
|
|
|
this to fail. Otherwise, tests might fail to detect server crashes.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub kill9
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
my $name = $self->name;
|
|
|
|
return unless defined $self->{_pid};
|
2021-03-24 23:52:25 +01:00
|
|
|
|
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
2019-04-13 07:36:38 +02:00
|
|
|
print "### Killing node \"$name\" using signal 9\n";
|
2022-02-20 17:47:56 +01:00
|
|
|
kill(9, $self->{_pid});
|
2019-04-13 07:36:38 +02:00
|
|
|
$self->{_pid} = undef;
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->stop(mode)
|
|
|
|
|
|
|
|
Stop the node using pg_ctl -m $mode and wait for it to stop.
|
|
|
|
|
Make PostgresNode.pm check server status more carefully.
PostgresNode blithely ignored the exit status of pg_ctl, and in general
made no effort to be sure that the server was running when it should be.
This caused it to miss server crashes, which is a serious shortcoming
in a test scaffold. Make it complain if pg_ctl fails, and modify the
start and stop logic to complain if the server doesn't start, or doesn't
stop, when expected.
Also, have it turn off the "restart_after_crash" configuration parameter
in created clusters, as bitter experience has shown that leaving that on
can mask crashes too.
We might at some point need variant functions that allow for, eg,
server start failure to be expected. But no existing test case appears
to want that, and it surely shouldn't be the default behavior.
Note that this *will* break the buildfarm, as it will expose known
bugs that the previous testing failed to. I'm committing it despite
that, to verify that we get the expected failures in the buildfarm
not just in manual testing.
Back-patch into 9.6 where PostgresNode was introduced. (The 9.6
branch is not expected to show any failures.)
Discussion: https://postgr.es/m/21432.1492886428@sss.pgh.pa.us
2017-04-23 00:18:25 +02:00
|
|
|
Note: if the node is already known stopped, this does nothing.
|
|
|
|
However, if we think it's running and it's not, it's important for
|
|
|
|
this to fail. Otherwise, tests might fail to detect server crashes.
|
|
|
|
|
2022-01-20 23:28:07 +01:00
|
|
|
With optional extra param fail_ok => 1, returns 0 for failure
|
|
|
|
instead of bailing out.
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub stop
|
|
|
|
{
|
2022-01-20 23:28:07 +01:00
|
|
|
my ($self, $mode, %params) = @_;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
my $pgdata = $self->data_dir;
|
2016-01-20 18:13:11 +01:00
|
|
|
my $name = $self->name;
|
2022-01-20 23:28:07 +01:00
|
|
|
my $ret;
|
2021-03-24 23:52:25 +01:00
|
|
|
|
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
2016-02-26 17:24:22 +01:00
|
|
|
$mode = 'fast' unless defined $mode;
|
2022-01-20 23:28:07 +01:00
|
|
|
return 1 unless defined $self->{_pid};
|
|
|
|
|
2016-01-20 18:13:11 +01:00
|
|
|
print "### Stopping node \"$name\" using mode $mode\n";
|
2022-01-20 23:28:07 +01:00
|
|
|
$ret = PostgreSQL::Test::Utils::system_log('pg_ctl', '-D', $pgdata,
|
|
|
|
'-m', $mode, 'stop');
|
|
|
|
|
|
|
|
if ($ret != 0)
|
|
|
|
{
|
|
|
|
print "# pg_ctl stop failed: $ret\n";
|
|
|
|
|
|
|
|
# Check to see if we still have a postmaster or not.
|
|
|
|
$self->_update_pid(-1);
|
|
|
|
|
|
|
|
BAIL_OUT("pg_ctl stop failed") unless $params{fail_ok};
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Make PostgresNode.pm check server status more carefully.
PostgresNode blithely ignored the exit status of pg_ctl, and in general
made no effort to be sure that the server was running when it should be.
This caused it to miss server crashes, which is a serious shortcoming
in a test scaffold. Make it complain if pg_ctl fails, and modify the
start and stop logic to complain if the server doesn't start, or doesn't
stop, when expected.
Also, have it turn off the "restart_after_crash" configuration parameter
in created clusters, as bitter experience has shown that leaving that on
can mask crashes too.
We might at some point need variant functions that allow for, eg,
server start failure to be expected. But no existing test case appears
to want that, and it surely shouldn't be the default behavior.
Note that this *will* break the buildfarm, as it will expose known
bugs that the previous testing failed to. I'm committing it despite
that, to verify that we get the expected failures in the buildfarm
not just in manual testing.
Back-patch into 9.6 where PostgresNode was introduced. (The 9.6
branch is not expected to show any failures.)
Discussion: https://postgr.es/m/21432.1492886428@sss.pgh.pa.us
2017-04-23 00:18:25 +02:00
|
|
|
$self->_update_pid(0);
|
2022-01-20 23:28:07 +01:00
|
|
|
return 1;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
2016-04-08 09:48:53 +02:00
|
|
|
=item $node->reload()
|
|
|
|
|
|
|
|
Reload configuration parameters on the node.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub reload
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
my $port = $self->port;
|
|
|
|
my $pgdata = $self->data_dir;
|
|
|
|
my $name = $self->name;
|
2021-03-24 23:52:25 +01:00
|
|
|
|
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
2016-04-08 09:48:53 +02:00
|
|
|
print "### Reloading node \"$name\"\n";
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::system_or_bail('pg_ctl', '-D', $pgdata,
|
|
|
|
'reload');
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
2016-04-08 09:48:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=item $node->restart()
|
|
|
|
|
2017-01-13 18:00:00 +01:00
|
|
|
Wrapper for pg_ctl restart
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub restart
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
my $port = $self->port;
|
|
|
|
my $pgdata = $self->data_dir;
|
|
|
|
my $logfile = $self->logfile;
|
2016-01-20 18:13:11 +01:00
|
|
|
my $name = $self->name;
|
2019-03-15 21:24:05 +01:00
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
local %ENV = $self->_get_env(PGAPPNAME => undef);
|
2019-03-15 21:24:05 +01:00
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
print "### Restarting node \"$name\"\n";
|
2019-03-15 21:24:05 +01:00
|
|
|
|
2021-07-29 11:58:06 +02:00
|
|
|
# -w is now the default but having it here does no harm and helps
|
|
|
|
# compatibility with older versions.
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::system_or_bail('pg_ctl', '-w', '-D', $pgdata,
|
|
|
|
'-l', $logfile, 'restart');
|
2019-03-15 21:24:05 +01:00
|
|
|
|
Make PostgresNode.pm check server status more carefully.
PostgresNode blithely ignored the exit status of pg_ctl, and in general
made no effort to be sure that the server was running when it should be.
This caused it to miss server crashes, which is a serious shortcoming
in a test scaffold. Make it complain if pg_ctl fails, and modify the
start and stop logic to complain if the server doesn't start, or doesn't
stop, when expected.
Also, have it turn off the "restart_after_crash" configuration parameter
in created clusters, as bitter experience has shown that leaving that on
can mask crashes too.
We might at some point need variant functions that allow for, eg,
server start failure to be expected. But no existing test case appears
to want that, and it surely shouldn't be the default behavior.
Note that this *will* break the buildfarm, as it will expose known
bugs that the previous testing failed to. I'm committing it despite
that, to verify that we get the expected failures in the buildfarm
not just in manual testing.
Back-patch into 9.6 where PostgresNode was introduced. (The 9.6
branch is not expected to show any failures.)
Discussion: https://postgr.es/m/21432.1492886428@sss.pgh.pa.us
2017-04-23 00:18:25 +02:00
|
|
|
$self->_update_pid(1);
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 17:24:22 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->promote()
|
|
|
|
|
2017-01-13 18:00:00 +01:00
|
|
|
Wrapper for pg_ctl promote
|
2016-02-26 17:24:22 +01:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub promote
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
my $port = $self->port;
|
|
|
|
my $pgdata = $self->data_dir;
|
|
|
|
my $logfile = $self->logfile;
|
|
|
|
my $name = $self->name;
|
2021-03-24 23:52:25 +01:00
|
|
|
|
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
2016-02-26 17:24:22 +01:00
|
|
|
print "### Promoting node \"$name\"\n";
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::system_or_bail('pg_ctl', '-D', $pgdata, '-l',
|
Make PostgresNode.pm check server status more carefully.
PostgresNode blithely ignored the exit status of pg_ctl, and in general
made no effort to be sure that the server was running when it should be.
This caused it to miss server crashes, which is a serious shortcoming
in a test scaffold. Make it complain if pg_ctl fails, and modify the
start and stop logic to complain if the server doesn't start, or doesn't
stop, when expected.
Also, have it turn off the "restart_after_crash" configuration parameter
in created clusters, as bitter experience has shown that leaving that on
can mask crashes too.
We might at some point need variant functions that allow for, eg,
server start failure to be expected. But no existing test case appears
to want that, and it surely shouldn't be the default behavior.
Note that this *will* break the buildfarm, as it will expose known
bugs that the previous testing failed to. I'm committing it despite
that, to verify that we get the expected failures in the buildfarm
not just in manual testing.
Back-patch into 9.6 where PostgresNode was introduced. (The 9.6
branch is not expected to show any failures.)
Discussion: https://postgr.es/m/21432.1492886428@sss.pgh.pa.us
2017-04-23 00:18:25 +02:00
|
|
|
$logfile, 'promote');
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
2016-02-26 17:24:22 +01:00
|
|
|
}
|
|
|
|
|
2018-09-01 18:46:49 +02:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->logrotate()
|
|
|
|
|
|
|
|
Wrapper for pg_ctl logrotate
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub logrotate
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
my $port = $self->port;
|
|
|
|
my $pgdata = $self->data_dir;
|
|
|
|
my $logfile = $self->logfile;
|
|
|
|
my $name = $self->name;
|
2021-03-24 23:52:25 +01:00
|
|
|
|
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
2018-09-01 18:46:49 +02:00
|
|
|
print "### Rotating log in node \"$name\"\n";
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::system_or_bail('pg_ctl', '-D', $pgdata, '-l',
|
2018-09-01 18:46:49 +02:00
|
|
|
$logfile, 'logrotate');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-02-26 17:24:22 +01:00
|
|
|
# Internal routine to enable streaming replication on a standby node.
|
|
|
|
sub enable_streaming
|
|
|
|
{
|
2016-03-03 17:20:46 +01:00
|
|
|
my ($self, $root_node) = @_;
|
2016-02-26 17:24:22 +01:00
|
|
|
my $root_connstr = $root_node->connstr;
|
2016-03-03 17:20:46 +01:00
|
|
|
my $name = $self->name;
|
2016-02-26 17:24:22 +01:00
|
|
|
|
|
|
|
print "### Enabling streaming replication for node \"$name\"\n";
|
2016-03-03 17:20:46 +01:00
|
|
|
$self->append_conf(
|
2022-03-30 17:07:05 +02:00
|
|
|
$self->_recovery_file, qq(
|
2019-03-15 21:24:05 +01:00
|
|
|
primary_conninfo='$root_connstr'
|
2016-02-26 17:24:22 +01:00
|
|
|
));
|
2018-11-25 16:31:16 +01:00
|
|
|
$self->set_standby_mode();
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
2016-02-26 17:24:22 +01:00
|
|
|
}
|
2016-02-26 01:31:52 +01:00
|
|
|
|
2016-02-26 20:13:30 +01:00
|
|
|
# Internal routine to enable archive recovery command on a standby node
|
|
|
|
sub enable_restoring
|
|
|
|
{
|
2020-01-29 15:43:32 +01:00
|
|
|
my ($self, $root_node, $standby) = @_;
|
2022-02-18 23:00:03 +01:00
|
|
|
my $path = $root_node->archive_dir;
|
2016-02-26 20:13:30 +01:00
|
|
|
my $name = $self->name;
|
|
|
|
|
|
|
|
print "### Enabling WAL restore for node \"$name\"\n";
|
|
|
|
|
|
|
|
# On Windows, the path specified in the restore command needs to use
|
|
|
|
# double back-slashes to work properly and to be able to detect properly
|
|
|
|
# the file targeted by the copy command, so the directory value used
|
|
|
|
# in this routine, using only one back-slash, need to be properly changed
|
|
|
|
# first. Paths also need to be double-quoted to prevent failures where
|
|
|
|
# the path contains spaces.
|
2021-10-24 16:28:19 +02:00
|
|
|
$path =~ s{\\}{\\\\}g if ($PostgreSQL::Test::Utils::windows_os);
|
2016-03-03 17:20:46 +01:00
|
|
|
my $copy_command =
|
2021-10-24 16:28:19 +02:00
|
|
|
$PostgreSQL::Test::Utils::windows_os
|
2016-03-03 17:20:46 +01:00
|
|
|
? qq{copy "$path\\\\%f" "%p"}
|
2016-07-09 22:47:38 +02:00
|
|
|
: qq{cp "$path/%f" "%p"};
|
2016-02-26 20:13:30 +01:00
|
|
|
|
2016-03-03 17:20:46 +01:00
|
|
|
$self->append_conf(
|
2022-03-30 17:07:05 +02:00
|
|
|
$self->_recovery_file, qq(
|
2016-02-26 20:13:30 +01:00
|
|
|
restore_command = '$copy_command'
|
|
|
|
));
|
2020-01-29 15:43:32 +01:00
|
|
|
if ($standby)
|
|
|
|
{
|
|
|
|
$self->set_standby_mode();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$self->set_recovery_mode();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-03-30 17:07:05 +02:00
|
|
|
sub _recovery_file { return "postgresql.conf"; }
|
|
|
|
|
2020-01-29 15:43:32 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->set_recovery_mode()
|
|
|
|
|
|
|
|
Place recovery.signal file.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub set_recovery_mode
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
|
|
|
|
$self->append_conf('recovery.signal', '');
|
2018-11-25 16:31:16 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->set_standby_mode()
|
|
|
|
|
|
|
|
Place standby.signal file.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub set_standby_mode
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
|
|
|
|
$self->append_conf('standby.signal', '');
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
2016-02-26 20:13:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Internal routine to enable archiving
|
|
|
|
sub enable_archiving
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
2022-02-18 23:00:03 +01:00
|
|
|
my $path = $self->archive_dir;
|
2016-02-26 20:13:30 +01:00
|
|
|
my $name = $self->name;
|
|
|
|
|
|
|
|
print "### Enabling WAL archiving for node \"$name\"\n";
|
|
|
|
|
|
|
|
# On Windows, the path specified in the restore command needs to use
|
|
|
|
# double back-slashes to work properly and to be able to detect properly
|
|
|
|
# the file targeted by the copy command, so the directory value used
|
|
|
|
# in this routine, using only one back-slash, need to be properly changed
|
|
|
|
# first. Paths also need to be double-quoted to prevent failures where
|
|
|
|
# the path contains spaces.
|
2021-10-24 16:28:19 +02:00
|
|
|
$path =~ s{\\}{\\\\}g if ($PostgreSQL::Test::Utils::windows_os);
|
2016-03-03 17:20:46 +01:00
|
|
|
my $copy_command =
|
2021-10-24 16:28:19 +02:00
|
|
|
$PostgreSQL::Test::Utils::windows_os
|
2016-03-03 17:20:46 +01:00
|
|
|
? qq{copy "%p" "$path\\\\%f"}
|
2016-07-09 22:47:38 +02:00
|
|
|
: qq{cp "%p" "$path/%f"};
|
2016-02-26 20:13:30 +01:00
|
|
|
|
|
|
|
# Enable archive_mode and archive_command on node
|
2016-03-03 17:20:46 +01:00
|
|
|
$self->append_conf(
|
|
|
|
'postgresql.conf', qq(
|
2016-02-26 20:13:30 +01:00
|
|
|
archive_mode = on
|
|
|
|
archive_command = '$copy_command'
|
|
|
|
));
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
2016-02-26 20:13:30 +01:00
|
|
|
}
|
|
|
|
|
2022-01-19 22:29:09 +01:00
|
|
|
# Internal method to update $self->{_pid}
|
|
|
|
# $is_running = 1: pid file should be there
|
|
|
|
# $is_running = 0: pid file should NOT be there
|
|
|
|
# $is_running = -1: we aren't sure
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub _update_pid
|
|
|
|
{
|
Make PostgresNode.pm check server status more carefully.
PostgresNode blithely ignored the exit status of pg_ctl, and in general
made no effort to be sure that the server was running when it should be.
This caused it to miss server crashes, which is a serious shortcoming
in a test scaffold. Make it complain if pg_ctl fails, and modify the
start and stop logic to complain if the server doesn't start, or doesn't
stop, when expected.
Also, have it turn off the "restart_after_crash" configuration parameter
in created clusters, as bitter experience has shown that leaving that on
can mask crashes too.
We might at some point need variant functions that allow for, eg,
server start failure to be expected. But no existing test case appears
to want that, and it surely shouldn't be the default behavior.
Note that this *will* break the buildfarm, as it will expose known
bugs that the previous testing failed to. I'm committing it despite
that, to verify that we get the expected failures in the buildfarm
not just in manual testing.
Back-patch into 9.6 where PostgresNode was introduced. (The 9.6
branch is not expected to show any failures.)
Discussion: https://postgr.es/m/21432.1492886428@sss.pgh.pa.us
2017-04-23 00:18:25 +02:00
|
|
|
my ($self, $is_running) = @_;
|
2016-01-20 18:13:11 +01:00
|
|
|
my $name = $self->name;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
|
|
|
# If we can open the PID file, read its first line and that's the PID we
|
Make PostgresNode.pm check server status more carefully.
PostgresNode blithely ignored the exit status of pg_ctl, and in general
made no effort to be sure that the server was running when it should be.
This caused it to miss server crashes, which is a serious shortcoming
in a test scaffold. Make it complain if pg_ctl fails, and modify the
start and stop logic to complain if the server doesn't start, or doesn't
stop, when expected.
Also, have it turn off the "restart_after_crash" configuration parameter
in created clusters, as bitter experience has shown that leaving that on
can mask crashes too.
We might at some point need variant functions that allow for, eg,
server start failure to be expected. But no existing test case appears
to want that, and it surely shouldn't be the default behavior.
Note that this *will* break the buildfarm, as it will expose known
bugs that the previous testing failed to. I'm committing it despite
that, to verify that we get the expected failures in the buildfarm
not just in manual testing.
Back-patch into 9.6 where PostgresNode was introduced. (The 9.6
branch is not expected to show any failures.)
Discussion: https://postgr.es/m/21432.1492886428@sss.pgh.pa.us
2017-04-23 00:18:25 +02:00
|
|
|
# want.
|
2017-03-27 04:24:13 +02:00
|
|
|
if (open my $pidfile, '<', $self->data_dir . "/postmaster.pid")
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
{
|
2015-12-07 23:25:31 +01:00
|
|
|
chomp($self->{_pid} = <$pidfile>);
|
|
|
|
close $pidfile;
|
Make PostgresNode.pm check server status more carefully.
PostgresNode blithely ignored the exit status of pg_ctl, and in general
made no effort to be sure that the server was running when it should be.
This caused it to miss server crashes, which is a serious shortcoming
in a test scaffold. Make it complain if pg_ctl fails, and modify the
start and stop logic to complain if the server doesn't start, or doesn't
stop, when expected.
Also, have it turn off the "restart_after_crash" configuration parameter
in created clusters, as bitter experience has shown that leaving that on
can mask crashes too.
We might at some point need variant functions that allow for, eg,
server start failure to be expected. But no existing test case appears
to want that, and it surely shouldn't be the default behavior.
Note that this *will* break the buildfarm, as it will expose known
bugs that the previous testing failed to. I'm committing it despite
that, to verify that we get the expected failures in the buildfarm
not just in manual testing.
Back-patch into 9.6 where PostgresNode was introduced. (The 9.6
branch is not expected to show any failures.)
Discussion: https://postgr.es/m/21432.1492886428@sss.pgh.pa.us
2017-04-23 00:18:25 +02:00
|
|
|
|
2022-01-20 23:28:07 +01:00
|
|
|
# If we aren't sure what to expect, validate the PID using kill().
|
|
|
|
# This protects against stale PID files left by crashed postmasters.
|
|
|
|
if ($is_running == -1 && kill(0, $self->{_pid}) == 0)
|
|
|
|
{
|
|
|
|
print
|
|
|
|
"# Stale postmaster.pid file for node \"$name\": PID $self->{_pid} no longer exists\n";
|
|
|
|
$self->{_pid} = undef;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
print "# Postmaster PID for node \"$name\" is $self->{_pid}\n";
|
|
|
|
|
Make PostgresNode.pm check server status more carefully.
PostgresNode blithely ignored the exit status of pg_ctl, and in general
made no effort to be sure that the server was running when it should be.
This caused it to miss server crashes, which is a serious shortcoming
in a test scaffold. Make it complain if pg_ctl fails, and modify the
start and stop logic to complain if the server doesn't start, or doesn't
stop, when expected.
Also, have it turn off the "restart_after_crash" configuration parameter
in created clusters, as bitter experience has shown that leaving that on
can mask crashes too.
We might at some point need variant functions that allow for, eg,
server start failure to be expected. But no existing test case appears
to want that, and it surely shouldn't be the default behavior.
Note that this *will* break the buildfarm, as it will expose known
bugs that the previous testing failed to. I'm committing it despite
that, to verify that we get the expected failures in the buildfarm
not just in manual testing.
Back-patch into 9.6 where PostgresNode was introduced. (The 9.6
branch is not expected to show any failures.)
Discussion: https://postgr.es/m/21432.1492886428@sss.pgh.pa.us
2017-04-23 00:18:25 +02:00
|
|
|
# If we found a pidfile when there shouldn't be one, complain.
|
2022-01-19 22:29:09 +01:00
|
|
|
BAIL_OUT("postmaster.pid unexpectedly present") if $is_running == 0;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-12-07 23:25:31 +01:00
|
|
|
$self->{_pid} = undef;
|
Make PostgresNode.pm check server status more carefully.
PostgresNode blithely ignored the exit status of pg_ctl, and in general
made no effort to be sure that the server was running when it should be.
This caused it to miss server crashes, which is a serious shortcoming
in a test scaffold. Make it complain if pg_ctl fails, and modify the
start and stop logic to complain if the server doesn't start, or doesn't
stop, when expected.
Also, have it turn off the "restart_after_crash" configuration parameter
in created clusters, as bitter experience has shown that leaving that on
can mask crashes too.
We might at some point need variant functions that allow for, eg,
server start failure to be expected. But no existing test case appears
to want that, and it surely shouldn't be the default behavior.
Note that this *will* break the buildfarm, as it will expose known
bugs that the previous testing failed to. I'm committing it despite
that, to verify that we get the expected failures in the buildfarm
not just in manual testing.
Back-patch into 9.6 where PostgresNode was introduced. (The 9.6
branch is not expected to show any failures.)
Discussion: https://postgr.es/m/21432.1492886428@sss.pgh.pa.us
2017-04-23 00:18:25 +02:00
|
|
|
print "# No postmaster PID for node \"$name\"\n";
|
2017-05-18 01:01:23 +02:00
|
|
|
|
Make PostgresNode.pm check server status more carefully.
PostgresNode blithely ignored the exit status of pg_ctl, and in general
made no effort to be sure that the server was running when it should be.
This caused it to miss server crashes, which is a serious shortcoming
in a test scaffold. Make it complain if pg_ctl fails, and modify the
start and stop logic to complain if the server doesn't start, or doesn't
stop, when expected.
Also, have it turn off the "restart_after_crash" configuration parameter
in created clusters, as bitter experience has shown that leaving that on
can mask crashes too.
We might at some point need variant functions that allow for, eg,
server start failure to be expected. But no existing test case appears
to want that, and it surely shouldn't be the default behavior.
Note that this *will* break the buildfarm, as it will expose known
bugs that the previous testing failed to. I'm committing it despite
that, to verify that we get the expected failures in the buildfarm
not just in manual testing.
Back-patch into 9.6 where PostgresNode was introduced. (The 9.6
branch is not expected to show any failures.)
Discussion: https://postgr.es/m/21432.1492886428@sss.pgh.pa.us
2017-04-23 00:18:25 +02:00
|
|
|
# Complain if we expected to find a pidfile.
|
2022-01-19 22:29:09 +01:00
|
|
|
BAIL_OUT("postmaster.pid unexpectedly not present") if $is_running == 1;
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
=item PostgreSQL::Test::Cluster->new(node_name, %params)
|
2016-02-26 01:31:52 +01:00
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
Build a new object of class C<PostgreSQL::Test::Cluster> (or of a subclass, if you have
|
2017-07-26 00:39:44 +02:00
|
|
|
one), assigning a free port number. Remembers the node, to prevent its port
|
|
|
|
number from being reused for another node, and to ensure that it gets
|
|
|
|
shut down when the test script exits.
|
2016-02-26 01:31:52 +01:00
|
|
|
|
2019-04-13 07:36:38 +02:00
|
|
|
=over
|
|
|
|
|
|
|
|
=item port => [1,65535]
|
|
|
|
|
|
|
|
By default, this function assigns a port number to each node. Specify this to
|
|
|
|
force a particular port number. The caller is responsible for evaluating
|
|
|
|
potential conflicts and privilege requirements.
|
|
|
|
|
|
|
|
=item own_host => 1
|
|
|
|
|
|
|
|
By default, all nodes use the same PGHOST value. If specified, generate a
|
|
|
|
PGHOST specific to this node. This allows multiple nodes to use the same
|
|
|
|
port.
|
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
=item install_path => '/path/to/postgres/installation'
|
|
|
|
|
|
|
|
Using this parameter is it possible to have nodes pointing to different
|
|
|
|
installations, for testing different versions together or the same version
|
|
|
|
with different build parameters. The provided path must be the parent of the
|
|
|
|
installation's 'bin' and 'lib' directories. In the common case where this is
|
|
|
|
not provided, Postgres binaries will be found in the caller's PATH.
|
|
|
|
|
2019-04-13 07:36:38 +02:00
|
|
|
=back
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=cut
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2021-07-29 11:58:08 +02:00
|
|
|
sub new
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
{
|
2021-07-29 11:58:08 +02:00
|
|
|
my $class = shift;
|
2019-04-13 07:36:38 +02:00
|
|
|
my ($name, %params) = @_;
|
2019-08-04 19:07:12 +02:00
|
|
|
|
|
|
|
# Select a port.
|
|
|
|
my $port;
|
|
|
|
if (defined $params{port})
|
|
|
|
{
|
|
|
|
$port = $params{port};
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
# When selecting a port, we look for an unassigned TCP port number,
|
|
|
|
# even if we intend to use only Unix-domain sockets. This is clearly
|
|
|
|
# necessary on $use_tcp (Windows) configurations, and it seems like a
|
|
|
|
# good idea on Unixen as well.
|
|
|
|
$port = get_free_port();
|
|
|
|
}
|
|
|
|
|
|
|
|
# Select a host.
|
|
|
|
my $host = $test_pghost;
|
|
|
|
if ($params{own_host})
|
|
|
|
{
|
|
|
|
if ($use_tcp)
|
|
|
|
{
|
|
|
|
$last_host_assigned++;
|
|
|
|
$last_host_assigned > 254 and BAIL_OUT("too many own_host nodes");
|
|
|
|
$host = '127.0.0.' . $last_host_assigned;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$host = "$test_pghost/$name"; # Assume $name =~ /^[-_a-zA-Z0-9]+$/
|
|
|
|
mkdir $host;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-29 11:58:08 +02:00
|
|
|
my $testname = basename($0);
|
|
|
|
$testname =~ s/\.[^.]+$//;
|
|
|
|
my $node = {
|
|
|
|
_port => $port,
|
|
|
|
_host => $host,
|
2021-10-24 16:28:19 +02:00
|
|
|
_basedir =>
|
|
|
|
"$PostgreSQL::Test::Utils::tmp_check/t_${testname}_${name}_data",
|
2021-07-29 11:58:08 +02:00
|
|
|
_name => $name,
|
|
|
|
_logfile_generation => 0,
|
2021-10-24 16:28:19 +02:00
|
|
|
_logfile_base =>
|
|
|
|
"$PostgreSQL::Test::Utils::log_path/${testname}_${name}",
|
|
|
|
_logfile =>
|
|
|
|
"$PostgreSQL::Test::Utils::log_path/${testname}_${name}.log"
|
2021-07-29 11:58:08 +02:00
|
|
|
};
|
2019-08-04 19:07:12 +02:00
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
if ($params{install_path})
|
|
|
|
{
|
|
|
|
$node->{_install_path} = $params{install_path};
|
|
|
|
}
|
|
|
|
|
2021-07-29 11:58:08 +02:00
|
|
|
bless $node, $class;
|
|
|
|
mkdir $node->{_basedir}
|
|
|
|
or
|
|
|
|
BAIL_OUT("could not create data directory \"$node->{_basedir}\": $!");
|
|
|
|
|
|
|
|
$node->dump_info;
|
|
|
|
|
2021-04-22 16:56:28 +02:00
|
|
|
$node->_set_pg_version;
|
|
|
|
|
2022-03-30 17:07:05 +02:00
|
|
|
my $ver = $node->{_pg_version};
|
2021-04-22 16:56:28 +02:00
|
|
|
|
2022-03-30 17:07:05 +02:00
|
|
|
# Use a subclass as defined below (or elsewhere) if this version
|
|
|
|
# isn't fully compatible. Warn if the version is too old and thus we don't
|
|
|
|
# have a subclass of this class.
|
|
|
|
if (ref $ver && $ver < $min_compat)
|
|
|
|
{
|
|
|
|
my $maj = $ver->major(separator => '_');
|
|
|
|
my $subclass = $class . "::V_$maj";
|
|
|
|
if ($subclass->isa($class))
|
|
|
|
{
|
|
|
|
bless $node, $subclass;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
carp
|
|
|
|
"PostgreSQL::Test::Cluster isn't fully compatible with version $ver";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Add node to list of nodes
|
|
|
|
push(@all_nodes, $node);
|
2021-04-22 16:56:28 +02:00
|
|
|
|
2019-08-04 19:07:12 +02:00
|
|
|
return $node;
|
|
|
|
}
|
|
|
|
|
2021-04-22 16:56:28 +02:00
|
|
|
# Private routine to run the pg_config binary found in our environment (or in
|
|
|
|
# our install_path, if we have one), and set the version from it
|
|
|
|
#
|
|
|
|
sub _set_pg_version
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
my $inst = $self->{_install_path};
|
|
|
|
my $pg_config = "pg_config";
|
2021-05-12 19:14:10 +02:00
|
|
|
|
2021-04-22 16:56:28 +02:00
|
|
|
if (defined $inst)
|
|
|
|
{
|
|
|
|
# If the _install_path is invalid, our PATH variables might find an
|
|
|
|
# unrelated pg_config executable elsewhere. Sanity check the
|
|
|
|
# directory.
|
|
|
|
BAIL_OUT("directory not found: $inst")
|
|
|
|
unless -d $inst;
|
2021-05-12 19:14:10 +02:00
|
|
|
|
2021-04-22 16:56:28 +02:00
|
|
|
# If the directory exists but is not the root of a postgresql
|
|
|
|
# installation, or if the user configured using
|
|
|
|
# --bindir=$SOMEWHERE_ELSE, we're not going to find pg_config, so
|
|
|
|
# complain about that, too.
|
|
|
|
$pg_config = "$inst/bin/pg_config";
|
|
|
|
BAIL_OUT("pg_config not found: $pg_config")
|
2021-10-15 18:56:29 +02:00
|
|
|
unless -e $pg_config
|
2021-10-24 16:28:19 +02:00
|
|
|
or ($PostgreSQL::Test::Utils::windows_os and -e "$pg_config.exe");
|
2021-04-22 16:56:28 +02:00
|
|
|
BAIL_OUT("pg_config not executable: $pg_config")
|
2021-10-24 16:28:19 +02:00
|
|
|
unless $PostgreSQL::Test::Utils::windows_os or -x $pg_config;
|
2021-05-12 19:14:10 +02:00
|
|
|
|
2021-04-22 16:56:28 +02:00
|
|
|
# Leave $pg_config install_path qualified, to be sure we get the right
|
|
|
|
# version information, below, or die trying
|
|
|
|
}
|
2021-05-12 19:14:10 +02:00
|
|
|
|
2021-04-22 16:56:28 +02:00
|
|
|
local %ENV = $self->_get_env();
|
2021-05-12 19:14:10 +02:00
|
|
|
|
2021-04-22 16:56:28 +02:00
|
|
|
# We only want the version field
|
2021-05-20 14:03:15 +02:00
|
|
|
my $version_line = qx{$pg_config --version};
|
|
|
|
BAIL_OUT("$pg_config failed: $!") if $?;
|
2021-05-12 19:14:10 +02:00
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
$self->{_pg_version} = PostgreSQL::Version->new($version_line);
|
2021-05-12 19:14:10 +02:00
|
|
|
|
2021-04-22 16:56:28 +02:00
|
|
|
BAIL_OUT("could not parse pg_config --version output: $version_line")
|
|
|
|
unless defined $self->{_pg_version};
|
|
|
|
}
|
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
# Private routine to return a copy of the environment with the PATH and
|
|
|
|
# (DY)LD_LIBRARY_PATH correctly set when there is an install path set for
|
|
|
|
# the node.
|
|
|
|
#
|
|
|
|
# Routines that call Postgres binaries need to call this routine like this:
|
|
|
|
#
|
2022-03-31 14:34:39 +02:00
|
|
|
# local %ENV = $self->_get_env([%extra_settings]);
|
2021-03-24 23:52:25 +01:00
|
|
|
#
|
|
|
|
# A copy of the environment is taken and node's host and port settings are
|
2022-03-15 03:29:23 +01:00
|
|
|
# added as PGHOST and PGPORT, then the extra settings (if any) are applied.
|
|
|
|
# Any setting in %extra_settings with a value that is undefined is deleted;
|
|
|
|
# the remainder are set. Then the PATH and (DY)LD_LIBRARY_PATH are adjusted
|
2021-03-24 23:52:25 +01:00
|
|
|
# if the node's install path is set, and the copy environment is returned.
|
|
|
|
#
|
2021-07-29 11:58:08 +02:00
|
|
|
# The install path set in new() needs to be a directory containing
|
2021-03-24 23:52:25 +01:00
|
|
|
# bin and lib subdirectories as in a standard PostgreSQL installation, so this
|
|
|
|
# can't be used with installations where the bin and lib directories don't have
|
|
|
|
# a common parent directory.
|
|
|
|
sub _get_env
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
my %inst_env = (%ENV, PGHOST => $self->{_host}, PGPORT => $self->{_port});
|
|
|
|
# the remaining arguments are modifications to make to the environment
|
|
|
|
my %mods = (@_);
|
|
|
|
while (my ($k, $v) = each %mods)
|
|
|
|
{
|
|
|
|
if (defined $v)
|
|
|
|
{
|
|
|
|
$inst_env{$k} = "$v";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
delete $inst_env{$k};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# now fix up the new environment for the install path
|
|
|
|
my $inst = $self->{_install_path};
|
|
|
|
if ($inst)
|
|
|
|
{
|
2021-10-24 16:28:19 +02:00
|
|
|
if ($PostgreSQL::Test::Utils::windows_os)
|
2021-03-24 23:52:25 +01:00
|
|
|
{
|
|
|
|
# Windows picks up DLLs from the PATH rather than *LD_LIBRARY_PATH
|
|
|
|
# choose the right path separator
|
|
|
|
if ($Config{osname} eq 'MSWin32')
|
|
|
|
{
|
|
|
|
$inst_env{PATH} = "$inst/bin;$inst/lib;$ENV{PATH}";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$inst_env{PATH} = "$inst/bin:$inst/lib:$ENV{PATH}";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
my $dylib_name =
|
|
|
|
$Config{osname} eq 'darwin'
|
|
|
|
? "DYLD_LIBRARY_PATH"
|
|
|
|
: "LD_LIBRARY_PATH";
|
|
|
|
$inst_env{PATH} = "$inst/bin:$ENV{PATH}";
|
|
|
|
if (exists $ENV{$dylib_name})
|
|
|
|
{
|
|
|
|
$inst_env{$dylib_name} = "$inst/lib:$ENV{$dylib_name}";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$inst_env{$dylib_name} = "$inst/lib";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (%inst_env);
|
|
|
|
}
|
|
|
|
|
2021-04-20 16:14:16 +02:00
|
|
|
# Private routine to get an installation path qualified command.
|
|
|
|
#
|
|
|
|
# IPC::Run maintains a cache, %cmd_cache, mapping commands to paths. Tests
|
|
|
|
# which use nodes spanning more than one postgres installation path need to
|
|
|
|
# avoid confusing which installation's binaries get run. Setting $ENV{PATH} is
|
|
|
|
# insufficient, as IPC::Run does not check to see if the path has changed since
|
|
|
|
# caching a command.
|
|
|
|
sub installed_command
|
|
|
|
{
|
|
|
|
my ($self, $cmd) = @_;
|
|
|
|
|
|
|
|
# Nodes using alternate installation locations use their installation's
|
|
|
|
# bin/ directory explicitly
|
|
|
|
return join('/', $self->{_install_path}, 'bin', $cmd)
|
|
|
|
if defined $self->{_install_path};
|
|
|
|
|
|
|
|
# Nodes implicitly using the default installation location rely on IPC::Run
|
|
|
|
# to find the right binary, which should not cause %cmd_cache confusion,
|
|
|
|
# because no nodes with other installation paths do it that way.
|
|
|
|
return $cmd;
|
|
|
|
}
|
|
|
|
|
2019-08-04 19:07:12 +02:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item get_free_port()
|
|
|
|
|
|
|
|
Locate an unprivileged (high) TCP port that's not currently bound to
|
2021-07-29 11:58:08 +02:00
|
|
|
anything. This is used by C<new()>, and also by some test cases that need to
|
|
|
|
start other, non-Postgres servers.
|
2019-08-04 19:07:12 +02:00
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
Ports assigned to existing PostgreSQL::Test::Cluster objects are automatically
|
2019-08-04 19:07:12 +02:00
|
|
|
excluded, even if those servers are not currently running.
|
|
|
|
|
2022-11-20 15:51:50 +01:00
|
|
|
The port number is reserved so that other concurrent test programs will not
|
|
|
|
try to use the same port.
|
2019-08-04 19:07:12 +02:00
|
|
|
|
2021-07-29 11:58:08 +02:00
|
|
|
Note: this is not an instance method. As it's not exported it should be
|
2021-10-24 16:28:19 +02:00
|
|
|
called from outside the module as C<PostgreSQL::Test::Cluster::get_free_port()>.
|
2021-07-29 11:58:08 +02:00
|
|
|
|
2019-08-04 19:07:12 +02:00
|
|
|
=cut
|
|
|
|
|
|
|
|
sub get_free_port
|
|
|
|
{
|
|
|
|
my $found = 0;
|
|
|
|
my $port = $last_port_assigned;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
|
|
|
while ($found == 0)
|
|
|
|
{
|
2016-06-12 10:19:56 +02:00
|
|
|
|
Improve PostgresNode.pm's logic for detecting already-in-use ports.
Buildfarm members bowerbird and jacana have shown intermittent "could not
bind IPv4 socket" failures in the BinInstallCheck stage since mid-December,
shortly after commits 1caef31d9e550408 and 9821492ee417a591 changed the
logic for selecting which port to use in temporary installations. One
plausible explanation is that we are randomly selecting ports that are
already in use for some non-Postgres purpose. Although the code tried
to defend against already-in-use ports, it used pg_isready to probe
the port which is quite unhelpful: if some non-Postgres server responds
at the given address, pg_isready will generally say "no response",
leading to exactly the wrong conclusion about whether the port is free.
Instead, let's use a simple TCP connect() call to see if anything answers
without making assumptions about what it is. Note that this means there's
no direct check for a conflicting Unix socket, but that should be okay
because there should be no other Unix sockets in use in the temporary
socket directory created for a test run.
This is only a partial solution for the TCP case, since if the port number
is in use for an outgoing connection rather than a listening socket, we'll
fail to detect that. We could try to bind() to the proposed port as a
means of detecting that case, but that would introduce its own failure
modes, since the system might consider the address to remain reserved for
some period of time after we drop the bound socket. Close study of the
errors returned by bowerbird and jacana suggests that what we're seeing
there may be conflicts with listening not outgoing sockets, so let's try
this and see if it improves matters. It's certainly better than what's
there now, in any case.
Michael Paquier, adjusted by me to work on non-Windows as well as Windows
2016-04-24 21:31:36 +02:00
|
|
|
# advance $port, wrapping correctly around range end
|
2015-12-08 00:06:21 +01:00
|
|
|
$port = 49152 if ++$port >= 65536;
|
Improve PostgresNode.pm's logic for detecting already-in-use ports.
Buildfarm members bowerbird and jacana have shown intermittent "could not
bind IPv4 socket" failures in the BinInstallCheck stage since mid-December,
shortly after commits 1caef31d9e550408 and 9821492ee417a591 changed the
logic for selecting which port to use in temporary installations. One
plausible explanation is that we are randomly selecting ports that are
already in use for some non-Postgres purpose. Although the code tried
to defend against already-in-use ports, it used pg_isready to probe
the port which is quite unhelpful: if some non-Postgres server responds
at the given address, pg_isready will generally say "no response",
leading to exactly the wrong conclusion about whether the port is free.
Instead, let's use a simple TCP connect() call to see if anything answers
without making assumptions about what it is. Note that this means there's
no direct check for a conflicting Unix socket, but that should be okay
because there should be no other Unix sockets in use in the temporary
socket directory created for a test run.
This is only a partial solution for the TCP case, since if the port number
is in use for an outgoing connection rather than a listening socket, we'll
fail to detect that. We could try to bind() to the proposed port as a
means of detecting that case, but that would introduce its own failure
modes, since the system might consider the address to remain reserved for
some period of time after we drop the bound socket. Close study of the
errors returned by bowerbird and jacana suggests that what we're seeing
there may be conflicts with listening not outgoing sockets, so let's try
this and see if it improves matters. It's certainly better than what's
there now, in any case.
Michael Paquier, adjusted by me to work on non-Windows as well as Windows
2016-04-24 21:31:36 +02:00
|
|
|
print "# Checking port $port\n";
|
|
|
|
|
|
|
|
# Check first that candidate port number is not included in
|
|
|
|
# the list of already-registered nodes.
|
|
|
|
$found = 1;
|
|
|
|
foreach my $node (@all_nodes)
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
{
|
Improve PostgresNode.pm's logic for detecting already-in-use ports.
Buildfarm members bowerbird and jacana have shown intermittent "could not
bind IPv4 socket" failures in the BinInstallCheck stage since mid-December,
shortly after commits 1caef31d9e550408 and 9821492ee417a591 changed the
logic for selecting which port to use in temporary installations. One
plausible explanation is that we are randomly selecting ports that are
already in use for some non-Postgres purpose. Although the code tried
to defend against already-in-use ports, it used pg_isready to probe
the port which is quite unhelpful: if some non-Postgres server responds
at the given address, pg_isready will generally say "no response",
leading to exactly the wrong conclusion about whether the port is free.
Instead, let's use a simple TCP connect() call to see if anything answers
without making assumptions about what it is. Note that this means there's
no direct check for a conflicting Unix socket, but that should be okay
because there should be no other Unix sockets in use in the temporary
socket directory created for a test run.
This is only a partial solution for the TCP case, since if the port number
is in use for an outgoing connection rather than a listening socket, we'll
fail to detect that. We could try to bind() to the proposed port as a
means of detecting that case, but that would introduce its own failure
modes, since the system might consider the address to remain reserved for
some period of time after we drop the bound socket. Close study of the
errors returned by bowerbird and jacana suggests that what we're seeing
there may be conflicts with listening not outgoing sockets, so let's try
this and see if it improves matters. It's certainly better than what's
there now, in any case.
Michael Paquier, adjusted by me to work on non-Windows as well as Windows
2016-04-24 21:31:36 +02:00
|
|
|
$found = 0 if ($node->port == $port);
|
|
|
|
}
|
|
|
|
|
2019-08-04 19:07:12 +02:00
|
|
|
# Check to see if anything else is listening on this TCP port.
|
|
|
|
# Seek a port available for all possible listen_addresses values,
|
|
|
|
# so callers can harness this port for the widest range of purposes.
|
2021-04-21 16:21:22 +02:00
|
|
|
# The 0.0.0.0 test achieves that for MSYS, which automatically sets
|
|
|
|
# SO_EXCLUSIVEADDRUSE. Testing 0.0.0.0 is insufficient for Windows
|
|
|
|
# native Perl (https://stackoverflow.com/a/14388707), so we also
|
|
|
|
# have to test individual addresses. Doing that for 127.0.0/24
|
|
|
|
# addresses other than 127.0.0.1 might fail with EADDRNOTAVAIL on
|
|
|
|
# non-Linux, non-Windows kernels.
|
2019-04-15 05:02:19 +02:00
|
|
|
#
|
2021-04-21 16:21:22 +02:00
|
|
|
# Thus, 0.0.0.0 and individual 127.0.0/24 addresses are tested
|
|
|
|
# only on Windows and only when TCP usage is requested.
|
Improve PostgresNode.pm's logic for detecting already-in-use ports.
Buildfarm members bowerbird and jacana have shown intermittent "could not
bind IPv4 socket" failures in the BinInstallCheck stage since mid-December,
shortly after commits 1caef31d9e550408 and 9821492ee417a591 changed the
logic for selecting which port to use in temporary installations. One
plausible explanation is that we are randomly selecting ports that are
already in use for some non-Postgres purpose. Although the code tried
to defend against already-in-use ports, it used pg_isready to probe
the port which is quite unhelpful: if some non-Postgres server responds
at the given address, pg_isready will generally say "no response",
leading to exactly the wrong conclusion about whether the port is free.
Instead, let's use a simple TCP connect() call to see if anything answers
without making assumptions about what it is. Note that this means there's
no direct check for a conflicting Unix socket, but that should be okay
because there should be no other Unix sockets in use in the temporary
socket directory created for a test run.
This is only a partial solution for the TCP case, since if the port number
is in use for an outgoing connection rather than a listening socket, we'll
fail to detect that. We could try to bind() to the proposed port as a
means of detecting that case, but that would introduce its own failure
modes, since the system might consider the address to remain reserved for
some period of time after we drop the bound socket. Close study of the
errors returned by bowerbird and jacana suggests that what we're seeing
there may be conflicts with listening not outgoing sockets, so let's try
this and see if it improves matters. It's certainly better than what's
there now, in any case.
Michael Paquier, adjusted by me to work on non-Windows as well as Windows
2016-04-24 21:31:36 +02:00
|
|
|
if ($found == 1)
|
|
|
|
{
|
2019-05-06 05:02:41 +02:00
|
|
|
foreach my $addr (qw(127.0.0.1),
|
2021-10-24 16:28:19 +02:00
|
|
|
($use_tcp && $PostgreSQL::Test::Utils::windows_os)
|
2021-04-21 16:21:22 +02:00
|
|
|
? qw(127.0.0.2 127.0.0.3 0.0.0.0)
|
|
|
|
: ())
|
2019-04-15 05:02:19 +02:00
|
|
|
{
|
2019-08-04 19:07:12 +02:00
|
|
|
if (!can_bind($addr, $port))
|
|
|
|
{
|
|
|
|
$found = 0;
|
|
|
|
last;
|
|
|
|
}
|
2019-04-15 05:02:19 +02:00
|
|
|
}
|
2022-11-20 15:51:50 +01:00
|
|
|
$found = _reserve_port($port) if $found;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-13 07:36:38 +02:00
|
|
|
print "# Found port $port\n";
|
|
|
|
|
2019-08-04 19:07:12 +02:00
|
|
|
# Update port for next time
|
|
|
|
$last_port_assigned = $port;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2019-08-04 19:07:12 +02:00
|
|
|
return $port;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2019-04-15 05:02:19 +02:00
|
|
|
# Internal routine to check whether a host:port is available to bind
|
|
|
|
sub can_bind
|
|
|
|
{
|
|
|
|
my ($host, $port) = @_;
|
|
|
|
my $iaddr = inet_aton($host);
|
|
|
|
my $paddr = sockaddr_in($port, $iaddr);
|
|
|
|
my $proto = getprotobyname("tcp");
|
|
|
|
|
|
|
|
socket(SOCK, PF_INET, SOCK_STREAM, $proto)
|
|
|
|
or die "socket failed: $!";
|
|
|
|
|
|
|
|
# As in postmaster, don't use SO_REUSEADDR on Windows
|
|
|
|
setsockopt(SOCK, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
|
2021-10-24 16:28:19 +02:00
|
|
|
unless $PostgreSQL::Test::Utils::windows_os;
|
2019-04-15 05:02:19 +02:00
|
|
|
my $ret = bind(SOCK, $paddr) && listen(SOCK, SOMAXCONN);
|
|
|
|
close(SOCK);
|
|
|
|
return $ret;
|
|
|
|
}
|
|
|
|
|
2022-11-20 15:51:50 +01:00
|
|
|
# Internal routine to reserve a port number
|
|
|
|
# Returns 1 if successful, 0 if port is already reserved.
|
|
|
|
sub _reserve_port
|
|
|
|
{
|
|
|
|
my $port = shift;
|
|
|
|
# open in rw mode so we don't have to reopen it and lose the lock
|
|
|
|
my $filename = "$portdir/$port.rsv";
|
|
|
|
sysopen(my $portfile, $filename, O_RDWR | O_CREAT)
|
|
|
|
|| die "opening port file $filename: $!";
|
|
|
|
# take an exclusive lock to avoid concurrent access
|
|
|
|
flock($portfile, LOCK_EX) || die "locking port file $filename: $!";
|
|
|
|
# see if someone else has or had a reservation of this port
|
2022-11-23 13:03:06 +01:00
|
|
|
my $pid = <$portfile> || "0";
|
2022-11-20 15:51:50 +01:00
|
|
|
chomp $pid;
|
|
|
|
if ($pid + 0 > 0)
|
|
|
|
{
|
|
|
|
if (kill 0, $pid)
|
|
|
|
{
|
|
|
|
# process exists and is owned by us, so we can't reserve this port
|
|
|
|
flock($portfile, LOCK_UN);
|
|
|
|
close($portfile);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# All good, go ahead and reserve the port
|
|
|
|
seek($portfile, 0, SEEK_SET);
|
|
|
|
# print the pid with a fixed width so we don't leave any trailing junk
|
|
|
|
print $portfile sprintf("%10d\n", $$);
|
|
|
|
flock($portfile, LOCK_UN);
|
|
|
|
close($portfile);
|
|
|
|
push(@port_reservation_files, $filename);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-08-16 05:21:52 +02:00
|
|
|
# Automatically shut down any still-running nodes (in the same order the nodes
|
|
|
|
# were created in) when the test script exits.
|
Fix order of shutdown cleanup operations in PostgresNode.pm.
Previously, database clusters created by a TAP test were shut down by
DESTROY methods attached to the PostgresNode objects representing them.
The trouble with that is that if the objects survive into the final global
destruction phase (which they do), Perl executes the DESTROY methods in an
unspecified order. Thus, the order of shutdown of multiple clusters was
indeterminate, which might lead to not-very-reproducible errors getting
logged (eg from a slave whose master might or might not get killed first).
Worse, the File::Temp objects representing the temporary PGDATA directories
might get destroyed before the PostgresNode objects, resulting in attempts
to delete PGDATA directories that still have live servers in them. On
Windows, this would lead to directory deletion failures; on Unix, it
usually had no effects worse than erratic "could not open temporary
statistics file "pg_stat/global.tmp": No such file or directory" log
messages.
While none of this would affect the reported result of the TAP test, which
is already determined, it could be very confusing when one is trying to
understand from the logs what went wrong with a failed test.
To fix, do the postmaster shutdowns in an END block rather than at object
destruction time. The END block will execute at a well-defined (and
reasonable) time during script termination, and it will stop the
postmasters in order of PostgresNode object creation. (Perhaps we should
change that to be reverse order of creation, but the main point here is
that we now have control which we did not before.) Use "pg_ctl stop", not
an asynchronous kill(SIGQUIT), so that we wait for the postmasters to shut
down before proceeding with directory deletion.
Deletion of temporary directories still happens in an unspecified order
during global destruction, but I can see no reason to care about that
once the postmasters are stopped.
2016-04-26 18:43:03 +02:00
|
|
|
END
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
{
|
2016-06-12 10:19:56 +02:00
|
|
|
|
Fix order of shutdown cleanup operations in PostgresNode.pm.
Previously, database clusters created by a TAP test were shut down by
DESTROY methods attached to the PostgresNode objects representing them.
The trouble with that is that if the objects survive into the final global
destruction phase (which they do), Perl executes the DESTROY methods in an
unspecified order. Thus, the order of shutdown of multiple clusters was
indeterminate, which might lead to not-very-reproducible errors getting
logged (eg from a slave whose master might or might not get killed first).
Worse, the File::Temp objects representing the temporary PGDATA directories
might get destroyed before the PostgresNode objects, resulting in attempts
to delete PGDATA directories that still have live servers in them. On
Windows, this would lead to directory deletion failures; on Unix, it
usually had no effects worse than erratic "could not open temporary
statistics file "pg_stat/global.tmp": No such file or directory" log
messages.
While none of this would affect the reported result of the TAP test, which
is already determined, it could be very confusing when one is trying to
understand from the logs what went wrong with a failed test.
To fix, do the postmaster shutdowns in an END block rather than at object
destruction time. The END block will execute at a well-defined (and
reasonable) time during script termination, and it will stop the
postmasters in order of PostgresNode object creation. (Perhaps we should
change that to be reverse order of creation, but the main point here is
that we now have control which we did not before.) Use "pg_ctl stop", not
an asynchronous kill(SIGQUIT), so that we wait for the postmasters to shut
down before proceeding with directory deletion.
Deletion of temporary directories still happens in an unspecified order
during global destruction, but I can see no reason to care about that
once the postmasters are stopped.
2016-04-26 18:43:03 +02:00
|
|
|
# take care not to change the script's exit value
|
|
|
|
my $exit_code = $?;
|
|
|
|
|
|
|
|
foreach my $node (@all_nodes)
|
|
|
|
{
|
2022-10-19 17:09:51 +02:00
|
|
|
# During unclean termination (which could be a signal or some
|
|
|
|
# other failure), we're not sure that the status of our nodes
|
|
|
|
# has been correctly set up already, so try and update it to
|
|
|
|
# improve our chances of shutting them down.
|
|
|
|
$node->_update_pid(-1) if $exit_code != 0;
|
|
|
|
|
|
|
|
# If that fails, don't let that foil other nodes' shutdown
|
|
|
|
$node->teardown_node(fail_ok => 1);
|
2017-09-05 18:22:33 +02:00
|
|
|
|
|
|
|
# skip clean if we are requested to retain the basedir
|
|
|
|
next if defined $ENV{'PG_TEST_NOCLEAN'};
|
|
|
|
|
|
|
|
# clean basedir on clean test invocation
|
2021-10-24 16:28:19 +02:00
|
|
|
$node->clean_node
|
|
|
|
if $exit_code == 0 && PostgreSQL::Test::Utils::all_tests_passing();
|
Fix order of shutdown cleanup operations in PostgresNode.pm.
Previously, database clusters created by a TAP test were shut down by
DESTROY methods attached to the PostgresNode objects representing them.
The trouble with that is that if the objects survive into the final global
destruction phase (which they do), Perl executes the DESTROY methods in an
unspecified order. Thus, the order of shutdown of multiple clusters was
indeterminate, which might lead to not-very-reproducible errors getting
logged (eg from a slave whose master might or might not get killed first).
Worse, the File::Temp objects representing the temporary PGDATA directories
might get destroyed before the PostgresNode objects, resulting in attempts
to delete PGDATA directories that still have live servers in them. On
Windows, this would lead to directory deletion failures; on Unix, it
usually had no effects worse than erratic "could not open temporary
statistics file "pg_stat/global.tmp": No such file or directory" log
messages.
While none of this would affect the reported result of the TAP test, which
is already determined, it could be very confusing when one is trying to
understand from the logs what went wrong with a failed test.
To fix, do the postmaster shutdowns in an END block rather than at object
destruction time. The END block will execute at a well-defined (and
reasonable) time during script termination, and it will stop the
postmasters in order of PostgresNode object creation. (Perhaps we should
change that to be reverse order of creation, but the main point here is
that we now have control which we did not before.) Use "pg_ctl stop", not
an asynchronous kill(SIGQUIT), so that we wait for the postmasters to shut
down before proceeding with directory deletion.
Deletion of temporary directories still happens in an unspecified order
during global destruction, but I can see no reason to care about that
once the postmasters are stopped.
2016-04-26 18:43:03 +02:00
|
|
|
}
|
|
|
|
|
2022-11-20 15:51:50 +01:00
|
|
|
unlink @port_reservation_files;
|
|
|
|
|
Fix order of shutdown cleanup operations in PostgresNode.pm.
Previously, database clusters created by a TAP test were shut down by
DESTROY methods attached to the PostgresNode objects representing them.
The trouble with that is that if the objects survive into the final global
destruction phase (which they do), Perl executes the DESTROY methods in an
unspecified order. Thus, the order of shutdown of multiple clusters was
indeterminate, which might lead to not-very-reproducible errors getting
logged (eg from a slave whose master might or might not get killed first).
Worse, the File::Temp objects representing the temporary PGDATA directories
might get destroyed before the PostgresNode objects, resulting in attempts
to delete PGDATA directories that still have live servers in them. On
Windows, this would lead to directory deletion failures; on Unix, it
usually had no effects worse than erratic "could not open temporary
statistics file "pg_stat/global.tmp": No such file or directory" log
messages.
While none of this would affect the reported result of the TAP test, which
is already determined, it could be very confusing when one is trying to
understand from the logs what went wrong with a failed test.
To fix, do the postmaster shutdowns in an END block rather than at object
destruction time. The END block will execute at a well-defined (and
reasonable) time during script termination, and it will stop the
postmasters in order of PostgresNode object creation. (Perhaps we should
change that to be reverse order of creation, but the main point here is
that we now have control which we did not before.) Use "pg_ctl stop", not
an asynchronous kill(SIGQUIT), so that we wait for the postmasters to shut
down before proceeding with directory deletion.
Deletion of temporary directories still happens in an unspecified order
during global destruction, but I can see no reason to care about that
once the postmasters are stopped.
2016-04-26 18:43:03 +02:00
|
|
|
$? = $exit_code;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->teardown_node()
|
|
|
|
|
|
|
|
Do an immediate stop of the node
|
|
|
|
|
2022-10-19 17:09:51 +02:00
|
|
|
Any optional extra parameter is passed to ->stop.
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub teardown_node
|
|
|
|
{
|
2022-10-19 17:09:51 +02:00
|
|
|
my ($self, %params) = @_;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2022-10-19 17:09:51 +02:00
|
|
|
$self->stop('immediate', %params);
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
2017-09-05 18:22:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->clean_node()
|
|
|
|
|
|
|
|
Remove the base directory of the node if the node has been stopped.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub clean_node
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
rmtree $self->{_basedir} unless defined $self->{_pid};
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
2016-03-03 21:58:30 +01:00
|
|
|
=item $node->safe_psql($dbname, $sql) => stdout
|
2016-02-26 01:31:52 +01:00
|
|
|
|
2016-03-03 21:58:30 +01:00
|
|
|
Invoke B<psql> to run B<sql> on B<dbname> and return its stdout on success.
|
|
|
|
Die if the SQL produces an error. Runs with B<ON_ERROR_STOP> set.
|
2016-02-26 01:31:52 +01:00
|
|
|
|
2016-03-03 21:58:30 +01:00
|
|
|
Takes optional extra params like timeout and timed_out parameters with the same
|
|
|
|
options as psql.
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|
2016-03-03 21:58:30 +01:00
|
|
|
sub safe_psql
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
{
|
2016-03-03 21:58:30 +01:00
|
|
|
my ($self, $dbname, $sql, %params) = @_;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
my ($stdout, $stderr);
|
|
|
|
|
2016-03-03 21:58:30 +01:00
|
|
|
my $ret = $self->psql(
|
|
|
|
$dbname, $sql,
|
|
|
|
%params,
|
|
|
|
stdout => \$stdout,
|
|
|
|
stderr => \$stderr,
|
|
|
|
on_error_die => 1,
|
|
|
|
on_error_stop => 1);
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2016-03-03 21:58:30 +01:00
|
|
|
# psql can emit stderr from NOTICEs etc
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
if ($stderr ne "")
|
|
|
|
{
|
|
|
|
print "#### Begin standard error\n";
|
|
|
|
print $stderr;
|
2016-03-03 21:58:30 +01:00
|
|
|
print "\n#### End standard error\n";
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
2016-03-03 21:58:30 +01:00
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
return $stdout;
|
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
2016-03-03 21:58:30 +01:00
|
|
|
=item $node->psql($dbname, $sql, %params) => psql_retval
|
|
|
|
|
|
|
|
Invoke B<psql> to execute B<$sql> on B<$dbname> and return the return value
|
|
|
|
from B<psql>, which is run with on_error_stop by default so that it will
|
|
|
|
stop running sql and return 3 if the passed SQL results in an error.
|
|
|
|
|
|
|
|
As a convenience, if B<psql> is called in array context it returns an
|
|
|
|
array containing ($retval, $stdout, $stderr).
|
|
|
|
|
|
|
|
psql is invoked in tuples-only unaligned mode with reading of B<.psqlrc>
|
|
|
|
disabled. That may be overridden by passing extra psql parameters.
|
|
|
|
|
|
|
|
stdout and stderr are transformed to UNIX line endings if on Windows. Any
|
|
|
|
trailing newline is removed.
|
|
|
|
|
|
|
|
Dies on failure to invoke psql but not if psql exits with a nonzero
|
|
|
|
return code (unless on_error_die specified).
|
|
|
|
|
|
|
|
If psql exits because of a signal, an exception is raised.
|
|
|
|
|
|
|
|
=over
|
|
|
|
|
|
|
|
=item stdout => \$stdout
|
|
|
|
|
|
|
|
B<stdout>, if given, must be a scalar reference to which standard output is
|
|
|
|
written. If not given, standard output is not redirected and will be printed
|
|
|
|
unless B<psql> is called in array context, in which case it's captured and
|
|
|
|
returned.
|
|
|
|
|
|
|
|
=item stderr => \$stderr
|
|
|
|
|
|
|
|
Same as B<stdout> but gets standard error. If the same scalar is passed for
|
|
|
|
both B<stdout> and B<stderr> the results may be interleaved unpredictably.
|
|
|
|
|
|
|
|
=item on_error_stop => 1
|
|
|
|
|
|
|
|
By default, the B<psql> method invokes the B<psql> program with ON_ERROR_STOP=1
|
2020-12-13 05:12:25 +01:00
|
|
|
set, so SQL execution is stopped at the first error and exit code 3 is
|
2016-03-03 21:58:30 +01:00
|
|
|
returned. Set B<on_error_stop> to 0 to ignore errors instead.
|
|
|
|
|
|
|
|
=item on_error_die => 0
|
|
|
|
|
|
|
|
By default, this method returns psql's result code. Pass on_error_die to
|
|
|
|
instead die with an informative message.
|
|
|
|
|
|
|
|
=item timeout => 'interval'
|
|
|
|
|
|
|
|
Set a timeout for the psql call as an interval accepted by B<IPC::Run::timer>
|
|
|
|
(integer seconds is fine). This method raises an exception on timeout, unless
|
|
|
|
the B<timed_out> parameter is also given.
|
|
|
|
|
|
|
|
=item timed_out => \$timed_out
|
|
|
|
|
|
|
|
If B<timeout> is set and this parameter is given, the scalar it references
|
|
|
|
is set to true if the psql call times out.
|
|
|
|
|
Move some client-specific routines from SSLServer to PostgresNode
test_connect_ok() and test_connect_fails() have always been part of the
SSL tests, and check if a connection to the backend should work or not,
and there are sanity checks done on specific error patterns dropped by
libpq if the connection fails.
This was fundamentally wrong on two aspects. First, SSLServer.pm works
mostly on setting up and changing the SSL configuration of a
PostgresNode, and has really nothing to do with the client. Second,
the situation became worse in light of b34ca595, where the SSL tests
would finish by using a psql command that may not come from the same
installation as the node set up.
This commit moves those client routines into PostgresNode, making easier
the refactoring of SSLServer to become more SSL-implementation aware.
This can also be reused by the ldap, kerberos and authentication test
suites for connection checks, and a follow-up patch should extend those
interfaces to match with backend log patterns.
Author: Michael Paquier
Reviewed-by: Andrew Dunstan, Daniel Gustafsson, Álvaro Herrera
Discussion: https://postgr.es/m/YGLKNBf9zyh6+WSt@paquier.xyz
2021-04-01 02:48:17 +02:00
|
|
|
=item connstr => B<value>
|
|
|
|
|
|
|
|
If set, use this as the connection string for the connection to the
|
|
|
|
backend.
|
|
|
|
|
2020-05-16 01:59:29 +02:00
|
|
|
=item replication => B<value>
|
|
|
|
|
|
|
|
If set, add B<replication=value> to the conninfo string.
|
|
|
|
Passing the literal value C<database> results in a logical replication
|
|
|
|
connection.
|
|
|
|
|
2016-03-03 21:58:30 +01:00
|
|
|
=item extra_params => ['--single-transaction']
|
|
|
|
|
|
|
|
If given, it must be an array reference containing additional parameters to B<psql>.
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
e.g.
|
|
|
|
|
|
|
|
my ($stdout, $stderr, $timed_out);
|
2021-05-31 09:29:58 +02:00
|
|
|
my $cmdret = $node->psql('postgres', 'SELECT pg_sleep(600)',
|
2016-03-03 21:58:30 +01:00
|
|
|
stdout => \$stdout, stderr => \$stderr,
|
2022-03-05 03:53:13 +01:00
|
|
|
timeout => $PostgreSQL::Test::Utils::timeout_default,
|
|
|
|
timed_out => \$timed_out,
|
2016-03-03 21:58:30 +01:00
|
|
|
extra_params => ['--single-transaction'])
|
|
|
|
|
|
|
|
will set $cmdret to undef and $timed_out to a true value.
|
|
|
|
|
|
|
|
$node->psql('postgres', $sql, on_error_die => 1);
|
|
|
|
|
|
|
|
dies with an informative message if $sql fails.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub psql
|
|
|
|
{
|
|
|
|
my ($self, $dbname, $sql, %params) = @_;
|
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
2016-03-03 21:58:30 +01:00
|
|
|
my $stdout = $params{stdout};
|
|
|
|
my $stderr = $params{stderr};
|
2020-05-16 01:59:29 +02:00
|
|
|
my $replication = $params{replication};
|
2016-03-03 21:58:30 +01:00
|
|
|
my $timeout = undef;
|
|
|
|
my $timeout_exception = 'psql timed out';
|
Move some client-specific routines from SSLServer to PostgresNode
test_connect_ok() and test_connect_fails() have always been part of the
SSL tests, and check if a connection to the backend should work or not,
and there are sanity checks done on specific error patterns dropped by
libpq if the connection fails.
This was fundamentally wrong on two aspects. First, SSLServer.pm works
mostly on setting up and changing the SSL configuration of a
PostgresNode, and has really nothing to do with the client. Second,
the situation became worse in light of b34ca595, where the SSL tests
would finish by using a psql command that may not come from the same
installation as the node set up.
This commit moves those client routines into PostgresNode, making easier
the refactoring of SSLServer to become more SSL-implementation aware.
This can also be reused by the ldap, kerberos and authentication test
suites for connection checks, and a follow-up patch should extend those
interfaces to match with backend log patterns.
Author: Michael Paquier
Reviewed-by: Andrew Dunstan, Daniel Gustafsson, Álvaro Herrera
Discussion: https://postgr.es/m/YGLKNBf9zyh6+WSt@paquier.xyz
2021-04-01 02:48:17 +02:00
|
|
|
|
|
|
|
# Build the connection string.
|
|
|
|
my $psql_connstr;
|
|
|
|
if (defined $params{connstr})
|
|
|
|
{
|
|
|
|
$psql_connstr = $params{connstr};
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$psql_connstr = $self->connstr($dbname);
|
|
|
|
}
|
|
|
|
$psql_connstr .= defined $replication ? " replication=$replication" : "";
|
|
|
|
|
2021-04-20 16:14:16 +02:00
|
|
|
my @psql_params = (
|
|
|
|
$self->installed_command('psql'),
|
|
|
|
'-XAtq', '-d', $psql_connstr, '-f', '-');
|
2016-03-03 21:58:30 +01:00
|
|
|
|
|
|
|
# If the caller wants an array and hasn't passed stdout/stderr
|
|
|
|
# references, allocate temporary ones to capture them so we
|
|
|
|
# can return them. Otherwise we won't redirect them at all.
|
|
|
|
if (wantarray)
|
|
|
|
{
|
|
|
|
if (!defined($stdout))
|
|
|
|
{
|
|
|
|
my $temp_stdout = "";
|
|
|
|
$stdout = \$temp_stdout;
|
|
|
|
}
|
|
|
|
if (!defined($stderr))
|
|
|
|
{
|
|
|
|
my $temp_stderr = "";
|
|
|
|
$stderr = \$temp_stderr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$params{on_error_stop} = 1 unless defined $params{on_error_stop};
|
|
|
|
$params{on_error_die} = 0 unless defined $params{on_error_die};
|
|
|
|
|
|
|
|
push @psql_params, '-v', 'ON_ERROR_STOP=1' if $params{on_error_stop};
|
|
|
|
push @psql_params, @{ $params{extra_params} }
|
|
|
|
if defined $params{extra_params};
|
|
|
|
|
|
|
|
$timeout =
|
|
|
|
IPC::Run::timeout($params{timeout}, exception => $timeout_exception)
|
|
|
|
if (defined($params{timeout}));
|
|
|
|
|
2016-03-29 00:17:06 +02:00
|
|
|
${ $params{timed_out} } = 0 if defined $params{timed_out};
|
|
|
|
|
2016-03-03 21:58:30 +01:00
|
|
|
# IPC::Run would otherwise append to existing contents:
|
|
|
|
$$stdout = "" if ref($stdout);
|
|
|
|
$$stderr = "" if ref($stderr);
|
|
|
|
|
|
|
|
my $ret;
|
|
|
|
|
2018-04-26 20:13:46 +02:00
|
|
|
# Run psql and capture any possible exceptions. If the exception is
|
|
|
|
# because of a timeout and the caller requested to handle that, just return
|
|
|
|
# and set the flag. Otherwise, and for any other exception, rethrow.
|
|
|
|
#
|
|
|
|
# For background, see
|
2022-11-16 10:24:37 +01:00
|
|
|
# https://metacpan.org/release/ETHER/Try-Tiny-0.24/view/lib/Try/Tiny.pm
|
2016-03-03 21:58:30 +01:00
|
|
|
do
|
|
|
|
{
|
|
|
|
local $@;
|
|
|
|
eval {
|
|
|
|
my @ipcrun_opts = (\@psql_params, '<', \$sql);
|
|
|
|
push @ipcrun_opts, '>', $stdout if defined $stdout;
|
|
|
|
push @ipcrun_opts, '2>', $stderr if defined $stderr;
|
|
|
|
push @ipcrun_opts, $timeout if defined $timeout;
|
|
|
|
|
|
|
|
IPC::Run::run @ipcrun_opts;
|
|
|
|
$ret = $?;
|
|
|
|
};
|
|
|
|
my $exc_save = $@;
|
|
|
|
if ($exc_save)
|
|
|
|
{
|
2017-05-18 01:01:23 +02:00
|
|
|
|
2016-03-03 21:58:30 +01:00
|
|
|
# IPC::Run::run threw an exception. re-throw unless it's a
|
|
|
|
# timeout, which we'll handle by testing is_expired
|
|
|
|
die $exc_save
|
2017-03-01 19:52:38 +01:00
|
|
|
if (blessed($exc_save)
|
|
|
|
|| $exc_save !~ /^\Q$timeout_exception\E/);
|
2016-03-03 21:58:30 +01:00
|
|
|
|
|
|
|
$ret = undef;
|
|
|
|
|
|
|
|
die "Got timeout exception '$exc_save' but timer not expired?!"
|
|
|
|
unless $timeout->is_expired;
|
|
|
|
|
|
|
|
if (defined($params{timed_out}))
|
|
|
|
{
|
|
|
|
${ $params{timed_out} } = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
die "psql timed out: stderr: '$$stderr'\n"
|
|
|
|
. "while running '@psql_params'";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
if (defined $$stdout)
|
|
|
|
{
|
|
|
|
chomp $$stdout;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defined $$stderr)
|
|
|
|
{
|
|
|
|
chomp $$stderr;
|
|
|
|
}
|
|
|
|
|
|
|
|
# See http://perldoc.perl.org/perlvar.html#%24CHILD_ERROR
|
|
|
|
# We don't use IPC::Run::Simple to limit dependencies.
|
|
|
|
#
|
|
|
|
# We always die on signal.
|
|
|
|
my $core = $ret & 128 ? " (core dumped)" : "";
|
|
|
|
die "psql exited with signal "
|
|
|
|
. ($ret & 127)
|
|
|
|
. "$core: '$$stderr' while running '@psql_params'"
|
|
|
|
if $ret & 127;
|
|
|
|
$ret = $ret >> 8;
|
|
|
|
|
|
|
|
if ($ret && $params{on_error_die})
|
|
|
|
{
|
|
|
|
die "psql error: stderr: '$$stderr'\nwhile running '@psql_params'"
|
|
|
|
if $ret == 1;
|
|
|
|
die "connection error: '$$stderr'\nwhile running '@psql_params'"
|
|
|
|
if $ret == 2;
|
2017-01-04 17:50:23 +01:00
|
|
|
die
|
2018-04-26 17:52:52 +02:00
|
|
|
"error running SQL: '$$stderr'\nwhile running '@psql_params' with sql '$sql'"
|
2016-03-03 21:58:30 +01:00
|
|
|
if $ret == 3;
|
|
|
|
die "psql returns $ret: '$$stderr'\nwhile running '@psql_params'";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (wantarray)
|
|
|
|
{
|
|
|
|
return ($ret, $$stdout, $$stderr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return $ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2023-04-07 22:14:20 +02:00
|
|
|
=item $node->background_psql($dbname, %params) => PostgreSQL::Test::BackgroundPsql instance
|
2020-12-13 06:38:36 +01:00
|
|
|
|
2023-04-07 22:14:20 +02:00
|
|
|
Invoke B<psql> on B<$dbname> and return a BackgroundPsql object.
|
2020-12-13 06:38:36 +01:00
|
|
|
|
2023-04-07 22:14:20 +02:00
|
|
|
A default timeout of $PostgreSQL::Test::Utils::timeout_default is set up,
|
|
|
|
which can be modified later.
|
2020-12-13 06:38:36 +01:00
|
|
|
|
|
|
|
psql is invoked in tuples-only unaligned mode with reading of B<.psqlrc>
|
|
|
|
disabled. That may be overridden by passing extra psql parameters.
|
|
|
|
|
|
|
|
Dies on failure to invoke psql, or if psql fails to connect. Errors occurring
|
|
|
|
later are the caller's problem. psql runs with on_error_stop by default so
|
|
|
|
that it will stop running sql and return 3 if passed SQL results in an error.
|
|
|
|
|
2023-04-07 22:14:20 +02:00
|
|
|
Be sure to "quit" the returned object when done with it.
|
2020-12-13 06:38:36 +01:00
|
|
|
|
|
|
|
=over
|
|
|
|
|
|
|
|
=item on_error_stop => 1
|
|
|
|
|
|
|
|
By default, the B<psql> method invokes the B<psql> program with ON_ERROR_STOP=1
|
|
|
|
set, so SQL execution is stopped at the first error and exit code 3 is
|
|
|
|
returned. Set B<on_error_stop> to 0 to ignore errors instead.
|
|
|
|
|
|
|
|
=item replication => B<value>
|
|
|
|
|
|
|
|
If set, add B<replication=value> to the conninfo string.
|
|
|
|
Passing the literal value C<database> results in a logical replication
|
|
|
|
connection.
|
|
|
|
|
|
|
|
=item extra_params => ['--single-transaction']
|
|
|
|
|
|
|
|
If given, it must be an array reference containing additional parameters to B<psql>.
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub background_psql
|
|
|
|
{
|
2023-04-07 22:14:20 +02:00
|
|
|
my ($self, $dbname, %params) = @_;
|
2020-12-13 06:38:36 +01:00
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
2020-12-13 06:38:36 +01:00
|
|
|
my $replication = $params{replication};
|
|
|
|
|
|
|
|
my @psql_params = (
|
2021-04-20 16:14:16 +02:00
|
|
|
$self->installed_command('psql'),
|
2020-12-13 06:38:36 +01:00
|
|
|
'-XAtq',
|
|
|
|
'-d',
|
|
|
|
$self->connstr($dbname)
|
|
|
|
. (defined $replication ? " replication=$replication" : ""),
|
|
|
|
'-f',
|
|
|
|
'-');
|
|
|
|
|
|
|
|
$params{on_error_stop} = 1 unless defined $params{on_error_stop};
|
|
|
|
|
|
|
|
push @psql_params, '-v', 'ON_ERROR_STOP=1' if $params{on_error_stop};
|
|
|
|
push @psql_params, @{ $params{extra_params} }
|
|
|
|
if defined $params{extra_params};
|
|
|
|
|
2023-04-07 22:14:20 +02:00
|
|
|
return PostgreSQL::Test::BackgroundPsql->new(0, \@psql_params);
|
2020-12-13 06:38:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2023-04-07 22:14:20 +02:00
|
|
|
=item $node->interactive_psql($dbname, %params) => BackgroundPsql instance
|
2020-01-02 21:02:21 +01:00
|
|
|
|
2023-04-07 22:14:20 +02:00
|
|
|
Invoke B<psql> on B<$dbname> and return a BackgroundPsql object, which the
|
|
|
|
caller may use to send interactive input to B<psql>.
|
2020-01-02 21:02:21 +01:00
|
|
|
|
2023-04-07 22:14:20 +02:00
|
|
|
A default timeout of $PostgreSQL::Test::Utils::timeout_default is set up,
|
|
|
|
which can be modified later.
|
2020-01-02 21:02:21 +01:00
|
|
|
|
|
|
|
psql is invoked in tuples-only unaligned mode with reading of B<.psqlrc>
|
|
|
|
disabled. That may be overridden by passing extra psql parameters.
|
|
|
|
|
|
|
|
Dies on failure to invoke psql, or if psql fails to connect.
|
|
|
|
Errors occurring later are the caller's problem.
|
|
|
|
|
2023-04-07 22:14:20 +02:00
|
|
|
Be sure to "quit" the returned object when done with it.
|
2020-01-02 21:02:21 +01:00
|
|
|
|
|
|
|
The only extra parameter currently accepted is
|
|
|
|
|
|
|
|
=over
|
|
|
|
|
|
|
|
=item extra_params => ['--single-transaction']
|
|
|
|
|
|
|
|
If given, it must be an array reference containing additional parameters to B<psql>.
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
This requires IO::Pty in addition to IPC::Run.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub interactive_psql
|
|
|
|
{
|
2023-04-07 22:14:20 +02:00
|
|
|
my ($self, $dbname, %params) = @_;
|
2020-01-02 21:02:21 +01:00
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
2021-04-20 16:14:16 +02:00
|
|
|
my @psql_params = (
|
|
|
|
$self->installed_command('psql'),
|
|
|
|
'-XAt', '-d', $self->connstr($dbname));
|
2020-01-02 21:02:21 +01:00
|
|
|
|
|
|
|
push @psql_params, @{ $params{extra_params} }
|
|
|
|
if defined $params{extra_params};
|
|
|
|
|
2023-04-07 22:14:20 +02:00
|
|
|
return PostgreSQL::Test::BackgroundPsql->new(1, \@psql_params);
|
2020-01-02 21:02:21 +01:00
|
|
|
}
|
|
|
|
|
2021-10-24 03:36:38 +02:00
|
|
|
# Common sub of pgbench-invoking interfaces. Makes any requested script files
|
|
|
|
# and returns pgbench command-line options causing use of those files.
|
|
|
|
sub _pgbench_make_files
|
|
|
|
{
|
|
|
|
my ($self, $files) = @_;
|
|
|
|
my @file_opts;
|
|
|
|
|
|
|
|
if (defined $files)
|
|
|
|
{
|
|
|
|
|
|
|
|
# note: files are ordered for determinism
|
|
|
|
for my $fn (sort keys %$files)
|
|
|
|
{
|
|
|
|
my $filename = $self->basedir . '/' . $fn;
|
|
|
|
push @file_opts, '-f', $filename;
|
|
|
|
|
|
|
|
# cleanup file weight
|
|
|
|
$filename =~ s/\@\d+$//;
|
|
|
|
|
|
|
|
#push @filenames, $filename;
|
|
|
|
# filenames are expected to be unique on a test
|
|
|
|
if (-e $filename)
|
|
|
|
{
|
|
|
|
ok(0, "$filename must not already exist");
|
|
|
|
unlink $filename or die "cannot unlink $filename: $!";
|
|
|
|
}
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::append_to_file($filename, $$files{$fn});
|
2021-10-24 03:36:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return @file_opts;
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->pgbench($opts, $stat, $out, $err, $name, $files, @args)
|
|
|
|
|
|
|
|
Invoke B<pgbench>, with parameters and files.
|
|
|
|
|
|
|
|
=over
|
|
|
|
|
|
|
|
=item $opts
|
|
|
|
|
|
|
|
Options as a string to be split on spaces.
|
|
|
|
|
|
|
|
=item $stat
|
|
|
|
|
|
|
|
Expected exit status.
|
|
|
|
|
|
|
|
=item $out
|
|
|
|
|
|
|
|
Reference to a regexp list that must match stdout.
|
|
|
|
|
|
|
|
=item $err
|
|
|
|
|
|
|
|
Reference to a regexp list that must match stderr.
|
|
|
|
|
|
|
|
=item $name
|
|
|
|
|
|
|
|
Name of test for error messages.
|
|
|
|
|
|
|
|
=item $files
|
|
|
|
|
|
|
|
Reference to filename/contents dictionary.
|
|
|
|
|
|
|
|
=item @args
|
|
|
|
|
|
|
|
Further raw options or arguments.
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub pgbench
|
|
|
|
{
|
|
|
|
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
|
|
|
|
|
|
|
my ($self, $opts, $stat, $out, $err, $name, $files, @args) = @_;
|
|
|
|
my @cmd = (
|
|
|
|
'pgbench',
|
|
|
|
split(/\s+/, $opts),
|
|
|
|
$self->_pgbench_make_files($files), @args);
|
|
|
|
|
|
|
|
$self->command_checks_all(\@cmd, $stat, $out, $err, $name);
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2021-04-05 03:13:57 +02:00
|
|
|
=item $node->connect_ok($connstr, $test_name, %params)
|
Move some client-specific routines from SSLServer to PostgresNode
test_connect_ok() and test_connect_fails() have always been part of the
SSL tests, and check if a connection to the backend should work or not,
and there are sanity checks done on specific error patterns dropped by
libpq if the connection fails.
This was fundamentally wrong on two aspects. First, SSLServer.pm works
mostly on setting up and changing the SSL configuration of a
PostgresNode, and has really nothing to do with the client. Second,
the situation became worse in light of b34ca595, where the SSL tests
would finish by using a psql command that may not come from the same
installation as the node set up.
This commit moves those client routines into PostgresNode, making easier
the refactoring of SSLServer to become more SSL-implementation aware.
This can also be reused by the ldap, kerberos and authentication test
suites for connection checks, and a follow-up patch should extend those
interfaces to match with backend log patterns.
Author: Michael Paquier
Reviewed-by: Andrew Dunstan, Daniel Gustafsson, Álvaro Herrera
Discussion: https://postgr.es/m/YGLKNBf9zyh6+WSt@paquier.xyz
2021-04-01 02:48:17 +02:00
|
|
|
|
|
|
|
Attempt a connection with a custom connection string. This is expected
|
|
|
|
to succeed.
|
|
|
|
|
2021-04-05 03:13:57 +02:00
|
|
|
=over
|
|
|
|
|
|
|
|
=item sql => B<value>
|
|
|
|
|
|
|
|
If this parameter is set, this query is used for the connection attempt
|
|
|
|
instead of the default.
|
|
|
|
|
|
|
|
=item expected_stdout => B<value>
|
|
|
|
|
|
|
|
If this regular expression is set, matches it with the output generated.
|
|
|
|
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
=item log_like => [ qr/required message/ ]
|
|
|
|
|
|
|
|
If given, it must be an array reference containing a list of regular
|
|
|
|
expressions that must match against the server log, using
|
|
|
|
C<Test::More::like()>.
|
|
|
|
|
|
|
|
=item log_unlike => [ qr/prohibited message/ ]
|
|
|
|
|
|
|
|
If given, it must be an array reference containing a list of regular
|
|
|
|
expressions that must NOT match against the server log. They will be
|
|
|
|
passed to C<Test::More::unlike()>.
|
|
|
|
|
2021-04-05 03:13:57 +02:00
|
|
|
=back
|
|
|
|
|
Move some client-specific routines from SSLServer to PostgresNode
test_connect_ok() and test_connect_fails() have always been part of the
SSL tests, and check if a connection to the backend should work or not,
and there are sanity checks done on specific error patterns dropped by
libpq if the connection fails.
This was fundamentally wrong on two aspects. First, SSLServer.pm works
mostly on setting up and changing the SSL configuration of a
PostgresNode, and has really nothing to do with the client. Second,
the situation became worse in light of b34ca595, where the SSL tests
would finish by using a psql command that may not come from the same
installation as the node set up.
This commit moves those client routines into PostgresNode, making easier
the refactoring of SSLServer to become more SSL-implementation aware.
This can also be reused by the ldap, kerberos and authentication test
suites for connection checks, and a follow-up patch should extend those
interfaces to match with backend log patterns.
Author: Michael Paquier
Reviewed-by: Andrew Dunstan, Daniel Gustafsson, Álvaro Herrera
Discussion: https://postgr.es/m/YGLKNBf9zyh6+WSt@paquier.xyz
2021-04-01 02:48:17 +02:00
|
|
|
=cut
|
|
|
|
|
|
|
|
sub connect_ok
|
|
|
|
{
|
|
|
|
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
2021-04-05 03:13:57 +02:00
|
|
|
my ($self, $connstr, $test_name, %params) = @_;
|
|
|
|
|
|
|
|
my $sql;
|
|
|
|
if (defined($params{sql}))
|
|
|
|
{
|
|
|
|
$sql = $params{sql};
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$sql = "SELECT \$\$connected with $connstr\$\$";
|
|
|
|
}
|
|
|
|
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
my (@log_like, @log_unlike);
|
|
|
|
if (defined($params{log_like}))
|
|
|
|
{
|
|
|
|
@log_like = @{ $params{log_like} };
|
|
|
|
}
|
|
|
|
if (defined($params{log_unlike}))
|
|
|
|
{
|
|
|
|
@log_unlike = @{ $params{log_unlike} };
|
|
|
|
}
|
|
|
|
|
2021-04-16 22:54:04 +02:00
|
|
|
my $log_location = -s $self->logfile;
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
|
2021-04-05 03:13:57 +02:00
|
|
|
# Never prompt for a password, any callers of this routine should
|
|
|
|
# have set up things properly, and this should not block.
|
|
|
|
my ($ret, $stdout, $stderr) = $self->psql(
|
Move some client-specific routines from SSLServer to PostgresNode
test_connect_ok() and test_connect_fails() have always been part of the
SSL tests, and check if a connection to the backend should work or not,
and there are sanity checks done on specific error patterns dropped by
libpq if the connection fails.
This was fundamentally wrong on two aspects. First, SSLServer.pm works
mostly on setting up and changing the SSL configuration of a
PostgresNode, and has really nothing to do with the client. Second,
the situation became worse in light of b34ca595, where the SSL tests
would finish by using a psql command that may not come from the same
installation as the node set up.
This commit moves those client routines into PostgresNode, making easier
the refactoring of SSLServer to become more SSL-implementation aware.
This can also be reused by the ldap, kerberos and authentication test
suites for connection checks, and a follow-up patch should extend those
interfaces to match with backend log patterns.
Author: Michael Paquier
Reviewed-by: Andrew Dunstan, Daniel Gustafsson, Álvaro Herrera
Discussion: https://postgr.es/m/YGLKNBf9zyh6+WSt@paquier.xyz
2021-04-01 02:48:17 +02:00
|
|
|
'postgres',
|
2021-04-05 03:13:57 +02:00
|
|
|
$sql,
|
|
|
|
extra_params => ['-w'],
|
Move some client-specific routines from SSLServer to PostgresNode
test_connect_ok() and test_connect_fails() have always been part of the
SSL tests, and check if a connection to the backend should work or not,
and there are sanity checks done on specific error patterns dropped by
libpq if the connection fails.
This was fundamentally wrong on two aspects. First, SSLServer.pm works
mostly on setting up and changing the SSL configuration of a
PostgresNode, and has really nothing to do with the client. Second,
the situation became worse in light of b34ca595, where the SSL tests
would finish by using a psql command that may not come from the same
installation as the node set up.
This commit moves those client routines into PostgresNode, making easier
the refactoring of SSLServer to become more SSL-implementation aware.
This can also be reused by the ldap, kerberos and authentication test
suites for connection checks, and a follow-up patch should extend those
interfaces to match with backend log patterns.
Author: Michael Paquier
Reviewed-by: Andrew Dunstan, Daniel Gustafsson, Álvaro Herrera
Discussion: https://postgr.es/m/YGLKNBf9zyh6+WSt@paquier.xyz
2021-04-01 02:48:17 +02:00
|
|
|
connstr => "$connstr",
|
|
|
|
on_error_stop => 0);
|
|
|
|
|
2021-04-05 03:13:57 +02:00
|
|
|
is($ret, 0, $test_name);
|
|
|
|
|
|
|
|
if (defined($params{expected_stdout}))
|
|
|
|
{
|
2022-02-15 11:35:17 +01:00
|
|
|
like($stdout, $params{expected_stdout}, "$test_name: stdout matches");
|
2021-04-05 03:13:57 +02:00
|
|
|
}
|
2022-02-15 11:35:17 +01:00
|
|
|
|
|
|
|
is($stderr, "", "$test_name: no stderr");
|
|
|
|
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
if (@log_like or @log_unlike)
|
|
|
|
{
|
2021-10-24 16:28:19 +02:00
|
|
|
my $log_contents =
|
|
|
|
PostgreSQL::Test::Utils::slurp_file($self->logfile, $log_location);
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
|
|
|
|
while (my $regex = shift @log_like)
|
|
|
|
{
|
|
|
|
like($log_contents, $regex, "$test_name: log matches");
|
|
|
|
}
|
|
|
|
while (my $regex = shift @log_unlike)
|
|
|
|
{
|
|
|
|
unlike($log_contents, $regex, "$test_name: log does not match");
|
|
|
|
}
|
|
|
|
}
|
Move some client-specific routines from SSLServer to PostgresNode
test_connect_ok() and test_connect_fails() have always been part of the
SSL tests, and check if a connection to the backend should work or not,
and there are sanity checks done on specific error patterns dropped by
libpq if the connection fails.
This was fundamentally wrong on two aspects. First, SSLServer.pm works
mostly on setting up and changing the SSL configuration of a
PostgresNode, and has really nothing to do with the client. Second,
the situation became worse in light of b34ca595, where the SSL tests
would finish by using a psql command that may not come from the same
installation as the node set up.
This commit moves those client routines into PostgresNode, making easier
the refactoring of SSLServer to become more SSL-implementation aware.
This can also be reused by the ldap, kerberos and authentication test
suites for connection checks, and a follow-up patch should extend those
interfaces to match with backend log patterns.
Author: Michael Paquier
Reviewed-by: Andrew Dunstan, Daniel Gustafsson, Álvaro Herrera
Discussion: https://postgr.es/m/YGLKNBf9zyh6+WSt@paquier.xyz
2021-04-01 02:48:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2021-04-05 03:13:57 +02:00
|
|
|
=item $node->connect_fails($connstr, $test_name, %params)
|
Move some client-specific routines from SSLServer to PostgresNode
test_connect_ok() and test_connect_fails() have always been part of the
SSL tests, and check if a connection to the backend should work or not,
and there are sanity checks done on specific error patterns dropped by
libpq if the connection fails.
This was fundamentally wrong on two aspects. First, SSLServer.pm works
mostly on setting up and changing the SSL configuration of a
PostgresNode, and has really nothing to do with the client. Second,
the situation became worse in light of b34ca595, where the SSL tests
would finish by using a psql command that may not come from the same
installation as the node set up.
This commit moves those client routines into PostgresNode, making easier
the refactoring of SSLServer to become more SSL-implementation aware.
This can also be reused by the ldap, kerberos and authentication test
suites for connection checks, and a follow-up patch should extend those
interfaces to match with backend log patterns.
Author: Michael Paquier
Reviewed-by: Andrew Dunstan, Daniel Gustafsson, Álvaro Herrera
Discussion: https://postgr.es/m/YGLKNBf9zyh6+WSt@paquier.xyz
2021-04-01 02:48:17 +02:00
|
|
|
|
|
|
|
Attempt a connection with a custom connection string. This is expected
|
2021-04-05 03:13:57 +02:00
|
|
|
to fail.
|
|
|
|
|
|
|
|
=over
|
|
|
|
|
|
|
|
=item expected_stderr => B<value>
|
|
|
|
|
|
|
|
If this regular expression is set, matches it with the output generated.
|
|
|
|
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
=item log_like => [ qr/required message/ ]
|
|
|
|
|
|
|
|
=item log_unlike => [ qr/prohibited message/ ]
|
|
|
|
|
|
|
|
See C<connect_ok(...)>, above.
|
|
|
|
|
2021-04-05 03:13:57 +02:00
|
|
|
=back
|
Move some client-specific routines from SSLServer to PostgresNode
test_connect_ok() and test_connect_fails() have always been part of the
SSL tests, and check if a connection to the backend should work or not,
and there are sanity checks done on specific error patterns dropped by
libpq if the connection fails.
This was fundamentally wrong on two aspects. First, SSLServer.pm works
mostly on setting up and changing the SSL configuration of a
PostgresNode, and has really nothing to do with the client. Second,
the situation became worse in light of b34ca595, where the SSL tests
would finish by using a psql command that may not come from the same
installation as the node set up.
This commit moves those client routines into PostgresNode, making easier
the refactoring of SSLServer to become more SSL-implementation aware.
This can also be reused by the ldap, kerberos and authentication test
suites for connection checks, and a follow-up patch should extend those
interfaces to match with backend log patterns.
Author: Michael Paquier
Reviewed-by: Andrew Dunstan, Daniel Gustafsson, Álvaro Herrera
Discussion: https://postgr.es/m/YGLKNBf9zyh6+WSt@paquier.xyz
2021-04-01 02:48:17 +02:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub connect_fails
|
|
|
|
{
|
|
|
|
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
2021-04-05 03:13:57 +02:00
|
|
|
my ($self, $connstr, $test_name, %params) = @_;
|
|
|
|
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
my (@log_like, @log_unlike);
|
|
|
|
if (defined($params{log_like}))
|
|
|
|
{
|
|
|
|
@log_like = @{ $params{log_like} };
|
|
|
|
}
|
|
|
|
if (defined($params{log_unlike}))
|
|
|
|
{
|
|
|
|
@log_unlike = @{ $params{log_unlike} };
|
|
|
|
}
|
|
|
|
|
2021-04-16 22:54:04 +02:00
|
|
|
my $log_location = -s $self->logfile;
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
|
2021-04-05 03:13:57 +02:00
|
|
|
# Never prompt for a password, any callers of this routine should
|
|
|
|
# have set up things properly, and this should not block.
|
Move some client-specific routines from SSLServer to PostgresNode
test_connect_ok() and test_connect_fails() have always been part of the
SSL tests, and check if a connection to the backend should work or not,
and there are sanity checks done on specific error patterns dropped by
libpq if the connection fails.
This was fundamentally wrong on two aspects. First, SSLServer.pm works
mostly on setting up and changing the SSL configuration of a
PostgresNode, and has really nothing to do with the client. Second,
the situation became worse in light of b34ca595, where the SSL tests
would finish by using a psql command that may not come from the same
installation as the node set up.
This commit moves those client routines into PostgresNode, making easier
the refactoring of SSLServer to become more SSL-implementation aware.
This can also be reused by the ldap, kerberos and authentication test
suites for connection checks, and a follow-up patch should extend those
interfaces to match with backend log patterns.
Author: Michael Paquier
Reviewed-by: Andrew Dunstan, Daniel Gustafsson, Álvaro Herrera
Discussion: https://postgr.es/m/YGLKNBf9zyh6+WSt@paquier.xyz
2021-04-01 02:48:17 +02:00
|
|
|
my ($ret, $stdout, $stderr) = $self->psql(
|
|
|
|
'postgres',
|
2021-04-06 02:53:06 +02:00
|
|
|
undef,
|
2021-04-05 03:13:57 +02:00
|
|
|
extra_params => ['-w'],
|
|
|
|
connstr => "$connstr");
|
Move some client-specific routines from SSLServer to PostgresNode
test_connect_ok() and test_connect_fails() have always been part of the
SSL tests, and check if a connection to the backend should work or not,
and there are sanity checks done on specific error patterns dropped by
libpq if the connection fails.
This was fundamentally wrong on two aspects. First, SSLServer.pm works
mostly on setting up and changing the SSL configuration of a
PostgresNode, and has really nothing to do with the client. Second,
the situation became worse in light of b34ca595, where the SSL tests
would finish by using a psql command that may not come from the same
installation as the node set up.
This commit moves those client routines into PostgresNode, making easier
the refactoring of SSLServer to become more SSL-implementation aware.
This can also be reused by the ldap, kerberos and authentication test
suites for connection checks, and a follow-up patch should extend those
interfaces to match with backend log patterns.
Author: Michael Paquier
Reviewed-by: Andrew Dunstan, Daniel Gustafsson, Álvaro Herrera
Discussion: https://postgr.es/m/YGLKNBf9zyh6+WSt@paquier.xyz
2021-04-01 02:48:17 +02:00
|
|
|
|
2021-04-05 03:13:57 +02:00
|
|
|
isnt($ret, 0, $test_name);
|
|
|
|
|
|
|
|
if (defined($params{expected_stderr}))
|
|
|
|
{
|
|
|
|
like($stderr, $params{expected_stderr}, "$test_name: matches");
|
|
|
|
}
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
|
|
|
|
if (@log_like or @log_unlike)
|
|
|
|
{
|
2021-10-24 16:28:19 +02:00
|
|
|
my $log_contents =
|
|
|
|
PostgreSQL::Test::Utils::slurp_file($self->logfile, $log_location);
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
|
|
|
|
while (my $regex = shift @log_like)
|
|
|
|
{
|
|
|
|
like($log_contents, $regex, "$test_name: log matches");
|
|
|
|
}
|
|
|
|
while (my $regex = shift @log_unlike)
|
|
|
|
{
|
|
|
|
unlike($log_contents, $regex, "$test_name: log does not match");
|
|
|
|
}
|
|
|
|
}
|
Move some client-specific routines from SSLServer to PostgresNode
test_connect_ok() and test_connect_fails() have always been part of the
SSL tests, and check if a connection to the backend should work or not,
and there are sanity checks done on specific error patterns dropped by
libpq if the connection fails.
This was fundamentally wrong on two aspects. First, SSLServer.pm works
mostly on setting up and changing the SSL configuration of a
PostgresNode, and has really nothing to do with the client. Second,
the situation became worse in light of b34ca595, where the SSL tests
would finish by using a psql command that may not come from the same
installation as the node set up.
This commit moves those client routines into PostgresNode, making easier
the refactoring of SSLServer to become more SSL-implementation aware.
This can also be reused by the ldap, kerberos and authentication test
suites for connection checks, and a follow-up patch should extend those
interfaces to match with backend log patterns.
Author: Michael Paquier
Reviewed-by: Andrew Dunstan, Daniel Gustafsson, Álvaro Herrera
Discussion: https://postgr.es/m/YGLKNBf9zyh6+WSt@paquier.xyz
2021-04-01 02:48:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2017-07-02 20:03:41 +02:00
|
|
|
=item $node->poll_query_until($dbname, $query [, $expected ])
|
2016-02-26 01:31:52 +01:00
|
|
|
|
2017-07-02 20:03:41 +02:00
|
|
|
Run B<$query> repeatedly, until it returns the B<$expected> result
|
|
|
|
('t', or SQL boolean true, by default).
|
|
|
|
Continues polling if B<psql> returns an error result.
|
2022-03-05 03:53:13 +01:00
|
|
|
Times out after $PostgreSQL::Test::Utils::timeout_default seconds.
|
2017-07-02 20:03:41 +02:00
|
|
|
Returns 1 if successful, 0 if timed out.
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub poll_query_until
|
|
|
|
{
|
2017-07-02 20:03:41 +02:00
|
|
|
my ($self, $dbname, $query, $expected) = @_;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
2017-07-02 20:03:41 +02:00
|
|
|
$expected = 't' unless defined($expected); # default value
|
|
|
|
|
2021-04-20 16:14:16 +02:00
|
|
|
my $cmd = [
|
|
|
|
$self->installed_command('psql'), '-XAt',
|
2021-06-03 22:08:33 +02:00
|
|
|
'-d', $self->connstr($dbname)
|
2021-04-20 16:14:16 +02:00
|
|
|
];
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
my ($stdout, $stderr);
|
2022-03-05 03:53:13 +01:00
|
|
|
my $max_attempts = 10 * $PostgreSQL::Test::Utils::timeout_default;
|
2017-07-02 20:03:41 +02:00
|
|
|
my $attempts = 0;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
|
|
|
while ($attempts < $max_attempts)
|
|
|
|
{
|
2021-06-03 22:08:33 +02:00
|
|
|
my $result = IPC::Run::run $cmd, '<', \$query,
|
|
|
|
'>', \$stdout, '2>', \$stderr;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
|
|
|
chomp($stdout);
|
Restore robustness of TAP tests that wait for postmaster restart.
Several TAP tests use poll_query_until() to wait for the postmaster
to restart. They were checking to see if a trivial query
(e.g. "SELECT 1") succeeds. However, that's problematic in the wake
of commit 11e9caff8, because now that we feed said query to psql
via stdin, we risk IPC::Run whining about a SIGPIPE failure if psql
quits before reading the query. Hence, we can't use a nonempty
query in cases where we need to wait for connection failures to
stop happening.
Per the precedent of commits c757a3da0 and 6d41dd045, we can pass
"undef" as the query in such cases to ensure that IPC::Run has
nothing to write. However, then we have to say that the expected
output is empty, and this exposes a deficiency in poll_query_until:
if psql fails altogether and returns empty stdout, poll_query_until
will treat that as a success! That's because, contrary to its
documentation, it makes no actual check for psql failure, looking
neither at the exit status nor at stderr.
To fix that, adjust poll_query_until to insist on empty stderr as
well as a stdout match. (I experimented with checking exit status
instead, but it seems that psql often does exit(1) in cases that we
need to consider successes. That might be something to fix someday,
but it would be a non-back-patchable behavior change.)
Back-patch to v10. The test cases needing this exist only as far
back as v11, but it seems wise to keep poll_query_until's behavior
the same in v10, in case we back-patch another such test case in
future. (9.6 does not currently need this change, because in that
branch poll_query_until can't be told to accept empty stdout as
a success case.)
Per assorted buildfarm failures, mostly on hoverfly.
Discussion: https://postgr.es/m/CAA4eK1+zM6L4QSA1XMvXY_qqWwdUmqkOS1+hWvL8QcYEBGA1Uw@mail.gmail.com
2021-06-12 21:12:10 +02:00
|
|
|
chomp($stderr);
|
2017-07-02 20:03:41 +02:00
|
|
|
|
Restore robustness of TAP tests that wait for postmaster restart.
Several TAP tests use poll_query_until() to wait for the postmaster
to restart. They were checking to see if a trivial query
(e.g. "SELECT 1") succeeds. However, that's problematic in the wake
of commit 11e9caff8, because now that we feed said query to psql
via stdin, we risk IPC::Run whining about a SIGPIPE failure if psql
quits before reading the query. Hence, we can't use a nonempty
query in cases where we need to wait for connection failures to
stop happening.
Per the precedent of commits c757a3da0 and 6d41dd045, we can pass
"undef" as the query in such cases to ensure that IPC::Run has
nothing to write. However, then we have to say that the expected
output is empty, and this exposes a deficiency in poll_query_until:
if psql fails altogether and returns empty stdout, poll_query_until
will treat that as a success! That's because, contrary to its
documentation, it makes no actual check for psql failure, looking
neither at the exit status nor at stderr.
To fix that, adjust poll_query_until to insist on empty stderr as
well as a stdout match. (I experimented with checking exit status
instead, but it seems that psql often does exit(1) in cases that we
need to consider successes. That might be something to fix someday,
but it would be a non-back-patchable behavior change.)
Back-patch to v10. The test cases needing this exist only as far
back as v11, but it seems wise to keep poll_query_until's behavior
the same in v10, in case we back-patch another such test case in
future. (9.6 does not currently need this change, because in that
branch poll_query_until can't be told to accept empty stdout as
a success case.)
Per assorted buildfarm failures, mostly on hoverfly.
Discussion: https://postgr.es/m/CAA4eK1+zM6L4QSA1XMvXY_qqWwdUmqkOS1+hWvL8QcYEBGA1Uw@mail.gmail.com
2021-06-12 21:12:10 +02:00
|
|
|
if ($stdout eq $expected && $stderr eq '')
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-07-02 20:03:41 +02:00
|
|
|
# Wait 0.1 second before retrying.
|
2017-07-17 21:35:19 +02:00
|
|
|
usleep(100_000);
|
2017-07-02 20:03:41 +02:00
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
$attempts++;
|
|
|
|
}
|
|
|
|
|
2022-03-05 03:53:13 +01:00
|
|
|
# Give up. Print the output from the last attempt, hopefully that's useful
|
|
|
|
# for debugging.
|
2018-10-16 18:27:14 +02:00
|
|
|
diag qq(poll_query_until timed out executing this query:
|
|
|
|
$query
|
|
|
|
expecting this output:
|
|
|
|
$expected
|
|
|
|
last actual query output:
|
|
|
|
$stdout
|
|
|
|
with stderr:
|
|
|
|
$stderr);
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->command_ok(...)
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
Runs a shell command like PostgreSQL::Test::Utils::command_ok, but with PGHOST and PGPORT set
|
|
|
|
so that the command will default to connecting to this PostgreSQL::Test::Cluster.
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub command_ok
|
|
|
|
{
|
2018-05-22 20:25:01 +02:00
|
|
|
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
my $self = shift;
|
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
local %ENV = $self->_get_env();
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::command_ok(@_);
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
2017-09-08 15:32:50 +02:00
|
|
|
=item $node->command_fails(...)
|
2016-02-26 01:31:52 +01:00
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::command_fails with our connection parameters. See command_ok(...)
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub command_fails
|
|
|
|
{
|
2018-05-22 20:25:01 +02:00
|
|
|
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
my $self = shift;
|
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
local %ENV = $self->_get_env();
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::command_fails(@_);
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->command_like(...)
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::command_like with our connection parameters. See command_ok(...)
|
2016-02-26 01:31:52 +01:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub command_like
|
|
|
|
{
|
2018-05-22 20:25:01 +02:00
|
|
|
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
my $self = shift;
|
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
local %ENV = $self->_get_env();
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::command_like(@_);
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
2021-09-01 03:28:01 +02:00
|
|
|
=item $node->command_fails_like(...)
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::command_fails_like with our connection parameters. See command_ok(...)
|
2021-09-01 03:28:01 +02:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub command_fails_like
|
|
|
|
{
|
|
|
|
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
|
|
|
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::command_fails_like(@_);
|
2021-09-01 03:28:01 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2017-09-08 15:32:50 +02:00
|
|
|
=item $node->command_checks_all(...)
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::command_checks_all with our connection parameters. See
|
2019-04-13 07:36:38 +02:00
|
|
|
command_ok(...)
|
2017-09-08 15:32:50 +02:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub command_checks_all
|
|
|
|
{
|
2018-05-22 20:25:01 +02:00
|
|
|
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
|
|
|
|
2017-09-08 15:32:50 +02:00
|
|
|
my $self = shift;
|
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
local %ENV = $self->_get_env();
|
2017-09-08 15:32:50 +02:00
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
PostgreSQL::Test::Utils::command_checks_all(@_);
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
2017-09-08 15:32:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=item $node->issues_sql_like(cmd, expected_sql, test_name)
|
|
|
|
|
|
|
|
Run a command on the node, then verify that $expected_sql appears in the
|
|
|
|
server log file.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
sub issues_sql_like
|
|
|
|
{
|
2018-05-22 20:25:01 +02:00
|
|
|
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
my ($self, $cmd, $expected_sql, $test_name) = @_;
|
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
local %ENV = $self->_get_env();
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2021-04-16 22:54:04 +02:00
|
|
|
my $log_location = -s $self->logfile;
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
my $result = PostgreSQL::Test::Utils::run_log($cmd);
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
ok($result, "@$cmd exit code 0");
|
2021-10-24 16:28:19 +02:00
|
|
|
my $log =
|
|
|
|
PostgreSQL::Test::Utils::slurp_file($self->logfile, $log_location);
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
like($log, $expected_sql, "$test_name: SQL found in server log");
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
}
|
|
|
|
|
2023-03-29 21:53:38 +02:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->log_content()
|
|
|
|
|
|
|
|
Returns the contents of log of the node
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub log_content
|
|
|
|
{
|
|
|
|
my ($self) = @_;
|
|
|
|
return PostgreSQL::Test::Utils::slurp_file($self->logfile);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=pod
|
|
|
|
|
2016-08-04 20:44:23 +02:00
|
|
|
=item $node->run_log(...)
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
Runs a shell command like PostgreSQL::Test::Utils::run_log, but with connection parameters set
|
|
|
|
so that the command will default to connecting to this PostgreSQL::Test::Cluster.
|
2016-08-04 20:44:23 +02:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub run_log
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
|
2021-03-24 23:52:25 +01:00
|
|
|
local %ENV = $self->_get_env();
|
2016-08-04 20:44:23 +02:00
|
|
|
|
2022-03-29 22:29:49 +02:00
|
|
|
return PostgreSQL::Test::Utils::run_log(@_);
|
2016-08-04 20:44:23 +02:00
|
|
|
}
|
|
|
|
|
2017-01-05 11:07:59 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->lsn(mode)
|
2017-01-04 17:50:23 +01:00
|
|
|
|
2017-05-11 17:49:59 +02:00
|
|
|
Look up WAL locations on the server:
|
2017-01-04 17:50:23 +01:00
|
|
|
|
2020-06-14 20:47:37 +02:00
|
|
|
* insert location (primary only, error on replica)
|
|
|
|
* write location (primary only, error on replica)
|
|
|
|
* flush location (primary only, error on replica)
|
|
|
|
* receive location (always undef on primary)
|
|
|
|
* replay location (always undef on primary)
|
2017-01-04 17:50:23 +01:00
|
|
|
|
|
|
|
mode must be specified.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub lsn
|
|
|
|
{
|
|
|
|
my ($self, $mode) = @_;
|
2017-05-11 17:49:59 +02:00
|
|
|
my %modes = (
|
|
|
|
'insert' => 'pg_current_wal_insert_lsn()',
|
|
|
|
'flush' => 'pg_current_wal_flush_lsn()',
|
|
|
|
'write' => 'pg_current_wal_lsn()',
|
|
|
|
'receive' => 'pg_last_wal_receive_lsn()',
|
|
|
|
'replay' => 'pg_last_wal_replay_lsn()');
|
2017-01-04 17:50:23 +01:00
|
|
|
|
|
|
|
$mode = '<undef>' if !defined($mode);
|
2018-02-24 20:35:54 +01:00
|
|
|
croak "unknown mode for 'lsn': '$mode', valid modes are "
|
2017-01-04 17:50:23 +01:00
|
|
|
. join(', ', keys %modes)
|
|
|
|
if !defined($modes{$mode});
|
|
|
|
|
|
|
|
my $result = $self->safe_psql('postgres', "SELECT $modes{$mode}");
|
|
|
|
chomp($result);
|
|
|
|
if ($result eq '')
|
|
|
|
{
|
2017-03-27 04:24:13 +02:00
|
|
|
return;
|
2017-01-04 17:50:23 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-05 11:07:59 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->wait_for_catchup(standby_name, mode, target_lsn)
|
2017-01-04 17:50:23 +01:00
|
|
|
|
Clean up TAP tests' usage of wait_for_catchup().
By default, wait_for_catchup() waits for the replication connection
to reach the primary's write LSN. That's fine, but in an apparent
attempt to save one query round-trip, it was coded so that we
executed pg_current_wal_lsn() again during each probe query.
Thus, we presented the standby with a moving target to be reached.
(While the test script itself couldn't be causing the write LSN
to advance while it's blocked in wait_for_catchup(), it's plenty
plausible that background activity such as autovacuum is emitting
more WAL.) That could make the test take longer than necessary,
and potentially it could mask bugs by allowing the standby to process
more WAL than a strict interpretation of the test scenario allows.
So, change wait_for_catchup() to do it "by the book", explicitly
collecting the write LSN to wait for at the outset.
Also, various call sites were instructing wait_for_catchup() to
wait for the standby to reach the primary's insert LSN rather than
its write LSN. This also seems like a bad idea. While in most
test scenarios those are the same, if they are different then the
inserted-but-not-yet-written WAL is not presently available to the
standby. The test isn't doing anything to make it become so, so
again we have the potential for unwanted test delay, perhaps even
a test timeout. (Again, background activity would be needed to
make this more than a hypothetical problem.) Hence, change the
callers where necessary so that the wait target is always the
primary's write LSN.
While at it, simplify callers by making use of wait_for_catchup's
default arguments wherever possible (the preceding change makes
this possible in more places than it was before). And rewrite
wait_for_catchup's documentation a bit.
Patch by me; thanks to Julien Rouhaud for review.
Discussion: https://postgr.es/m/2368336.1641843098@sss.pgh.pa.us
2022-01-16 19:29:02 +01:00
|
|
|
Wait for the replication connection with application_name standby_name until
|
|
|
|
its 'mode' replication column in pg_stat_replication equals or passes the
|
|
|
|
specified or default target_lsn. By default the replay_lsn is waited for,
|
|
|
|
but 'mode' may be specified to wait for any of sent|write|flush|replay.
|
|
|
|
The replication connection must be in a streaming state.
|
|
|
|
|
|
|
|
When doing physical replication, the standby is usually identified by
|
|
|
|
passing its PostgreSQL::Test::Cluster instance. When doing logical
|
|
|
|
replication, standby_name identifies a subscription.
|
|
|
|
|
2023-04-27 10:52:53 +02:00
|
|
|
When not in recovery, the default value of target_lsn is $node->lsn('write'),
|
|
|
|
which ensures that the standby has caught up to what has been committed on
|
|
|
|
the primary.
|
|
|
|
|
|
|
|
When in recovery, the default value of target_lsn is $node->lsn('replay')
|
|
|
|
instead which ensures that the cascaded standby has caught up to what has been
|
|
|
|
replayed on the standby.
|
|
|
|
|
Clean up TAP tests' usage of wait_for_catchup().
By default, wait_for_catchup() waits for the replication connection
to reach the primary's write LSN. That's fine, but in an apparent
attempt to save one query round-trip, it was coded so that we
executed pg_current_wal_lsn() again during each probe query.
Thus, we presented the standby with a moving target to be reached.
(While the test script itself couldn't be causing the write LSN
to advance while it's blocked in wait_for_catchup(), it's plenty
plausible that background activity such as autovacuum is emitting
more WAL.) That could make the test take longer than necessary,
and potentially it could mask bugs by allowing the standby to process
more WAL than a strict interpretation of the test scenario allows.
So, change wait_for_catchup() to do it "by the book", explicitly
collecting the write LSN to wait for at the outset.
Also, various call sites were instructing wait_for_catchup() to
wait for the standby to reach the primary's insert LSN rather than
its write LSN. This also seems like a bad idea. While in most
test scenarios those are the same, if they are different then the
inserted-but-not-yet-written WAL is not presently available to the
standby. The test isn't doing anything to make it become so, so
again we have the potential for unwanted test delay, perhaps even
a test timeout. (Again, background activity would be needed to
make this more than a hypothetical problem.) Hence, change the
callers where necessary so that the wait target is always the
primary's write LSN.
While at it, simplify callers by making use of wait_for_catchup's
default arguments wherever possible (the preceding change makes
this possible in more places than it was before). And rewrite
wait_for_catchup's documentation a bit.
Patch by me; thanks to Julien Rouhaud for review.
Discussion: https://postgr.es/m/2368336.1641843098@sss.pgh.pa.us
2022-01-16 19:29:02 +01:00
|
|
|
If you pass an explicit value of target_lsn, it should almost always be
|
|
|
|
the primary's write LSN; so this parameter is seldom needed except when
|
|
|
|
querying some intermediate replication node rather than the primary.
|
2017-01-04 17:50:23 +01:00
|
|
|
|
|
|
|
If there is no active replication connection from this peer, waits until
|
|
|
|
poll_query_until timeout.
|
|
|
|
|
|
|
|
Requires that the 'postgres' db exists and is accessible.
|
|
|
|
|
|
|
|
This is not a test. It die()s on failure.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub wait_for_catchup
|
|
|
|
{
|
|
|
|
my ($self, $standby_name, $mode, $target_lsn) = @_;
|
|
|
|
$mode = defined($mode) ? $mode : 'replay';
|
|
|
|
my %valid_modes =
|
|
|
|
('sent' => 1, 'write' => 1, 'flush' => 1, 'replay' => 1);
|
2018-02-24 20:35:54 +01:00
|
|
|
croak "unknown mode $mode for 'wait_for_catchup', valid modes are "
|
2017-01-04 17:50:23 +01:00
|
|
|
. join(', ', keys(%valid_modes))
|
|
|
|
unless exists($valid_modes{$mode});
|
2017-05-18 01:01:23 +02:00
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
# Allow passing of a PostgreSQL::Test::Cluster instance as shorthand
|
|
|
|
if (blessed($standby_name)
|
|
|
|
&& $standby_name->isa("PostgreSQL::Test::Cluster"))
|
2017-01-04 17:50:23 +01:00
|
|
|
{
|
|
|
|
$standby_name = $standby_name->name;
|
|
|
|
}
|
Clean up TAP tests' usage of wait_for_catchup().
By default, wait_for_catchup() waits for the replication connection
to reach the primary's write LSN. That's fine, but in an apparent
attempt to save one query round-trip, it was coded so that we
executed pg_current_wal_lsn() again during each probe query.
Thus, we presented the standby with a moving target to be reached.
(While the test script itself couldn't be causing the write LSN
to advance while it's blocked in wait_for_catchup(), it's plenty
plausible that background activity such as autovacuum is emitting
more WAL.) That could make the test take longer than necessary,
and potentially it could mask bugs by allowing the standby to process
more WAL than a strict interpretation of the test scenario allows.
So, change wait_for_catchup() to do it "by the book", explicitly
collecting the write LSN to wait for at the outset.
Also, various call sites were instructing wait_for_catchup() to
wait for the standby to reach the primary's insert LSN rather than
its write LSN. This also seems like a bad idea. While in most
test scenarios those are the same, if they are different then the
inserted-but-not-yet-written WAL is not presently available to the
standby. The test isn't doing anything to make it become so, so
again we have the potential for unwanted test delay, perhaps even
a test timeout. (Again, background activity would be needed to
make this more than a hypothetical problem.) Hence, change the
callers where necessary so that the wait target is always the
primary's write LSN.
While at it, simplify callers by making use of wait_for_catchup's
default arguments wherever possible (the preceding change makes
this possible in more places than it was before). And rewrite
wait_for_catchup's documentation a bit.
Patch by me; thanks to Julien Rouhaud for review.
Discussion: https://postgr.es/m/2368336.1641843098@sss.pgh.pa.us
2022-01-16 19:29:02 +01:00
|
|
|
if (!defined($target_lsn))
|
2018-01-08 23:32:09 +01:00
|
|
|
{
|
2023-04-27 10:52:53 +02:00
|
|
|
my $isrecovery =
|
|
|
|
$self->safe_psql('postgres', "SELECT pg_is_in_recovery()");
|
|
|
|
chomp($isrecovery);
|
|
|
|
if ($isrecovery eq 't')
|
|
|
|
{
|
|
|
|
$target_lsn = $self->lsn('replay');
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$target_lsn = $self->lsn('write');
|
|
|
|
}
|
2018-01-08 23:32:09 +01:00
|
|
|
}
|
2017-05-11 17:49:59 +02:00
|
|
|
print "Waiting for replication conn "
|
|
|
|
. $standby_name . "'s "
|
|
|
|
. $mode
|
|
|
|
. "_lsn to pass "
|
Clean up TAP tests' usage of wait_for_catchup().
By default, wait_for_catchup() waits for the replication connection
to reach the primary's write LSN. That's fine, but in an apparent
attempt to save one query round-trip, it was coded so that we
executed pg_current_wal_lsn() again during each probe query.
Thus, we presented the standby with a moving target to be reached.
(While the test script itself couldn't be causing the write LSN
to advance while it's blocked in wait_for_catchup(), it's plenty
plausible that background activity such as autovacuum is emitting
more WAL.) That could make the test take longer than necessary,
and potentially it could mask bugs by allowing the standby to process
more WAL than a strict interpretation of the test scenario allows.
So, change wait_for_catchup() to do it "by the book", explicitly
collecting the write LSN to wait for at the outset.
Also, various call sites were instructing wait_for_catchup() to
wait for the standby to reach the primary's insert LSN rather than
its write LSN. This also seems like a bad idea. While in most
test scenarios those are the same, if they are different then the
inserted-but-not-yet-written WAL is not presently available to the
standby. The test isn't doing anything to make it become so, so
again we have the potential for unwanted test delay, perhaps even
a test timeout. (Again, background activity would be needed to
make this more than a hypothetical problem.) Hence, change the
callers where necessary so that the wait target is always the
primary's write LSN.
While at it, simplify callers by making use of wait_for_catchup's
default arguments wherever possible (the preceding change makes
this possible in more places than it was before). And rewrite
wait_for_catchup's documentation a bit.
Patch by me; thanks to Julien Rouhaud for review.
Discussion: https://postgr.es/m/2368336.1641843098@sss.pgh.pa.us
2022-01-16 19:29:02 +01:00
|
|
|
. $target_lsn . " on "
|
2017-05-11 17:49:59 +02:00
|
|
|
. $self->name . "\n";
|
2022-03-30 17:07:05 +02:00
|
|
|
# Before release 12 walreceiver just set the application name to
|
|
|
|
# "walreceiver"
|
|
|
|
my $query = qq[SELECT '$target_lsn' <= ${mode}_lsn AND state = 'streaming'
|
|
|
|
FROM pg_catalog.pg_stat_replication
|
|
|
|
WHERE application_name IN ('$standby_name', 'walreceiver')];
|
2022-11-12 20:19:50 +01:00
|
|
|
if (!$self->poll_query_until('postgres', $query))
|
|
|
|
{
|
|
|
|
if (PostgreSQL::Test::Utils::has_wal_read_bug)
|
|
|
|
{
|
|
|
|
# Mimic having skipped the test file. If >0 tests have run, the
|
|
|
|
# harness won't accept a skip; otherwise, it won't accept
|
|
|
|
# done_testing(). Force a nonzero count by running one test.
|
|
|
|
ok(1, 'dummy test before skip for filesystem bug');
|
|
|
|
carp "skip rest: timed out waiting for catchup & filesystem bug";
|
|
|
|
done_testing();
|
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
croak "timed out waiting for catchup";
|
|
|
|
}
|
|
|
|
}
|
2017-01-04 17:50:23 +01:00
|
|
|
print "done\n";
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
2017-01-04 17:50:23 +01:00
|
|
|
}
|
|
|
|
|
2017-01-05 11:07:59 +01:00
|
|
|
=pod
|
|
|
|
|
2023-02-13 11:52:19 +01:00
|
|
|
=item $node->wait_for_replay_catchup($standby_name [, $base_node ])
|
|
|
|
|
|
|
|
Wait for the replication connection with application_name I<$standby_name>
|
|
|
|
until its B<replay> replication column in pg_stat_replication in I<$node>
|
|
|
|
equals or passes the I<$base_node>'s B<replay_lsn>. If I<$base_node> is
|
|
|
|
omitted, the LSN to wait for is obtained from I<$node>.
|
|
|
|
|
|
|
|
The replication connection must be in a streaming state.
|
|
|
|
|
|
|
|
Requires that the 'postgres' db exists and is accessible.
|
|
|
|
|
|
|
|
This is not a test. It die()s on failure.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub wait_for_replay_catchup
|
|
|
|
{
|
|
|
|
my ($self, $standby_name, $node) = @_;
|
|
|
|
$node = defined($node) ? $node : $self;
|
|
|
|
|
|
|
|
$self->wait_for_catchup($standby_name, 'replay', $node->lsn('flush'));
|
|
|
|
}
|
|
|
|
|
2017-01-05 11:07:59 +01:00
|
|
|
=item $node->wait_for_slot_catchup(slot_name, mode, target_lsn)
|
2017-01-04 17:50:23 +01:00
|
|
|
|
|
|
|
Wait for the named replication slot to equal or pass the supplied target_lsn.
|
2017-05-11 17:49:59 +02:00
|
|
|
The location used is the restart_lsn unless mode is given, in which case it may
|
2017-01-04 17:50:23 +01:00
|
|
|
be 'restart' or 'confirmed_flush'.
|
|
|
|
|
|
|
|
Requires that the 'postgres' db exists and is accessible.
|
|
|
|
|
|
|
|
This is not a test. It die()s on failure.
|
|
|
|
|
|
|
|
If the slot is not active, will time out after poll_query_until's timeout.
|
|
|
|
|
2020-06-14 20:47:37 +02:00
|
|
|
target_lsn may be any arbitrary lsn, but is typically $primary_node->lsn('insert').
|
2017-01-04 17:50:23 +01:00
|
|
|
|
|
|
|
Note that for logical slots, restart_lsn is held down by the oldest in-progress tx.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub wait_for_slot_catchup
|
|
|
|
{
|
|
|
|
my ($self, $slot_name, $mode, $target_lsn) = @_;
|
|
|
|
$mode = defined($mode) ? $mode : 'restart';
|
|
|
|
if (!($mode eq 'restart' || $mode eq 'confirmed_flush'))
|
|
|
|
{
|
2018-02-24 20:35:54 +01:00
|
|
|
croak "valid modes are restart, confirmed_flush";
|
2017-01-04 17:50:23 +01:00
|
|
|
}
|
2018-02-24 20:35:54 +01:00
|
|
|
croak 'target lsn must be specified' unless defined($target_lsn);
|
2017-01-04 17:50:23 +01:00
|
|
|
print "Waiting for replication slot "
|
|
|
|
. $slot_name . "'s "
|
|
|
|
. $mode
|
|
|
|
. "_lsn to pass "
|
|
|
|
. $target_lsn . " on "
|
|
|
|
. $self->name . "\n";
|
|
|
|
my $query =
|
2018-04-26 17:52:52 +02:00
|
|
|
qq[SELECT '$target_lsn' <= ${mode}_lsn FROM pg_catalog.pg_replication_slots WHERE slot_name = '$slot_name';];
|
2017-01-04 17:50:23 +01:00
|
|
|
$self->poll_query_until('postgres', $query)
|
2018-02-24 20:35:54 +01:00
|
|
|
or croak "timed out waiting for catchup";
|
2017-01-04 17:50:23 +01:00
|
|
|
print "done\n";
|
2018-05-27 15:08:42 +02:00
|
|
|
return;
|
2017-01-04 17:50:23 +01:00
|
|
|
}
|
|
|
|
|
2017-01-05 11:07:59 +01:00
|
|
|
=pod
|
|
|
|
|
2022-08-03 12:01:17 +02:00
|
|
|
=item $node->wait_for_subscription_sync(publisher, subname, dbname)
|
|
|
|
|
|
|
|
Wait for all tables in pg_subscription_rel to complete the initial
|
|
|
|
synchronization (i.e to be either in 'syncdone' or 'ready' state).
|
|
|
|
|
|
|
|
If the publisher node is given, additionally, check if the subscriber has
|
|
|
|
caught up to what has been committed on the primary. This is useful to
|
|
|
|
ensure that the initial data synchronization has been completed after
|
|
|
|
creating a new subscription.
|
|
|
|
|
|
|
|
If there is no active replication connection from this peer, wait until
|
|
|
|
poll_query_until timeout.
|
|
|
|
|
|
|
|
This is not a test. It die()s on failure.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub wait_for_subscription_sync
|
|
|
|
{
|
|
|
|
my ($self, $publisher, $subname, $dbname) = @_;
|
|
|
|
my $name = $self->name;
|
|
|
|
|
|
|
|
$dbname = defined($dbname) ? $dbname : 'postgres';
|
|
|
|
|
|
|
|
# Wait for all tables to finish initial sync.
|
|
|
|
print "Waiting for all subscriptions in \"$name\" to synchronize data\n";
|
|
|
|
my $query =
|
|
|
|
qq[SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('r', 's');];
|
|
|
|
$self->poll_query_until($dbname, $query)
|
|
|
|
or croak "timed out waiting for subscriber to synchronize data";
|
|
|
|
|
|
|
|
# Then, wait for the replication to catchup if required.
|
|
|
|
if (defined($publisher))
|
|
|
|
{
|
|
|
|
croak 'subscription name must be specified' unless defined($subname);
|
|
|
|
$publisher->wait_for_catchup($subname);
|
|
|
|
}
|
|
|
|
|
|
|
|
print "done\n";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
Respect permissions within logical replication.
Prevent logical replication workers from performing insert, update,
delete, truncate, or copy commands on tables unless the subscription
owner has permission to do so.
Prevent subscription owners from circumventing row-level security by
forbidding replication into tables with row-level security policies
which the subscription owner is subject to, without regard to whether
the policy would ordinarily allow the INSERT, UPDATE, DELETE or
TRUNCATE which is being replicated. This seems sufficient for now, as
superusers, roles with bypassrls, and target table owners should still
be able to replicate despite RLS policies. We can revisit the
question of applying row-level security policies on a per-row basis if
this restriction proves too severe in practice.
Author: Mark Dilger
Reviewed-by: Jeff Davis, Andrew Dunstan, Ronan Dunklau
Discussion: https://postgr.es/m/9DFC88D3-1300-4DE8-ACBC-4CEF84399A53%40enterprisedb.com
2022-01-08 02:38:20 +01:00
|
|
|
=item $node->wait_for_log(regexp, offset)
|
|
|
|
|
|
|
|
Waits for the contents of the server log file, starting at the given offset, to
|
|
|
|
match the supplied regular expression. Checks the entire log if no offset is
|
2022-03-05 03:53:13 +01:00
|
|
|
given. Times out after $PostgreSQL::Test::Utils::timeout_default seconds.
|
Respect permissions within logical replication.
Prevent logical replication workers from performing insert, update,
delete, truncate, or copy commands on tables unless the subscription
owner has permission to do so.
Prevent subscription owners from circumventing row-level security by
forbidding replication into tables with row-level security policies
which the subscription owner is subject to, without regard to whether
the policy would ordinarily allow the INSERT, UPDATE, DELETE or
TRUNCATE which is being replicated. This seems sufficient for now, as
superusers, roles with bypassrls, and target table owners should still
be able to replicate despite RLS policies. We can revisit the
question of applying row-level security policies on a per-row basis if
this restriction proves too severe in practice.
Author: Mark Dilger
Reviewed-by: Jeff Davis, Andrew Dunstan, Ronan Dunklau
Discussion: https://postgr.es/m/9DFC88D3-1300-4DE8-ACBC-4CEF84399A53%40enterprisedb.com
2022-01-08 02:38:20 +01:00
|
|
|
|
|
|
|
If successful, returns the length of the entire log file, in bytes.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub wait_for_log
|
|
|
|
{
|
|
|
|
my ($self, $regexp, $offset) = @_;
|
|
|
|
$offset = 0 unless defined $offset;
|
|
|
|
|
2022-03-05 03:53:13 +01:00
|
|
|
my $max_attempts = 10 * $PostgreSQL::Test::Utils::timeout_default;
|
Respect permissions within logical replication.
Prevent logical replication workers from performing insert, update,
delete, truncate, or copy commands on tables unless the subscription
owner has permission to do so.
Prevent subscription owners from circumventing row-level security by
forbidding replication into tables with row-level security policies
which the subscription owner is subject to, without regard to whether
the policy would ordinarily allow the INSERT, UPDATE, DELETE or
TRUNCATE which is being replicated. This seems sufficient for now, as
superusers, roles with bypassrls, and target table owners should still
be able to replicate despite RLS policies. We can revisit the
question of applying row-level security policies on a per-row basis if
this restriction proves too severe in practice.
Author: Mark Dilger
Reviewed-by: Jeff Davis, Andrew Dunstan, Ronan Dunklau
Discussion: https://postgr.es/m/9DFC88D3-1300-4DE8-ACBC-4CEF84399A53%40enterprisedb.com
2022-01-08 02:38:20 +01:00
|
|
|
my $attempts = 0;
|
|
|
|
|
|
|
|
while ($attempts < $max_attempts)
|
|
|
|
{
|
|
|
|
my $log =
|
|
|
|
PostgreSQL::Test::Utils::slurp_file($self->logfile, $offset);
|
|
|
|
|
|
|
|
return $offset + length($log) if ($log =~ m/$regexp/);
|
|
|
|
|
|
|
|
# Wait 0.1 second before retrying.
|
|
|
|
usleep(100_000);
|
|
|
|
|
|
|
|
$attempts++;
|
|
|
|
}
|
|
|
|
|
|
|
|
croak "timed out waiting for match: $regexp";
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2017-01-05 11:07:59 +01:00
|
|
|
=item $node->query_hash($dbname, $query, @columns)
|
2017-01-04 17:50:23 +01:00
|
|
|
|
|
|
|
Execute $query on $dbname, replacing any appearance of the string __COLUMNS__
|
|
|
|
within the query with a comma-separated list of @columns.
|
|
|
|
|
|
|
|
If __COLUMNS__ does not appear in the query, its result columns must EXACTLY
|
|
|
|
match the order and number (but not necessarily alias) of supplied @columns.
|
|
|
|
|
|
|
|
The query must return zero or one rows.
|
|
|
|
|
|
|
|
Return a hash-ref representation of the results of the query, with any empty
|
|
|
|
or null results as defined keys with an empty-string value. There is no way
|
|
|
|
to differentiate between null and empty-string result fields.
|
|
|
|
|
|
|
|
If the query returns zero rows, return a hash with all columns empty. There
|
|
|
|
is no way to differentiate between zero rows returned and a row with only
|
|
|
|
null columns.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub query_hash
|
|
|
|
{
|
|
|
|
my ($self, $dbname, $query, @columns) = @_;
|
2018-02-24 20:35:54 +01:00
|
|
|
croak 'calls in array context for multi-row results not supported yet'
|
2017-01-04 17:50:23 +01:00
|
|
|
if (wantarray);
|
2017-05-18 01:01:23 +02:00
|
|
|
|
2017-01-04 17:50:23 +01:00
|
|
|
# Replace __COLUMNS__ if found
|
|
|
|
substr($query, index($query, '__COLUMNS__'), length('__COLUMNS__')) =
|
|
|
|
join(', ', @columns)
|
|
|
|
if index($query, '__COLUMNS__') >= 0;
|
|
|
|
my $result = $self->safe_psql($dbname, $query);
|
2017-05-18 01:01:23 +02:00
|
|
|
|
2017-01-04 17:50:23 +01:00
|
|
|
# hash slice, see http://stackoverflow.com/a/16755894/398670 .
|
|
|
|
#
|
|
|
|
# Fills the hash with empty strings produced by x-operator element
|
|
|
|
# duplication if result is an empty row
|
|
|
|
#
|
|
|
|
my %val;
|
|
|
|
@val{@columns} =
|
2017-07-02 23:22:09 +02:00
|
|
|
$result ne '' ? split(qr/\|/, $result, -1) : ('',) x scalar(@columns);
|
2017-01-04 17:50:23 +01:00
|
|
|
return \%val;
|
|
|
|
}
|
|
|
|
|
2017-01-05 11:07:59 +01:00
|
|
|
=pod
|
|
|
|
|
|
|
|
=item $node->slot(slot_name)
|
2017-01-04 17:50:23 +01:00
|
|
|
|
|
|
|
Return hash-ref of replication slot data for the named slot, or a hash-ref with
|
|
|
|
all values '' if not found. Does not differentiate between null and empty string
|
|
|
|
for fields, no field is ever undef.
|
|
|
|
|
|
|
|
The restart_lsn and confirmed_flush_lsn fields are returned verbatim, and also
|
2022-09-14 04:58:13 +02:00
|
|
|
as a 2-list of [highword, lowword] integer. Since we rely on Perl 5.14 we can't
|
2017-01-04 17:50:23 +01:00
|
|
|
"use bigint", it's from 5.20, and we can't assume we have Math::Bigint from CPAN
|
|
|
|
either.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub slot
|
|
|
|
{
|
|
|
|
my ($self, $slot_name) = @_;
|
|
|
|
my @columns = (
|
|
|
|
'plugin', 'slot_type', 'datoid', 'database',
|
|
|
|
'active', 'active_pid', 'xmin', 'catalog_xmin',
|
|
|
|
'restart_lsn');
|
|
|
|
return $self->query_hash(
|
|
|
|
'postgres',
|
2018-04-26 17:52:52 +02:00
|
|
|
"SELECT __COLUMNS__ FROM pg_catalog.pg_replication_slots WHERE slot_name = '$slot_name'",
|
2017-01-04 17:50:23 +01:00
|
|
|
@columns);
|
|
|
|
}
|
|
|
|
|
2016-08-04 20:44:23 +02:00
|
|
|
=pod
|
|
|
|
|
2017-03-21 15:04:49 +01:00
|
|
|
=item $node->pg_recvlogical_upto(self, dbname, slot_name, endpos, timeout_secs, ...)
|
|
|
|
|
|
|
|
Invoke pg_recvlogical to read from slot_name on dbname until LSN endpos, which
|
|
|
|
corresponds to pg_recvlogical --endpos. Gives up after timeout (if nonzero).
|
|
|
|
|
|
|
|
Disallows pg_recvlogical from internally retrying on error by passing --no-loop.
|
|
|
|
|
|
|
|
Plugin options are passed as additional keyword arguments.
|
|
|
|
|
|
|
|
If called in scalar context, returns stdout, and die()s on timeout or nonzero return.
|
|
|
|
|
|
|
|
If called in array context, returns a tuple of (retval, stdout, stderr, timeout).
|
|
|
|
timeout is the IPC::Run::Timeout object whose is_expired method can be tested
|
|
|
|
to check for timeout. retval is undef on timeout.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub pg_recvlogical_upto
|
|
|
|
{
|
|
|
|
my ($self, $dbname, $slot_name, $endpos, $timeout_secs, %plugin_options)
|
|
|
|
= @_;
|
2021-03-24 23:52:25 +01:00
|
|
|
|
|
|
|
local %ENV = $self->_get_env();
|
|
|
|
|
2017-03-21 15:04:49 +01:00
|
|
|
my ($stdout, $stderr);
|
|
|
|
|
|
|
|
my $timeout_exception = 'pg_recvlogical timed out';
|
|
|
|
|
2018-02-24 20:35:54 +01:00
|
|
|
croak 'slot name must be specified' unless defined($slot_name);
|
|
|
|
croak 'endpos must be specified' unless defined($endpos);
|
2017-03-21 15:04:49 +01:00
|
|
|
|
|
|
|
my @cmd = (
|
2021-04-20 16:14:16 +02:00
|
|
|
$self->installed_command('pg_recvlogical'),
|
|
|
|
'-S', $slot_name, '--dbname', $self->connstr($dbname));
|
2017-03-21 15:04:49 +01:00
|
|
|
push @cmd, '--endpos', $endpos;
|
|
|
|
push @cmd, '-f', '-', '--no-loop', '--start';
|
|
|
|
|
|
|
|
while (my ($k, $v) = each %plugin_options)
|
|
|
|
{
|
2018-02-24 20:35:54 +01:00
|
|
|
croak "= is not permitted to appear in replication option name"
|
2017-03-21 15:04:49 +01:00
|
|
|
if ($k =~ qr/=/);
|
|
|
|
push @cmd, "-o", "$k=$v";
|
|
|
|
}
|
|
|
|
|
|
|
|
my $timeout;
|
|
|
|
$timeout =
|
|
|
|
IPC::Run::timeout($timeout_secs, exception => $timeout_exception)
|
|
|
|
if $timeout_secs;
|
|
|
|
my $ret = 0;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
local $@;
|
|
|
|
eval {
|
|
|
|
IPC::Run::run(\@cmd, ">", \$stdout, "2>", \$stderr, $timeout);
|
|
|
|
$ret = $?;
|
|
|
|
};
|
|
|
|
my $exc_save = $@;
|
|
|
|
if ($exc_save)
|
|
|
|
{
|
2017-05-18 01:01:23 +02:00
|
|
|
|
2017-03-21 15:04:49 +01:00
|
|
|
# IPC::Run::run threw an exception. re-throw unless it's a
|
|
|
|
# timeout, which we'll handle by testing is_expired
|
|
|
|
die $exc_save
|
|
|
|
if (blessed($exc_save) || $exc_save !~ qr/$timeout_exception/);
|
|
|
|
|
|
|
|
$ret = undef;
|
|
|
|
|
|
|
|
die "Got timeout exception '$exc_save' but timer not expired?!"
|
|
|
|
unless $timeout->is_expired;
|
|
|
|
|
|
|
|
die
|
2018-04-26 17:52:52 +02:00
|
|
|
"$exc_save waiting for endpos $endpos with stdout '$stdout', stderr '$stderr'"
|
2017-03-21 15:04:49 +01:00
|
|
|
unless wantarray;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
if (wantarray)
|
|
|
|
{
|
|
|
|
return ($ret, $stdout, $stderr, $timeout);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
die
|
2018-04-26 17:52:52 +02:00
|
|
|
"pg_recvlogical exited with code '$ret', stdout '$stdout' and stderr '$stderr'"
|
2017-03-21 15:04:49 +01:00
|
|
|
if $ret;
|
|
|
|
return $stdout;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
Harden TAP tests that intentionally corrupt page checksums.
The previous method for doing that was to write zeroes into a
predetermined set of page locations. However, there's a roughly
1-in-64K chance that the existing checksum will match by chance,
and yesterday several buildfarm animals started to reproducibly
see that, resulting in test failures because no checksum mismatch
was reported.
Since the checksum includes the page LSN, test success depends on
the length of the installation's WAL history, which is affected by
(at least) the initial catalog contents, the set of locales installed
on the system, and the length of the pathname of the test directory.
Sooner or later we were going to hit a chance match, and today is
that day.
Harden these tests by specifically inverting the checksum field and
leaving all else alone, thereby guaranteeing that the checksum is
incorrect.
In passing, fix places that were using seek() to set up for syswrite(),
a combination that the Perl docs very explicitly warn against. We've
probably escaped problems because no regular buffered I/O is done on
these filehandles; but if it ever breaks, we wouldn't deserve or get
much sympathy.
Although we've only seen problems in HEAD, now that we recognize the
environmental dependencies it seems like it might be just a matter
of time until someone manages to hit this in back-branch testing.
Hence, back-patch to v11 where we started doing this kind of test.
Discussion: https://postgr.es/m/3192026.1648185780@sss.pgh.pa.us
2022-03-25 19:23:26 +01:00
|
|
|
=item $node->corrupt_page_checksum(self, file, page_offset)
|
|
|
|
|
|
|
|
Intentionally corrupt the checksum field of one page in a file.
|
|
|
|
The server must be stopped for this to work reliably.
|
|
|
|
|
|
|
|
The file name should be specified relative to the cluster datadir.
|
|
|
|
page_offset had better be a multiple of the cluster's block size.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub corrupt_page_checksum
|
|
|
|
{
|
|
|
|
my ($self, $file, $page_offset) = @_;
|
|
|
|
my $pgdata = $self->data_dir;
|
|
|
|
my $pageheader;
|
|
|
|
|
|
|
|
open my $fh, '+<', "$pgdata/$file" or die "open($file) failed: $!";
|
|
|
|
binmode $fh;
|
|
|
|
sysseek($fh, $page_offset, 0) or die "sysseek failed: $!";
|
|
|
|
sysread($fh, $pageheader, 24) or die "sysread failed: $!";
|
|
|
|
# This inverts the pd_checksum field (only); see struct PageHeaderData
|
|
|
|
$pageheader ^= "\0\0\0\0\0\0\0\0\xff\xff";
|
|
|
|
sysseek($fh, $page_offset, 0) or die "sysseek failed: $!";
|
|
|
|
syswrite($fh, $pageheader) or die "syswrite failed: $!";
|
|
|
|
close $fh;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-10-19 17:09:51 +02:00
|
|
|
#
|
|
|
|
# Signal handlers
|
|
|
|
#
|
|
|
|
$SIG{TERM} = $SIG{INT} = sub {
|
|
|
|
die "death by signal";
|
|
|
|
};
|
|
|
|
|
Harden TAP tests that intentionally corrupt page checksums.
The previous method for doing that was to write zeroes into a
predetermined set of page locations. However, there's a roughly
1-in-64K chance that the existing checksum will match by chance,
and yesterday several buildfarm animals started to reproducibly
see that, resulting in test failures because no checksum mismatch
was reported.
Since the checksum includes the page LSN, test success depends on
the length of the installation's WAL history, which is affected by
(at least) the initial catalog contents, the set of locales installed
on the system, and the length of the pathname of the test directory.
Sooner or later we were going to hit a chance match, and today is
that day.
Harden these tests by specifically inverting the checksum field and
leaving all else alone, thereby guaranteeing that the checksum is
incorrect.
In passing, fix places that were using seek() to set up for syswrite(),
a combination that the Perl docs very explicitly warn against. We've
probably escaped problems because no regular buffered I/O is done on
these filehandles; but if it ever breaks, we wouldn't deserve or get
much sympathy.
Although we've only seen problems in HEAD, now that we recognize the
environmental dependencies it seems like it might be just a matter
of time until someone manages to hit this in back-branch testing.
Hence, back-patch to v11 where we started doing this kind of test.
Discussion: https://postgr.es/m/3192026.1648185780@sss.pgh.pa.us
2022-03-25 19:23:26 +01:00
|
|
|
=pod
|
|
|
|
|
2023-04-08 11:24:50 +02:00
|
|
|
=item $node->create_logical_slot_on_standby(self, primary, slot_name, dbname)
|
|
|
|
|
|
|
|
Create logical replication slot on given standby
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
sub create_logical_slot_on_standby
|
|
|
|
{
|
|
|
|
my ($self, $primary, $slot_name, $dbname) = @_;
|
|
|
|
my ($stdout, $stderr);
|
|
|
|
|
|
|
|
my $handle;
|
|
|
|
|
|
|
|
$handle = IPC::Run::start(
|
2023-05-19 23:24:48 +02:00
|
|
|
[
|
2023-04-08 11:24:50 +02:00
|
|
|
'pg_recvlogical', '-d',
|
|
|
|
$self->connstr($dbname), '-P',
|
|
|
|
'test_decoding', '-S',
|
|
|
|
$slot_name, '--create-slot'
|
|
|
|
],
|
|
|
|
'>',
|
|
|
|
\$stdout,
|
|
|
|
'2>',
|
|
|
|
\$stderr);
|
|
|
|
|
|
|
|
# Once the slot's restart_lsn is determined, the standby looks for
|
|
|
|
# xl_running_xacts WAL record from the restart_lsn onwards. First wait
|
|
|
|
# until the slot restart_lsn is determined.
|
|
|
|
|
|
|
|
$self->poll_query_until(
|
|
|
|
'postgres', qq[
|
|
|
|
SELECT restart_lsn IS NOT NULL
|
|
|
|
FROM pg_catalog.pg_replication_slots WHERE slot_name = '$slot_name'
|
|
|
|
])
|
|
|
|
or die
|
|
|
|
"timed out waiting for logical slot to calculate its restart_lsn";
|
|
|
|
|
|
|
|
# Then arrange for the xl_running_xacts record for which pg_recvlogical is
|
|
|
|
# waiting.
|
|
|
|
$primary->safe_psql('postgres', 'SELECT pg_log_standby_snapshot()');
|
|
|
|
|
|
|
|
$handle->finish();
|
|
|
|
|
|
|
|
is($self->slot($slot_name)->{'slot_type'},
|
|
|
|
'logical', $slot_name . ' on standby created')
|
|
|
|
or die "could not create slot" . $slot_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
2016-02-26 01:31:52 +01:00
|
|
|
=back
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
2022-03-30 17:07:05 +02:00
|
|
|
##########################################################################
|
|
|
|
|
|
|
|
package PostgreSQL::Test::Cluster::V_11
|
|
|
|
; ## no critic (ProhibitMultiplePackages)
|
|
|
|
|
2022-10-18 11:51:50 +02:00
|
|
|
use parent -norequire, qw(PostgreSQL::Test::Cluster);
|
2022-03-30 17:07:05 +02:00
|
|
|
|
|
|
|
# https://www.postgresql.org/docs/11/release-11.html
|
|
|
|
|
|
|
|
# max_wal_senders + superuser_reserved_connections must be < max_connections
|
|
|
|
# uses recovery.conf
|
|
|
|
|
|
|
|
sub _recovery_file { return "recovery.conf"; }
|
|
|
|
|
|
|
|
sub set_standby_mode
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
$self->append_conf("recovery.conf", "standby_mode = on\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
sub init
|
|
|
|
{
|
|
|
|
my ($self, %params) = @_;
|
|
|
|
$self->SUPER::init(%params);
|
|
|
|
$self->adjust_conf('postgresql.conf', 'max_wal_senders',
|
|
|
|
$params{allows_streaming} ? 5 : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
##########################################################################
|
|
|
|
|
|
|
|
package PostgreSQL::Test::Cluster::V_10
|
|
|
|
; ## no critic (ProhibitMultiplePackages)
|
|
|
|
|
2022-10-18 11:51:50 +02:00
|
|
|
use parent -norequire, qw(PostgreSQL::Test::Cluster::V_11);
|
2022-03-30 17:07:05 +02:00
|
|
|
|
|
|
|
# https://www.postgresql.org/docs/10/release-10.html
|
|
|
|
|
|
|
|
########################################################################
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
1;
|