You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-09-16 09:06:18 +02:00
Text execution improvements:
1) Tests for all operating systems can now be run with a single command. 2) Tests can be run in parallel with --process-max. 3) Container generation now integrated into test.pl 4) Some basic test documentation.
This commit is contained in:
@@ -184,7 +184,6 @@ if (@stryOutput == 0)
|
||||
if ($oManifest->isBackRest())
|
||||
{
|
||||
push(@stryOutput, 'help');
|
||||
push(@stryOutput, 'markdown');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +202,8 @@ for my $strOutput (@stryOutput)
|
||||
docProcess("${strBasePath}/xml/index.xml", "${strBasePath}/../README.md", $oManifest);
|
||||
docProcess("${strBasePath}/xml/change-log.xml", "${strBasePath}/../CHANGELOG.md", $oManifest);
|
||||
}
|
||||
elsif ($strOutput eq 'markdown')
|
||||
|
||||
if ($strOutput eq 'markdown')
|
||||
{
|
||||
my $oMarkdown =
|
||||
new BackRestDoc::Markdown::DocMarkdown
|
||||
|
@@ -198,6 +198,8 @@ sub sectionProcess
|
||||
|
||||
my $strMarkdown = '#' . ('#' x $iDepth) . ' ' . $self->processText($oSection->nodeGet('title')->textGet());
|
||||
|
||||
my $strLastChild = undef;
|
||||
|
||||
foreach my $oChild ($oSection->nodeList())
|
||||
{
|
||||
&log(DEBUG, (' ' x ($iDepth + 2)) . 'process child ' . $oChild->nameGet());
|
||||
@@ -288,14 +290,22 @@ sub sectionProcess
|
||||
# Add code block
|
||||
elsif ($oChild->nameGet() eq 'code-block')
|
||||
{
|
||||
# $oSectionBodyElement->
|
||||
# addNew(HTML_DIV, 'code-block',
|
||||
# {strContent => $oChild->valueGet()});
|
||||
if ($oChild->paramTest('title'))
|
||||
{
|
||||
$strMarkdown .= "\n\n_" . $oChild->paramGet('title') . "_:";
|
||||
}
|
||||
|
||||
$strMarkdown .= "\n```\n" . trim($oChild->valueGet()) . "\n```";
|
||||
}
|
||||
# Add descriptive text
|
||||
elsif ($oChild->nameGet() eq 'p')
|
||||
{
|
||||
$strMarkdown .= "\n\n" . $self->processText($oChild->textGet());
|
||||
if (defined($strLastChild) && $strLastChild ne 'code-block')
|
||||
{
|
||||
$strMarkdown .= "\n";
|
||||
}
|
||||
|
||||
$strMarkdown .= "\n" . $self->processText($oChild->textGet());
|
||||
}
|
||||
# Add option descriptive text
|
||||
elsif ($oChild->nameGet() eq 'option-description')
|
||||
@@ -342,6 +352,8 @@ sub sectionProcess
|
||||
{
|
||||
# $self->sectionChildProcess($oSection, $oChild, $iDepth + 1);
|
||||
}
|
||||
|
||||
$strLastChild = $oChild->nameGet();
|
||||
}
|
||||
|
||||
# Return from function and log return values if any
|
||||
|
@@ -29,6 +29,7 @@
|
||||
<source key="index"/>
|
||||
<source key="user-guide"/>
|
||||
<source key="reference" type="custom"/>
|
||||
<source key="test"/>
|
||||
</source-list>
|
||||
|
||||
<render-list>
|
||||
@@ -42,5 +43,9 @@
|
||||
<render type="pdf" file="{[pdf-file]}">
|
||||
<render-source key="user-guide"/>
|
||||
</render>
|
||||
|
||||
<render type="markdown">
|
||||
<render-source key="test" file="../../../test/README.md"/>
|
||||
</render>
|
||||
</render-list>
|
||||
</doc>
|
||||
|
60
doc/xml/test.xml
Normal file
60
doc/xml/test.xml
Normal file
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE doc SYSTEM "doc.dtd">
|
||||
<doc subtitle="Regression, Unit, & Integration Testing" toc="y">
|
||||
|
||||
<section id="introduction">
|
||||
<title>Introduction</title>
|
||||
|
||||
<p><backrest/> uses Docker to run tests and generate documentation. Docker's light-weight virualization provides the a good balance between proper OS emulation and performance (especially startup)</p>
|
||||
|
||||
<p>A `Vagrantfile` is provided that contains the complete configuration required to run <backrest/> tests and build documentation. If Vagrant is not suitable then the `Vagrantfile` still contains the configuration steps required to build a test system.</p>
|
||||
|
||||
<p>Note that this is not required for normal operation of <backrest/>.</p>
|
||||
</section>
|
||||
|
||||
<section id="testing">
|
||||
<title>Testing</title>
|
||||
|
||||
<p>The easiest way to start testing <backrest/> is with the included `Vagrantfile`.</p>
|
||||
|
||||
<code-block title="Build Vagrant and Logon">
|
||||
cd test
|
||||
vagrant up
|
||||
vagrant ssh
|
||||
</code-block>
|
||||
|
||||
<p>The <code>vagrant up</code> step could take some time as a number of Docker containers must also be built. The <code>vagrant up</code> command automatically logs onto the VM.</p>
|
||||
|
||||
<code-block title="Run All Tests">
|
||||
/backrest/test/test.pl
|
||||
</code-block>
|
||||
|
||||
<code-block title="Run Tests for a Specific OS">
|
||||
/backrest/test/test.pl --vm=co6
|
||||
</code-block>
|
||||
|
||||
<code-block title="Run Tests for a Specific OS and Module">
|
||||
/backrest/test/test.pl --vm=co6 --module=backup
|
||||
</code-block>
|
||||
|
||||
<code-block title="Run Tests for a Specific OS, Module, and Test">
|
||||
/backrest/test/test.pl --vm=co6 --module=backup --full
|
||||
</code-block>
|
||||
|
||||
<code-block title="Run Tests for a Specific OS, Module, Test, and Thread Max">
|
||||
/backrest/test/test.pl --vm=co6 --module=backup --full --thread-max=4
|
||||
</code-block>
|
||||
|
||||
<p>Note that thread-max is only applicable to the <id>synthetic</id> and <id>full</id> tests in the <id>backup</id> module.</p>
|
||||
|
||||
<code-block title="Run Tests for a Specific OS, Module, Test, Thread Max, and Database Version">
|
||||
/backrest/test/test.pl --vm=co6 --module=backup --full --thread-max=4 --db-version=9.4
|
||||
</code-block>
|
||||
|
||||
<p>Note that db-version is only applicable to the <id>full</id> test in the <id>backup</id> module.</p>
|
||||
|
||||
<code-block title="Iterate All Possible Test Combinations">
|
||||
/backrest/test/test.pl --dry-run
|
||||
</code-block>
|
||||
</section>
|
||||
</doc>
|
@@ -425,6 +425,7 @@ sub log
|
||||
my $strMessage = shift;
|
||||
my $iCode = shift;
|
||||
my $bSuppressLog = shift;
|
||||
my $iIndent = shift;
|
||||
|
||||
# Set defaults
|
||||
$bSuppressLog = defined($bSuppressLog) ? $bSuppressLog : false;
|
||||
@@ -459,7 +460,15 @@ sub log
|
||||
$strMessageFormat = (defined($iCode) ? "[${iCode}]: " : '') . $strMessageFormat;
|
||||
|
||||
# Indent subsequent lines of the message if it has more than one line - makes the log more readable
|
||||
$strMessageFormat =~ s/\n/\n /g;
|
||||
if (defined($iIndent))
|
||||
{
|
||||
my $strIndent = ' ' x $iIndent;
|
||||
$strMessageFormat =~ s/\n/\n${strIndent}/g;
|
||||
}
|
||||
else
|
||||
{
|
||||
$strMessageFormat =~ s/\n/\n /g;
|
||||
}
|
||||
|
||||
if ($strLevel eq TRACE || $strLevel eq TEST)
|
||||
{
|
||||
|
@@ -251,7 +251,7 @@ sub lineRead
|
||||
$self->waitPid();
|
||||
|
||||
# Only error if reading from the input stream
|
||||
if (!defined($bInRead) || $bInRead)
|
||||
if (defined($bError) && $bError)
|
||||
{
|
||||
confess &log(ERROR, "unexpected EOF", ERROR_FILE_READ);
|
||||
}
|
||||
@@ -297,7 +297,8 @@ sub lineRead
|
||||
}
|
||||
|
||||
# Return the line that was found and adjust the buffer position
|
||||
my $strLine = substr($self->{strBuffer}, $self->{iBufferPos}, $iLineFeedPos - $self->{iBufferPos});
|
||||
my $strLine = $iLineFeedPos - $self->{iBufferPos} == 0 ? '' :
|
||||
substr($self->{strBuffer}, $self->{iBufferPos}, $iLineFeedPos - $self->{iBufferPos});
|
||||
$self->{iBufferPos} = $iLineFeedPos + 1;
|
||||
|
||||
return $strLine;
|
||||
|
58
test/README.md
Normal file
58
test/README.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# pgBackRest - Regression, Unit, & Integration Testing
|
||||
|
||||
## Introduction
|
||||
|
||||
pgBackRest uses Docker to run tests and generate documentation. Docker's light-weight virualization provides the a good balance between proper OS emulation and performance (especially startup)
|
||||
|
||||
A `Vagrantfile` is provided that contains the complete configuration required to run pgBackRest tests and build documentation. If Vagrant is not suitable then the `Vagrantfile` still contains the configuration steps required to build a test system.
|
||||
|
||||
Note that this is not required for normal operation of pgBackRest.
|
||||
|
||||
## Testing
|
||||
|
||||
The easiest way to start testing pgBackRest is with the included `Vagrantfile`.
|
||||
|
||||
_Build Vagrant and Logon_:
|
||||
```
|
||||
cd test
|
||||
vagrant up
|
||||
vagrant ssh
|
||||
```
|
||||
The `vagrant up` step could take some time as a number of Docker containers must also be built. The `vagrant up` command automatically logs onto the VM.
|
||||
|
||||
_Run All Tests_:
|
||||
```
|
||||
/backrest/test/test.pl
|
||||
```
|
||||
|
||||
_Run Tests for a Specific OS_:
|
||||
```
|
||||
/backrest/test/test.pl --vm=co6
|
||||
```
|
||||
|
||||
_Run Tests for a Specific OS and Module_:
|
||||
```
|
||||
/backrest/test/test.pl --vm=co6 --module=backup
|
||||
```
|
||||
|
||||
_Run Tests for a Specific OS, Module, and Test_:
|
||||
```
|
||||
/backrest/test/test.pl --vm=co6 --module=backup --full
|
||||
```
|
||||
|
||||
_Run Tests for a Specific OS, Module, Test, and Thread Max_:
|
||||
```
|
||||
/backrest/test/test.pl --vm=co6 --module=backup --full --thread-max=4
|
||||
```
|
||||
Note that thread-max is only applicable to the `synthetic` and `full` tests in the `backup` module.
|
||||
|
||||
_Run Tests for a Specific OS, Module, Test, Thread Max, and Database Version_:
|
||||
```
|
||||
/backrest/test/test.pl --vm=co6 --module=backup --full --thread-max=4 --db-version=9.4
|
||||
```
|
||||
Note that db-version is only applicable to the `full` test in the `backup` module.
|
||||
|
||||
_Iterate All Possible Test Combinations_:
|
||||
```
|
||||
/backrest/test/test.pl --dry-run
|
||||
```
|
4
test/Vagrantfile
vendored
4
test/Vagrantfile
vendored
@@ -30,8 +30,8 @@ Vagrant.configure(2) do |config|
|
||||
/usr/local/texlive/2015/bin/x86_64-linux/tlmgr install caption xcolor listings parskip helvetic ltablex titlesec \
|
||||
epstopdf courier sectsty pgf ms
|
||||
|
||||
# Build docker images
|
||||
/backrest/test/container.pl
|
||||
# Build vm images
|
||||
/backrest/test/test.pl --vm-build
|
||||
SHELL
|
||||
|
||||
# Don't share the default vagrant folder
|
||||
|
@@ -21,6 +21,7 @@ use Symbol 'gensym';
|
||||
use lib dirname($0) . '/../lib';
|
||||
use BackRest::Common::Log;
|
||||
use BackRest::Common::Wait;
|
||||
use BackRest::Protocol::IO;
|
||||
|
||||
####################################################################################################################################
|
||||
# Operation constants
|
||||
@@ -121,6 +122,9 @@ sub begin
|
||||
|
||||
$self->{pId} = open3(undef, $self->{hOut}, $self->{hError}, $self->{strCommand});
|
||||
|
||||
# Create select objects
|
||||
$self->{oIO} = new BackRest::Protocol::IO($self->{hOut}, undef, $self->{hError}, undef, 30, 65536);
|
||||
|
||||
if (!defined($self->{hError}))
|
||||
{
|
||||
confess 'STDERR handle is undefined';
|
||||
@@ -138,67 +142,67 @@ sub endRetry
|
||||
my
|
||||
(
|
||||
$strOperation,
|
||||
$strTest
|
||||
$strTest,
|
||||
$bWait
|
||||
) =
|
||||
logDebugParam
|
||||
(
|
||||
OP_EXECUTE_TEST_END_RETRY, \@_,
|
||||
{name => 'strTest', required => false, trace => true}
|
||||
{name => 'strTest', required => false, trace => true},
|
||||
{name => 'bWait', required => false, default => true, trace => true}
|
||||
);
|
||||
|
||||
# Create select objects
|
||||
my $oErrorSelect = IO::Select->new();
|
||||
$oErrorSelect->add($self->{hError});
|
||||
my $oOutSelect = IO::Select->new();
|
||||
$oOutSelect->add($self->{hOut});
|
||||
|
||||
# Drain the output and error streams and look for test points
|
||||
# my $iWait = $bWait ? .05 : 0;
|
||||
|
||||
while(waitpid($self->{pId}, WNOHANG) == 0)
|
||||
{
|
||||
# Drain the stderr stream
|
||||
if ($oErrorSelect->can_read(0))
|
||||
my $bFound = false;
|
||||
# # Drain the stderr stream
|
||||
# !!! This is a good idea but can only be done with the IO object has separate buffers for stdin and stderr
|
||||
# while (my $strLine = $self->{oIO}->lineRead(0, false, false))
|
||||
# {
|
||||
# $bFound = true;
|
||||
# $self->{strErrorLog} .= "$strLine\n";
|
||||
# }
|
||||
|
||||
# Drain the stdout stream and look for test points
|
||||
while (defined(my $strLine = $self->{oIO}->lineRead(0, true, false)))
|
||||
{
|
||||
while (my $strLine = readline($self->{hError}))
|
||||
$self->{strOutLog} .= "$strLine\n";
|
||||
$bFound = true;
|
||||
|
||||
if (defined($strTest) && testCheck($strLine, $strTest))
|
||||
{
|
||||
$self->{strErrorLog} .= $strLine;
|
||||
&log(DEBUG, "Found test ${strTest}");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
# Drain the stdout stream and look for test points
|
||||
if ($oOutSelect->can_read(.05))
|
||||
if (!$bWait)
|
||||
{
|
||||
while (my $strLine = readline($self->{hOut}))
|
||||
{
|
||||
$self->{strOutLog} .= $strLine;
|
||||
return undef;
|
||||
}
|
||||
|
||||
if (defined($strTest) && testCheck($strLine, $strTest))
|
||||
{
|
||||
&log(DEBUG, "Found test ${strTest}");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!$bFound)
|
||||
{
|
||||
waitHiRes(.05);
|
||||
}
|
||||
}
|
||||
|
||||
# Check the exit status
|
||||
my $iExitStatus = ${^CHILD_ERROR_NATIVE} >> 8;
|
||||
|
||||
# Drain the stderr stream
|
||||
if ($oErrorSelect->can_read(0))
|
||||
# Drain the stdout stream
|
||||
while (defined(my $strLine = $self->{oIO}->lineRead(0, true, false)))
|
||||
{
|
||||
while (my $strLine = readline($self->{hError}))
|
||||
{
|
||||
$self->{strErrorLog} .= $strLine;
|
||||
}
|
||||
$self->{strOutLog} .= "$strLine\n";
|
||||
}
|
||||
|
||||
# Drain the stdout stream
|
||||
if ($oOutSelect->can_read(0))
|
||||
# Drain the stderr stream
|
||||
while (defined(my $strLine = $self->{oIO}->lineRead(0, false, false)))
|
||||
{
|
||||
while (my $strLine = readline($self->{hOut}))
|
||||
{
|
||||
$self->{strOutLog} .= $strLine;
|
||||
}
|
||||
$self->{strErrorLog} .= "$strLine\n";
|
||||
}
|
||||
|
||||
# Pass the log to the LogTest object
|
||||
@@ -278,12 +282,14 @@ sub end
|
||||
my
|
||||
(
|
||||
$strOperation,
|
||||
$strTest
|
||||
$strTest,
|
||||
$bWait
|
||||
) =
|
||||
logDebugParam
|
||||
(
|
||||
OP_EXECUTE_TEST_END, \@_,
|
||||
{name => 'strTest', required => false}
|
||||
{name => 'strTest', required => false, trace => true},
|
||||
{name => 'bWait', required => false, default => true, trace => true}
|
||||
);
|
||||
|
||||
# If retry is not defined then run endRetry() one time
|
||||
@@ -291,7 +297,7 @@ sub end
|
||||
|
||||
if (!defined($self->{iRetrySeconds}))
|
||||
{
|
||||
$iExitStatus = $self->endRetry($strTest);
|
||||
$iExitStatus = $self->endRetry($strTest, $bWait);
|
||||
}
|
||||
# Else loop until success or timeout
|
||||
else
|
||||
@@ -302,7 +308,7 @@ sub end
|
||||
{
|
||||
$self->{bRetry} = false;
|
||||
$self->begin();
|
||||
$iExitStatus = $self->endRetry($strTest);
|
||||
$iExitStatus = $self->endRetry($strTest, $bWait);
|
||||
|
||||
if ($self->{bRetry})
|
||||
{
|
||||
@@ -314,7 +320,7 @@ sub end
|
||||
if ($self->{bRetry})
|
||||
{
|
||||
$self->begin();
|
||||
$iExitStatus = $self->endRetry($strTest);
|
||||
$iExitStatus = $self->endRetry($strTest, $bWait);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -258,10 +258,13 @@ sub BackRestTestConfig_Test
|
||||
#-------------------------------------------------------------------------------------------------------------------------------
|
||||
# Test command-line options
|
||||
#-------------------------------------------------------------------------------------------------------------------------------
|
||||
if ($strTest eq 'all' || $strTest eq 'option')
|
||||
my $strThisTest = 'option';
|
||||
|
||||
if ($strTest eq 'all' || $strTest eq $strThisTest)
|
||||
{
|
||||
$iRun = 0;
|
||||
&log(INFO, "Option module\n");
|
||||
|
||||
&log(INFO, "Test ${strThisTest}\n");
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'backup with no stanza'))
|
||||
{
|
||||
@@ -543,10 +546,13 @@ sub BackRestTestConfig_Test
|
||||
#-------------------------------------------------------------------------------------------------------------------------------
|
||||
# Test mixed command-line/config
|
||||
#-------------------------------------------------------------------------------------------------------------------------------
|
||||
if ($strTest eq 'all' || $strTest eq 'config')
|
||||
$strThisTest = 'config';
|
||||
|
||||
if ($strTest eq 'all' || $strTest eq $strThisTest)
|
||||
{
|
||||
$iRun = 0;
|
||||
&log(INFO, "Config module\n");
|
||||
|
||||
&log(INFO, "Test ${strThisTest}\n");
|
||||
|
||||
BackRestTestCommon_Create();
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/perl
|
||||
####################################################################################################################################
|
||||
# container.pl - Build docker containers for testing and documentation
|
||||
# Container.pm - Build docker containers for testing and documentation
|
||||
####################################################################################################################################
|
||||
package BackRestTest::Docker::Container;
|
||||
|
||||
####################################################################################################################################
|
||||
# Perl includes
|
||||
@@ -10,112 +10,18 @@ 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 Cwd qw(abs_path);
|
||||
use Exporter qw(import);
|
||||
our @EXPORT = qw();
|
||||
use File::Basename qw(dirname);
|
||||
use Getopt::Long qw(GetOptions);
|
||||
use Scalar::Util qw(blessed);
|
||||
# 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::Ini;
|
||||
use BackRest::Common::Log;
|
||||
use BackRest::FileCommon;
|
||||
# use BackRest::Db;
|
||||
|
||||
use lib dirname($0) . '/lib';
|
||||
use BackRestTest::Common::ExecuteTest;
|
||||
# use BackRestTest::CommonTest;
|
||||
# use BackRestTest::CompareTest;
|
||||
# use BackRestTest::ConfigTest;
|
||||
# use BackRestTest::FileTest;
|
||||
# use BackRestTest::HelpTest;
|
||||
|
||||
####################################################################################################################################
|
||||
# Usage
|
||||
####################################################################################################################################
|
||||
|
||||
=head1 NAME
|
||||
|
||||
container.pl - Docker Container Build
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
container.pl [options]
|
||||
|
||||
Build Options:
|
||||
--os os to build (defaults to all)
|
||||
|
||||
Configuration Options:
|
||||
--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 $bVersion = false;
|
||||
my $bHelp = false;
|
||||
my $bQuiet = false;
|
||||
|
||||
GetOptions ('q|quiet' => \$bQuiet,
|
||||
'version' => \$bVersion,
|
||||
'help' => \$bHelp,
|
||||
'log-level=s' => \$strLogLevel)
|
||||
or pod2usage(2);
|
||||
|
||||
# Display version and exit if requested
|
||||
if ($bVersion || $bHelp)
|
||||
{
|
||||
syswrite(*STDOUT, 'pgBackRest ' . BACKREST_VERSION . " Docker Container Build\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);
|
||||
|
||||
# Set console log level
|
||||
if ($bQuiet)
|
||||
{
|
||||
$strLogLevel = 'off';
|
||||
}
|
||||
|
||||
logLevelSet(undef, uc($strLogLevel));
|
||||
|
||||
# Create temp path
|
||||
my $strTempPath = dirname(abs_path($0)) . '/.vagrant/docker';
|
||||
|
||||
if (!-e $strTempPath)
|
||||
{
|
||||
mkdir $strTempPath
|
||||
or confess &log(ERROR, "unable to create ${strTempPath}");
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# Valid OS list
|
||||
@@ -285,8 +191,17 @@ sub perlInstall
|
||||
####################################################################################################################################
|
||||
# Build containers
|
||||
####################################################################################################################################
|
||||
eval
|
||||
sub containerBuild
|
||||
{
|
||||
# Create temp path
|
||||
my $strTempPath = dirname(abs_path($0)) . '/.vagrant/docker';
|
||||
|
||||
if (!-e $strTempPath)
|
||||
{
|
||||
mkdir $strTempPath
|
||||
or confess &log(ERROR, "unable to create ${strTempPath}");
|
||||
}
|
||||
|
||||
# Create SSH key (if it does not already exist)
|
||||
if (-e "${strTempPath}/id_rsa")
|
||||
{
|
||||
@@ -296,7 +211,7 @@ eval
|
||||
{
|
||||
&log(INFO, "Building SSH keys...");
|
||||
|
||||
executeTest("ssh-keygen -f ${strTempPath}/id_rsa -t rsa -b 768 -N ''");
|
||||
executeTest("ssh-keygen -f ${strTempPath}/id_rsa -t rsa -b 768 -N ''", {bSuppressStdErr => true});
|
||||
}
|
||||
|
||||
foreach my $strOS (@stryOS)
|
||||
@@ -337,7 +252,9 @@ eval
|
||||
}
|
||||
elsif ($strOS eq OS_U12 || $strOS eq OS_U14)
|
||||
{
|
||||
$strImage .= "RUN apt-get -y install openssh-server\n";
|
||||
$strImage .=
|
||||
"RUN apt-get update\n" .
|
||||
"RUN apt-get -y install openssh-server\n";
|
||||
}
|
||||
|
||||
$strImage .=
|
||||
@@ -441,7 +358,8 @@ eval
|
||||
|
||||
# Write the image
|
||||
fileStringWrite("${strTempPath}/${strImageName}", "$strImage\n", false);
|
||||
executeTest("docker build -f ${strTempPath}/${strImageName} -t backrest/${strImageName} ${strTempPath}");
|
||||
executeTest("docker build -f ${strTempPath}/${strImageName} -t backrest/${strImageName} ${strTempPath}",
|
||||
{bSuppressStdErr => true});
|
||||
|
||||
# Db image
|
||||
###########################################################################################################################
|
||||
@@ -512,7 +430,9 @@ eval
|
||||
|
||||
# Write the image
|
||||
fileStringWrite("${strTempPath}/${strImageName}", "${strImage}\n", false);
|
||||
executeTest("docker build -f ${strTempPath}/${strImageName} -t backrest/${strImageName} ${strTempPath}");
|
||||
executeTest("docker build -f ${strTempPath}/${strImageName} -t backrest/${strImageName} ${strTempPath}",
|
||||
{bSuppressStdErr => true});
|
||||
|
||||
|
||||
# Db Doc image
|
||||
###########################################################################################################################
|
||||
@@ -527,7 +447,9 @@ eval
|
||||
|
||||
# Write the image
|
||||
fileStringWrite("${strTempPath}/${strImageName}", "${strImage}\n", false);
|
||||
executeTest("docker build -f ${strTempPath}/${strImageName} -t backrest/${strImageName} ${strTempPath}");
|
||||
executeTest("docker build -f ${strTempPath}/${strImageName} -t backrest/${strImageName} ${strTempPath}",
|
||||
{bSuppressStdErr => true});
|
||||
|
||||
|
||||
# Backup image
|
||||
###########################################################################################################################
|
||||
@@ -545,7 +467,9 @@ eval
|
||||
|
||||
# Write the image
|
||||
fileStringWrite("${strTempPath}/${strImageName}", "${strImage}\n", false);
|
||||
executeTest("docker build -f ${strTempPath}/${strImageName} -t backrest/${strImageName} ${strTempPath}");
|
||||
executeTest("docker build -f ${strTempPath}/${strImageName} -t backrest/${strImageName} ${strTempPath}",
|
||||
{bSuppressStdErr => true});
|
||||
|
||||
|
||||
# Backup Doc image
|
||||
###########################################################################################################################
|
||||
@@ -568,7 +492,9 @@ eval
|
||||
|
||||
# Write the image
|
||||
fileStringWrite("${strTempPath}/${strImageName}", "${strImage}\n", false);
|
||||
executeTest("docker build -f ${strTempPath}/${strImageName} -t backrest/${strImageName} ${strTempPath}");
|
||||
executeTest("docker build -f ${strTempPath}/${strImageName} -t backrest/${strImageName} ${strTempPath}",
|
||||
{bSuppressStdErr => true});
|
||||
|
||||
|
||||
# Test image
|
||||
###########################################################################################################################
|
||||
@@ -605,21 +531,12 @@ eval
|
||||
|
||||
# Write the image
|
||||
fileStringWrite("${strTempPath}/${strImageName}", "${strImage}\n", false);
|
||||
executeTest("docker build -f ${strTempPath}/${strImageName} -t backrest/${strImageName} ${strTempPath}");
|
||||
executeTest("docker build -f ${strTempPath}/${strImageName} -t backrest/${strImageName} ${strTempPath}",
|
||||
{bSuppressStdErr => true});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
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;;
|
||||
}
|
||||
|
||||
push @EXPORT, qw(containerBuild);
|
||||
|
||||
1;
|
510
test/test.pl
510
test/test.pl
@@ -17,11 +17,15 @@ use File::Basename qw(dirname);
|
||||
use Getopt::Long qw(GetOptions);
|
||||
use Cwd qw(abs_path);
|
||||
use Pod::Usage qw(pod2usage);
|
||||
use POSIX qw(ceil);
|
||||
use Time::HiRes qw(gettimeofday);
|
||||
use Scalar::Util qw(blessed);
|
||||
|
||||
use lib dirname($0) . '/../lib';
|
||||
use BackRest::Common::Ini;
|
||||
use BackRest::Common::Log;
|
||||
use BackRest::Common::String;
|
||||
use BackRest::Common::Wait;
|
||||
use BackRest::Db;
|
||||
|
||||
use lib dirname($0) . '/lib';
|
||||
@@ -30,9 +34,9 @@ use BackRestTest::Common::ExecuteTest;
|
||||
use BackRestTest::CommonTest;
|
||||
use BackRestTest::CompareTest;
|
||||
use BackRestTest::ConfigTest;
|
||||
use BackRestTest::Docker::Container;
|
||||
use BackRestTest::FileTest;
|
||||
use BackRestTest::HelpTest;
|
||||
# use BackRestTest::IniTest;
|
||||
|
||||
####################################################################################################################################
|
||||
# Usage
|
||||
@@ -47,7 +51,7 @@ test.pl - pgBackRest Unit Tests
|
||||
test.pl [options]
|
||||
|
||||
Test Options:
|
||||
--module test module to execute:
|
||||
--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)
|
||||
@@ -58,12 +62,18 @@ test.pl [options]
|
||||
--log-force force overwrite of current test log files
|
||||
|
||||
Configuration Options:
|
||||
--exe backup executable
|
||||
--exe pgBackRest 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
|
||||
|
||||
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)
|
||||
|
||||
General Options:
|
||||
--version display version and exit
|
||||
--help display usage and exit
|
||||
@@ -73,11 +83,13 @@ test.pl [options]
|
||||
# Command line parameters
|
||||
####################################################################################################################################
|
||||
my $strLogLevel = 'info';
|
||||
my $strOS = undef;
|
||||
my $strOS = 'all';
|
||||
my $bVmOut = false;
|
||||
my $strModule = 'all';
|
||||
my $strModuleTest = 'all';
|
||||
my $iModuleTestRun = undef;
|
||||
my $iThreadMax = undef;
|
||||
my $iProcessMax = 1;
|
||||
my $bDryRun = false;
|
||||
my $bNoCleanup = false;
|
||||
my $strPgSqlBin;
|
||||
@@ -89,6 +101,7 @@ my $bQuiet = false;
|
||||
my $bInfinite = false;
|
||||
my $strDbVersion = 'all';
|
||||
my $bLogForce = false;
|
||||
my $bVmBuild = false;
|
||||
|
||||
my $strCommandLine = join(' ', @ARGV);
|
||||
|
||||
@@ -99,11 +112,14 @@ GetOptions ('q|quiet' => \$bQuiet,
|
||||
'exes=s' => \$strExe,
|
||||
'test-path=s' => \$strTestPath,
|
||||
'log-level=s' => \$strLogLevel,
|
||||
'os=s' => \$strOS,
|
||||
'vm=s' => \$strOS,
|
||||
'vm-out' => \$bVmOut,
|
||||
'vm-build' => \$bVmBuild,
|
||||
'module=s' => \$strModule,
|
||||
'test=s' => \$strModuleTest,
|
||||
'run=s' => \$iModuleTestRun,
|
||||
'thread-max=s' => \$iThreadMax,
|
||||
'process-max=s' => \$iProcessMax,
|
||||
'dry-run' => \$bDryRun,
|
||||
'no-cleanup' => \$bNoCleanup,
|
||||
'infinite' => \$bInfinite,
|
||||
@@ -131,27 +147,6 @@ if (@ARGV > 0)
|
||||
pod2usage();
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# Start OS VM and run
|
||||
####################################################################################################################################
|
||||
if (defined($strOS))
|
||||
{
|
||||
executeTest("docker rm -f ${strOS}-test", {bSuppressError => true});
|
||||
executeTest("docker run -itd -h ${strOS}-test --name=${strOS}-test -v /backrest:/backrest backrest/${strOS}-test");
|
||||
|
||||
$strCommandLine =~ s/\-\-os\=\S*//g;
|
||||
$strCommandLine =~ s/\-\-test-path\=\S*//g;
|
||||
|
||||
system("docker exec -it -u vagrant ${strOS}-test $0 ${strCommandLine} --test-path=/home/vagrant/test");
|
||||
|
||||
if (!$bNoCleanup)
|
||||
{
|
||||
executeTest("docker rm -f ${strOS}-test");
|
||||
}
|
||||
|
||||
exit 0;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# Setup
|
||||
####################################################################################################################################
|
||||
@@ -181,55 +176,21 @@ 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';
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# Build Docker containers
|
||||
####################################################################################################################################
|
||||
if ($bVmBuild)
|
||||
{
|
||||
containerBuild();
|
||||
exit 0;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# Make sure version number matches in the change log.
|
||||
####################################################################################################################################
|
||||
@@ -257,28 +218,396 @@ 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
|
||||
{
|
||||
################################################################################################################################
|
||||
# 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,
|
||||
thread => true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
my $oyTestRun = [];
|
||||
|
||||
################################################################################################################################
|
||||
# Start VM and run
|
||||
################################################################################################################################
|
||||
if ($strOS ne 'none')
|
||||
{
|
||||
# Determine which tests to run
|
||||
my $iTestsToRun = 0;
|
||||
|
||||
foreach my $oModule (@{$$oTestDefinition{module}})
|
||||
{
|
||||
if ($strModule eq $$oModule{name} || $strModule eq 'all')
|
||||
{
|
||||
&log(DEBUG, "Select Module $$oModule{name}");
|
||||
|
||||
foreach my $oTest (@{$$oModule{test}})
|
||||
{
|
||||
if ($strModuleTest eq $$oTest{name} || $strModuleTest eq 'all')
|
||||
{
|
||||
&log(DEBUG, " Select Test $$oTest{name}");
|
||||
|
||||
my $iTestRunMin = defined($iModuleTestRun) ? $iModuleTestRun : (defined($$oTest{total}) ? 1 : -1);
|
||||
my $iTestRunMax = defined($iModuleTestRun) ? $iModuleTestRun : (defined($$oTest{total}) ? $$oTest{total} : -1);
|
||||
|
||||
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++)
|
||||
{
|
||||
&log(DEBUG, " Select Run $iTestRunIdx");
|
||||
|
||||
my $stryTestOS = [];
|
||||
|
||||
if ($strOS eq 'all')
|
||||
{
|
||||
$stryTestOS = ['u12', 'u14', 'co6', 'co7'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$stryTestOS = [$strOS];
|
||||
}
|
||||
|
||||
my $iyThreadMax = [defined($iThreadMax) ? $iThreadMax : 1];
|
||||
|
||||
if (defined($$oTest{thread}) && $$oTest{thread} && !defined($iThreadMax))
|
||||
{
|
||||
$iyThreadMax = [1, 4];
|
||||
}
|
||||
|
||||
foreach my $iThreadTestMax (@{$iyThreadMax})
|
||||
{
|
||||
foreach my $strTestOS (@{$stryTestOS})
|
||||
{
|
||||
my $oTestRun =
|
||||
{
|
||||
os => $strTestOS,
|
||||
module => $$oModule{name},
|
||||
test => $$oTest{name},
|
||||
run => $iTestRunIdx == -1 ? undef : $iTestRunIdx,
|
||||
thread => $iThreadTestMax
|
||||
};
|
||||
|
||||
push(@{$oyTestRun}, $oTestRun);
|
||||
$iTestsToRun++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($iTestsToRun == 0)
|
||||
{
|
||||
confess &log(ERROR, 'no tests were selected');
|
||||
}
|
||||
|
||||
my $iTestFail = 0;
|
||||
my $oyProcess = [];
|
||||
|
||||
if (!$bDryRun)
|
||||
{
|
||||
for (my $iProcessIdx = 0; $iProcessIdx < 8; $iProcessIdx++)
|
||||
{
|
||||
# &log(INFO, "stop test-${iProcessIdx}");
|
||||
push(@{$oyProcess}, undef);
|
||||
executeTest("docker rm -f test-${iProcessIdx}", {bSuppressError => true});
|
||||
}
|
||||
}
|
||||
|
||||
my $iTestIdx = 0;
|
||||
my $iProcessTotal;
|
||||
my $iTestMax = @{$oyTestRun};
|
||||
my $lStartTime = time();
|
||||
|
||||
# foreach my $oTest (@{$oyTestRun})
|
||||
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))
|
||||
{
|
||||
my $fTestElapsedTime = ceil((gettimeofday() - $$oyProcess[$iProcessIdx]{start_time}) * 100) / 100;
|
||||
|
||||
if (!($iExitStatus == 0 || $iExitStatus == 255))
|
||||
{
|
||||
&log(ERROR, "${strTestDone} (err${iExitStatus}-${fTestElapsedTime}s)" .
|
||||
(defined($oExecDone->{strOutLog}) ? ":\n\n" . trim($oExecDone->{strOutLog}) . "\n" : ''),
|
||||
undef, undef, 4);
|
||||
$iTestFail++;
|
||||
}
|
||||
else
|
||||
{
|
||||
&log( INFO, "${strTestDone} (${fTestElapsedTime}s)".
|
||||
($bVmOut ? ":\n\n" . trim($oExecDone->{strOutLog}) . "\n" : ''), undef, undef, 4);
|
||||
}
|
||||
|
||||
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}" : '') .
|
||||
(defined($$oTest{thread}) ? ", thread-max=$$oTest{thread}" : '');
|
||||
|
||||
my $strImage = 'test-' . $iProcessIdx;
|
||||
|
||||
&log($bDryRun ? INFO : DEBUG, $strTest);
|
||||
|
||||
if (!$bDryRun)
|
||||
{
|
||||
executeTest("docker run -itd -h $$oTest{os}-test --name=${strImage}" .
|
||||
" -v /backrest:/backrest backrest/$$oTest{os}-test");
|
||||
}
|
||||
|
||||
$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;
|
||||
|
||||
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}" : '') .
|
||||
" --no-cleanup";
|
||||
|
||||
&log(DEBUG, $strCommand);
|
||||
|
||||
if (!$bDryRun)
|
||||
{
|
||||
my $fTestStartTime = gettimeofday();
|
||||
my $oExec = new BackRestTest::Common::ExecuteTest($strCommand, {bSuppressError => true});
|
||||
|
||||
$oExec->begin();
|
||||
|
||||
my $oProcess =
|
||||
{
|
||||
exec => $oExec,
|
||||
test => $strTest,
|
||||
idx => $iTestIdx,
|
||||
start_time => $fTestStartTime
|
||||
};
|
||||
|
||||
$$oyProcess[$iProcessIdx] = $oProcess;
|
||||
}
|
||||
|
||||
$iProcessTotal++;
|
||||
}
|
||||
}
|
||||
}
|
||||
while ($iProcessTotal > 0);
|
||||
|
||||
&log(INFO, 'TESTS COMPLETED ' . ($iTestFail == 0 ? 'SUCCESSFULLY' : "WITH ${iTestFail} FAILURE(S)") .
|
||||
' (' . (time() - $lStartTime) . 's)');
|
||||
|
||||
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")
|
||||
{
|
||||
&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;
|
||||
}
|
||||
|
||||
################################################################################################################################
|
||||
# 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;
|
||||
|
||||
do
|
||||
{
|
||||
if (BackRestTestCommon_Setup($strExe, $strTestPath, $stryTestVersion[0], $iModuleTestRun,
|
||||
@@ -357,10 +686,9 @@ if ($@)
|
||||
}
|
||||
|
||||
syswrite(*STDOUT, $oMessage);
|
||||
exit 255;;
|
||||
exit 250;
|
||||
}
|
||||
|
||||
|
||||
if (!$bDryRun)
|
||||
{
|
||||
&log(INFO, 'TESTS COMPLETED SUCCESSFULLY (DESPITE ANY ERROR MESSAGES YOU SAW)');
|
||||
|
Reference in New Issue
Block a user