mirror of https://github.com/postgres/postgres
This commit provides testig coverage for ccd38024bc
, checking that a
role granted pg_signal_autovacuum_worker is able to stop a vacuum
worker.
An injection point with a wait is placed at the beginning of autovacuum
worker startup to make sure that a worker is still alive when sending
and processing the signal sent.
Author: Anthony Leung, Michael Paquier, Kirill Reshke
Reviewed-by: Andrey Borodin, Nathan Bossart
Discussion: https://postgr.es/m/CALdSSPiQPuuQpOkF7x0g2QkA5eE-3xXt7hiJFvShV1bHKDvf8w@mail.gmail.com
pull/167/head
parent
47ecbfdfcc
commit
d2b74882ca
@ -0,0 +1,95 @@ |
||||
# Copyright (c) 2024, PostgreSQL Global Development Group |
||||
|
||||
# Test signaling autovacuum worker with pg_signal_autovacuum_worker. |
||||
# |
||||
# Only roles with privileges of pg_signal_autovacuum_worker are allowed to |
||||
# signal autovacuum workers. This test uses an injection point located |
||||
# at the beginning of the autovacuum worker startup. |
||||
|
||||
use strict; |
||||
use warnings; |
||||
use PostgreSQL::Test::Cluster; |
||||
use Test::More; |
||||
|
||||
if ($ENV{enable_injection_points} ne 'yes') |
||||
{ |
||||
plan skip_all => 'Injection points not supported by this build'; |
||||
} |
||||
|
||||
# Initialize postgres |
||||
my $psql_err = ''; |
||||
my $psql_out = ''; |
||||
my $node = PostgreSQL::Test::Cluster->new('node'); |
||||
$node->init; |
||||
|
||||
# This ensures a quick worker spawn. |
||||
$node->append_conf('postgresql.conf', 'autovacuum_naptime = 1'); |
||||
$node->start; |
||||
$node->safe_psql('postgres', 'CREATE EXTENSION injection_points;'); |
||||
|
||||
$node->safe_psql( |
||||
'postgres', qq( |
||||
CREATE ROLE regress_regular_role; |
||||
CREATE ROLE regress_worker_role; |
||||
GRANT pg_signal_autovacuum_worker TO regress_worker_role; |
||||
)); |
||||
|
||||
# From this point, autovacuum worker will wait at startup. |
||||
$node->safe_psql('postgres', |
||||
"SELECT injection_points_attach('autovacuum-worker-start', 'wait');"); |
||||
|
||||
# Accelerate worker creation in case we reach this point before the naptime |
||||
# ends. |
||||
$node->reload(); |
||||
|
||||
# Wait until an autovacuum worker starts. |
||||
$node->wait_for_event('autovacuum worker', 'autovacuum-worker-start'); |
||||
|
||||
# And grab one of them. |
||||
my $av_pid = $node->safe_psql( |
||||
'postgres', qq( |
||||
SELECT pid FROM pg_stat_activity WHERE backend_type = 'autovacuum worker' AND wait_event = 'autovacuum-worker-start' LIMIT 1; |
||||
)); |
||||
|
||||
# Regular role cannot terminate autovacuum worker. |
||||
my $terminate_with_no_pg_signal_av = $node->psql( |
||||
'postgres', qq( |
||||
SET ROLE regress_regular_role; |
||||
SELECT pg_terminate_backend('$av_pid'); |
||||
), |
||||
stdout => \$psql_out, |
||||
stderr => \$psql_err); |
||||
|
||||
like( |
||||
$psql_err, |
||||
qr/ERROR: permission denied to terminate process\nDETAIL: Only roles with privileges of the "pg_signal_autovacuum_worker" role may terminate autovacuum workers./, |
||||
"autovacuum worker not signaled with regular role"); |
||||
|
||||
my $offset = -s $node->logfile; |
||||
|
||||
# Role with pg_signal_autovacuum can terminate autovacuum worker. |
||||
my $terminate_with_pg_signal_av = $node->psql( |
||||
'postgres', qq( |
||||
SET ROLE regress_worker_role; |
||||
SELECT pg_terminate_backend('$av_pid'); |
||||
), |
||||
stdout => \$psql_out, |
||||
stderr => \$psql_err); |
||||
|
||||
# Wait for the autovacuum worker to exit before scanning the logs. |
||||
$node->poll_query_until('postgres', |
||||
"SELECT count(*) = 0 FROM pg_stat_activity " |
||||
. "WHERE pid = '$av_pid' AND backend_type = 'autovacuum worker';"); |
||||
|
||||
# Check that the primary server logs a FATAL indicating that autovacuum |
||||
# is terminated. |
||||
ok( $node->log_contains( |
||||
qr/FATAL: terminating autovacuum process due to administrator command/, |
||||
$offset), |
||||
"autovacuum worker signaled with pg_signal_autovacuum_worker granted"); |
||||
|
||||
# Release injection point. |
||||
$node->safe_psql('postgres', |
||||
"SELECT injection_points_detach('autovacuum-worker-start');"); |
||||
|
||||
done_testing(); |
Loading…
Reference in new issue