#################################################################################################################################### # CommonTest.pm - Common globals used for testing #################################################################################################################################### package pgBackRestTest::Common::FileTest; #################################################################################################################################### # Perl includes #################################################################################################################################### use strict; use warnings FATAL => qw(all); use Carp qw(confess); use Cwd qw(abs_path cwd); use Exporter qw(import); our @EXPORT = qw(); use File::Basename qw(dirname); use File::Copy qw(move); use File::Path qw(remove_tree); use IO::Select; use IPC::Open3; use POSIX ':sys_wait_h'; use Symbol 'gensym'; use pgBackRestDoc::Common::Ini; use pgBackRestDoc::Common::Log; use pgBackRestDoc::Common::String; use pgBackRestTest::Common::ExecuteTest; use pgBackRestTest::Common::HostGroupTest; use pgBackRestTest::Common::LogTest; use pgBackRestTest::Common::RunTest; use pgBackRestTest::Common::StorageBase; use pgBackRestTest::Common::VmTest; use pgBackRestTest::Common::Wait; use pgBackRestTest::Env::Host::HostBaseTest; use pgBackRestTest::Env::Host::HostBackupTest; use pgBackRestTest::Env::Host::HostDbCommonTest; use pgBackRestTest::Env::Host::HostDbTest; use pgBackRestTest::Env::Host::HostS3Test; use pgBackRestTest::Env::Manifest; #################################################################################################################################### # testLinkCreate # # Create a symlink #################################################################################################################################### sub testLinkCreate { my $strLink = shift; my $strDestination = shift; # Create the file symlink($strDestination, $strLink) or confess "unable to link ${strLink} to ${strDestination}"; } push(@EXPORT, qw(testLinkCreate)); #################################################################################################################################### # testPathMode # # Set mode of an existing path. #################################################################################################################################### sub testPathMode { my $strPath = shift; my $strMode = shift; # Set the mode chmod(oct($strMode), $strPath) or confess 'unable to set mode ${strMode} for ${strPath}'; } push(@EXPORT, qw(testPathMode)); #################################################################################################################################### # testPathRemove # # Remove a path and all subpaths. #################################################################################################################################### sub testPathRemove { my $strPath = shift; my $bSuppressError = shift; executeTest('rm -rf ' . $strPath, {bSuppressError => $bSuppressError}); } push(@EXPORT, qw(testPathRemove)); #################################################################################################################################### # testFileCreate # # Create a file specifying content, mode, and time. #################################################################################################################################### sub testFileCreate { my $strFile = shift; my $strContent = shift; my $lTime = shift; my $strMode = shift; # Open the file and save strContent to it my $hFile = shift; open($hFile, '>', $strFile) or confess "unable to open ${strFile} for writing"; if (defined($strContent) && $strContent ne '') { syswrite($hFile, $strContent) or confess "unable to write to ${strFile}: $!"; } close($hFile); # Set the time if (defined($lTime)) { utime($lTime, $lTime, $strFile) or confess 'unable to set time ${lTime} for ${strPath}'; } # Set the mode chmod(oct(defined($strMode) ? $strMode : '0600'), $strFile) or confess 'unable to set mode ${strMode} for ${strFile}'; } push(@EXPORT, qw(testFileCreate)); #################################################################################################################################### # testFileRemove # # Remove a file. #################################################################################################################################### sub testFileRemove { my $strFile = shift; unlink($strFile) or confess "unable to remove ${strFile}: $!"; } push(@EXPORT, qw(testFileRemove)); #################################################################################################################################### # forceStorageMode - force mode on a file or path #################################################################################################################################### sub forceStorageMode { # Assign function parameters, defaults, and log debug info my ( $strOperation, $oStorage, $strPath, $strMode, $bRecurse ) = logDebugParam ( __PACKAGE__ . '::forceStorageMode', \@_, {name => 'oStorage'}, {name => 'strPath'}, {name => 'strMode'}, {name => 'bRecurse', optional => true, default => false}, ); # Mode commands are ignored on object storage if ($oStorage->type() ne STORAGE_OBJECT) { executeTest('chmod ' . ($bRecurse ? '-R ' : '') . "${strMode} ${strPath}"); } # Return from function and log return values if any return logDebugReturn($strOperation); } push(@EXPORT, qw(forceStorageMode)); #################################################################################################################################### # forceStorageMove - force move a directory or file #################################################################################################################################### sub forceStorageMove { # Assign function parameters, defaults, and log debug info my ( $strOperation, $oStorage, $strSourcePath, $strDestinationPath, $bRecurse, ) = logDebugParam ( __PACKAGE__ . '->forceStorageMove', \@_, {name => 'oStorage'}, {name => 'strSourcePath'}, {name => 'strDestinationPath'}, {name => 'bRecurse', optional => true, default => true}, ); # If object storage then use storage commands to remove if ($oStorage->type() eq STORAGE_OBJECT) { if ($bRecurse) { my $rhManifest = $oStorage->manifest($strSourcePath); foreach my $strName (sort(keys(%{$rhManifest}))) { if ($rhManifest->{$strName}{type} eq 'f') { $oStorage->put( "${strDestinationPath}/${strName}", ${$oStorage->get("${strSourcePath}/${strName}", {bRaw => true})}, {bRaw => true}); } } $oStorage->pathRemove($strSourcePath, {bRecurse => true}); } else { $oStorage->put($strDestinationPath, ${$oStorage->get($strSourcePath)}); $oStorage->remove($strSourcePath); } } # Else remove using filesystem commands else { executeTest("mv ${strSourcePath} ${strDestinationPath}"); } # Return from function and log return values if any return logDebugReturn($strOperation); } push(@EXPORT, qw(forceStorageMove)); #################################################################################################################################### # forceStorageRemove - force remove a file or path from storage #################################################################################################################################### sub forceStorageRemove { # Assign function parameters, defaults, and log debug info my ( $strOperation, $oStorage, $strPath, $bRecurse ) = logDebugParam ( __PACKAGE__ . '->forceStorageRemove', \@_, {name => 'oStorage'}, {name => 'strPath'}, {name => 'bRecurse', optional => true, default => false}, ); # If object storage then use storage commands to remove if ($oStorage->type() eq STORAGE_OBJECT) { $oStorage->pathRemove($strPath, {bRecurse => true}); } else { executeTest('rm -f' . ($bRecurse ? 'r ' : ' ') . $strPath); } # Return from function and log return values if any return logDebugReturn($strOperation); } push(@EXPORT, qw(forceStorageRemove)); 1;