mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
532 lines
22 KiB
Perl
Executable File
532 lines
22 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
####################################################################################################################################
|
|
# BackupTest.pl - Unit Tests for BackRest::File
|
|
####################################################################################################################################
|
|
package BackRestTest::BackupTest;
|
|
|
|
####################################################################################################################################
|
|
# Perl includes
|
|
####################################################################################################################################
|
|
use strict;
|
|
use warnings;
|
|
use english;
|
|
use Carp;
|
|
|
|
use File::Basename;
|
|
use File::Copy "cp";
|
|
|
|
use lib dirname($0) . "/../lib";
|
|
use BackRest::Utility;
|
|
use BackRest::File;
|
|
use BackRest::Remote;
|
|
|
|
use BackRestTest::CommonTest;
|
|
|
|
use Exporter qw(import);
|
|
our @EXPORT = qw(BackRestTestBackup_Test);
|
|
|
|
my $strTestPath;
|
|
my $strHost;
|
|
my $strUserBackRest;
|
|
|
|
####################################################################################################################################
|
|
# BackRestTestBackup_ClusterStop
|
|
####################################################################################################################################
|
|
sub BackRestTestBackup_ClusterStop
|
|
{
|
|
my $strPath = shift;
|
|
|
|
# If the db directory already exists, stop the cluster and remove the directory
|
|
if (-e $strPath . "/postmaster.pid")
|
|
{
|
|
BackRestTestCommon_Execute("pg_ctl stop -D $strPath -w -s -m fast");
|
|
}
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# BackRestTestBackup_ClusterRestart
|
|
####################################################################################################################################
|
|
sub BackRestTestBackup_ClusterRestart
|
|
{
|
|
my $strPath = BackRestTestCommon_DbCommonPathGet();
|
|
|
|
# If the db directory already exists, stop the cluster and remove the directory
|
|
if (-e $strPath . "/postmaster.pid")
|
|
{
|
|
BackRestTestCommon_Execute("pg_ctl restart -D $strPath -w -s");
|
|
}
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# BackRestTestBackup_ClusterCreate
|
|
####################################################################################################################################
|
|
sub BackRestTestBackup_ClusterCreate
|
|
{
|
|
my $strPath = shift;
|
|
my $iPort = shift;
|
|
|
|
my $strArchive = BackRestTestCommon_CommandMainGet() . " --stanza=" . BackRestTestCommon_StanzaGet() .
|
|
" --config=" . BackRestTestCommon_DbPathGet() . "/pg_backrest.conf archive-push %p";
|
|
|
|
BackRestTestCommon_Execute("initdb -D $strPath -A trust");
|
|
BackRestTestCommon_Execute("/Library/PostgreSQL/9.3/bin/pg_ctl start -o \"-c port=$iPort -c checkpoint_segments=1 " .
|
|
"-c wal_level=archive -c archive_mode=on -c archive_command='$strArchive'\" " .
|
|
"-D $strPath -l $strPath/postgresql.log -w -s");
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# BackRestTestBackup_Drop
|
|
####################################################################################################################################
|
|
sub BackRestTestBackup_Drop
|
|
{
|
|
# Stop the cluster if one is running
|
|
BackRestTestBackup_ClusterStop(BackRestTestCommon_DbCommonPathGet());
|
|
|
|
# Remove the backrest private directory
|
|
if (-e BackRestTestCommon_BackupPathGet())
|
|
{
|
|
BackRestTestCommon_Execute('rm -rf ' . BackRestTestCommon_BackupPathGet(), true, true);
|
|
}
|
|
|
|
# Remove the test directory
|
|
system('rm -rf ' . BackRestTestCommon_TestPathGet()) == 0
|
|
or die 'unable to remove ' . BackRestTestCommon_TestPathGet() . 'path';
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# BackRestTestBackup_Create
|
|
####################################################################################################################################
|
|
sub BackRestTestBackup_Create
|
|
{
|
|
my $bRemote = shift;
|
|
my $bCluster = shift;
|
|
|
|
# Set defaults
|
|
$bRemote = defined($bRemote) ? $bRemote : false;
|
|
$bCluster = defined($bCluster) ? $bCluster : true;
|
|
|
|
# Drop the old test directory
|
|
BackRestTestBackup_Drop();
|
|
|
|
# Create the test directory
|
|
mkdir(BackRestTestCommon_TestPathGet(), oct('0770'))
|
|
or confess 'Unable to create ' . BackRestTestCommon_TestPathGet() . ' path';
|
|
|
|
# Create the db directory
|
|
mkdir(BackRestTestCommon_DbPathGet(), oct('0700'))
|
|
or confess 'Unable to create ' . BackRestTestCommon_DbPathGet() . ' path';
|
|
|
|
# Create the db/common directory
|
|
mkdir(BackRestTestCommon_DbCommonPathGet())
|
|
or confess 'Unable to create ' . BackRestTestCommon_DbCommonPathGet() . ' path';
|
|
|
|
# Create the archive directory
|
|
mkdir(BackRestTestCommon_ArchivePathGet(), oct('0700'))
|
|
or confess 'Unable to create ' . BackRestTestCommon_ArchivePathGet() . ' path';
|
|
|
|
# Create the backup directory
|
|
if ($bRemote)
|
|
{
|
|
BackRestTestCommon_Execute("mkdir -m 700 " . BackRestTestCommon_BackupPathGet(), true);
|
|
}
|
|
else
|
|
{
|
|
mkdir(BackRestTestCommon_BackupPathGet(), oct('0700'))
|
|
or confess 'Unable to create ' . BackRestTestCommon_BackupPathGet() . ' path';
|
|
}
|
|
|
|
# Create the cluster
|
|
if ($bCluster)
|
|
{
|
|
BackRestTestBackup_ClusterCreate(BackRestTestCommon_DbCommonPathGet(), BackRestTestCommon_DbPortGet());
|
|
}
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# BackRestTestBackup_Test
|
|
####################################################################################################################################
|
|
sub BackRestTestBackup_Test
|
|
{
|
|
my $strTest = shift;
|
|
|
|
# If no test was specified, then run them all
|
|
if (!defined($strTest))
|
|
{
|
|
$strTest = 'all';
|
|
}
|
|
|
|
# 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';
|
|
my $strArchiveTestFile = BackRestTestCommon_DataPathGet() . '/test.archive.bin';
|
|
my $iThreadMax = 8;
|
|
|
|
# Print test banner
|
|
&log(INFO, "BACKUP MODULE ******************************************************************");
|
|
|
|
#-------------------------------------------------------------------------------------------------------------------------------
|
|
# Create remote
|
|
#-------------------------------------------------------------------------------------------------------------------------------
|
|
my $oRemote = BackRest::Remote->new
|
|
(
|
|
strHost => $strHost,
|
|
strUser => $strUserBackRest,
|
|
strCommand => BackRestTestCommon_CommandRemoteGet()
|
|
);
|
|
|
|
#-------------------------------------------------------------------------------------------------------------------------------
|
|
# Test archive-push
|
|
#-------------------------------------------------------------------------------------------------------------------------------
|
|
if ($strTest eq 'all' || $strTest eq 'archive-push')
|
|
{
|
|
$iRun = 0;
|
|
$bCreate = true;
|
|
my $oFile;
|
|
|
|
&log(INFO, "Test archive-push\n");
|
|
|
|
for (my $bRemote = false; $bRemote <= true; $bRemote++)
|
|
{
|
|
for (my $bCompress = false; $bCompress <= true; $bCompress++)
|
|
{
|
|
for (my $bChecksum = false; $bChecksum <= true; $bChecksum++)
|
|
{
|
|
for (my $bArchiveAsync = false; $bArchiveAsync <= $bRemote; $bArchiveAsync++)
|
|
{
|
|
for (my $bCompressAsync = false; $bCompressAsync <= true; $bCompressAsync++)
|
|
{
|
|
# Increment the run, log, and decide whether this unit test should be run
|
|
if (!BackRestTestCommon_Run(++$iRun,
|
|
"rmt ${bRemote}, cmp ${bCompress}, chk ${bChecksum}, " .
|
|
"arc_async ${bArchiveAsync}, cmp_async ${bCompressAsync}")) {next}
|
|
|
|
# Create the test directory
|
|
if ($bCreate)
|
|
{
|
|
# Create the file object
|
|
$oFile = (BackRest::File->new
|
|
(
|
|
strStanza => $strStanza,
|
|
strBackupPath => BackRestTestCommon_BackupPathGet(),
|
|
strRemote => $bRemote ? 'backup' : undef,
|
|
oRemote => $bRemote ? $oRemote : undef
|
|
))->clone();
|
|
|
|
BackRestTestBackup_Create($bRemote, false);
|
|
#
|
|
# # Create the db/common/pg_xlog directory
|
|
# mkdir($strXlogPath)
|
|
# or confess 'Unable to create ${strXlogPath} path';
|
|
|
|
$bCreate = false;
|
|
}
|
|
|
|
BackRestTestCommon_ConfigCreate('db',
|
|
($bRemote ? REMOTE_BACKUP : undef),
|
|
$bCompress,
|
|
$bChecksum, # checksum
|
|
undef, # hardlink
|
|
undef, # thread-max
|
|
$bArchiveAsync,
|
|
$bCompressAsync);
|
|
|
|
my $strCommand = BackRestTestCommon_CommandMainGet() . ' --config=' . BackRestTestCommon_DbPathGet() .
|
|
"/pg_backrest.conf --stanza=db archive-push";
|
|
|
|
# Loop through backups
|
|
for (my $iBackup = 1; $iBackup <= 3; $iBackup++)
|
|
{
|
|
my $strArchiveFile;
|
|
|
|
# Loop through archive files
|
|
for (my $iArchive = 1; $iArchive <= $iArchiveMax; $iArchive++)
|
|
{
|
|
# Construct the archive filename
|
|
my $iArchiveNo = (($iBackup - 1) * $iArchiveMax + ($iArchive - 1)) + 1;
|
|
|
|
if ($iArchiveNo > 255)
|
|
{
|
|
confess "backup total * archive total cannot be greater than 255";
|
|
}
|
|
|
|
$strArchiveFile = uc(sprintf("0000000100000001%08x", $iArchiveNo));
|
|
|
|
&log(INFO, " backup " . sprintf("%02d", $iBackup) .
|
|
", archive " .sprintf("%02x", $iArchive) .
|
|
" - ${strArchiveFile}");
|
|
|
|
my $strSourceFile = "${strXlogPath}/${strArchiveFile}";
|
|
|
|
$oFile->copy(PATH_DB_ABSOLUTE, $strArchiveTestFile, # Source file
|
|
PATH_DB_ABSOLUTE, $strSourceFile, # Destination file
|
|
false, # Source is not compressed
|
|
false, # Destination is not compressed
|
|
undef, undef, undef, # Unused params
|
|
true); # Create path if it does not exist
|
|
|
|
BackRestTestCommon_Execute($strCommand . " ${strSourceFile}");
|
|
|
|
# Build the archive name to check for at the destination
|
|
my $strArchiveCheck = $strArchiveFile;
|
|
|
|
if ($bChecksum)
|
|
{
|
|
$strArchiveCheck .= "-${strArchiveChecksum}";
|
|
}
|
|
|
|
if ($bCompress)
|
|
{
|
|
$strArchiveCheck .= ".gz";
|
|
}
|
|
|
|
if (!$oFile->exists(PATH_BACKUP_ARCHIVE, $strArchiveCheck))
|
|
{
|
|
sleep(1);
|
|
|
|
if (!$oFile->exists(PATH_BACKUP_ARCHIVE, $strArchiveCheck))
|
|
{
|
|
confess "unable to find " . $oFile->path_get(PATH_BACKUP_ARCHIVE, $strArchiveCheck);
|
|
}
|
|
}
|
|
}
|
|
|
|
# !!! Need to put in tests for .backup files here
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$bCreate = true;
|
|
}
|
|
|
|
if (BackRestTestCommon_Cleanup())
|
|
{
|
|
&log(INFO, 'cleanup');
|
|
BackRestTestBackup_Drop();
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------------------------------------------------------------------------
|
|
# Test archive-get
|
|
#-------------------------------------------------------------------------------------------------------------------------------
|
|
if ($strTest eq 'all' || $strTest eq 'archive-get')
|
|
{
|
|
$iRun = 0;
|
|
$bCreate = true;
|
|
my $oFile;
|
|
|
|
&log(INFO, "Test archive-get\n");
|
|
|
|
for (my $bRemote = false; $bRemote <= true; $bRemote++)
|
|
{
|
|
for (my $bCompress = false; $bCompress <= true; $bCompress++)
|
|
{
|
|
for (my $bChecksum = false; $bChecksum <= true; $bChecksum++)
|
|
{
|
|
# Increment the run, log, and decide whether this unit test should be run
|
|
if (!BackRestTestCommon_Run(++$iRun,
|
|
"rmt ${bRemote}, cmp ${bCompress}, chk ${bChecksum}")) {next}
|
|
|
|
# Create the test directory
|
|
if ($bCreate)
|
|
{
|
|
# Create the file object
|
|
$oFile = (BackRest::File->new
|
|
(
|
|
strStanza => $strStanza,
|
|
strBackupPath => BackRestTestCommon_BackupPathGet(),
|
|
strRemote => $bRemote ? 'backup' : undef,
|
|
oRemote => $bRemote ? $oRemote : undef
|
|
))->clone();
|
|
|
|
BackRestTestBackup_Create($bRemote, false);
|
|
|
|
# Create the db/common/pg_xlog directory
|
|
mkdir($strXlogPath)
|
|
or confess 'Unable to create ${strXlogPath} path';
|
|
|
|
$bCreate = false;
|
|
}
|
|
|
|
BackRestTestCommon_ConfigCreate('db', # local
|
|
($bRemote ? REMOTE_BACKUP : undef), # remote
|
|
$bCompress, # compress
|
|
$bChecksum, # checksum
|
|
undef, # hardlink
|
|
undef, # thread-max
|
|
undef, # archive-async
|
|
undef); # compress-async
|
|
|
|
my $strCommand = BackRestTestCommon_CommandMainGet() . ' --config=' . BackRestTestCommon_DbPathGet() .
|
|
"/pg_backrest.conf --stanza=db archive-get";
|
|
|
|
# Loop through backups
|
|
my $strArchiveFile;
|
|
|
|
# Loop through archive files
|
|
for (my $iArchiveNo = 1; $iArchiveNo <= $iArchiveMax; $iArchiveNo++)
|
|
{
|
|
# Construct the archive filename
|
|
if ($iArchiveNo > 255)
|
|
{
|
|
confess "backup total * archive total cannot be greater than 255";
|
|
}
|
|
|
|
$strArchiveFile = uc(sprintf("0000000100000001%08x", $iArchiveNo));
|
|
|
|
&log(INFO, " archive " .sprintf("%02x", $iArchiveNo) .
|
|
" - ${strArchiveFile}");
|
|
|
|
my $strSourceFile = $strArchiveFile;
|
|
|
|
if ($bChecksum)
|
|
{
|
|
$strSourceFile .= "-${strArchiveChecksum}";
|
|
}
|
|
|
|
if ($bCompress)
|
|
{
|
|
$strSourceFile .= ".gz";
|
|
}
|
|
|
|
$oFile->copy(PATH_DB_ABSOLUTE, $strArchiveTestFile, # Source file
|
|
PATH_BACKUP_ARCHIVE, $strSourceFile, # Destination file
|
|
false, # Source is not compressed
|
|
$bCompress, # Destination compress based on test
|
|
undef, undef, undef, # Unused params
|
|
true); # Create path if it does not exist
|
|
|
|
my $strDestinationFile = "${strXlogPath}/${strArchiveFile}";
|
|
|
|
BackRestTestCommon_Execute($strCommand . " ${strArchiveFile} ${strDestinationFile}");
|
|
|
|
# Check that the destination file exists
|
|
if ($oFile->exists(PATH_DB_ABSOLUTE, $strDestinationFile))
|
|
{
|
|
if ($oFile->hash(PATH_DB_ABSOLUTE, $strDestinationFile) ne $strArchiveChecksum)
|
|
{
|
|
confess "archive file hash does not match ${strArchiveChecksum}";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
confess 'archive file is not in destination';
|
|
}
|
|
}
|
|
|
|
$bCreate = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (BackRestTestCommon_Cleanup())
|
|
{
|
|
&log(INFO, 'cleanup');
|
|
BackRestTestBackup_Drop();
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------------------------------------------------------------------------
|
|
# Test full
|
|
#-------------------------------------------------------------------------------------------------------------------------------
|
|
if ($strTest eq 'all' || $strTest eq 'full')
|
|
{
|
|
$iRun = 0;
|
|
$bCreate = true;
|
|
|
|
&log(INFO, "Test Full Backup\n");
|
|
|
|
for (my $bRemote = false; $bRemote <= true; $bRemote++)
|
|
{
|
|
for (my $bLarge = false; $bLarge <= false; $bLarge++)
|
|
{
|
|
for (my $bCompress = false; $bCompress <= false; $bCompress++)
|
|
{
|
|
for (my $bChecksum = false; $bChecksum <= false; $bChecksum++)
|
|
{
|
|
for (my $bHardlink = false; $bHardlink <= true; $bHardlink++)
|
|
{
|
|
for (my $bArchiveAsync = false; $bArchiveAsync <= $bRemote; $bArchiveAsync++)
|
|
{
|
|
# Increment the run, log, and decide whether this unit test should be run
|
|
if (!BackRestTestCommon_Run(++$iRun,
|
|
"rmt ${bRemote}, lrg ${bLarge}, cmp ${bCompress}, chk ${bChecksum}, " .
|
|
"hardlink ${bHardlink}, arc_async ${bArchiveAsync}")) {next}
|
|
|
|
# Create the test directory
|
|
if ($bCreate)
|
|
{
|
|
BackRestTestBackup_Create($bRemote);
|
|
$bCreate = false;
|
|
}
|
|
|
|
# Create db config
|
|
BackRestTestCommon_ConfigCreate('db', # local
|
|
$bRemote ? REMOTE_BACKUP : undef, # remote
|
|
$bCompress, # compress
|
|
$bChecksum, # checksum
|
|
defined($bRemote) ? undef : $bHardlink, # hardlink
|
|
defined($bRemote) ? undef : $iThreadMax, # thread-max
|
|
$bArchiveAsync, # archive-async
|
|
undef); # compress-async
|
|
|
|
# Create backup config
|
|
if ($bRemote)
|
|
{
|
|
BackRestTestCommon_ConfigCreate('backup', # local
|
|
$bRemote ? REMOTE_DB : undef, # remote
|
|
$bCompress, # compress
|
|
$bChecksum, # checksum
|
|
$bHardlink, # hardlink
|
|
$iThreadMax, # thread-max
|
|
undef, # archive-async
|
|
undef); # compress-async
|
|
}
|
|
|
|
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++)
|
|
{
|
|
&log(INFO, " incr " . sprintf("%02d", $iIncr));
|
|
|
|
BackRestTestCommon_Execute($strCommand, $bRemote);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$bCreate = true;
|
|
}
|
|
}
|
|
|
|
if (BackRestTestCommon_Cleanup())
|
|
{
|
|
&log(INFO, 'cleanup');
|
|
BackRestTestBackup_Drop();
|
|
}
|
|
}
|
|
}
|
|
|
|
1;
|