mirror of
https://github.com/postgres/postgres.git
synced 2026-01-14 02:01:53 +00:00
Fix test_misc/010_index_concurrently_upsert for cache-clobbering builds
The test script added by commit e1c971945d failed to handle the case
of cache-clobbering builds (CLOBBER_CACHE_ALWAYS and
CATCACHE_FORCE_RELEASE) properly -- it would only exit a loop on
timeout, which is slow, and unfortunate because I (Álvaro) increased the
timeout for that loop to the complete default TAP test timeout, causing
the buildfarm to report the whole test run as a timeout failure. We can
be much quicker: exit the loop as soon as the backend is seen as waiting
on the injection point.
In this commit we still reduce the timeout (of that loop and a nearby
one just to be safe) to half of the default.
I (Álvaro) had also changed Mihail's "sleep(1)" to "sleep(0.1)", which
apparently turns a 1s sleep into a 0s sleep, because Perl -- probably
making this a busy loop. Use Time::HiRes::usleep instead, like we do in
other tests.
Author: Mihail Nikalayeu <mihailnikalayeu@gmail.com>
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Discussion: https://postgr.es/m/CADzfLwWOVyJygX6BFuyuhTKkJ7uw2e8OcVCDnf6iqnOFhMPE%2BA%40mail.gmail.com
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
|
||||
# Copyright (c) 2025, PostgreSQL Global Development Group
|
||||
# Copyright (c) 2026, PostgreSQL Global Development Group
|
||||
|
||||
# Test INSERT ON CONFLICT DO UPDATE behavior concurrent with
|
||||
# CREATE INDEX CONCURRENTLY and REINDEX CONCURRENTLY.
|
||||
@ -15,6 +15,7 @@ use warnings FATAL => 'all';
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
use Test::More;
|
||||
use Time::HiRes qw(usleep);
|
||||
|
||||
plan skip_all => 'Injection points not supported by this build'
|
||||
unless $ENV{enable_injection_points} eq 'yes';
|
||||
@ -624,14 +625,16 @@ $s1->query_until(
|
||||
\echo attaching_injection_point
|
||||
SELECT injection_points_attach('invalidate-catalog-snapshot-end', 'wait');
|
||||
]);
|
||||
# In case of CLOBBER_CACHE_ALWAYS - s1 may hit the injection point during attach.
|
||||
# Wait for s1 to become idle (attach completed) or wakeup if stuck on injection point.
|
||||
|
||||
# In cases of cache clobbering, s1 may hit the injection point during attach.
|
||||
# Wait for that session to become idle (attach completed), or wake it up if
|
||||
# it becomes stuck on injection point.
|
||||
if (!wait_for_idle($node, $s1_pid))
|
||||
{
|
||||
ok_injection_point(
|
||||
$node,
|
||||
'invalidate-catalog-snapshot-end',
|
||||
's1 hit injection point during attach (CLOBBER_CACHE_ALWAYS)');
|
||||
's1 hit injection point during attach (cache clobbering mode)');
|
||||
$node->safe_psql(
|
||||
'postgres', q[
|
||||
SELECT injection_points_wakeup('invalidate-catalog-snapshot-end');
|
||||
@ -715,13 +718,16 @@ $s1->query_until(
|
||||
\echo attaching_injection_point
|
||||
SELECT injection_points_attach('invalidate-catalog-snapshot-end', 'wait');
|
||||
]);
|
||||
# In case of CLOBBER_CACHE_ALWAYS - s1 may hit the injection point during attach.
|
||||
# Wait for s1 to become idle (attach completed) or wakeup if stuck on injection point.
|
||||
|
||||
# In cases of cache clobbering, s1 may hit the injection point during attach.
|
||||
# Wait for that session to become idle (attach completed), or wake it up if
|
||||
# it becomes stuck on injection point.
|
||||
if (!wait_for_idle($node, $s1_pid))
|
||||
{
|
||||
ok_injection_point($node, 'invalidate-catalog-snapshot-end',
|
||||
'Test 8: s1 hit injection point during attach (CLOBBER_CACHE_ALWAYS)'
|
||||
);
|
||||
ok_injection_point(
|
||||
$node,
|
||||
'invalidate-catalog-snapshot-end',
|
||||
's1 hit injection point during attach (cache clobbering mode)');
|
||||
$node->safe_psql(
|
||||
'postgres', q[
|
||||
SELECT injection_points_wakeup('invalidate-catalog-snapshot-end');
|
||||
@ -793,7 +799,7 @@ done_testing();
|
||||
sub wait_for_injection_point
|
||||
{
|
||||
my ($node, $point_name, $timeout) = @_;
|
||||
$timeout //= $PostgreSQL::Test::Utils::timeout_default;
|
||||
$timeout //= $PostgreSQL::Test::Utils::timeout_default / 2;
|
||||
|
||||
for (my $elapsed = 0; $elapsed < $timeout * 10; $elapsed++)
|
||||
{
|
||||
@ -805,7 +811,7 @@ sub wait_for_injection_point
|
||||
LIMIT 1;
|
||||
]);
|
||||
return 1 if $pid ne '';
|
||||
sleep(0.1);
|
||||
usleep(100_000);
|
||||
}
|
||||
|
||||
# Timeout - report diagnostic information
|
||||
@ -833,20 +839,25 @@ sub ok_injection_point
|
||||
}
|
||||
|
||||
# Helper: Wait for a specific backend to become idle.
|
||||
# Returns true if idle, false if timeout.
|
||||
# Returns true if idle, false if waiting for injection point or timeout.
|
||||
sub wait_for_idle
|
||||
{
|
||||
my ($node, $pid, $timeout) = @_;
|
||||
$timeout //= $PostgreSQL::Test::Utils::timeout_default;
|
||||
$timeout //= $PostgreSQL::Test::Utils::timeout_default / 2;
|
||||
|
||||
for (my $elapsed = 0; $elapsed < $timeout * 10; $elapsed++)
|
||||
{
|
||||
my $state = $node->safe_psql(
|
||||
my $result = $node->safe_psql(
|
||||
'postgres', qq[
|
||||
SELECT state FROM pg_stat_activity WHERE pid = $pid;
|
||||
SELECT state, wait_event_type FROM pg_stat_activity WHERE pid = $pid;
|
||||
]);
|
||||
my ($state, $wait_event_type) = split(/\|/, $result, 2);
|
||||
$state //= '';
|
||||
$wait_event_type //= '';
|
||||
return 1 if $state eq 'idle';
|
||||
sleep(0.1);
|
||||
return 0 if $wait_event_type eq 'InjectionPoint';
|
||||
|
||||
usleep(100_000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user