diff options
Diffstat (limited to 'src/test/authentication')
-rw-r--r-- | src/test/authentication/Makefile | 4 | ||||
-rw-r--r-- | src/test/authentication/meson.build | 4 | ||||
-rw-r--r-- | src/test/authentication/t/007_pre_auth.pl | 81 |
3 files changed, 89 insertions, 0 deletions
diff --git a/src/test/authentication/Makefile b/src/test/authentication/Makefile index c4022dc829b..8b5beced080 100644 --- a/src/test/authentication/Makefile +++ b/src/test/authentication/Makefile @@ -13,6 +13,10 @@ subdir = src/test/authentication top_builddir = ../../.. include $(top_builddir)/src/Makefile.global +EXTRA_INSTALL = src/test/modules/injection_points + +export enable_injection_points + check: $(prove_check) diff --git a/src/test/authentication/meson.build b/src/test/authentication/meson.build index f6e48411c11..800b3a5ff40 100644 --- a/src/test/authentication/meson.build +++ b/src/test/authentication/meson.build @@ -5,6 +5,9 @@ tests += { 'sd': meson.current_source_dir(), 'bd': meson.current_build_dir(), 'tap': { + 'env': { + 'enable_injection_points': get_option('injection_points') ? 'yes' : 'no', + }, 'tests': [ 't/001_password.pl', 't/002_saslprep.pl', @@ -12,6 +15,7 @@ tests += { 't/004_file_inclusion.pl', 't/005_sspi.pl', 't/006_login_trigger.pl', + 't/007_pre_auth.pl', ], }, } diff --git a/src/test/authentication/t/007_pre_auth.pl b/src/test/authentication/t/007_pre_auth.pl new file mode 100644 index 00000000000..a638226dbaf --- /dev/null +++ b/src/test/authentication/t/007_pre_auth.pl @@ -0,0 +1,81 @@ + +# Copyright (c) 2021-2025, PostgreSQL Global Development Group + +# Tests for connection behavior prior to authentication. + +use strict; +use warnings FATAL => 'all'; + +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Time::HiRes qw(usleep); +use Test::More; + +if ($ENV{enable_injection_points} ne 'yes') +{ + plan skip_all => 'Injection points not supported by this build'; +} + +my $node = PostgreSQL::Test::Cluster->new('primary'); +$node->init; +$node->append_conf( + 'postgresql.conf', q[ +log_connections = on +]); + +$node->start; + +# Check if the extension injection_points is available, as it may be +# possible that this script is run with installcheck, where the module +# would not be installed by default. +if (!$node->check_extension('injection_points')) +{ + plan skip_all => 'Extension injection_points not installed'; +} + +$node->safe_psql('postgres', 'CREATE EXTENSION injection_points'); + +# Connect to the server and inject a waitpoint. +my $psql = $node->background_psql('postgres'); +$psql->query_safe("SELECT injection_points_attach('init-pre-auth', 'wait')"); + +# From this point on, all new connections will hang during startup, just before +# authentication. Use the $psql connection handle for server interaction. +my $conn = $node->background_psql('postgres', wait => 0); + +# Wait for the connection to show up. +my $pid; +while (1) +{ + $pid = $psql->query( + "SELECT pid FROM pg_stat_activity WHERE state = 'starting';"); + last if $pid ne ""; + + usleep(100_000); +} + +note "backend $pid is authenticating"; +ok(1, 'authenticating connections are recorded in pg_stat_activity'); + +# Detach the waitpoint and wait for the connection to complete. +$psql->query_safe("SELECT injection_points_wakeup('init-pre-auth');"); +$conn->wait_connect(); + +# Make sure the pgstat entry is updated eventually. +while (1) +{ + my $state = + $psql->query("SELECT state FROM pg_stat_activity WHERE pid = $pid;"); + last if $state eq "idle"; + + note "state for backend $pid is '$state'; waiting for 'idle'..."; + usleep(100_000); +} + +ok(1, 'authenticated connections reach idle state in pg_stat_activity'); + +$psql->query_safe("SELECT injection_points_detach('init-pre-auth');"); +$psql->quit(); +$conn->quit(); + +done_testing(); |