summaryrefslogtreecommitdiffstats
path: root/src/bin/pg_ctl/t
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:19:15 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:19:15 +0000
commit6eb9c5a5657d1fe77b55cc261450f3538d35a94d (patch)
tree657d8194422a5daccecfd42d654b8a245ef7b4c8 /src/bin/pg_ctl/t
parentInitial commit. (diff)
downloadpostgresql-13-upstream.tar.xz
postgresql-13-upstream.zip
Adding upstream version 13.4.upstream/13.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/bin/pg_ctl/t')
-rw-r--r--src/bin/pg_ctl/t/001_start_stop.pl109
-rw-r--r--src/bin/pg_ctl/t/002_status.pl25
-rw-r--r--src/bin/pg_ctl/t/003_promote.pl61
-rw-r--r--src/bin/pg_ctl/t/004_logrotate.pl108
4 files changed, 303 insertions, 0 deletions
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
new file mode 100644
index 0000000..b1e419f
--- /dev/null
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -0,0 +1,109 @@
+use strict;
+use warnings;
+
+use Config;
+use Fcntl ':mode';
+use File::stat qw{lstat};
+use PostgresNode;
+use TestLib;
+use Test::More tests => 24;
+
+my $tempdir = TestLib::tempdir;
+my $tempdir_short = TestLib::tempdir_short;
+
+program_help_ok('pg_ctl');
+program_version_ok('pg_ctl');
+program_options_handling_ok('pg_ctl');
+
+command_exit_is([ 'pg_ctl', 'start', '-D', "$tempdir/nonexistent" ],
+ 1, 'pg_ctl start with nonexistent directory');
+
+command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data", '-o', '-N' ],
+ 'pg_ctl initdb');
+command_ok([ $ENV{PG_REGRESS}, '--config-auth', "$tempdir/data" ],
+ 'configure authentication');
+my $node_port = get_free_port();
+open my $conf, '>>', "$tempdir/data/postgresql.conf";
+print $conf "fsync = off\n";
+print $conf "port = $node_port\n";
+print $conf TestLib::slurp_file($ENV{TEMP_CONFIG})
+ if defined $ENV{TEMP_CONFIG};
+
+if ($use_unix_sockets)
+{
+ print $conf "listen_addresses = ''\n";
+ print $conf "unix_socket_directories = '$tempdir_short'\n";
+}
+else
+{
+ print $conf "listen_addresses = '127.0.0.1'\n";
+}
+close $conf;
+my $ctlcmd = [
+ 'pg_ctl', 'start', '-D', "$tempdir/data", '-l',
+ "$TestLib::log_path/001_start_stop_server.log"
+];
+if ($Config{osname} ne 'msys')
+{
+ command_like($ctlcmd, qr/done.*server started/s, 'pg_ctl start');
+}
+else
+{
+
+ # use the version of command_like that doesn't hang on Msys here
+ command_like_safe($ctlcmd, qr/done.*server started/s, 'pg_ctl start');
+}
+
+# sleep here is because Windows builds can't check postmaster.pid exactly,
+# so they may mistake a pre-existing postmaster.pid for one created by the
+# postmaster they start. Waiting more than the 2 seconds slop time allowed
+# by wait_for_postmaster() prevents that mistake.
+sleep 3 if ($windows_os);
+command_fails([ 'pg_ctl', 'start', '-D', "$tempdir/data" ],
+ 'second pg_ctl start fails');
+command_ok([ 'pg_ctl', 'stop', '-D', "$tempdir/data" ], 'pg_ctl stop');
+command_fails([ 'pg_ctl', 'stop', '-D', "$tempdir/data" ],
+ 'second pg_ctl stop fails');
+
+# Log file for default permission test. The permissions won't be checked on
+# Windows but we still want to do the restart test.
+my $logFileName = "$tempdir/data/perm-test-600.log";
+
+command_ok([ 'pg_ctl', 'restart', '-D', "$tempdir/data", '-l', $logFileName ],
+ 'pg_ctl restart with server not running');
+
+# Permissions on log file should be default
+SKIP:
+{
+ skip "unix-style permissions not supported on Windows", 2
+ if ($windows_os);
+
+ ok(-f $logFileName);
+ ok(check_mode_recursive("$tempdir/data", 0700, 0600));
+}
+
+# Log file for group access test
+$logFileName = "$tempdir/data/perm-test-640.log";
+
+SKIP:
+{
+ skip "group access not supported on Windows", 3 if ($windows_os);
+
+ system_or_bail 'pg_ctl', 'stop', '-D', "$tempdir/data";
+
+ # Change the data dir mode so log file will be created with group read
+ # privileges on the next start
+ chmod_recursive("$tempdir/data", 0750, 0640);
+
+ command_ok(
+ [ 'pg_ctl', 'start', '-D', "$tempdir/data", '-l', $logFileName ],
+ 'start server to check group permissions');
+
+ ok(-f $logFileName);
+ ok(check_mode_recursive("$tempdir/data", 0750, 0640));
+}
+
+command_ok([ 'pg_ctl', 'restart', '-D', "$tempdir/data" ],
+ 'pg_ctl restart with server running');
+
+system_or_bail 'pg_ctl', 'stop', '-D', "$tempdir/data";
diff --git a/src/bin/pg_ctl/t/002_status.pl b/src/bin/pg_ctl/t/002_status.pl
new file mode 100644
index 0000000..606d105
--- /dev/null
+++ b/src/bin/pg_ctl/t/002_status.pl
@@ -0,0 +1,25 @@
+use strict;
+use warnings;
+
+use PostgresNode;
+use TestLib;
+use Test::More tests => 3;
+
+my $tempdir = TestLib::tempdir;
+my $tempdir_short = TestLib::tempdir_short;
+
+command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/nonexistent" ],
+ 4, 'pg_ctl status with nonexistent directory');
+
+my $node = get_new_node('main');
+$node->init;
+
+command_exit_is([ 'pg_ctl', 'status', '-D', $node->data_dir ],
+ 3, 'pg_ctl status with server not running');
+
+system_or_bail 'pg_ctl', '-l', "$tempdir/logfile", '-D',
+ $node->data_dir, '-w', 'start';
+command_exit_is([ 'pg_ctl', 'status', '-D', $node->data_dir ],
+ 0, 'pg_ctl status with server running');
+
+system_or_bail 'pg_ctl', 'stop', '-D', $node->data_dir;
diff --git a/src/bin/pg_ctl/t/003_promote.pl b/src/bin/pg_ctl/t/003_promote.pl
new file mode 100644
index 0000000..ecb294b
--- /dev/null
+++ b/src/bin/pg_ctl/t/003_promote.pl
@@ -0,0 +1,61 @@
+use strict;
+use warnings;
+
+use PostgresNode;
+use TestLib;
+use Test::More tests => 12;
+
+my $tempdir = TestLib::tempdir;
+
+command_fails_like(
+ [ 'pg_ctl', '-D', "$tempdir/nonexistent", 'promote' ],
+ qr/directory .* does not exist/,
+ 'pg_ctl promote with nonexistent directory');
+
+my $node_primary = get_new_node('primary');
+$node_primary->init(allows_streaming => 1);
+
+command_fails_like(
+ [ 'pg_ctl', '-D', $node_primary->data_dir, 'promote' ],
+ qr/PID file .* does not exist/,
+ 'pg_ctl promote of not running instance fails');
+
+$node_primary->start;
+
+command_fails_like(
+ [ 'pg_ctl', '-D', $node_primary->data_dir, 'promote' ],
+ qr/not in standby mode/,
+ 'pg_ctl promote of primary instance fails');
+
+my $node_standby = get_new_node('standby');
+$node_primary->backup('my_backup');
+$node_standby->init_from_backup($node_primary, 'my_backup',
+ has_streaming => 1);
+$node_standby->start;
+
+is($node_standby->safe_psql('postgres', 'SELECT pg_is_in_recovery()'),
+ 't', 'standby is in recovery');
+
+command_ok([ 'pg_ctl', '-D', $node_standby->data_dir, '-W', 'promote' ],
+ 'pg_ctl -W promote of standby runs');
+
+ok( $node_standby->poll_query_until(
+ 'postgres', 'SELECT NOT pg_is_in_recovery()'),
+ 'promoted standby is not in recovery');
+
+# same again with default wait option
+$node_standby = get_new_node('standby2');
+$node_standby->init_from_backup($node_primary, 'my_backup',
+ has_streaming => 1);
+$node_standby->start;
+
+is($node_standby->safe_psql('postgres', 'SELECT pg_is_in_recovery()'),
+ 't', 'standby is in recovery');
+
+command_ok([ 'pg_ctl', '-D', $node_standby->data_dir, 'promote' ],
+ 'pg_ctl promote of standby runs');
+
+# no wait here
+
+is($node_standby->safe_psql('postgres', 'SELECT pg_is_in_recovery()'),
+ 'f', 'promoted standby is not in recovery');
diff --git a/src/bin/pg_ctl/t/004_logrotate.pl b/src/bin/pg_ctl/t/004_logrotate.pl
new file mode 100644
index 0000000..2f381e5
--- /dev/null
+++ b/src/bin/pg_ctl/t/004_logrotate.pl
@@ -0,0 +1,108 @@
+use strict;
+use warnings;
+
+use PostgresNode;
+use TestLib;
+use Test::More tests => 5;
+use Time::HiRes qw(usleep);
+
+# Set up node with logging collector
+my $node = get_new_node('primary');
+$node->init();
+$node->append_conf(
+ 'postgresql.conf', qq(
+logging_collector = on
+# these ensure stability of test results:
+log_rotation_age = 0
+lc_messages = 'C'
+));
+
+$node->start();
+
+# Verify that log output gets to the file
+
+$node->psql('postgres', 'SELECT 1/0');
+
+# might need to retry if logging collector process is slow...
+my $max_attempts = 180 * 10;
+
+my $current_logfiles;
+for (my $attempts = 0; $attempts < $max_attempts; $attempts++)
+{
+ eval {
+ $current_logfiles = slurp_file($node->data_dir . '/current_logfiles');
+ };
+ last unless $@;
+ usleep(100_000);
+}
+die $@ if $@;
+
+note "current_logfiles = $current_logfiles";
+
+like(
+ $current_logfiles,
+ qr|^stderr log/postgresql-.*log$|,
+ 'current_logfiles is sane');
+
+my $lfname = $current_logfiles;
+$lfname =~ s/^stderr //;
+chomp $lfname;
+
+my $first_logfile;
+for (my $attempts = 0; $attempts < $max_attempts; $attempts++)
+{
+ $first_logfile = slurp_file($node->data_dir . '/' . $lfname);
+ last if $first_logfile =~ m/division by zero/;
+ usleep(100_000);
+}
+
+like($first_logfile, qr/division by zero/, 'found expected log file content');
+
+# While we're at it, test pg_current_logfile() function
+is($node->safe_psql('postgres', "SELECT pg_current_logfile('stderr')"),
+ $lfname, 'pg_current_logfile() gives correct answer');
+
+# Sleep 2 seconds and ask for log rotation; this should result in
+# output into a different log file name.
+sleep(2);
+$node->logrotate();
+
+# pg_ctl logrotate doesn't wait for rotation request to be completed.
+# Allow a bit of time for it to happen.
+my $new_current_logfiles;
+for (my $attempts = 0; $attempts < $max_attempts; $attempts++)
+{
+ $new_current_logfiles = slurp_file($node->data_dir . '/current_logfiles');
+ last if $new_current_logfiles ne $current_logfiles;
+ usleep(100_000);
+}
+
+note "now current_logfiles = $new_current_logfiles";
+
+like(
+ $new_current_logfiles,
+ qr|^stderr log/postgresql-.*log$|,
+ 'new current_logfiles is sane');
+
+$lfname = $new_current_logfiles;
+$lfname =~ s/^stderr //;
+chomp $lfname;
+
+# Verify that log output gets to this file, too
+
+$node->psql('postgres', 'fee fi fo fum');
+
+my $second_logfile;
+for (my $attempts = 0; $attempts < $max_attempts; $attempts++)
+{
+ $second_logfile = slurp_file($node->data_dir . '/' . $lfname);
+ last if $second_logfile =~ m/syntax error/;
+ usleep(100_000);
+}
+
+like(
+ $second_logfile,
+ qr/syntax error/,
+ 'found expected log file content in new log file');
+
+$node->stop();