You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-09-16 09:06:18 +02:00
Changes for testing - finished changing config to local implementation.
This commit is contained in:
@@ -75,15 +75,25 @@ my $strType; # Type of backup: full, differential (diff), incremental
|
|||||||
|
|
||||||
# Test parameters - not for general use
|
# Test parameters - not for general use
|
||||||
my $bNoFork = false; # Prevents the archive process from forking when local archiving is enabled
|
my $bNoFork = false; # Prevents the archive process from forking when local archiving is enabled
|
||||||
|
my $bTest = false; # Enters test mode - not harmful in anyway, but adds special logging and pauses for unit testing
|
||||||
|
my $iTestDelay = 5; # Amount of time to delay after hitting a test point (the default would not be enough for manual tests)
|
||||||
|
|
||||||
GetOptions ("config=s" => \$strConfigFile,
|
GetOptions ("config=s" => \$strConfigFile,
|
||||||
"stanza=s" => \$strStanza,
|
"stanza=s" => \$strStanza,
|
||||||
"type=s" => \$strType,
|
"type=s" => \$strType,
|
||||||
|
|
||||||
# Test parameters - not for general use
|
# Test parameters - not for general use
|
||||||
"no-fork" => \$bNoFork)
|
"no-fork" => \$bNoFork,
|
||||||
|
"test" => \$bTest,
|
||||||
|
"test-delay=s" => \$iTestDelay)
|
||||||
or confess("Error in command line arguments\n");
|
or confess("Error in command line arguments\n");
|
||||||
|
|
||||||
|
# Test delay should be between 1 and 600 seconds
|
||||||
|
if (!($iTestDelay >= 1 && $iTestDelay <= 600))
|
||||||
|
{
|
||||||
|
confess &log(ERROR, 'test-delay must be between 1 and 600 seconds');
|
||||||
|
}
|
||||||
|
|
||||||
####################################################################################################################################
|
####################################################################################################################################
|
||||||
# Global variables
|
# Global variables
|
||||||
####################################################################################################################################
|
####################################################################################################################################
|
||||||
@@ -599,7 +609,9 @@ backup_init
|
|||||||
!$bChecksum,
|
!$bChecksum,
|
||||||
config_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_THREAD_MAX),
|
config_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_THREAD_MAX),
|
||||||
config_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_ARCHIVE_REQUIRED, true, "y") eq "y" ? true : false,
|
config_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_ARCHIVE_REQUIRED, true, "y") eq "y" ? true : false,
|
||||||
config_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_THREAD_TIMEOUT)
|
config_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_THREAD_TIMEOUT),
|
||||||
|
$bTest,
|
||||||
|
$iTestDelay
|
||||||
);
|
);
|
||||||
|
|
||||||
####################################################################################################################################
|
####################################################################################################################################
|
||||||
|
@@ -10,9 +10,7 @@ use warnings;
|
|||||||
use Carp;
|
use Carp;
|
||||||
use File::Basename;
|
use File::Basename;
|
||||||
use File::Path qw(remove_tree);
|
use File::Path qw(remove_tree);
|
||||||
use JSON;
|
|
||||||
use Scalar::Util qw(looks_like_number);
|
use Scalar::Util qw(looks_like_number);
|
||||||
use Storable;
|
|
||||||
use Thread::Queue;
|
use Thread::Queue;
|
||||||
|
|
||||||
use lib dirname($0);
|
use lib dirname($0);
|
||||||
@@ -37,6 +35,8 @@ my $iThreadThreshold = 10;
|
|||||||
my $iSmallFileThreshold = 65536;
|
my $iSmallFileThreshold = 65536;
|
||||||
my $bArchiveRequired;
|
my $bArchiveRequired;
|
||||||
my $iThreadTimeout;
|
my $iThreadTimeout;
|
||||||
|
my $bTest;
|
||||||
|
my $iTestDelay;
|
||||||
|
|
||||||
# Thread variables
|
# Thread variables
|
||||||
my @oThread;
|
my @oThread;
|
||||||
@@ -58,6 +58,8 @@ sub backup_init
|
|||||||
my $iThreadMaxParam = shift;
|
my $iThreadMaxParam = shift;
|
||||||
my $bArchiveRequiredParam = shift;
|
my $bArchiveRequiredParam = shift;
|
||||||
my $iThreadTimeoutParam = shift;
|
my $iThreadTimeoutParam = shift;
|
||||||
|
my $bTestParam = shift;
|
||||||
|
my $iTestDelayParam = shift;
|
||||||
|
|
||||||
$oDb = $oDbParam;
|
$oDb = $oDbParam;
|
||||||
$oFile = $oFileParam;
|
$oFile = $oFileParam;
|
||||||
@@ -68,6 +70,14 @@ sub backup_init
|
|||||||
$iThreadMax = $iThreadMaxParam;
|
$iThreadMax = $iThreadMaxParam;
|
||||||
$bArchiveRequired = $bArchiveRequiredParam;
|
$bArchiveRequired = $bArchiveRequiredParam;
|
||||||
$iThreadTimeout = $iThreadTimeoutParam;
|
$iThreadTimeout = $iThreadTimeoutParam;
|
||||||
|
$bTest = defined($bTestParam) ? $bTestParam : false;
|
||||||
|
$iTestDelay = defined($bTestParam) ? $iTestDelayParam : undef;
|
||||||
|
|
||||||
|
# Make sure that a delay is specified in test mode
|
||||||
|
if ($bTest && !defined($iTestDelay))
|
||||||
|
{
|
||||||
|
confess &log(ASSERT, "iTestDelay must be provided when bTest is true");
|
||||||
|
}
|
||||||
|
|
||||||
if (!defined($iThreadMax))
|
if (!defined($iThreadMax))
|
||||||
{
|
{
|
||||||
@@ -641,66 +651,6 @@ sub backup_type_find
|
|||||||
return $strDirectory;
|
return $strDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
####################################################################################################################################
|
|
||||||
# BACKUP_MANIFEST_LOAD - Load the backup manifest
|
|
||||||
####################################################################################################################################
|
|
||||||
sub backup_manifest_load
|
|
||||||
{
|
|
||||||
my $strBackupManifestFile = shift;
|
|
||||||
|
|
||||||
return %{retrieve($strBackupManifestFile) or confess &log(ERROR, "unable to read ${strBackupManifestFile}")};
|
|
||||||
}
|
|
||||||
|
|
||||||
####################################################################################################################################
|
|
||||||
# BACKUP_MANIFEST_SAVE - Save the backup manifest
|
|
||||||
####################################################################################################################################
|
|
||||||
sub backup_manifest_save
|
|
||||||
{
|
|
||||||
my $strBackupManifestFile = shift;
|
|
||||||
my $oConfig = shift;
|
|
||||||
|
|
||||||
my $hFile;
|
|
||||||
my $bFirst = true;
|
|
||||||
|
|
||||||
open($hFile, '>', $strBackupManifestFile)
|
|
||||||
or confess "unable to open ${$strBackupManifestFile}";
|
|
||||||
|
|
||||||
foreach my $strSection (sort(keys $oConfig))
|
|
||||||
{
|
|
||||||
if (!$bFirst)
|
|
||||||
{
|
|
||||||
syswrite($hFile, "\n")
|
|
||||||
or confess "unable to write lf: $!";
|
|
||||||
}
|
|
||||||
|
|
||||||
syswrite($hFile, "[${strSection}]\n")
|
|
||||||
or confess "unable to write section ${strSection}: $!";
|
|
||||||
|
|
||||||
foreach my $strKey (sort(keys ${$oConfig}{"${strSection}"}))
|
|
||||||
{
|
|
||||||
my $strValue = ${$oConfig}{"${strSection}"}{"${strKey}"};
|
|
||||||
|
|
||||||
if (defined($strValue))
|
|
||||||
{
|
|
||||||
if (ref($strValue) eq "HASH")
|
|
||||||
{
|
|
||||||
syswrite($hFile, "${strKey}=" . encode_json($strValue) . "\n")
|
|
||||||
or confess "unable to write key ${strKey}: $!";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
syswrite($hFile, "${strKey}=${strValue}\n")
|
|
||||||
or confess "unable to write key ${strKey}: $!";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$bFirst = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
# store($oBackupManifestRef, $strBackupManifestFile) or confess &log(ERROR, "unable to open ${strBackupManifestFile}");
|
|
||||||
}
|
|
||||||
|
|
||||||
####################################################################################################################################
|
####################################################################################################################################
|
||||||
# BACKUP_FILE_NOT_IN_MANIFEST - Find all files in a backup path that are not in the supplied manifest
|
# BACKUP_FILE_NOT_IN_MANIFEST - Find all files in a backup path that are not in the supplied manifest
|
||||||
####################################################################################################################################
|
####################################################################################################################################
|
||||||
@@ -1359,7 +1309,8 @@ sub backup
|
|||||||
|
|
||||||
if (defined($strBackupLastPath))
|
if (defined($strBackupLastPath))
|
||||||
{
|
{
|
||||||
%oLastManifest = backup_manifest_load($oFile->path_get(PATH_BACKUP_CLUSTER) . "/$strBackupLastPath/backup.manifest");
|
my %oLastManifest;
|
||||||
|
config_load($oFile->path_get(PATH_BACKUP_CLUSTER) . "/$strBackupLastPath/backup.manifest", \%oLastManifest);
|
||||||
|
|
||||||
if (!defined($oLastManifest{backup}{label}))
|
if (!defined($oLastManifest{backup}{label}))
|
||||||
{
|
{
|
||||||
@@ -1430,7 +1381,7 @@ sub backup
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Save the backup conf file first time - so we can see what is happening in the backup
|
# Save the backup conf file first time - so we can see what is happening in the backup
|
||||||
backup_manifest_save($strBackupConfFile, \%oBackupManifest);
|
config_save($strBackupConfFile, \%oBackupManifest);
|
||||||
|
|
||||||
# Perform the backup
|
# Perform the backup
|
||||||
backup_file($strBackupPath, $strDbClusterPath, \%oBackupManifest);
|
backup_file($strBackupPath, $strDbClusterPath, \%oBackupManifest);
|
||||||
@@ -1450,7 +1401,7 @@ sub backup
|
|||||||
if ($bArchiveRequired)
|
if ($bArchiveRequired)
|
||||||
{
|
{
|
||||||
# Save the backup conf file second time - before getting archive logs in case that fails
|
# Save the backup conf file second time - before getting archive logs in case that fails
|
||||||
backup_manifest_save($strBackupConfFile, \%oBackupManifest);
|
config_save($strBackupConfFile, \%oBackupManifest);
|
||||||
|
|
||||||
# After the backup has been stopped, need to make a copy of the archive logs need to make the db consistent
|
# After the backup has been stopped, need to make a copy of the archive logs need to make the db consistent
|
||||||
&log(DEBUG, "retrieving archive logs ${strArchiveStart}:${strArchiveStop}");
|
&log(DEBUG, "retrieving archive logs ${strArchiveStart}:${strArchiveStop}");
|
||||||
@@ -1479,11 +1430,11 @@ sub backup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Need some sort of backup validate - create a manifest and compare the backup manifest
|
# Need some sort of backup validate - create a manifest and compare the backup to manifest
|
||||||
# !!! DO IT
|
# !!! DO IT
|
||||||
|
|
||||||
# Save the backup conf file final time
|
# Save the backup conf file final time
|
||||||
backup_manifest_save($strBackupConfFile, \%oBackupManifest);
|
config_save($strBackupConfFile, \%oBackupManifest);
|
||||||
|
|
||||||
# Rename the backup tmp path to complete the backup
|
# Rename the backup tmp path to complete the backup
|
||||||
&log(DEBUG, "moving ${strBackupTmpPath} to " . $oFile->path_get(PATH_BACKUP_CLUSTER, $strBackupPath));
|
&log(DEBUG, "moving ${strBackupTmpPath} to " . $oFile->path_get(PATH_BACKUP_CLUSTER, $strBackupPath));
|
||||||
@@ -1514,15 +1465,17 @@ sub archive_list_get
|
|||||||
&log(TRACE, "archive_list_get: post-9.3 database, including log FF");
|
&log(TRACE, "archive_list_get: post-9.3 database, including log FF");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Get the timelines and make sure they match
|
||||||
my $strTimeline = substr($strArchiveStart, 0, 8);
|
my $strTimeline = substr($strArchiveStart, 0, 8);
|
||||||
my @stryArchive;
|
my @stryArchive;
|
||||||
my $iArchiveIdx = 0;
|
my $iArchiveIdx = 0;
|
||||||
|
|
||||||
if ($strTimeline ne substr($strArchiveStop, 0, 8))
|
if ($strTimeline ne substr($strArchiveStop, 0, 8))
|
||||||
{
|
{
|
||||||
confess "Timelines between ${strArchiveStart} and ${strArchiveStop} differ";
|
confess &log(ERROR, "Timelines between ${strArchiveStart} and ${strArchiveStop} differ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Iterate through all archive logs between start and stop
|
||||||
my $iStartMajor = hex substr($strArchiveStart, 8, 8);
|
my $iStartMajor = hex substr($strArchiveStart, 8, 8);
|
||||||
my $iStartMinor = hex substr($strArchiveStart, 16, 8);
|
my $iStartMinor = hex substr($strArchiveStart, 16, 8);
|
||||||
|
|
||||||
@@ -1692,7 +1645,8 @@ sub backup_expire
|
|||||||
# even though they are also in the pg_xlog directory (since they have been copied more than once).
|
# even though they are also in the pg_xlog directory (since they have been copied more than once).
|
||||||
&log(INFO, "archive retention based on backup " . $strArchiveRetentionBackup);
|
&log(INFO, "archive retention based on backup " . $strArchiveRetentionBackup);
|
||||||
|
|
||||||
my %oManifest = backup_manifest_load($oFile->path_get(PATH_BACKUP_CLUSTER) . "/$strArchiveRetentionBackup/backup.manifest");
|
my %oManifest;
|
||||||
|
config_load($oFile->path_get(PATH_BACKUP_CLUSTER) . "/$strArchiveRetentionBackup/backup.manifest", \%oManifest);
|
||||||
my $strArchiveLast = ${oManifest}{backup}{"archive-start"};
|
my $strArchiveLast = ${oManifest}{backup}{"archive-start"};
|
||||||
|
|
||||||
if (!defined($strArchiveLast))
|
if (!defined($strArchiveLast))
|
||||||
|
@@ -11,6 +11,7 @@ use Carp;
|
|||||||
use Fcntl qw(:DEFAULT :flock);
|
use Fcntl qw(:DEFAULT :flock);
|
||||||
use File::Path qw(remove_tree);
|
use File::Path qw(remove_tree);
|
||||||
use File::Basename;
|
use File::Basename;
|
||||||
|
use JSON;
|
||||||
|
|
||||||
use lib dirname($0) . "/../lib";
|
use lib dirname($0) . "/../lib";
|
||||||
use BackRest::Exception;
|
use BackRest::Exception;
|
||||||
@@ -21,6 +22,7 @@ our @EXPORT = qw(version_get
|
|||||||
data_hash_build trim common_prefix wait_for_file date_string_get file_size_format execute
|
data_hash_build trim common_prefix wait_for_file date_string_get file_size_format execute
|
||||||
log log_file_set log_level_set
|
log log_file_set log_level_set
|
||||||
lock_file_create lock_file_remove
|
lock_file_create lock_file_remove
|
||||||
|
config_save config_load
|
||||||
TRACE DEBUG ERROR ASSERT WARN INFO OFF true false);
|
TRACE DEBUG ERROR ASSERT WARN INFO OFF true false);
|
||||||
|
|
||||||
# Global constants
|
# Global constants
|
||||||
@@ -412,4 +414,115 @@ sub log
|
|||||||
return $strMessage;
|
return $strMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
####################################################################################################################################
|
||||||
|
# CONFIG_LOAD - Load config file
|
||||||
|
####################################################################################################################################
|
||||||
|
sub config_load
|
||||||
|
{
|
||||||
|
my $strFile = shift;
|
||||||
|
my $oConfig = shift;
|
||||||
|
|
||||||
|
# Open the config file
|
||||||
|
my $hFile;
|
||||||
|
my $strSection;
|
||||||
|
|
||||||
|
open($hFile, '<', $strFile)
|
||||||
|
or confess &log(ERROR, "unable to open ${strFile}");
|
||||||
|
|
||||||
|
while (my $strLine = readline($hFile))
|
||||||
|
{
|
||||||
|
$strLine = trim($strLine);
|
||||||
|
# print "line:${strLine}\n";
|
||||||
|
|
||||||
|
if ($strLine ne '')
|
||||||
|
{
|
||||||
|
# Get the section
|
||||||
|
if (index($strLine, '[') == 0)
|
||||||
|
{
|
||||||
|
$strSection = substr($strLine, 1, length($strLine) - 2);
|
||||||
|
# print "found section ${strSection}\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# Get key and value
|
||||||
|
my $iIndex = index($strLine, '=');
|
||||||
|
|
||||||
|
if ($iIndex == -1)
|
||||||
|
{
|
||||||
|
confess &log(ERROR, "unable to read from ${strFile}: ${strLine}");
|
||||||
|
}
|
||||||
|
|
||||||
|
my $strKey = substr($strLine, 0, $iIndex);
|
||||||
|
my $strValue = substr($strLine, $iIndex + 1);
|
||||||
|
|
||||||
|
# print "found key ${strKey}:${strValue}\n";
|
||||||
|
|
||||||
|
# Try to store value as JSON
|
||||||
|
eval
|
||||||
|
{
|
||||||
|
${$oConfig}{"${strSection}"}{"${strKey}"} = decode_json($strValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
# On error store value as a scalar
|
||||||
|
if ($@)
|
||||||
|
{
|
||||||
|
${$oConfig}{"${strSection}"}{"${strKey}"} = $strValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close($hFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
####################################################################################################################################
|
||||||
|
# CONFIG_SAVE - Save config file
|
||||||
|
####################################################################################################################################
|
||||||
|
sub config_save
|
||||||
|
{
|
||||||
|
my $strBackupManifestFile = shift;
|
||||||
|
my $oConfig = shift;
|
||||||
|
|
||||||
|
my $hFile;
|
||||||
|
my $bFirst = true;
|
||||||
|
|
||||||
|
open($hFile, '>', $strBackupManifestFile)
|
||||||
|
or confess &log(ERROR, "unable to open ${strBackupManifestFile}");
|
||||||
|
|
||||||
|
foreach my $strSection (sort(keys $oConfig))
|
||||||
|
{
|
||||||
|
if (!$bFirst)
|
||||||
|
{
|
||||||
|
syswrite($hFile, "\n")
|
||||||
|
or confess "unable to write lf: $!";
|
||||||
|
}
|
||||||
|
|
||||||
|
syswrite($hFile, "[${strSection}]\n")
|
||||||
|
or confess "unable to write section ${strSection}: $!";
|
||||||
|
|
||||||
|
foreach my $strKey (sort(keys ${$oConfig}{"${strSection}"}))
|
||||||
|
{
|
||||||
|
my $strValue = ${$oConfig}{"${strSection}"}{"${strKey}"};
|
||||||
|
|
||||||
|
if (defined($strValue))
|
||||||
|
{
|
||||||
|
if (ref($strValue) eq "HASH")
|
||||||
|
{
|
||||||
|
syswrite($hFile, "${strKey}=" . encode_json($strValue) . "\n")
|
||||||
|
or confess "unable to write key ${strKey}: $!";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
syswrite($hFile, "${strKey}=${strValue}\n")
|
||||||
|
or confess "unable to write key ${strKey}: $!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$bFirst = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
close($hFile);
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@@ -16,6 +16,8 @@ use File::Basename;
|
|||||||
use Cwd 'abs_path';
|
use Cwd 'abs_path';
|
||||||
use Config::IniFiles;
|
use Config::IniFiles;
|
||||||
use IPC::Open3;
|
use IPC::Open3;
|
||||||
|
use POSIX ":sys_wait_h";
|
||||||
|
use IO::Select;
|
||||||
|
|
||||||
use lib dirname($0) . "/../lib";
|
use lib dirname($0) . "/../lib";
|
||||||
use BackRest::Utility;
|
use BackRest::Utility;
|
||||||
@@ -99,32 +101,74 @@ sub BackRestTestCommon_Execute
|
|||||||
}
|
}
|
||||||
|
|
||||||
# system($strCommand);
|
# system($strCommand);
|
||||||
my $strError;
|
# my $strError = '';
|
||||||
|
my $strErrorLog = '';
|
||||||
my $hError;
|
my $hError;
|
||||||
open($hError, '>', \$strError) or confess "unable to open handle to stderr string: $!\n";
|
# open($hError, '>', BackRestTestCommon_TestPathGet() . '/stderr.log');# or confess "unable to open handle to stderr string: $!\n";
|
||||||
|
# open($hError, '>', \$strError) or confess "unable to open handle to stderr string: $!\n";
|
||||||
|
|
||||||
my $strOut;
|
# my $strOut = '';
|
||||||
|
my $strOutLog = '';
|
||||||
my $hOut;
|
my $hOut;
|
||||||
open($hOut, '>', \$strOut) or confess "unable to open handle to stdout string: $!\n";
|
# open($hOut, '>', BackRestTestCommon_TestPathGet() . '/stdout.log');# or confess "unable to open handle to stderr string: $!\n";
|
||||||
|
# open($hOut, '>', \$strOut) or confess "unable to open handle to stdout string: $!\n";
|
||||||
|
|
||||||
my $pId = open3(undef, $hOut, $hError, $strCommand);
|
my $pId = open3(undef, $hOut, $hError, $strCommand);
|
||||||
|
my $oErrorSelect = IO::Select->new();
|
||||||
|
$oErrorSelect->add($hError);
|
||||||
|
my $oOutSelect = IO::Select->new();
|
||||||
|
$oOutSelect->add($hOut);
|
||||||
|
|
||||||
# Wait for the process to finish and report any errors
|
# Wait for the process to finish and report any errors
|
||||||
waitpid($pId, 0);
|
# my $iExitStatus;
|
||||||
|
|
||||||
|
# waitpid($pId, 0);
|
||||||
|
|
||||||
|
while(waitpid($pId, WNOHANG) == 0)
|
||||||
|
{
|
||||||
|
# print "stuck here\n";
|
||||||
|
|
||||||
|
if ($oErrorSelect->can_read(.1))
|
||||||
|
{
|
||||||
|
# print "read err\n";
|
||||||
|
|
||||||
|
while (my $strLine = readline($hError))
|
||||||
|
{
|
||||||
|
# print "out: ${strLine}";
|
||||||
|
$strErrorLog .= $strLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($oOutSelect->can_read(.1))
|
||||||
|
{
|
||||||
|
# print "read out begin\n";
|
||||||
|
|
||||||
|
while (my $strLine = readline($hOut))
|
||||||
|
{
|
||||||
|
# print "out: ${strLine}";
|
||||||
|
$strOutLog .= $strLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
# print "read out end\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# print "got out\n";
|
||||||
|
|
||||||
my $iExitStatus = ${^CHILD_ERROR_NATIVE} >> 8;
|
my $iExitStatus = ${^CHILD_ERROR_NATIVE} >> 8;
|
||||||
|
# $iExitStatus = $iExitStatus >> 8;
|
||||||
|
|
||||||
if ($iExitStatus != 0 && !$bSuppressError)
|
if ($iExitStatus != 0 && !$bSuppressError)
|
||||||
{
|
{
|
||||||
while (my $strLine = readline($hError))
|
print "${strErrorLog}";
|
||||||
{
|
|
||||||
print $strLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
confess &log(ERROR, "command '${strCommand}' returned " . $iExitStatus);
|
confess &log(ERROR, "command '${strCommand}' returned " . $iExitStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
close($hError);
|
# print "${strOutLog}\n";
|
||||||
close($hOut);
|
|
||||||
|
# close($hError);
|
||||||
|
# close($hOut);
|
||||||
|
|
||||||
# while (my $strLine = readline($hOut))
|
# while (my $strLine = readline($hOut))
|
||||||
# {
|
# {
|
||||||
@@ -141,16 +185,19 @@ sub BackRestTestCommon_Setup
|
|||||||
my $bDryRunParam = shift;
|
my $bDryRunParam = shift;
|
||||||
my $bNoCleanupParam = shift;
|
my $bNoCleanupParam = shift;
|
||||||
|
|
||||||
|
my $strBasePath = dirname(dirname(abs_path($0)));
|
||||||
|
|
||||||
$strCommonStanza = "db";
|
$strCommonStanza = "db";
|
||||||
$strCommonCommandMain = '/Users/dsteele/pg_backrest/bin/pg_backrest.pl';
|
$strCommonCommandMain = "${strBasePath}/bin/pg_backrest.pl";
|
||||||
$strCommonCommandRemote = '/Users/dsteele/pg_backrest/bin/pg_backrest_remote.pl';
|
$strCommonCommandRemote = "${strBasePath}/bin/pg_backrest_remote.pl";
|
||||||
$strCommonCommandPsql = '/Library/PostgreSQL/9.3/bin/psql -X %option%';
|
$strCommonCommandPsql = '/Library/PostgreSQL/9.3/bin/psql -X %option%';
|
||||||
|
# $strCommonCommandPsql = 'psql -X %option%';
|
||||||
$strCommonHost = '127.0.0.1';
|
$strCommonHost = '127.0.0.1';
|
||||||
$strCommonUser = getpwuid($<);
|
$strCommonUser = getpwuid($<);
|
||||||
$strCommonGroup = getgrgid($();
|
$strCommonGroup = getgrgid($();
|
||||||
$strCommonUserBackRest = 'backrest';
|
$strCommonUserBackRest = 'backrest';
|
||||||
$strCommonTestPath = dirname(abs_path($0)) . '/test';
|
$strCommonTestPath = "${strBasePath}/test/test";
|
||||||
$strCommonDataPath = dirname(abs_path($0)) . '/data';
|
$strCommonDataPath = "${strBasePath}/test/data";
|
||||||
$strCommonBackupPath = "${strCommonTestPath}/backrest";
|
$strCommonBackupPath = "${strCommonTestPath}/backrest";
|
||||||
$strCommonArchivePath = "${strCommonTestPath}/archive";
|
$strCommonArchivePath = "${strCommonTestPath}/archive";
|
||||||
$strCommonDbPath = "${strCommonTestPath}/db";
|
$strCommonDbPath = "${strCommonTestPath}/db";
|
||||||
@@ -197,7 +244,7 @@ sub BackRestTestCommon_ConfigCreate
|
|||||||
$oParamHash{$strCommonStanza}{'user'} = $strCommonUser;
|
$oParamHash{$strCommonStanza}{'user'} = $strCommonUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
$oParamHash{'global:log'}{'level-console'} = 'error';
|
$oParamHash{'global:log'}{'level-console'} = 'trace';
|
||||||
$oParamHash{'global:log'}{'level-file'} = 'trace';
|
$oParamHash{'global:log'}{'level-file'} = 'trace';
|
||||||
|
|
||||||
if ($strLocal eq REMOTE_BACKUP)
|
if ($strLocal eq REMOTE_BACKUP)
|
||||||
|
@@ -13,10 +13,10 @@ use english;
|
|||||||
use Carp;
|
use Carp;
|
||||||
|
|
||||||
use File::Basename;
|
use File::Basename;
|
||||||
use JSON; # remove when config functions go to utility
|
|
||||||
|
|
||||||
use lib dirname($0) . "/../lib";
|
use lib dirname($0) . "/../lib";
|
||||||
use BackRest::Utility;
|
use BackRest::Utility;
|
||||||
|
use BackRest::File;
|
||||||
|
|
||||||
use BackRestTest::CommonTest;
|
use BackRestTest::CommonTest;
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ sub BackRestTestUtility_Test
|
|||||||
{
|
{
|
||||||
$iRun = 0;
|
$iRun = 0;
|
||||||
$bCreate = true;
|
$bCreate = true;
|
||||||
my $oFile;
|
my $oFile = BackRest::File->new();
|
||||||
|
|
||||||
&log(INFO, "Test config\n");
|
&log(INFO, "Test config\n");
|
||||||
|
|
||||||
@@ -78,6 +78,8 @@ sub BackRestTestUtility_Test
|
|||||||
# Create the test directory
|
# Create the test directory
|
||||||
if ($bCreate)
|
if ($bCreate)
|
||||||
{
|
{
|
||||||
|
# $oFile = BackRest::File->new();
|
||||||
|
|
||||||
# # Create the file object
|
# # Create the file object
|
||||||
# $oFile = (BackRest::File->new
|
# $oFile = (BackRest::File->new
|
||||||
# (
|
# (
|
||||||
@@ -92,6 +94,7 @@ sub BackRestTestUtility_Test
|
|||||||
$bCreate = false;
|
$bCreate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Generate a test config
|
||||||
my %oConfig;
|
my %oConfig;
|
||||||
|
|
||||||
$oConfig{test1}{key1} = 'value';
|
$oConfig{test1}{key1} = 'value';
|
||||||
@@ -103,48 +106,28 @@ sub BackRestTestUtility_Test
|
|||||||
$oConfig{test3}{key2}{sub1} = 'value';
|
$oConfig{test3}{key2}{sub1} = 'value';
|
||||||
$oConfig{test3}{key2}{sub2} = 'value';
|
$oConfig{test3}{key2}{sub2} = 'value';
|
||||||
|
|
||||||
my $strFile = "$strTestPath/test.cfg";
|
# Save the test config
|
||||||
my $hFile;
|
my $strFile = "${strTestPath}/config.cfg";
|
||||||
my $bFirst = true;
|
config_save($strFile, \%oConfig);
|
||||||
|
|
||||||
open($hFile, '>', $strFile)
|
my $strConfigHash = $oFile->hash(PATH_ABSOLUTE, $strFile);
|
||||||
or confess "unable to open ${strFile}";
|
|
||||||
|
|
||||||
foreach my $strSection (sort(keys %oConfig))
|
# Reload the test config
|
||||||
|
my %oConfigTest;
|
||||||
|
|
||||||
|
config_load($strFile, \%oConfigTest);
|
||||||
|
|
||||||
|
# Resave the test config and compare hashes
|
||||||
|
my $strFileTest = "${strTestPath}/config-test.cfg";
|
||||||
|
config_save($strFileTest, \%oConfigTest);
|
||||||
|
|
||||||
|
my $strConfigTestHash = $oFile->hash(PATH_ABSOLUTE, $strFileTest);
|
||||||
|
|
||||||
|
if ($strConfigHash ne $strConfigTestHash)
|
||||||
{
|
{
|
||||||
if (!$bFirst)
|
confess "config hash ${strConfigHash} != ${strConfigTestHash}";
|
||||||
{
|
|
||||||
syswrite($hFile, "\n")
|
|
||||||
or confess "unable to write lf: $!";
|
|
||||||
}
|
|
||||||
|
|
||||||
syswrite($hFile, "[${strSection}]\n")
|
|
||||||
or confess "unable to write section ${strSection}: $!";
|
|
||||||
|
|
||||||
foreach my $strKey (sort(keys $oConfig{$strSection}))
|
|
||||||
{
|
|
||||||
my $strValue = $oConfig{"${strSection}"}{"${strKey}"};
|
|
||||||
|
|
||||||
if (defined($strValue))
|
|
||||||
{
|
|
||||||
if (ref($strValue) eq "HASH")
|
|
||||||
{
|
|
||||||
syswrite($hFile, "${strKey}=" . encode_json($strValue) . "\n")
|
|
||||||
or confess "unable to write key ${strKey}: $!";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
syswrite($hFile, "${strKey}=${strValue}\n")
|
|
||||||
or confess "unable to write key ${strKey}: $!";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$bFirst = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
close($hFile);
|
|
||||||
|
|
||||||
if (BackRestTestCommon_Cleanup())
|
if (BackRestTestCommon_Cleanup())
|
||||||
{
|
{
|
||||||
&log(INFO, 'cleanup');
|
&log(INFO, 'cleanup');
|
||||||
|
Reference in New Issue
Block a user