aboutsummaryrefslogtreecommitdiff
path: root/src/test/authentication/t/007_pre_auth.pl
blob: 7b3765e6d253b2a9d262d397f80434eff088f247 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# 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 = 'receipt,authentication'
]);

$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 in pg_stat_activity, with the wait_event
# of the injection point.
my $pid;
while (1)
{
	$pid = $psql->query(
		qq{SELECT pid FROM pg_stat_activity
  WHERE backend_type = 'client backend'
    AND state = 'starting'
    AND wait_event = 'init-pre-auth';});
	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();