mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-18 21:51:39 +02:00
ddd4c14773
Implemented issue #136: Add stderr back into protocol layer. There were also miscellaneous bug fixes and improvements to buffering in IO.pm.
342 lines
11 KiB
Perl
Executable File
342 lines
11 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
####################################################################################################################################
|
|
# test.pl - pgBackRest Unit Tests
|
|
####################################################################################################################################
|
|
|
|
####################################################################################################################################
|
|
# Perl includes
|
|
####################################################################################################################################
|
|
use strict;
|
|
use warnings FATAL => qw(all);
|
|
use Carp qw(confess longmess);
|
|
|
|
# Convert die to confess to capture the stack trace
|
|
$SIG{__DIE__} = sub { Carp::confess @_ };
|
|
|
|
use File::Basename qw(dirname);
|
|
use Getopt::Long qw(GetOptions);
|
|
use Cwd qw(abs_path);
|
|
use Pod::Usage qw(pod2usage);
|
|
use Scalar::Util qw(blessed);
|
|
|
|
use lib dirname($0) . '/../lib';
|
|
use BackRest::Common::Ini;
|
|
use BackRest::Common::Log;
|
|
use BackRest::Db;
|
|
|
|
use lib dirname($0) . '/lib';
|
|
use BackRestTest::BackupTest;
|
|
use BackRestTest::CommonTest;
|
|
use BackRestTest::CompareTest;
|
|
use BackRestTest::ConfigTest;
|
|
use BackRestTest::FileTest;
|
|
use BackRestTest::HelpTest;
|
|
# use BackRestTest::IniTest;
|
|
|
|
####################################################################################################################################
|
|
# Usage
|
|
####################################################################################################################################
|
|
|
|
=head1 NAME
|
|
|
|
test.pl - pgBackRest Unit Tests
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
test.pl [options]
|
|
|
|
Test Options:
|
|
--module test module to execute:
|
|
--test execute the specified test in a module
|
|
--run execute only the specified test run
|
|
--thread-max max threads to run for backup/restore (default 4)
|
|
--dry-run show only the tests that would be executed but don't execute them
|
|
--no-cleanup don't cleaup after the last test is complete - useful for debugging
|
|
--infinite repeat selected tests forever
|
|
--db-version version of postgres to test (or all)
|
|
--log-force force overwrite of current test log files
|
|
|
|
Configuration Options:
|
|
--exe backup executable
|
|
--psql-bin path to the psql executables (e.g. /usr/lib/postgresql/9.3/bin/)
|
|
--test-path path where tests are executed (defaults to ./test)
|
|
--log-level log level to use for tests (defaults to INFO)
|
|
--quiet, -q equivalent to --log-level=off
|
|
|
|
General Options:
|
|
--version display version and exit
|
|
--help display usage and exit
|
|
=cut
|
|
|
|
####################################################################################################################################
|
|
# Command line parameters
|
|
####################################################################################################################################
|
|
my $strLogLevel = 'info';
|
|
my $strModule = 'all';
|
|
my $strModuleTest = 'all';
|
|
my $iModuleTestRun = undef;
|
|
my $iThreadMax = undef;
|
|
my $bDryRun = false;
|
|
my $bNoCleanup = false;
|
|
my $strPgSqlBin;
|
|
my $strExe;
|
|
my $strTestPath;
|
|
my $bVersion = false;
|
|
my $bHelp = false;
|
|
my $bQuiet = false;
|
|
my $bInfinite = false;
|
|
my $strDbVersion = 'all';
|
|
my $bLogForce = false;
|
|
|
|
GetOptions ('q|quiet' => \$bQuiet,
|
|
'version' => \$bVersion,
|
|
'help' => \$bHelp,
|
|
'pgsql-bin=s' => \$strPgSqlBin,
|
|
'exes=s' => \$strExe,
|
|
'test-path=s' => \$strTestPath,
|
|
'log-level=s' => \$strLogLevel,
|
|
'module=s' => \$strModule,
|
|
'test=s' => \$strModuleTest,
|
|
'run=s' => \$iModuleTestRun,
|
|
'thread-max=s' => \$iThreadMax,
|
|
'dry-run' => \$bDryRun,
|
|
'no-cleanup' => \$bNoCleanup,
|
|
'infinite' => \$bInfinite,
|
|
'db-version=s' => \$strDbVersion,
|
|
'log-force' => \$bLogForce)
|
|
or pod2usage(2);
|
|
|
|
# Display version and exit if requested
|
|
if ($bVersion || $bHelp)
|
|
{
|
|
syswrite(*STDOUT, 'pgBackRest ' . BACKREST_VERSION . " Unit Tests\n");
|
|
|
|
if ($bHelp)
|
|
{
|
|
syswrite(*STDOUT, "\n");
|
|
pod2usage();
|
|
}
|
|
|
|
exit 0;
|
|
}
|
|
|
|
if (@ARGV > 0)
|
|
{
|
|
syswrite(*STDOUT, "invalid parameter\n\n");
|
|
pod2usage();
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# Setup
|
|
####################################################################################################################################
|
|
# Set a neutral umask so tests work as expected
|
|
umask(0);
|
|
|
|
if (defined($strExe) && !-e $strExe)
|
|
{
|
|
confess '--exe must exist and be fully qualified'
|
|
}
|
|
|
|
# Set console log level
|
|
if ($bQuiet)
|
|
{
|
|
$strLogLevel = 'off';
|
|
}
|
|
|
|
logLevelSet(undef, uc($strLogLevel));
|
|
|
|
if ($strModuleTest ne 'all' && $strModule eq 'all')
|
|
{
|
|
confess "--module must be provided for --test=\"${strModuleTest}\"";
|
|
}
|
|
|
|
if (defined($iModuleTestRun) && $strModuleTest eq 'all')
|
|
{
|
|
confess "--test must be provided for --run=\"${iModuleTestRun}\"";
|
|
}
|
|
|
|
# Search for psql bin
|
|
my @stryTestVersion;
|
|
my @stryVersionSupport = versionSupport();
|
|
|
|
if (!defined($strPgSqlBin))
|
|
{
|
|
# Distribution-specific paths where the PostgreSQL binaries may be located
|
|
my @strySearchPath =
|
|
(
|
|
'/usr/lib/postgresql/VERSION/bin', # Debian/Ubuntu
|
|
'/usr/pgsql-VERSION/bin', # CentOS/RHEL/Fedora
|
|
'/Library/PostgreSQL/VERSION/bin', # OSX
|
|
'/usr/local/bin' # BSD
|
|
);
|
|
|
|
foreach my $strSearchPath (@strySearchPath)
|
|
{
|
|
for (my $iVersionIdx = @stryVersionSupport - 1; $iVersionIdx >= 0; $iVersionIdx--)
|
|
{
|
|
if ($strDbVersion eq 'all' || $strDbVersion eq 'max' && @stryTestVersion == 0 ||
|
|
$strDbVersion eq $stryVersionSupport[$iVersionIdx])
|
|
{
|
|
my $strVersionPath = $strSearchPath;
|
|
$strVersionPath =~ s/VERSION/$stryVersionSupport[$iVersionIdx]/g;
|
|
|
|
if (-e "${strVersionPath}/initdb")
|
|
{
|
|
&log(INFO, "FOUND pgsql-bin at ${strVersionPath}");
|
|
push @stryTestVersion, $strVersionPath;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Make sure at least one version of postgres was found
|
|
@stryTestVersion > 0
|
|
or confess 'pgsql-bin was not defined and postgres could not be located automatically';
|
|
}
|
|
else
|
|
{
|
|
push @stryTestVersion, $strPgSqlBin;
|
|
}
|
|
|
|
# Check thread total
|
|
if (defined($iThreadMax) && ($iThreadMax < 1 || $iThreadMax > 32))
|
|
{
|
|
confess 'thread-max must be between 1 and 32';
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# Make sure version number matches in the change log.
|
|
####################################################################################################################################
|
|
my $hReadMe;
|
|
my $strLine;
|
|
my $bMatch = false;
|
|
my $strChangeLogFile = abs_path(dirname($0) . '/../CHANGELOG.md');
|
|
|
|
if (!open($hReadMe, '<', $strChangeLogFile))
|
|
{
|
|
confess "unable to open ${strChangeLogFile}";
|
|
}
|
|
|
|
while ($strLine = readline($hReadMe))
|
|
{
|
|
if ($strLine =~ /^\#\# v/)
|
|
{
|
|
$bMatch = substr($strLine, 4, length(BACKREST_VERSION)) eq BACKREST_VERSION;
|
|
last;
|
|
}
|
|
}
|
|
|
|
if (!$bMatch)
|
|
{
|
|
confess 'unable to find version ' . BACKREST_VERSION . " as last revision in ${strChangeLogFile}";
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# Clean whitespace only if test.pl is being run from the test directory in the backrest repo
|
|
####################################################################################################################################
|
|
if (-e './test.pl' && -e '../bin/pg_backrest')
|
|
{
|
|
BackRestTestCommon_Execute(
|
|
"find .. -type f -not -path \"../.git/*\" -not -path \"*.DS_Store\" -not -path \"../test/test/*\" " .
|
|
"-not -path \"../test/data/*\" " .
|
|
"-exec sh -c 'for i;do echo \"\$i\" && sed 's/[[:space:]]*\$//' \"\$i\">/tmp/.\$\$ && cat /tmp/.\$\$ " .
|
|
"> \"\$i\";done' arg0 {} + > /dev/null", false, true);
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# Runs tests
|
|
####################################################################################################################################
|
|
# &log(INFO, "Testing with test_path = " . BackRestTestCommon_TestPathGet() . ", host = {strHost}, user = {strUser}, " .
|
|
# "group = {strGroup}");
|
|
|
|
my $iRun = 0;
|
|
|
|
eval
|
|
{
|
|
do
|
|
{
|
|
if (BackRestTestCommon_Setup($strExe, $strTestPath, $stryTestVersion[0], $iModuleTestRun,
|
|
$bDryRun, $bNoCleanup, $bLogForce))
|
|
{
|
|
&log(INFO, "TESTING psql-bin = $stryTestVersion[0]\n");
|
|
|
|
if ($bInfinite)
|
|
{
|
|
$iRun++;
|
|
&log(INFO, "INFINITE - RUN ${iRun}\n");
|
|
}
|
|
|
|
# if ($strModule eq 'all' || $strModule eq 'ini')
|
|
# {
|
|
# BackRestTestIni_Test($strModuleTest);
|
|
# }
|
|
|
|
if ($strModule eq 'all' || $strModule eq 'help')
|
|
{
|
|
BackRestTestHelp_Test($strModuleTest);
|
|
}
|
|
|
|
if ($strModule eq 'all' || $strModule eq 'config')
|
|
{
|
|
BackRestTestConfig_Test($strModuleTest);
|
|
}
|
|
|
|
if ($strModule eq 'all' || $strModule eq 'file')
|
|
{
|
|
BackRestTestFile_Test($strModuleTest);
|
|
}
|
|
|
|
if ($strModule eq 'all' || $strModule eq 'backup')
|
|
{
|
|
if (!defined($iThreadMax) || $iThreadMax == 1)
|
|
{
|
|
BackRestTestBackup_Test($strModuleTest, 1);
|
|
}
|
|
|
|
if (!defined($iThreadMax) || $iThreadMax > 1)
|
|
{
|
|
BackRestTestBackup_Test($strModuleTest, defined($iThreadMax) ? $iThreadMax : 4);
|
|
}
|
|
|
|
if (@stryTestVersion > 1 && ($strModuleTest eq 'all' || $strModuleTest eq 'full'))
|
|
{
|
|
for (my $iVersionIdx = 1; $iVersionIdx < @stryTestVersion; $iVersionIdx++)
|
|
{
|
|
BackRestTestCommon_Setup($strExe, $strTestPath, $stryTestVersion[$iVersionIdx],
|
|
$iModuleTestRun, $bDryRun, $bNoCleanup);
|
|
&log(INFO, "TESTING psql-bin = $stryTestVersion[$iVersionIdx] for backup/full\n");
|
|
BackRestTestBackup_Test('full', defined($iThreadMax) ? $iThreadMax : 4);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($strModule eq 'compare')
|
|
{
|
|
BackRestTestCompare_Test($strModuleTest);
|
|
}
|
|
}
|
|
}
|
|
while ($bInfinite);
|
|
};
|
|
|
|
if ($@)
|
|
{
|
|
my $oMessage = $@;
|
|
|
|
# If a backrest exception then return the code - don't confess
|
|
if (blessed($oMessage) && $oMessage->isa('BackRest::Common::Exception'))
|
|
{
|
|
syswrite(*STDOUT, $oMessage->trace());
|
|
exit $oMessage->code();
|
|
}
|
|
|
|
syswrite(*STDOUT, $oMessage);
|
|
exit 255;;
|
|
}
|
|
|
|
|
|
if (!$bDryRun)
|
|
{
|
|
&log(INFO, 'TESTS COMPLETED SUCCESSFULLY (DESPITE ANY ERROR MESSAGES YOU SAW)');
|
|
}
|