Add a new helper function wait_for_file() to Utils.pm.
authorFujii Masao <fujii@postgresql.org>
Fri, 16 Jan 2026 03:35:56 +0000 (12:35 +0900)
committerFujii Masao <fujii@postgresql.org>
Fri, 16 Jan 2026 03:35:56 +0000 (12:35 +0900)
wait_for_file() waits for the contents of a specified file, starting at an
optional offset, to match a given regular expression. If no offset is
provided, the entire file is checked. The function times out after
$PostgreSQL::Test::Utils::timeout_default seconds. It returns the total
file length on success.

The existing wait_for_log() function contains almost identical logic, but
is limited to reading the cluster's log file. This commit also refactors
wait_for_log() to call wait_for_file() instead, avoiding code duplication.

This helper will be used by upcoming changes.

Suggested-by: Mircea Cadariu <cadariu.mircea@gmail.com>
Author: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: Mircea Cadariu <cadariu.mircea@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CAHGQGwFeTymZQ7RLvMU6WuDGar8bUQCazg=VOfA-9GeBkg-FzA@mail.gmail.com

src/test/perl/PostgreSQL/Test/Cluster.pm
src/test/perl/PostgreSQL/Test/Utils.pm

index 955dfc0e7f81898cb102ab610a383e6f3e47b6e5..e267ba868fed7f311cc23fa201a2b4d3b11504c3 100644 (file)
@@ -3535,25 +3535,9 @@ If successful, returns the length of the entire log file, in bytes.
 sub wait_for_log
 {
    my ($self, $regexp, $offset) = @_;
-   $offset = 0 unless defined $offset;
 
-   my $max_attempts = 10 * $PostgreSQL::Test::Utils::timeout_default;
-   my $attempts = 0;
-
-   while ($attempts < $max_attempts)
-   {
-       my $log =
-         PostgreSQL::Test::Utils::slurp_file($self->logfile, $offset);
-
-       return $offset + length($log) if ($log =~ m/$regexp/);
-
-       # Wait 0.1 second before retrying.
-       usleep(100_000);
-
-       $attempts++;
-   }
-
-   croak "timed out waiting for match: $regexp";
+   return PostgreSQL::Test::Utils::wait_for_file($self->logfile, $regexp,
+       $offset);
 }
 
 =pod
index 423b9c05ca36c8ee7495e0b937645584678ca912..ff843eecc6eb4bb08226cc555d98a12d3a27f04c 100644 (file)
@@ -58,6 +58,7 @@ use File::Temp ();
 use IPC::Run;
 use POSIX qw(locale_h);
 use PostgreSQL::Test::SimpleTee;
+use Time::HiRes qw(usleep);
 
 # We need a version of Test::More recent enough to support subtests
 use Test::More 0.98;
@@ -73,6 +74,7 @@ our @EXPORT = qw(
   chmod_recursive
   check_pg_config
   compare_files
+  wait_for_file
   dir_symlink
   scan_server_header
   system_or_bail
@@ -868,6 +870,43 @@ sub compare_files
 
 =pod
 
+=item wait_for_file(filename, regexp[, offset])
+
+Waits for the contents of the specified file, starting at the given offset, to
+match the supplied regular expression.  Checks the entire file if no offset is
+given.  Times out after $timeout_default seconds.
+
+If successful, returns the length of the entire file, in bytes.
+
+=cut
+
+sub wait_for_file
+{
+   my ($filename, $regexp, $offset) = @_;
+   $offset = 0 unless defined $offset;
+
+   my $max_attempts = 10 * $timeout_default;
+   my $attempts = 0;
+
+   while ($attempts < $max_attempts)
+   {
+       if (-e $filename)
+       {
+           my $contents = slurp_file($filename, $offset);
+           return $offset + length($contents) if ($contents =~ m/$regexp/);
+       }
+
+       # Wait 0.1 second before retrying.
+       usleep(100_000);
+
+       $attempts++;
+   }
+
+   croak "timed out waiting for file $filename contents to match: $regexp";
+}
+
+=pod
+
 =item dir_symlink(oldname, newname)
 
 Portably create a symlink for a directory. On Windows this creates a junction