diff --git a/src/test/perl/RecursiveCopy.pm b/src/test/perl/RecursiveCopy.pm index 28ecaf6db2..54459dd401 100644 --- a/src/test/perl/RecursiveCopy.pm +++ b/src/test/perl/RecursiveCopy.pm @@ -31,10 +31,12 @@ use File::Copy; Recursively copy all files and directories from $from to $to. Only regular files and subdirectories are copied. Trying to copy other types -of directory entries raises an exception. +of directory entries results in skipping those. While it would be tempting to +raise an error, it could be possible that a file or a directory is suddendly +removed while being copied or scanned. -Raises an exception if a file would be overwritten, the source directory can't -be read, or any I/O operation fails. Always returns true. +Raises an exception if a file would be overwritten or any I/O operation fails, +except if on ENOENT which is considered as a no-op. Always returns true. If the B parameter is given, it must be a subroutine reference. This subroutine will be called for each entry in the source directory with its @@ -91,10 +93,9 @@ sub _copypath_recurse # Check for symlink -- needed only on source dir die "Cannot operate on symlinks" if -l $srcpath; - # Can't handle symlinks or other weird things - die "Source path \"$srcpath\" is not a regular file or directory" - unless -f $srcpath - or -d $srcpath; + # Can't handle symlinks or other weird things. A missing file or + # directory is also a no-op. + return 1 unless -f $srcpath or -d $srcpath; # Abort if destination path already exists. Should we allow directories # to exist already? @@ -104,15 +105,41 @@ sub _copypath_recurse # same name and we're done. if (-f $srcpath) { - copy($srcpath, $destpath) - or die "copy $srcpath -> $destpath failed: $!"; + unless (copy($srcpath, $destpath)) + { + # Ignore ENOENT to prevent problems where the file whose copy + # is attempted gets suddendly removed. + if ($!{ENOENT}) + { + warn "copy $srcpath -> $destpath failed: $!"; + } + else + { + die "copy $srcpath -> $destpath failed: $!"; + } + } return 1; } # Otherwise this is directory: create it on dest and recurse onto it. mkdir($destpath) or die "mkdir($destpath) failed: $!"; - opendir(my $directory, $srcpath) or die "could not opendir($srcpath): $!"; + my $directory; + unless (opendir($directory, $srcpath)) + { + # Ignore ENOENT to prevent problems where the directory whose + # scan is done gets suddendly removed. + if ($!{ENOENT}) + { + warn "could not opendir($srcpath): $!"; + return 1; + } + else + { + die "could not opendir($srcpath): $!"; + } + } + while (my $entry = readdir($directory)) { next if ($entry eq '.' or $entry eq '..'); diff --git a/src/test/recovery/t/010_logical_decoding_timelines.pl b/src/test/recovery/t/010_logical_decoding_timelines.pl index edc0219c9c..5620450acf 100644 --- a/src/test/recovery/t/010_logical_decoding_timelines.pl +++ b/src/test/recovery/t/010_logical_decoding_timelines.pl @@ -24,7 +24,6 @@ use warnings; use PostgresNode; use TestLib; use Test::More tests => 13; -use RecursiveCopy; use File::Copy; use IPC::Run (); use Scalar::Util qw(blessed);