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();
}
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)
{
$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_PATH_MISSING => 6,
COMMAND_ERR_PATH_CREATE => 7,
COMMAND_ERR_PARAM => 8
COMMAND_ERR_PATH_READ => 8
};
####################################################################################################################################
@ -455,7 +455,7 @@ sub move
# Run remotely
if ($self->is_remote($strSourcePathType))
{
confess "${strDebug}: remote operation not supported";
confess &log(ASSERT, "${strDebug}: remote operation not supported");
}
# Run locally
else
@ -494,8 +494,7 @@ sub move
if ($strSourcePathType eq PATH_ABSOLUTE)
{
print $strError;
exit ($iErrorCode);
confess &log(ERROR, $strError, $iErrorCode);
}
confess &log(ERROR, "${strDebug}: " . $strError);
@ -524,7 +523,7 @@ sub compress
# Run remotely
if ($self->is_remote($strPathType))
{
confess "${strDebug}: remote operation not supported";
confess &log(ASSERT, "${strDebug}: remote operation not supported");
}
# Run locally
else
@ -532,18 +531,17 @@ sub compress
if (!gzip($strPathOp => "${strPathOp}.gz"))
{
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";
$iErrorCode = 1;
$iErrorCode = COMMAND_ERR_FILE_MISSING;
}
if ($strPathType eq PATH_ABSOLUTE)
{
print $strError;
exit ($iErrorCode);
confess &log(ERROR, $strError, $iErrorCode);
}
confess &log(ERROR, "${strDebug}: " . $strError);
@ -616,7 +614,7 @@ sub path_create
# If running on command line the return directly
if ($strPathType eq PATH_ABSOLUTE)
{
confess &log(ERROR, $!, COMMAND_ERR_PATH_CREATE);
confess &log(ERROR, $strError, COMMAND_ERR_PATH_CREATE);
}
# Error the normal way
@ -650,7 +648,7 @@ sub exists
# Build param hash
my %oParamHash;
$oParamHash{path} = ${strPathOp};
$oParamHash{path} = $strPathOp;
# Add remote info to debug string
my $strRemote = "remote (" . $self->{oRemote}->command_param_string(\%oParamHash) . ")";
@ -689,6 +687,292 @@ sub exists
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
#
@ -1033,97 +1317,6 @@ sub hash
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
####################################################################################################################################
@ -1197,201 +1390,5 @@ sub remove
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;
__PACKAGE__->meta->make_immutable;

View File

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