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