1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00

manifest() and list() are working.

This commit is contained in:
David Steele 2014-06-21 18:19:37 -04:00
parent 53f1d3c78e
commit 7c161be995
3 changed files with 606 additions and 535 deletions

View File

@ -117,6 +117,24 @@ while ($strCommand ne OP_EXIT)
$oRemote->output_write(); $oRemote->output_write();
} }
elsif ($strCommand eq OP_FILE_LIST)
{
my $strOutput;
foreach my $strFile ($oFile->list(PATH_ABSOLUTE, param_get(\%oParamHash, 'path'),
param_get(\%oParamHash, 'expression', false),
param_get(\%oParamHash, 'sort_order')))
{
if (defined($strOutput))
{
$strOutput .= "\n";
}
$strOutput .= $strFile;
}
$oRemote->output_write($strOutput);
}
elsif ($strCommand eq OP_FILE_PATH_CREATE) elsif ($strCommand eq OP_FILE_PATH_CREATE)
{ {
$oFile->path_create(PATH_ABSOLUTE, param_get(\%oParamHash, 'path'), param_get(\%oParamHash, 'permission', false)); $oFile->path_create(PATH_ABSOLUTE, param_get(\%oParamHash, 'path'), param_get(\%oParamHash, 'permission', false));

View File

@ -69,7 +69,7 @@ use constant
COMMAND_ERR_LINK_READ => 5, COMMAND_ERR_LINK_READ => 5,
COMMAND_ERR_PATH_MISSING => 6, COMMAND_ERR_PATH_MISSING => 6,
COMMAND_ERR_PATH_CREATE => 7, COMMAND_ERR_PATH_CREATE => 7,
COMMAND_ERR_PARAM => 8 COMMAND_ERR_PATH_READ => 8
}; };
#################################################################################################################################### ####################################################################################################################################
@ -455,7 +455,7 @@ sub move
# Run remotely # Run remotely
if ($self->is_remote($strSourcePathType)) if ($self->is_remote($strSourcePathType))
{ {
confess "${strDebug}: remote operation not supported"; confess &log(ASSERT, "${strDebug}: remote operation not supported");
} }
# Run locally # Run locally
else else
@ -494,8 +494,7 @@ sub move
if ($strSourcePathType eq PATH_ABSOLUTE) if ($strSourcePathType eq PATH_ABSOLUTE)
{ {
print $strError; confess &log(ERROR, $strError, $iErrorCode);
exit ($iErrorCode);
} }
confess &log(ERROR, "${strDebug}: " . $strError); confess &log(ERROR, "${strDebug}: " . $strError);
@ -524,7 +523,7 @@ sub compress
# Run remotely # Run remotely
if ($self->is_remote($strPathType)) if ($self->is_remote($strPathType))
{ {
confess "${strDebug}: remote operation not supported"; confess &log(ASSERT, "${strDebug}: remote operation not supported");
} }
# Run locally # Run locally
else else
@ -532,18 +531,17 @@ sub compress
if (!gzip($strPathOp => "${strPathOp}.gz")) if (!gzip($strPathOp => "${strPathOp}.gz"))
{ {
my $strError = "${strPathOp} could not be compressed:" . $!; my $strError = "${strPathOp} could not be compressed:" . $!;
my $iErrorCode = 2; my $iErrorCode = COMMAND_ERR_FILE_READ;
unless (-e $strPathOp) if (!$self->exists($strPathType, $strFile))
{ {
$strError = "${strPathOp} does not exist"; $strError = "${strPathOp} does not exist";
$iErrorCode = 1; $iErrorCode = COMMAND_ERR_FILE_MISSING;
} }
if ($strPathType eq PATH_ABSOLUTE) if ($strPathType eq PATH_ABSOLUTE)
{ {
print $strError; confess &log(ERROR, $strError, $iErrorCode);
exit ($iErrorCode);
} }
confess &log(ERROR, "${strDebug}: " . $strError); confess &log(ERROR, "${strDebug}: " . $strError);
@ -616,7 +614,7 @@ sub path_create
# If running on command line the return directly # If running on command line the return directly
if ($strPathType eq PATH_ABSOLUTE) if ($strPathType eq PATH_ABSOLUTE)
{ {
confess &log(ERROR, $!, COMMAND_ERR_PATH_CREATE); confess &log(ERROR, $strError, COMMAND_ERR_PATH_CREATE);
} }
# Error the normal way # Error the normal way
@ -650,7 +648,7 @@ sub exists
# Build param hash # Build param hash
my %oParamHash; my %oParamHash;
$oParamHash{path} = ${strPathOp}; $oParamHash{path} = $strPathOp;
# Add remote info to debug string # Add remote info to debug string
my $strRemote = "remote (" . $self->{oRemote}->command_param_string(\%oParamHash) . ")"; my $strRemote = "remote (" . $self->{oRemote}->command_param_string(\%oParamHash) . ")";
@ -689,6 +687,292 @@ sub exists
return true; return true;
} }
####################################################################################################################################
# LIST
####################################################################################################################################
sub list
{
my $self = shift;
my $strPathType = shift;
my $strPath = shift;
my $strExpression = shift;
my $strSortOrder = shift;
# Set defaults
$strSortOrder = defined($strSortOrder) ? $strSortOrder : 'forward';
# Set operation variables
my $strPathOp = $self->path_get($strPathType, $strPath);
my @stryFileList;
# Get the root path for the file list
my $strOperation = OP_FILE_LIST;
my $strDebug = "${strPathType}:${strPathOp}" .
", expression " . (defined($strExpression) ? $strExpression : "[UNDEF]") .
", sort ${strSortOrder}";
&log(DEBUG, "${strOperation}: ${strDebug}");
# Run remotely
if ($self->is_remote($strPathType))
{
# Build param hash
my %oParamHash;
$oParamHash{path} = $strPathOp;
$oParamHash{sort_order} = $strSortOrder;
if (defined($strExpression))
{
$oParamHash{expression} = $strExpression;
}
# Add remote info to debug string
my $strRemote = "remote (" . $self->{oRemote}->command_param_string(\%oParamHash) . ")";
$strDebug = "${strOperation}: ${strRemote}: ${strDebug}";
&log(TRACE, "${strOperation}: ${strRemote}");
# Execute the command
my $strOutput = $self->{oRemote}->command_execute($strOperation, \%oParamHash, false, $strDebug);
if (defined($strOutput))
{
@stryFileList = split(/\n/, $strOutput);
}
}
# Run locally
else
{
my $hPath;
if (!opendir($hPath, $strPathOp))
{
my $strError = "${strPathOp} could not be read: " . $!;
my $iErrorCode = COMMAND_ERR_PATH_READ;
if (!$self->exists($strPathType, $strPath))
{
$strError = "${strPathOp} does not exist";
$iErrorCode = COMMAND_ERR_PATH_MISSING;
}
if ($strPathType eq PATH_ABSOLUTE)
{
confess &log(ERROR, $strError, $iErrorCode);
}
confess &log(ERROR, "${strDebug}: " . $strError);
}
@stryFileList = grep(!/^(\.)|(\.\.)$/i, readdir($hPath));
close($hPath);
if (defined($strExpression))
{
@stryFileList = grep(/$strExpression/i, @stryFileList);
}
# Reverse sort
if (defined($strSortOrder) && $strSortOrder eq "reverse")
{
@stryFileList = sort {$b cmp $a} @stryFileList;
}
# Normal sort
else
{
@stryFileList = sort @stryFileList;
}
}
# Return file list
return @stryFileList;
}
####################################################################################################################################
# MANIFEST
#
# Builds a path/file manifest starting with the base path and including all subpaths. The manifest contains all the information
# needed to perform a backup or a delta with a previous backup.
####################################################################################################################################
sub manifest
{
my $self = shift;
my $strPathType = shift;
my $strPath = shift;
my $oManifestHashRef = shift;
# Set operation variables
my $strPathOp = $self->path_get($strPathType, $strPath);
# Set operation and debug strings
my $strOperation = OP_FILE_EXISTS;
my $strDebug = "${strPathType}:${strPathOp}";
&log(DEBUG, "${strOperation}: ${strDebug}");
# Run remotely
if ($self->is_remote($strPathType))
{
confess &log(ASSERT, "${strDebug}: remote operation not supported");
}
# Run locally
else
{
manifest_recurse($strPathType, $strPathOp, undef, 0, $oManifestHashRef);
}
}
sub manifest_recurse
{
my $strPathType = shift;
my $strPathOp = shift;
my $strPathFileOp = shift;
my $iDepth = shift;
my $oManifestHashRef = shift;
my $strErrorPrefix = "File->manifest";
my $strPathRead = $strPathOp . (defined($strPathFileOp) ? "/${strPathFileOp}" : "");
my $hPath;
if (!opendir($hPath, $strPathRead))
{
my $strError = "${strPathRead} could not be read: " . $!;
my $iErrorCode = 2;
unless (-e $strPathRead)
{
$strError = "${strPathRead} does not exist";
$iErrorCode = 1;
}
if ($strPathType eq PATH_ABSOLUTE)
{
print $strError;
exit ($iErrorCode);
}
confess &log(ERROR, "${strErrorPrefix}: " . $strError);
}
my @stryFileList = grep(!/^\..$/i, readdir($hPath));
close($hPath);
foreach my $strFile (@stryFileList)
{
my $strPathFile = "${strPathRead}/$strFile";
my $bCurrentDir = $strFile eq ".";
if ($iDepth != 0)
{
if ($bCurrentDir)
{
$strFile = $strPathFileOp;
$strPathFile = $strPathRead;
}
else
{
$strFile = "${strPathFileOp}/${strFile}";
}
}
my $oStat = lstat($strPathFile);
if (!defined($oStat))
{
if (-e $strPathFile)
{
my $strError = "${strPathFile} could not be read: " . $!;
if ($strPathType eq PATH_ABSOLUTE)
{
print $strError;
exit COMMAND_ERR_FILE_READ;
}
confess &log(ERROR, "${strErrorPrefix}: " . $strError);
}
next;
}
# Check for regular file
if (S_ISREG($oStat->mode))
{
${$oManifestHashRef}{name}{"${strFile}"}{type} = "f";
# Get inode
${$oManifestHashRef}{name}{"${strFile}"}{inode} = $oStat->ino;
# Get size
${$oManifestHashRef}{name}{"${strFile}"}{size} = $oStat->size;
# Get modification time
${$oManifestHashRef}{name}{"${strFile}"}{modification_time} = $oStat->mtime;
}
# Check for directory
elsif (S_ISDIR($oStat->mode))
{
${$oManifestHashRef}{name}{"${strFile}"}{type} = "d";
}
# Check for link
elsif (S_ISLNK($oStat->mode))
{
${$oManifestHashRef}{name}{"${strFile}"}{type} = "l";
# Get link destination
${$oManifestHashRef}{name}{"${strFile}"}{link_destination} = readlink($strPathFile);
if (!defined(${$oManifestHashRef}{name}{"${strFile}"}{link_destination}))
{
if (-e $strPathFile)
{
my $strError = "${strPathFile} error reading link: " . $!;
if ($strPathType eq PATH_ABSOLUTE)
{
print $strError;
exit COMMAND_ERR_LINK_READ;
}
confess &log(ERROR, "${strErrorPrefix}: " . $strError);
}
}
}
else
{
my $strError = "${strPathFile} is not of type directory, file, or link";
if ($strPathType eq PATH_ABSOLUTE)
{
print $strError;
exit COMMAND_ERR_FILE_TYPE;
}
confess &log(ERROR, "${strErrorPrefix}: " . $strError);
}
# Get user name
${$oManifestHashRef}{name}{"${strFile}"}{user} = getpwuid($oStat->uid);
# Get group name
${$oManifestHashRef}{name}{"${strFile}"}{group} = getgrgid($oStat->gid);
# Get permissions
if (${$oManifestHashRef}{name}{"${strFile}"}{type} ne "l")
{
${$oManifestHashRef}{name}{"${strFile}"}{permission} = sprintf("%04o", S_IMODE($oStat->mode));
}
# Recurse into directories
if (${$oManifestHashRef}{name}{"${strFile}"}{type} eq "d" && !$bCurrentDir)
{
manifest_recurse($strPathType, $strPathOp,
$strFile,
$iDepth + 1, $oManifestHashRef);
}
}
}
#################################################################################################################################### ####################################################################################################################################
# COPY # COPY
# #
@ -1033,97 +1317,6 @@ sub hash
return $strHash; return $strHash;
} }
####################################################################################################################################
# LIST
####################################################################################################################################
sub list
{
my $self = shift;
my $strPathType = shift;
my $strPath = shift;
my $strExpression = shift;
my $strSortOrder = shift;
# Get the root path for the file list
my @stryFileList;
my $strErrorPrefix = "File->list";
my $bRemote = $self->is_remote($strPathType);
my $strPathOp = $self->path_get($strPathType, $strPath);
&log(TRACE, "${strErrorPrefix}: " . ($bRemote ? "remote" : "local") . " ${strPathType}:${strPathOp}" .
", expression " . (defined($strExpression) ? $strExpression : "[UNDEF]") .
", sort " . (defined($strSortOrder) ? $strSortOrder : "[UNDEF]"));
# Run remotely
if ($self->is_remote($strPathType))
{
my $strCommand = $self->{strCommand} .
(defined($strSortOrder) && $strSortOrder eq "reverse" ? " --sort=reverse" : "") .
(defined($strExpression) ? " --expression=\"" . $strExpression . "\"" : "") .
" list ${strPathOp}";
# Run via SSH
my $oSSH = $self->remote_get($strPathType);
my $strOutput = $oSSH->capture($strCommand);
# Handle any errors
if ($oSSH->error)
{
confess &log(ERROR, "${strErrorPrefix} remote (${strCommand}): " . (defined($strOutput) ? $strOutput : $oSSH->error));
}
@stryFileList = split(/\n/, $strOutput);
}
# Run locally
else
{
my $hPath;
if (!opendir($hPath, $strPathOp))
{
my $strError = "${strPathOp} could not be read:" . $!;
my $iErrorCode = 2;
unless (-e $strPath)
{
$strError = "${strPathOp} does not exist";
$iErrorCode = 1;
}
if ($strPathType eq PATH_ABSOLUTE)
{
print $strError;
exit ($iErrorCode);
}
confess &log(ERROR, "${strErrorPrefix}: " . $strError);
}
@stryFileList = grep(!/^(\.)|(\.\.)$/i, readdir($hPath));
close($hPath);
if (defined($strExpression))
{
@stryFileList = grep(/$strExpression/i, @stryFileList);
}
# Reverse sort
if (defined($strSortOrder) && $strSortOrder eq "reverse")
{
@stryFileList = sort {$b cmp $a} @stryFileList;
}
# Normal sort
else
{
@stryFileList = sort @stryFileList;
}
}
# Return file list
return @stryFileList;
}
#################################################################################################################################### ####################################################################################################################################
# REMOVE # REMOVE
#################################################################################################################################### ####################################################################################################################################
@ -1197,201 +1390,5 @@ sub remove
return $bRemoved; return $bRemoved;
} }
####################################################################################################################################
# MANIFEST
#
# Builds a path/file manifest starting with the base path and including all subpaths. The manifest contains all the information
# needed to perform a backup or a delta with a previous backup.
####################################################################################################################################
sub manifest
{
my $self = shift;
my $strPathType = shift;
my $strPath = shift;
my $oManifestHashRef = shift;
# Get the root path for the manifest
my $strErrorPrefix = "File->manifest";
my $bRemote = $self->is_remote($strPathType);
my $strPathOp = $self->path_get($strPathType, $strPath);
&log(TRACE, "${strErrorPrefix}: " . ($bRemote ? "remote" : "local") . " ${strPathType}:${strPathOp}");
# Run remotely
if ($bRemote)
{
# Build the command
my $strCommand = $self->{strCommand} . " manifest ${strPathOp}";
# Run it remotely
my $oSSH = $self->remote_get($strPathType);
my $strOutput = $oSSH->capture($strCommand);
if ($oSSH->error)
{
confess &log(ERROR, "${strErrorPrefix} remote (${strCommand}): " . (defined($strOutput) ? $strOutput : $oSSH->error));
}
return data_hash_build($oManifestHashRef, $strOutput, "\t", ".");
}
# Run locally
else
{
manifest_recurse($strPathType, $strPathOp, undef, 0, $oManifestHashRef);
}
}
sub manifest_recurse
{
my $strPathType = shift;
my $strPathOp = shift;
my $strPathFileOp = shift;
my $iDepth = shift;
my $oManifestHashRef = shift;
my $strErrorPrefix = "File->manifest";
my $strPathRead = $strPathOp . (defined($strPathFileOp) ? "/${strPathFileOp}" : "");
my $hPath;
if (!opendir($hPath, $strPathRead))
{
my $strError = "${strPathRead} could not be read:" . $!;
my $iErrorCode = 2;
unless (-e $strPathRead)
{
$strError = "${strPathRead} does not exist";
$iErrorCode = 1;
}
if ($strPathType eq PATH_ABSOLUTE)
{
print $strError;
exit ($iErrorCode);
}
confess &log(ERROR, "${strErrorPrefix}: " . $strError);
}
my @stryFileList = grep(!/^\..$/i, readdir($hPath));
close($hPath);
foreach my $strFile (@stryFileList)
{
my $strPathFile = "${strPathRead}/$strFile";
my $bCurrentDir = $strFile eq ".";
if ($iDepth != 0)
{
if ($bCurrentDir)
{
$strFile = $strPathFileOp;
$strPathFile = $strPathRead;
}
else
{
$strFile = "${strPathFileOp}/${strFile}";
}
}
my $oStat = lstat($strPathFile);
if (!defined($oStat))
{
if (-e $strPathFile)
{
my $strError = "${strPathFile} could not be read: " . $!;
if ($strPathType eq PATH_ABSOLUTE)
{
print $strError;
exit COMMAND_ERR_FILE_READ;
}
confess &log(ERROR, "${strErrorPrefix}: " . $strError);
}
next;
}
# Check for regular file
if (S_ISREG($oStat->mode))
{
${$oManifestHashRef}{name}{"${strFile}"}{type} = "f";
# Get inode
${$oManifestHashRef}{name}{"${strFile}"}{inode} = $oStat->ino;
# Get size
${$oManifestHashRef}{name}{"${strFile}"}{size} = $oStat->size;
# Get modification time
${$oManifestHashRef}{name}{"${strFile}"}{modification_time} = $oStat->mtime;
}
# Check for directory
elsif (S_ISDIR($oStat->mode))
{
${$oManifestHashRef}{name}{"${strFile}"}{type} = "d";
}
# Check for link
elsif (S_ISLNK($oStat->mode))
{
${$oManifestHashRef}{name}{"${strFile}"}{type} = "l";
# Get link destination
${$oManifestHashRef}{name}{"${strFile}"}{link_destination} = readlink($strPathFile);
if (!defined(${$oManifestHashRef}{name}{"${strFile}"}{link_destination}))
{
if (-e $strPathFile)
{
my $strError = "${strPathFile} error reading link: " . $!;
if ($strPathType eq PATH_ABSOLUTE)
{
print $strError;
exit COMMAND_ERR_LINK_READ;
}
confess &log(ERROR, "${strErrorPrefix}: " . $strError);
}
}
}
else
{
my $strError = "${strPathFile} is not of type directory, file, or link";
if ($strPathType eq PATH_ABSOLUTE)
{
print $strError;
exit COMMAND_ERR_FILE_TYPE;
}
confess &log(ERROR, "${strErrorPrefix}: " . $strError);
}
# Get user name
${$oManifestHashRef}{name}{"${strFile}"}{user} = getpwuid($oStat->uid);
# Get group name
${$oManifestHashRef}{name}{"${strFile}"}{group} = getgrgid($oStat->gid);
# Get permissions
if (${$oManifestHashRef}{name}{"${strFile}"}{type} ne "l")
{
${$oManifestHashRef}{name}{"${strFile}"}{permission} = sprintf("%04o", S_IMODE($oStat->mode));
}
# Recurse into directories
if (${$oManifestHashRef}{name}{"${strFile}"}{type} eq "d" && !$bCurrentDir)
{
manifest_recurse($strPathType, $strPathOp,
$strFile,
$iDepth + 1, $oManifestHashRef);
}
}
}
no Moose; no Moose;
__PACKAGE__->meta->make_immutable; __PACKAGE__->meta->make_immutable;

View File

@ -34,10 +34,14 @@ my $strUserBackRest;
#################################################################################################################################### ####################################################################################################################################
sub BackRestFileTestSetup sub BackRestFileTestSetup
{ {
my $bPrivate = shift;
my $bDropOnly = shift; my $bDropOnly = shift;
# Remove the backrest private directory # Remove the backrest private directory
system("ssh ${strUserBackRest}\@${strHost} 'rm -rf ${strTestPath}/\*'"); if (-e "${strTestPath}/private")
{
system("ssh ${strUserBackRest}\@${strHost} 'rm -rf ${strTestPath}/private'");
}
# Remove the test directory # Remove the test directory
system("rm -rf ${strTestPath}") == 0 or die 'unable to drop test path'; system("rm -rf ${strTestPath}") == 0 or die 'unable to drop test path';
@ -45,11 +49,14 @@ sub BackRestFileTestSetup
if (defined($bDropOnly) || !$bDropOnly) if (defined($bDropOnly) || !$bDropOnly)
{ {
# Create the test directory # Create the test directory
system("mkdir ${strTestPath}") == 0 or confess "Unable to create test directory"; mkdir($strTestPath, oct("0770")) or confess "Unable to create test directory";
# Create the backrest private directory # Create the backrest private directory
if (defined($bPrivate) && $bPrivate)
{
system("ssh backrest\@${strHost} 'mkdir -m 700 ${strTestPath}/private'") == 0 or die 'unable to create test/private path'; system("ssh backrest\@${strHost} 'mkdir -m 700 ${strTestPath}/private'") == 0 or die 'unable to create test/private path';
} }
}
} }
#################################################################################################################################### ####################################################################################################################################
@ -130,7 +137,7 @@ sub BackRestFileTest
"remote ${bRemote}, exists ${bExists}, error ${bError}, permission ${bPermission}"); "remote ${bRemote}, exists ${bExists}, error ${bError}, permission ${bPermission}");
# Setup test directory # Setup test directory
BackRestFileTestSetup(); BackRestFileTestSetup($bError);
my $strPath = "${strTestPath}/path"; my $strPath = "${strTestPath}/path";
my $strPermission; my $strPermission;
@ -255,7 +262,7 @@ sub BackRestFileTest
", dst_exists $bDestinationExists, dst_error $bDestinationError, dst_create $bCreate"); ", dst_exists $bDestinationExists, dst_error $bDestinationError, dst_create $bCreate");
# Setup test directory # Setup test directory
BackRestFileTestSetup(); BackRestFileTestSetup($bSourceError || $bDestinationError);
my $strSourceFile = "${strTestPath}/test.txt"; my $strSourceFile = "${strTestPath}/test.txt";
my $strDestinationFile = "${strTestPath}/test-dest.txt"; my $strDestinationFile = "${strTestPath}/test-dest.txt";
@ -344,7 +351,7 @@ sub BackRestFileTest
"remote $bRemote, exists $bExists, error $bError"); "remote $bRemote, exists $bExists, error $bError");
# Setup test directory # Setup test directory
BackRestFileTestSetup(); BackRestFileTestSetup($bError);
my $strFile = "${strTestPath}/test.txt"; my $strFile = "${strTestPath}/test.txt";
my $strSourceHash; my $strSourceHash;
@ -408,238 +415,287 @@ sub BackRestFileTest
#------------------------------------------------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------------------------------------------------------
# Test manifest() # Test manifest()
#------------------------------------------------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------------------------------------------------------
# if ($strTest eq 'all' || $strTest eq 'manifest') if ($strTest eq 'all' || $strTest eq 'manifest')
# { {
# $iRun = 0; $iRun = 0;
#
# &log(INFO, "--------------------------------------------------------------------------------"); &log(INFO, "--------------------------------------------------------------------------------");
# &log(INFO, "Test File->manifest()\n"); &log(INFO, "Test File->manifest()\n");
#
# # Create the test data my $strManifestCompare =
# system("rm -rf test"); ".,d,${strUser},${strGroup},0770,,,,\n" .
# "sub1,d,${strUser},${strGroup},0750,,,,\n" .
# system("mkdir -m 750 ${strTestPath}") == 0 or confess "Unable to create test directory"; "sub1/sub2,d,${strUser},${strGroup},0750,,,,\n" .
# system("mkdir -m 750 ${strTestPath}/sub1") == 0 or confess "Unable to create test directory"; "sub1/sub2/test,l,${strUser},${strGroup},,,,,../..\n" .
# system("mkdir -m 750 ${strTestPath}/sub1/sub2") == 0 or confess "Unable to create test directory"; "sub1/sub2/test-hardlink.txt,f,${strUser},${strGroup},1640,1111111111,0,9,\n" .
# "sub1/sub2/test-sub2.txt,f,${strUser},${strGroup},0666,1111111113,0,11,\n" .
# system("echo 'TESTDATA' > ${strTestPath}/test.txt"); "sub1/test,l,${strUser},${strGroup},,,,,..\n" .
# utime(1111111111, 1111111111, "${strTestPath}/test.txt"); "sub1/test-hardlink.txt,f,${strUser},${strGroup},1640,1111111111,0,9,\n" .
# system("chmod 1640 ${strTestPath}/test.txt"); "sub1/test-sub1.txt,f,${strUser},${strGroup},0646,1111111112,0,10,\n" .
# "test.txt,f,${strUser},${strGroup},1640,1111111111,0,9,";
# system("echo 'TESTDATA_' > ${strTestPath}/sub1/test-sub1.txt");
# utime(1111111112, 1111111112, "${strTestPath}/sub1/test-sub1.txt"); for (my $bRemote = 0; $bRemote <= 1; $bRemote++)
# system("chmod 0640 ${strTestPath}/sub1/test-sub1.txt"); {
# # Create the file object
# system("echo 'TESTDATA__' > ${strTestPath}/sub1/sub2/test-sub2.txt"); my $oFile = BackRest::File->new
# utime(1111111113, 1111111113, "${strTestPath}/sub1/sub2/test-sub2.txt"); (
# system("chmod 0646 ${strTestPath}/sub1/test-sub1.txt"); strStanza => "db",
# strBackupClusterPath => undef,
# system("ln ${strTestPath}/test.txt ${strTestPath}/sub1/test-hardlink.txt"); strBackupPath => ${strTestPath},
# system("ln ${strTestPath}/test.txt ${strTestPath}/sub1/sub2/test-hardlink.txt"); strRemote => $bRemote ? 'backup' : undef,
# oRemote => $bRemote ? $oRemote : undef
# system("ln -s .. ${strTestPath}/sub1/test"); );
# system("chmod 0700 ${strTestPath}/sub1/test");
# system("ln -s ../.. ${strTestPath}/sub1/sub2/test"); for (my $bError = 0; $bError <= 1; $bError++)
# system("chmod 0750 ${strTestPath}/sub1/sub2/test"); {
# for (my $bExists = 0; $bExists <= 1; $bExists++)
# my $strManifestCompare = {
# ".,d,${strUser},${strGroup},0750,,,,\n" . $iRun++;
# "sub1,d,${strUser},${strGroup},0750,,,,\n" .
# "sub1/sub2,d,${strUser},${strGroup},0750,,,,\n" . &log(INFO, "run ${iRun} - " .
# "sub1/sub2/test,l,${strUser},${strGroup},,,,,../..\n" . "remote $bRemote, error $bError, exists $bExists");
# "sub1/sub2/test-hardlink.txt,f,${strUser},${strGroup},1640,1111111111,0,9,\n" .
# "sub1/sub2/test-sub2.txt,f,${strUser},${strGroup},0666,1111111113,0,11,\n" . # Setup test directory
# "sub1/test,l,${strUser},${strGroup},,,,,..\n" . BackRestFileTestSetup($bError);
# "sub1/test-hardlink.txt,f,${strUser},${strGroup},1640,1111111111,0,9,\n" .
# "sub1/test-sub1.txt,f,${strUser},${strGroup},0646,1111111112,0,10,\n" . # Setup test data
# "test.txt,f,${strUser},${strGroup},1640,1111111111,0,9,"; system("mkdir -m 750 ${strTestPath}/sub1") == 0 or confess "Unable to create test directory";
# system("mkdir -m 750 ${strTestPath}/sub1/sub2") == 0 or confess "Unable to create test directory";
# for (my $bRemote = 0; $bRemote <= 1; $bRemote++)
# { system("echo 'TESTDATA' > ${strTestPath}/test.txt");
# my $oFile = BackRest::File->new utime(1111111111, 1111111111, "${strTestPath}/test.txt");
# ( system("chmod 1640 ${strTestPath}/test.txt");
# strStanza => $strStanza,
# bNoCompression => true, system("echo 'TESTDATA_' > ${strTestPath}/sub1/test-sub1.txt");
# strCommand => $strCommand, utime(1111111112, 1111111112, "${strTestPath}/sub1/test-sub1.txt");
# strBackupClusterPath => ${strTestPath}, system("chmod 0640 ${strTestPath}/sub1/test-sub1.txt");
# strBackupPath => ${strTestPath},
# strBackupHost => $bRemote ? $strHost : undef, system("echo 'TESTDATA__' > ${strTestPath}/sub1/sub2/test-sub2.txt");
# strBackupUser => $bRemote ? $strUser : undef utime(1111111113, 1111111113, "${strTestPath}/sub1/sub2/test-sub2.txt");
# ); system("chmod 0646 ${strTestPath}/sub1/test-sub1.txt");
#
# for (my $bError = 0; $bError <= 1; $bError++) system("ln ${strTestPath}/test.txt ${strTestPath}/sub1/test-hardlink.txt");
# { system("ln ${strTestPath}/test.txt ${strTestPath}/sub1/sub2/test-hardlink.txt");
# $iRun++;
# system("ln -s .. ${strTestPath}/sub1/test");
# &log(INFO, "run ${iRun} - " . system("chmod 0700 ${strTestPath}/sub1/test");
# "remote $bRemote, error $bError"); system("ln -s ../.. ${strTestPath}/sub1/sub2/test");
# system("chmod 0750 ${strTestPath}/sub1/sub2/test");
# my $strPath = $strTestPath;
# system("chmod 0770 ${strTestPath}");
# if ($bError)
# { # Create path
# $strPath .= "-error"; my $strPath = $strTestPath;
# }
# if ($bError)
# # Execute in eval in case of error {
# eval $strPath = $strTestPath . "/private";
# { }
# my %oManifestHash; elsif (!$bExists)
# $oFile->manifest(PATH_BACKUP_ABSOLUTE, $strPath, \%oManifestHash); {
# $strPath = $strTestPath . "/error";
# my $strManifest; }
#
# foreach my $strName (sort(keys $oManifestHash{name})) # Execute in eval in case of error
# { my %oManifestHash;
# if (!defined($strManifest)) my $bErrorExpected = !$bExists || $bError || $bRemote;
# {
# $strManifest = ""; eval
# } {
# else $oFile->manifest(PATH_BACKUP_ABSOLUTE, $strPath, \%oManifestHash);
# { };
# $strManifest .= "\n";
# } # Check for an error
# if ($@)
# if (defined($oManifestHash{name}{"${strName}"}{inode})) {
# { if ($bErrorExpected)
# $oManifestHash{name}{"${strName}"}{inode} = 0; {
# } next;
# }
# $strManifest .=
# "${strName}," . confess "error raised: " . $@ . "\n";
# $oManifestHash{name}{"${strName}"}{type} . "," . }
# (defined($oManifestHash{name}{"${strName}"}{user}) ?
# $oManifestHash{name}{"${strName}"}{user} : "") . "," . # Check for an expected error
# (defined($oManifestHash{name}{"${strName}"}{group}) ? if ($bErrorExpected)
# $oManifestHash{name}{"${strName}"}{group} : "") . "," . {
# (defined($oManifestHash{name}{"${strName}"}{permission}) ? confess 'error was expected';
# $oManifestHash{name}{"${strName}"}{permission} : "") . "," . }
# (defined($oManifestHash{name}{"${strName}"}{modification_time}) ?
# $oManifestHash{name}{"${strName}"}{modification_time} : "") . "," . my $strManifest;
# (defined($oManifestHash{name}{"${strName}"}{inode}) ?
# $oManifestHash{name}{"${strName}"}{inode} : "") . "," . # Validate the manifest
# (defined($oManifestHash{name}{"${strName}"}{size}) ? foreach my $strName (sort(keys $oManifestHash{name}))
# $oManifestHash{name}{"${strName}"}{size} : "") . "," . {
# (defined($oManifestHash{name}{"${strName}"}{link_destination}) ? if (!defined($strManifest))
# $oManifestHash{name}{"${strName}"}{link_destination} : ""); {
# } $strManifest = "";
# }
# if ($strManifest ne $strManifestCompare) else
# { {
# confess "manifest is not equal:\n\n${strManifest}\n\ncompare:\n\n${strManifestCompare}\n\n"; $strManifest .= "\n";
# } }
# };
# if (defined($oManifestHash{name}{"${strName}"}{inode}))
# if ($@ && !$bError) {
# { $oManifestHash{name}{"${strName}"}{inode} = 0;
# confess "error raised: " . $@ . "\n"; }
# }
# } $strManifest .=
# } "${strName}," .
# } $oManifestHash{name}{"${strName}"}{type} . "," .
(defined($oManifestHash{name}{"${strName}"}{user}) ?
$oManifestHash{name}{"${strName}"}{user} : "") . "," .
(defined($oManifestHash{name}{"${strName}"}{group}) ?
$oManifestHash{name}{"${strName}"}{group} : "") . "," .
(defined($oManifestHash{name}{"${strName}"}{permission}) ?
$oManifestHash{name}{"${strName}"}{permission} : "") . "," .
(defined($oManifestHash{name}{"${strName}"}{modification_time}) ?
$oManifestHash{name}{"${strName}"}{modification_time} : "") . "," .
(defined($oManifestHash{name}{"${strName}"}{inode}) ?
$oManifestHash{name}{"${strName}"}{inode} : "") . "," .
(defined($oManifestHash{name}{"${strName}"}{size}) ?
$oManifestHash{name}{"${strName}"}{size} : "") . "," .
(defined($oManifestHash{name}{"${strName}"}{link_destination}) ?
$oManifestHash{name}{"${strName}"}{link_destination} : "");
}
if ($strManifest ne $strManifestCompare)
{
confess "manifest is not equal:\n\n${strManifest}\n\ncompare:\n\n${strManifestCompare}\n\n";
}
}
}
}
}
#------------------------------------------------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------------------------------------------------------
# Test list() # Test list()
#------------------------------------------------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------------------------------------------------------
# if ($strTest eq 'all' || $strTest eq 'list') if ($strTest eq 'all' || $strTest eq 'list')
# { {
# $iRun = 0; $iRun = 0;
#
# &log(INFO, "--------------------------------------------------------------------------------"); &log(INFO, "--------------------------------------------------------------------------------");
# &log(INFO, "Test File->list()\n"); &log(INFO, "Test File->list()\n");
#
# for (my $bRemote = 0; $bRemote <= 1; $bRemote++) for (my $bRemote = 0; $bRemote <= 1; $bRemote++)
# { {
# my $oFile = BackRest::File->new # Create the file object
# ( my $oFile = BackRest::File->new
# strStanza => $strStanza, (
# bNoCompression => true, strStanza => "db",
# strCommand => $strCommand, strBackupClusterPath => undef,
# strBackupClusterPath => ${strTestPath}, strBackupPath => ${strTestPath},
# strBackupPath => ${strTestPath}, strRemote => $bRemote ? 'backup' : undef,
# strBackupHost => $bRemote ? $strHost : undef, oRemote => $bRemote ? $oRemote : undef
# strBackupUser => $bRemote ? $strUser : undef );
# );
# # Loop through exists
# # Loop through exists for (my $bSort = 0; $bSort <= 1; $bSort++)
# for (my $bSort = 0; $bSort <= 1; $bSort++) {
# { my $strSort = $bSort ? undef : "reverse";
# my $strSort = $bSort ? undef : "reverse";
# # Loop through expression
# # Loop through expression for (my $iExpression = 0; $iExpression <= 2; $iExpression++)
# for (my $iExpression = 0; $iExpression <= 2; $iExpression++) {
# { my $strExpression;
# my $strExpression;
# # Expression tha returns results
# # Expression tha returns results if ($iExpression == 1)
# if ($iExpression == 1) {
# { $strExpression = "^test2\\..*\$";
# $strExpression = "^test2\\..*\$"; }
# } # Expression that does not return results
# # Expression that does not return results elsif ($iExpression == 2)
# elsif ($iExpression == 2) {
# { $strExpression = "^du\$";
# $strExpression = "^du\$"; }
# }
# # Loop through exists
# # Loop through exists for (my $bExists = 0; $bExists <= 1; $bExists++)
# for (my $bExists = 0; $bExists <= 1; $bExists++) {
# {
# $iRun++; # Loop through error
# for (my $bError = 0; $bError <= 1; $bError++)
# &log(INFO, "run ${iRun} - " . {
# "remote $bRemote, exists $bExists, " . $iRun++;
# "expression " . (defined($strExpression) ? $strExpression : "[undef]") . ", " .
# "sort " . (defined($strSort) ? $strSort : "[undef]")); &log(INFO, "run ${iRun} - " .
# "remote $bRemote, error $bError, exists $bExists, " .
# my $strPath = "${strTestPath}"; "expression " . (defined($strExpression) ? $strExpression : "[undef]") . ", " .
# "sort " . (defined($strSort) ? $strSort : "[undef]"));
# # Drop the old test directory and create a new one
# system("rm -rf test"); # Setup test directory
# BackRestFileTestSetup($bError);
# if ($bExists)
# { my $strPath = "${strTestPath}";
# system("mkdir test") == 0 or confess "Unable to create test directory";
# system("echo 'TESTDATA' > ${strPath}/test.txt"); if ($bError)
# system("echo 'TESTDATA2' > ${strPath}/test2.txt"); {
# } $strPath = "${strTestPath}/private";
# }
# my @stryFileCompare = split(/\n/, "test.txt\ntest2.txt"); elsif (!$bExists)
# {
# # Execute in eval in case of error $strPath = "${strTestPath}/error";
# eval }
# { else
# my @stryFileList = $oFile->list(PATH_BACKUP_ABSOLUTE, $strPath, $strExpression, $strSort); {
# system("echo 'TESTDATA' > ${strPath}/test.txt");
# if (defined($strExpression)) system("echo 'TESTDATA2' > ${strPath}/test2.txt");
# { }
# @stryFileCompare = grep(/$strExpression/i, @stryFileCompare);
# } my @stryFileCompare = split(/\n/, "test.txt\ntest2.txt");
#
# if (defined($strSort)) # Execute in eval in case of error
# { my @stryFileList;
# @stryFileCompare = sort {$b cmp $a} @stryFileCompare; my $bErrorExpected = !$bExists || $bError;
# }
# eval
# my $strFileList = sprintf("@stryFileList"); {
# my $strFileCompare = sprintf("@stryFileCompare"); @stryFileList = $oFile->list(PATH_BACKUP_ABSOLUTE, $strPath, $strExpression, $strSort);
# };
# if ($strFileList ne $strFileCompare)
# { if ($@)
# confess "list (${strFileList})[" . @stryFileList . {
# "] does not match compare (${strFileCompare})[" . @stryFileCompare . "]"; if ($bErrorExpected)
# } {
# }; next;
# }
# if ($@ && $bExists)
# { confess "error raised: " . $@ . "\n";
# confess "error raised: " . $@ . "\n"; }
# }
# } if ($bErrorExpected)
# } {
# } confess 'error was expected';
# } }
# }
# Validate the list
if (defined($strExpression))
{
@stryFileCompare = grep(/$strExpression/i, @stryFileCompare);
}
if (defined($strSort))
{
@stryFileCompare = sort {$b cmp $a} @stryFileCompare;
}
my $strFileList = sprintf("@stryFileList");
my $strFileCompare = sprintf("@stryFileCompare");
if ($strFileList ne $strFileCompare)
{
confess "list (${strFileList})[" . @stryFileList .
"] does not match compare (${strFileCompare})[" . @stryFileCompare . "]";
}
}
}
}
}
}
}
#------------------------------------------------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------------------------------------------------------
# Test remove() # Test remove()
@ -811,7 +867,7 @@ sub BackRestFileTest
"remote $bRemote, exists $bExists, error ${bError}"); "remote $bRemote, exists $bExists, error ${bError}");
# Setup test directory # Setup test directory
BackRestFileTestSetup(); BackRestFileTestSetup($bError);
my $strFile = "${strTestPath}/test.txt"; my $strFile = "${strTestPath}/test.txt";
@ -934,7 +990,7 @@ sub BackRestFileTest
":${strDestinationPath}, dstcmp $bDestinationCompress"); ":${strDestinationPath}, dstcmp $bDestinationCompress");
# Setup test directory # Setup test directory
BackRestFileTestSetup(); BackRestFileTestSetup(false);
system("mkdir ${strTestPath}/backup") == 0 or confess "Unable to create test/backup directory"; system("mkdir ${strTestPath}/backup") == 0 or confess "Unable to create test/backup directory";
system("mkdir ${strTestPath}/db") == 0 or confess "Unable to create test/db directory"; system("mkdir ${strTestPath}/db") == 0 or confess "Unable to create test/db directory";