1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00
pgbackrest/test/lib/pgBackRestTest/Module/Backup/BackupInfoUnitPerlTest.pm
David Steele 88a633da17 Divide tests into three types (unit, integration, performance).
Many options that were set per test can instead be inferred from the types, i.e. container, c, expect, and individual.

Also finish renaming Perl unit tests with the -perl suffix.
2018-04-24 09:12:25 -04:00

263 lines
14 KiB
Perl

####################################################################################################################################
# Unit tests for BackupInfo
####################################################################################################################################
package pgBackRestTest::Module::Backup::BackupInfoUnitPerlTest;
use parent 'pgBackRestTest::Env::HostEnvTest';
####################################################################################################################################
# Perl includes
####################################################################################################################################
use strict;
use warnings FATAL => qw(all);
use Carp qw(confess);
use English '-no_match_vars';
use File::Basename qw(dirname);
use Storable qw(dclone);
use pgBackRest::Archive::Info;
use pgBackRest::Backup::Info;
use pgBackRest::Common::Cipher;
use pgBackRest::Common::Exception;
use pgBackRest::Common::Lock;
use pgBackRest::Common::Log;
use pgBackRest::Config::Config;
use pgBackRest::DbVersion;
use pgBackRest::InfoCommon;
use pgBackRest::Manifest;
use pgBackRest::Protocol::Storage::Helper;
use pgBackRest::Storage::Base;
use pgBackRestTest::Env::HostEnvTest;
use pgBackRestTest::Common::ExecuteTest;
use pgBackRestTest::Common::RunTest;
####################################################################################################################################
# initModule
####################################################################################################################################
sub initModule
{
my $self = shift;
$self->{strRepoPath} = $self->testPath() . '/repo';
}
####################################################################################################################################
# initTest
####################################################################################################################################
sub initTest
{
my $self = shift;
# Load options
$self->configTestClear();
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
$self->optionTestSet(CFGOPT_REPO_PATH, $self->testPath() . '/repo');
$self->configTestLoad(CFGCMD_ARCHIVE_PUSH);
# Create backup info path
storageRepo()->pathCreate(STORAGE_REPO_BACKUP, {bCreateParent => true});
# Create archive info path
storageRepo()->pathCreate(STORAGE_REPO_ARCHIVE, {bCreateParent => true});
}
####################################################################################################################################
# run
####################################################################################################################################
sub run
{
my $self = shift;
my $i93ControlVersion = 937;
my $i93CatalogVersion = 201306121;
my $i94ControlVersion = 942;
my $i94CatalogVersion = 201409291;
################################################################################################################################
if ($self->begin("BackupInfo::check() && BackupInfo::confirmDb()"))
{
my $oBackupInfo = new pgBackRest::Backup::Info(storageRepo()->pathGet(STORAGE_REPO_BACKUP), false, false,
{bIgnoreMissing => true});
$oBackupInfo->create(PG_VERSION_93, $self->dbSysId(PG_VERSION_93), $i93ControlVersion, $i93CatalogVersion, true);
# All DB section matches
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(sub {$oBackupInfo->check(
PG_VERSION_93, $i93ControlVersion, $i93CatalogVersion, $self->dbSysId(PG_VERSION_93), false)}, 1, 'db section matches');
# DB section version mismatch
#---------------------------------------------------------------------------------------------------------------------------
$self->testException(sub {$oBackupInfo->check(PG_VERSION_94, $i93ControlVersion, $i93CatalogVersion,
$self->dbSysId(PG_VERSION_93))}, ERROR_BACKUP_MISMATCH,
"database version = " . &PG_VERSION_94 . ", system-id " . $self->dbSysId(PG_VERSION_93) .
" does not match backup version = " . &PG_VERSION_93 . ", " . "system-id = " . $self->dbSysId(PG_VERSION_93) .
"\nHINT: is this the correct stanza?");
# DB section system-id mismatch
#---------------------------------------------------------------------------------------------------------------------------
$self->testException(
sub {$oBackupInfo->check(PG_VERSION_93, $i93ControlVersion, $i93CatalogVersion, $self->dbSysId(PG_VERSION_94))},
ERROR_BACKUP_MISMATCH,
"database version = " . &PG_VERSION_93 . ", system-id " . $self->dbSysId(PG_VERSION_94) .
" does not match backup version = " . &PG_VERSION_93 . ", " . "system-id = " . $self->dbSysId(PG_VERSION_93) .
"\nHINT: is this the correct stanza?");
# DB section control version mismatch
#---------------------------------------------------------------------------------------------------------------------------
$self->testException(sub {$oBackupInfo->check(PG_VERSION_93, 123, $i93CatalogVersion, $self->dbSysId(PG_VERSION_93))},
ERROR_BACKUP_MISMATCH, "database control-version = 123, catalog-version $i93CatalogVersion " .
"does not match backup control-version = $i93ControlVersion, catalog-version = $i93CatalogVersion" .
"\nHINT: this may be a symptom of database or repository corruption!");
# DB section catalog version mismatch
#---------------------------------------------------------------------------------------------------------------------------
$self->testException(sub {$oBackupInfo->check(PG_VERSION_93, $i93ControlVersion, 123456789, $self->dbSysId(PG_VERSION_93))},
ERROR_BACKUP_MISMATCH, "database control-version = $i93ControlVersion, catalog-version 123456789 " .
"does not match backup control-version = $i93ControlVersion, catalog-version = $i93CatalogVersion" .
"\nHINT: this may be a symptom of database or repository corruption!");
my $strBackupLabel = "20170403-175647F";
$oBackupInfo->set(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackupLabel, INFO_BACKUP_KEY_HISTORY_ID,
$oBackupInfo->get(INFO_BACKUP_SECTION_DB, INFO_BACKUP_KEY_HISTORY_ID));
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(sub {$oBackupInfo->confirmDb($strBackupLabel, PG_VERSION_93, $self->dbSysId(PG_VERSION_93))}, true,
'backup db matches');
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(sub {$oBackupInfo->confirmDb($strBackupLabel, PG_VERSION_94, $self->dbSysId(PG_VERSION_93))}, false,
'backup db wrong version');
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(sub {$oBackupInfo->confirmDb($strBackupLabel, PG_VERSION_93, $self->dbSysId(PG_VERSION_94))}, false,
'backup db wrong system-id');
}
################################################################################################################################
if ($self->begin("BackupInfo::backupArchiveDbHistoryId()"))
{
my $oBackupInfo = new pgBackRest::Backup::Info(storageRepo()->pathGet(STORAGE_REPO_BACKUP), false, false,
{bIgnoreMissing => true});
$oBackupInfo->create(PG_VERSION_93, $self->dbSysId(PG_VERSION_93), $i93ControlVersion, $i93CatalogVersion, true);
my $oArchiveInfo = new pgBackRest::Archive::Info(storageRepo()->pathGet(STORAGE_REPO_ARCHIVE), false,
{bLoad => false, bIgnoreMissing => true});
$oArchiveInfo->create(PG_VERSION_93, $self->dbSysId(PG_VERSION_93), true);
# Map archiveId to Backup history id
#---------------------------------------------------------------------------------------------------------------------------
my $strArchiveId = $oArchiveInfo->archiveId({strDbVersion => PG_VERSION_93, ullDbSysId => $self->dbSysId(PG_VERSION_93)});
$self->testResult(sub {$oBackupInfo->backupArchiveDbHistoryId($strArchiveId,
storageRepo()->pathGet(STORAGE_REPO_ARCHIVE))}, 1, 'backupArchiveDbHistoryId found');
# Unable to map archiveId to Backup history id
#---------------------------------------------------------------------------------------------------------------------------
$strArchiveId = &PG_VERSION_94 . "-2";
$self->testResult(sub {$oBackupInfo->backupArchiveDbHistoryId($strArchiveId,
storageRepo()->pathGet(STORAGE_REPO_ARCHIVE))}, "[undef]", 'backupArchiveDbHistoryId not found');
# Same version but different ullsystemid so continue looking until find match
#---------------------------------------------------------------------------------------------------------------------------
# Update db section and db history sections
my $iHistoryId = $oBackupInfo->dbHistoryIdGet(true)+1;
$oBackupInfo->dbSectionSet(
PG_VERSION_94, $i94ControlVersion, $i94CatalogVersion, $self->dbSysId(PG_VERSION_93), $iHistoryId);
$oArchiveInfo->dbSectionSet(PG_VERSION_94, $self->dbSysId(PG_VERSION_93), $iHistoryId);
$oBackupInfo->save();
$oArchiveInfo->save();
$strArchiveId = &PG_VERSION_94 . "-" . $iHistoryId;
$self->testResult(sub {$oBackupInfo->backupArchiveDbHistoryId($strArchiveId,
storageRepo()->pathGet(STORAGE_REPO_ARCHIVE))}, $iHistoryId, 'same db version but different system-id');
# Different version but same ullsystemid
#---------------------------------------------------------------------------------------------------------------------------
$iHistoryId = $oBackupInfo->dbHistoryIdGet(false)+1;
$oBackupInfo->dbSectionSet(
PG_VERSION_94, $i93ControlVersion, $i93CatalogVersion, $self->dbSysId(PG_VERSION_94), $iHistoryId);
$oArchiveInfo->dbSectionSet(PG_VERSION_94, $self->dbSysId(PG_VERSION_94), $iHistoryId);
$oBackupInfo->save();
$oArchiveInfo->save();
$strArchiveId = &PG_VERSION_93 . "-" . $iHistoryId;
$self->testResult(sub {$oBackupInfo->backupArchiveDbHistoryId($strArchiveId,
storageRepo()->pathGet(STORAGE_REPO_ARCHIVE))}, "[undef]", 'same db system-id but different version');
# First and last version and ullsystemid same in backup.info but only 1st in archive info - return last
#---------------------------------------------------------------------------------------------------------------------------
$iHistoryId = $oBackupInfo->dbHistoryIdGet(true)+1;
$oBackupInfo->dbSectionSet(
PG_VERSION_93, $i93ControlVersion, $i93CatalogVersion, $self->dbSysId(PG_VERSION_93), $iHistoryId);
$oBackupInfo->save();
$strArchiveId = &PG_VERSION_93 . "-1";
$self->testResult(sub {$oBackupInfo->backupArchiveDbHistoryId($strArchiveId,
storageRepo()->pathGet(STORAGE_REPO_ARCHIVE))}, $iHistoryId, 'duplicate 1st and last version/sysid - last chosen');
}
################################################################################################################################
if ($self->begin("encryption"))
{
# Create a backupInfo file
my $oBackupInfo = new pgBackRest::Backup::Info(storageRepo()->pathGet(STORAGE_REPO_BACKUP), false, false,
{bIgnoreMissing => true});
$oBackupInfo->create(PG_VERSION_93, $self->dbSysId(PG_VERSION_93), $i93ControlVersion, $i93CatalogVersion, true);
my $strFile = $oBackupInfo->{strFileName};
# Prepend encryption Magic signature to simulate encryption
executeTest('echo "' . CIPHER_MAGIC . '$(cat ' . $strFile . ')" > ' . $strFile);
$self->testException(sub {new pgBackRest::Backup::Info(storageRepo()->pathGet(STORAGE_REPO_BACKUP))}, ERROR_CIPHER,
"unable to parse '$strFile'" .
"\nHINT: Is or was the repo encrypted?");
# Create encrypted files, change the passphrase and attempt to load - ensure flush error returned as parse error
#---------------------------------------------------------------------------------------------------------------------------
# Remove the backup info files
executeTest('sudo rm ' . $oBackupInfo->{strFileName} . '*');
# Clear the storage repo settings and change the passphrase
storageRepoCacheClear($self->stanza());
my $strCipherPass = 'x';
$self->configTestClear();
$self->optionTestSet(CFGOPT_REPO_CIPHER_TYPE, CFGOPTVAL_REPO_CIPHER_TYPE_AES_256_CBC);
$self->optionTestSet(CFGOPT_REPO_CIPHER_PASS, $strCipherPass);
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
$self->optionTestSet(CFGOPT_REPO_PATH, $self->testPath() . '/repo');
$self->configTestLoad(CFGCMD_ARCHIVE_PUSH);
# Confirm exception when not passing a sub passphrase
$self->testException(sub {new pgBackRest::Backup::Info(storageRepo()->pathGet(STORAGE_REPO_BACKUP), false, false,
{bIgnoreMissing => true})}, ERROR_ASSERT,
'a user passphrase and sub passphrase are both required when encrypting');
my $strCipherPassSub = cipherPassGen();
# Create encrypted files
$oBackupInfo = new pgBackRest::Backup::Info(storageRepo()->pathGet(STORAGE_REPO_BACKUP), false, false,
{bIgnoreMissing => true, strCipherPassSub => $strCipherPassSub});
$oBackupInfo->create(PG_VERSION_93, $self->dbSysId(PG_VERSION_93), $i93ControlVersion, $i93CatalogVersion, true);
# Clear the storage repo settings and change the passphrase
storageRepoCacheClear($self->stanza());
$self->optionTestSet(CFGOPT_REPO_CIPHER_TYPE, CFGOPTVAL_REPO_CIPHER_TYPE_AES_256_CBC);
$self->optionTestSet(CFGOPT_REPO_CIPHER_PASS, BOGUS);
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
$self->optionTestSet(CFGOPT_REPO_PATH, $self->testPath() . '/repo');
$self->configTestLoad(CFGCMD_ARCHIVE_PUSH);
$self->testException(sub {new pgBackRest::Backup::Info(storageRepo()->pathGet(STORAGE_REPO_BACKUP))}, ERROR_CIPHER,
"unable to parse '" . $oBackupInfo->{strFileName} . "'" .
"\nHINT: Is or was the repo encrypted?");
}
}
1;