1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00
pgbackrest/test/lib/pgBackRestTest/Module/Info/InfoInfoBackupPerlTest.pm
David Steele 11c7c8fabb Remove pgbackrest test user.
This user was created before we tested in containers to ensure isolation between the pg and repo hosts which were then just directories.  The downside is that this resulted in a lot of sudos to set the pgbackrest user and to remove files which did not belong to the main test user.

Containers provide isolation without needing separate users so we can now safely remove the pgbackrest user.  This allows us to remove most sudos, except where they are explicitly needed in tests.

While we're at it, remove the code that installed the Perl C library (which also required sudo) and simply add the build path to @INC instead.
2019-10-12 09:45:18 -04:00

263 lines
14 KiB
Perl

####################################################################################################################################
# Unit tests for BackupInfo
####################################################################################################################################
package pgBackRestTest::Module::Info::InfoInfoBackupPerlTest;
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_CRYPTO,
"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('rm ' . $oBackupInfo->{strFileName} . '*');
# Clear the storage repo settings and change the passphrase
storageRepoCacheClear();
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->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_CRYPTO,
"unable to parse '" . $oBackupInfo->{strFileName} . "'" .
"\nHINT: is or was the repo encrypted?");
}
}
1;