You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-09-16 09:06:18 +02:00
Coverage testing always enabled on Debian-based containers.
* Full coverage is verified when specified. * Modules marked with partial coverage will error if they are actually fully covered. * Simplified test representation is DefineTest. * Added new representation for queries in DefineTest and added API functions. * Update modules using DefineTest to use new API.
This commit is contained in:
18
.travis.yml
18
.travis.yml
@@ -13,31 +13,35 @@ services:
|
||||
- docker
|
||||
|
||||
env:
|
||||
- PGB_TEST_VM="co6" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=help --module=config --module=file --module=stanza --module=archive --module=backup --module=expire --module=info"
|
||||
- PGB_TEST_VM="co6" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=help --module=config --module=file --module=info --module=stanza --module=archive --module=backup --module=expire"
|
||||
- PGB_TEST_VM="co6" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=full --test=synthetic --no-lint --no-package"
|
||||
- PGB_TEST_VM="co6" PGB_BUILD_PARAM="--db=9.1" PGB_TEST_PARAM="--module=full --test=real --db=9.1 --process-max=2 --no-lint --no-package"
|
||||
- PGB_TEST_VM="co6" PGB_BUILD_PARAM="--db=9.0" PGB_TEST_PARAM="--module=full --test=real --db=9.0 --process-max=2 --no-lint --no-package"
|
||||
- PGB_TEST_VM="u16" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=help --module=config --module=file --module=stanza --module=archive --module=backup --module=expire --module=info --no-lint"
|
||||
- PGB_TEST_VM="u16" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=help --module=config --module=file --module=info --module=stanza --module=archive --module=backup --module=expire --no-lint"
|
||||
- PGB_TEST_VM="u16" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=full --test=synthetic --no-lint --no-package"
|
||||
- PGB_TEST_VM="u16" PGB_BUILD_PARAM="--db=9.4" PGB_TEST_PARAM="--module=full --test=real --db=9.4 --process-max=2 --no-lint --no-package"
|
||||
- PGB_TEST_VM="d8" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=help --module=config --module=file --module=stanza --module=archive --module=backup --module=expire --module=info --no-lint"
|
||||
- PGB_TEST_VM="d8" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=help --module=config --module=file --module=info --module=stanza --module=archive --module=backup --module=expire --no-lint"
|
||||
- PGB_TEST_VM="d8" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=full --test=synthetic --no-lint --no-package"
|
||||
- PGB_TEST_VM="d8" PGB_BUILD_PARAM="--db=9.3" PGB_TEST_PARAM="--module=full --test=real --db=9.3 --process-max=2 --no-lint --no-package"
|
||||
- PGB_TEST_VM="d8" PGB_BUILD_PARAM="--db=8.4" PGB_TEST_PARAM="--module=full --test=real --db=8.4 --process-max=2 --no-lint --no-package"
|
||||
- PGB_TEST_VM="co7" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=help --module=config --module=file --module=stanza --module=archive --module=backup --module=expire --module=info --no-lint"
|
||||
- PGB_TEST_VM="co7" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=help --module=config --module=file --module=info --module=stanza --module=archive --module=backup --module=expire --no-lint"
|
||||
- PGB_TEST_VM="co7" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=full --test=synthetic --no-lint --no-package"
|
||||
- PGB_TEST_VM="co7" PGB_BUILD_PARAM="--db=9.6" PGB_TEST_PARAM="--module=full --test=real --db=9.6 --process-max=2 --no-lint --no-package"
|
||||
- PGB_TEST_VM="co7" PGB_BUILD_PARAM="--db=9.5" PGB_TEST_PARAM="--module=full --test=real --db=9.5 --process-max=2 --no-lint --no-package"
|
||||
- PGB_TEST_VM="u14" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=help --module=config --module=file --module=stanza --module=archive --module=backup --module=expire --module=info --no-lint"
|
||||
- PGB_TEST_VM="u14" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=help --module=config --module=file --module=info --module=stanza --module=archive --module=backup --module=expire --no-lint"
|
||||
- PGB_TEST_VM="u14" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=full --test=synthetic --no-lint --no-package"
|
||||
- PGB_TEST_VM="u14" PGB_BUILD_PARAM="--db=9.2" PGB_TEST_PARAM="--module=full --test=real --db=9.2 --process-max=2 --no-lint --no-package"
|
||||
- PGB_TEST_VM="u12" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=help --module=config --module=file --module=stanza --module=archive --module=backup --module=expire --module=info --no-lint"
|
||||
- PGB_TEST_VM="u12" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=help --module=config --module=file --module=info --module=stanza --module=archive --module=backup --module=expire --no-lint"
|
||||
- PGB_TEST_VM="u12" PGB_BUILD_PARAM="--db=none" PGB_TEST_PARAM="--module=full --test=synthetic --no-lint --no-package"
|
||||
- PGB_TEST_VM="u12" PGB_BUILD_PARAM="--db=8.3" PGB_TEST_PARAM="--module=full --test=real --db=8.3 --process-max=2 --no-lint --no-package"
|
||||
|
||||
before_install:
|
||||
- sudo apt-get -qq update
|
||||
- sudo apt-get install libxml-checker-perl libdbd-pg-perl libperl-critic-perl libdevel-cover-perl
|
||||
- sudo apt-get install libxml-checker-perl libdbd-pg-perl libperl-critic-perl libtemplate-perl libpod-coverage-perl libtest-differences-perl libhtml-parser-perl lintian debhelper txt2man devscripts libjson-perl
|
||||
- git clone https://anonscm.debian.org/git/pkg-perl/packages/libdevel-cover-perl.git ~/libdevel-cover-perl
|
||||
- cd ~/libdevel-cover-perl && git checkout debian/1.23-2 && debuild -i -us -uc -b
|
||||
- sudo dpkg -i ~/libdevel-cover-perl_1.23-2_amd64.deb
|
||||
- /usr/bin/cover -v
|
||||
|
||||
install:
|
||||
- sudo adduser --ingroup=${USER?} --disabled-password --gecos "" backrest
|
||||
|
@@ -212,6 +212,10 @@
|
||||
|
||||
<release-test-list>
|
||||
<release-refactor-list>
|
||||
<release-item>
|
||||
<p>Coverage testing always enabled on Debian-based containers.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Require description in every call to <code>testResult()</code>.</p>
|
||||
</release-item>
|
||||
|
@@ -32,6 +32,24 @@ sub trim
|
||||
|
||||
push @EXPORT, qw(trim);
|
||||
|
||||
####################################################################################################################################
|
||||
# coalesce
|
||||
#
|
||||
# Return the first non-null parameter.
|
||||
####################################################################################################################################
|
||||
sub coalesce
|
||||
{
|
||||
foreach my $strParam (@_)
|
||||
{
|
||||
if (defined($strParam))
|
||||
{
|
||||
return $strParam;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
push @EXPORT, qw(coalesce);
|
||||
|
||||
####################################################################################################################################
|
||||
# commonPrefix
|
||||
#
|
||||
|
42
test/Vagrantfile
vendored
42
test/Vagrantfile
vendored
@@ -13,6 +13,7 @@ Vagrant.configure(2) do |config|
|
||||
|
||||
# Provision the VM
|
||||
config.vm.provision "shell", inline: <<-SHELL
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
echo 'Build Begin' && date
|
||||
|
||||
# Suppress "dpkg-reconfigure: unable to re-open stdin: No file or directory" warning
|
||||
@@ -22,18 +23,32 @@ Vagrant.configure(2) do |config|
|
||||
sed -i 's/^127\.0\.0\.1\t.*/127\.0\.0\.1\tlocalhost pgbackrest-test/' /etc/hosts
|
||||
hostnamectl set-hostname pgbackrest-test
|
||||
|
||||
# Update Apt
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
echo 'Update Apt' && date
|
||||
apt-get update
|
||||
|
||||
# Install build tools
|
||||
apt-get install -y devscripts build-essential lintian git txt2man debhelper
|
||||
|
||||
# Synchronize date
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
echo 'Synchronize Date' && date
|
||||
apt-get install -y ntpdate
|
||||
ntpdate pool.ntp.org
|
||||
|
||||
# Install Docker
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
echo 'Install Perl Modules' && date
|
||||
apt-get install -y libdbd-pg-perl libxml-checker-perl libperl-critic-perl libdevel-nytprof-perl
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
echo 'Install Build Tools' && date
|
||||
apt-get install -y devscripts build-essential lintian git txt2man debhelper
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
echo 'Build Devel::Cover' && date
|
||||
apt-get install -y libpod-coverage-perl libtest-differences-perl libhtml-parser-perl libtemplate-perl
|
||||
git clone --branch debian/1.23-2 \
|
||||
https://anonscm.debian.org/git/pkg-perl/packages/libdevel-cover-perl.git /root/libdevel-cover-perl
|
||||
cd /root/libdevel-cover-perl && debuild --no-lintian -i -us -uc -b > /dev/null
|
||||
dpkg -i /root/libdevel-cover-perl_1.23-2_amd64.deb
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
echo 'Install Docker' && date
|
||||
apt-get install -y apt-transport-https ca-certificates
|
||||
apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
|
||||
@@ -44,31 +59,28 @@ Vagrant.configure(2) do |config|
|
||||
service docker start
|
||||
sudo usermod -aG docker ubuntu
|
||||
|
||||
# Install Perl modules
|
||||
echo 'Install Perl Modules' && date
|
||||
apt-get install -y libdbd-pg-perl libxml-checker-perl libperl-critic-perl libdevel-nytprof-perl libdevel-cover-perl
|
||||
|
||||
# Install utilities
|
||||
echo 'Install Utilities' && date
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
echo 'Install Dev Utilities' && date
|
||||
apt-get install -y vim htop
|
||||
|
||||
# Install TeX Live
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
echo 'Install TeX Live' && date
|
||||
apt-get install -y --no-install-recommends texlive-latex-base texlive-latex-extra texlive-fonts-recommended
|
||||
apt-get install -y texlive-font-utils
|
||||
|
||||
# Create backrest user and postgres group
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
echo 'Create Postgres Group & pgBackRest User' && date
|
||||
groupadd -g5000 postgres
|
||||
adduser --uid=5001 --ingroup=ubuntu --disabled-password --gecos "" backrest
|
||||
|
||||
# Build VM images
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
echo 'Build VM Images' && date
|
||||
rm -rf /backrest/test/.vagrant/docker/*
|
||||
rm -rf /backrest/test/.vagrant/libc/*
|
||||
rm -rf /backrest/test/.vagrant/package/*
|
||||
sudo su - ubuntu -c '/backrest/test/test.pl --vm-build'
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
echo 'Build End' && date
|
||||
SHELL
|
||||
|
||||
|
@@ -94,23 +94,20 @@ sub process
|
||||
# Iterate each OS
|
||||
foreach my $strVm (VM_LIST)
|
||||
{
|
||||
my $hTestDef = testDefGet();
|
||||
my $hVm = vmGet();
|
||||
my @stryModule;
|
||||
my $hFullModule = undef;
|
||||
my $strFullModule = undef;
|
||||
|
||||
# Get all modules but full to break up the tests
|
||||
foreach my $hModule (@{$hTestDef->{&TESTDEF_MODULE}})
|
||||
foreach my $strModule (testDefModuleList())
|
||||
{
|
||||
my $strModule = $hModule->{&TESTDEF_MODULE_NAME};
|
||||
|
||||
if ($strModule ne 'full')
|
||||
{
|
||||
push(@stryModule, $strModule);
|
||||
}
|
||||
else
|
||||
{
|
||||
$hFullModule = $hModule;
|
||||
$strFullModule = $strModule;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,20 +121,18 @@ sub process
|
||||
$bFirst = false;
|
||||
|
||||
# Now generate full tests
|
||||
my $hRealTest = undef;
|
||||
my $strRealTest = undef;
|
||||
|
||||
if (!defined($hFullModule))
|
||||
if (!defined($strFullModule))
|
||||
{
|
||||
confess "the full module is not defined, has the name changed?";
|
||||
confess "${strFullModule} module not found, has the name changed?";
|
||||
}
|
||||
|
||||
foreach my $hTest (@{$hFullModule->{&TESTDEF_TEST}})
|
||||
foreach my $strTest (testDefModuleTestList($strFullModule))
|
||||
{
|
||||
my $strTest = $hTest->{&TESTDEF_TEST_NAME};
|
||||
|
||||
if ($strTest eq 'real')
|
||||
{
|
||||
$hRealTest = $hTest;
|
||||
$strRealTest = $strTest;
|
||||
|
||||
foreach my $strDbVersion (sort {$b cmp $a} @{$hVm->{$strVm}{&VM_DB_MINIMAL}})
|
||||
{
|
||||
@@ -155,9 +150,9 @@ sub process
|
||||
}
|
||||
}
|
||||
|
||||
if (!defined($hRealTest))
|
||||
if (!defined($strRealTest))
|
||||
{
|
||||
confess 'real test not found in full module, has the name changed?';
|
||||
confess "${strRealTest} test not found in ${strFullModule} module, has the name changed?";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +161,12 @@ sub process
|
||||
"\n" .
|
||||
"before_install:\n" .
|
||||
" - sudo apt-get -qq update\n" .
|
||||
" - sudo apt-get install libxml-checker-perl libdbd-pg-perl libperl-critic-perl libdevel-cover-perl\n" .
|
||||
" - sudo apt-get install libxml-checker-perl libdbd-pg-perl libperl-critic-perl libtemplate-perl libpod-coverage-perl" .
|
||||
" libtest-differences-perl libhtml-parser-perl lintian debhelper txt2man devscripts libjson-perl\n" .
|
||||
" - git clone https://anonscm.debian.org/git/pkg-perl/packages/libdevel-cover-perl.git ~/libdevel-cover-perl\n" .
|
||||
' - cd ~/libdevel-cover-perl && git checkout debian/' . LIB_COVER_VERSION . " && debuild -i -us -uc -b\n" .
|
||||
' - sudo dpkg -i ~/' . LIB_COVER_PACKAGE . "\n" .
|
||||
' - ' . LIB_COVER_EXE . " -v\n" .
|
||||
"\n" .
|
||||
"install:\n" .
|
||||
" - sudo adduser --ingroup=\${USER?} --disabled-password --gecos \"\" " . BACKREST_USER . "\n" .
|
||||
|
@@ -46,6 +46,16 @@ use constant BACKREST_USER => 'backrest
|
||||
push @EXPORT, qw(BACKREST_USER);
|
||||
use constant BACKREST_USER_ID => getpwnam(BACKREST_USER) . '';
|
||||
|
||||
####################################################################################################################################
|
||||
# Package constants
|
||||
####################################################################################################################################
|
||||
use constant LIB_COVER_VERSION => '1.23-2';
|
||||
push @EXPORT, qw(LIB_COVER_VERSION);
|
||||
use constant LIB_COVER_PACKAGE => 'libdevel-cover-perl_' . LIB_COVER_VERSION . '_amd64.deb';
|
||||
push @EXPORT, qw(LIB_COVER_PACKAGE);
|
||||
use constant LIB_COVER_EXE => '/usr/bin/cover';
|
||||
push @EXPORT, qw(LIB_COVER_EXE);
|
||||
|
||||
####################################################################################################################################
|
||||
# Container repo
|
||||
####################################################################################################################################
|
||||
@@ -257,6 +267,27 @@ sub sudoSetup
|
||||
return $strScript;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# Devel::Cover setup
|
||||
####################################################################################################################################
|
||||
sub coverSetup
|
||||
{
|
||||
my $strOS = shift;
|
||||
|
||||
my $strScript = '';
|
||||
my $oVm = vmGet();
|
||||
|
||||
if ($$oVm{$strOS}{&VM_OS_BASE} eq VM_OS_BASE_DEBIAN)
|
||||
{
|
||||
$strScript .=
|
||||
"\n\n# Install Devel::Cover\n" .
|
||||
"COPY ${strOS}-" . LIB_COVER_PACKAGE . ' /tmp/' . LIB_COVER_PACKAGE . "\n" .
|
||||
'RUN dpkg -i /tmp/' . LIB_COVER_PACKAGE;
|
||||
}
|
||||
|
||||
return $strScript;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# Install Perl packages
|
||||
####################################################################################################################################
|
||||
@@ -269,27 +300,30 @@ sub perlInstall
|
||||
|
||||
if ($strOS eq VM_CO6)
|
||||
{
|
||||
return $strImage .
|
||||
$strImage .=
|
||||
'RUN yum install -y perl perl-Time-HiRes perl-parent perl-JSON perl-Digest-SHA perl-DBD-Pg';
|
||||
}
|
||||
elsif ($strOS eq VM_CO7)
|
||||
{
|
||||
return $strImage .
|
||||
$strImage .=
|
||||
'RUN yum install -y perl perl-JSON-PP perl-Digest-SHA perl-DBD-Pg';
|
||||
}
|
||||
elsif ($strOS eq VM_U12 || $strOS eq VM_U14)
|
||||
{
|
||||
return $strImage .
|
||||
'RUN apt-get install -y libdbd-pg-perl libdbi-perl libnet-daemon-perl libplrpc-perl';
|
||||
$strImage .=
|
||||
'RUN apt-get install -y libdbd-pg-perl libdbi-perl libnet-daemon-perl libplrpc-perl libhtml-parser-perl';
|
||||
}
|
||||
elsif ($strOS eq VM_U16 || $strOS eq VM_D8)
|
||||
{
|
||||
return $strImage .
|
||||
'RUN apt-get install -y libdbd-pg-perl libdbi-perl' .
|
||||
($strOS eq VM_U16 ? ' libdevel-cover-perl libtest-pod-coverage-perl' : '');
|
||||
$strImage .=
|
||||
'RUN apt-get install -y libdbd-pg-perl libdbi-perl libhtml-parser-perl';
|
||||
}
|
||||
else
|
||||
{
|
||||
confess &log(ERROR, "unable to install perl for os '${strOS}'");
|
||||
}
|
||||
|
||||
confess &log(ERROR, "unable to install perl for os '${strOS}'");
|
||||
return $strImage;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
@@ -487,8 +521,12 @@ sub containerBuild
|
||||
{
|
||||
$strScript =
|
||||
"# Install package build tools and package source\n" .
|
||||
"RUN apt-get install -y devscripts build-essential lintian git libxml-checker-perl txt2man debhelper && \\\n" .
|
||||
" git clone https://anonscm.debian.org/git/pkg-postgresql/pgbackrest.git /root/package-src\n";
|
||||
"RUN apt-get install -y devscripts build-essential lintian git libxml-checker-perl txt2man debhelper" .
|
||||
" libpod-coverage-perl libppi-html-perl libtemplate-perl libtest-differences-perl && \\\n" .
|
||||
" git clone https://anonscm.debian.org/git/pkg-postgresql/pgbackrest.git /root/package-src && \\\n" .
|
||||
" git clone https://anonscm.debian.org/git/pkg-perl/packages/libdevel-cover-perl.git" .
|
||||
" /root/libdevel-cover-perl && \\\n" .
|
||||
' cd /root/libdevel-cover-perl && git checkout debian/' . LIB_COVER_VERSION . ' && debuild -i -us -uc -b';
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -500,6 +538,20 @@ sub containerBuild
|
||||
# Write the image
|
||||
containerWrite($strTempPath, $strOS, 'Build', $strImageParent, $strImage, $strScript, $bVmForce, false);
|
||||
|
||||
# Copy Devel::Cover to host so it can be installed in other containers
|
||||
if ($$oVm{$strOS}{&VM_OS_BASE} eq VM_OS_BASE_DEBIAN)
|
||||
{
|
||||
executeTest('docker rm -f test-build', {bSuppressError => true});
|
||||
executeTest(
|
||||
"docker run -itd -h test-build --name=test-build" .
|
||||
" -v ${strTempPath}:${strTempPath} " . containerRepo() . ":${strOS}-build",
|
||||
{bSuppressStdErr => true});
|
||||
executeTest(
|
||||
"docker exec -i test-build " .
|
||||
"bash -c 'cp /root/" . LIB_COVER_PACKAGE . " ${strTempPath}/${strOS}-" . LIB_COVER_PACKAGE . "'");
|
||||
executeTest('docker rm -f test-build');
|
||||
}
|
||||
|
||||
# Db image
|
||||
###########################################################################################################################
|
||||
my @stryDbBuild;
|
||||
@@ -588,6 +640,9 @@ sub containerBuild
|
||||
# Install SSH key
|
||||
$strScript = sshSetup($strOS, TEST_USER, TEST_GROUP, $$oVm{$strOS}{&VM_CONTROL_MASTER});
|
||||
|
||||
# Setup Devel::Cover
|
||||
$strScript .= coverSetup($strOS);
|
||||
|
||||
# Write the image
|
||||
containerWrite($strTempPath, $strOS, "${strTitle} Test", $strImageParent, $strImage, $strScript, $bVmForce, true, true);
|
||||
}
|
||||
@@ -600,6 +655,9 @@ sub containerBuild
|
||||
# Install SSH key
|
||||
$strScript = sshSetup($strOS, TEST_USER, TEST_GROUP, $$oVm{$strOS}{&VM_CONTROL_MASTER});
|
||||
|
||||
# Setup Devel::Cover
|
||||
$strScript .= coverSetup($strOS);
|
||||
|
||||
# Write the image
|
||||
containerWrite($strTempPath, $strOS, 'Db Synthetic Test', $strImageParent, $strImage, $strScript, $bVmForce, true, true);
|
||||
|
||||
@@ -627,6 +685,9 @@ sub containerBuild
|
||||
# Setup sudo
|
||||
$strScript .= "\n\n" . sudoSetup($strOS, TEST_GROUP);
|
||||
|
||||
# Setup Devel::Cover
|
||||
$strScript .= coverSetup($strOS);
|
||||
|
||||
# Write the image
|
||||
containerWrite($strTempPath, $strOS, 'Loop Test', $strImageParent, $strImage, $strScript, $bVmForce, true, true);
|
||||
|
||||
@@ -680,6 +741,9 @@ sub containerBuild
|
||||
"\n\n# Make " . TEST_USER . " home dir readable\n" .
|
||||
'RUN chmod g+r,g+x /home/' . TEST_USER;
|
||||
|
||||
# Setup Devel::Cover
|
||||
$strScript .= coverSetup($strOS);
|
||||
|
||||
# Write the image
|
||||
containerWrite($strTempPath, $strOS, "${strTitle} Test", $strImageParent, $strImage, $strScript, $bVmForce, true, true);
|
||||
}
|
||||
|
@@ -14,41 +14,50 @@ use Exporter qw(import);
|
||||
our @EXPORT = qw();
|
||||
|
||||
use pgBackRest::Common::Log;
|
||||
use pgBackRest::Common::String;
|
||||
|
||||
################################################################################################################################
|
||||
# Test definition constants
|
||||
################################################################################################################################
|
||||
use constant TESTDEF_MODULE => 'module';
|
||||
push @EXPORT, qw(TESTDEF_MODULE);
|
||||
use constant TESTDEF_MODULE_NAME => 'name';
|
||||
push @EXPORT, qw(TESTDEF_MODULE_NAME);
|
||||
|
||||
use constant TESTDEF_EXPECT => 'expect';
|
||||
push @EXPORT, qw(TESTDEF_EXPECT);
|
||||
use constant TESTDEF_NAME => 'name';
|
||||
push @EXPORT, qw(TESTDEF_NAME);
|
||||
use constant TESTDEF_TEST => 'test';
|
||||
push @EXPORT, qw(TESTDEF_TEST);
|
||||
use constant TESTDEF_TEST_ALL => 'all';
|
||||
push @EXPORT, qw(TESTDEF_TEST_ALL);
|
||||
use constant TESTDEF_TEST_COVERAGE => 'coverage';
|
||||
push @EXPORT, qw(TESTDEF_TEST_COVERAGE);
|
||||
use constant TESTDEF_TEST_INDIVIDUAL => 'individual';
|
||||
push @EXPORT, qw(TESTDEF_TEST_INDIVIDUAL);
|
||||
use constant TESTDEF_TEST_NAME => 'name';
|
||||
push @EXPORT, qw(TESTDEF_TEST_NAME);
|
||||
use constant TESTDEF_TEST_TOTAL => 'total';
|
||||
push @EXPORT, qw(TESTDEF_TEST_TOTAL);
|
||||
use constant TESTDEF_TEST_CONTAINER => 'container';
|
||||
push @EXPORT, qw(TESTDEF_TEST_CONTAINER);
|
||||
use constant TESTDEF_TEST_PROCESS => 'process';
|
||||
push @EXPORT, qw(TESTDEF_TEST_PROCESS);
|
||||
use constant TESTDEF_TEST_DB => 'db';
|
||||
push @EXPORT, qw(TESTDEF_TEST_DB);
|
||||
|
||||
# Determines if the test will be run against multiple db versions
|
||||
use constant TESTDEF_DB => 'db';
|
||||
push @EXPORT, qw(TESTDEF_DB);
|
||||
# Determines if the test will be run in a container or will create containers itself
|
||||
use constant TESTDEF_CONTAINER => 'container';
|
||||
push @EXPORT, qw(TESTDEF_CONTAINER);
|
||||
# Determines coverage for the test
|
||||
use constant TESTDEF_COVERAGE => 'coverage';
|
||||
push @EXPORT, qw(TESTDEF_COVERAGE);
|
||||
# Should expect log tests be run
|
||||
use constant TESTDEF_EXPECT => 'expect';
|
||||
push @EXPORT, qw(TESTDEF_EXPECT);
|
||||
# Determines if each run in a test will be run in a new container
|
||||
use constant TESTDEF_INDIVIDUAL => 'individual';
|
||||
push @EXPORT, qw(TESTDEF_INDIVIDUAL);
|
||||
# Determines if the test will be run with multiple processes
|
||||
use constant TESTDEF_PROCESS => 'process';
|
||||
push @EXPORT, qw(TESTDEF_PROCESS);
|
||||
# Total runs in the test
|
||||
use constant TESTDEF_TOTAL => 'total';
|
||||
push @EXPORT, qw(TESTDEF_TOTAL);
|
||||
|
||||
# The test provides full coverage for the module
|
||||
use constant TESTDEF_COVERAGE_FULL => true;
|
||||
push @EXPORT, qw(TESTDEF_COVERAGE_FULL);
|
||||
# The test provides partial coverage for the module
|
||||
use constant TESTDEF_COVERAGE_PARTIAL => false;
|
||||
push @EXPORT, qw(TESTDEF_COVERAGE_PARTIAL);
|
||||
|
||||
################################################################################################################################
|
||||
# Code modules
|
||||
################################################################################################################################
|
||||
use constant TESTDEF_MODULE_FILE => 'File';
|
||||
push @EXPORT, qw(TESTDEF_MODULE_FILE);
|
||||
use constant TESTDEF_MODULE_FILE_COMMON => TESTDEF_MODULE_FILE . 'Common';
|
||||
@@ -86,218 +95,211 @@ my $oTestDef =
|
||||
[
|
||||
# Help tests
|
||||
{
|
||||
&TESTDEF_MODULE_NAME => 'help',
|
||||
&TESTDEF_TEST_CONTAINER => true,
|
||||
&TESTDEF_NAME => 'help',
|
||||
&TESTDEF_CONTAINER => true,
|
||||
&TESTDEF_EXPECT => true,
|
||||
|
||||
&TESTDEF_TEST =>
|
||||
[
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'help',
|
||||
&TESTDEF_TEST_TOTAL => 1,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'help',
|
||||
&TESTDEF_TOTAL => 1,
|
||||
}
|
||||
]
|
||||
},
|
||||
# Config tests
|
||||
{
|
||||
&TESTDEF_MODULE_NAME => 'config',
|
||||
&TESTDEF_TEST_CONTAINER => true,
|
||||
&TESTDEF_NAME => 'config',
|
||||
&TESTDEF_CONTAINER => true,
|
||||
|
||||
&TESTDEF_TEST =>
|
||||
[
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'unit',
|
||||
&TESTDEF_TEST_TOTAL => 7,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'unit',
|
||||
&TESTDEF_TOTAL => 7,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'option',
|
||||
&TESTDEF_TEST_TOTAL => 34,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'option',
|
||||
&TESTDEF_TOTAL => 34,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'config',
|
||||
&TESTDEF_TEST_TOTAL => 25,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'config',
|
||||
&TESTDEF_TOTAL => 25,
|
||||
}
|
||||
]
|
||||
},
|
||||
# File tests
|
||||
{
|
||||
&TESTDEF_MODULE_NAME => 'file',
|
||||
&TESTDEF_TEST_CONTAINER => true,
|
||||
&TESTDEF_NAME => 'file',
|
||||
&TESTDEF_CONTAINER => true,
|
||||
|
||||
&TESTDEF_TEST_COVERAGE =>
|
||||
&TESTDEF_COVERAGE =>
|
||||
{
|
||||
&TESTDEF_MODULE_FILE => TESTDEF_COVERAGE_FULL,
|
||||
&TESTDEF_MODULE_FILE_COMMON => TESTDEF_COVERAGE_FULL,
|
||||
&TESTDEF_MODULE_FILE => TESTDEF_COVERAGE_PARTIAL,
|
||||
&TESTDEF_MODULE_FILE_COMMON => TESTDEF_COVERAGE_PARTIAL,
|
||||
},
|
||||
|
||||
&TESTDEF_TEST =>
|
||||
[
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'unit',
|
||||
&TESTDEF_TEST_TOTAL => 1,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'unit',
|
||||
&TESTDEF_TOTAL => 1,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'owner',
|
||||
&TESTDEF_TEST_TOTAL => 8,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'owner',
|
||||
&TESTDEF_TOTAL => 8,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'path-create',
|
||||
&TESTDEF_TEST_TOTAL => 8,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'path-create',
|
||||
&TESTDEF_TOTAL => 8,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'move',
|
||||
&TESTDEF_TEST_TOTAL => 24,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'move',
|
||||
&TESTDEF_TOTAL => 24,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'compress',
|
||||
&TESTDEF_TEST_TOTAL => 4,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'compress',
|
||||
&TESTDEF_TOTAL => 4,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'wait',
|
||||
&TESTDEF_TEST_TOTAL => 2,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'wait',
|
||||
&TESTDEF_TOTAL => 2,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'link',
|
||||
&TESTDEF_TEST_TOTAL => 1,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'link',
|
||||
&TESTDEF_TOTAL => 1,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'stat',
|
||||
&TESTDEF_TEST_TOTAL => 1,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'stat',
|
||||
&TESTDEF_TOTAL => 1,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'manifest',
|
||||
&TESTDEF_TEST_TOTAL => 5,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'manifest',
|
||||
&TESTDEF_TOTAL => 5,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'list',
|
||||
&TESTDEF_TEST_TOTAL => 72,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'list',
|
||||
&TESTDEF_TOTAL => 72,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'remove',
|
||||
&TESTDEF_TEST_TOTAL => 32,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'remove',
|
||||
&TESTDEF_TOTAL => 32,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'hash',
|
||||
&TESTDEF_TEST_TOTAL => 16,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'hash',
|
||||
&TESTDEF_TOTAL => 16,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'exists',
|
||||
&TESTDEF_TEST_TOTAL => 6,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'exists',
|
||||
&TESTDEF_TOTAL => 6,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'copy',
|
||||
&TESTDEF_TEST_TOTAL => 144,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'copy',
|
||||
&TESTDEF_TOTAL => 144,
|
||||
}
|
||||
]
|
||||
},
|
||||
# Info tests
|
||||
{
|
||||
&TESTDEF_NAME => 'info',
|
||||
&TESTDEF_CONTAINER => true,
|
||||
|
||||
&TESTDEF_TEST =>
|
||||
[
|
||||
{
|
||||
&TESTDEF_NAME => 'unit',
|
||||
&TESTDEF_TOTAL => 1,
|
||||
|
||||
&TESTDEF_COVERAGE =>
|
||||
{
|
||||
&TESTDEF_MODULE_INFO => TESTDEF_COVERAGE_PARTIAL,
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
# Stanza tests
|
||||
{
|
||||
&TESTDEF_MODULE_NAME => 'stanza',
|
||||
&TESTDEF_TEST_CONTAINER => false,
|
||||
&TESTDEF_EXPECT => true,
|
||||
&TESTDEF_NAME => 'stanza',
|
||||
|
||||
&TESTDEF_TEST_COVERAGE =>
|
||||
&TESTDEF_COVERAGE =>
|
||||
{
|
||||
&TESTDEF_MODULE_STANZA => TESTDEF_COVERAGE_FULL,
|
||||
&TESTDEF_MODULE_STANZA => TESTDEF_COVERAGE_PARTIAL,
|
||||
},
|
||||
|
||||
&TESTDEF_TEST =>
|
||||
[
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'unit',
|
||||
&TESTDEF_EXPECT => false,
|
||||
&TESTDEF_TEST_TOTAL => 2,
|
||||
&TESTDEF_NAME => 'unit',
|
||||
&TESTDEF_TOTAL => 2,
|
||||
&TESTDEF_CONTAINER => true,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'create',
|
||||
&TESTDEF_TEST_TOTAL => 2
|
||||
&TESTDEF_NAME => 'create',
|
||||
&TESTDEF_TOTAL => 2,
|
||||
&TESTDEF_EXPECT => true,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'upgrade',
|
||||
&TESTDEF_TEST_TOTAL => 2
|
||||
&TESTDEF_NAME => 'upgrade',
|
||||
&TESTDEF_TOTAL => 2,
|
||||
&TESTDEF_EXPECT => true,
|
||||
},
|
||||
]
|
||||
},
|
||||
# Archive tests
|
||||
{
|
||||
&TESTDEF_MODULE_NAME => 'archive',
|
||||
&TESTDEF_TEST_CONTAINER => false,
|
||||
&TESTDEF_EXPECT => true,
|
||||
&TESTDEF_NAME => 'archive',
|
||||
|
||||
&TESTDEF_TEST =>
|
||||
[
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'unit',
|
||||
&TESTDEF_TEST_TOTAL => 4,
|
||||
&TESTDEF_TEST_CONTAINER => true,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_EXPECT => false,
|
||||
&TESTDEF_NAME => 'unit',
|
||||
&TESTDEF_TOTAL => 4,
|
||||
&TESTDEF_CONTAINER => true,
|
||||
|
||||
&TESTDEF_TEST_COVERAGE =>
|
||||
{
|
||||
&TESTDEF_TEST_ALL =>
|
||||
&TESTDEF_COVERAGE =>
|
||||
{
|
||||
&TESTDEF_MODULE_ARCHIVE_COMMON => TESTDEF_COVERAGE_PARTIAL,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'push-unit',
|
||||
&TESTDEF_TEST_TOTAL => 7,
|
||||
&TESTDEF_TEST_CONTAINER => true,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_EXPECT => false,
|
||||
&TESTDEF_NAME => 'push-unit',
|
||||
&TESTDEF_TOTAL => 7,
|
||||
&TESTDEF_CONTAINER => true,
|
||||
|
||||
&TESTDEF_TEST_COVERAGE =>
|
||||
{
|
||||
&TESTDEF_TEST_ALL =>
|
||||
&TESTDEF_COVERAGE =>
|
||||
{
|
||||
&TESTDEF_MODULE_ARCHIVE_PUSH => TESTDEF_COVERAGE_FULL,
|
||||
&TESTDEF_MODULE_ARCHIVE_PUSH_ASYNC => TESTDEF_COVERAGE_FULL,
|
||||
&TESTDEF_MODULE_ARCHIVE_PUSH_FILE => TESTDEF_COVERAGE_PARTIAL,
|
||||
}
|
||||
&TESTDEF_MODULE_ARCHIVE_PUSH_FILE => TESTDEF_COVERAGE_FULL,
|
||||
},
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'push',
|
||||
&TESTDEF_TEST_TOTAL => 8,
|
||||
&TESTDEF_TEST_PROCESS => true,
|
||||
&TESTDEF_NAME => 'push',
|
||||
&TESTDEF_TOTAL => 8,
|
||||
&TESTDEF_PROCESS => true,
|
||||
&TESTDEF_INDIVIDUAL => true,
|
||||
&TESTDEF_EXPECT => true,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'stop',
|
||||
&TESTDEF_TEST_TOTAL => 6
|
||||
&TESTDEF_NAME => 'stop',
|
||||
&TESTDEF_TOTAL => 6,
|
||||
&TESTDEF_INDIVIDUAL => true,
|
||||
&TESTDEF_EXPECT => true,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'get',
|
||||
&TESTDEF_TEST_TOTAL => 8
|
||||
&TESTDEF_NAME => 'get',
|
||||
&TESTDEF_TOTAL => 8,
|
||||
&TESTDEF_INDIVIDUAL => true,
|
||||
&TESTDEF_EXPECT => true,
|
||||
},
|
||||
]
|
||||
},
|
||||
# Backup tests
|
||||
{
|
||||
&TESTDEF_MODULE_NAME => 'backup',
|
||||
&TESTDEF_TEST_CONTAINER => false,
|
||||
&TESTDEF_EXPECT => false,
|
||||
&TESTDEF_NAME => 'backup',
|
||||
&TESTDEF_CONTAINER => true,
|
||||
|
||||
&TESTDEF_TEST_COVERAGE =>
|
||||
&TESTDEF_COVERAGE =>
|
||||
{
|
||||
&TESTDEF_MODULE_BACKUP_COMMON => TESTDEF_COVERAGE_FULL,
|
||||
},
|
||||
@@ -305,79 +307,51 @@ my $oTestDef =
|
||||
&TESTDEF_TEST =>
|
||||
[
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'unit',
|
||||
&TESTDEF_TEST_TOTAL => 3,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'unit',
|
||||
&TESTDEF_TOTAL => 3,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'info-unit',
|
||||
&TESTDEF_TEST_TOTAL => 1,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_NAME => 'info-unit',
|
||||
&TESTDEF_TOTAL => 1,
|
||||
},
|
||||
]
|
||||
},
|
||||
# Expire tests
|
||||
{
|
||||
&TESTDEF_MODULE_NAME => 'expire',
|
||||
&TESTDEF_TEST_CONTAINER => false,
|
||||
&TESTDEF_NAME => 'expire',
|
||||
&TESTDEF_EXPECT => true,
|
||||
&TESTDEF_INDIVIDUAL => true,
|
||||
|
||||
&TESTDEF_TEST_COVERAGE =>
|
||||
&TESTDEF_COVERAGE =>
|
||||
{
|
||||
&TESTDEF_MODULE_EXPIRE => TESTDEF_COVERAGE_FULL,
|
||||
&TESTDEF_MODULE_EXPIRE => TESTDEF_COVERAGE_PARTIAL,
|
||||
},
|
||||
|
||||
&TESTDEF_TEST =>
|
||||
[
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'expire',
|
||||
&TESTDEF_TEST_TOTAL => 2,
|
||||
},
|
||||
]
|
||||
},
|
||||
# Info tests
|
||||
{
|
||||
&TESTDEF_MODULE_NAME => 'info',
|
||||
&TESTDEF_TEST_CONTAINER => false,
|
||||
&TESTDEF_EXPECT => true,
|
||||
|
||||
&TESTDEF_TEST =>
|
||||
[
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'unit',
|
||||
&TESTDEF_TEST_CONTAINER => true,
|
||||
&TESTDEF_TEST_INDIVIDUAL => false,
|
||||
&TESTDEF_EXPECT => false,
|
||||
&TESTDEF_TEST_TOTAL => 1,
|
||||
|
||||
&TESTDEF_TEST_COVERAGE =>
|
||||
{
|
||||
&TESTDEF_TEST_ALL =>
|
||||
{
|
||||
&TESTDEF_MODULE_INFO => TESTDEF_COVERAGE_FULL,
|
||||
}
|
||||
},
|
||||
&TESTDEF_NAME => 'expire',
|
||||
&TESTDEF_TOTAL => 2,
|
||||
},
|
||||
]
|
||||
},
|
||||
# Full tests
|
||||
{
|
||||
&TESTDEF_MODULE_NAME => 'full',
|
||||
&TESTDEF_TEST_CONTAINER => false,
|
||||
&TESTDEF_NAME => 'full',
|
||||
&TESTDEF_EXPECT => true,
|
||||
&TESTDEF_INDIVIDUAL => true,
|
||||
&TESTDEF_PROCESS => true,
|
||||
|
||||
&TESTDEF_TEST =>
|
||||
[
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'synthetic',
|
||||
&TESTDEF_TEST_TOTAL => 8,
|
||||
&TESTDEF_TEST_PROCESS => true
|
||||
&TESTDEF_NAME => 'synthetic',
|
||||
&TESTDEF_TOTAL => 8,
|
||||
},
|
||||
{
|
||||
&TESTDEF_TEST_NAME => 'real',
|
||||
&TESTDEF_TEST_TOTAL => 11,
|
||||
&TESTDEF_TEST_PROCESS => true,
|
||||
&TESTDEF_TEST_DB => true
|
||||
&TESTDEF_NAME => 'real',
|
||||
&TESTDEF_TOTAL => 11,
|
||||
&TESTDEF_DB => true,
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -385,55 +359,154 @@ my $oTestDef =
|
||||
};
|
||||
|
||||
####################################################################################################################################
|
||||
# testDefGet
|
||||
# Process normalized data into a more queryable form
|
||||
####################################################################################################################################
|
||||
sub testDefGet
|
||||
my $hTestDefHash; # An easier way to query hash version of the above
|
||||
my @stryModule; # Ordered list of modules
|
||||
my $hModuleTest; # Ordered list of tests for each module
|
||||
my $hCoverageType; # Coverage type for each code module (full/partial)
|
||||
my $hCoverageList; # Tests required for full code module coverage (if type full)
|
||||
|
||||
# Iterate each module
|
||||
foreach my $hModule (@{$oTestDef->{&TESTDEF_MODULE}})
|
||||
{
|
||||
return $oTestDef;
|
||||
}
|
||||
# Push the module onto the ordered list
|
||||
my $strModule = $hModule->{&TESTDEF_NAME};
|
||||
push(@stryModule, $strModule);
|
||||
|
||||
push @EXPORT, qw(testDefGet);
|
||||
|
||||
####################################################################################################################################
|
||||
# testDefModuleGet
|
||||
####################################################################################################################################
|
||||
sub testDefModuleGet
|
||||
{
|
||||
my $strModule = shift;
|
||||
|
||||
# Find the module
|
||||
foreach my $hModule (@{$oTestDef->{&TESTDEF_MODULE}})
|
||||
{
|
||||
if ($hModule->{&TESTDEF_MODULE_NAME} eq $strModule)
|
||||
{
|
||||
return $hModule;
|
||||
}
|
||||
}
|
||||
|
||||
confess &log(ASSERT, "unable to find module ${strModule}");
|
||||
}
|
||||
|
||||
push @EXPORT, qw(testDefModuleGet);
|
||||
|
||||
####################################################################################################################################
|
||||
# testDefModuleTestGet
|
||||
####################################################################################################################################
|
||||
sub testDefModuleTestGet
|
||||
{
|
||||
my $hModule = shift;
|
||||
my $strModuleTest = shift;
|
||||
# Iterate each test
|
||||
my @stryModuleTest;
|
||||
|
||||
foreach my $hModuleTest (@{$hModule->{&TESTDEF_TEST}})
|
||||
{
|
||||
if ($hModuleTest->{&TESTDEF_TEST_NAME} eq $strModuleTest)
|
||||
# Push the test on the order list
|
||||
my $strTest = $hModuleTest->{&TESTDEF_NAME};
|
||||
push(@stryModuleTest, $strTest);
|
||||
|
||||
# Resolve variables that can be set in the module or the test
|
||||
foreach my $strVar (
|
||||
TESTDEF_CONTAINER, TESTDEF_EXPECT, TESTDEF_PROCESS, TESTDEF_DB, TESTDEF_INDIVIDUAL)
|
||||
{
|
||||
return $hModuleTest;
|
||||
$hTestDefHash->{$strModule}{$strTest}{$strVar} = coalesce(
|
||||
$hModuleTest->{$strVar}, coalesce($hModule->{$strVar}, false));
|
||||
}
|
||||
|
||||
# Set test count
|
||||
$hTestDefHash->{$strModule}{$strTest}{&TESTDEF_TOTAL} = $hModuleTest->{&TESTDEF_TOTAL};
|
||||
|
||||
# Concatenate coverage for modules and tests
|
||||
foreach my $hCoverage ($hModule->{&TESTDEF_COVERAGE}, $hModuleTest->{&TESTDEF_COVERAGE})
|
||||
{
|
||||
foreach my $strCodeModule (sort(keys(%{$hCoverage})))
|
||||
{
|
||||
if (defined($hTestDefHash->{$strModule}{$strTest}{&TESTDEF_COVERAGE}{$strCodeModule}))
|
||||
{
|
||||
confess &log(ASSERT,
|
||||
"${strCodeModule} is defined for coverage in both module ${strModule} and test ${strTest}");
|
||||
}
|
||||
|
||||
$hTestDefHash->{$strModule}{$strTest}{&TESTDEF_COVERAGE}{$strCodeModule} = $hCoverage->{$strCodeModule};
|
||||
|
||||
# Build coverage type hash and make sure coverage type does not change
|
||||
if (!defined($hCoverageType->{$strCodeModule}))
|
||||
{
|
||||
$hCoverageType->{$strCodeModule} = $hCoverage->{$strCodeModule};
|
||||
}
|
||||
elsif ($hCoverageType->{$strCodeModule} != $hCoverage->{$strCodeModule})
|
||||
{
|
||||
confess &log(ASSERT, "cannot mix full/partial coverage for ${strCodeModule}");
|
||||
}
|
||||
|
||||
# Add to coverage list
|
||||
push(@{$hCoverageList->{$strCodeModule}}, {strModule=> $strModule, strTest => $strTest});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
confess &log(ASSERT, "unable to find module test ${strModuleTest}");
|
||||
$hModuleTest->{$strModule} = \@stryModuleTest;
|
||||
}
|
||||
|
||||
push @EXPORT, qw(testDefModuleTestGet);
|
||||
####################################################################################################################################
|
||||
# testDefModuleList
|
||||
####################################################################################################################################
|
||||
sub testDefModuleList
|
||||
{
|
||||
return @stryModule;
|
||||
}
|
||||
|
||||
push @EXPORT, qw(testDefModuleList);
|
||||
|
||||
####################################################################################################################################
|
||||
# testDefModule
|
||||
####################################################################################################################################
|
||||
sub testDefModule
|
||||
{
|
||||
my $strModule = shift;
|
||||
|
||||
if (!defined($hTestDefHash->{$strModule}))
|
||||
{
|
||||
confess &log(ASSERT, "unable to find module ${strModule}");
|
||||
}
|
||||
|
||||
return $hTestDefHash->{$strModule};
|
||||
}
|
||||
|
||||
push @EXPORT, qw(testDefModule);
|
||||
|
||||
|
||||
####################################################################################################################################
|
||||
# testDefModuleTestList
|
||||
####################################################################################################################################
|
||||
sub testDefModuleTestList
|
||||
{
|
||||
my $strModule = shift;
|
||||
|
||||
if (!defined($hModuleTest->{$strModule}))
|
||||
{
|
||||
confess &log(ASSERT, "unable to find module ${strModule}");
|
||||
}
|
||||
|
||||
return @{$hModuleTest->{$strModule}};
|
||||
}
|
||||
|
||||
push @EXPORT, qw(testDefModuleTestList);
|
||||
|
||||
####################################################################################################################################
|
||||
# testDefModuleTest
|
||||
####################################################################################################################################
|
||||
sub testDefModuleTest
|
||||
{
|
||||
my $strModule = shift;
|
||||
my $strModuleTest = shift;
|
||||
|
||||
if (!defined($hTestDefHash->{$strModule}{$strModuleTest}))
|
||||
{
|
||||
confess &log(ASSERT, "unable to find module ${strModule}, test ${strModuleTest}");
|
||||
}
|
||||
|
||||
return $hTestDefHash->{$strModule}{$strModuleTest};
|
||||
}
|
||||
|
||||
push @EXPORT, qw(testDefModuleTest);
|
||||
|
||||
####################################################################################################################################
|
||||
# testDefCoverageType
|
||||
####################################################################################################################################
|
||||
sub testDefCoverageType
|
||||
{
|
||||
return $hCoverageType;
|
||||
}
|
||||
|
||||
push @EXPORT, qw(testDefCoverageType);
|
||||
|
||||
####################################################################################################################################
|
||||
# testDefCoverageList
|
||||
####################################################################################################################################
|
||||
sub testDefCoverageList
|
||||
{
|
||||
return $hCoverageList;
|
||||
}
|
||||
|
||||
push @EXPORT, qw(testDefCoverageList);
|
||||
|
||||
1;
|
||||
|
@@ -28,6 +28,7 @@ use pgBackRestTest::Common::ContainerTest;
|
||||
use pgBackRestTest::Common::ExecuteTest;
|
||||
use pgBackRestTest::Common::ListTest;
|
||||
use pgBackRestTest::Common::RunTest;
|
||||
use pgBackRestTest::Common::VmTest;
|
||||
|
||||
####################################################################################################################################
|
||||
# new
|
||||
@@ -56,7 +57,6 @@ sub new
|
||||
$self->{strLogLevel},
|
||||
$self->{bLogForce},
|
||||
$self->{bShowOutputAsync},
|
||||
$self->{bCoverage},
|
||||
$self->{bNoCleanup},
|
||||
$self->{iRetry},
|
||||
) =
|
||||
@@ -76,7 +76,6 @@ sub new
|
||||
{name => 'strLogLevel'},
|
||||
{name => 'bLogForce'},
|
||||
{name => 'bShowOutputAsync'},
|
||||
{name => 'bCoverage'},
|
||||
{name => 'bNoCleanup'},
|
||||
{name => 'iRetry'},
|
||||
);
|
||||
@@ -166,7 +165,7 @@ sub run
|
||||
# Create command
|
||||
my $strCommand =
|
||||
($self->{oTest}->{&TEST_CONTAINER} ? 'docker exec -i -u ' . TEST_USER . " ${strImage} " : '') .
|
||||
($self->{bCoverage} ? testRunExe(
|
||||
(vmCoverage($self->{oTest}->{&TEST_VM}) ? testRunExe(
|
||||
abs_path($0), dirname($self->{strCoveragePath}), $self->{strBackRestBase}, $self->{oTest}->{&TEST_MODULE},
|
||||
$self->{oTest}->{&TEST_NAME}, defined($self->{oTest}->{&TEST_RUN}) ? $self->{oTest}->{&TEST_RUN} : 'all') :
|
||||
abs_path($0)) .
|
||||
@@ -180,7 +179,6 @@ sub run
|
||||
(defined($self->{oTest}->{&TEST_PROCESS}) ? ' --process-max=' . $self->{oTest}->{&TEST_PROCESS} : '') .
|
||||
($self->{strLogLevel} ne lc(INFO) ? " --log-level=$self->{strLogLevel}" : '') .
|
||||
' --pgsql-bin=' . $self->{oTest}->{&TEST_PGSQL_BIN} .
|
||||
($self->{bCoverage} ? ' --coverage' : '') .
|
||||
($self->{bLogForce} ? ' --log-force' : '') .
|
||||
($self->{bDryRun} ? ' --dry-run' : '') .
|
||||
($self->{bDryRun} ? ' --vm-out' : '') .
|
||||
|
@@ -51,9 +51,8 @@ sub testListGet
|
||||
my $iyModuleTestRun = shift;
|
||||
my $strDbVersion = shift;
|
||||
my $iProcessMax = shift;
|
||||
my $bCoverage = shift;
|
||||
my $bCoverageOnly = shift;
|
||||
|
||||
my $oTestDef = testDefGet();
|
||||
my $oyVm = vmGet();
|
||||
my $oyTestRun = [];
|
||||
|
||||
@@ -71,13 +70,17 @@ sub testListGet
|
||||
|
||||
foreach my $strTestOS (@stryTestOS)
|
||||
{
|
||||
foreach my $oModule (@{$$oTestDef{&TESTDEF_MODULE}})
|
||||
foreach my $strModule (testDefModuleList())
|
||||
{
|
||||
if (@{$stryModule} == 0 || grep(/^$$oModule{&TESTDEF_MODULE_NAME}$/i, @{$stryModule}))
|
||||
my $hModule = testDefModule($strModule);
|
||||
|
||||
if (@{$stryModule} == 0 || grep(/^$strModule$/i, @{$stryModule}))
|
||||
{
|
||||
foreach my $oTest (@{$$oModule{test}})
|
||||
foreach my $strModuleTest (testDefModuleTestList($strModule))
|
||||
{
|
||||
if (@{$stryModuleTest} == 0 || grep(/^$$oTest{&TESTDEF_TEST_NAME}$/i, @{$stryModuleTest}))
|
||||
my $hTest = testDefModuleTest($strModule, $strModuleTest);
|
||||
|
||||
if (@{$stryModuleTest} == 0 || grep(/^$strModuleTest$/i, @{$stryModuleTest}))
|
||||
{
|
||||
my $iDbVersionMin = -1;
|
||||
my $iDbVersionMax = -1;
|
||||
@@ -91,7 +94,7 @@ sub testListGet
|
||||
$strDbVersionKey = &VM_DB_MINIMAL;
|
||||
}
|
||||
|
||||
if (defined($$oTest{&TESTDEF_TEST_DB}) && $$oTest{&TESTDEF_TEST_DB})
|
||||
if (defined($hTest->{&TESTDEF_DB}) && $hTest->{&TESTDEF_DB})
|
||||
{
|
||||
$iDbVersionMin = 0;
|
||||
$iDbVersionMax = @{$$oyVm{$strTestOS}{$strDbVersionKey}} - 1;
|
||||
@@ -107,10 +110,10 @@ sub testListGet
|
||||
{
|
||||
# Individual tests will be each be run in a separate container. This is the default.
|
||||
my $bTestIndividual =
|
||||
!defined($$oTest{&TESTDEF_TEST_INDIVIDUAL}) || $$oTest{&TESTDEF_TEST_INDIVIDUAL} ? true : false;
|
||||
!defined($hTest->{&TESTDEF_INDIVIDUAL}) || $hTest->{&TESTDEF_INDIVIDUAL} ? true : false;
|
||||
|
||||
my $iTestRunMin = $bTestIndividual ? 1 : -1;
|
||||
my $iTestRunMax = $bTestIndividual ? $$oTest{&TESTDEF_TEST_TOTAL} : -1;
|
||||
my $iTestRunMax = $bTestIndividual ? $hTest->{&TESTDEF_TOTAL} : -1;
|
||||
|
||||
for (my $iTestRunIdx = $iTestRunMin; $iTestRunIdx <= $iTestRunMax; $iTestRunIdx++)
|
||||
{
|
||||
@@ -119,16 +122,12 @@ sub testListGet
|
||||
$bTestIndividual && @{$iyModuleTestRun} != 0 &&
|
||||
!grep(/^$iTestRunIdx$/i, @{$iyModuleTestRun}));
|
||||
|
||||
# Skip this run if coverage is requested and this test does not provide coverage
|
||||
next if (
|
||||
$bCoverage &&
|
||||
(($bTestIndividual && !defined($oTest->{&TESTDEF_TEST_COVERAGE}{$iTestRunIdx})) ||
|
||||
(!$bTestIndividual && !defined($oTest->{&TESTDEF_TEST_COVERAGE}{&TESTDEF_TEST_ALL}))) &&
|
||||
!defined($oModule->{&TESTDEF_TEST_COVERAGE}));
|
||||
# Skip this run if only coverage tests are requested and this test does not provide coverage
|
||||
next if ($bCoverageOnly && !defined($hTest->{&TESTDEF_COVERAGE}));
|
||||
|
||||
my $iyProcessMax = [defined($iProcessMax) ? $iProcessMax : 1];
|
||||
|
||||
if (defined($$oTest{&TESTDEF_TEST_PROCESS}) && $$oTest{&TESTDEF_TEST_PROCESS} &&
|
||||
if (defined($hTest->{&TESTDEF_PROCESS}) && $hTest->{&TESTDEF_PROCESS} &&
|
||||
!defined($iProcessMax) && $bFirstDbVersion)
|
||||
{
|
||||
$iyProcessMax = [1, 4];
|
||||
@@ -153,12 +152,12 @@ sub testListGet
|
||||
my $oTestRun =
|
||||
{
|
||||
&TEST_VM => $strTestOS,
|
||||
&TEST_CONTAINER => defined($oTest->{&TESTDEF_TEST_CONTAINER}) ?
|
||||
$oTest->{&TESTDEF_TEST_CONTAINER} : $oModule->{&TESTDEF_TEST_CONTAINER},
|
||||
&TEST_CONTAINER => defined($hTest->{&TESTDEF_CONTAINER}) ?
|
||||
$hTest->{&TESTDEF_CONTAINER} : $hModule->{&TESTDEF_CONTAINER},
|
||||
&TEST_PGSQL_BIN => $strPgSqlBin,
|
||||
&TEST_PERL_ARCH_PATH => $$oyVm{$strTestOS}{&VMDEF_PERL_ARCH_PATH},
|
||||
&TEST_MODULE => $$oModule{&TESTDEF_MODULE_NAME},
|
||||
&TEST_NAME => $$oTest{&TESTDEF_TEST_NAME},
|
||||
&TEST_MODULE => $strModule,
|
||||
&TEST_NAME => $strModuleTest,
|
||||
&TEST_RUN =>
|
||||
$iTestRunIdx == -1 ? (@{$iyModuleTestRun} == 0 ? undef : $iyModuleTestRun) :
|
||||
[$iTestRunIdx],
|
||||
|
@@ -22,6 +22,7 @@ use pgBackRest::Common::Wait;
|
||||
use pgBackRestTest::Common::DefineTest;
|
||||
use pgBackRestTest::Common::ExecuteTest;
|
||||
use pgBackRestTest::Common::LogTest;
|
||||
use pgBackRestTest::Common::VmTest;
|
||||
|
||||
####################################################################################################################################
|
||||
# Constant to use when bogus data is required
|
||||
@@ -118,7 +119,6 @@ sub process
|
||||
$self->{bDryRun},
|
||||
$self->{bCleanup},
|
||||
$self->{bLogForce},
|
||||
$self->{bCoverage},
|
||||
$self->{strPgUser},
|
||||
$self->{strBackRestUser},
|
||||
$self->{strGroup},
|
||||
@@ -141,7 +141,6 @@ sub process
|
||||
{name => 'bDryRun'},
|
||||
{name => 'bCleanup'},
|
||||
{name => 'bLogForce'},
|
||||
{name => 'bCoverage'},
|
||||
{name => 'strPgUser'},
|
||||
{name => 'strBackRestUser'},
|
||||
{name => 'strGroup'},
|
||||
@@ -157,12 +156,11 @@ sub process
|
||||
$self->cleanModule();
|
||||
|
||||
# Make sure the correct number of tests ran
|
||||
my $hModule = testDefModuleGet($self->{strModule});
|
||||
my $hModuleTest = testDefModuleTestGet($hModule, $self->{strModuleTest});
|
||||
my $hModuleTest = testDefModuleTest($self->{strModule}, $self->{strModuleTest});
|
||||
|
||||
if ($hModuleTest->{&TESTDEF_TEST_TOTAL} != $self->runCurrent())
|
||||
if ($hModuleTest->{&TESTDEF_TOTAL} != $self->runCurrent())
|
||||
{
|
||||
confess &log(ASSERT, "expected $hModuleTest->{&TESTDEF_TEST_TOTAL} tests to run but $self->{iRun} ran");
|
||||
confess &log(ASSERT, "expected $hModuleTest->{&TESTDEF_TOTAL} tests to run but $self->{iRun} ran");
|
||||
}
|
||||
|
||||
# Return from function and log return values if any
|
||||
@@ -205,14 +203,7 @@ sub begin
|
||||
# Else get the default expect setting
|
||||
else
|
||||
{
|
||||
my $hModule = testDefModuleGet($self->{strModule});
|
||||
my $hModuleTest = testDefModuleTestGet($hModule, $self->{strModuleTest});
|
||||
$self->{bExpect} =
|
||||
defined($hModuleTest->{&TESTDEF_EXPECT}) ?
|
||||
($hModuleTest->{&TESTDEF_EXPECT} ? true : false) :
|
||||
(defined($hModule->{&TESTDEF_EXPECT}) ?
|
||||
($hModule->{&TESTDEF_EXPECT} ? true : false) :
|
||||
false);
|
||||
$self->{bExpect} = (testDefModuleTest($self->{strModule}, $self->{strModuleTest}))->{&TESTDEF_EXPECT};
|
||||
}
|
||||
|
||||
# Increment the run counter;
|
||||
@@ -494,33 +485,9 @@ sub testRunExe
|
||||
my $bLog = shift;
|
||||
|
||||
# Limit Perl modules tested to what is defined in the test coverage (if it exists)
|
||||
my $hTestCoverage = (testDefModuleTest($strModule, $strTest))->{&TESTDEF_COVERAGE};
|
||||
my $strPerlModule;
|
||||
my $strPerlModuleLog;
|
||||
my $hTestCoverage;
|
||||
my $hTestDef = testDefGet();
|
||||
|
||||
foreach my $hTestModule (@{$hTestDef->{&TESTDEF_MODULE}})
|
||||
{
|
||||
if ($hTestModule->{&TESTDEF_MODULE_NAME} eq $strModule)
|
||||
{
|
||||
$hTestCoverage = $hTestModule->{&TESTDEF_TEST_COVERAGE};
|
||||
|
||||
foreach my $hTest (@{$hTestModule->{&TESTDEF_TEST}})
|
||||
{
|
||||
if (defined($strTest) && $hTest->{&TESTDEF_TEST_NAME} eq $strTest)
|
||||
{
|
||||
$hTestCoverage =
|
||||
defined($hTest->{&TESTDEF_TEST_COVERAGE}{$iRun}) ? $hTest->{&TESTDEF_TEST_COVERAGE}{$iRun} :
|
||||
$hTest->{&TESTDEF_TEST_COVERAGE}{&TESTDEF_TEST_ALL};
|
||||
|
||||
if (!defined($hTestCoverage))
|
||||
{
|
||||
$hTestCoverage = $hTestModule->{&TESTDEF_TEST_COVERAGE};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (defined($hTestCoverage))
|
||||
{
|
||||
@@ -535,9 +502,8 @@ sub testRunExe
|
||||
if (defined($strPerlModule))
|
||||
{
|
||||
$strExe =
|
||||
'perl -MDevel::Cover=-silent,1,-dir,' . $strCoveragePath . ',-subs_only,1' .
|
||||
",-select${strPerlModule},+inc," . $strBackRestBasePath .
|
||||
',-coverage,statement,branch,condition,path,subroutine' . " ${strExe}";
|
||||
"perl -MDevel::Cover=-silent,1,-dir,${strCoveragePath},-select${strPerlModule},+inc,${strBackRestBasePath}" .
|
||||
",-coverage,statement,branch,condition,path,subroutine ${strExe}";
|
||||
|
||||
if (defined($bLog) && $bLog)
|
||||
{
|
||||
@@ -559,7 +525,7 @@ sub backrestExe {return shift->{strBackRestExe}}
|
||||
sub backrestExeOriginal {return shift->{strBackRestExeOriginal}}
|
||||
sub backrestUser {return shift->{strBackRestUser}}
|
||||
sub basePath {return shift->{strBasePath}}
|
||||
sub coverage {return shift->{bCoverage}}
|
||||
sub coverage {vmBaseTest(shift->{strVm}, VM_OS_BASE_DEBIAN)}
|
||||
sub dataPath {return shift->basePath() . '/test/data'}
|
||||
sub doCleanup {return shift->{bCleanup}}
|
||||
sub doExpect {return shift->{bExpect}}
|
||||
|
@@ -275,4 +275,29 @@ sub vmGet
|
||||
|
||||
push @EXPORT, qw(vmGet);
|
||||
|
||||
####################################################################################################################################
|
||||
# vmBaseTest
|
||||
####################################################################################################################################
|
||||
sub vmBaseTest
|
||||
{
|
||||
my $strVm = shift;
|
||||
my $strDistroTest = shift;
|
||||
|
||||
return $oyVm->{$strVm}{&VM_OS_BASE} eq $strDistroTest ? true : false;
|
||||
}
|
||||
|
||||
push @EXPORT, qw(vmBaseTest);
|
||||
|
||||
####################################################################################################################################
|
||||
# vmCoverage
|
||||
####################################################################################################################################
|
||||
sub vmCoverage
|
||||
{
|
||||
my $strVm = shift;
|
||||
|
||||
return $strVm eq VM_ALL ? false : vmBaseTest($strVm, VM_OS_BASE_DEBIAN);
|
||||
}
|
||||
|
||||
push @EXPORT, qw(vmCoverage);
|
||||
|
||||
1;
|
||||
|
179
test/test.pl
179
test/test.pl
@@ -17,6 +17,7 @@ $SIG{__DIE__} = sub { Carp::confess @_ };
|
||||
use File::Basename qw(dirname);
|
||||
use Getopt::Long qw(GetOptions);
|
||||
use Cwd qw(abs_path cwd);
|
||||
use JSON::PP;
|
||||
use Pod::Usage qw(pod2usage);
|
||||
use POSIX qw(ceil strftime);
|
||||
use Time::HiRes qw(gettimeofday);
|
||||
@@ -39,6 +40,7 @@ use BackRestDoc::Custom::DocCustomRelease;
|
||||
|
||||
use pgBackRestTest::Common::ContainerTest;
|
||||
use pgBackRestTest::Common::CiTest;
|
||||
use pgBackRestTest::Common::DefineTest;
|
||||
use pgBackRestTest::Common::ExecuteTest;
|
||||
use pgBackRestTest::Common::HostGroupTest;
|
||||
use pgBackRestTest::Common::JobTest;
|
||||
@@ -69,11 +71,11 @@ test.pl [options]
|
||||
--log-force force overwrite of current test log files
|
||||
--no-lint disable static source code analysis
|
||||
--build-only compile the C library / packages and run tests only
|
||||
--coverage perform coverage analysis
|
||||
--coverage-only only run coverage tests (as a subset of selected tests)
|
||||
--smart perform libc/package builds only when source timestamps have changed
|
||||
--no-package do not build packages
|
||||
--no-ci-config don't overwrite the current continuous integration config
|
||||
--dev --no-lint --smart --no-package --vm-out --process-max=1 --retry=0 --ci-no-config
|
||||
--dev --no-lint --smart --no-package --vm-out --process-max=1
|
||||
|
||||
Configuration Options:
|
||||
--psql-bin path to the psql executables (e.g. /usr/lib/postgresql/9.3/bin/)
|
||||
@@ -113,13 +115,13 @@ my $bHelp = false;
|
||||
my $bQuiet = false;
|
||||
my $strDbVersion = 'minimal';
|
||||
my $bLogForce = false;
|
||||
my $strVm = VM_ALL;
|
||||
my $strVm;
|
||||
my $strVmHost = VM_HOST_DEFAULT;
|
||||
my $bVmBuild = false;
|
||||
my $bVmForce = false;
|
||||
my $bNoLint = false;
|
||||
my $bBuildOnly = false;
|
||||
my $bCoverage = false;
|
||||
my $bCoverageOnly = false;
|
||||
my $bSmart = false;
|
||||
my $bNoPackage = false;
|
||||
my $bNoCiConfig = false;
|
||||
@@ -151,7 +153,7 @@ GetOptions ('q|quiet' => \$bQuiet,
|
||||
'build-only' => \$bBuildOnly,
|
||||
'no-package' => \$bNoPackage,
|
||||
'no-ci-config' => \$bNoCiConfig,
|
||||
'coverage' => \$bCoverage,
|
||||
'coverage-only' => \$bCoverageOnly,
|
||||
'smart' => \$bSmart,
|
||||
'dev' => \$bDev,
|
||||
'retry=s' => \$iRetry)
|
||||
@@ -190,7 +192,6 @@ eval
|
||||
$bNoLint = true;
|
||||
$bSmart = true;
|
||||
$bNoPackage = true;
|
||||
$bNoCiConfig = true;
|
||||
$bVmOut = true;
|
||||
$iProcessMax = 1;
|
||||
}
|
||||
@@ -231,18 +232,27 @@ eval
|
||||
$strTestPath = cwd() . '/test';
|
||||
}
|
||||
|
||||
# Coverage can only be run with u16 containers due to version compatibility issues
|
||||
if ($bCoverage)
|
||||
if ($bCoverageOnly)
|
||||
{
|
||||
if ($strVm eq VM_ALL)
|
||||
if (!defined($strVm))
|
||||
{
|
||||
&log(INFO, "Set --vm=${strVmHost} for coverage testing");
|
||||
$strVm = $strVmHost;
|
||||
}
|
||||
elsif ($strVm ne $strVmHost)
|
||||
elsif ($strVm eq VM_ALL)
|
||||
{
|
||||
confess &log(ERROR, "only --vm=${strVmHost} can be used for coverage testing");
|
||||
confess &log(ERROR, "select a single Debian-based VM for coverage testing");
|
||||
}
|
||||
elsif (!vmCoverage($strVm))
|
||||
{
|
||||
confess &log(ERROR, "only Debian-based VMs can be used for coverage testing");
|
||||
}
|
||||
}
|
||||
|
||||
# If VM is not defined then set it to all
|
||||
if (!defined($strVm))
|
||||
{
|
||||
$strVm = VM_ALL;
|
||||
}
|
||||
|
||||
# Get the base backrest path
|
||||
@@ -572,7 +582,7 @@ eval
|
||||
# Determine which tests to run
|
||||
#-----------------------------------------------------------------------------------------------------------------------
|
||||
my $oyTestRun = testListGet(
|
||||
$strVm, \@stryModule, \@stryModuleTest, \@iyModuleTestRun, $strDbVersion, $iProcessMax, $bCoverage);
|
||||
$strVm, \@stryModule, \@stryModuleTest, \@iyModuleTestRun, $strDbVersion, $iProcessMax, $bCoverageOnly);
|
||||
|
||||
if (@{$oyTestRun} == 0)
|
||||
{
|
||||
@@ -650,8 +660,7 @@ eval
|
||||
{
|
||||
my $oJob = new pgBackRestTest::Common::JobTest(
|
||||
$strBackRestBase, $strTestPath, $strCoveragePath, $$oyTestRun[$iTestIdx], $bDryRun, $bVmOut, $iVmIdx,
|
||||
$iVmMax, $iTestIdx, $iTestMax, $strLogLevel, $bLogForce, $bShowOutputAsync, $bCoverage, $bNoCleanup,
|
||||
$iRetry);
|
||||
$iVmMax, $iTestIdx, $iTestMax, $strLogLevel, $bLogForce, $bShowOutputAsync, $bNoCleanup, $iRetry);
|
||||
$iTestIdx++;
|
||||
|
||||
if ($oJob->run())
|
||||
@@ -665,18 +674,133 @@ eval
|
||||
}
|
||||
while ($iVmTotal > 0);
|
||||
|
||||
# Write out coverage info
|
||||
# Write out coverage info and test coverage
|
||||
#-----------------------------------------------------------------------------------------------------------------------
|
||||
if ($bCoverage)
|
||||
my $iUncoveredCodeModuleTotal = 0;
|
||||
|
||||
if (vmCoverage($strVm) && !$bDryRun)
|
||||
{
|
||||
&log(INFO, 'Writing coverage report');
|
||||
&log(INFO, 'writing coverage report');
|
||||
executeTest("rm -rf ${strBackRestBase}/test/coverage");
|
||||
executeTest("cp -rp ${strCoveragePath} ${strCoveragePath}_temp");
|
||||
executeTest("cover -report json -outputdir ${strBackRestBase}/test/coverage ${strCoveragePath}_temp");
|
||||
executeTest("rm -rf ${strCoveragePath}_temp");
|
||||
executeTest("cp -rp ${strCoveragePath} ${strCoveragePath}_temp");
|
||||
executeTest("cover -outputdir ${strBackRestBase}/test/coverage ${strCoveragePath}_temp");
|
||||
executeTest("rm -rf ${strCoveragePath}_temp");
|
||||
executeTest(
|
||||
LIB_COVER_EXE . " -report json -outputdir ${strBackRestBase}/test/coverage ${strCoveragePath}_temp",
|
||||
{bSuppressStdErr => true});
|
||||
executeTest("sudo rm -rf ${strCoveragePath}_temp");
|
||||
executeTest("sudo cp -rp ${strCoveragePath} ${strCoveragePath}_temp");
|
||||
executeTest(
|
||||
LIB_COVER_EXE . " -outputdir ${strBackRestBase}/test/coverage ${strCoveragePath}_temp",
|
||||
{bSuppressStdErr => true});
|
||||
executeTest("sudo rm -rf ${strCoveragePath}_temp");
|
||||
|
||||
# Determine which modules were covered (only check coverage if all tests were successful)
|
||||
#-----------------------------------------------------------------------------------------------------------------------
|
||||
if ($iTestFail == 0)
|
||||
{
|
||||
my $hModuleTest; # Everything that was run
|
||||
|
||||
# Build a hash of all modules, tests, and runs that were executed
|
||||
foreach my $hTestRun (@{$oyTestRun})
|
||||
{
|
||||
# Get coverage for the module
|
||||
my $strModule = $hTestRun->{&TEST_MODULE};
|
||||
my $hModule = testDefModule($strModule);
|
||||
|
||||
# Get coverage for the test
|
||||
my $strTest = $hTestRun->{&TEST_NAME};
|
||||
my $hTest = testDefModuleTest($strModule, $strTest);
|
||||
|
||||
# If no tests are listed it means all of them were run
|
||||
if (@{$hTestRun->{&TEST_RUN}} == 0)
|
||||
{
|
||||
$hModuleTest->{$strModule}{$strTest} = true;
|
||||
}
|
||||
}
|
||||
|
||||
# Load the results of coverage testing from JSON
|
||||
my $oJSON = JSON::PP->new()->allow_nonref();
|
||||
my $hCoverageResult = $oJSON->decode(fileStringRead("${strBackRestBase}/test/coverage/cover.json"));
|
||||
|
||||
# Now compare against code modules that should have full coverage
|
||||
my $hCoverageList = testDefCoverageList();
|
||||
my $hCoverageType = testDefCoverageType();
|
||||
my $hCoverageActual;
|
||||
|
||||
foreach my $strCodeModule (sort(keys(%{$hCoverageList})))
|
||||
{
|
||||
if (@{$hCoverageList->{$strCodeModule}} > 0)
|
||||
{
|
||||
my $iCoverageTotal = 0;
|
||||
|
||||
foreach my $hTest (@{$hCoverageList->{$strCodeModule}})
|
||||
{
|
||||
if (!defined($hModuleTest->{$hTest->{strModule}}{$hTest->{strTest}}))
|
||||
{
|
||||
next;
|
||||
}
|
||||
|
||||
$iCoverageTotal++;
|
||||
}
|
||||
|
||||
if (@{$hCoverageList->{$strCodeModule}} == $iCoverageTotal)
|
||||
{
|
||||
$hCoverageActual->{$strCodeModule} = $hCoverageType->{$strCodeModule};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (keys(%{$hCoverageActual}) > 0)
|
||||
{
|
||||
&log(INFO, 'test coverage for: ' . join(', ', sort(keys(%{$hCoverageActual}))));
|
||||
}
|
||||
else
|
||||
{
|
||||
&log(INFO, 'no code modules had all tests run required for coverage');
|
||||
}
|
||||
|
||||
foreach my $strCodeModule (sort(keys(%{$hCoverageActual})))
|
||||
{
|
||||
# Get summary results (??? Need to fix this for coverage testing on bin/pgbackrest since .pm is required)
|
||||
my $hCoverageResultAll =
|
||||
$hCoverageResult->{'summary'}
|
||||
{"${strBackRestBase}/lib/" . BACKREST_NAME . "/${strCodeModule}.pm"}{total};
|
||||
|
||||
if (!defined($hCoverageResultAll))
|
||||
{
|
||||
confess &log(ERROR, "unable to find coverage results for ${strCodeModule}");
|
||||
}
|
||||
|
||||
# Check that all code has been covered
|
||||
if ($hCoverageActual->{$strCodeModule} == TESTDEF_COVERAGE_FULL)
|
||||
{
|
||||
my $iUncoveredLines =
|
||||
$hCoverageResultAll->{total} - $hCoverageResultAll->{covered} - $hCoverageResultAll->{uncoverable};
|
||||
|
||||
if ($iUncoveredLines != 0)
|
||||
{
|
||||
&log(ERROR, "code module ${strCodeModule} is not fully covered");
|
||||
$iUncoveredCodeModuleTotal++;
|
||||
}
|
||||
}
|
||||
# Else test how much partial coverage where was
|
||||
else
|
||||
{
|
||||
my $iCoveragePercent = int(
|
||||
($hCoverageResultAll->{covered} + $hCoverageResultAll->{uncoverable}) * 100 /
|
||||
$hCoverageResultAll->{total});
|
||||
|
||||
if ($iCoveragePercent == 100)
|
||||
{
|
||||
&log(ERROR, "code module ${strCodeModule} has 100% coverage but is not marked fully covered");
|
||||
$iUncoveredCodeModuleTotal++;
|
||||
}
|
||||
else
|
||||
{
|
||||
&log(INFO, "code module ${strCodeModule} has (expected) partial coverage of ${iCoveragePercent}%");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Print test info and exit
|
||||
@@ -687,12 +811,16 @@ eval
|
||||
}
|
||||
else
|
||||
{
|
||||
&log(INFO, 'TESTS COMPLETED ' . ($iTestFail == 0 ? 'SUCCESSFULLY' : "WITH ${iTestFail} FAILURE(S)") .
|
||||
($iTestRetry == 0 ? '' : ", ${iTestRetry} RETRY(IES)") .
|
||||
&log(INFO,
|
||||
'TESTS COMPLETED ' . ($iTestFail == 0 ? 'SUCCESSFULLY' .
|
||||
($iUncoveredCodeModuleTotal == 0 ? '' : " WITH ${iUncoveredCodeModuleTotal} MODULE(S) MISSING COVERAGE") :
|
||||
"WITH ${iTestFail} FAILURE(S)") . ($iTestRetry == 0 ? '' : ", ${iTestRetry} RETRY(IES)") .
|
||||
' (' . (time() - $lStartTime) . 's)');
|
||||
|
||||
exit 1 if ($iTestFail > 0 || $iUncoveredCodeModuleTotal > 0);
|
||||
}
|
||||
|
||||
exit $iTestFail == 0 ? 0 : 1;
|
||||
exit 0;
|
||||
}
|
||||
|
||||
################################################################################################################################
|
||||
@@ -713,7 +841,6 @@ eval
|
||||
$strDbVersion ne 'minimal' ? $strDbVersion: undef, # Db version
|
||||
$stryModule[0], $stryModuleTest[0], \@iyModuleTestRun, # Module info
|
||||
$iProcessMax, $bVmOut, $bDryRun, $bNoCleanup, $bLogForce, # Test options
|
||||
$bCoverage, # Test options
|
||||
TEST_USER, BACKREST_USER, TEST_GROUP); # User/group info
|
||||
|
||||
if (!$bNoCleanup)
|
||||
|
Reference in New Issue
Block a user