1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2026-05-22 10:15:16 +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:
David Steele
2017-04-10 12:31:30 -04:00
parent eb4918d018
commit 367e06f4be
12 changed files with 648 additions and 358 deletions
+16 -16
View File
@@ -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" .
+74 -10
View File
@@ -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);
}
+289 -216
View File
@@ -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_COVERAGE =>
{
&TESTDEF_TEST_ALL =>
{
&TESTDEF_MODULE_ARCHIVE_COMMON => TESTDEF_COVERAGE_PARTIAL,
}
&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_COVERAGE =>
{
&TESTDEF_TEST_ALL =>
{
&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 => TESTDEF_COVERAGE_FULL,
&TESTDEF_MODULE_ARCHIVE_PUSH_ASYNC => TESTDEF_COVERAGE_FULL,
&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;
+2 -4
View File
@@ -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' : '') .
+19 -20
View File
@@ -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],
+9 -43
View File
@@ -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}}
+25
View File
@@ -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;