diff --git a/doc/xml/release.xml b/doc/xml/release.xml index f520133fa..61c39283d 100644 --- a/doc/xml/release.xml +++ b/doc/xml/release.xml @@ -163,6 +163,20 @@ + + + + + + + + +

Modified the info command (both text and JSON output) to display the archive ID and minimum/maximum WAL currently present in the archive for the current and prior, if any, database cluster version.

+
+
+
+
+

IMPORTANT NOTE: 8.3 and 8.4 installations utilizing tablespaces should upgrade immediately from any 1.XX release and run a full backup. A bug prevented tablespaces from being backed up on these versions only. ≥ 9.0 is not affected.

diff --git a/lib/pgBackRest/Info.pm b/lib/pgBackRest/Info.pm index e767bb211..d219f25f3 100644 --- a/lib/pgBackRest/Info.pm +++ b/lib/pgBackRest/Info.pm @@ -119,16 +119,7 @@ sub process elsif (optionTest(OPTION_OUTPUT, INFO_OUTPUT_JSON)) { my $oJSON = JSON::PP->new()->canonical()->pretty()->indent_length(4); - my $strJSON = $oJSON->encode($oyStanzaList); - - syswrite(*STDOUT, $strJSON); - - # On some systems a linefeed will be appended by encode() but others will not have it. In our case there should always - # be a terminating linefeed. - if ($strJSON !~ /\n$/) - { - syswrite(*STDOUT, "\n"); - } + $self->outputJSON($oJSON->encode($oyStanzaList)); } else { @@ -143,6 +134,35 @@ sub process ); } +#################################################################################################################################### +# outputJSON +################################################################################################################################### +sub outputJSON +{ + my $self = shift; + + # Assign function parameters, defaults, and log debug info + my + ( + $strOperation, + $strJSON, + ) = + logDebugParam + ( + __PACKAGE__ . '->outputJSON', \@_, + {name => 'strJSON'}, + ); + + syswrite(*STDOUT, $strJSON); + + # On some systems a linefeed will be appended by encode() but others will not have it. In our case there should always + # be a terminating linefeed. + if ($strJSON !~ /\n$/) + { + syswrite(*STDOUT, "\n"); + } +} + #################################################################################################################################### # formatText # @@ -171,10 +191,44 @@ sub formatText # Output stanza name and status $strOutput .= (defined($strOutput) ? "\n" : '') . $self->formatTextStanza($oStanzaInfo) . "\n"; - # Output information for each stanza backup, from oldest to newest - foreach my $oBackupInfo (@{$$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP}}) + # Initialize the flag to indicate the first DB in the INFO_BACKUP_SECTION_DB is the current database + my $bDbCurrent = true; + + # Loop through the DB history array for the stanza from newest to oldest + foreach my $hDbInfo (reverse @{$oStanzaInfo->{&INFO_BACKUP_SECTION_DB}}) { - $strOutput .= "\n" . $self->formatTextBackup($oBackupInfo) . "\n"; + $strOutput .= $bDbCurrent ? "\n db (current)" : "\n db (prior)"; + $bDbCurrent = false; + + # Get the archive information for the DB + foreach my $hDbArchive (@{$oStanzaInfo->{&INFO_SECTION_ARCHIVE}}) + { + if ($hDbArchive->{&INFO_SECTION_DB}{&INFO_HISTORY_ID} == $hDbInfo->{&INFO_HISTORY_ID}) + { + # Output archive start / stop values + $strOutput .= "\n wal archive min/max (" . $hDbArchive->{&INFO_KEY_ID} . "): "; + + if (defined($hDbArchive->{&INFO_KEY_MIN})) + { + $strOutput .= $hDbArchive->{&INFO_KEY_MIN} . ' / ' . $hDbArchive->{&INFO_KEY_MAX}; + } + else + { + $strOutput .= 'none present'; + } + + $strOutput .= "\n"; + } + } + + # Get information for each stanza backup for the DB, from oldest to newest + foreach my $oBackupInfo (@{$$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP}}) + { + if ($oBackupInfo->{&INFO_SECTION_DB}{&INFO_KEY_ID} == $hDbInfo->{&INFO_HISTORY_ID}) + { + $strOutput .= "\n" . $self->formatTextBackup($oBackupInfo) . "\n"; + } + } } } @@ -213,21 +267,6 @@ sub formatTextStanza " status: " . ($oStanzaInfo->{&INFO_SECTION_STATUS}{&INFO_KEY_CODE} == 0 ? INFO_STANZA_STATUS_OK : INFO_STANZA_STATUS_ERROR . ' (' . $oStanzaInfo->{&INFO_SECTION_STATUS}{&INFO_KEY_MESSAGE} . ')'); - # Output archive start / stop values - $strOutput .= - "\n wal archive min/max: "; - - if (defined($oStanzaInfo->{&INFO_SECTION_ARCHIVE}{&INFO_KEY_MIN}) && - defined($oStanzaInfo->{&INFO_SECTION_ARCHIVE}{&INFO_KEY_MAX})) - { - $strOutput .= - $oStanzaInfo->{&INFO_SECTION_ARCHIVE}{&INFO_KEY_MIN} . ' / ' . $oStanzaInfo->{&INFO_SECTION_ARCHIVE}{&INFO_KEY_MAX}; - } - else - { - $strOutput .= 'none present'; - } - # Return from function and log return values if any return logDebugReturn ( @@ -258,14 +297,14 @@ sub formatTextBackup ); my $strOutput = - ' ' . $$oBackupInfo{&INFO_KEY_TYPE} . ' backup: ' . $$oBackupInfo{&INFO_KEY_LABEL} . "\n" . + ' ' . $$oBackupInfo{&INFO_KEY_TYPE} . ' backup: ' . $$oBackupInfo{&INFO_KEY_LABEL} . "\n" . - ' timestamp start/stop: ' . + ' timestamp start/stop: ' . timestampFormat(undef, $$oBackupInfo{&INFO_SECTION_TIMESTAMP}{&INFO_KEY_START}) . ' / ' . timestampFormat(undef, $$oBackupInfo{&INFO_SECTION_TIMESTAMP}{&INFO_KEY_STOP}) . "\n" . - " wal start/stop: "; + " wal start/stop: "; if (defined($oBackupInfo->{&INFO_SECTION_ARCHIVE}{&INFO_KEY_START}) && defined($oBackupInfo->{&INFO_SECTION_ARCHIVE}{&INFO_KEY_STOP})) @@ -279,14 +318,14 @@ sub formatTextBackup } $strOutput .= - "\n database size: " . + "\n database size: " . (defined($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_KEY_SIZE}) ? fileSizeFormat($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_KEY_SIZE}) : '') . ', backup size: ' . (defined($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_KEY_DELTA}) ? fileSizeFormat($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_KEY_DELTA}) : '') . "\n" . - ' repository size: ' . + ' repository size: ' . (defined($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_SECTION_REPO}{&INFO_KEY_SIZE}) ? fileSizeFormat($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_SECTION_REPO}{&INFO_KEY_SIZE}) : '') . ', repository backup size: ' . @@ -296,7 +335,7 @@ sub formatTextBackup # List the backup reference chain, if any, for this backup if (defined($oBackupInfo->{&INFO_KEY_REFERENCE}) && @{$oBackupInfo->{&INFO_KEY_REFERENCE}} > 0) { - $strOutput .= "\n backup reference list: " . (join(', ', @{$$oBackupInfo{&INFO_KEY_REFERENCE}})); + $strOutput .= "\n backup reference list: " . (join(', ', @{$$oBackupInfo{&INFO_KEY_REFERENCE}})); } # Return from function and log return values if any @@ -369,16 +408,17 @@ sub stanzaList }; } - # Get the first/last WAL - my $strArchiveStart; - my $strArchiveStop; + # Array to store tne min/max archive for each database for which there are archives + my @oyDbArchiveList = (); + + # Get the current DB info (always last element in the array) + my $hDbCurrent = @{$oStanzaInfo->{&INFO_BACKUP_SECTION_DB}}[-1]; + my $strDbCurrentVersion = $hDbCurrent->{&INFO_KEY_VERSION}; + my $ullDbCurrentSystemId = $hDbCurrent->{&INFO_KEY_SYSTEM_ID}; # Loop through the DB history from oldest to newest foreach my $hDbInfo (@{$oStanzaInfo->{&INFO_BACKUP_SECTION_DB}}) { - $strArchiveStart = undef; - $strArchiveStop = undef; - my $strArchiveStanzaPath = "archive/" . $strStanzaFound; my $strDbVersion = $hDbInfo->{&INFO_KEY_VERSION}; my $ullDbSysId = $hDbInfo->{&INFO_KEY_SYSTEM_ID}; @@ -390,46 +430,17 @@ sub stanzaList ullDbSysId => $hDbInfo->{&INFO_KEY_SYSTEM_ID}}); my $strArchivePath = "archive/${strStanzaFound}/${strArchiveId}"; - if (storageRepo()->pathExists($strArchivePath)) + # Fill in the archive info if available + my $hDbArchive = $self->dbArchiveSection($hDbInfo, $strArchiveId, $strArchivePath, $strDbCurrentVersion, + $ullDbCurrentSystemId); + if (defined($hDbArchive)) { - my @stryWalMajor = storageRepo()->list($strArchivePath, {strExpression => '^[0-F]{16}$'}); - - # Get first WAL segment - foreach my $strWalMajor (@stryWalMajor) - { - my @stryWalFile = storageRepo()->list( - "${strArchivePath}/${strWalMajor}", - {strExpression => "^[0-F]{24}-[0-f]{40}(\\." . COMPRESS_EXT . "){0,1}\$"}); - - if (@stryWalFile > 0) - { - $strArchiveStart = substr($stryWalFile[0], 0, 24); - last; - } - } - - # Get last WAL segment - foreach my $strWalMajor (sort({$b cmp $a} @stryWalMajor)) - { - my @stryWalFile = storageRepo()->list( - "${strArchivePath}/${strWalMajor}", - {strExpression => "^[0-F]{24}-[0-f]{40}(\\." . COMPRESS_EXT . "){0,1}\$", strSortOrder => 'reverse'}); - - if (@stryWalFile > 0) - { - $strArchiveStop = substr($stryWalFile[0], 0, 24); - last; - } - } + push(@oyDbArchiveList, $hDbArchive); } } - # Store only the last (current) database's archive min/max - $oStanzaInfo->{&INFO_SECTION_ARCHIVE} = - { - &INFO_KEY_MIN => $strArchiveStart, - &INFO_KEY_MAX => $strArchiveStop, - }; + # Store the archive min/max for each database in the archive section + $oStanzaInfo->{&INFO_SECTION_ARCHIVE} = \@oyDbArchiveList; push @oyStanzaList, $oStanzaInfo; } @@ -572,4 +583,92 @@ sub backupList ); } +#################################################################################################################################### +# dbArchiveSection - fills the archive section for a db. Note this is a function in order to aid unit test coverage. +#################################################################################################################################### +sub dbArchiveSection +{ + my $self = shift; + + # Assign function parameters, defaults, and log debug info + my + ( + $strOperation, + $hDbInfo, + $strArchiveId, + $strArchivePath, + $strDbCurrentVersion, + $ullDbCurrentSystemId, + ) = + logDebugParam + ( + __PACKAGE__ . '->dbArchiveSection', \@_, + {name => 'hDbInfo'}, + {name => 'strArchiveId'}, + {name => 'strArchivePath'}, + {name => 'strDbCurrentVersion'}, + {name => 'ullDbCurrentSystemId'}, + ); + + my $hDbArchive = undef; + my $strArchiveStart = undef; + my $strArchiveStop = undef; + + if (storageRepo()->pathExists($strArchivePath)) + { + my @stryWalMajor = storageRepo()->list($strArchivePath, {strExpression => '^[0-F]{16}$'}); + + # Get first WAL segment + foreach my $strWalMajor (@stryWalMajor) + { + my @stryWalFile = storageRepo()->list( + "${strArchivePath}/${strWalMajor}", + {strExpression => "^[0-F]{24}-[0-f]{40}(\\." . COMPRESS_EXT . "){0,1}\$"}); + + if (@stryWalFile > 0) + { + $strArchiveStart = substr($stryWalFile[0], 0, 24); + last; + } + } + + # Get last WAL segment + foreach my $strWalMajor (sort({$b cmp $a} @stryWalMajor)) + { + my @stryWalFile = storageRepo()->list( + "${strArchivePath}/${strWalMajor}", + {strExpression => "^[0-F]{24}-[0-f]{40}(\\." . COMPRESS_EXT . "){0,1}\$", strSortOrder => 'reverse'}); + + if (@stryWalFile > 0) + { + $strArchiveStop = substr($stryWalFile[0], 0, 24); + last; + } + } + } + + # If there is an archive or the database is the current database then store it + if (($strDbCurrentVersion eq $hDbInfo->{&INFO_KEY_VERSION} && + $ullDbCurrentSystemId == $hDbInfo->{&INFO_KEY_SYSTEM_ID}) || + defined($strArchiveStart) ) + { + $hDbArchive = + { + &INFO_KEY_ID => $strArchiveId, + &INFO_KEY_MIN => $strArchiveStart, + &INFO_KEY_MAX => $strArchiveStop, + &INFO_SECTION_DB => + { + &INFO_HISTORY_ID => $hDbInfo->{&INFO_HISTORY_ID}, + }, + }; + } + # Return from function and log return values if any + return logDebugReturn + ( + $strOperation, + {name => 'hDbArchive', value => $hDbArchive, trace => true}, + ); +} + 1; diff --git a/lib/pgBackRest/Version.pm b/lib/pgBackRest/Version.pm index ec0d9f672..85bd08a8b 100644 --- a/lib/pgBackRest/Version.pm +++ b/lib/pgBackRest/Version.pm @@ -35,7 +35,7 @@ use constant BACKREST_BIN => abs_path( # Defines the current version of the BackRest executable. The version number is used to track features but does not affect what # repositories or manifests can be read - that's the job of the format number. #----------------------------------------------------------------------------------------------------------------------------------- -use constant BACKREST_VERSION => '1.20'; +use constant BACKREST_VERSION => '1.21dev'; push @EXPORT, qw(BACKREST_VERSION); # Format Format Number diff --git a/libc/lib/pgBackRest/LibC.pm b/libc/lib/pgBackRest/LibC.pm index 843d49d5d..e5e30a625 100644 --- a/libc/lib/pgBackRest/LibC.pm +++ b/libc/lib/pgBackRest/LibC.pm @@ -11,7 +11,7 @@ use AutoLoader; our @ISA = qw(Exporter); # Library version (add .999 during development) -our $VERSION = '1.20'; +our $VERSION = '1.21.999'; sub libCVersion {return $VERSION}; diff --git a/test/expect/mock-all-001.log b/test/expect/mock-all-001.log index 9cf2795ef..b16082a1f 100644 --- a/test/expect/mock-all-001.log +++ b/test/expect/mock-all-001.log @@ -3614,71 +3614,79 @@ info db stanza - normal output (db-master host) ------------------------------------------------------------------------------------------------------------------------------------ stanza: db status: ok - wal archive min/max: none present - full backup: [BACKUP-FULL-2] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 160KB, backup size: 160KB - repository size: 160KB, repository backup size: 160KB + db (current) + wal archive min/max (9.4-1): none present - diff backup: [BACKUP-DIFF-2] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 160KB, backup size: 29B - repository size: 160KB, repository backup size: 29B - backup reference list: [BACKUP-FULL-2] + full backup: [BACKUP-FULL-2] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 160KB, backup size: 160KB + repository size: 160KB, repository backup size: 160KB - incr backup: [BACKUP-INCR-3] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 160KB, backup size: 13B - repository size: 160KB, repository backup size: 13B - backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-2] + diff backup: [BACKUP-DIFF-2] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 160KB, backup size: 29B + repository size: 160KB, repository backup size: 29B + backup reference list: [BACKUP-FULL-2] - incr backup: [BACKUP-INCR-4] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 8B - repository size: 144KB, repository backup size: 8B - backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-2], [BACKUP-INCR-3] + incr backup: [BACKUP-INCR-3] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 160KB, backup size: 13B + repository size: 160KB, repository backup size: 13B + backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-2] - diff backup: [BACKUP-DIFF-3] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 43B - repository size: 144KB, repository backup size: 43B - backup reference list: [BACKUP-FULL-2] + incr backup: [BACKUP-INCR-4] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 8B + repository size: 144KB, repository backup size: 8B + backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-2], [BACKUP-INCR-3] - incr backup: [BACKUP-INCR-5] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 0B - repository size: 144KB, repository backup size: 0B - backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-3] + diff backup: [BACKUP-DIFF-3] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 43B + repository size: 144KB, repository backup size: 43B + backup reference list: [BACKUP-FULL-2] - diff backup: [BACKUP-DIFF-4] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 34B - repository size: 144KB, repository backup size: 34B - backup reference list: [BACKUP-FULL-2] + incr backup: [BACKUP-INCR-5] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 0B + repository size: 144KB, repository backup size: 0B + backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-3] - full backup: [BACKUP-FULL-3] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 144KB - repository size: 1.4KB, repository backup size: 1.4KB + diff backup: [BACKUP-DIFF-4] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 34B + repository size: 144KB, repository backup size: 34B + backup reference list: [BACKUP-FULL-2] + + full backup: [BACKUP-FULL-3] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 144KB + repository size: 1.4KB, repository backup size: 1.4KB info db stanza - normal output (db-master host) > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --stanza=db --output=json info ------------------------------------------------------------------------------------------------------------------------------------ [ { - "archive" : { - "max" : null, - "min" : null - }, + "archive" : [ + { + "database" : { + "id" : "1" + }, + "id" : "9.4-1", + "max" : null, + "min" : null + } + ], "backup" : [ { "archive" : { @@ -4267,34 +4275,41 @@ info all stanzas - normal output (db-master host) ------------------------------------------------------------------------------------------------------------------------------------ stanza: db status: ok - wal archive min/max: none present - full backup: [BACKUP-FULL-3] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 144KB - repository size: 1.4KB, repository backup size: 1.4KB + db (current) + wal archive min/max (9.4-1): none present - diff backup: [BACKUP-DIFF-5] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 9B - repository size: 1.5KB, repository backup size: 29B - backup reference list: [BACKUP-FULL-3] + full backup: [BACKUP-FULL-3] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 144KB + repository size: 1.4KB, repository backup size: 1.4KB + + diff backup: [BACKUP-DIFF-5] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 9B + repository size: 1.5KB, repository backup size: 29B + backup reference list: [BACKUP-FULL-3] stanza: db_empty status: error (no valid backups) - wal archive min/max: none present info all stanzas - normal output (db-master host) > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --output=json info ------------------------------------------------------------------------------------------------------------------------------------ [ { - "archive" : { - "max" : null, - "min" : null - }, + "archive" : [ + { + "database" : { + "id" : "1" + }, + "id" : "9.4-1", + "max" : null, + "min" : null + } + ], "backup" : [ { "archive" : { @@ -4371,10 +4386,7 @@ info all stanzas - normal output (db-master host) } }, { - "archive" : { - "max" : null, - "min" : null - }, + "archive" : [], "backup" : [], "db" : [], "name" : "db_empty", @@ -4390,7 +4402,6 @@ info bogus stanza - bogus stanza (db-master host) ------------------------------------------------------------------------------------------------------------------------------------ stanza: bogus status: error (missing stanza path) - wal archive min/max: none present info bogus stanza - bogus stanza (db-master host) > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --stanza=bogus --output=json info diff --git a/test/expect/mock-all-002.log b/test/expect/mock-all-002.log index 8a8c96d9b..18aeee018 100644 --- a/test/expect/mock-all-002.log +++ b/test/expect/mock-all-002.log @@ -3860,71 +3860,79 @@ info db stanza - normal output (db-master host) ------------------------------------------------------------------------------------------------------------------------------------ stanza: db status: ok - wal archive min/max: none present - full backup: [BACKUP-FULL-2] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 160KB, backup size: 160KB - repository size: 160KB, repository backup size: 160KB + db (current) + wal archive min/max (9.4-1): none present - diff backup: [BACKUP-DIFF-2] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 160KB, backup size: 29B - repository size: 160KB, repository backup size: 29B - backup reference list: [BACKUP-FULL-2] + full backup: [BACKUP-FULL-2] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 160KB, backup size: 160KB + repository size: 160KB, repository backup size: 160KB - incr backup: [BACKUP-INCR-3] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 160KB, backup size: 13B - repository size: 160KB, repository backup size: 13B - backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-2] + diff backup: [BACKUP-DIFF-2] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 160KB, backup size: 29B + repository size: 160KB, repository backup size: 29B + backup reference list: [BACKUP-FULL-2] - incr backup: [BACKUP-INCR-4] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 8B - repository size: 144KB, repository backup size: 8B - backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-2], [BACKUP-INCR-3] + incr backup: [BACKUP-INCR-3] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 160KB, backup size: 13B + repository size: 160KB, repository backup size: 13B + backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-2] - diff backup: [BACKUP-DIFF-3] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 43B - repository size: 144KB, repository backup size: 43B - backup reference list: [BACKUP-FULL-2] + incr backup: [BACKUP-INCR-4] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 8B + repository size: 144KB, repository backup size: 8B + backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-2], [BACKUP-INCR-3] - incr backup: [BACKUP-INCR-5] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 0B - repository size: 144KB, repository backup size: 0B - backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-3] + diff backup: [BACKUP-DIFF-3] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 43B + repository size: 144KB, repository backup size: 43B + backup reference list: [BACKUP-FULL-2] - diff backup: [BACKUP-DIFF-4] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 34B - repository size: 144KB, repository backup size: 34B - backup reference list: [BACKUP-FULL-2] + incr backup: [BACKUP-INCR-5] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 0B + repository size: 144KB, repository backup size: 0B + backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-3] - full backup: [BACKUP-FULL-3] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 144KB - repository size: 1.4KB, repository backup size: 1.4KB + diff backup: [BACKUP-DIFF-4] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 34B + repository size: 144KB, repository backup size: 34B + backup reference list: [BACKUP-FULL-2] + + full backup: [BACKUP-FULL-3] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 144KB + repository size: 1.4KB, repository backup size: 1.4KB info db stanza - normal output (backup host) > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --log-level-console=warn --stanza=db --output=json info ------------------------------------------------------------------------------------------------------------------------------------ [ { - "archive" : { - "max" : null, - "min" : null - }, + "archive" : [ + { + "database" : { + "id" : "1" + }, + "id" : "9.4-1", + "max" : null, + "min" : null + } + ], "backup" : [ { "archive" : { @@ -4529,34 +4537,41 @@ info all stanzas - normal output (backup host) ------------------------------------------------------------------------------------------------------------------------------------ stanza: db status: ok - wal archive min/max: none present - full backup: [BACKUP-FULL-3] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 144KB - repository size: 1.4KB, repository backup size: 1.4KB + db (current) + wal archive min/max (9.4-1): none present - diff backup: [BACKUP-DIFF-5] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 9B - repository size: 1.5KB, repository backup size: 29B - backup reference list: [BACKUP-FULL-3] + full backup: [BACKUP-FULL-3] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 144KB + repository size: 1.4KB, repository backup size: 1.4KB + + diff backup: [BACKUP-DIFF-5] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 9B + repository size: 1.5KB, repository backup size: 29B + backup reference list: [BACKUP-FULL-3] stanza: db_empty status: error (no valid backups) - wal archive min/max: none present info all stanzas - normal output (db-master host) > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --output=json info ------------------------------------------------------------------------------------------------------------------------------------ [ { - "archive" : { - "max" : null, - "min" : null - }, + "archive" : [ + { + "database" : { + "id" : "1" + }, + "id" : "9.4-1", + "max" : null, + "min" : null + } + ], "backup" : [ { "archive" : { @@ -4633,10 +4648,7 @@ info all stanzas - normal output (db-master host) } }, { - "archive" : { - "max" : null, - "min" : null - }, + "archive" : [], "backup" : [], "db" : [], "name" : "db_empty", @@ -4652,7 +4664,6 @@ info bogus stanza - bogus stanza (backup host) ------------------------------------------------------------------------------------------------------------------------------------ stanza: bogus status: error (missing stanza path) - wal archive min/max: none present info bogus stanza - bogus stanza (db-master host) > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --stanza=bogus --output=json info diff --git a/test/expect/mock-all-003.log b/test/expect/mock-all-003.log index c01d10f02..df44f37a2 100644 --- a/test/expect/mock-all-003.log +++ b/test/expect/mock-all-003.log @@ -2317,71 +2317,79 @@ info db stanza - normal output (db-master host) ------------------------------------------------------------------------------------------------------------------------------------ stanza: db status: ok - wal archive min/max: none present - full backup: [BACKUP-FULL-2] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 160KB, backup size: 160KB - repository size: 160KB, repository backup size: 160KB + db (current) + wal archive min/max (9.4-1): none present - diff backup: [BACKUP-DIFF-2] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 160KB, backup size: 29B - repository size: 160KB, repository backup size: 29B - backup reference list: [BACKUP-FULL-2] + full backup: [BACKUP-FULL-2] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 160KB, backup size: 160KB + repository size: 160KB, repository backup size: 160KB - incr backup: [BACKUP-INCR-3] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 160KB, backup size: 13B - repository size: 160KB, repository backup size: 13B - backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-2] + diff backup: [BACKUP-DIFF-2] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 160KB, backup size: 29B + repository size: 160KB, repository backup size: 29B + backup reference list: [BACKUP-FULL-2] - incr backup: [BACKUP-INCR-4] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 8B - repository size: 144KB, repository backup size: 8B - backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-2], [BACKUP-INCR-3] + incr backup: [BACKUP-INCR-3] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 160KB, backup size: 13B + repository size: 160KB, repository backup size: 13B + backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-2] - diff backup: [BACKUP-DIFF-3] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 43B - repository size: 144KB, repository backup size: 43B - backup reference list: [BACKUP-FULL-2] + incr backup: [BACKUP-INCR-4] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 8B + repository size: 144KB, repository backup size: 8B + backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-2], [BACKUP-INCR-3] - incr backup: [BACKUP-INCR-5] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 0B - repository size: 144KB, repository backup size: 0B - backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-3] + diff backup: [BACKUP-DIFF-3] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 43B + repository size: 144KB, repository backup size: 43B + backup reference list: [BACKUP-FULL-2] - diff backup: [BACKUP-DIFF-4] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 34B - repository size: 144KB, repository backup size: 34B - backup reference list: [BACKUP-FULL-2] + incr backup: [BACKUP-INCR-5] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 0B + repository size: 144KB, repository backup size: 0B + backup reference list: [BACKUP-FULL-2], [BACKUP-DIFF-3] - full backup: [BACKUP-FULL-3] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 144KB - repository size: 1.4KB, repository backup size: 1.4KB + diff backup: [BACKUP-DIFF-4] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 34B + repository size: 144KB, repository backup size: 34B + backup reference list: [BACKUP-FULL-2] + + full backup: [BACKUP-FULL-3] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 144KB + repository size: 1.4KB, repository backup size: 1.4KB info db stanza - normal output (backup host) > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --log-level-console=warn --stanza=db --output=json info ------------------------------------------------------------------------------------------------------------------------------------ [ { - "archive" : { - "max" : null, - "min" : null - }, + "archive" : [ + { + "database" : { + "id" : "1" + }, + "id" : "9.4-1", + "max" : null, + "min" : null + } + ], "backup" : [ { "archive" : { @@ -2875,30 +2883,38 @@ info all stanzas - normal output (backup host) ------------------------------------------------------------------------------------------------------------------------------------ stanza: db status: ok - wal archive min/max: none present - full backup: [BACKUP-FULL-3] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 144KB - repository size: 1.4KB, repository backup size: 1.4KB + db (current) + wal archive min/max (9.4-1): none present - diff backup: [BACKUP-DIFF-5] - timestamp start/stop: [TIMESTAMP-STR] - wal start/stop: n/a - database size: 144KB, backup size: 9B - repository size: 1.5KB, repository backup size: 29B - backup reference list: [BACKUP-FULL-3] + full backup: [BACKUP-FULL-3] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 144KB + repository size: 1.4KB, repository backup size: 1.4KB + + diff backup: [BACKUP-DIFF-5] + timestamp start/stop: [TIMESTAMP-STR] + wal start/stop: n/a + database size: 144KB, backup size: 9B + repository size: 1.5KB, repository backup size: 29B + backup reference list: [BACKUP-FULL-3] info all stanzas - normal output (db-master host) > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --output=json info ------------------------------------------------------------------------------------------------------------------------------------ [ { - "archive" : { - "max" : null, - "min" : null - }, + "archive" : [ + { + "database" : { + "id" : "1" + }, + "id" : "9.4-1", + "max" : null, + "min" : null + } + ], "backup" : [ { "archive" : { @@ -2981,7 +2997,6 @@ info bogus stanza - bogus stanza (backup host) ------------------------------------------------------------------------------------------------------------------------------------ stanza: bogus status: error (missing stanza path) - wal archive min/max: none present info bogus stanza - bogus stanza (db-master host) > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --stanza=bogus --output=json info diff --git a/test/expect/stanza-upgrade-001.log b/test/expect/stanza-upgrade-001.log index 81782c401..973bcfbda 100644 --- a/test/expect/stanza-upgrade-001.log +++ b/test/expect/stanza-upgrade-001.log @@ -396,10 +396,24 @@ info all stanzas - db upgraded - db-1 and db-2 listed (db-master host) ------------------------------------------------------------------------------------------------------------------------------------ [ { - "archive" : { - "max" : "000000010000000100000001", - "min" : "000000010000000100000001" - }, + "archive" : [ + { + "database" : { + "id" : "1" + }, + "id" : "9.4-2", + "max" : "000000010000000100000001", + "min" : "000000010000000100000001" + }, + { + "database" : { + "id" : "2" + }, + "id" : "9.5-4", + "max" : "000000010000000100000001", + "min" : "000000010000000100000001" + } + ], "backup" : [ { "archive" : { diff --git a/test/expect/stanza-upgrade-002.log b/test/expect/stanza-upgrade-002.log index c86b4b32c..639b90b7b 100644 --- a/test/expect/stanza-upgrade-002.log +++ b/test/expect/stanza-upgrade-002.log @@ -440,10 +440,24 @@ info all stanzas - db upgraded - db-1 and db-2 listed (db-master host) ------------------------------------------------------------------------------------------------------------------------------------ [ { - "archive" : { - "max" : "000000010000000100000001", - "min" : "000000010000000100000001" - }, + "archive" : [ + { + "database" : { + "id" : "1" + }, + "id" : "9.4-2", + "max" : "000000010000000100000001", + "min" : "000000010000000100000001" + }, + { + "database" : { + "id" : "2" + }, + "id" : "9.5-4", + "max" : "000000010000000100000001", + "min" : "000000010000000100000001" + } + ], "backup" : [ { "archive" : { diff --git a/test/expect/stanza-upgrade-003.log b/test/expect/stanza-upgrade-003.log index dc05ed2c1..f3cb13f74 100644 --- a/test/expect/stanza-upgrade-003.log +++ b/test/expect/stanza-upgrade-003.log @@ -454,10 +454,24 @@ info all stanzas - db upgraded - db-1 and db-2 listed (db-master host) ------------------------------------------------------------------------------------------------------------------------------------ [ { - "archive" : { - "max" : "000000010000000100000001", - "min" : "000000010000000100000001" - }, + "archive" : [ + { + "database" : { + "id" : "1" + }, + "id" : "9.4-2", + "max" : "000000010000000100000001", + "min" : "000000010000000100000001" + }, + { + "database" : { + "id" : "2" + }, + "id" : "9.5-4", + "max" : "000000010000000100000001", + "min" : "000000010000000100000001" + } + ], "backup" : [ { "archive" : { diff --git a/test/lib/pgBackRestTest/Common/DefineTest.pm b/test/lib/pgBackRestTest/Common/DefineTest.pm index 7bfb7265c..ae9e64dba 100644 --- a/test/lib/pgBackRestTest/Common/DefineTest.pm +++ b/test/lib/pgBackRestTest/Common/DefineTest.pm @@ -273,7 +273,7 @@ my $oTestDef = &TESTDEF_COVERAGE => { - &TESTDEF_MODULE_INFO => TESTDEF_COVERAGE_PARTIAL, + &TESTDEF_MODULE_INFO => TESTDEF_COVERAGE_FULL, }, }, ] diff --git a/test/lib/pgBackRestTest/Module/Info/InfoUnitTest.pm b/test/lib/pgBackRestTest/Module/Info/InfoUnitTest.pm index 7c098bd12..c2690fa29 100644 --- a/test/lib/pgBackRestTest/Module/Info/InfoUnitTest.pm +++ b/test/lib/pgBackRestTest/Module/Info/InfoUnitTest.pm @@ -22,6 +22,7 @@ use pgBackRest::Common::Log; use pgBackRest::Config::Config; use pgBackRest::DbVersion; use pgBackRest::Info; +use pgBackRest::InfoCommon; use pgBackRest::Manifest; use pgBackRest::Protocol::Helper; use pgBackRest::Protocol::Storage::Helper; @@ -29,6 +30,7 @@ use pgBackRest::Protocol::Storage::Helper; use pgBackRestTest::Common::ExecuteTest; use pgBackRestTest::Common::RunTest; use pgBackRestTest::Env::ExpireEnvTest; +use pgBackRestTest::Common::FileTest; use pgBackRestTest::Env::Host::HostBackupTest; use pgBackRestTest::Env::HostEnvTest; @@ -60,17 +62,12 @@ sub initTest # Create backup info path storageTest()->pathCreate($self->{strBackupPath}, {bIgnoreExists => true, bCreateParent => true}); - - # Set options for stanzaCreate - $self->optionStanzaCreate(); - - # Create the test object - $self->{oExpireTest} = new pgBackRestTest::Env::ExpireEnvTest(undef, $self->backrestExe(), storageRepo(), undef, $self); - - $self->{oExpireTest}->stanzaCreate($self->stanza(), PG_VERSION_94); } -sub optionStanzaCreate +#################################################################################################################################### +# initStanzaCreate - initialize options and create the stanza object +#################################################################################################################################### +sub initStanzaCreate { my $self = shift; @@ -86,6 +83,37 @@ sub optionStanzaCreate $self->optionSetTest($oOption, OPTION_PROTOCOL_TIMEOUT, 6); $self->configLoadExpect(dclone($oOption), CMD_STANZA_CREATE); + + # Create the test object + $self->{oExpireTest} = new pgBackRestTest::Env::ExpireEnvTest(undef, $self->backrestExe(), storageRepo(), undef, $self); + + $self->{oExpireTest}->stanzaCreate($self->stanza(), PG_VERSION_94); +} + +#################################################################################################################################### +# initStanzaUpgrade - initialize options and create the stanza object +#################################################################################################################################### +sub initStanzaUpgrade +{ + my $self = shift; + + # Set options for stanzaCreate + my $oOption = {}; + + $self->optionSetTest($oOption, OPTION_STANZA, $self->stanza()); + $self->optionSetTest($oOption, OPTION_DB_PATH, $self->{strDbPath}); + $self->optionSetTest($oOption, OPTION_REPO_PATH, $self->{strRepoPath}); + $self->optionSetTest($oOption, OPTION_LOG_PATH, $self->testPath()); + $self->optionBoolSetTest($oOption, OPTION_ONLINE, false); + $self->optionSetTest($oOption, OPTION_DB_TIMEOUT, 5); + $self->optionSetTest($oOption, OPTION_PROTOCOL_TIMEOUT, 6); + + $self->configLoadExpect(dclone($oOption), CMD_STANZA_UPGRADE); + + # Create the test object + $self->{oExpireTest} = new pgBackRestTest::Env::ExpireEnvTest(undef, $self->backrestExe(), storageRepo(), undef, $self); + + $self->{oExpireTest}->stanzaUpgrade($self->stanza(), PG_VERSION_95); } #################################################################################################################################### @@ -97,83 +125,232 @@ sub run my $oOption = {}; - $self->optionSetTest($oOption, OPTION_STANZA, $self->stanza()); - $self->optionSetTest($oOption, OPTION_REPO_PATH, $self->{strRepoPath}); - # Used to create backups and WAL to test use constant SECONDS_PER_DAY => 86400; my $lBaseTime = 1486137448 - (60 * SECONDS_PER_DAY); ################################################################################################################################ - if ($self->begin("Info->formatTextStanza() && Info->formatTextBackup()")) + if ($self->begin("Info")) { logDisable(); $self->configLoadExpect(dclone($oOption), CMD_INFO); logEnable(); my $oInfo = new pgBackRest::Info(); + # Output No stanzas exist in default text option #--------------------------------------------------------------------------------------------------------------------------- - my $hyStanza = $oInfo->stanzaList($self->stanza()); - $self->testResult(sub {$oInfo->formatTextStanza(@{$hyStanza}[0])}, - "stanza: db\n status: error (no valid backups)\n wal archive min/max: none present", "stanza text output"); + $self->testResult(sub {$oInfo->process()}, 0, 'No stanzas exist and default text option'); + # Invalid option + #--------------------------------------------------------------------------------------------------------------------------- + optionSet(OPTION_OUTPUT, BOGUS); + + $self->testException(sub {$oInfo->process()}, ERROR_ASSERT, "invalid info output option '" . BOGUS . "'"); + + # Output json option with no stanza defined + #--------------------------------------------------------------------------------------------------------------------------- + $self->optionSetTest($oOption, OPTION_OUTPUT, INFO_OUTPUT_JSON); + logDisable(); $self->configLoadExpect(dclone($oOption), CMD_INFO); logEnable(); + + $self->testResult(sub {$oInfo->process()}, 0, 'json option'); + + # Add linefeed to JSON + #--------------------------------------------------------------------------------------------------------------------------- + my $strJson = '[{"archive" : 1}]'; + $self->testResult(sub {$oInfo->outputJSON($strJson)}, 1, 'add linefeed to json'); + + # Missing stanza path + #--------------------------------------------------------------------------------------------------------------------------- + my $hyStanza = $oInfo->stanzaList(BOGUS); + + $self->testResult(sub {$oInfo->formatText($hyStanza)}, + "stanza: bogus\n status: error (missing stanza path)\n", + 'missing stanza path'); + + # formatBackupText - coverage for certain conditions + #--------------------------------------------------------------------------------------------------------------------------- + my $oBackupHash = + { + 'archive' => + { + 'start' => 1, + 'stop' => undef + }, + 'timestamp' => + { + 'start' => 1481039848, + 'stop' => 1481039848, + }, + 'label' => 'BACKUPLABEL', + 'reference' => ['BACKUPREFERENCE'], + 'type' => 'BACKUPTYPE', + }; + + $self->testResult(sub {$oInfo->formatTextBackup($oBackupHash)}, + " BACKUPTYPE backup: BACKUPLABEL\n" . + " timestamp start/stop: 2016-12-06 15:57:28 / 2016-12-06 15:57:28\n" . + " wal start/stop: n/a\n" . + " database size: , backup size: \n" . + " repository size: , repository backup size: \n" . + " backup reference list: BACKUPREFERENCE", + 'formatTextBackup'); + + # Test !isRepoLocal branch + #--------------------------------------------------------------------------------------------------------------------------- + optionSet(OPTION_BACKUP_HOST, false); + $self->testException(sub {$oInfo->stanzaList(BOGUS)}, ERROR_ASSERT, "option backup-cmd is required"); + + # dbArchiveSection() -- no archive + #--------------------------------------------------------------------------------------------------------------------------- + my $hDbInfo = + { + &INFO_HISTORY_ID => 1, + &INFO_DB_VERSION => PG_VERSION_94, + &INFO_SYSTEM_ID => WAL_VERSION_94_SYS_ID, + }; + + $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, PG_VERSION_94 . '-1', $self->{strArchivePath}, PG_VERSION_94, + WAL_VERSION_94_SYS_ID)}, "{database => {id => 1}, id => 9.4-1, max => [undef], min => [undef]}", + 'no archive, db-ver match, db-sys match'); + + $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, PG_VERSION_94 . '-1', $self->{strArchivePath}, PG_VERSION_94, + WAL_VERSION_95_SYS_ID)}, undef, 'no archive, db-ver match, db-sys mismatch'); + + $hDbInfo->{&INFO_DB_VERSION} = PG_VERSION_95; + $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, PG_VERSION_94 . '-1', $self->{strArchivePath}, PG_VERSION_94, + WAL_VERSION_94_SYS_ID)}, undef, 'no archive, db-ver mismatch, db-sys match'); + + $hDbInfo->{&INFO_SYSTEM_ID} = WAL_VERSION_95_SYS_ID; + $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, PG_VERSION_94 . '-1', $self->{strArchivePath}, PG_VERSION_94, + WAL_VERSION_94_SYS_ID)}, undef, 'no archive, db-ver mismatch, db-sys mismatch'); + + # Create more than one stanza but no data + #--------------------------------------------------------------------------------------------------------------------------- + $self->optionSetTest($oOption, OPTION_STANZA, $self->stanza()); + $self->optionSetTest($oOption, OPTION_REPO_PATH, $self->{strRepoPath}); + logDisable(); $self->configLoadExpect(dclone($oOption), CMD_INFO); logEnable(); + + # Create archive info paths but no archive info + storageTest()->pathCreate($self->{strArchivePath}, {bIgnoreExists => true, bCreateParent => true}); + storageTest()->pathCreate("$self->{strRepoPath}/archive/" . BOGUS, {bIgnoreExists => true, bCreateParent => true}); + + # Create backup info paths but no backup info + storageTest()->pathCreate($self->{strBackupPath}, {bIgnoreExists => true, bCreateParent => true}); + storageTest()->pathCreate("$self->{strRepoPath}/backup/" . BOGUS, {bIgnoreExists => true, bCreateParent => true}); + + # Get a list of all stanzas in the repo + $hyStanza = $oInfo->stanzaList(); + + $self->testResult(sub {$oInfo->formatText($hyStanza)}, + "stanza: bogus\n status: error (no valid backups)\n\n" . + "stanza: db\n status: error (no valid backups)\n", + 'fomatText() multiple stanzas'); + + # Define the stanza option + #--------------------------------------------------------------------------------------------------------------------------- + $self->optionSetTest($oOption, OPTION_STANZA, $self->stanza()); + $self->optionReset($oOption, OPTION_OUTPUT); + logDisable(); $self->configLoadExpect(dclone($oOption), CMD_INFO); logEnable(); + + $self->testResult(sub {$oInfo->process()}, 0, 'stanza set'); + + # Create the stanza - no WAL or backups + #--------------------------------------------------------------------------------------------------------------------------- + $self->initStanzaCreate(); + logDisable(); $self->configLoadExpect(dclone($oOption), CMD_INFO); logEnable(); + + $hyStanza = $oInfo->stanzaList($self->stanza()); + $self->testResult(sub {$oInfo->formatText($hyStanza)}, + "stanza: db\n status: error (no valid backups)\n\n" . + " db (current)\n wal archive min/max (9.4-1): none present\n", + "formatText() one stanza"); + + # Create a backup and list backup for just one stanza #--------------------------------------------------------------------------------------------------------------------------- $self->{oExpireTest}->backupCreate($self->stanza(), BACKUP_TYPE_FULL, $lBaseTime += SECONDS_PER_DAY, -1, -1); + $hyStanza = $oInfo->stanzaList($self->stanza()); + $self->testResult(sub {$oInfo->formatText($hyStanza)}, + "stanza: db\n status: ok\n\n db (current)\n wal archive min/max (9.4-1): none present\n\n" . + " full backup: 20161206-155728F\n" . + " timestamp start/stop: 2016-12-06 15:57:28 / 2016-12-06 15:57:28\n" . + " wal start/stop: n/a\n database size: 0B, backup size: 0B\n" . + " repository size: 0B, repository backup size: 0B\n", + "formatText() one stanza"); - $self->testResult(sub {$oInfo->formatTextStanza(@{$hyStanza}[-1])}, - "stanza: db\n status: ok\n wal archive min/max: none present", - "stanza text output"); - - $self->testResult(sub {$oInfo->formatTextBackup(@{$hyStanza}[-1]->{&INFO_BACKUP_SECTION_BACKUP}[-1])}, - " full backup: 20161206-155728F\n" . - " timestamp start/stop: 2016-12-06 15:57:28 / 2016-12-06 15:57:28\n" . - " wal start/stop: n/a\n" . - " database size: 0B, backup size: 0B\n" . - " repository size: 0B, repository backup size: 0B", - "full backup text output"); - + # Coverage for major WAL paths with no WAL #--------------------------------------------------------------------------------------------------------------------------- - $self->{oExpireTest}->backupCreate($self->stanza(), BACKUP_TYPE_DIFF, $lBaseTime += SECONDS_PER_DAY); + storageTest()->pathCreate($self->{strArchivePath} . "/9.4-1/0000000100000000", {bIgnoreExists => true}); + storageTest()->pathCreate($self->{strArchivePath} . "/9.4-1/0000000200000000", {bIgnoreExists => true}); $hyStanza = $oInfo->stanzaList($self->stanza()); + $self->testResult(sub {$oInfo->formatText($hyStanza)}, + "stanza: db\n status: ok\n\n db (current)\n wal archive min/max (9.4-1): none present\n\n" . + " full backup: 20161206-155728F\n" . + " timestamp start/stop: 2016-12-06 15:57:28 / 2016-12-06 15:57:28\n" . + " wal start/stop: n/a\n database size: 0B, backup size: 0B\n" . + " repository size: 0B, repository backup size: 0B\n", + "formatText() major WAL paths with no WAL"); - $self->testResult(sub {$oInfo->formatTextStanza(@{$hyStanza}[-1])}, - "stanza: db\n status: ok\n wal archive min/max: 000000010000000000000000 / 000000010000000000000005", - "stanza text output"); - - $self->testResult(sub {$oInfo->formatTextBackup(@{$hyStanza}[-1]->{&INFO_BACKUP_SECTION_BACKUP}[-1])}, - " diff backup: 20161206-155728F_20161207-155728D\n" . - " timestamp start/stop: 2016-12-07 15:57:28 / 2016-12-07 15:57:28\n" . - " wal start/stop: 000000010000000000000000 / 000000010000000000000002\n" . - " database size: 0B, backup size: 0B\n" . - " repository size: 0B, repository backup size: 0B", - "diff backup text output"); - + # Upgrade postgres version and backup with WAL #--------------------------------------------------------------------------------------------------------------------------- - $self->{oExpireTest}->backupCreate($self->stanza(), BACKUP_TYPE_INCR, $lBaseTime += SECONDS_PER_DAY, 256); + undef($self->{oExpireTest}); + $self->initStanzaUpgrade(); + logDisable(); $self->configLoadExpect(dclone($oOption), CMD_INFO); logEnable(); + + $self->{oExpireTest}->backupCreate($self->stanza(), BACKUP_TYPE_FULL, $lBaseTime += SECONDS_PER_DAY, 1, 1); + $self->{oExpireTest}->backupCreate($self->stanza(), BACKUP_TYPE_DIFF, $lBaseTime += SECONDS_PER_DAY, 1, 1); + + # Remove the 9.4-1 path for condition test coverage + storageTest()->remove($self->{strArchivePath} . "/9.4-1/", {bRecurse => true}); + $hyStanza = $oInfo->stanzaList($self->stanza()); + $self->testResult(sub {$oInfo->formatText($hyStanza)}, + "stanza: db\n status: ok\n" . + "\n db (current)\n" . + " wal archive min/max (9.5-2): 000000010000000000000000 / 000000010000000000000003\n\n" . + " full backup: 20161207-155728F\n" . + " timestamp start/stop: 2016-12-07 15:57:28 / 2016-12-07 15:57:28\n" . + " wal start/stop: 000000010000000000000000 / 000000010000000000000000\n" . + " database size: 0B, backup size: 0B\n" . + " repository size: 0B, repository backup size: 0B\n\n" . + " diff backup: 20161207-155728F_20161208-155728D\n" . + " timestamp start/stop: 2016-12-08 15:57:28 / 2016-12-08 15:57:28\n" . + " wal start/stop: 000000010000000000000002 / 000000010000000000000002\n" . + " database size: 0B, backup size: 0B\n" . + " repository size: 0B, repository backup size: 0B\n" . + "\n db (prior)\n" . + " full backup: 20161206-155728F\n" . + " timestamp start/stop: 2016-12-06 15:57:28 / 2016-12-06 15:57:28\n" . + " wal start/stop: n/a\n" . + " database size: 0B, backup size: 0B\n" . + " repository size: 0B, repository backup size: 0B\n", + "formatText() multiple DB versions"); - $self->testResult(sub {$oInfo->formatTextStanza(@{$hyStanza}[-1])}, - "stanza: db\n status: ok\n wal archive min/max: 000000010000000000000000 / 000000010000000100000008", - "stanza text output"); - - $self->testResult(sub {$oInfo->formatTextBackup(@{$hyStanza}[-1]->{&INFO_BACKUP_SECTION_BACKUP}[-1])}, - " incr backup: 20161206-155728F_20161208-155728I\n" . - " timestamp start/stop: 2016-12-08 15:57:28 / 2016-12-08 15:57:28\n" . - " wal start/stop: 000000010000000000000006 / 000000010000000100000005\n" . - " database size: 0B, backup size: 0B\n" . - " repository size: 0B, repository backup size: 0B", - "incr backup text output"); - - # Upgrade the stanza, generate archive and confirm the min/max archive is for the new (current) DB version + # dbArchiveSection() -- with archive #--------------------------------------------------------------------------------------------------------------------------- - $self->optionStanzaCreate(); - $self->{oExpireTest}->stanzaUpgrade($self->stanza(), PG_VERSION_95); - $self->{oExpireTest}->backupCreate($self->stanza(), BACKUP_TYPE_FULL, $lBaseTime += SECONDS_PER_DAY, 2); - $hyStanza = $oInfo->stanzaList($self->stanza()); + $hDbInfo->{&INFO_HISTORY_ID} = 2; + $hDbInfo->{&INFO_DB_VERSION} = PG_VERSION_95; + $hDbInfo->{&INFO_SYSTEM_ID} = WAL_VERSION_95_SYS_ID; - $self->testResult(sub {$oInfo->formatTextStanza(@{$hyStanza}[-1])}, - "stanza: db\n status: ok\n wal archive min/max: 000000010000000000000000 / 000000010000000000000004", - "stanza text output"); + my $strArchiveId = PG_VERSION_95 . '-2'; + $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, $strArchiveId, "$self->{strArchivePath}/$strArchiveId", + PG_VERSION_95, WAL_VERSION_95_SYS_ID)}, + "{database => {id => 2}, id => 9.5-2, max => 000000010000000000000003, min => 000000010000000000000000}", + 'archive, db-ver match, db-sys-id match'); + + $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, $strArchiveId, "$self->{strArchivePath}/$strArchiveId", + PG_VERSION_95, WAL_VERSION_94_SYS_ID)}, + "{database => {id => 2}, id => 9.5-2, max => 000000010000000000000003, min => 000000010000000000000000}", + 'archive, db-ver match, db-sys-id mismatch'); + + $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, $strArchiveId, "$self->{strArchivePath}/$strArchiveId", + PG_VERSION_94, WAL_VERSION_95_SYS_ID)}, + "{database => {id => 2}, id => 9.5-2, max => 000000010000000000000003, min => 000000010000000000000000}", + 'archive, db-ver mismatch, db-sys-id match'); + + $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, $strArchiveId, "$self->{strArchivePath}/$strArchiveId", + PG_VERSION_94, WAL_VERSION_94_SYS_ID)}, + "{database => {id => 2}, id => 9.5-2, max => 000000010000000000000003, min => 000000010000000000000000}", + 'archive, db-ver mismatch, db-sys-id mismatch'); } } diff --git a/test/test.pl b/test/test.pl index c7d5fb6a9..5425858fb 100755 --- a/test/test.pl +++ b/test/test.pl @@ -562,7 +562,10 @@ eval } # Remove patches that should be applied to core code - $oStorageBackRest->remove("${strBuildPath}/debian/patches", {bRecurse => true}); + if ($oStorageBackRest->pathExists("${strBuildPath}/debian/patches")) + { + $oStorageBackRest->remove("${strBuildPath}/debian/patches", {bRecurse => true}); + } # Update changelog to add experimental version $oStorageBackRest->put("${strBuildPath}/debian/changelog",