1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00
pgbackrest/test/lib/pgBackRestTest/Module/Manifest/ManifestAllPerlTest.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

1083 lines
69 KiB
Perl

####################################################################################################################################
# Unit tests for Manifest module
####################################################################################################################################
package pgBackRestTest::Module::Manifest::ManifestAllPerlTest;
use parent 'pgBackRestTest::Env::HostEnvTest';
####################################################################################################################################
# Perl includes
####################################################################################################################################
use strict;
use warnings FATAL => qw(all);
use Carp qw(confess);
use File::Basename qw(dirname);
use Storable qw(dclone);
use pgBackRest::Backup::Common;
use pgBackRest::Common::Exception;
use pgBackRest::Common::Ini;
use pgBackRest::Common::Log;
use pgBackRest::Common::String;
use pgBackRest::Common::Wait;
use pgBackRest::Config::Config;
use pgBackRest::DbVersion;
use pgBackRest::Manifest;
use pgBackRest::Protocol::Helper;
use pgBackRest::Protocol::Storage::Helper;
use pgBackRest::Storage::Helper;
use pgBackRest::Version;
use pgBackRestTest::Common::ContainerTest;
use pgBackRestTest::Common::ExecuteTest;
use pgBackRestTest::Common::FileTest;
use pgBackRestTest::Common::RunTest;
use pgBackRestTest::Env::Host::HostBackupTest;
####################################################################################################################################
# Issues / Improvements
#
# While working on the unit tests a number of possible issues/improvements have come up. Issues are documented in the tests where
# they are relevant with an INVESTIGATE tag. General improvements are listed here to be addressed later:
#
# 1. Assignment of required values to the manifest is haphazard. Db version is in the constructor but the rest is assigned in
# Backup.pm. These should probably all be passed in the constructor. It may be like it is now in part because of test needs
# but that should be changed if so.
#
# 2. Improve validate function to check that all values that are collected actually got set. Some things are being checked now,
# but others like backup-lsn-start, backup-wal-start, etc. are not. Include all options like option-compress, etc. and db info
# like db-id, system-id, etc. Basically, validate should check everything in the manifest before it is saved (for the last time
# since intermediate saves may be missing data) and make sure nothing is missing or extraneous. Also check the contents of
# values, i.e. make sure that checksum is really a 40-character hex string.
#
# 3. In fileAdd() the mode should be based on a mask (remove execute bit) of the dir mode, rather than a constant. i.e. dir mode
# 0700 should become 0600, dir mode 0750 should become 0640, etc.
####################################################################################################################################
####################################################################################################################################
# Constants
####################################################################################################################################
use constant MODE_0750 => '0750';
use constant MODE_0700 => '0700';
use constant MODE_0644 => '0644';
use constant MODE_0600 => '0600';
use constant PGCONTROL_SIZE => 8192;
####################################################################################################################################
# initModule
####################################################################################################################################
sub initModule
{
my $self = shift;
$self->{strDbPath} = $self->testPath() . "/db";
$self->{strRepoPath} = $self->testPath() . "/repo";
$self->{strArchivePath} = "$self->{strRepoPath}/archive/" . $self->stanza();
$self->{strBackupPath} = "$self->{strRepoPath}/backup/" . $self->stanza();
$self->{strSpoolPath} = "$self->{strArchivePath}/out";
$self->{strExpectedManifest} = $self->testPath() . "/expected.manifest";
$self->{strActualManifest} = $self->testPath() . "/actual.manifest";
}
####################################################################################################################################
# initTest
####################################################################################################################################
sub initTest
{
my $self = shift;
# Create archive info path
storageTest()->pathCreate($self->{strArchivePath}, {bIgnoreExists => true, bCreateParent => true});
# Create backup info path
storageTest()->pathCreate($self->{strBackupPath}, {bIgnoreExists => true, bCreateParent => true});
# Create pg_control global path
storageTest()->pathCreate($self->{strDbPath} . '/' . DB_PATH_GLOBAL, {bCreateParent => true});
}
####################################################################################################################################
# manifestCompare
####################################################################################################################################
sub manifestCompare
{
my $self = shift;
my $oManifestExpected = shift;
my $oManifestActual = shift;
# Remove manifest files if exist
storageTest()->remove($self->{strExpectedManifest}, {bIgnoreMissing => true});
storageTest()->remove($self->{strActualManifest}, {bIgnoreMissing => true});
# Section backup. Confirm the copy-start timestamp is set for the actual manifest then copy it to the expected so files can
# be compared
if ($oManifestActual->test(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_TIMESTAMP_COPY_START))
{
$oManifestExpected->set(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_TIMESTAMP_COPY_START, undef,
$oManifestActual->get(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_TIMESTAMP_COPY_START));
}
else
{
return MANIFEST_KEY_TIMESTAMP_COPY_START . " not set in actual manifest";
}
storageTest()->put($self->{strActualManifest}, iniRender($oManifestActual->{oContent}));
storageTest()->put($self->{strExpectedManifest}, iniRender($oManifestExpected->{oContent}));
return executeTest("diff " . $self->{strExpectedManifest} . " " . $self->{strActualManifest});
}
####################################################################################################################################
# run
####################################################################################################################################
sub run
{
my $self = shift;
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
$self->optionTestSet(CFGOPT_REPO_PATH, $self->{strRepoPath});
$self->optionTestSet(CFGOPT_PG_PATH, $self->{strDbPath});
$self->configTestLoad(CFGCMD_ARCHIVE_PUSH);
my $strBackupLabel = backupLabelFormat(CFGOPTVAL_BACKUP_TYPE_FULL, undef, 1482000000);
my $strBackupPath = storageRepo->pathGet(STORAGE_REPO_BACKUP . "/${strBackupLabel}");
my $strBackupManifestFile = "$strBackupPath/" . FILE_MANIFEST;
my $iDbCatalogVersion = 201409291;
my $lTime = time() - 10000;
my $strTest = 'test';
my $oManifestBase = new pgBackRest::Common::Ini($self->{strExpectedManifest}, {bLoad => false});
# Section: backup:db
$oManifestBase->set(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_DB_VERSION, undef, PG_VERSION_94);
# Section: target:path
my $hDefault = {};
$oManifestBase->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_TARGET_PGDATA, undef, $hDefault);
$oManifestBase->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_PATH_GLOBAL, undef, $hDefault);
# Section: target:path:default
$oManifestBase->set(MANIFEST_SECTION_TARGET_PATH . ":default", MANIFEST_SUBKEY_MODE, undef, MODE_0750);
$oManifestBase->set(MANIFEST_SECTION_TARGET_PATH . ":default", MANIFEST_SUBKEY_GROUP, undef, TEST_GROUP);
$oManifestBase->set(MANIFEST_SECTION_TARGET_PATH . ":default", MANIFEST_SUBKEY_USER, undef, TEST_USER);
# Section backup:target
$oManifestBase->set(MANIFEST_SECTION_BACKUP_TARGET, MANIFEST_TARGET_PGDATA, MANIFEST_SUBKEY_TYPE, MANIFEST_VALUE_PATH);
$oManifestBase->set(MANIFEST_SECTION_BACKUP_TARGET, MANIFEST_TARGET_PGDATA, MANIFEST_SUBKEY_PATH, $self->{strDbPath});
################################################################################################################################
if ($self->begin('new()'))
{
# Missing DB version
#---------------------------------------------------------------------------------------------------------------------------
$self->testException(sub {(new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false}))}, ERROR_ASSERT,
'strDbVersion must be provided with bLoad = false');
# Successfully instantiate
#---------------------------------------------------------------------------------------------------------------------------
my $oManifest = $self->testResult(sub {(new pgBackRest::Manifest($strBackupManifestFile,
{bLoad => false, strDbVersion => PG_VERSION_94}))}, "[object]", 'manifest instantiated');
# Initialize
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(sub {$oManifest->test(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_DB_VERSION, undef, PG_VERSION_94) &&
$oManifest->test(INI_SECTION_BACKREST, INI_KEY_FORMAT, undef, $oManifest->{iInitFormat}) &&
$oManifest->test(INI_SECTION_BACKREST, INI_KEY_VERSION, undef, $oManifest->{strInitVersion})}, true,
' manifest initialized');
# Attempt to save without proper path
#---------------------------------------------------------------------------------------------------------------------------
$self->testException(sub {$oManifest->save()}, ERROR_PATH_MISSING,
"unable to open '" . $strBackupManifestFile . "': No such file or directory");
# Create path and save
#---------------------------------------------------------------------------------------------------------------------------
storageRepo()->pathCreate($strBackupPath);
$self->testResult(sub {$oManifest->save()}, "[undef]", 'manifest saved');
# Load and check the saved file
#---------------------------------------------------------------------------------------------------------------------------
my $oBackupManifest = $self->testResult(sub {(new pgBackRest::Manifest($strBackupManifestFile))}, "[object]",
' saved manifest loaded');
$self->testResult(sub {($oManifest->numericGet(INI_SECTION_BACKREST, INI_KEY_FORMAT) ==
$oBackupManifest->numericGet(INI_SECTION_BACKREST, INI_KEY_FORMAT)) &&
($oManifest->get(INI_SECTION_BACKREST, INI_KEY_CHECKSUM) eq
$oBackupManifest->get(INI_SECTION_BACKREST, INI_KEY_CHECKSUM))}, true,
' saved manifest equals initial manifest');
}
################################################################################################################################
if ($self->begin('build()'))
{
my $oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_94});
# Build error if offline = true and no tablespace path
#---------------------------------------------------------------------------------------------------------------------------
$self->testException(sub {$oManifest->build(storageDb(), $self->{strDbPath}, undef, false)}, ERROR_FILE_MISSING,
"unable to stat '" . $self->{strDbPath} . "/" . MANIFEST_TARGET_PGTBLSPC . "': No such file or directory");
# bOnline = true tests - Compare the base manifest
#---------------------------------------------------------------------------------------------------------------------------
$oManifest->build(storageDb(), $self->{strDbPath}, undef, true);
$self->testResult(sub {$self->manifestCompare($oManifestBase, $oManifest)}, "", 'base manifest');
# Create expected manifest from base
my $oManifestExpected = dclone($oManifestBase);
# Add global/pg_control file and PG_VERSION file and create a directory with a different modes than default
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_FILE_PGCONTROL,
{strMode => MODE_0644, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime}),
$self->controlGenerateContent(PG_VERSION_94));
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_FILE_PGVERSION,
{strMode => MODE_0600, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime}), PG_VERSION_94);
# Create base path with different mode than default
storageDb()->pathCreate(DB_PATH_BASE, {strMode => MODE_0700});
# Update expected manifest
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_MODE, undef, MODE_0600);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_GROUP, undef, TEST_GROUP);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_USER, undef, TEST_USER);
$oManifestExpected->boolSet(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_MASTER, undef, true);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_FILE_PGCONTROL, MANIFEST_SUBKEY_SIZE, PGCONTROL_SIZE);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_FILE_PGCONTROL, MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_FILE_PGCONTROL, MANIFEST_SUBKEY_MODE, MODE_0644);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' .DB_FILE_PGVERSION,
MANIFEST_SUBKEY_SIZE, length(&PG_VERSION_94));
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' .DB_FILE_PGVERSION,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_PATH_BASE, MANIFEST_SUBKEY_MODE, MODE_0700);
$oManifest->build(storageDb(), $self->{strDbPath}, undef, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "", 'paths/files and different modes');
# Master = false
#---------------------------------------------------------------------------------------------------------------------------
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_PATH_BASE . '/' . $strTest,
{strMode => MODE_0600, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime}), $strTest);
# Update expected manifest
$oManifestExpected->boolSet(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . DB_PATH_BASE . '/' . $strTest,
MANIFEST_SUBKEY_MASTER, undef, false);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . DB_PATH_BASE . '/' . $strTest,
MANIFEST_SUBKEY_SIZE, length($strTest));
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . DB_PATH_BASE . '/' . $strTest,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifest->build(storageDb(), $self->{strDbPath}, undef, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "", 'master false');
# Create a pg_config path and file link
my $strConfFile = '/pg_config/postgresql.conf';
my $strConfContent = "listen_addresses = *\n";
storageDb()->pathCreate('pg_config');
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . $strConfFile,
{strMode => MODE_0600, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime}), $strConfContent);
# link db/pg_config/postgresql.conf.link -> ./postgresql.conf
testLinkCreate($self->{strDbPath} . $strConfFile . '.link', './postgresql.conf');
# INVESTIGATE: on the command line, these links appear to be fine but in the code, a debug line prior to the recursive call to build() produces:
# STRPATH BEFORE BUILD: /home/ubuntu/test/test-0/db/base, STRLEVEL PASSED: $VAR1 = 'pg_data/base/pg_config_bad';
# STRFILTER: $VAR1 = undef;
# STRPATH BEFORE BUILD: /home/ubuntu/test/test-0/db/pg_config, STRLEVEL PASSED: $VAR1 = 'pg_data/base/pg_config_bad/postgresql.conf.link';
# STRFILTER: $VAR1 = undef;
# STRPATH BEFORE BUILD: /home/ubuntu/test/test-0/db/base/base, STRLEVEL PASSED: $VAR1 = 'pg_data/base/postgresql.conf';
# STRFILTER: $VAR1 = undef;
#
# and right here throws: 'unable to stat '/home/ubuntu/test/test-0/db/base/pg_config/postgresql.conf': No such file or directory'
# -- note the extra "base" here - it should just be /home/ubuntu/test/test-0/db/pg_config/postgresql.conf
# # link db/base/pg_config_bad -> ../../db/pg_config
# testLinkCreate($self->{strDbPath} . '/'. DB_PATH_BASE . '/pg_config_bad', '../../db/pg_config');
# # link db/base/postgresql.conf -> ../pg_config/postgresql.conf
# testLinkCreate($self->{strDbPath} . '/'. DB_PATH_BASE . '/postgresql.conf', '..' . $strConfFile);
# $self->testException(sub {$oManifest->build(storageDb(), $self->{strDbPath}, undef, true)}, ERROR_LINK_DESTINATION,
# 'TEST THIS');
# INVESTIGATE: Even though the below code creates a duplicate link, this error occurs (note the pg_config/pg_config):
# 'unable to stat '/home/ubuntu/test/test-0/db/pg_config/pg_config/./postgresql.conf': No such file or directory'
# ubuntu@pgbackrest-test:~$ ls -l /home/ubuntu/test/test-0/db/pg_config/
# total 4
# -rw------- 1 ubuntu ubuntu 21 Nov 9 17:07 postgresql.conf
# lrwxrwxrwx 1 ubuntu ubuntu 17 Nov 9 19:53 postgresql.conf.bad.link -> ./postgresql.conf
# lrwxrwxrwx 1 ubuntu ubuntu 17 Nov 9 19:53 postgresql.conf.link -> ./postgresql.conf
# # This link will cause errors because it points to the same location as above
# testLinkCreate($self->{strDbPath} . $strConfFile . '.bad.link', './postgresql.conf');
#
# $self->testException(sub {$oManifest->build(storageDb(), $self->{strDbPath}, undef, true)}, ERROR_LINK_DESTINATION,
# 'TEST ERROR');
# testFileRemove($self->{strDbPath} . $strConfFile . '.link.bad');
# Update expected manifest
$oManifestExpected->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_PATH_BASE, MANIFEST_SUBKEY_MODE, MODE_0700);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_TARGET_PGDATA . '/pg_config', undef, $hDefault);
# Section backup:target
$oManifestExpected->set(MANIFEST_SECTION_BACKUP_TARGET, MANIFEST_TARGET_PGDATA . $strConfFile . '.link',
MANIFEST_SUBKEY_FILE, 'postgresql.conf');
$oManifestExpected->set(MANIFEST_SECTION_BACKUP_TARGET, MANIFEST_TARGET_PGDATA . $strConfFile . '.link',
MANIFEST_SUBKEY_PATH, '.');
$oManifestExpected->set(MANIFEST_SECTION_BACKUP_TARGET, MANIFEST_TARGET_PGDATA . $strConfFile . '.link',
MANIFEST_SUBKEY_TYPE, MANIFEST_VALUE_LINK);
# Section target:file
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . $strConfFile,
MANIFEST_SUBKEY_SIZE, length($strConfContent));
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . $strConfFile,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
# Section target:link
$oManifestExpected->set(MANIFEST_SECTION_TARGET_LINK, MANIFEST_TARGET_PGDATA . $strConfFile . '.link',
MANIFEST_SUBKEY_DESTINATION, './postgresql.conf');
# Section target:link:default
$oManifestExpected->set(MANIFEST_SECTION_TARGET_LINK . ":default", MANIFEST_SUBKEY_GROUP, undef, TEST_GROUP);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_LINK . ":default", MANIFEST_SUBKEY_USER, undef, TEST_USER);
$oManifest->build(storageDb(), $self->{strDbPath}, undef, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "", 'link');
# Test skip files/directories
#---------------------------------------------------------------------------------------------------------------------------
# Create files to skip
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_FILE_POSTGRESQLAUTOCONFTMP ), '');
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_FILE_BACKUPLABELOLD), '');
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_FILE_POSTMASTEROPTS), '');
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_FILE_POSTMASTERPID), '');
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_FILE_RECOVERYCONF), '');
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_FILE_RECOVERYDONE), '');
# Create directories to skip. Add a bogus file to them for test coverage.
storageDb()->pathCreate(DB_FILE_PREFIX_TMP);
storageDb()->pathCreate('pg_xlog');
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/pg_xlog/' . BOGUS,
{strMode => MODE_0644, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime}), '');
storageDb()->pathCreate(DB_PATH_PGDYNSHMEM);
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_PATH_PGDYNSHMEM . '/' . BOGUS,
{strMode => MODE_0600, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime}), '');
storageDb()->pathCreate(DB_PATH_PGNOTIFY);
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_PATH_PGNOTIFY . '/' . BOGUS,
{strMode => MODE_0600, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime}), '');
storageDb()->pathCreate(DB_PATH_PGREPLSLOT);
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_PATH_PGREPLSLOT . '/' . BOGUS,
{strMode => MODE_0600, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime}), '');
storageDb()->pathCreate(DB_PATH_PGSERIAL);
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_PATH_PGSERIAL . '/' . BOGUS,
{strMode => MODE_0600, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime}), '');
storageDb()->pathCreate(DB_PATH_PGSNAPSHOTS);
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_PATH_PGSNAPSHOTS . '/' . BOGUS,
{strMode => MODE_0600, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime}), '');
storageDb()->pathCreate(DB_PATH_PGSTATTMP);
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_PATH_PGSTATTMP . '/' . BOGUS,
{strMode => MODE_0600, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime}), '');
storageDb()->pathCreate(DB_PATH_PGSUBTRANS);
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . DB_PATH_PGSUBTRANS . '/' . BOGUS,
{strMode => MODE_0600, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime}), '');
storageDb()->pathCreate(DB_FILE_PGINTERNALINIT);
# Update expected manifest
$oManifestExpected->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_TARGET_PGDATA . '/pg_xlog', undef, $hDefault);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_PATH_PGDYNSHMEM, undef, $hDefault);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_PATH_PGNOTIFY, undef, $hDefault);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_PATH_PGREPLSLOT, undef, $hDefault);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_PATH_PGSERIAL, undef, $hDefault);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_PATH_PGSNAPSHOTS, undef, $hDefault);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_PATH_PGSTATTMP, undef, $hDefault);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_PATH_PGSUBTRANS, undef, $hDefault);
$oManifest->build(storageDb(), $self->{strDbPath}, undef, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "", 'skip directories/files');
# Unskip code path coverage
#---------------------------------------------------------------------------------------------------------------------------
my $oManifestExpectedUnskip = dclone($oManifestExpected);
# Change DB version to 93
$oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_93});
$oManifestExpectedUnskip->set(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_DB_VERSION, undef, PG_VERSION_93);
# Update expected manifest
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_MODE, undef, MODE_0600);
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_GROUP, undef, TEST_GROUP);
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_USER, undef, TEST_USER);
$oManifestExpectedUnskip->boolSet(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_MASTER, undef, true);
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGDYNSHMEM . '/' . BOGUS,
MANIFEST_SUBKEY_SIZE, 0);
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGDYNSHMEM . '/' . BOGUS,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGREPLSLOT . '/' . BOGUS,
MANIFEST_SUBKEY_SIZE, 0);
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGREPLSLOT . '/' . BOGUS,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifest->build(storageDb(), $self->{strDbPath}, undef, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpectedUnskip, $oManifest)}, "", 'unskip 94 directories');
# Change DB version to 91
$oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_91});
$oManifestExpectedUnskip->set(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_DB_VERSION, undef, PG_VERSION_91);
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGSNAPSHOTS . '/' . BOGUS,
MANIFEST_SUBKEY_SIZE, 0);
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGSNAPSHOTS . '/' . BOGUS,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifest->build(storageDb(), $self->{strDbPath}, undef, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpectedUnskip, $oManifest)}, "", 'unskip 92 directories');
# Change DB version to 90
$oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_90});
$oManifestExpectedUnskip->set(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_DB_VERSION, undef, PG_VERSION_90);
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGSERIAL . '/' . BOGUS,
MANIFEST_SUBKEY_SIZE, 0);
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGSERIAL . '/' . BOGUS,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifest->build(storageDb(), $self->{strDbPath}, undef, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpectedUnskip, $oManifest)}, "", 'unskip 91 directories');
# Change DB version to 84
$oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_84});
$oManifestExpectedUnskip->set(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_DB_VERSION, undef, PG_VERSION_84);
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGNOTIFY . '/' . BOGUS,
MANIFEST_SUBKEY_SIZE, 0);
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGNOTIFY . '/' . BOGUS,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifest->build(storageDb(), $self->{strDbPath}, undef, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpectedUnskip, $oManifest)}, "", 'unskip 90 directories');
# Change DB version to 83
$oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_83});
$oManifestExpectedUnskip->set(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_DB_VERSION, undef, PG_VERSION_83);
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGSTATTMP . '/' . BOGUS,
MANIFEST_SUBKEY_SIZE, 0);
$oManifestExpectedUnskip->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGSTATTMP . '/' . BOGUS,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifest->build(storageDb(), $self->{strDbPath}, undef, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpectedUnskip, $oManifest)}, "", 'unskip 84 directories');
# Reset Manifest for next tests
$oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_94});
$oManifest->build(storageDb(), $self->{strDbPath}, undef, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "", 'manifest reset');
# Tablespaces
#---------------------------------------------------------------------------------------------------------------------------
# Create pg_tblspc path
my $strTblSpcPath = $self->{strDbPath} . '/' . DB_PATH_PGTBLSPC;
storageDb()->pathCreate($strTblSpcPath, {bCreateParent => true});
# Create a directory in pg_tblspc
storageDb()->pathCreate("$strTblSpcPath/" . BOGUS, {strMode => '0700'});
$self->testException(sub {$oManifest->build(storageDb(), $self->{strDbPath}, undef, true)}, ERROR_LINK_EXPECTED,
MANIFEST_TARGET_PGTBLSPC . "/" . BOGUS . " is not a symlink - " . DB_PATH_PGTBLSPC . " should contain only symlinks");
testPathRemove("${strTblSpcPath}/" . BOGUS);
my $strTblspcId = '99999';
# Invalid relative tablespace is ../
testLinkCreate("${strTblSpcPath}/${strTblspcId}", '../');
$self->testException(sub {$oManifest->build(storageDb(), $self->{strDbPath}, undef, true)}, ERROR_TABLESPACE_IN_PGDATA,
'tablespace symlink ../ destination must not be in $PGDATA');
testFileRemove("${strTblSpcPath}/${strTblspcId}");
# Invalid relative tablespace is ..
testLinkCreate("${strTblSpcPath}/${strTblspcId}", '..');
$self->testException(sub {$oManifest->build(storageDb(), $self->{strDbPath}, undef, true)}, ERROR_TABLESPACE_IN_PGDATA,
'tablespace symlink .. destination must not be in $PGDATA');
testFileRemove("${strTblSpcPath}/${strTblspcId}");
# Invalid relative tablespace is ../base - a subdirectory of $PGDATA
testLinkCreate("${strTblSpcPath}/${strTblspcId}", '../base');
$self->testException(sub {$oManifest->build(storageDb(), $self->{strDbPath}, undef, true)}, ERROR_TABLESPACE_IN_PGDATA,
'tablespace symlink ../base destination must not be in $PGDATA');
testFileRemove("${strTblSpcPath}/${strTblspcId}");
# Create the catalog key for the tablespace construction
$oManifest->set(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_CATALOG, undef, $iDbCatalogVersion);
# Invalid absolute tablespace is $self->{strDbPath} . /base
# INVESTIGATE: But this should fail because the link points to a directory in pg_data but instead it passes the
# index($hManifest->{$strName}{link_destination}, '/') != 0 and then fails later. It WILL fail "destination must not be in
# $PGDATA" if an ending slash is added - so maybe the comment in Manifest.pm "# Make sure that DB_PATH_PGTBLSPC contains
# only absolute links that do not point inside PGDATA" is not exactly correct?
testLinkCreate("${strTblSpcPath}/${strTblspcId}", $self->{strDbPath} . '/base');
$self->testException(sub {$oManifest->build(storageDb(), $self->{strDbPath}, undef, true)}, ERROR_ASSERT,
"tablespace with oid ${strTblspcId} not found in tablespace map\n" .
"HINT: was a tablespace created or dropped during the backup?");
testFileRemove("${strTblSpcPath}/${strTblspcId}");
# Invalid relative tablespace is ../../BOGUS - which is not in $PGDATA and does not exist
testLinkCreate("${strTblSpcPath}/${strTblspcId}", '../../' . BOGUS);
$self->testException(sub {$oManifest->build(storageDb(), $self->{strDbPath}, undef, true)}, ERROR_ASSERT,
"tablespace with oid ${strTblspcId} not found in tablespace map\n" .
"HINT: was a tablespace created or dropped during the backup?");
testFileRemove("${strTblSpcPath}/${strTblspcId}");
# Create tablespace directory outside PGDATA
my $strTablespace = 'tablespace';
storageTest()->pathCreate($strTablespace);
my $strIntermediateLink = $self->{strDbPath} . "/intermediate_link";
# Create a link to a link
testLinkCreate($strIntermediateLink, $self->testPath() . '/' . $strTablespace);
testLinkCreate("${strTblSpcPath}/${strTblspcId}", $strIntermediateLink);
$self->testException(sub {$oManifest->build(storageDb(), $self->{strDbPath}, undef, false)}, ERROR_LINK_DESTINATION,
"link '${strTblSpcPath}/${strTblspcId}' -> '$strIntermediateLink' cannot reference another link");
testFileRemove($self->{strDbPath} . "/intermediate_link");
testFileRemove("${strTblSpcPath}/${strTblspcId}");
# Reload the manifest otherwise it will contain invalid data from the above exception tests
$oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_94});
# Set the required db catalog version for tablespaces
$oManifest->numericSet(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_CATALOG, undef, $iDbCatalogVersion);
$oManifestExpected->numericSet(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_CATALOG, undef, $iDbCatalogVersion);
# Create a valid symlink pg_tblspc/1 to tablespace/ts1/1 directory
my $strTablespaceOid = '1';
my $strTablespaceName = "ts${strTablespaceOid}";
storageTest()->pathCreate("${strTablespace}/${strTablespaceName}/${strTablespaceOid}", {bCreateParent => true});
my $strTablespacePath = storageTest()->pathGet("${strTablespace}/${strTablespaceName}/${strTablespaceOid}");
testLinkCreate("${strTblSpcPath}/${strTablespaceOid}", $strTablespacePath);
# Create the tablespace info in expected manifest
my $strMfTs = MANIFEST_TARGET_PGTBLSPC . "/" . $strTablespaceOid;
$oManifestExpected->set(MANIFEST_SECTION_BACKUP_TARGET, $strMfTs, MANIFEST_SUBKEY_PATH, $strTablespacePath);
$oManifestExpected->set(MANIFEST_SECTION_BACKUP_TARGET, $strMfTs, MANIFEST_SUBKEY_TABLESPACE_ID, $strTablespaceOid);
$oManifestExpected->set(MANIFEST_SECTION_BACKUP_TARGET, $strMfTs, MANIFEST_SUBKEY_TABLESPACE_NAME, $strTablespaceName);
$oManifestExpected->set(MANIFEST_SECTION_BACKUP_TARGET, $strMfTs, MANIFEST_SUBKEY_TYPE, MANIFEST_VALUE_LINK);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_LINK, MANIFEST_TARGET_PGDATA . "/${strMfTs}", MANIFEST_SUBKEY_DESTINATION,
$strTablespacePath);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_TARGET_PGTBLSPC, undef, $hDefault);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_PATH_PGTBLSPC, undef, $hDefault);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_PATH, $strMfTs, undef, $hDefault);
# In offline mode, do not skip the db WAL path
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_FILE_PGCONTROL, MANIFEST_SUBKEY_MODE, MODE_0644);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/pg_xlog/' . BOGUS,
MANIFEST_SUBKEY_MODE, MODE_0644);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/pg_xlog/' . BOGUS,
MANIFEST_SUBKEY_SIZE, 0);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/pg_xlog/' . BOGUS,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifest->build(storageDb(), $self->{strDbPath}, undef, false);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "",
'offline with valid tablespace - do not skip database WAL directory');
# Create tablespace and database maps
my $hTablespaceMap = {};
$hTablespaceMap->{$strTablespaceOid} = $strTablespaceName;
my $hDatabaseMap = {};
$hDatabaseMap->{&BOGUS}{&MANIFEST_KEY_DB_ID} = 12345;
$hDatabaseMap->{&BOGUS}{&MANIFEST_KEY_DB_LAST_SYSTEM_ID} = 67890;
$oManifestExpected->numericSet(MANIFEST_SECTION_DB, BOGUS, MANIFEST_KEY_DB_ID, $hDatabaseMap->{&BOGUS}{&MANIFEST_KEY_DB_ID});
$oManifestExpected->numericSet(MANIFEST_SECTION_DB, BOGUS, MANIFEST_KEY_DB_LAST_SYSTEM_ID,
$hDatabaseMap->{&BOGUS}{&MANIFEST_KEY_DB_LAST_SYSTEM_ID});
$oManifest->build(storageDb(), $self->{strDbPath}, undef, false, $hTablespaceMap, $hDatabaseMap);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "",
'offline passing tablespace map and database map');
# Reload the manifest with version < 9.0
#---------------------------------------------------------------------------------------------------------------------------
$oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_84});
# Catalog not stored in < 9.0
$oManifestExpected->remove(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_CATALOG);
$oManifestExpected->set(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_DB_VERSION, undef, PG_VERSION_84);
# Add unskip directories
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGDYNSHMEM . '/' . BOGUS,
MANIFEST_SUBKEY_SIZE, 0);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGDYNSHMEM . '/' . BOGUS,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGREPLSLOT . '/' . BOGUS,
MANIFEST_SUBKEY_SIZE, 0);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGREPLSLOT . '/' . BOGUS,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGSNAPSHOTS . '/' . BOGUS,
MANIFEST_SUBKEY_SIZE, 0);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGSNAPSHOTS . '/' . BOGUS,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGSERIAL . '/' . BOGUS,
MANIFEST_SUBKEY_SIZE, 0);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGSERIAL . '/' . BOGUS,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGNOTIFY . '/' . BOGUS,
MANIFEST_SUBKEY_SIZE, 0);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_PATH_PGNOTIFY . '/' . BOGUS,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oManifest->build(storageDb(), $self->{strDbPath}, undef, false, $hTablespaceMap, $hDatabaseMap);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "",
'tablespace with version < 9.0');
# Undefined user/group
#---------------------------------------------------------------------------------------------------------------------------
executeTest("sudo chgrp 777 " . $self->{strDbPath} . '/pg_xlog/' . BOGUS);
executeTest("sudo chown 777 " . $self->{strDbPath} . '/pg_xlog/' . BOGUS);
$oManifestExpected->boolSet(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/pg_xlog/' . BOGUS,
MANIFEST_SUBKEY_GROUP, false);
$oManifestExpected->boolSet(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/pg_xlog/' . BOGUS,
MANIFEST_SUBKEY_USER, false);
$oManifest->build(storageDb(), $self->{strDbPath}, undef, false);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "",
'undefined user/group');
# Reset the group / owner
executeTest("sudo chgrp " . TEST_GROUP . " " . $self->{strDbPath} . '/pg_xlog/' . BOGUS);
executeTest("sudo chown " . TEST_USER . " " . $self->{strDbPath} . '/pg_xlog/' . BOGUS);
}
################################################################################################################################
if ($self->begin('get/set'))
{
my $oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_94});
# SubKey required but has not been set
#---------------------------------------------------------------------------------------------------------------------------
$self->testException(sub {$oManifest->boolGet(MANIFEST_SECTION_TARGET_FILE, BOGUS, MANIFEST_SUBKEY_CHECKSUM_PAGE)},
ERROR_ASSERT, "strSection '" . MANIFEST_SECTION_TARGET_FILE . "', strKey '" . BOGUS . "', strSubKey '" .
MANIFEST_SUBKEY_CHECKSUM_PAGE . "' is required but not defined");
# SubKey not required and not set
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(sub {$oManifest->boolGet(MANIFEST_SECTION_TARGET_FILE, BOGUS, MANIFEST_SUBKEY_CHECKSUM_PAGE, false)},
false, 'boolGet() - false');
# Set and get a boolean value
#---------------------------------------------------------------------------------------------------------------------------
$oManifest->boolSet(MANIFEST_SECTION_TARGET_FILE, BOGUS, MANIFEST_SUBKEY_CHECKSUM_PAGE, true);
$self->testResult(sub {$oManifest->boolGet(MANIFEST_SECTION_TARGET_FILE, BOGUS, MANIFEST_SUBKEY_CHECKSUM_PAGE)}, true,
'boolGet() - true');
# Get default boolean value
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(sub {$oManifest->boolGet(MANIFEST_SECTION_BACKUP_OPTION, MANIFEST_KEY_COMPRESS, undef, false, true)},
true, 'boolGet() - default true');
# Get but don't return a default boolean value even if there is supposed to be one
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(sub {$oManifest->boolGet(MANIFEST_SECTION_BACKUP_OPTION, MANIFEST_KEY_COMPRESS, undef, false, false)},
false, 'boolGet() - default false');
# Get default numeric value
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(sub {$oManifest->numericGet(MANIFEST_SECTION_TARGET_FILE, BOGUS, MANIFEST_SUBKEY_SIZE, false, 0)},
0, 'numericGet() - default 0');
# Coverage for $self->SUPER::get("${strSection}:default"
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(sub {$oManifest->get(MANIFEST_SECTION_TARGET_FILE, BOGUS, MANIFEST_SUBKEY_USER, false)},
"[undef]", 'get() - default section');
# Get the correct path for the control file in the DB
#---------------------------------------------------------------------------------------------------------------------------
$oManifest->set(MANIFEST_SECTION_BACKUP_TARGET, MANIFEST_TARGET_PGDATA, MANIFEST_SUBKEY_PATH, $self->{strDbPath});
$self->testResult(sub {$oManifest->dbPathGet($oManifest->get(MANIFEST_SECTION_BACKUP_TARGET, MANIFEST_TARGET_PGDATA,
MANIFEST_SUBKEY_PATH), MANIFEST_FILE_PGCONTROL)},
$self->{strDbPath} . "/" . DB_FILE_PGCONTROL, 'dbPathGet() - control file');
# Get filename - no path passed
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(sub {$oManifest->dbPathGet(undef, BOGUS)}, BOGUS, 'dbPathGet() - filename');
# repoPathGet - no tablespace
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(sub {$oManifest->repoPathGet(MANIFEST_TARGET_PGDATA, DB_FILE_PGCONTROL)},
MANIFEST_TARGET_PGDATA . "/" . DB_FILE_PGCONTROL, 'repoPathGet() - pg_control');
# repoPathGet - tablespace - no subpath
#---------------------------------------------------------------------------------------------------------------------------
my $strTablespaceId = "1";
my $strTablespace = MANIFEST_TARGET_PGTBLSPC . "/" . $strTablespaceId;
my $strTablespaceName = "ts" . $strTablespaceId;
$oManifest->set(MANIFEST_SECTION_BACKUP_TARGET, $strTablespace, MANIFEST_SUBKEY_PATH, $self->{strDbPath} .
"/tablespace/" . $strTablespaceName);
$self->testResult(sub {$oManifest->repoPathGet($strTablespace)}, $strTablespace,
'repoPathGet() - tablespace - no tablepace-id nor subpath');
# repoPathGet - fully qualified tablespace target
#---------------------------------------------------------------------------------------------------------------------------
# Set the catalog for the DB since that is what is expected to be returned
$oManifest->numericSet(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_CATALOG, undef, $iDbCatalogVersion);
$self->testResult(sub {$oManifest->tablespacePathGet()}, "PG_" . PG_VERSION_94 . "_" . $iDbCatalogVersion,
'tablespacePathGet()');
$oManifest->set(MANIFEST_SECTION_BACKUP_TARGET, $strTablespace, MANIFEST_SUBKEY_TABLESPACE_ID, $strTablespaceId);
$oManifest->set(MANIFEST_SECTION_BACKUP_TARGET, $strTablespace, MANIFEST_SUBKEY_TABLESPACE_NAME, $strTablespaceName);
$oManifest->set(MANIFEST_SECTION_BACKUP_TARGET, $strTablespace, MANIFEST_SUBKEY_TYPE, MANIFEST_VALUE_LINK);
$self->testResult(sub {$oManifest->repoPathGet($strTablespace, BOGUS)}, $strTablespace . "/PG_" . PG_VERSION_94 . "_" .
$iDbCatalogVersion . "/" . BOGUS, 'repoPathGet() - tablespace valid with subpath');
# Set the DB version to < 9.0 - there is no special sudirectory in earlier PG versions
$oManifest->set(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_DB_VERSION, undef, PG_VERSION_84);
$self->testResult(sub {$oManifest->repoPathGet($strTablespace, BOGUS)}, $strTablespace . "/" . BOGUS,
'repoPathGet() - tablespace in 8.4 valid with subpath');
$oManifest->set(MANIFEST_SECTION_BACKUP_DB, MANIFEST_KEY_DB_VERSION, undef, PG_VERSION_94);
# isTargetLink
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(sub {$oManifest->isTargetLink(MANIFEST_TARGET_PGDATA)}, false, "isTargetLink - false");
$self->testResult(sub {$oManifest->isTargetLink($strTablespace)}, true, "isTargetLink - true");
# isTargetLink
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(sub {$oManifest->isTargetFile(MANIFEST_TARGET_PGDATA)}, false, "isTargetFile - false");
$oManifest->set(MANIFEST_SECTION_BACKUP_TARGET, MANIFEST_TARGET_PGDATA, MANIFEST_SUBKEY_FILE, BOGUS);
$self->testResult(sub {$oManifest->isTargetFile(MANIFEST_TARGET_PGDATA)}, true, "isTargetFile - true");
}
################################################################################################################################
if ($self->begin('isTarget - exceptions'))
{
my $oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_94});
# Target not defined
#---------------------------------------------------------------------------------------------------------------------------
$self->testException(sub {$oManifest->isTargetValid()}, ERROR_ASSERT, 'target is not defined');
$self->testException(sub {$oManifest->isTargetFile()}, ERROR_ASSERT, 'target is not defined');
$self->testException(sub {$oManifest->isTargetLink()}, ERROR_ASSERT, 'target is not defined');
$self->testException(sub {$oManifest->isTargetTablespace()}, ERROR_ASSERT, 'target is not defined');
# Target not valid
#---------------------------------------------------------------------------------------------------------------------------
$self->testException(sub {$oManifest->isTargetValid(BOGUS, true)}, ERROR_ASSERT, BOGUS . ' is not a valid target');
$self->testResult(sub {$oManifest->isTargetValid(BOGUS, false)}, false, 'isTargetValid - bError = false, return false');
$self->testResult(sub {$oManifest->isTargetValid(BOGUS)}, false, 'isTargetValid - bError = undef, false');
}
################################################################################################################################
if ($self->begin('dbVerion(), xactPath(), walPath()'))
{
# dbVersion, xactPath and walPath - PG < 10
#---------------------------------------------------------------------------------------------------------------------------
my $oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_94});
$self->testResult(sub {$oManifest->dbVersion()}, PG_VERSION_94, 'dbVersion < 10');
$self->testResult(sub {$oManifest->xactPath()}, 'pg_clog', ' xactPath - pg_clog');
$self->testResult(sub {$oManifest->walPath()}, 'pg_xlog', ' walPath - pg_xlog');
# dbVersion, xactPath and walPath - PG >= 10
#---------------------------------------------------------------------------------------------------------------------------
$oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_10});
$self->testResult(sub {$oManifest->dbVersion()}, PG_VERSION_10, 'dbVersion >= 10');
$self->testResult(sub {$oManifest->xactPath()}, 'pg_xact', ' xactPath - pg_xact');
$self->testResult(sub {$oManifest->walPath()}, 'pg_wal', ' walPath - pg_wal');
}
################################################################################################################################
if ($self->begin('validate()'))
{
my $oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_94});
# Set a target:file with only a timestamp - fail size not set
#---------------------------------------------------------------------------------------------------------------------------
$oManifest->numericSet(MANIFEST_SECTION_TARGET_FILE, BOGUS, MANIFEST_SUBKEY_TIMESTAMP, 1509384645);
$self->testException(sub {$oManifest->validate()}, ERROR_ASSERT,
"manifest subvalue 'size' not set for file '" . BOGUS . "'");
# Set target:file size - fail checksum not set
#---------------------------------------------------------------------------------------------------------------------------
$oManifest->numericSet(MANIFEST_SECTION_TARGET_FILE, BOGUS, MANIFEST_SUBKEY_SIZE, 1);
$self->testException(sub {$oManifest->validate()}, ERROR_ASSERT,
"manifest subvalue 'checksum' not set for file '" . BOGUS . "'");
# Set target:file checksum - validate passes when size > 0 and checksum set
#---------------------------------------------------------------------------------------------------------------------------
$oManifest->numericSet(MANIFEST_SECTION_TARGET_FILE, BOGUS, MANIFEST_SUBKEY_CHECKSUM, 0);
$self->testResult(sub {$oManifest->validate()}, "[undef]", 'manifest validated - size 1, checksum 0');
# Set target:file size to 0 - validate passes when size 0
#---------------------------------------------------------------------------------------------------------------------------
$oManifest->numericSet(MANIFEST_SECTION_TARGET_FILE, BOGUS, MANIFEST_SUBKEY_SIZE, 0);
$self->testResult(sub {$oManifest->validate()}, "[undef]", 'manifest validated - size 0');
}
################################################################################################################################
if ($self->begin('future file and last manifest'))
{
my $oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_94});
# Create expected manifest from base
my $oManifestExpected = dclone($oManifestBase);
# Future timestamp on file
#---------------------------------------------------------------------------------------------------------------------------
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . $strTest,
{strMode => MODE_0600, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime + 20000}), $strTest);
# Update expected manifest
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_MODE, undef, MODE_0600);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_GROUP, undef, TEST_GROUP);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_USER, undef, TEST_USER);
$oManifestExpected->boolSet(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_MASTER, undef, true);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTest, MANIFEST_SUBKEY_SIZE,
length($strTest));
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTest, MANIFEST_SUBKEY_TIMESTAMP,
$lTime + 20000);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTest, MANIFEST_SUBKEY_FUTURE, 'y');
$self->testResult(sub {$oManifest->build(storageDb(), $self->{strDbPath}, undef, true)}, "[undef]",
'future timestamp warning', {strLogExpect =>
"WARN: some files have timestamps in the future - they will be copied to prevent possible race conditions"});
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "", 'manifest future subkey=y');
# Future timestamp in last manifest
#---------------------------------------------------------------------------------------------------------------------------
my $oLastManifest = dclone($oManifestExpected);
# Set a backup label
$oLastManifest->set(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_LABEL, undef, BOGUS);
$oManifestExpected->set(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_PRIOR, undef, BOGUS);
# Remove the file and recreate it without it being in the future
storageTest()->remove($self->{strDbPath} . '/' . $strTest);
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . $strTest,
{strMode => MODE_0600, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime}), $strTest);
# Remove the future subkey from the expected manifest and reset the timestamp
$oManifestExpected->remove(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTest, MANIFEST_SUBKEY_FUTURE);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTest, MANIFEST_SUBKEY_TIMESTAMP,
$lTime);
# Create a new manifest
$oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_94});
$self->testResult(sub {$oManifest->build(storageDb(), $self->{strDbPath}, $oLastManifest, true)}, "[undef]",
'last manifest future timestamp warning', {strLogExpect =>
"WARN: some files have timestamps in the future - they will be copied to prevent possible race conditions"});
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "",
'last manifest future subkey=y, new manifest future subkey removed');
# File info in last manifest same as current
#---------------------------------------------------------------------------------------------------------------------------
$oLastManifest->remove(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTest, MANIFEST_SUBKEY_FUTURE);
$oLastManifest->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTest, MANIFEST_SUBKEY_TIMESTAMP,
$lTime);
# Update reference in expected manifest
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTest, MANIFEST_SUBKEY_REFERENCE,
BOGUS);
# Check reference
$oManifest->build(storageDb(), $self->{strDbPath}, $oLastManifest, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "",
'reference set to prior backup label');
# Create a new file reference
my $strTestNew = $strTest . 'new';
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . $strTestNew,
{strMode => MODE_0600, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTime}), $strTestNew);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_SIZE, length($strTestNew));
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
$oLastManifest->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_SIZE, length($strTestNew));
$oLastManifest->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_TIMESTAMP, $lTime);
# Set a reference, checksum, repo size, master and page checksum in the last manifest
my $strCheckSum = '1234567890';
my $lRepoSize = 10000;
$oLastManifest->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_REFERENCE, BOGUS . BOGUS);
$oLastManifest->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_CHECKSUM, $strCheckSum);
$oLastManifest->numericSet(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_REPO_SIZE, $lRepoSize);
$oLastManifest->boolSet(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_MASTER, false);
$oLastManifest->boolSet(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_CHECKSUM_PAGE, true);
# Update expected manifest
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_REFERENCE, BOGUS . BOGUS);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_CHECKSUM, $strCheckSum);
$oManifestExpected->numericSet(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_REPO_SIZE, $lRepoSize);
$oManifestExpected->boolSet(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_CHECKSUM_PAGE, true);
# Default "master" is flipping because it's not something we read from disk
$oManifestExpected->boolSet(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_MASTER, undef, false);
$oManifestExpected->boolSet(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTest,
MANIFEST_SUBKEY_MASTER, true);
$oManifest->build(storageDb(), $self->{strDbPath}, $oLastManifest, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "", 'updates from last manifest');
# MANIFEST_SUBKEY_CHECKSUM_PAGE = false and MANIFEST_SUBKEY_CHECKSUM_PAGE_ERROR set/not set
#---------------------------------------------------------------------------------------------------------------------------
$oLastManifest->boolSet(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_CHECKSUM_PAGE, false);
$oManifestExpected->boolSet(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_CHECKSUM_PAGE, false);
$oManifest->build(storageDb(), $self->{strDbPath}, $oLastManifest, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "",
'checksum-page false, checksum-page-error not set');
my @iyChecksumPageError = (1);
$oLastManifest->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_CHECKSUM_PAGE_ERROR, \@iyChecksumPageError);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, MANIFEST_TARGET_PGDATA . '/' . $strTestNew,
MANIFEST_SUBKEY_CHECKSUM_PAGE_ERROR, \@iyChecksumPageError);
$oManifest->build(storageDb(), $self->{strDbPath}, $oLastManifest, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "",
'checksum-page false, checksum-page-error set');
}
################################################################################################################################
if ($self->begin('fileAdd()'))
{
my $oManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_94});
my $oManifestExpected = dclone($oManifestBase);
$oManifest->build(storageDb(), $self->{strDbPath}, undef, true);
# Add a file after building manifest
my $lTimeTest = $lTime + 10;
storageDb()->put(storageDb()->openWrite($self->{strDbPath} . '/' . $strTest,
{strMode => MODE_0644, strUser => TEST_USER, strGroup => TEST_GROUP, lTimestamp => $lTimeTest}), $strTest);
$oManifest->fileAdd($strTest, $lTimeTest, 0, 0, true);
# Update expected manifest
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_MODE, MODE_0600);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_USER, TEST_USER);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_GROUP, TEST_GROUP);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_TIMESTAMP, $lTimeTest);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_SIZE, 0);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_CHECKSUM, 0);
$oManifestExpected->boolSet(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_MASTER, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "", 'file added to manifest');
# Remove the file user, mode and group from the actual and expected manifest
$oManifestExpected->remove(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_MODE);
$oManifestExpected->remove(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_USER);
$oManifestExpected->remove(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_GROUP);
$oManifest->remove(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_MODE);
$oManifest->remove(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_USER);
$oManifest->remove(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_GROUP);
# Add a target:file:default section to the manifests with a mode other than 0600
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_MODE, undef, MODE_0750);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_GROUP, undef, TEST_GROUP);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_USER, undef, TEST_USER);
$oManifest->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_MODE, undef, MODE_0750);
$oManifest->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_GROUP, undef, TEST_GROUP);
$oManifest->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_USER, undef, TEST_USER);
# Set the expected mode to 0600
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_MODE, MODE_0600);
$oManifest->fileAdd($strTest, $lTimeTest, 0, 0, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "",
'file added to manifest - file:default values set');
# Remove the file mode from the manifests and change the default so it need not be set for the file
$oManifest->remove(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_MODE);
$oManifest->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_MODE, undef, MODE_0600);
$oManifestExpected->remove(MANIFEST_SECTION_TARGET_FILE, $strTest, MANIFEST_SUBKEY_MODE);
$oManifestExpected->set(MANIFEST_SECTION_TARGET_FILE . ":default", MANIFEST_SUBKEY_MODE, undef, MODE_0600);
$oManifest->fileAdd($strTest, $lTimeTest, 0, 0, true);
$self->testResult(sub {$self->manifestCompare($oManifestExpected, $oManifest)}, "",
'file added to manifest - default mode set 0600');
}
################################################################################################################################
if ($self->begin('isChecksumPage()'))
{
my $strFile = BOGUS;
$self->testResult(sub {isChecksumPage($strFile)}, false, "file '${strFile}' isChecksumPage=false");
$strFile = MANIFEST_TARGET_PGDATA . '/' . DB_PATH_BASE . '/' . DB_FILE_PGVERSION;
$self->testResult(sub {isChecksumPage($strFile)}, false,
"file '${strFile}' isChecksumPage=false");
$strFile = MANIFEST_TARGET_PGDATA . '/' . DB_PATH_BASE . '/' . DB_FILE_PGINTERNALINIT;
$self->testResult(sub {isChecksumPage($strFile)}, false,
"file '${strFile}' isChecksumPage=false");
$strFile = MANIFEST_TARGET_PGDATA . '/' . DB_PATH_BASE. '/' . DB_FILE_PGFILENODEMAP;
$self->testResult(sub {isChecksumPage($strFile)}, false,
"file '${strFile}' isChecksumPage=false");
$strFile = MANIFEST_TARGET_PGTBLSPC . '/' . DB_FILE_PGFILENODEMAP;
$self->testResult(sub {isChecksumPage($strFile)}, false,
"file '${strFile}' isChecksumPage=false");
$strFile = MANIFEST_TARGET_PGTBLSPC . '/' . DB_FILE_PGINTERNALINIT;
$self->testResult(sub {isChecksumPage($strFile)}, false,
"file '${strFile}' isChecksumPage=false");
$strFile = MANIFEST_TARGET_PGTBLSPC . '/' . DB_FILE_PGVERSION;
$self->testResult(sub {isChecksumPage($strFile)}, false,
"file '${strFile}' isChecksumPage=false");
$strFile = MANIFEST_TARGET_PGDATA . '/' . DB_PATH_GLOBAL. '/' . DB_FILE_PGFILENODEMAP;
$self->testResult(sub {isChecksumPage($strFile)}, false,
"file '${strFile}' isChecksumPage=false");
$strFile = MANIFEST_TARGET_PGDATA . '/' . DB_PATH_GLOBAL. '/' . DB_FILE_PGINTERNALINIT;
$self->testResult(sub {isChecksumPage($strFile)}, false,
"file '${strFile}' isChecksumPage=false");
$strFile = MANIFEST_TARGET_PGDATA . '/' . DB_PATH_GLOBAL. '/' . DB_FILE_PGVERSION;
$self->testResult(sub {isChecksumPage($strFile)}, false,
"file '${strFile}' isChecksumPage=false");
$strFile = MANIFEST_TARGET_PGDATA . '/' . DB_PATH_GLOBAL. '/' . DB_FILE_PGCONTROL;
$self->testResult(sub {isChecksumPage($strFile)}, false,
"file '${strFile}' isChecksumPage=false");
$strFile = MANIFEST_TARGET_PGDATA . '/' . DB_FILE_PGCONTROL;
$self->testResult(sub {isChecksumPage($strFile)}, false,
"file '${strFile}' isChecksumPage=false");
$strFile = MANIFEST_TARGET_PGDATA . '/' . DB_PATH_BASE . '/' . BOGUS;
$self->testResult(sub {isChecksumPage($strFile)}, true,
"file '${strFile}' isChecksumPage=true");
$strFile = MANIFEST_TARGET_PGDATA . '/' . DB_PATH_GLOBAL . '/' . BOGUS;
$self->testResult(sub {isChecksumPage($strFile)}, true,
"file '${strFile}' isChecksumPage=true");
}
}
1;