2013-11-17 21:58:21 +03:00
|
|
|
#!/usr/bin/perl
|
2014-04-03 00:25:37 +03:00
|
|
|
####################################################################################################################################
|
2015-08-29 20:20:46 +02:00
|
|
|
# test.pl - pgBackRest Unit Tests
|
2014-04-03 00:25:37 +03:00
|
|
|
####################################################################################################################################
|
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# Perl includes
|
|
|
|
####################################################################################################################################
|
|
|
|
use strict;
|
2015-04-19 23:27:40 +02:00
|
|
|
use warnings FATAL => qw(all);
|
2015-06-14 00:25:49 +02:00
|
|
|
use Carp qw(confess longmess);
|
|
|
|
|
2015-08-29 20:20:46 +02:00
|
|
|
# Convert die to confess to capture the stack trace
|
2015-06-14 00:25:49 +02:00
|
|
|
$SIG{__DIE__} = sub { Carp::confess @_ };
|
2014-04-03 00:25:37 +03:00
|
|
|
|
2015-08-29 20:20:46 +02:00
|
|
|
use File::Basename qw(dirname);
|
|
|
|
use Getopt::Long qw(GetOptions);
|
2016-01-15 02:37:06 +02:00
|
|
|
use Cwd qw(abs_path cwd);
|
2015-08-29 20:20:46 +02:00
|
|
|
use Pod::Usage qw(pod2usage);
|
2016-01-09 15:21:53 +02:00
|
|
|
use POSIX qw(ceil);
|
|
|
|
use Time::HiRes qw(gettimeofday);
|
2015-06-21 18:06:13 +02:00
|
|
|
use Scalar::Util qw(blessed);
|
2014-04-03 00:25:37 +03:00
|
|
|
|
2014-09-16 18:22:55 +03:00
|
|
|
use lib dirname($0) . '/../lib';
|
2015-08-29 20:20:46 +02:00
|
|
|
use BackRest::Common::Ini;
|
|
|
|
use BackRest::Common::Log;
|
2016-01-09 15:21:53 +02:00
|
|
|
use BackRest::Common::String;
|
|
|
|
use BackRest::Common::Wait;
|
2015-04-03 04:07:23 +02:00
|
|
|
use BackRest::Db;
|
2014-06-22 17:30:17 +03:00
|
|
|
|
2014-09-16 18:22:55 +03:00
|
|
|
use lib dirname($0) . '/lib';
|
2015-08-29 20:20:46 +02:00
|
|
|
use BackRestTest::BackupTest;
|
2015-12-29 20:57:10 +02:00
|
|
|
use BackRestTest::Common::ExecuteTest;
|
2016-01-11 02:30:51 +02:00
|
|
|
use BackRestTest::Common::VmTest;
|
2014-06-22 17:30:17 +03:00
|
|
|
use BackRestTest::CommonTest;
|
2015-08-29 20:20:46 +02:00
|
|
|
use BackRestTest::CompareTest;
|
2015-03-08 19:26:09 +02:00
|
|
|
use BackRestTest::ConfigTest;
|
2016-01-11 02:30:51 +02:00
|
|
|
use BackRestTest::Docker::ContainerTest;
|
2014-05-14 22:07:37 +03:00
|
|
|
use BackRestTest::FileTest;
|
2015-09-08 18:58:13 +02:00
|
|
|
use BackRestTest::HelpTest;
|
2014-04-03 00:25:37 +03:00
|
|
|
|
2015-01-11 18:52:16 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# Usage
|
|
|
|
####################################################################################################################################
|
|
|
|
|
|
|
|
=head1 NAME
|
|
|
|
|
2015-08-29 20:20:46 +02:00
|
|
|
test.pl - pgBackRest Unit Tests
|
2015-01-11 18:52:16 +02:00
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
|
|
|
|
test.pl [options]
|
|
|
|
|
|
|
|
Test Options:
|
2016-01-09 15:21:53 +02:00
|
|
|
--module test module to execute
|
2015-06-27 17:12:44 +02:00
|
|
|
--test execute the specified test in a module
|
|
|
|
--run execute only the specified test run
|
2015-02-28 17:21:36 +02:00
|
|
|
--thread-max max threads to run for backup/restore (default 4)
|
2015-01-12 16:05:26 +02:00
|
|
|
--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
|
2015-02-28 06:31:39 +02:00
|
|
|
--infinite repeat selected tests forever
|
2015-04-03 04:07:23 +02:00
|
|
|
--db-version version of postgres to test (or all)
|
2015-05-05 19:08:48 +02:00
|
|
|
--log-force force overwrite of current test log files
|
2016-02-23 16:25:22 +02:00
|
|
|
--no-lint Disable static source code analysis
|
2015-01-11 18:52:16 +02:00
|
|
|
|
|
|
|
Configuration Options:
|
2016-01-09 15:21:53 +02:00
|
|
|
--exe pgBackRest executable
|
2015-01-12 16:05:26 +02:00
|
|
|
--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
|
2015-01-11 18:52:16 +02:00
|
|
|
|
2016-01-09 15:21:53 +02:00
|
|
|
VM Options:
|
|
|
|
--vm-build build Docker containers
|
|
|
|
--vm execute in a docker container (u12, u14, co6, co7)
|
|
|
|
--vm-out Show VM output (default false)
|
|
|
|
--process-max max VMs to run in parallel (default 1)
|
|
|
|
|
2015-01-11 18:52:16 +02:00
|
|
|
General Options:
|
2015-01-12 16:05:26 +02:00
|
|
|
--version display version and exit
|
|
|
|
--help display usage and exit
|
2015-01-11 18:52:16 +02:00
|
|
|
=cut
|
|
|
|
|
2014-04-03 00:25:37 +03:00
|
|
|
####################################################################################################################################
|
2014-06-04 04:22:07 +03:00
|
|
|
# Command line parameters
|
|
|
|
####################################################################################################################################
|
2015-04-03 04:07:23 +02:00
|
|
|
my $strLogLevel = 'info';
|
2016-01-09 15:21:53 +02:00
|
|
|
my $strOS = 'all';
|
|
|
|
my $bVmOut = false;
|
2014-06-05 17:20:03 +03:00
|
|
|
my $strModule = 'all';
|
|
|
|
my $strModuleTest = 'all';
|
2014-06-22 17:54:31 +03:00
|
|
|
my $iModuleTestRun = undef;
|
2015-09-09 21:40:54 +02:00
|
|
|
my $iThreadMax = undef;
|
2016-01-09 15:21:53 +02:00
|
|
|
my $iProcessMax = 1;
|
2014-07-16 05:32:41 +03:00
|
|
|
my $bDryRun = false;
|
|
|
|
my $bNoCleanup = false;
|
2014-08-11 04:22:17 +03:00
|
|
|
my $strPgSqlBin;
|
2015-07-11 23:16:35 +02:00
|
|
|
my $strExe;
|
2014-08-11 04:22:17 +03:00
|
|
|
my $strTestPath;
|
2015-01-11 18:52:16 +02:00
|
|
|
my $bVersion = false;
|
|
|
|
my $bHelp = false;
|
|
|
|
my $bQuiet = false;
|
2015-02-28 06:31:39 +02:00
|
|
|
my $bInfinite = false;
|
2015-09-09 21:40:54 +02:00
|
|
|
my $strDbVersion = 'all';
|
2015-05-05 19:08:48 +02:00
|
|
|
my $bLogForce = false;
|
2016-01-09 15:21:53 +02:00
|
|
|
my $bVmBuild = false;
|
2016-02-23 16:25:22 +02:00
|
|
|
my $bNoLint = false;
|
2015-01-11 18:52:16 +02:00
|
|
|
|
2015-12-29 20:57:10 +02:00
|
|
|
my $strCommandLine = join(' ', @ARGV);
|
|
|
|
|
2015-01-11 18:52:16 +02:00
|
|
|
GetOptions ('q|quiet' => \$bQuiet,
|
|
|
|
'version' => \$bVersion,
|
|
|
|
'help' => \$bHelp,
|
|
|
|
'pgsql-bin=s' => \$strPgSqlBin,
|
2015-07-11 23:16:35 +02:00
|
|
|
'exes=s' => \$strExe,
|
2014-09-16 18:22:55 +03:00
|
|
|
'test-path=s' => \$strTestPath,
|
|
|
|
'log-level=s' => \$strLogLevel,
|
2016-01-09 15:21:53 +02:00
|
|
|
'vm=s' => \$strOS,
|
|
|
|
'vm-out' => \$bVmOut,
|
|
|
|
'vm-build' => \$bVmBuild,
|
2014-09-16 18:22:55 +03:00
|
|
|
'module=s' => \$strModule,
|
2015-06-27 17:12:44 +02:00
|
|
|
'test=s' => \$strModuleTest,
|
|
|
|
'run=s' => \$iModuleTestRun,
|
2015-02-28 17:21:36 +02:00
|
|
|
'thread-max=s' => \$iThreadMax,
|
2016-01-09 15:21:53 +02:00
|
|
|
'process-max=s' => \$iProcessMax,
|
2014-09-16 18:22:55 +03:00
|
|
|
'dry-run' => \$bDryRun,
|
2015-02-28 06:31:39 +02:00
|
|
|
'no-cleanup' => \$bNoCleanup,
|
2015-04-03 04:07:23 +02:00
|
|
|
'infinite' => \$bInfinite,
|
2015-05-05 19:08:48 +02:00
|
|
|
'db-version=s' => \$strDbVersion,
|
2016-02-23 16:25:22 +02:00
|
|
|
'log-force' => \$bLogForce,
|
|
|
|
'no-lint' => \$bNoLint)
|
2015-01-11 18:52:16 +02:00
|
|
|
or pod2usage(2);
|
|
|
|
|
|
|
|
# Display version and exit if requested
|
|
|
|
if ($bVersion || $bHelp)
|
|
|
|
{
|
2015-08-29 20:20:46 +02:00
|
|
|
syswrite(*STDOUT, 'pgBackRest ' . BACKREST_VERSION . " Unit Tests\n");
|
2015-01-11 18:52:16 +02:00
|
|
|
|
|
|
|
if ($bHelp)
|
|
|
|
{
|
2015-08-29 20:20:46 +02:00
|
|
|
syswrite(*STDOUT, "\n");
|
2015-01-11 18:52:16 +02:00
|
|
|
pod2usage();
|
|
|
|
}
|
|
|
|
|
|
|
|
exit 0;
|
|
|
|
}
|
2014-06-04 04:22:07 +03:00
|
|
|
|
2015-04-03 04:07:23 +02:00
|
|
|
if (@ARGV > 0)
|
|
|
|
{
|
2015-08-29 20:20:46 +02:00
|
|
|
syswrite(*STDOUT, "invalid parameter\n\n");
|
2015-04-03 04:07:23 +02:00
|
|
|
pod2usage();
|
|
|
|
}
|
2015-03-08 19:26:09 +02:00
|
|
|
|
2014-06-04 04:22:07 +03:00
|
|
|
####################################################################################################################################
|
|
|
|
# Setup
|
|
|
|
####################################################################################################################################
|
|
|
|
# Set a neutral umask so tests work as expected
|
|
|
|
umask(0);
|
|
|
|
|
2015-08-27 21:55:29 +02:00
|
|
|
if (defined($strExe) && !-e $strExe)
|
|
|
|
{
|
|
|
|
confess '--exe must exist and be fully qualified'
|
|
|
|
}
|
|
|
|
|
2015-01-11 18:52:16 +02:00
|
|
|
# Set console log level
|
|
|
|
if ($bQuiet)
|
|
|
|
{
|
|
|
|
$strLogLevel = 'off';
|
|
|
|
}
|
|
|
|
|
2016-01-15 02:37:06 +02:00
|
|
|
logLevelSet(uc($strLogLevel), uc($strLogLevel));
|
2014-06-04 04:22:07 +03:00
|
|
|
|
2014-06-05 17:20:03 +03:00
|
|
|
if ($strModuleTest ne 'all' && $strModule eq 'all')
|
|
|
|
{
|
2015-10-08 17:43:56 +02:00
|
|
|
confess "--module must be provided for --test=\"${strModuleTest}\"";
|
2014-06-05 17:20:03 +03:00
|
|
|
}
|
|
|
|
|
2014-06-22 17:54:31 +03:00
|
|
|
if (defined($iModuleTestRun) && $strModuleTest eq 'all')
|
|
|
|
{
|
2015-10-08 17:43:56 +02:00
|
|
|
confess "--test must be provided for --run=\"${iModuleTestRun}\"";
|
2014-06-22 17:54:31 +03:00
|
|
|
}
|
|
|
|
|
2015-02-28 17:21:36 +02:00
|
|
|
# Check thread total
|
2015-09-09 21:40:54 +02:00
|
|
|
if (defined($iThreadMax) && ($iThreadMax < 1 || $iThreadMax > 32))
|
2015-02-28 17:21:36 +02:00
|
|
|
{
|
|
|
|
confess 'thread-max must be between 1 and 32';
|
|
|
|
}
|
|
|
|
|
2016-01-09 15:21:53 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# Build Docker containers
|
|
|
|
####################################################################################################################################
|
|
|
|
if ($bVmBuild)
|
|
|
|
{
|
|
|
|
containerBuild();
|
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
|
2014-06-08 00:29:11 +03:00
|
|
|
####################################################################################################################################
|
2015-08-07 20:43:53 +02:00
|
|
|
# Make sure version number matches in the change log.
|
2014-06-08 00:29:11 +03:00
|
|
|
####################################################################################################################################
|
|
|
|
my $hReadMe;
|
|
|
|
my $strLine;
|
|
|
|
my $bMatch = false;
|
2015-08-07 20:43:53 +02:00
|
|
|
my $strChangeLogFile = abs_path(dirname($0) . '/../CHANGELOG.md');
|
2014-06-08 00:29:11 +03:00
|
|
|
|
2015-08-07 20:43:53 +02:00
|
|
|
if (!open($hReadMe, '<', $strChangeLogFile))
|
2014-06-08 00:29:11 +03:00
|
|
|
{
|
2015-08-07 20:43:53 +02:00
|
|
|
confess "unable to open ${strChangeLogFile}";
|
2014-06-08 00:29:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
while ($strLine = readline($hReadMe))
|
|
|
|
{
|
2015-08-07 20:43:53 +02:00
|
|
|
if ($strLine =~ /^\#\# v/)
|
2014-06-08 00:29:11 +03:00
|
|
|
{
|
2015-08-07 20:43:53 +02:00
|
|
|
$bMatch = substr($strLine, 4, length(BACKREST_VERSION)) eq BACKREST_VERSION;
|
2014-06-08 00:29:11 +03:00
|
|
|
last;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$bMatch)
|
|
|
|
{
|
2015-08-07 20:43:53 +02:00
|
|
|
confess 'unable to find version ' . BACKREST_VERSION . " as last revision in ${strChangeLogFile}";
|
2014-06-08 00:29:11 +03:00
|
|
|
}
|
|
|
|
|
2016-01-09 15:21:53 +02:00
|
|
|
eval
|
2014-08-11 04:22:17 +03:00
|
|
|
{
|
2016-01-09 15:21:53 +02:00
|
|
|
################################################################################################################################
|
|
|
|
# Define tests
|
|
|
|
################################################################################################################################
|
|
|
|
my $oTestDefinition =
|
|
|
|
{
|
|
|
|
module =>
|
|
|
|
[
|
|
|
|
# Help tests
|
|
|
|
{
|
|
|
|
name => 'help',
|
|
|
|
test =>
|
|
|
|
[
|
|
|
|
{
|
|
|
|
name => 'help'
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
# Config tests
|
|
|
|
{
|
|
|
|
name => 'config',
|
|
|
|
test =>
|
|
|
|
[
|
|
|
|
{
|
|
|
|
name => 'option'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'config'
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
# File tests
|
|
|
|
{
|
|
|
|
name => 'file',
|
|
|
|
test =>
|
|
|
|
[
|
|
|
|
{
|
|
|
|
name => 'path_create'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'move'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'compress'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'wait'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'manifest'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'list'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'remove'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'hash'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'exists'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'copy'
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
# Backup tests
|
|
|
|
{
|
|
|
|
name => 'backup',
|
|
|
|
test =>
|
|
|
|
[
|
|
|
|
{
|
|
|
|
name => 'archive-push',
|
|
|
|
total => 8
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'archive-stop',
|
|
|
|
total => 6
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'archive-get',
|
|
|
|
total => 8
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'expire',
|
|
|
|
total => 1
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'synthetic',
|
|
|
|
total => 8,
|
|
|
|
thread => true
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name => 'full',
|
|
|
|
total => 8,
|
2016-01-11 02:30:51 +02:00
|
|
|
thread => true,
|
|
|
|
db => true
|
2016-01-09 15:21:53 +02:00
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
};
|
2014-08-11 04:22:17 +03:00
|
|
|
|
2016-01-09 15:21:53 +02:00
|
|
|
my $oyTestRun = [];
|
2014-06-22 17:30:17 +03:00
|
|
|
|
2016-01-09 15:21:53 +02:00
|
|
|
################################################################################################################################
|
|
|
|
# Start VM and run
|
|
|
|
################################################################################################################################
|
|
|
|
if ($strOS ne 'none')
|
|
|
|
{
|
2016-01-15 02:37:06 +02:00
|
|
|
if (!$bDryRun)
|
|
|
|
{
|
2016-02-23 16:25:22 +02:00
|
|
|
# Run Perl critic
|
|
|
|
if (!$bNoLint)
|
|
|
|
{
|
|
|
|
my $strBasePath = dirname(dirname(abs_path($0)));
|
|
|
|
|
|
|
|
&log(INFO, "Performing static code analysis using perl -cW");
|
|
|
|
|
|
|
|
# Check the exe for warnings
|
|
|
|
my $strWarning = trim(executeTest("perl -cW ${strBasePath}/bin/pg_backrest 2>&1"));
|
|
|
|
|
|
|
|
if ($strWarning ne "${strBasePath}/bin/pg_backrest syntax OK")
|
|
|
|
{
|
|
|
|
confess &log(ERROR, "${strBasePath}/bin/pg_backrest failed syntax check:\n${strWarning}");
|
|
|
|
}
|
|
|
|
|
|
|
|
&log(INFO, "Performing static code analysis using perlcritic");
|
|
|
|
|
|
|
|
executeTest('perlcritic --quiet --verbose=8 --brutal --top=10' .
|
|
|
|
' --verbose "[%p] %f: %m at line %l, column %c. %e. (Severity: %s)\n"' .
|
|
|
|
" \"--profile=${strBasePath}/test/lint/perlcritic.policy\"" .
|
|
|
|
" ${strBasePath}/bin/pg_backrest ${strBasePath}/lib/*" .
|
|
|
|
" ${strBasePath}/test/test.pl ${strBasePath}/test/lib/*" .
|
|
|
|
" ${strBasePath}/doc/doc.pl ${strBasePath}/doc/lib/*");
|
|
|
|
}
|
|
|
|
|
2016-01-15 02:37:06 +02:00
|
|
|
logFileSet(cwd() . "/test");
|
|
|
|
}
|
|
|
|
|
2016-01-11 02:30:51 +02:00
|
|
|
my $oyVm = vmGet();
|
|
|
|
|
|
|
|
if ($strOS ne 'all' && !defined($${oyVm}{$strOS}))
|
|
|
|
{
|
|
|
|
confess &log(ERROR, "${strOS} is not a valid VM");
|
|
|
|
}
|
|
|
|
|
2016-01-09 15:21:53 +02:00
|
|
|
# Determine which tests to run
|
|
|
|
my $iTestsToRun = 0;
|
|
|
|
|
2016-01-11 02:30:51 +02:00
|
|
|
my $stryTestOS = [];
|
|
|
|
|
|
|
|
if ($strOS eq 'all')
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2016-01-11 02:30:51 +02:00
|
|
|
$stryTestOS = ['co6', 'u12', 'co7', 'u14'];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$stryTestOS = [$strOS];
|
|
|
|
}
|
2016-01-09 15:21:53 +02:00
|
|
|
|
2016-01-11 02:30:51 +02:00
|
|
|
foreach my $strTestOS (@{$stryTestOS})
|
|
|
|
{
|
|
|
|
foreach my $oModule (@{$$oTestDefinition{module}})
|
|
|
|
{
|
|
|
|
if ($strModule eq $$oModule{name} || $strModule eq 'all')
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2016-01-11 02:30:51 +02:00
|
|
|
foreach my $oTest (@{$$oModule{test}})
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2016-01-11 02:30:51 +02:00
|
|
|
if ($strModuleTest eq $$oTest{name} || $strModuleTest eq 'all')
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2016-01-11 02:30:51 +02:00
|
|
|
my $iDbVersionMin = -1;
|
|
|
|
my $iDbVersionMax = -1;
|
2016-01-09 15:21:53 +02:00
|
|
|
|
2016-01-11 02:30:51 +02:00
|
|
|
if (defined($$oTest{db}) && $$oTest{db})
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2016-01-11 02:30:51 +02:00
|
|
|
$iDbVersionMin = 0;
|
|
|
|
$iDbVersionMax = @{$$oyVm{$strTestOS}{db}} - 1;
|
2016-01-09 15:21:53 +02:00
|
|
|
}
|
|
|
|
|
2016-01-11 02:30:51 +02:00
|
|
|
my $bFirstDbVersion = true;
|
2016-01-09 15:21:53 +02:00
|
|
|
|
2016-01-11 02:30:51 +02:00
|
|
|
for (my $iDbVersionIdx = $iDbVersionMax; $iDbVersionIdx >= $iDbVersionMin; $iDbVersionIdx--)
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2016-01-11 02:30:51 +02:00
|
|
|
if ($iDbVersionIdx == -1 || $strDbVersion eq 'all' ||
|
|
|
|
($strDbVersion ne 'all' && $strDbVersion eq ${$$oyVm{$strTestOS}{db}}[$iDbVersionIdx]))
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2016-01-14 05:43:26 +02:00
|
|
|
my $iTestRunMin = defined($iModuleTestRun) ?
|
|
|
|
$iModuleTestRun : (defined($$oTest{total}) ? 1 : -1);
|
|
|
|
my $iTestRunMax = defined($iModuleTestRun) ?
|
|
|
|
$iModuleTestRun : (defined($$oTest{total}) ? $$oTest{total} : -1);
|
2016-01-11 02:30:51 +02:00
|
|
|
|
|
|
|
if (defined($$oTest{total}) && $iTestRunMax > $$oTest{total})
|
|
|
|
{
|
|
|
|
confess &log(ERROR, "invalid run - must be >= 1 and <= $$oTest{total}")
|
|
|
|
}
|
|
|
|
|
|
|
|
for (my $iTestRunIdx = $iTestRunMin; $iTestRunIdx <= $iTestRunMax; $iTestRunIdx++)
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2016-01-11 02:30:51 +02:00
|
|
|
my $iyThreadMax = [defined($iThreadMax) ? $iThreadMax : 1];
|
|
|
|
|
|
|
|
if (defined($$oTest{thread}) && $$oTest{thread} &&
|
|
|
|
!defined($iThreadMax) && $bFirstDbVersion)
|
|
|
|
{
|
|
|
|
$iyThreadMax = [1, 4];
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach my $iThreadTestMax (@{$iyThreadMax})
|
|
|
|
{
|
|
|
|
my $oTestRun =
|
|
|
|
{
|
|
|
|
os => $strTestOS,
|
|
|
|
module => $$oModule{name},
|
|
|
|
test => $$oTest{name},
|
|
|
|
run => $iTestRunIdx == -1 ? undef : $iTestRunIdx,
|
|
|
|
thread => $iThreadTestMax,
|
|
|
|
db => $iDbVersionIdx == -1 ? undef : ${$$oyVm{$strTestOS}{db}}[$iDbVersionIdx]
|
|
|
|
};
|
|
|
|
|
|
|
|
push(@{$oyTestRun}, $oTestRun);
|
|
|
|
$iTestsToRun++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$bFirstDbVersion = false;
|
2016-01-09 15:21:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($iTestsToRun == 0)
|
|
|
|
{
|
|
|
|
confess &log(ERROR, 'no tests were selected');
|
|
|
|
}
|
|
|
|
|
2016-01-16 06:22:30 +02:00
|
|
|
&log(INFO, $iTestsToRun . ' test' . ($iTestsToRun > 1 ? 's': '') . " selected\n");
|
|
|
|
|
|
|
|
if ($bNoCleanup && $iTestsToRun > 1)
|
|
|
|
{
|
|
|
|
confess &log(ERROR, '--no-cleanup is not valid when more than one test will run')
|
|
|
|
}
|
|
|
|
|
2016-01-09 15:21:53 +02:00
|
|
|
my $iTestFail = 0;
|
|
|
|
my $oyProcess = [];
|
|
|
|
|
2016-01-14 05:43:26 +02:00
|
|
|
if (!$bDryRun || $bVmOut)
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
|
|
|
for (my $iProcessIdx = 0; $iProcessIdx < 8; $iProcessIdx++)
|
|
|
|
{
|
|
|
|
# &log(INFO, "stop test-${iProcessIdx}");
|
|
|
|
push(@{$oyProcess}, undef);
|
|
|
|
executeTest("docker rm -f test-${iProcessIdx}", {bSuppressError => true});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-14 05:43:26 +02:00
|
|
|
if ($bDryRun)
|
|
|
|
{
|
|
|
|
$iProcessMax = 1;
|
|
|
|
}
|
|
|
|
|
2016-01-09 15:21:53 +02:00
|
|
|
my $iTestIdx = 0;
|
|
|
|
my $iProcessTotal;
|
|
|
|
my $iTestMax = @{$oyTestRun};
|
|
|
|
my $lStartTime = time();
|
2016-01-14 05:43:26 +02:00
|
|
|
my $bShowOutputAsync = $bVmOut && (@{$oyTestRun} == 1 || $iProcessMax == 1) && ! $bDryRun ? true : false;
|
2016-01-09 15:21:53 +02:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
$iProcessTotal = 0;
|
|
|
|
|
|
|
|
for (my $iProcessIdx = 0; $iProcessIdx < $iProcessMax; $iProcessIdx++)
|
|
|
|
{
|
|
|
|
if (defined($$oyProcess[$iProcessIdx]))
|
|
|
|
{
|
|
|
|
my $oExecDone = $$oyProcess[$iProcessIdx]{exec};
|
|
|
|
my $strTestDone = $$oyProcess[$iProcessIdx]{test};
|
|
|
|
my $iTestDoneIdx = $$oyProcess[$iProcessIdx]{idx};
|
|
|
|
|
|
|
|
my $iExitStatus = $oExecDone->end(undef, $iProcessMax == 1);
|
|
|
|
|
|
|
|
if (defined($iExitStatus))
|
|
|
|
{
|
2016-01-14 05:43:26 +02:00
|
|
|
if ($bShowOutputAsync)
|
|
|
|
{
|
|
|
|
syswrite(*STDOUT, "\n");
|
|
|
|
}
|
|
|
|
|
2016-01-09 15:21:53 +02:00
|
|
|
my $fTestElapsedTime = ceil((gettimeofday() - $$oyProcess[$iProcessIdx]{start_time}) * 100) / 100;
|
|
|
|
|
|
|
|
if (!($iExitStatus == 0 || $iExitStatus == 255))
|
|
|
|
{
|
|
|
|
&log(ERROR, "${strTestDone} (err${iExitStatus}-${fTestElapsedTime}s)" .
|
2016-01-14 05:43:26 +02:00
|
|
|
(defined($oExecDone->{strOutLog}) && !$bShowOutputAsync ?
|
|
|
|
":\n\n" . trim($oExecDone->{strOutLog}) . "\n" : ''), undef, undef, 4);
|
2016-01-09 15:21:53 +02:00
|
|
|
$iTestFail++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-01-14 05:43:26 +02:00
|
|
|
&log(INFO, "${strTestDone} (${fTestElapsedTime}s)".
|
|
|
|
($bVmOut && !$bShowOutputAsync ?
|
|
|
|
":\n\n" . trim($oExecDone->{strOutLog}) . "\n" : ''), undef, undef, 4);
|
2016-01-09 15:21:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!$bNoCleanup)
|
|
|
|
{
|
|
|
|
executeTest("docker rm -f test-${iProcessIdx}");
|
|
|
|
}
|
|
|
|
|
|
|
|
$$oyProcess[$iProcessIdx] = undef;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$iProcessTotal++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($iProcessTotal == $iProcessMax)
|
|
|
|
{
|
|
|
|
waitHiRes(.1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while ($iProcessTotal == $iProcessMax);
|
|
|
|
|
|
|
|
for (my $iProcessIdx = 0; $iProcessIdx < $iProcessMax; $iProcessIdx++)
|
|
|
|
{
|
|
|
|
if (!defined($$oyProcess[$iProcessIdx]) && $iTestIdx < @{$oyTestRun})
|
|
|
|
{
|
|
|
|
my $oTest = $$oyTestRun[$iTestIdx];
|
|
|
|
$iTestIdx++;
|
|
|
|
|
|
|
|
my $strTest = sprintf('P%0' . length($iProcessMax) . 'd-T%0' . length($iTestMax) . 'd/%0' .
|
|
|
|
length($iTestMax) . "d - ", $iProcessIdx, $iTestIdx, $iTestMax) .
|
|
|
|
"vm=$$oTest{os}, module=$$oTest{module}, test=$$oTest{test}" .
|
|
|
|
(defined($$oTest{run}) ? ", run=$$oTest{run}" : '') .
|
2016-01-11 02:30:51 +02:00
|
|
|
(defined($$oTest{thread}) ? ", thread-max=$$oTest{thread}" : '') .
|
|
|
|
(defined($$oTest{db}) ? ", db=$$oTest{db}" : '');
|
2016-01-09 15:21:53 +02:00
|
|
|
|
|
|
|
my $strImage = 'test-' . $iProcessIdx;
|
2016-01-23 01:01:21 +02:00
|
|
|
my $strDbVersion = (defined($$oTest{db}) ? $$oTest{db} : '9.4');
|
|
|
|
$strDbVersion =~ s/\.//;
|
2016-01-09 15:21:53 +02:00
|
|
|
|
2016-01-14 05:43:26 +02:00
|
|
|
&log($bDryRun && !$bVmOut || $bShowOutputAsync ? INFO : DEBUG, "${strTest}" .
|
|
|
|
($bVmOut || $bShowOutputAsync ? "\n" : ''));
|
2016-01-09 15:21:53 +02:00
|
|
|
|
2016-01-14 05:43:26 +02:00
|
|
|
if (!$bDryRun || $bVmOut)
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
|
|
|
executeTest("docker run -itd -h $$oTest{os}-test --name=${strImage}" .
|
2016-01-23 01:01:21 +02:00
|
|
|
" -v /backrest:/backrest backrest/$$oTest{os}-test-${strDbVersion}");
|
2016-01-09 15:21:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$strCommandLine =~ s/\-\-os\=\S*//g;
|
|
|
|
$strCommandLine =~ s/\-\-test-path\=\S*//g;
|
|
|
|
$strCommandLine =~ s/\-\-module\=\S*//g;
|
|
|
|
$strCommandLine =~ s/\-\-test\=\S*//g;
|
|
|
|
$strCommandLine =~ s/\-\-run\=\S*//g;
|
2016-01-11 02:30:51 +02:00
|
|
|
$strCommandLine =~ s/\-\-db\-version\=\S*//g;
|
2016-01-09 15:21:53 +02:00
|
|
|
|
|
|
|
my $strCommand = "docker exec -i -u vagrant ${strImage} $0 ${strCommandLine} --test-path=/home/vagrant/test" .
|
|
|
|
" --vm=none --module=$$oTest{module} --test=$$oTest{test}" .
|
|
|
|
(defined($$oTest{run}) ? " --run=$$oTest{run}" : '') .
|
|
|
|
(defined($$oTest{thread}) ? " --thread-max=$$oTest{thread}" : '') .
|
2016-01-11 02:30:51 +02:00
|
|
|
(defined($$oTest{db}) ? " --db-version=$$oTest{db}" : '') .
|
2016-01-14 05:43:26 +02:00
|
|
|
($bDryRun ? " --dry-run" : '') .
|
|
|
|
" --no-cleanup --vm-out";
|
2016-01-09 15:21:53 +02:00
|
|
|
|
|
|
|
&log(DEBUG, $strCommand);
|
|
|
|
|
2016-01-14 05:43:26 +02:00
|
|
|
if (!$bDryRun || $bVmOut)
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
|
|
|
my $fTestStartTime = gettimeofday();
|
2016-01-14 05:43:26 +02:00
|
|
|
my $oExec = new BackRestTest::Common::ExecuteTest(
|
|
|
|
$strCommand,
|
|
|
|
{bSuppressError => true, bShowOutputAsync => $bShowOutputAsync});
|
2016-01-09 15:21:53 +02:00
|
|
|
|
|
|
|
$oExec->begin();
|
|
|
|
|
|
|
|
my $oProcess =
|
|
|
|
{
|
|
|
|
exec => $oExec,
|
|
|
|
test => $strTest,
|
|
|
|
idx => $iTestIdx,
|
|
|
|
start_time => $fTestStartTime
|
|
|
|
};
|
|
|
|
|
|
|
|
$$oyProcess[$iProcessIdx] = $oProcess;
|
|
|
|
}
|
|
|
|
|
|
|
|
$iProcessTotal++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while ($iProcessTotal > 0);
|
|
|
|
|
2016-01-14 05:43:26 +02:00
|
|
|
if ($bDryRun)
|
|
|
|
{
|
|
|
|
&log(INFO, 'DRY RUN COMPLETED');
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
&log(INFO, 'TESTS COMPLETED ' . ($iTestFail == 0 ? 'SUCCESSFULLY' : "WITH ${iTestFail} FAILURE(S)") .
|
|
|
|
' (' . (time() - $lStartTime) . 's)');
|
|
|
|
}
|
2016-01-09 15:21:53 +02:00
|
|
|
|
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
################################################################################################################################
|
|
|
|
# Search for psql
|
|
|
|
################################################################################################################################
|
|
|
|
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")
|
|
|
|
{
|
2016-01-14 05:43:26 +02:00
|
|
|
&log(DEBUG, "FOUND pgsql-bin at ${strVersionPath}");
|
2016-01-09 15:21:53 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
################################################################################################################################
|
|
|
|
# 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;
|
2014-07-17 06:38:38 +03:00
|
|
|
|
2015-06-14 00:25:49 +02:00
|
|
|
do
|
2015-02-28 06:31:39 +02:00
|
|
|
{
|
2015-07-11 23:16:35 +02:00
|
|
|
if (BackRestTestCommon_Setup($strExe, $strTestPath, $stryTestVersion[0], $iModuleTestRun,
|
|
|
|
$bDryRun, $bNoCleanup, $bLogForce))
|
2015-06-14 00:25:49 +02:00
|
|
|
{
|
2016-01-14 05:43:26 +02:00
|
|
|
if (!$bVmOut &&
|
|
|
|
($strModule eq 'all' ||
|
|
|
|
$strModule eq 'backup' && $strModuleTest eq 'all' ||
|
|
|
|
$strModule eq 'backup' && $strModuleTest eq 'full'))
|
|
|
|
{
|
|
|
|
&log(INFO, "TESTING psql-bin = $stryTestVersion[0]\n");
|
|
|
|
}
|
2015-03-08 19:26:09 +02:00
|
|
|
|
2015-06-14 16:12:36 +02:00
|
|
|
if ($bInfinite)
|
|
|
|
{
|
|
|
|
$iRun++;
|
|
|
|
&log(INFO, "INFINITE - RUN ${iRun}\n");
|
|
|
|
}
|
2015-02-28 06:31:39 +02:00
|
|
|
|
2015-08-29 20:20:46 +02:00
|
|
|
# if ($strModule eq 'all' || $strModule eq 'ini')
|
|
|
|
# {
|
|
|
|
# BackRestTestIni_Test($strModuleTest);
|
|
|
|
# }
|
2015-06-14 00:25:49 +02:00
|
|
|
|
2015-09-08 18:58:13 +02:00
|
|
|
if ($strModule eq 'all' || $strModule eq 'help')
|
|
|
|
{
|
2016-01-14 05:43:26 +02:00
|
|
|
BackRestTestHelp_Test($strModuleTest, undef, $bVmOut);
|
2015-09-08 18:58:13 +02:00
|
|
|
}
|
|
|
|
|
2015-06-14 16:12:36 +02:00
|
|
|
if ($strModule eq 'all' || $strModule eq 'config')
|
|
|
|
{
|
2016-01-14 05:43:26 +02:00
|
|
|
BackRestTestConfig_Test($strModuleTest, undef, $bVmOut);
|
2015-06-14 16:12:36 +02:00
|
|
|
}
|
2015-04-03 04:07:23 +02:00
|
|
|
|
2015-06-14 16:12:36 +02:00
|
|
|
if ($strModule eq 'all' || $strModule eq 'file')
|
|
|
|
{
|
2016-01-14 05:43:26 +02:00
|
|
|
BackRestTestFile_Test($strModuleTest, undef, $bVmOut);
|
2015-06-14 16:12:36 +02:00
|
|
|
}
|
2015-06-14 00:25:49 +02:00
|
|
|
|
2015-06-14 16:12:36 +02:00
|
|
|
if ($strModule eq 'all' || $strModule eq 'backup')
|
2015-04-03 04:07:23 +02:00
|
|
|
{
|
2015-09-09 21:40:54 +02:00
|
|
|
if (!defined($iThreadMax) || $iThreadMax == 1)
|
|
|
|
{
|
2016-01-14 05:43:26 +02:00
|
|
|
BackRestTestBackup_Test($strModuleTest, 1, $bVmOut);
|
2015-09-09 21:40:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!defined($iThreadMax) || $iThreadMax > 1)
|
|
|
|
{
|
2016-01-14 05:43:26 +02:00
|
|
|
BackRestTestBackup_Test($strModuleTest, defined($iThreadMax) ? $iThreadMax : 4, $bVmOut);
|
2015-09-09 21:40:54 +02:00
|
|
|
}
|
2015-06-14 16:12:36 +02:00
|
|
|
|
|
|
|
if (@stryTestVersion > 1 && ($strModuleTest eq 'all' || $strModuleTest eq 'full'))
|
2015-06-14 00:25:49 +02:00
|
|
|
{
|
2015-06-14 16:12:36 +02:00
|
|
|
for (my $iVersionIdx = 1; $iVersionIdx < @stryTestVersion; $iVersionIdx++)
|
|
|
|
{
|
2015-07-12 04:47:22 +02:00
|
|
|
BackRestTestCommon_Setup($strExe, $strTestPath, $stryTestVersion[$iVersionIdx],
|
2015-06-14 16:12:36 +02:00
|
|
|
$iModuleTestRun, $bDryRun, $bNoCleanup);
|
|
|
|
&log(INFO, "TESTING psql-bin = $stryTestVersion[$iVersionIdx] for backup/full\n");
|
2016-01-14 05:43:26 +02:00
|
|
|
BackRestTestBackup_Test('full', defined($iThreadMax) ? $iThreadMax : 4, $bVmOut);
|
2015-06-14 16:12:36 +02:00
|
|
|
}
|
2015-06-14 00:25:49 +02:00
|
|
|
}
|
2015-04-03 04:07:23 +02:00
|
|
|
}
|
2015-06-14 00:25:49 +02:00
|
|
|
|
2015-06-14 16:12:36 +02:00
|
|
|
if ($strModule eq 'compare')
|
|
|
|
{
|
|
|
|
BackRestTestCompare_Test($strModuleTest);
|
|
|
|
}
|
2015-06-14 00:25:49 +02:00
|
|
|
}
|
2015-02-28 06:31:39 +02:00
|
|
|
}
|
2015-06-14 00:25:49 +02:00
|
|
|
while ($bInfinite);
|
|
|
|
};
|
2015-04-08 00:36:59 +02:00
|
|
|
|
2015-06-14 00:25:49 +02:00
|
|
|
if ($@)
|
|
|
|
{
|
|
|
|
my $oMessage = $@;
|
|
|
|
|
|
|
|
# If a backrest exception then return the code - don't confess
|
2015-08-29 20:20:46 +02:00
|
|
|
if (blessed($oMessage) && $oMessage->isa('BackRest::Common::Exception'))
|
2015-04-08 00:36:59 +02:00
|
|
|
{
|
2015-06-14 00:25:49 +02:00
|
|
|
syswrite(*STDOUT, $oMessage->trace());
|
|
|
|
exit $oMessage->code();
|
2015-04-08 00:36:59 +02:00
|
|
|
}
|
2015-06-14 00:25:49 +02:00
|
|
|
|
|
|
|
syswrite(*STDOUT, $oMessage);
|
2016-01-09 15:21:53 +02:00
|
|
|
exit 250;
|
2014-06-22 18:56:01 +03:00
|
|
|
}
|
2015-06-14 00:25:49 +02:00
|
|
|
|
2016-01-14 05:43:26 +02:00
|
|
|
if (!$bDryRun && !$bVmOut)
|
2014-07-16 05:32:41 +03:00
|
|
|
{
|
2015-01-11 18:52:16 +02:00
|
|
|
&log(INFO, 'TESTS COMPLETED SUCCESSFULLY (DESPITE ANY ERROR MESSAGES YOU SAW)');
|
2014-07-16 05:32:41 +03:00
|
|
|
}
|