2016-06-24 14:12:58 +02:00
|
|
|
####################################################################################################################################
|
2017-01-05 01:31:16 +02:00
|
|
|
# FullCommonTest.pm - Common code for backup tests
|
2016-06-24 14:12:58 +02:00
|
|
|
####################################################################################################################################
|
2017-05-12 22:43:04 +02:00
|
|
|
package pgBackRestTest::Env::HostEnvTest;
|
|
|
|
use parent 'pgBackRestTest::Env::ConfigEnvTest';
|
2016-06-24 14:12:58 +02:00
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# Perl includes
|
|
|
|
####################################################################################################################################
|
|
|
|
use strict;
|
|
|
|
use warnings FATAL => qw(all);
|
|
|
|
use Carp qw(confess);
|
|
|
|
|
|
|
|
use Exporter qw(import);
|
|
|
|
our @EXPORT = qw();
|
2017-06-09 23:51:41 +02:00
|
|
|
use Storable qw(dclone);
|
2016-06-24 14:12:58 +02:00
|
|
|
|
2016-08-24 18:39:27 +02:00
|
|
|
use pgBackRest::Common::Log;
|
2016-06-24 14:12:58 +02:00
|
|
|
use pgBackRest::Config::Config;
|
2017-06-09 23:51:41 +02:00
|
|
|
use pgBackRest::Protocol::Storage::Helper;
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2017-05-12 22:43:04 +02:00
|
|
|
use pgBackRestTest::Env::Host::HostBackupTest;
|
|
|
|
use pgBackRestTest::Env::Host::HostBaseTest;
|
|
|
|
use pgBackRestTest::Env::Host::HostDbCommonTest;
|
|
|
|
use pgBackRestTest::Env::Host::HostDbTest;
|
|
|
|
use pgBackRestTest::Env::Host::HostDbSyntheticTest;
|
2017-06-12 16:52:32 +02:00
|
|
|
use pgBackRestTest::Env::Host::HostS3Test;
|
|
|
|
use pgBackRestTest::Common::ContainerTest;
|
|
|
|
use pgBackRestTest::Common::ExecuteTest;
|
2016-06-24 14:12:58 +02:00
|
|
|
use pgBackRestTest::Common::HostGroupTest;
|
2017-06-09 23:51:41 +02:00
|
|
|
use pgBackRestTest::Common::RunTest;
|
2016-06-24 14:12:58 +02:00
|
|
|
|
|
|
|
####################################################################################################################################
|
2016-12-23 15:22:59 +02:00
|
|
|
# Constants
|
|
|
|
####################################################################################################################################
|
2017-04-03 16:42:55 +02:00
|
|
|
use constant WAL_VERSION_92 => '92';
|
|
|
|
push @EXPORT, qw(WAL_VERSION_92);
|
|
|
|
use constant WAL_VERSION_92_SYS_ID => 6393320793115174899;
|
|
|
|
push @EXPORT, qw(WAL_VERSION_92_SYS_ID);
|
|
|
|
use constant WAL_VERSION_93 => '93';
|
|
|
|
push @EXPORT, qw(WAL_VERSION_93);
|
|
|
|
use constant WAL_VERSION_93_SYS_ID => 6395542721432104958;
|
|
|
|
push @EXPORT, qw(WAL_VERSION_93_SYS_ID);
|
2016-12-23 15:22:59 +02:00
|
|
|
use constant WAL_VERSION_94 => '94';
|
|
|
|
push @EXPORT, qw(WAL_VERSION_94);
|
2017-01-27 18:02:27 +02:00
|
|
|
use constant WAL_VERSION_94_SYS_ID => 6353949018581704918;
|
|
|
|
push @EXPORT, qw(WAL_VERSION_94_SYS_ID);
|
2017-04-03 16:42:55 +02:00
|
|
|
use constant WAL_VERSION_95 => '95';
|
|
|
|
push @EXPORT, qw(WAL_VERSION_95);
|
|
|
|
use constant WAL_VERSION_95_SYS_ID => 6392579261579036436;
|
|
|
|
push @EXPORT, qw(WAL_VERSION_95_SYS_ID);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# setup
|
|
|
|
####################################################################################################################################
|
|
|
|
sub setup
|
|
|
|
{
|
|
|
|
my $self = shift;
|
2016-06-24 14:12:58 +02:00
|
|
|
my $bSynthetic = shift;
|
|
|
|
my $oLogTest = shift;
|
|
|
|
my $oConfigParam = shift;
|
|
|
|
|
2017-06-12 16:52:32 +02:00
|
|
|
# Start S3 server first since it takes the longest
|
|
|
|
#-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
my $oHostS3;
|
|
|
|
|
|
|
|
if ($oConfigParam->{bS3})
|
|
|
|
{
|
|
|
|
$oHostS3 = new pgBackRestTest::Env::Host::HostS3Test();
|
|
|
|
}
|
|
|
|
|
2016-06-24 14:12:58 +02:00
|
|
|
# Get host group
|
|
|
|
my $oHostGroup = hostGroupGet();
|
|
|
|
|
2016-08-24 18:39:27 +02:00
|
|
|
# Create the backup host
|
|
|
|
my $strBackupDestination;
|
|
|
|
my $bHostBackup = defined($$oConfigParam{bHostBackup}) ? $$oConfigParam{bHostBackup} : false;
|
2016-06-24 14:12:58 +02:00
|
|
|
my $oHostBackup = undef;
|
|
|
|
|
2016-08-24 18:39:27 +02:00
|
|
|
if ($bHostBackup)
|
2016-06-24 14:12:58 +02:00
|
|
|
{
|
2016-08-24 18:39:27 +02:00
|
|
|
$strBackupDestination = defined($$oConfigParam{strBackupDestination}) ? $$oConfigParam{strBackupDestination} : HOST_BACKUP;
|
|
|
|
|
2017-05-12 22:43:04 +02:00
|
|
|
$oHostBackup = new pgBackRestTest::Env::Host::HostBackupTest(
|
2017-06-12 16:52:32 +02:00
|
|
|
{strBackupDestination => $strBackupDestination, bSynthetic => $bSynthetic, oLogTest => $oLogTest,
|
|
|
|
bRepoLocal => !$oConfigParam->{bS3}});
|
2016-06-24 14:12:58 +02:00
|
|
|
$oHostGroup->hostAdd($oHostBackup);
|
|
|
|
}
|
2016-08-24 18:39:27 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
$strBackupDestination =
|
|
|
|
defined($$oConfigParam{strBackupDestination}) ? $$oConfigParam{strBackupDestination} : HOST_DB_MASTER;
|
|
|
|
}
|
2016-06-24 14:12:58 +02:00
|
|
|
|
2016-08-24 18:39:27 +02:00
|
|
|
# Create the db-master host
|
2016-06-24 14:12:58 +02:00
|
|
|
my $oHostDbMaster = undef;
|
|
|
|
|
|
|
|
if ($bSynthetic)
|
|
|
|
{
|
2017-05-12 22:43:04 +02:00
|
|
|
$oHostDbMaster = new pgBackRestTest::Env::Host::HostDbSyntheticTest(
|
2017-06-12 16:52:32 +02:00
|
|
|
{strBackupDestination => $strBackupDestination, oLogTest => $oLogTest, bRepoLocal => !$oConfigParam->{bS3}});
|
2016-06-24 14:12:58 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-05-12 22:43:04 +02:00
|
|
|
$oHostDbMaster = new pgBackRestTest::Env::Host::HostDbTest(
|
2017-06-12 16:52:32 +02:00
|
|
|
{strBackupDestination => $strBackupDestination, oLogTest => $oLogTest, bRepoLocal => !$oConfigParam->{bS3}});
|
2016-06-24 14:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$oHostGroup->hostAdd($oHostDbMaster);
|
2016-08-24 18:39:27 +02:00
|
|
|
|
|
|
|
# Create the db-standby host
|
|
|
|
my $oHostDbStandby = undef;
|
|
|
|
|
|
|
|
if (defined($$oConfigParam{bStandby}) && $$oConfigParam{bStandby})
|
|
|
|
{
|
2017-05-12 22:43:04 +02:00
|
|
|
$oHostDbStandby = new pgBackRestTest::Env::Host::HostDbTest(
|
2017-06-12 16:52:32 +02:00
|
|
|
{strBackupDestination => $strBackupDestination, bStandby => true, oLogTest => $oLogTest,
|
|
|
|
bRepoLocal => !$oConfigParam->{bS3}});
|
2016-08-24 18:39:27 +02:00
|
|
|
|
|
|
|
$oHostGroup->hostAdd($oHostDbStandby);
|
|
|
|
}
|
2016-06-24 14:12:58 +02:00
|
|
|
|
2017-06-12 16:52:32 +02:00
|
|
|
# Finalize S3 server
|
|
|
|
#-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
if (defined($oHostS3))
|
|
|
|
{
|
|
|
|
$oHostGroup->hostAdd($oHostS3, {rstryHostName => ['pgbackrest-dev.s3.amazonaws.com', 's3.amazonaws.com']});
|
|
|
|
|
|
|
|
# Wait for server to start
|
|
|
|
executeTest('docker logs -f ' . $oHostS3->container() . " | grep -m 1 \"server started\"");
|
|
|
|
|
|
|
|
$oHostS3->executeS3('mb s3://' . HOST_S3_BUCKET);
|
|
|
|
}
|
2016-06-24 14:12:58 +02:00
|
|
|
# Create db master config
|
2016-08-24 18:39:27 +02:00
|
|
|
$oHostDbMaster->configCreate({
|
|
|
|
strBackupSource => $$oConfigParam{strBackupSource},
|
|
|
|
bCompress => $$oConfigParam{bCompress},
|
|
|
|
bHardlink => $bHostBackup ? undef : $$oConfigParam{bHardLink},
|
2017-06-12 16:52:32 +02:00
|
|
|
bArchiveAsync => $$oConfigParam{bArchiveAsync},
|
|
|
|
bS3 => $$oConfigParam{bS3}});
|
2016-08-24 18:39:27 +02:00
|
|
|
|
|
|
|
# Create backup config if backup host exists
|
|
|
|
if (defined($oHostBackup))
|
|
|
|
{
|
|
|
|
$oHostBackup->configCreate({
|
|
|
|
bCompress => $$oConfigParam{bCompress},
|
2017-06-12 16:52:32 +02:00
|
|
|
bHardlink => $$oConfigParam{bHardLink},
|
|
|
|
bS3 => $$oConfigParam{bS3}});
|
2016-08-24 18:39:27 +02:00
|
|
|
}
|
|
|
|
# If backup host is not defined set it to db-master
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$oHostBackup = $strBackupDestination eq HOST_DB_MASTER ? $oHostDbMaster : $oHostDbStandby;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Create db-standby config
|
|
|
|
if (defined($oHostDbStandby))
|
2016-06-24 14:12:58 +02:00
|
|
|
{
|
2016-08-24 18:39:27 +02:00
|
|
|
$oHostDbStandby->configCreate({
|
|
|
|
strBackupSource => $$oConfigParam{strBackupSource},
|
|
|
|
bCompress => $$oConfigParam{bCompress},
|
|
|
|
bHardlink => $bHostBackup ? undef : $$oConfigParam{bHardLink},
|
|
|
|
bArchiveAsync => $$oConfigParam{bArchiveAsync}});
|
2016-06-24 14:12:58 +02:00
|
|
|
}
|
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
# Set options needed for storage helper
|
2017-08-25 22:47:47 +02:00
|
|
|
$self->optionTestSet(CFGOPT_DB_PATH, $oHostDbMaster->dbBasePath());
|
|
|
|
$self->optionTestSet(CFGOPT_REPO_PATH, $oHostBackup->repoPath());
|
|
|
|
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
2017-06-12 16:52:32 +02:00
|
|
|
|
|
|
|
# Set S3 options
|
|
|
|
if (defined($oHostS3))
|
|
|
|
{
|
2017-08-25 22:47:47 +02:00
|
|
|
$self->optionTestSet(CFGOPT_REPO_TYPE, CFGOPTVAL_REPO_TYPE_S3);
|
|
|
|
$self->optionTestSet(CFGOPT_REPO_S3_KEY, HOST_S3_ACCESS_KEY);
|
|
|
|
$self->optionTestSet(CFGOPT_REPO_S3_KEY_SECRET, HOST_S3_ACCESS_SECRET_KEY);
|
|
|
|
$self->optionTestSet(CFGOPT_REPO_S3_BUCKET, HOST_S3_BUCKET);
|
|
|
|
$self->optionTestSet(CFGOPT_REPO_S3_ENDPOINT, HOST_S3_ENDPOINT);
|
|
|
|
$self->optionTestSet(CFGOPT_REPO_S3_REGION, HOST_S3_REGION);
|
|
|
|
$self->optionTestSet(CFGOPT_REPO_S3_HOST, $oHostS3->ipGet());
|
|
|
|
$self->optionTestSetBool(CFGOPT_REPO_S3_VERIFY_SSL, false);
|
2017-06-12 16:52:32 +02:00
|
|
|
}
|
|
|
|
|
2017-08-25 22:47:47 +02:00
|
|
|
$self->configTestLoad(CFGCMD_ARCHIVE_PUSH);
|
2017-06-09 23:51:41 +02:00
|
|
|
|
2017-06-12 16:52:32 +02:00
|
|
|
return $oHostDbMaster, $oHostDbStandby, $oHostBackup, $oHostS3;
|
2016-06-24 14:12:58 +02:00
|
|
|
}
|
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# archiveGenerate
|
|
|
|
#
|
|
|
|
# Generate an WAL segment for testing.
|
|
|
|
####################################################################################################################################
|
|
|
|
sub archiveGenerate
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
my $strXlogPath = shift;
|
|
|
|
my $iSourceNo = shift;
|
|
|
|
my $iArchiveNo = shift;
|
|
|
|
my $strWalVersion = shift;
|
|
|
|
my $bPartial = shift;
|
|
|
|
|
|
|
|
my $strArchiveFile = uc(sprintf('0000000100000001%08x', $iArchiveNo)) .
|
|
|
|
(defined($bPartial) && $bPartial ? '.partial' : '');
|
|
|
|
my $strArchiveTestFile = $self->dataPath() . "/backup.wal${iSourceNo}_${strWalVersion}.bin";
|
|
|
|
|
|
|
|
my $strSourceFile = "${strXlogPath}/${strArchiveFile}";
|
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
storageTest()->copy($strArchiveTestFile, $strSourceFile);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
return $strArchiveFile, $strSourceFile;
|
|
|
|
}
|
2016-06-24 14:12:58 +02:00
|
|
|
|
2017-01-27 18:02:27 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# walSegment
|
|
|
|
#
|
|
|
|
# Generate name of WAL segment from component parts.
|
|
|
|
####################################################################################################################################
|
|
|
|
sub walSegment
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
my $iTimeline = shift;
|
|
|
|
my $iMajor = shift;
|
|
|
|
my $iMinor = shift;
|
|
|
|
|
|
|
|
return uc(sprintf('%08x%08x%08x', $iTimeline, $iMajor, $iMinor));
|
|
|
|
}
|
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# walGenerate
|
|
|
|
#
|
|
|
|
# Generate a WAL segment and ready file for testing.
|
|
|
|
####################################################################################################################################
|
|
|
|
sub walGenerate
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
my $strWalPath = shift;
|
|
|
|
my $strPgVersion = shift;
|
|
|
|
my $iSourceNo = shift;
|
|
|
|
my $strWalSegment = shift;
|
|
|
|
my $bPartial = shift;
|
|
|
|
|
|
|
|
my $strWalFile = "${strWalPath}/${strWalSegment}" . (defined($bPartial) && $bPartial ? '.partial' : '');
|
|
|
|
my $strArchiveTestFile = $self->dataPath() . "/backup.wal${iSourceNo}_${strPgVersion}.bin";
|
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
storageTest()->copy($strArchiveTestFile, $strWalFile);
|
2017-01-27 18:02:27 +02:00
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
storageTest()->put("${strWalPath}/archive_status/${strWalSegment}.ready");
|
2017-01-27 18:02:27 +02:00
|
|
|
|
|
|
|
return $strWalFile;
|
|
|
|
}
|
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# walRemove
|
|
|
|
#
|
|
|
|
# Remove WAL file and ready file.
|
|
|
|
####################################################################################################################################
|
|
|
|
sub walRemove
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
my $strWalPath = shift;
|
|
|
|
my $strWalFile = shift;
|
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
storageTest()->remove("$self->{strWalPath}/${strWalFile}");
|
|
|
|
storageTest()->remove("$self->{strWalPath}/archive_status/${strWalFile}.ready");
|
2017-01-27 18:02:27 +02:00
|
|
|
}
|
|
|
|
|
2016-06-24 14:12:58 +02:00
|
|
|
1;
|