2017-02-21 15:59:23 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# JobTest.pm - Run a test job and monitor progress
|
|
|
|
####################################################################################################################################
|
|
|
|
package pgBackRestTest::Common::JobTest;
|
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# Perl includes
|
|
|
|
####################################################################################################################################
|
|
|
|
use strict;
|
|
|
|
use warnings FATAL => qw(all);
|
|
|
|
use Carp qw(confess);
|
|
|
|
use English '-no_match_vars';
|
|
|
|
|
|
|
|
use Cwd qw(abs_path);
|
|
|
|
use Exporter qw(import);
|
|
|
|
our @EXPORT = qw();
|
2017-10-12 18:55:48 +02:00
|
|
|
use File::Basename qw(dirname basename);
|
2017-02-21 15:59:23 +02:00
|
|
|
use POSIX qw(ceil);
|
2021-01-24 23:24:14 +02:00
|
|
|
use Time::HiRes qw(gettimeofday usleep);
|
2017-02-21 15:59:23 +02:00
|
|
|
|
2020-03-10 21:41:56 +02:00
|
|
|
use pgBackRestDoc::Common::Exception;
|
|
|
|
use pgBackRestDoc::Common::Log;
|
|
|
|
use pgBackRestDoc::Common::String;
|
2020-03-10 23:57:02 +02:00
|
|
|
use pgBackRestDoc::ProjectInfo;
|
2020-03-10 21:12:44 +02:00
|
|
|
|
2018-11-03 22:34:04 +02:00
|
|
|
use pgBackRestTest::Common::BuildTest;
|
2017-02-21 15:59:23 +02:00
|
|
|
use pgBackRestTest::Common::ContainerTest;
|
2019-05-15 19:04:56 +02:00
|
|
|
use pgBackRestTest::Common::CoverageTest;
|
2020-03-10 21:12:44 +02:00
|
|
|
use pgBackRestTest::Common::DbVersion;
|
2017-10-12 18:55:48 +02:00
|
|
|
use pgBackRestTest::Common::DefineTest;
|
2017-02-21 15:59:23 +02:00
|
|
|
use pgBackRestTest::Common::ExecuteTest;
|
|
|
|
use pgBackRestTest::Common::ListTest;
|
2017-02-21 18:47:45 +02:00
|
|
|
use pgBackRestTest::Common::RunTest;
|
2017-04-10 18:31:30 +02:00
|
|
|
use pgBackRestTest::Common::VmTest;
|
2017-02-21 15:59:23 +02:00
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# new
|
|
|
|
####################################################################################################################################
|
|
|
|
sub new
|
|
|
|
{
|
|
|
|
my $class = shift; # Class name
|
|
|
|
|
|
|
|
# Create the class hash
|
|
|
|
my $self = {};
|
|
|
|
bless $self, $class;
|
|
|
|
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
(
|
|
|
|
my $strOperation,
|
2017-06-09 23:51:41 +02:00
|
|
|
$self->{oStorageTest},
|
2017-02-21 15:59:23 +02:00
|
|
|
$self->{strBackRestBase},
|
|
|
|
$self->{strTestPath},
|
|
|
|
$self->{oTest},
|
|
|
|
$self->{bDryRun},
|
|
|
|
$self->{bVmOut},
|
|
|
|
$self->{iVmIdx},
|
|
|
|
$self->{iVmMax},
|
2021-01-24 22:35:40 +02:00
|
|
|
$self->{strMakeCmd},
|
2017-02-21 15:59:23 +02:00
|
|
|
$self->{iTestIdx},
|
|
|
|
$self->{iTestMax},
|
|
|
|
$self->{strLogLevel},
|
2018-07-21 01:03:46 +02:00
|
|
|
$self->{strLogLevelTest},
|
2019-12-17 22:23:07 +02:00
|
|
|
$self->{strLogLevelTestFile},
|
2020-03-22 16:12:29 +02:00
|
|
|
$self->{bLogTimestamp},
|
2017-02-21 15:59:23 +02:00
|
|
|
$self->{bShowOutputAsync},
|
|
|
|
$self->{bNoCleanup},
|
2017-02-22 05:10:02 +02:00
|
|
|
$self->{iRetry},
|
2023-01-28 13:55:53 +02:00
|
|
|
$self->{bBackTraceUnit},
|
2018-05-18 12:45:14 +02:00
|
|
|
$self->{bValgrindUnit},
|
|
|
|
$self->{bCoverageUnit},
|
2019-05-15 19:04:56 +02:00
|
|
|
$self->{bCoverageSummary},
|
2018-05-18 12:45:14 +02:00
|
|
|
$self->{bOptimize},
|
|
|
|
$self->{bProfile},
|
2019-09-28 20:02:12 +02:00
|
|
|
$self->{iScale},
|
2019-12-12 05:11:04 +02:00
|
|
|
$self->{strTimeZone},
|
2018-05-18 12:45:14 +02:00
|
|
|
$self->{bDebug},
|
2019-02-27 17:09:19 +02:00
|
|
|
$self->{bDebugTestTrace},
|
2019-04-24 02:52:03 +02:00
|
|
|
$self->{iBuildMax},
|
2017-02-21 15:59:23 +02:00
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
|
|
|
__PACKAGE__ . '->new', \@_,
|
2017-06-09 23:51:41 +02:00
|
|
|
{name => 'oStorageTest'},
|
2017-02-21 15:59:23 +02:00
|
|
|
{name => 'strBackRestBase'},
|
|
|
|
{name => 'strTestPath'},
|
|
|
|
{name => 'oTest'},
|
|
|
|
{name => 'bDryRun'},
|
|
|
|
{name => 'bVmOut'},
|
|
|
|
{name => 'iVmIdx'},
|
|
|
|
{name => 'iVmMax'},
|
2021-01-24 22:35:40 +02:00
|
|
|
{name => 'strMakeCmd'},
|
2017-02-21 15:59:23 +02:00
|
|
|
{name => 'iTestIdx'},
|
|
|
|
{name => 'iTestMax'},
|
|
|
|
{name => 'strLogLevel'},
|
2018-07-21 01:03:46 +02:00
|
|
|
{name => 'strLogLevelTest'},
|
2019-12-17 22:23:07 +02:00
|
|
|
{name => 'strLogLevelTestFile'},
|
2020-03-22 16:12:29 +02:00
|
|
|
{name => 'bLogTimestamp'},
|
2017-02-21 15:59:23 +02:00
|
|
|
{name => 'bShowOutputAsync'},
|
|
|
|
{name => 'bNoCleanup'},
|
2017-02-22 05:10:02 +02:00
|
|
|
{name => 'iRetry'},
|
2023-01-28 13:55:53 +02:00
|
|
|
{name => 'bBackTraceUnit'},
|
2018-05-18 12:45:14 +02:00
|
|
|
{name => 'bValgrindUnit'},
|
|
|
|
{name => 'bCoverageUnit'},
|
2019-05-15 19:04:56 +02:00
|
|
|
{name => 'bCoverageSummary'},
|
2018-05-18 12:45:14 +02:00
|
|
|
{name => 'bOptimize'},
|
|
|
|
{name => 'bProfile'},
|
2019-09-28 20:02:12 +02:00
|
|
|
{name => 'iScale'},
|
2019-12-12 05:11:04 +02:00
|
|
|
{name => 'strTimeZone', required => false},
|
2018-05-18 12:45:14 +02:00
|
|
|
{name => 'bDebug'},
|
2019-02-27 17:09:19 +02:00
|
|
|
{name => 'bDebugTestTrace'},
|
2019-04-24 02:52:03 +02:00
|
|
|
{name => 'iBuildMax'},
|
2017-02-21 15:59:23 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
# Set try to 0
|
|
|
|
$self->{iTry} = 0;
|
|
|
|
|
2022-07-27 16:32:32 +02:00
|
|
|
# Setup the path where unit test will be built
|
2022-07-29 16:31:36 +02:00
|
|
|
$self->{strUnitPath} = "$self->{strTestPath}/unit-$self->{iVmIdx}/$self->{oTest}->{&TEST_VM}";
|
2019-10-08 18:06:30 +02:00
|
|
|
$self->{strDataPath} = "$self->{strTestPath}/data-$self->{iVmIdx}";
|
2021-01-24 23:24:14 +02:00
|
|
|
$self->{strRepoPath} = "$self->{strTestPath}/repo";
|
2017-10-12 18:55:48 +02:00
|
|
|
|
2017-02-21 15:59:23 +02:00
|
|
|
# Return from function and log return values if any
|
|
|
|
return logDebugReturn
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
{name => 'self', value => $self, trace => true}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# run
|
|
|
|
####################################################################################################################################
|
|
|
|
sub run
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
(my $strOperation) = logDebugParam (__PACKAGE__ . '->run', \@_,);
|
|
|
|
|
2017-10-12 18:55:48 +02:00
|
|
|
# Start the test timer
|
|
|
|
my $fTestStartTime = gettimeofday();
|
|
|
|
|
2017-02-21 15:59:23 +02:00
|
|
|
# Was the job run?
|
|
|
|
my $bRun = false;
|
|
|
|
|
|
|
|
# Should the job be run?
|
|
|
|
$self->{iTry}++;
|
|
|
|
|
2017-02-22 05:10:02 +02:00
|
|
|
if ($self->{iTry} <= ($self->{iRetry} + 1))
|
2017-02-21 15:59:23 +02:00
|
|
|
{
|
2017-02-22 05:10:02 +02:00
|
|
|
if ($self->{iTry} != 1 && $self->{iTry} == ($self->{iRetry} + 1))
|
2017-02-21 15:59:23 +02:00
|
|
|
{
|
|
|
|
$self->{strLogLevel} = lc(DEBUG);
|
|
|
|
}
|
|
|
|
|
2017-10-12 18:55:48 +02:00
|
|
|
my $strTest = sprintf(
|
|
|
|
'P%0' . length($self->{iVmMax}) . 'd-T%0' . length($self->{iTestMax}) . 'd/%0' .
|
|
|
|
length($self->{iTestMax}) . "d - ", $self->{iVmIdx} + 1, $self->{iTestIdx} + 1, $self->{iTestMax}) .
|
|
|
|
'vm=' . $self->{oTest}->{&TEST_VM} .
|
|
|
|
', module=' . $self->{oTest}->{&TEST_MODULE} .
|
|
|
|
', test=' . $self->{oTest}->{&TEST_NAME} .
|
|
|
|
(defined($self->{oTest}->{&TEST_RUN}) ? ', run=' . join(',', sort(@{$self->{oTest}->{&TEST_RUN}})) : '') .
|
2020-01-08 18:54:44 +02:00
|
|
|
(defined($self->{oTest}->{&TEST_DB}) ? ', pg-version=' . $self->{oTest}->{&TEST_DB} : '') .
|
2017-10-12 18:55:48 +02:00
|
|
|
($self->{iTry} > 1 ? ' (retry ' . ($self->{iTry} - 1) . ')' : '');
|
2017-02-21 15:59:23 +02:00
|
|
|
|
|
|
|
my $strImage = 'test-' . $self->{iVmIdx};
|
|
|
|
my $strDbVersion = (defined($self->{oTest}->{&TEST_DB}) ? $self->{oTest}->{&TEST_DB} : PG_VERSION_94);
|
|
|
|
$strDbVersion =~ s/\.//;
|
|
|
|
|
|
|
|
&log($self->{bDryRun} && !$self->{bVmOut} || $self->{bShowOutputAsync} ? INFO : DETAIL, "${strTest}" .
|
2017-05-12 22:27:06 +02:00
|
|
|
(!($self->{bDryRun} || !$self->{bVmOut}) || $self->{bShowOutputAsync} ? "\n" : ''));
|
2017-02-21 15:59:23 +02:00
|
|
|
|
|
|
|
my $strHostTestPath = "$self->{strTestPath}/${strImage}";
|
2022-05-31 23:28:58 +02:00
|
|
|
my $strVmTestPath = $strHostTestPath;
|
2017-02-21 15:59:23 +02:00
|
|
|
|
2021-04-28 16:58:45 +02:00
|
|
|
# Don't create the container if this is a dry run unless output from the VM is required. Output can be requested
|
2017-02-21 15:59:23 +02:00
|
|
|
# to get more information about the specific tests that will be run.
|
2017-05-12 22:27:06 +02:00
|
|
|
if (!$self->{bDryRun} || $self->{bVmOut})
|
2017-02-21 15:59:23 +02:00
|
|
|
{
|
|
|
|
# Create host test directory
|
2017-06-09 23:51:41 +02:00
|
|
|
$self->{oStorageTest}->pathCreate($strHostTestPath, {strMode => '0770'});
|
2017-02-21 15:59:23 +02:00
|
|
|
|
2022-07-27 16:32:32 +02:00
|
|
|
# Create unit directory
|
|
|
|
if ($self->{oTest}->{&TEST_C} && !$self->{oStorageTest}->pathExists($self->{strUnitPath}))
|
2018-01-26 23:41:17 +02:00
|
|
|
{
|
2022-07-27 16:32:32 +02:00
|
|
|
$self->{oStorageTest}->pathCreate($self->{strUnitPath}, {strMode => '0770', bCreateParent => true});
|
2018-01-26 23:41:17 +02:00
|
|
|
}
|
2017-10-12 18:55:48 +02:00
|
|
|
|
2019-10-08 18:06:30 +02:00
|
|
|
# Create data directory
|
|
|
|
if ($self->{oTest}->{&TEST_C} && !$self->{oStorageTest}->pathExists($self->{strDataPath}))
|
2018-09-16 21:58:46 +02:00
|
|
|
{
|
2019-10-08 18:06:30 +02:00
|
|
|
$self->{oStorageTest}->pathCreate($self->{strDataPath}, {strMode => '0770'});
|
2018-09-16 21:58:46 +02:00
|
|
|
}
|
|
|
|
|
2022-07-27 16:32:32 +02:00
|
|
|
# Create ccache directory
|
|
|
|
my $strCCachePath = "$self->{strTestPath}/ccache-$self->{iVmIdx}/$self->{oTest}->{&TEST_VM}";
|
|
|
|
|
|
|
|
if ($self->{oTest}->{&TEST_C} && !$self->{oStorageTest}->pathExists($strCCachePath))
|
|
|
|
{
|
|
|
|
$self->{oStorageTest}->pathCreate($strCCachePath, {strMode => '0770', bCreateParent => true});
|
|
|
|
}
|
|
|
|
|
2017-02-21 15:59:23 +02:00
|
|
|
if ($self->{oTest}->{&TEST_CONTAINER})
|
|
|
|
{
|
2019-10-08 18:06:30 +02:00
|
|
|
if ($self->{oTest}->{&TEST_VM} ne VM_NONE)
|
|
|
|
{
|
2020-03-15 16:09:27 +02:00
|
|
|
my $strBinPath = $self->{strTestPath} . '/bin/' . $self->{oTest}->{&TEST_VM} . '/' . PROJECT_EXE;
|
2022-07-27 16:32:32 +02:00
|
|
|
my $strBuildPath = $self->{strTestPath} . '/build/' . $self->{oTest}->{&TEST_VM};
|
2020-03-15 16:09:27 +02:00
|
|
|
|
2019-10-08 18:06:30 +02:00
|
|
|
executeTest(
|
|
|
|
'docker run -itd -h ' . $self->{oTest}->{&TEST_VM} . "-test --name=${strImage}" .
|
|
|
|
" -v ${strHostTestPath}:${strVmTestPath}" .
|
2022-07-27 16:32:32 +02:00
|
|
|
($self->{oTest}->{&TEST_C} ? " -v $self->{strUnitPath}:$self->{strUnitPath}" : '') .
|
2019-10-08 18:06:30 +02:00
|
|
|
($self->{oTest}->{&TEST_C} ? " -v $self->{strDataPath}:$self->{strDataPath}" : '') .
|
2020-03-15 16:09:27 +02:00
|
|
|
" -v $self->{strBackRestBase}:$self->{strBackRestBase}" .
|
2022-07-27 16:32:32 +02:00
|
|
|
" -v $self->{strRepoPath}:$self->{strRepoPath}" .
|
2020-03-15 16:09:27 +02:00
|
|
|
($self->{oTest}->{&TEST_BIN_REQ} ? " -v ${strBinPath}:${strBinPath}:ro" : '') .
|
2022-07-29 16:31:36 +02:00
|
|
|
($self->{oTest}->{&TEST_C} ? " -v ${strBuildPath}:${strBuildPath}:ro" : '') .
|
|
|
|
($self->{oTest}->{&TEST_C} ? " -v ${strCCachePath}:/home/${\TEST_USER}/.ccache" : '') .
|
2020-03-15 16:09:27 +02:00
|
|
|
' ' . containerRepo() . ':' . $self->{oTest}->{&TEST_VM} . '-test',
|
2019-10-08 18:06:30 +02:00
|
|
|
{bSuppressStdErr => true});
|
|
|
|
}
|
2017-02-21 15:59:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-29 16:31:36 +02:00
|
|
|
# Disable debug/coverage for performance and profile tests
|
|
|
|
my $bPerformance = $self->{oTest}->{&TEST_TYPE} eq TESTDEF_PERFORMANCE;
|
|
|
|
|
|
|
|
if ($bPerformance || $self->{bProfile})
|
|
|
|
{
|
|
|
|
$self->{bDebug} = false;
|
|
|
|
$self->{bDebugTestTrace} = false;
|
|
|
|
$self->{bCoverageUnit} = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Is coverage being tested?
|
|
|
|
my $bCoverage = vmCoverageC($self->{oTest}->{&TEST_VM}) && $self->{bCoverageUnit};
|
|
|
|
|
2017-02-21 15:59:23 +02:00
|
|
|
# Create run parameters
|
|
|
|
my $strCommandRunParam = '';
|
|
|
|
|
|
|
|
foreach my $iRunIdx (@{$self->{oTest}->{&TEST_RUN}})
|
|
|
|
{
|
|
|
|
$strCommandRunParam .= ' --run=' . $iRunIdx;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$self->{bDryRun} || $self->{bVmOut})
|
|
|
|
{
|
2021-01-24 23:24:14 +02:00
|
|
|
my $strCommand = undef; # Command to run test
|
|
|
|
|
2022-07-27 16:32:32 +02:00
|
|
|
# If testing with C harness
|
2022-07-29 16:31:36 +02:00
|
|
|
if ($self->{oTest}->{&TEST_C})
|
2017-10-12 18:55:48 +02:00
|
|
|
{
|
2021-01-24 23:24:14 +02:00
|
|
|
# Create command
|
|
|
|
# ------------------------------------------------------------------------------------------------------------------
|
|
|
|
# Build filename for valgrind suppressions
|
|
|
|
my $strValgrindSuppress = $self->{strRepoPath} . '/test/src/valgrind.suppress.' . $self->{oTest}->{&TEST_VM};
|
|
|
|
|
|
|
|
$strCommand =
|
|
|
|
($self->{oTest}->{&TEST_VM} ne VM_NONE ? "docker exec -i -u ${\TEST_USER} ${strImage} bash -l -c '" : '') .
|
|
|
|
" \\\n" .
|
2022-07-29 16:31:36 +02:00
|
|
|
$self->{strTestPath} . '/build/' . $self->{oTest}->{&TEST_VM} . '/test/src/test-pgbackrest' .
|
|
|
|
' --repo-path=' . $self->{strTestPath} . '/repo' . ' --test-path=' . $self->{strTestPath} .
|
|
|
|
" --log-level=$self->{strLogLevel}" . ' --vm=' . $self->{oTest}->{&TEST_VM} .
|
|
|
|
' --vm-id=' . $self->{iVmIdx} . ($self->{bProfile} ? ' --profile' : '') .
|
2023-01-28 13:55:53 +02:00
|
|
|
($self->{bBackTraceUnit} ? '' : ' --no-back-trace') . ($bCoverage ? '' : ' --no-coverage') . ' test ' .
|
2022-07-29 16:31:36 +02:00
|
|
|
$self->{oTest}->{&TEST_MODULE} . '/' . $self->{oTest}->{&TEST_NAME} . " && \\\n" .
|
2022-03-25 02:43:43 +02:00
|
|
|
# Allow stderr to be copied to stderr and stdout
|
|
|
|
"exec 3>&1 && \\\n" .
|
2021-01-24 23:24:14 +02:00
|
|
|
# Test with valgrind when requested
|
|
|
|
($self->{bValgrindUnit} && $self->{oTest}->{&TEST_TYPE} ne TESTDEF_PERFORMANCE ?
|
|
|
|
'valgrind -q --gen-suppressions=all' .
|
|
|
|
($self->{oStorageTest}->exists($strValgrindSuppress) ? " --suppressions=${strValgrindSuppress}" : '') .
|
2021-09-21 16:16:16 +02:00
|
|
|
" --exit-on-first-error=yes --leak-check=full --leak-resolution=high --error-exitcode=25" . ' ' : '') .
|
2022-07-29 16:31:36 +02:00
|
|
|
"$self->{strUnitPath}/build/test-unit 2>&1 1>&3 | tee /dev/stderr" .
|
2021-01-24 23:24:14 +02:00
|
|
|
($self->{oTest}->{&TEST_VM} ne VM_NONE ? "'" : '');
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$strCommand =
|
|
|
|
($self->{oTest}->{&TEST_CONTAINER} ? 'docker exec -i -u ' . TEST_USER . " ${strImage} " : '') .
|
|
|
|
abs_path($0) .
|
|
|
|
" --test-path=${strVmTestPath}" .
|
|
|
|
" --vm=$self->{oTest}->{&TEST_VM}" .
|
|
|
|
" --vm-id=$self->{iVmIdx}" .
|
|
|
|
" --module=" . $self->{oTest}->{&TEST_MODULE} .
|
|
|
|
' --test=' . $self->{oTest}->{&TEST_NAME} .
|
|
|
|
$strCommandRunParam .
|
|
|
|
(defined($self->{oTest}->{&TEST_DB}) ? ' --pg-version=' . $self->{oTest}->{&TEST_DB} : '') .
|
|
|
|
($self->{strLogLevel} ne lc(INFO) ? " --log-level=$self->{strLogLevel}" : '') .
|
|
|
|
($self->{strLogLevelTestFile} ne lc(TRACE) ? " --log-level-test-file=$self->{strLogLevelTestFile}" : '') .
|
|
|
|
($self->{bLogTimestamp} ? '' : ' --no-log-timestamp') .
|
2022-11-14 06:47:27 +02:00
|
|
|
' --psql-bin=' . $self->{oTest}->{&TEST_PGSQL_BIN} .
|
2021-01-24 23:24:14 +02:00
|
|
|
($self->{strTimeZone} ? " --tz='$self->{strTimeZone}'" : '') .
|
|
|
|
($self->{bDryRun} ? ' --dry-run' : '') .
|
|
|
|
($self->{bDryRun} ? ' --vm-out' : '') .
|
|
|
|
($self->{bNoCleanup} ? " --no-cleanup" : '');
|
2017-10-12 18:55:48 +02:00
|
|
|
}
|
|
|
|
|
2017-02-21 15:59:23 +02:00
|
|
|
my $oExec = new pgBackRestTest::Common::ExecuteTest(
|
2018-04-13 02:42:26 +02:00
|
|
|
$strCommand, {bSuppressError => true, bShowOutputAsync => $self->{bShowOutputAsync}});
|
2017-02-21 15:59:23 +02:00
|
|
|
|
|
|
|
$oExec->begin();
|
|
|
|
|
|
|
|
$self->{oProcess} =
|
|
|
|
{
|
|
|
|
exec => $oExec,
|
|
|
|
test => $strTest,
|
2017-11-27 01:43:51 +02:00
|
|
|
start_time => $fTestStartTime,
|
2017-02-21 15:59:23 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
$bRun = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Return from function and log return values if any
|
|
|
|
return logDebugReturn
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
{name => 'bRun', value => $bRun, trace => true}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# end
|
|
|
|
####################################################################################################################################
|
|
|
|
sub end
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
(my $strOperation) = logDebugParam (__PACKAGE__ . '->run', \@_,);
|
|
|
|
|
|
|
|
# Is the job done?
|
|
|
|
my $bDone = false;
|
|
|
|
my $bFail = false;
|
|
|
|
|
|
|
|
my $oExecDone = $self->{oProcess}{exec};
|
|
|
|
my $strTestDone = $self->{oProcess}{test};
|
|
|
|
my $iTestDoneIdx = $self->{oProcess}{idx};
|
|
|
|
|
2019-12-10 20:16:47 +02:00
|
|
|
my $iExitStatus = $oExecDone->end($self->{iVmMax} == 1);
|
2017-02-21 15:59:23 +02:00
|
|
|
|
|
|
|
if (defined($iExitStatus))
|
|
|
|
{
|
2017-10-12 18:55:48 +02:00
|
|
|
my $strImage = 'test-' . $self->{iVmIdx};
|
|
|
|
|
2017-02-21 15:59:23 +02:00
|
|
|
if ($self->{bShowOutputAsync})
|
|
|
|
{
|
|
|
|
syswrite(*STDOUT, "\n");
|
|
|
|
}
|
|
|
|
|
2018-05-18 12:45:14 +02:00
|
|
|
# If C code generate profile info
|
|
|
|
if ($iExitStatus == 0 && $self->{oTest}->{&TEST_C} && $self->{bProfile})
|
|
|
|
{
|
|
|
|
executeTest(
|
2022-03-16 01:55:48 +02:00
|
|
|
($self->{oTest}->{&TEST_VM} ne VM_NONE ? 'docker exec -i -u ' . TEST_USER . " ${strImage} " : '') .
|
2022-07-29 16:31:36 +02:00
|
|
|
"gprof $self->{strUnitPath}/build/test-unit $self->{strUnitPath}/build/gmon.out >" .
|
|
|
|
" $self->{strUnitPath}/gprof.txt");
|
2018-05-18 12:45:14 +02:00
|
|
|
|
2020-03-14 20:50:36 +02:00
|
|
|
$self->{oStorageTest}->pathCreate(
|
|
|
|
"$self->{strBackRestBase}/test/result/profile", {strMode => '0750', bIgnoreExists => true, bCreateParent => true});
|
2018-05-18 12:45:14 +02:00
|
|
|
$self->{oStorageTest}->copy(
|
2022-07-27 16:32:32 +02:00
|
|
|
"$self->{strUnitPath}/gprof.txt", "$self->{strBackRestBase}/test/result/profile/gprof.txt");
|
2018-05-18 12:45:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# If C code generate coverage info
|
2018-09-15 19:27:06 +02:00
|
|
|
if ($iExitStatus == 0 && $self->{oTest}->{&TEST_C} && vmCoverageC($self->{oTest}->{&TEST_VM}) && $self->{bCoverageUnit})
|
2017-10-12 18:55:48 +02:00
|
|
|
{
|
2020-03-19 18:07:51 +02:00
|
|
|
coverageExtract(
|
2020-05-09 15:17:33 +02:00
|
|
|
$self->{oStorageTest}, $self->{oTest}->{&TEST_MODULE}, $self->{oTest}->{&TEST_NAME},
|
|
|
|
$self->{oTest}->{&TEST_VM} ne VM_NONE, $self->{bCoverageSummary},
|
2020-03-19 18:07:51 +02:00
|
|
|
$self->{oTest}->{&TEST_VM} eq VM_NONE ? undef : $strImage, $self->{strTestPath}, "$self->{strTestPath}/temp",
|
2022-07-28 20:53:48 +02:00
|
|
|
-e "$self->{strUnitPath}/build/test-unit.p" ?
|
|
|
|
"$self->{strUnitPath}/build/test-unit.p" : "$self->{strUnitPath}/build/test-unit\@exe",
|
|
|
|
$self->{strBackRestBase} . '/test/result');
|
2017-10-12 18:55:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Record elapsed time
|
2017-02-21 15:59:23 +02:00
|
|
|
my $fTestElapsedTime = ceil((gettimeofday() - $self->{oProcess}{start_time}) * 100) / 100;
|
|
|
|
|
2017-10-12 18:55:48 +02:00
|
|
|
# Output error
|
2022-03-25 02:43:43 +02:00
|
|
|
if ($iExitStatus != 0 || (defined($oExecDone->{strErrorLog}) && $oExecDone->{strErrorLog} ne ''))
|
2017-02-21 15:59:23 +02:00
|
|
|
{
|
2023-01-05 09:03:43 +02:00
|
|
|
# Get stdout (no need to get stderr since stderr is redirected to stdout)
|
2021-01-24 15:23:59 +02:00
|
|
|
my $strOutput = trim($oExecDone->{strOutLog}) ? "STDOUT:\n" . trim($oExecDone->{strOutLog}) : '';
|
|
|
|
|
|
|
|
# If no stdout or stderr output something rather than a blank line
|
|
|
|
if ($strOutput eq '')
|
|
|
|
{
|
|
|
|
$strOutput = 'NO OUTPUT ON STDOUT OR STDERR';
|
|
|
|
}
|
|
|
|
|
2020-03-22 16:12:29 +02:00
|
|
|
&log(ERROR, "${strTestDone} (err${iExitStatus}" . ($self->{bLogTimestamp} ? "-${fTestElapsedTime}s)" : '') .
|
2021-01-24 15:23:59 +02:00
|
|
|
(defined($oExecDone->{strOutLog}) && !$self->{bShowOutputAsync} ? ":\n\n${strOutput}\n" : ''), undef, undef, 4);
|
|
|
|
|
2017-02-21 15:59:23 +02:00
|
|
|
$bFail = true;
|
|
|
|
}
|
2017-10-12 18:55:48 +02:00
|
|
|
# Output success
|
2017-02-21 15:59:23 +02:00
|
|
|
else
|
|
|
|
{
|
2020-03-22 20:18:16 +02:00
|
|
|
&log(INFO, "${strTestDone}" . ($self->{bLogTimestamp} ? " (${fTestElapsedTime}s)" : '').
|
2017-02-21 15:59:23 +02:00
|
|
|
($self->{bVmOut} && !$self->{bShowOutputAsync} ?
|
|
|
|
":\n\n" . trim($oExecDone->{strOutLog}) . "\n" : ''), undef, undef, 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$self->{bNoCleanup})
|
|
|
|
{
|
|
|
|
my $strHostTestPath = "$self->{strTestPath}/${strImage}";
|
|
|
|
|
2019-10-08 18:06:30 +02:00
|
|
|
if ($self->{oTest}->{&TEST_VM} ne VM_NONE)
|
|
|
|
{
|
|
|
|
containerRemove("test-$self->{iVmIdx}");
|
|
|
|
}
|
|
|
|
|
2021-01-24 22:48:32 +02:00
|
|
|
executeTest("chmod -R 700 ${strHostTestPath}/* 2>&1;rm -rf ${strHostTestPath}");
|
2017-02-21 15:59:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$bDone = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Return from function and log return values if any
|
|
|
|
return logDebugReturn
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
{name => 'bDone', value => $bDone, trace => true},
|
|
|
|
{name => 'bFail', value => $bFail, trace => true}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|