mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-01-18 04:58:51 +02:00
Created unit tests for files deleted by the db during backup.
This commit is contained in:
parent
09e2351ae8
commit
0298e8dd16
@ -18,8 +18,6 @@ Put something here, there are people to recognize!
|
||||
|
||||
* Store actual backup begin and end times in backup.manifest
|
||||
|
||||
* Fix backup.manifest to not be a binary dump.
|
||||
|
||||
* Move backups to be removed to temp before deleting.
|
||||
|
||||
* Async archive-get.
|
||||
@ -40,9 +38,10 @@ Put something here, there are people to recognize!
|
||||
|
||||
* File->wait() function. Waits for a file or directory to exist with configurable retry and timeout.
|
||||
|
||||
* Missing files during backup generate an ERROR in the log - the backup works but this message should probably be suppressed.
|
||||
|
||||
## required perl modules
|
||||
|
||||
* IPC::Run
|
||||
* Net::OpenSSH
|
||||
* Digest::SHA
|
||||
* IO::Compress::Gzip
|
||||
@ -50,7 +49,7 @@ Put something here, there are people to recognize!
|
||||
* JSON
|
||||
|
||||
* Moose (Not using many features here, just use standard Perl object syntax?)
|
||||
* IPC::System::Simple (only used in DB object - should convert to IPC::Run)
|
||||
* IPC::System::Simple (only used in DB object - should convert this to DBD::Pg)
|
||||
|
||||
## release notes
|
||||
|
||||
|
@ -644,12 +644,11 @@ if ($strOperation eq OP_EXPIRE)
|
||||
}
|
||||
|
||||
remote_exit(0);
|
||||
|
||||
####################################################################################################################################
|
||||
# START EVAL BLOCK TO CATCH ERRORS AND STOP THREADS
|
||||
####################################################################################################################################
|
||||
};
|
||||
|
||||
####################################################################################################################################
|
||||
# CHECK FOR ERRORS AND STOP THREADS
|
||||
####################################################################################################################################
|
||||
if ($@)
|
||||
{
|
||||
remote_exit();
|
||||
|
@ -1231,10 +1231,6 @@ sub backup_file_thread
|
||||
# If file is missing assume the database removed it (else corruption and nothing we can do!)
|
||||
&log(INFO, "thread ${iThreadIdx} skipped file removed by database: " . $oFileCopyMap{$strFile}{db_file});
|
||||
|
||||
# Remove the destination file and the temp file just in case they had already been written
|
||||
$oFileThread->file_remove(PATH_BACKUP_TMP, $oFileCopyMap{$strFile}{backup_file}, true);
|
||||
$oFileThread->file_remove(PATH_BACKUP_TMP, $oFileCopyMap{$strFile}{backup_file});
|
||||
|
||||
# Write a message into the master queue to have the file removed from the manifest
|
||||
$oMasterQueue[$iThreadIdx]->enqueue("remove|$oFileCopyMap{$strFile}{file_section}|$oFileCopyMap{$strFile}{file}");
|
||||
|
||||
|
@ -1320,7 +1320,6 @@ sub copy
|
||||
eval
|
||||
{
|
||||
$strOutput = $self->{oRemote}->output_read($strOperation eq OP_FILE_COPY, $strDebug);
|
||||
|
||||
};
|
||||
|
||||
# If there is an error then evaluate
|
||||
|
@ -20,7 +20,7 @@ use Exporter qw(import);
|
||||
|
||||
our @EXPORT = qw(version_get
|
||||
data_hash_build trim common_prefix wait_for_file date_string_get file_size_format execute
|
||||
log log_file_set log_level_set test_set
|
||||
log log_file_set log_level_set test_set test_check
|
||||
lock_file_create lock_file_remove
|
||||
config_save config_load
|
||||
TRACE DEBUG ERROR ASSERT WARN INFO OFF true false
|
||||
@ -389,6 +389,17 @@ sub log_level_set
|
||||
}
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# TEST_CHECK - Check for a test message
|
||||
####################################################################################################################################
|
||||
sub test_check
|
||||
{
|
||||
my $strLog = shift;
|
||||
my $strTest = shift;
|
||||
|
||||
return index($strLog, TEST_ENCLOSE . '-' . $strTest . '-' . TEST_ENCLOSE) != -1;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# LOG - log messages
|
||||
####################################################################################################################################
|
||||
@ -401,23 +412,25 @@ sub log
|
||||
my $strMessageFormat = $strMessage;
|
||||
my $iLogLevelRank = $oLogLevelRank{"${strLevel}"}{rank};
|
||||
|
||||
# If test message
|
||||
if ($strLevel eq TEST)
|
||||
{
|
||||
$iLogLevelRank = $oLogLevelRank{TRACE}{rank} + 1;
|
||||
$strMessageFormat = TEST_ENCLOSE . '-' . $strMessageFormat . '-' . TEST_ENCLOSE;
|
||||
}
|
||||
# Else level rank must be valid
|
||||
elsif (!defined($iLogLevelRank))
|
||||
{
|
||||
confess &log(ASSERT, "log level ${strLevel} does not exist");
|
||||
}
|
||||
|
||||
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
|
||||
|
||||
# If message was undefined then set default message
|
||||
if (!defined($strMessageFormat))
|
||||
{
|
||||
$strMessageFormat = "(undefined)";
|
||||
}
|
||||
|
||||
# Indent subsequent lines of the message if it has more than one line - makes the log more readable
|
||||
if ($strLevel eq TRACE || $strLevel eq TEST)
|
||||
{
|
||||
$strMessageFormat =~ s/\n/\n /g;
|
||||
@ -433,24 +446,29 @@ sub log
|
||||
$strMessageFormat =~ s/\n/\n /g;
|
||||
}
|
||||
|
||||
# Format the message text
|
||||
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
|
||||
|
||||
$strMessageFormat = sprintf("%4d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec) .
|
||||
sprintf(" T%02d", threads->tid()) .
|
||||
(" " x (7 - length($strLevel))) . "${strLevel}: ${strMessageFormat}" .
|
||||
(defined($iCode) ? " (code ${iCode})" : "") . "\n";
|
||||
|
||||
# if ($strLevel eq TEST)
|
||||
# {
|
||||
# confess "log level rank $iLogLevelRank";
|
||||
# }
|
||||
|
||||
# Output to console depending on log level and test flag
|
||||
if ($iLogLevelRank <= $oLogLevelRank{"${strLogLevelConsole}"}{rank} ||
|
||||
$bTest && $strLevel eq TEST)
|
||||
{
|
||||
print $strMessageFormat;
|
||||
|
||||
if ($bTest && $strLevel eq TEST)
|
||||
{
|
||||
*STDOUT->flush();
|
||||
sleep($iTestDelay);
|
||||
}
|
||||
}
|
||||
|
||||
if ($iLogLevelRank <= $oLogLevelRank{"${strLogLevelFile}"}{rank} ||
|
||||
$bTest && $strLevel eq TEST)
|
||||
# Output to file depending on log level and test flag
|
||||
if ($iLogLevelRank <= $oLogLevelRank{"${strLogLevelFile}"}{rank})
|
||||
{
|
||||
if (defined($hLogFile))
|
||||
{
|
||||
@ -458,16 +476,13 @@ sub log
|
||||
}
|
||||
}
|
||||
|
||||
# Throw a typed exception if code is defined
|
||||
if (defined($iCode))
|
||||
{
|
||||
return BackRest::Exception->new(iCode => $iCode, strMessage => $strMessage);
|
||||
}
|
||||
|
||||
if ($bTest && $strLevel eq TEST)
|
||||
{
|
||||
sleep($iTestDelay);
|
||||
}
|
||||
|
||||
# Return the message test so it can be used in a confess
|
||||
return $strMessage;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ use Carp;
|
||||
|
||||
use File::Basename;
|
||||
use File::Copy "cp";
|
||||
use DBI;
|
||||
|
||||
use lib dirname($0) . "/../lib";
|
||||
use BackRest::Utility;
|
||||
@ -28,6 +29,56 @@ our @EXPORT = qw(BackRestTestBackup_Test);
|
||||
my $strTestPath;
|
||||
my $strHost;
|
||||
my $strUserBackRest;
|
||||
my $hDb;
|
||||
|
||||
####################################################################################################################################
|
||||
# BackRestTestBackup_PgConnect
|
||||
####################################################################################################################################
|
||||
sub BackRestTestBackup_PgConnect
|
||||
{
|
||||
# Disconnect user session
|
||||
BackRestTestBackup_PgDisconnect();
|
||||
|
||||
# Connect to the db (whether it is local or remote)
|
||||
$hDb = DBI->connect('dbi:Pg:dbname=postgres;port=' . BackRestTestCommon_DbPortGet .
|
||||
';host=' . BackRestTestCommon_DbPathGet(),
|
||||
BackRestTestCommon_UserGet(),
|
||||
undef,
|
||||
{AutoCommit => 1, RaiseError => 1});
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# BackRestTestBackup_Disconnect
|
||||
####################################################################################################################################
|
||||
sub BackRestTestBackup_PgDisconnect
|
||||
{
|
||||
# Connect to the db (whether it is local or remote)
|
||||
if (defined($hDb))
|
||||
{
|
||||
$hDb->disconnect;
|
||||
undef($hDb);
|
||||
}
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# BackRestTestBackup_PgExecute
|
||||
####################################################################################################################################
|
||||
sub BackRestTestBackup_PgExecute
|
||||
{
|
||||
my $strSql = shift;
|
||||
my $bSwitchXlog = shift;
|
||||
|
||||
&log(DEBUG, "SQL: ${strSql}");
|
||||
my $hStatement = $hDb->prepare($strSql);
|
||||
$hStatement->execute() or
|
||||
confess &log(ERROR, "Unable to execute: ${strSql}");
|
||||
$hStatement->finish();
|
||||
|
||||
if (defined($bSwitchXlog) && $bSwitchXlog)
|
||||
{
|
||||
BackRestTestBackup_PgExecute('select pg_switch_xlog()');
|
||||
}
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# BackRestTestBackup_ClusterStop
|
||||
@ -36,7 +87,10 @@ sub BackRestTestBackup_ClusterStop
|
||||
{
|
||||
my $strPath = shift;
|
||||
|
||||
# If the db directory already exists, stop the cluster and remove the directory
|
||||
# Disconnect user session
|
||||
BackRestTestBackup_PgDisconnect();
|
||||
|
||||
# If postmaster process is running them stop the cluster
|
||||
if (-e $strPath . "/postmaster.pid")
|
||||
{
|
||||
BackRestTestCommon_Execute("pg_ctl stop -D $strPath -w -s -m fast");
|
||||
@ -50,11 +104,17 @@ sub BackRestTestBackup_ClusterRestart
|
||||
{
|
||||
my $strPath = BackRestTestCommon_DbCommonPathGet();
|
||||
|
||||
# If the db directory already exists, stop the cluster and remove the directory
|
||||
# Disconnect user session
|
||||
BackRestTestBackup_PgDisconnect();
|
||||
|
||||
# If postmaster process is running them stop the cluster
|
||||
if (-e $strPath . "/postmaster.pid")
|
||||
{
|
||||
BackRestTestCommon_Execute("pg_ctl restart -D $strPath -w -s");
|
||||
}
|
||||
|
||||
# Connect user session
|
||||
BackRestTestBackup_PgConnect();
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
@ -70,9 +130,12 @@ sub BackRestTestBackup_ClusterCreate
|
||||
|
||||
BackRestTestCommon_Execute("initdb -D $strPath -A trust");
|
||||
BackRestTestCommon_Execute("pg_ctl start -o \"-c port=$iPort -c checkpoint_segments=1 " .
|
||||
"-c wal_level=archive -c archive_mode=on -c archive_command='$strArchive'\" " .
|
||||
# "-c unix_socket_directories='" . BackRestTestCommon_DbCommonPathGet() . "'\" " .
|
||||
"-c wal_level=archive -c archive_mode=on -c archive_command='$strArchive' " .
|
||||
"-c unix_socket_directories='" . BackRestTestCommon_DbPathGet() . "'\" " .
|
||||
"-D $strPath -l $strPath/postgresql.log -w -s");
|
||||
|
||||
# Connect user session
|
||||
BackRestTestBackup_PgConnect();
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
@ -156,15 +219,17 @@ sub BackRestTestBackup_Test
|
||||
$strTest = 'all';
|
||||
}
|
||||
|
||||
# Setup global variables
|
||||
$strTestPath = BackRestTestCommon_TestPathGet();
|
||||
$strHost = BackRestTestCommon_HostGet();
|
||||
$strUserBackRest = BackRestTestCommon_UserBackRestGet();
|
||||
|
||||
# Setup test variables
|
||||
my $iRun;
|
||||
my $bCreate;
|
||||
$strTestPath = BackRestTestCommon_TestPathGet();
|
||||
my $strStanza = BackRestTestCommon_StanzaGet();
|
||||
my $strUserBackRest = BackRestTestCommon_UserBackRestGet();
|
||||
my $strGroup = BackRestTestCommon_GroupGet();
|
||||
$strHost = BackRestTestCommon_HostGet();
|
||||
$strUserBackRest = BackRestTestCommon_UserBackRestGet();
|
||||
|
||||
my $strArchiveChecksum = '1c7e00fd09b9dd11fc2966590b3e3274645dd031';
|
||||
my $iArchiveMax = 3;
|
||||
my $strXlogPath = BackRestTestCommon_DbCommonPathGet() . '/pg_xlog';
|
||||
@ -494,20 +559,35 @@ sub BackRestTestBackup_Test
|
||||
undef); # compress-async
|
||||
}
|
||||
|
||||
# Create the backup command
|
||||
my $strCommand = BackRestTestCommon_CommandMainGet() . ' --config=' .
|
||||
($bRemote ? BackRestTestCommon_BackupPathGet() : BackRestTestCommon_DbPathGet()) .
|
||||
"/pg_backrest.conf --test --type=incr --stanza=${strStanza} backup";
|
||||
|
||||
|
||||
# Run the full/incremental tests
|
||||
for (my $iFull = 1; $iFull <= 1; $iFull++)
|
||||
{
|
||||
&log(INFO, " full " . sprintf("%02d", $iFull));
|
||||
|
||||
my $strCommand = BackRestTestCommon_CommandMainGet() . ' --config=' .
|
||||
($bRemote ? BackRestTestCommon_BackupPathGet() : BackRestTestCommon_DbPathGet()) .
|
||||
"/pg_backrest.conf --test --type=incr --stanza=${strStanza} backup";
|
||||
|
||||
BackRestTestCommon_Execute($strCommand, $bRemote);
|
||||
# exit 0;
|
||||
|
||||
for (my $iIncr = 1; $iIncr <= 1; $iIncr++)
|
||||
for (my $iIncr = 0; $iIncr <= 1; $iIncr++)
|
||||
{
|
||||
&log(INFO, " incr " . sprintf("%02d", $iIncr));
|
||||
&log(INFO, " " . ($iIncr == 0 ? "full " : " incr ") . sprintf("%02d", $iFull));
|
||||
|
||||
BackRestTestBackup_PgExecute('create table test (id int)');
|
||||
|
||||
BackRestTestCommon_ExecuteBegin($strCommand, $bRemote);
|
||||
|
||||
if (BackRestTestCommon_ExecuteEnd(TEST_MANIFEST_BUILD))
|
||||
{
|
||||
BackRestTestBackup_PgExecute('drop table test', true);
|
||||
|
||||
BackRestTestCommon_ExecuteEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
confess &log(ERROR, 'test point ' . TEST_MANIFEST_BUILD . ' was not found');
|
||||
}
|
||||
|
||||
|
||||
BackRestTestCommon_Execute($strCommand, $bRemote);
|
||||
}
|
||||
|
@ -23,7 +23,8 @@ use BackRest::Utility;
|
||||
use BackRest::File;
|
||||
|
||||
use Exporter qw(import);
|
||||
our @EXPORT = qw(BackRestTestCommon_Setup BackRestTestCommon_Execute BackRestTestCommon_ExecuteBackRest
|
||||
our @EXPORT = qw(BackRestTestCommon_Setup BackRestTestCommon_ExecuteBegin BackRestTestCommon_ExecuteEnd
|
||||
BackRestTestCommon_Execute BackRestTestCommon_ExecuteBackRest
|
||||
BackRestTestCommon_ConfigCreate BackRestTestCommon_Run BackRestTestCommon_Cleanup
|
||||
BackRestTestCommon_StanzaGet BackRestTestCommon_CommandMainGet BackRestTestCommon_CommandRemoteGet
|
||||
BackRestTestCommon_HostGet BackRestTestCommon_UserGet BackRestTestCommon_GroupGet
|
||||
@ -50,6 +51,14 @@ my $iModuleTestRun;
|
||||
my $bDryRun;
|
||||
my $bNoCleanup;
|
||||
|
||||
# Execution globals
|
||||
my $strErrorLog;
|
||||
my $hError;
|
||||
my $strOutLog;
|
||||
my $hOut;
|
||||
my $pId;
|
||||
my $strCommand;
|
||||
|
||||
####################################################################################################################################
|
||||
# BackRestTestBackup_Run
|
||||
####################################################################################################################################
|
||||
@ -82,32 +91,44 @@ sub BackRestTestCommon_Cleanup
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# BackRestTestBackup_Execute
|
||||
# BackRestTestBackup_ExecuteBegin
|
||||
####################################################################################################################################
|
||||
sub BackRestTestCommon_Execute
|
||||
sub BackRestTestCommon_ExecuteBegin
|
||||
{
|
||||
my $strCommand = shift;
|
||||
my $strCommandParam = shift;
|
||||
my $bRemote = shift;
|
||||
my $bSuppressError = shift;
|
||||
|
||||
# Set defaults
|
||||
$bRemote = defined($bRemote) ? $bRemote : false;
|
||||
$bSuppressError = defined($bSuppressError) ? $bSuppressError : false;
|
||||
|
||||
if ($bRemote)
|
||||
{
|
||||
$strCommand = "ssh ${strCommonUserBackRest}\@${strCommonHost} '${strCommand}'";
|
||||
$strCommand = "ssh ${strCommonUserBackRest}\@${strCommonHost} '${strCommandParam}'";
|
||||
}
|
||||
else
|
||||
{
|
||||
$strCommand = $strCommandParam;
|
||||
}
|
||||
|
||||
# Create error and out file handles and buffers
|
||||
my $strErrorLog = '';
|
||||
my $hError;
|
||||
|
||||
my $strOutLog = '';
|
||||
my $hOut;
|
||||
$strErrorLog = '';
|
||||
$hError = undef;
|
||||
$strOutLog = '';
|
||||
$hOut = undef;
|
||||
|
||||
# Execute the command
|
||||
my $pId = open3(undef, $hOut, $hError, $strCommand);
|
||||
$pId = open3(undef, $hOut, $hError, $strCommand);
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# BackRestTestBackup_ExecuteEnd
|
||||
####################################################################################################################################
|
||||
sub BackRestTestCommon_ExecuteEnd
|
||||
{
|
||||
my $strTest = shift;
|
||||
my $bSuppressError = shift;
|
||||
|
||||
# Set defaults
|
||||
$bSuppressError = defined($bSuppressError) ? $bSuppressError : false;
|
||||
|
||||
# Create select objects
|
||||
my $oErrorSelect = IO::Select->new();
|
||||
@ -133,6 +154,12 @@ sub BackRestTestCommon_Execute
|
||||
while (my $strLine = readline($hOut))
|
||||
{
|
||||
$strOutLog .= $strLine;
|
||||
|
||||
if (defined($strTest) && test_check($strLine, $strTest))
|
||||
{
|
||||
&log(DEBUG, "Found test ${strTest}");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -146,6 +173,24 @@ sub BackRestTestCommon_Execute
|
||||
($strOutLog ne '' ? "STDOUT:\n${strOutLog}" : '') .
|
||||
($strErrorLog ne '' ? "STDERR:\n${strErrorLog}" : ''));
|
||||
}
|
||||
|
||||
$hError = undef;
|
||||
$hOut = undef;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# BackRestTestBackup_Execute
|
||||
####################################################################################################################################
|
||||
sub BackRestTestCommon_Execute
|
||||
{
|
||||
my $strCommand = shift;
|
||||
my $bRemote = shift;
|
||||
my $bSuppressError = shift;
|
||||
|
||||
BackRestTestCommon_ExecuteBegin($strCommand, $bRemote);
|
||||
BackRestTestCommon_ExecuteEnd(undef, $bSuppressError);
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
@ -160,20 +205,23 @@ sub BackRestTestCommon_Setup
|
||||
my $strBasePath = dirname(dirname(abs_path($0)));
|
||||
|
||||
$strCommonStanza = "db";
|
||||
$strCommonCommandMain = "${strBasePath}/bin/pg_backrest.pl";
|
||||
$strCommonCommandRemote = "${strBasePath}/bin/pg_backrest_remote.pl";
|
||||
$strCommonCommandPsql = '/Library/PostgreSQL/9.3/bin/psql -X %option%';
|
||||
# $strCommonCommandPsql = 'psql -X %option%';
|
||||
$strCommonHost = '127.0.0.1';
|
||||
$strCommonUser = getpwuid($<);
|
||||
$strCommonGroup = getgrgid($();
|
||||
$strCommonUserBackRest = 'backrest';
|
||||
|
||||
$strCommonTestPath = "${strBasePath}/test/test";
|
||||
$strCommonDataPath = "${strBasePath}/test/data";
|
||||
$strCommonBackupPath = "${strCommonTestPath}/backrest";
|
||||
$strCommonArchivePath = "${strCommonTestPath}/archive";
|
||||
$strCommonDbPath = "${strCommonTestPath}/db";
|
||||
$strCommonDbCommonPath = "${strCommonTestPath}/db/common";
|
||||
|
||||
$strCommonCommandMain = "${strBasePath}/bin/pg_backrest.pl";
|
||||
$strCommonCommandRemote = "${strBasePath}/bin/pg_backrest_remote.pl";
|
||||
$strCommonCommandPsql = "/Library/PostgreSQL/9.3/bin/psql -X %option% -h ${strCommonDbPath}";
|
||||
# $strCommonCommandPsql = 'psql -X %option%';
|
||||
|
||||
$iCommonDbPort = 6543;
|
||||
$iModuleTestRun = $iModuleTestRunParam;
|
||||
$bDryRun = $bDryRunParam;
|
||||
|
Loading…
Reference in New Issue
Block a user