2013-11-17 21:58:21 +03:00
|
|
|
#!/usr/bin/perl
|
2014-04-03 00:25:37 +03:00
|
|
|
####################################################################################################################################
|
2015-08-29 20:20:46 +02:00
|
|
|
# test.pl - pgBackRest Unit Tests
|
2014-04-03 00:25:37 +03:00
|
|
|
####################################################################################################################################
|
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# Perl includes
|
|
|
|
####################################################################################################################################
|
|
|
|
use strict;
|
2015-04-19 23:27:40 +02:00
|
|
|
use warnings FATAL => qw(all);
|
2015-06-14 00:25:49 +02:00
|
|
|
use Carp qw(confess longmess);
|
2016-09-06 15:44:50 +02:00
|
|
|
use English '-no_match_vars';
|
2015-06-14 00:25:49 +02:00
|
|
|
|
2015-08-29 20:20:46 +02:00
|
|
|
# Convert die to confess to capture the stack trace
|
2015-06-14 00:25:49 +02:00
|
|
|
$SIG{__DIE__} = sub { Carp::confess @_ };
|
2014-04-03 00:25:37 +03:00
|
|
|
|
2020-03-14 18:39:29 +02:00
|
|
|
use Digest::SHA qw(sha1_hex);
|
2015-08-29 20:20:46 +02:00
|
|
|
use File::Basename qw(dirname);
|
2021-07-19 01:02:01 +02:00
|
|
|
use File::stat;
|
2015-08-29 20:20:46 +02:00
|
|
|
use Getopt::Long qw(GetOptions);
|
2016-01-15 02:37:06 +02:00
|
|
|
use Cwd qw(abs_path cwd);
|
2017-04-10 18:31:30 +02:00
|
|
|
use JSON::PP;
|
2015-08-29 20:20:46 +02:00
|
|
|
use Pod::Usage qw(pod2usage);
|
2017-02-18 05:31:16 +02:00
|
|
|
use POSIX qw(ceil strftime);
|
2016-01-09 15:21:53 +02:00
|
|
|
use Time::HiRes qw(gettimeofday);
|
2014-04-03 00:25:37 +03:00
|
|
|
|
2016-11-04 13:56:26 +02:00
|
|
|
use lib dirname($0) . '/lib';
|
2017-06-09 23:51:41 +02:00
|
|
|
use lib dirname(dirname($0)) . '/lib';
|
2017-08-25 22:47:47 +02:00
|
|
|
use lib dirname(dirname($0)) . '/build/lib';
|
2017-06-09 23:51:41 +02:00
|
|
|
use lib dirname(dirname($0)) . '/doc/lib';
|
2016-11-04 13:56:26 +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-03-10 06:00:20 +02:00
|
|
|
use pgBackRestTest::Common::BuildTest;
|
2018-04-16 21:52:17 +02:00
|
|
|
use pgBackRestTest::Common::CodeCountTest;
|
2016-06-24 14:12:58 +02:00
|
|
|
use pgBackRestTest::Common::ContainerTest;
|
2018-11-12 00:32:42 +02:00
|
|
|
use pgBackRestTest::Common::CoverageTest;
|
2017-04-10 18:31:30 +02:00
|
|
|
use pgBackRestTest::Common::DefineTest;
|
2016-04-14 15:30:54 +02:00
|
|
|
use pgBackRestTest::Common::ExecuteTest;
|
2016-06-24 14:12:58 +02:00
|
|
|
use pgBackRestTest::Common::HostGroupTest;
|
2017-02-21 15:59:23 +02:00
|
|
|
use pgBackRestTest::Common::JobTest;
|
2016-06-24 14:12:58 +02:00
|
|
|
use pgBackRestTest::Common::ListTest;
|
2016-12-23 15:22:59 +02:00
|
|
|
use pgBackRestTest::Common::RunTest;
|
2019-06-17 15:16:44 +02:00
|
|
|
use pgBackRestTest::Common::Storage;
|
|
|
|
use pgBackRestTest::Common::StoragePosix;
|
2016-12-13 01:54:07 +02:00
|
|
|
use pgBackRestTest::Common::VmTest;
|
2020-03-10 21:12:44 +02:00
|
|
|
use pgBackRestTest::Common::Wait;
|
2014-04-03 00:25:37 +03:00
|
|
|
|
2015-01-11 18:52:16 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# Usage
|
|
|
|
####################################################################################################################################
|
|
|
|
|
|
|
|
=head1 NAME
|
|
|
|
|
2015-08-29 20:20:46 +02:00
|
|
|
test.pl - pgBackRest Unit Tests
|
2015-01-11 18:52:16 +02:00
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
|
|
|
|
test.pl [options]
|
|
|
|
|
|
|
|
Test Options:
|
2016-01-09 15:21:53 +02:00
|
|
|
--module test module to execute
|
2015-06-27 17:12:44 +02:00
|
|
|
--test execute the specified test in a module
|
|
|
|
--run execute only the specified test run
|
2015-01-12 16:05:26 +02:00
|
|
|
--dry-run show only the tests that would be executed but don't execute them
|
2019-08-26 18:05:36 +02:00
|
|
|
--no-cleanup don't cleanup after the last test is complete - useful for debugging
|
2020-03-22 19:46:30 +02:00
|
|
|
--clean clean working and result paths for a completely fresh build
|
|
|
|
--clean-only execute --clean and exit
|
2018-02-04 01:27:38 +02:00
|
|
|
--pg-version version of postgres to test (all, defaults to minimal)
|
2020-03-14 20:35:09 +02:00
|
|
|
--build-only build the binary (and honor --build-package) but don't run tests
|
|
|
|
--build-package build the package
|
2019-04-24 02:52:03 +02:00
|
|
|
--build-max max processes to use for builds (default 4)
|
2017-10-12 18:55:48 +02:00
|
|
|
--c-only only run C tests
|
2019-10-08 18:06:30 +02:00
|
|
|
--container-only only run tests that must be run in a container
|
2020-03-27 02:36:09 +02:00
|
|
|
--no-performance do not run performance tests
|
2017-11-02 14:14:13 +02:00
|
|
|
--gen-only only run auto-generation
|
2022-06-06 19:52:56 +02:00
|
|
|
--min-gen only run required code generation
|
2021-03-31 16:36:22 +02:00
|
|
|
--gen-check check that auto-generated files are correct (used in CI to detect changes)
|
2018-04-16 21:52:17 +02:00
|
|
|
--code-count generate code counts
|
2023-01-28 13:55:53 +02:00
|
|
|
--no-back-trace don't run backrace on C unit tests (may be slow with valgrind)
|
2018-05-18 12:45:14 +02:00
|
|
|
--no-valgrind don't run valgrind on C unit tests (saves time)
|
|
|
|
--no-coverage don't run coverage on C unit tests (saves time)
|
2020-06-17 21:07:30 +02:00
|
|
|
--no-coverage-report run coverage but don't generate coverage report (saves time)
|
2018-05-18 12:45:14 +02:00
|
|
|
--no-optimize don't do compile optimization for C (saves compile time)
|
|
|
|
--profile generate profile info
|
|
|
|
--no-debug don't generate a debug build
|
2019-09-28 20:02:12 +02:00
|
|
|
--scale scale performance tests
|
2019-12-12 05:11:04 +02:00
|
|
|
--tz test with the specified timezone
|
2019-02-27 17:09:19 +02:00
|
|
|
--debug-test-trace test stack trace for low-level functions (slow, esp w/valgrind, may cause timeouts)
|
2015-01-11 18:52:16 +02:00
|
|
|
|
2023-01-30 07:22:41 +02:00
|
|
|
Code Format Options:
|
|
|
|
--code-format format code to project standards -- this may overwrite files!
|
|
|
|
--code-format-check check that code is formatted to project standards
|
|
|
|
|
2019-05-15 19:04:56 +02:00
|
|
|
Report Options:
|
|
|
|
--coverage-summary generate a coverage summary report for the documentation
|
2021-05-17 17:35:22 +02:00
|
|
|
--coverage-only only run coverage tests (as a subset of selected tests) for the documentation
|
2019-05-15 19:04:56 +02:00
|
|
|
|
2015-01-11 18:52:16 +02:00
|
|
|
Configuration Options:
|
2015-01-12 16:05:26 +02:00
|
|
|
--psql-bin path to the psql executables (e.g. /usr/lib/postgresql/9.3/bin/)
|
|
|
|
--test-path path where tests are executed (defaults to ./test)
|
2018-07-21 01:03:46 +02:00
|
|
|
--log-level log level to use for test harness (and Perl tests) (defaults to INFO)
|
|
|
|
--log-level-test log level to use for C tests (defaults to OFF)
|
2019-12-17 22:23:07 +02:00
|
|
|
--log-level-test-file log level to use for file logging in integration tests (defaults to TRACE)
|
2020-03-22 16:12:29 +02:00
|
|
|
--no-log-timestamp suppress timestamps, timings, etc. Used to generate documentation.
|
2021-01-24 22:35:40 +02:00
|
|
|
--make-cmd gnu-compatible make command (defaults to make)
|
2015-01-12 16:05:26 +02:00
|
|
|
--quiet, -q equivalent to --log-level=off
|
2015-01-11 18:52:16 +02:00
|
|
|
|
2016-01-09 15:21:53 +02:00
|
|
|
VM Options:
|
2021-10-28 21:15:49 +02:00
|
|
|
--vm docker container to build/test (e.g. rh7)
|
2016-01-09 15:21:53 +02:00
|
|
|
--vm-build build Docker containers
|
2016-04-14 00:47:29 +02:00
|
|
|
--vm-force force a rebuild of Docker containers
|
2016-01-09 15:21:53 +02:00
|
|
|
--vm-out Show VM output (default false)
|
2016-09-06 15:35:02 +02:00
|
|
|
--vm-max max VMs to run in parallel (default 1)
|
2016-01-09 15:21:53 +02:00
|
|
|
|
2015-01-11 18:52:16 +02:00
|
|
|
General Options:
|
2015-01-12 16:05:26 +02:00
|
|
|
--version display version and exit
|
|
|
|
--help display usage and exit
|
2015-01-11 18:52:16 +02:00
|
|
|
=cut
|
|
|
|
|
2014-04-03 00:25:37 +03:00
|
|
|
####################################################################################################################################
|
2014-06-04 04:22:07 +03:00
|
|
|
# Command line parameters
|
|
|
|
####################################################################################################################################
|
2020-03-22 19:46:30 +02:00
|
|
|
my $bClean;
|
|
|
|
my $bCleanOnly;
|
2017-02-21 15:59:23 +02:00
|
|
|
my $strLogLevel = lc(INFO);
|
2018-07-21 01:03:46 +02:00
|
|
|
my $strLogLevelTest = lc(OFF);
|
2021-02-24 15:27:58 +02:00
|
|
|
my $strLogLevelTestFile = lc(DEBUG);
|
2020-03-22 16:12:29 +02:00
|
|
|
my $bNoLogTimestamp = false;
|
2016-01-09 15:21:53 +02:00
|
|
|
my $bVmOut = false;
|
2017-01-05 01:29:13 +02:00
|
|
|
my @stryModule;
|
|
|
|
my @stryModuleTest;
|
|
|
|
my @iyModuleTestRun;
|
2016-09-06 15:35:02 +02:00
|
|
|
my $iVmMax = 1;
|
|
|
|
my $iVmId = undef;
|
2014-07-16 05:32:41 +03:00
|
|
|
my $bDryRun = false;
|
2023-01-30 07:22:41 +02:00
|
|
|
my $bCodeFormat = false;
|
|
|
|
my $bCodeFormatCheck = false;
|
2014-07-16 05:32:41 +03:00
|
|
|
my $bNoCleanup = false;
|
2014-08-11 04:22:17 +03:00
|
|
|
my $strPgSqlBin;
|
|
|
|
my $strTestPath;
|
2021-01-24 22:35:40 +02:00
|
|
|
my $strMakeCmd = 'make';
|
2015-01-11 18:52:16 +02:00
|
|
|
my $bVersion = false;
|
|
|
|
my $bHelp = false;
|
|
|
|
my $bQuiet = false;
|
2018-02-04 01:27:38 +02:00
|
|
|
my $strPgVersion = 'minimal';
|
2022-07-27 16:32:32 +02:00
|
|
|
my $strVm = VM_NONE;
|
2016-01-09 15:21:53 +02:00
|
|
|
my $bVmBuild = false;
|
2016-04-14 00:47:29 +02:00
|
|
|
my $bVmForce = false;
|
2017-02-18 05:31:16 +02:00
|
|
|
my $bBuildOnly = false;
|
2020-03-14 20:35:09 +02:00
|
|
|
my $bBuildPackage = false;
|
2019-04-24 02:52:03 +02:00
|
|
|
my $iBuildMax = 4;
|
2017-04-10 18:31:30 +02:00
|
|
|
my $bCoverageOnly = false;
|
2019-05-15 19:04:56 +02:00
|
|
|
my $bCoverageSummary = false;
|
2018-05-18 12:45:14 +02:00
|
|
|
my $bNoCoverage = false;
|
2020-06-17 21:07:30 +02:00
|
|
|
my $bNoCoverageReport = false;
|
2017-10-12 18:55:48 +02:00
|
|
|
my $bCOnly = false;
|
2019-10-08 18:06:30 +02:00
|
|
|
my $bContainerOnly = false;
|
2020-03-27 02:36:09 +02:00
|
|
|
my $bNoPerformance = false;
|
2017-11-02 14:14:13 +02:00
|
|
|
my $bGenOnly = false;
|
2021-03-31 16:36:22 +02:00
|
|
|
my $bGenCheck = false;
|
2022-06-06 19:52:56 +02:00
|
|
|
my $bMinGen = false;
|
2018-04-16 21:52:17 +02:00
|
|
|
my $bCodeCount = false;
|
2018-05-18 12:45:14 +02:00
|
|
|
my $bProfile = false;
|
2023-01-28 13:55:53 +02:00
|
|
|
my $bNoBackTrace = false;
|
2018-05-18 12:45:14 +02:00
|
|
|
my $bNoValgrind = false;
|
|
|
|
my $bNoOptimize = false;
|
|
|
|
my $bNoDebug = false;
|
2019-09-28 20:02:12 +02:00
|
|
|
my $iScale = 1;
|
2019-02-27 17:09:19 +02:00
|
|
|
my $bDebugTestTrace = false;
|
2017-02-23 01:43:10 +02:00
|
|
|
my $iRetry = 0;
|
2019-12-12 05:11:04 +02:00
|
|
|
my $strTimeZone = undef;
|
2015-01-11 18:52:16 +02:00
|
|
|
|
2019-05-15 19:04:56 +02:00
|
|
|
my @cmdOptions = @ARGV;
|
|
|
|
|
2015-01-11 18:52:16 +02:00
|
|
|
GetOptions ('q|quiet' => \$bQuiet,
|
|
|
|
'version' => \$bVersion,
|
|
|
|
'help' => \$bHelp,
|
2020-03-22 19:46:30 +02:00
|
|
|
'clean' => \$bClean,
|
|
|
|
'clean-only' => \$bCleanOnly,
|
2022-11-14 06:47:27 +02:00
|
|
|
'psql-bin=s' => \$strPgSqlBin,
|
2014-09-16 18:22:55 +03:00
|
|
|
'test-path=s' => \$strTestPath,
|
2021-01-24 22:35:40 +02:00
|
|
|
'make-cmd=s' => \$strMakeCmd,
|
2014-09-16 18:22:55 +03:00
|
|
|
'log-level=s' => \$strLogLevel,
|
2018-07-21 01:03:46 +02:00
|
|
|
'log-level-test=s' => \$strLogLevelTest,
|
2019-12-17 22:23:07 +02:00
|
|
|
'log-level-test-file=s' => \$strLogLevelTestFile,
|
2020-03-22 16:12:29 +02:00
|
|
|
'no-log-timestamp' => \$bNoLogTimestamp,
|
2016-04-14 00:47:29 +02:00
|
|
|
'vm=s' => \$strVm,
|
2016-01-09 15:21:53 +02:00
|
|
|
'vm-out' => \$bVmOut,
|
|
|
|
'vm-build' => \$bVmBuild,
|
2016-04-14 00:47:29 +02:00
|
|
|
'vm-force' => \$bVmForce,
|
2017-01-05 01:29:13 +02:00
|
|
|
'module=s@' => \@stryModule,
|
|
|
|
'test=s@' => \@stryModuleTest,
|
|
|
|
'run=s@' => \@iyModuleTestRun,
|
2016-09-06 15:35:02 +02:00
|
|
|
'vm-id=s' => \$iVmId,
|
2016-09-30 00:26:32 +02:00
|
|
|
'vm-max=s' => \$iVmMax,
|
2014-09-16 18:22:55 +03:00
|
|
|
'dry-run' => \$bDryRun,
|
2015-02-28 06:31:39 +02:00
|
|
|
'no-cleanup' => \$bNoCleanup,
|
2018-02-04 01:27:38 +02:00
|
|
|
'pg-version=s' => \$strPgVersion,
|
2017-02-18 05:31:16 +02:00
|
|
|
'build-only' => \$bBuildOnly,
|
2020-03-14 20:35:09 +02:00
|
|
|
'build-package' => \$bBuildPackage,
|
2019-04-24 02:52:03 +02:00
|
|
|
'build-max=s' => \$iBuildMax,
|
2017-04-10 18:31:30 +02:00
|
|
|
'coverage-only' => \$bCoverageOnly,
|
2019-05-15 19:04:56 +02:00
|
|
|
'coverage-summary' => \$bCoverageSummary,
|
2018-05-18 12:45:14 +02:00
|
|
|
'no-coverage' => \$bNoCoverage,
|
2020-06-17 21:07:30 +02:00
|
|
|
'no-coverage-report' => \$bNoCoverageReport,
|
2017-10-12 18:55:48 +02:00
|
|
|
'c-only' => \$bCOnly,
|
2019-10-08 18:06:30 +02:00
|
|
|
'container-only' => \$bContainerOnly,
|
2020-03-27 02:36:09 +02:00
|
|
|
'no-performance' => \$bNoPerformance,
|
2017-11-02 14:14:13 +02:00
|
|
|
'gen-only' => \$bGenOnly,
|
2021-03-31 16:36:22 +02:00
|
|
|
'gen-check' => \$bGenCheck,
|
2022-06-06 19:52:56 +02:00
|
|
|
'min-gen' => \$bMinGen,
|
2018-04-16 21:52:17 +02:00
|
|
|
'code-count' => \$bCodeCount,
|
2023-01-30 07:22:41 +02:00
|
|
|
'code-format' => \$bCodeFormat,
|
|
|
|
'code-format-check' => \$bCodeFormatCheck,
|
2018-05-18 12:45:14 +02:00
|
|
|
'profile' => \$bProfile,
|
2023-01-28 13:55:53 +02:00
|
|
|
'no-back-trace' => \$bNoBackTrace,
|
2018-05-18 12:45:14 +02:00
|
|
|
'no-valgrind' => \$bNoValgrind,
|
|
|
|
'no-optimize' => \$bNoOptimize,
|
|
|
|
'no-debug', => \$bNoDebug,
|
2019-09-28 20:02:12 +02:00
|
|
|
'scale=s' => \$iScale,
|
2019-12-12 05:11:04 +02:00
|
|
|
'tz=s', => \$strTimeZone,
|
2019-02-27 17:09:19 +02:00
|
|
|
'debug-test-trace', => \$bDebugTestTrace,
|
2017-02-22 05:10:02 +02:00
|
|
|
'retry=s' => \$iRetry)
|
2015-01-11 18:52:16 +02:00
|
|
|
or pod2usage(2);
|
|
|
|
|
2016-09-06 15:44:50 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# Run in eval block to catch errors
|
|
|
|
####################################################################################################################################
|
|
|
|
eval
|
2015-01-11 18:52:16 +02:00
|
|
|
{
|
2018-03-10 04:24:30 +02:00
|
|
|
# Record the start time
|
|
|
|
my $lStartTime = time();
|
|
|
|
|
2016-09-06 15:44:50 +02:00
|
|
|
# Display version and exit if requested
|
|
|
|
if ($bVersion || $bHelp)
|
|
|
|
{
|
2018-11-25 02:05:03 +02:00
|
|
|
syswrite(*STDOUT, PROJECT_NAME . ' ' . PROJECT_VERSION . " Test Engine\n");
|
2016-09-06 15:44:50 +02:00
|
|
|
|
|
|
|
if ($bHelp)
|
|
|
|
{
|
|
|
|
syswrite(*STDOUT, "\n");
|
|
|
|
pod2usage();
|
|
|
|
}
|
2015-01-11 18:52:16 +02:00
|
|
|
|
2016-09-06 15:44:50 +02:00
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (@ARGV > 0)
|
2015-01-11 18:52:16 +02:00
|
|
|
{
|
2016-09-06 15:44:50 +02:00
|
|
|
syswrite(*STDOUT, "invalid parameter\n\n");
|
2015-01-11 18:52:16 +02:00
|
|
|
pod2usage();
|
|
|
|
}
|
|
|
|
|
2019-10-17 11:56:45 +02:00
|
|
|
################################################################################################################################
|
|
|
|
# Disable code generation on dry-run
|
|
|
|
################################################################################################################################
|
|
|
|
if ($bDryRun)
|
|
|
|
{
|
2022-06-06 19:52:56 +02:00
|
|
|
$bMinGen = true;
|
2019-10-17 11:56:45 +02:00
|
|
|
}
|
|
|
|
|
2019-05-15 19:04:56 +02:00
|
|
|
################################################################################################################################
|
|
|
|
# Update options for --coverage-summary
|
|
|
|
################################################################################################################################
|
|
|
|
if ($bCoverageSummary)
|
|
|
|
{
|
|
|
|
$bCoverageOnly = true;
|
|
|
|
$bCOnly = true;
|
|
|
|
}
|
|
|
|
|
2018-05-18 12:45:14 +02:00
|
|
|
################################################################################################################################
|
|
|
|
# Update options for --profile
|
|
|
|
################################################################################################################################
|
|
|
|
if ($bProfile)
|
|
|
|
{
|
2023-01-28 13:55:53 +02:00
|
|
|
$bNoBackTrace = true;
|
2018-05-18 12:45:14 +02:00
|
|
|
$bNoValgrind = true;
|
|
|
|
$bNoCoverage = true;
|
2017-02-18 05:31:16 +02:00
|
|
|
}
|
|
|
|
|
2016-09-06 15:44:50 +02:00
|
|
|
################################################################################################################################
|
|
|
|
# Setup
|
|
|
|
################################################################################################################################
|
|
|
|
# Set a neutral umask so tests work as expected
|
|
|
|
umask(0);
|
2014-06-04 04:22:07 +03:00
|
|
|
|
2016-09-06 15:44:50 +02:00
|
|
|
# Set console log level
|
|
|
|
if ($bQuiet)
|
|
|
|
{
|
|
|
|
$strLogLevel = 'off';
|
|
|
|
}
|
2015-01-11 18:52:16 +02:00
|
|
|
|
2020-03-22 16:12:29 +02:00
|
|
|
logLevelSet(uc($strLogLevel), uc($strLogLevel), OFF, !$bNoLogTimestamp);
|
2021-05-03 22:31:27 +02:00
|
|
|
&log(INFO, 'test begin on ' . hostArch() . " - log level ${strLogLevel}");
|
2014-06-04 04:22:07 +03:00
|
|
|
|
2017-01-05 01:29:13 +02:00
|
|
|
if (@stryModuleTest != 0 && @stryModule != 1)
|
2016-09-06 15:44:50 +02:00
|
|
|
{
|
2017-01-05 01:29:13 +02:00
|
|
|
confess "Only one --module can be provided when --test is specified";
|
2016-09-06 15:44:50 +02:00
|
|
|
}
|
2014-06-05 17:20:03 +03:00
|
|
|
|
2017-01-05 01:29:13 +02:00
|
|
|
if (@iyModuleTestRun != 0 && @stryModuleTest != 1)
|
2016-09-06 15:44:50 +02:00
|
|
|
{
|
2017-01-05 01:29:13 +02:00
|
|
|
confess "Only one --test can be provided when --run is specified";
|
2016-09-06 15:44:50 +02:00
|
|
|
}
|
2014-06-22 17:54:31 +03:00
|
|
|
|
2022-07-27 16:32:32 +02:00
|
|
|
# Check vm
|
|
|
|
vmValid($strVm);
|
|
|
|
|
2019-08-26 18:05:36 +02:00
|
|
|
# Set test path if not explicitly set
|
2016-09-06 15:44:50 +02:00
|
|
|
if (!defined($strTestPath))
|
|
|
|
{
|
|
|
|
$strTestPath = cwd() . '/test';
|
|
|
|
}
|
2016-05-11 00:12:37 +02:00
|
|
|
|
2019-06-17 15:16:44 +02:00
|
|
|
my $oStorageTest = new pgBackRestTest::Common::Storage(
|
|
|
|
$strTestPath, new pgBackRestTest::Common::StoragePosix({bFileSync => false, bPathSync => false}));
|
2017-06-09 23:51:41 +02:00
|
|
|
|
2017-04-10 18:31:30 +02:00
|
|
|
if ($bCoverageOnly)
|
2017-01-10 03:49:04 +02:00
|
|
|
{
|
2017-04-10 18:31:30 +02:00
|
|
|
if (!defined($strVm))
|
2017-01-10 03:49:04 +02:00
|
|
|
{
|
2021-05-17 17:35:22 +02:00
|
|
|
confess &log(ERROR, "select a VM for coverage testing");
|
2017-01-10 03:49:04 +02:00
|
|
|
}
|
2017-04-10 18:31:30 +02:00
|
|
|
elsif ($strVm eq VM_ALL)
|
2017-01-10 03:49:04 +02:00
|
|
|
{
|
2021-05-17 17:35:22 +02:00
|
|
|
confess &log(ERROR, "select a single VM for coverage testing");
|
2017-01-10 03:49:04 +02:00
|
|
|
}
|
2017-04-10 18:31:30 +02:00
|
|
|
}
|
|
|
|
|
2016-09-06 15:44:50 +02:00
|
|
|
# Get the base backrest path
|
|
|
|
my $strBackRestBase = dirname(dirname(abs_path($0)));
|
2020-03-09 23:41:59 +02:00
|
|
|
my $strVagrantPath = "${strBackRestBase}/test/.vagrant";
|
2016-06-02 15:32:56 +02:00
|
|
|
|
2019-06-17 15:16:44 +02:00
|
|
|
my $oStorageBackRest = new pgBackRestTest::Common::Storage(
|
|
|
|
$strBackRestBase, new pgBackRestTest::Common::StoragePosix({bFileSync => false, bPathSync => false}));
|
2017-06-09 23:51:41 +02:00
|
|
|
|
2021-07-29 17:09:51 +02:00
|
|
|
# Check that the test path is not in the git repo path
|
|
|
|
if (index("${strTestPath}/", "${strBackRestBase}/") != -1)
|
|
|
|
{
|
|
|
|
confess &log(
|
|
|
|
ERROR,
|
|
|
|
"test path '${strTestPath}' may not be in the repo path '${strBackRestBase}'\n" .
|
|
|
|
"HINT: was test.pl run in '${strBackRestBase}'?\n" .
|
|
|
|
"HINT: use --test-path to set a test path\n" .
|
|
|
|
"HINT: run test.pl from outside the repo, e.g. 'pgbackrest/test/test.pl'");
|
|
|
|
}
|
|
|
|
|
2020-03-22 19:46:30 +02:00
|
|
|
################################################################################################################################
|
|
|
|
# Clean working and result paths
|
|
|
|
################################################################################################################################
|
|
|
|
if ($bClean || $bCleanOnly)
|
|
|
|
{
|
|
|
|
&log(INFO, "clean working (${strTestPath}) and result (${strBackRestBase}/test/result) paths");
|
|
|
|
|
|
|
|
if ($oStorageTest->pathExists($strTestPath))
|
|
|
|
{
|
|
|
|
executeTest("find ${strTestPath} -mindepth 1 -print0 | xargs -0 rm -rf");
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($oStorageTest->pathExists("${strBackRestBase}/test/result"))
|
|
|
|
{
|
|
|
|
executeTest("find ${strBackRestBase}/test/result -mindepth 1 -print0 | xargs -0 rm -rf");
|
|
|
|
}
|
|
|
|
|
|
|
|
# Exit when clean-only
|
|
|
|
exit 0 if $bCleanOnly;
|
|
|
|
}
|
|
|
|
|
2016-09-06 15:44:50 +02:00
|
|
|
################################################################################################################################
|
|
|
|
# Build Docker containers
|
|
|
|
################################################################################################################################
|
|
|
|
if ($bVmBuild)
|
|
|
|
{
|
2017-06-24 16:59:00 +02:00
|
|
|
containerBuild($oStorageBackRest, $strVm, $bVmForce);
|
2016-09-06 15:44:50 +02:00
|
|
|
exit 0;
|
|
|
|
}
|
2016-01-09 15:21:53 +02:00
|
|
|
|
2018-04-08 16:19:24 +02:00
|
|
|
################################################################################################################################
|
|
|
|
# Load test definition
|
|
|
|
################################################################################################################################
|
|
|
|
testDefLoad(${$oStorageBackRest->get("test/define.yaml")});
|
|
|
|
|
2016-01-09 15:21:53 +02:00
|
|
|
################################################################################################################################
|
|
|
|
# Start VM and run
|
|
|
|
################################################################################################################################
|
2016-09-06 15:35:02 +02:00
|
|
|
if (!defined($iVmId))
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2021-08-02 16:00:42 +02:00
|
|
|
# Clean any existing files in the src path that might interfere with the vpath build. This is kosher because the user should
|
|
|
|
# be expecting us to do builds in the src path during testing. Instead we clean the src path and do the builds elsewhere.
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
executeTest("make -C ${strBackRestBase}/src -f Makefile.in clean-all");
|
|
|
|
|
2022-07-27 16:32:32 +02:00
|
|
|
# Clean up
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
my $iTestFail = 0;
|
|
|
|
my $iTestRetry = 0;
|
|
|
|
my $oyProcess = [];
|
|
|
|
my $strCodePath = "${strBackRestBase}/test/result/coverage/raw";
|
|
|
|
|
|
|
|
if (!$bDryRun || $bVmOut)
|
|
|
|
{
|
|
|
|
&log(INFO, "cleanup old data" . ($strVm ne VM_NONE ? " and containers" : ''));
|
|
|
|
|
|
|
|
if ($strVm ne VM_NONE)
|
|
|
|
{
|
|
|
|
containerRemove('test-([0-9]+|build)');
|
|
|
|
}
|
|
|
|
|
|
|
|
for (my $iVmIdx = 0; $iVmIdx < 8; $iVmIdx++)
|
|
|
|
{
|
|
|
|
push(@{$oyProcess}, undef);
|
|
|
|
}
|
|
|
|
|
|
|
|
executeTest(
|
|
|
|
"chmod 700 -R ${strTestPath}/test-* 2>&1 || true && rm -rf ${strTestPath}/temp ${strTestPath}/test-*" .
|
|
|
|
" ${strTestPath}/data-*");
|
|
|
|
$oStorageTest->pathCreate("${strTestPath}/temp", {strMode => '0770', bIgnoreExists => true, bCreateParent => true});
|
|
|
|
|
|
|
|
# Remove old lcov dirs -- do it this way so the dirs stay open in finder/explorer, etc.
|
|
|
|
executeTest("rm -rf ${strBackRestBase}/test/result/coverage/lcov/*");
|
|
|
|
|
|
|
|
# Overwrite the C coverage report so it will load but not show old coverage
|
|
|
|
$oStorageTest->pathCreate(
|
|
|
|
"${strBackRestBase}/test/result/coverage", {strMode => '0770', bIgnoreExists => true, bCreateParent => true});
|
|
|
|
$oStorageBackRest->put(
|
|
|
|
"${strBackRestBase}/test/result/coverage/coverage.html", "<center>[ Generating New Report ]</center>");
|
|
|
|
|
|
|
|
# Copy C code for coverage tests
|
|
|
|
if (vmCoverageC($strVm) && !$bDryRun)
|
|
|
|
{
|
|
|
|
executeTest("rm -rf ${strBackRestBase}/test/result/coverage/raw/*");
|
|
|
|
$oStorageTest->pathCreate("${strCodePath}", {strMode => '0770', bIgnoreExists => true, bCreateParent => true});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-06 19:52:56 +02:00
|
|
|
# Auto-generate configure files unless --min-gen specified
|
2021-07-19 01:02:01 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2022-06-06 19:52:56 +02:00
|
|
|
if (!$bMinGen)
|
2021-07-19 01:02:01 +02:00
|
|
|
{
|
|
|
|
&log(INFO, "autogenerate configure");
|
|
|
|
|
|
|
|
# Auto-generate version for configure.ac script
|
|
|
|
#-----------------------------------------------------------------------------------------------------------------------
|
|
|
|
my $strConfigureAcOld = ${$oStorageTest->get("${strBackRestBase}/src/build/configure.ac")};
|
|
|
|
my $strConfigureAcNew;
|
|
|
|
|
|
|
|
foreach my $strLine (split("\n", $strConfigureAcOld))
|
|
|
|
{
|
|
|
|
if ($strLine =~ /^AC_INIT\(/)
|
|
|
|
{
|
|
|
|
$strLine = 'AC_INIT([' . PROJECT_NAME . '], [' . PROJECT_VERSION . '])';
|
|
|
|
}
|
|
|
|
|
|
|
|
$strConfigureAcNew .= "${strLine}\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
# Save into the src dir
|
|
|
|
my @stryBuilt;
|
|
|
|
my $strBuilt = 'src/build/configure.ac';
|
|
|
|
|
|
|
|
if (buildPutDiffers($oStorageBackRest, "${strBackRestBase}/${strBuilt}", $strConfigureAcNew))
|
|
|
|
{
|
|
|
|
push(@stryBuilt, $strBuilt);
|
|
|
|
}
|
|
|
|
|
|
|
|
# Error when checking that files have already been generated but they change
|
|
|
|
if ($bGenCheck && @stryBuilt)
|
|
|
|
{
|
|
|
|
confess &log(
|
|
|
|
ERROR,
|
|
|
|
"unexpected autogeneration of version in configure.ac script: " . join(', ', @stryBuilt) . ":\n" .
|
|
|
|
trim(executeTest("git -C ${strBackRestBase} diff")));
|
|
|
|
}
|
|
|
|
|
|
|
|
&log(INFO,
|
|
|
|
" autogenerated version in configure.ac script: " . (@stryBuilt ? join(', ', @stryBuilt) : 'no changes'));
|
|
|
|
|
|
|
|
# Auto-generate configure script
|
|
|
|
#-----------------------------------------------------------------------------------------------------------------------
|
|
|
|
# Set build file
|
|
|
|
@stryBuilt = ();
|
|
|
|
$strBuilt = 'src/configure';
|
|
|
|
|
|
|
|
# Get configure.ac and configure to see if anything has changed
|
|
|
|
my $strConfigureAc = ${$oStorageBackRest->get('src/build/configure.ac')};
|
|
|
|
my $strConfigureAcHash = sha1_hex($strConfigureAc);
|
|
|
|
my $rstrConfigure = $oStorageBackRest->get($oStorageBackRest->openRead($strBuilt, {bIgnoreMissing => true}));
|
|
|
|
|
|
|
|
# Check if configure needs to be regenerated
|
|
|
|
if (!defined($rstrConfigure) || !defined($$rstrConfigure) ||
|
|
|
|
$strConfigureAcHash ne substr($$rstrConfigure, length($$rstrConfigure) - 41, 40))
|
|
|
|
{
|
|
|
|
# Generate aclocal.m4
|
|
|
|
my $strAcLocal = executeTest("cd ${strBackRestBase}/src/build && aclocal --OUT=-");
|
|
|
|
$strAcLocal = trim($strAcLocal) . "\n";
|
|
|
|
|
|
|
|
buildPutDiffers($oStorageBackRest, "${strBackRestBase}/src/build/aclocal.m4", $strAcLocal);
|
|
|
|
|
|
|
|
# Generate configure
|
|
|
|
my $strConfigure = executeTest("cd ${strBackRestBase}/src/build && autoconf --output=-");
|
|
|
|
$strConfigure =
|
|
|
|
trim($strConfigure) . "\n\n# Generated from src/build/configure.ac sha1 ${strConfigureAcHash}\n";
|
|
|
|
|
|
|
|
# Remove cache created by autconf
|
|
|
|
executeTest("rm -rf ${strBackRestBase}/src/build/autom4te.cache");
|
|
|
|
|
|
|
|
# Remove unused options from help
|
|
|
|
my $strDirList =
|
|
|
|
"sbin|libexec|sysconf|sharedstate|localstate|runstate|lib|include|oldinclude|dataroot|data|info" .
|
|
|
|
"|locale|man|doc|html|dvi|pdf|ps";
|
|
|
|
|
|
|
|
$strConfigure =~ s/^ --(${strDirList})*dir=DIR.*\n//mg;
|
|
|
|
|
|
|
|
# Save into the src dir
|
|
|
|
$oStorageBackRest->put(
|
|
|
|
$oStorageBackRest->openWrite("${strBackRestBase}/${strBuilt}", {strMode => '0755'}), $strConfigure);
|
|
|
|
|
|
|
|
# Add to built list
|
|
|
|
push(@stryBuilt, $strBuilt);
|
|
|
|
}
|
|
|
|
|
|
|
|
# Error when checking that files have already been generated but they change
|
|
|
|
if ($bGenCheck && @stryBuilt)
|
|
|
|
{
|
|
|
|
confess &log(
|
|
|
|
ERROR,
|
|
|
|
"unexpected autogeneration of configure script: " . join(', ', @stryBuilt) . ":\n" .
|
|
|
|
trim(executeTest("git -C ${strBackRestBase} diff")));
|
|
|
|
}
|
|
|
|
|
|
|
|
&log(INFO, " autogenerated configure script: " . (@stryBuilt ? join(', ', @stryBuilt) : 'no changes'));
|
|
|
|
}
|
|
|
|
|
2022-06-06 19:52:56 +02:00
|
|
|
# Auto-generate version for root meson.build script
|
2022-07-27 16:32:32 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2022-06-06 19:52:56 +02:00
|
|
|
my $strMesonBuildOld = ${$oStorageTest->get("${strBackRestBase}/meson.build")};
|
|
|
|
my $strMesonBuildNew;
|
2022-06-03 20:13:56 +02:00
|
|
|
|
2022-06-06 19:52:56 +02:00
|
|
|
foreach my $strLine (split("\n", $strMesonBuildOld))
|
|
|
|
{
|
|
|
|
if ($strLine =~ /^ version\: '/)
|
2022-06-03 20:13:56 +02:00
|
|
|
{
|
2022-06-06 19:52:56 +02:00
|
|
|
$strLine = " version: '" . PROJECT_VERSION . "',";
|
2022-06-03 20:13:56 +02:00
|
|
|
}
|
2021-07-19 01:02:01 +02:00
|
|
|
|
2022-06-06 19:52:56 +02:00
|
|
|
$strMesonBuildNew .= "${strLine}\n";
|
2021-07-19 01:02:01 +02:00
|
|
|
}
|
|
|
|
|
2022-06-06 19:52:56 +02:00
|
|
|
buildPutDiffers($oStorageBackRest, "${strBackRestBase}/meson.build", $strMesonBuildNew);
|
2018-11-04 01:52:46 +02:00
|
|
|
|
2022-07-27 16:32:32 +02:00
|
|
|
# Start build container if vm is not none
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
if ($strVm ne VM_NONE)
|
|
|
|
{
|
|
|
|
my $strCCachePath = "${strTestPath}/ccache-0/${strVm}";
|
|
|
|
|
|
|
|
if (!$oStorageTest->pathExists($strCCachePath))
|
|
|
|
{
|
|
|
|
$oStorageTest->pathCreate($strCCachePath, {strMode => '0770', bCreateParent => true});
|
|
|
|
}
|
|
|
|
|
|
|
|
executeTest(
|
|
|
|
"docker run -itd -h test-build --name=test-build" .
|
|
|
|
" -v ${strBackRestBase}:${strBackRestBase} -v ${strTestPath}:${strTestPath}" .
|
|
|
|
" -v ${strCCachePath}:/home/${\TEST_USER}/.ccache" . ' ' . containerRepo() . ":${strVm}-test",
|
|
|
|
{bSuppressStdErr => true});
|
|
|
|
}
|
|
|
|
|
|
|
|
# Create path for repo cache
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
my $strRepoCachePath = "${strTestPath}/repo";
|
|
|
|
|
|
|
|
# Create the repo path -- this should hopefully prevent obvious rsync errors below
|
|
|
|
$oStorageTest->pathCreate($strRepoCachePath, {strMode => '0770', bIgnoreExists => true, bCreateParent => true});
|
|
|
|
|
|
|
|
# Auto-generate code files (if --min-gen specified then do minimum required)
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
my $strBuildPath = "${strTestPath}/build/${strVm}";
|
|
|
|
my $strBuildNinja = "${strBuildPath}/build.ninja";
|
|
|
|
|
|
|
|
&log(INFO, (!-e $strBuildNinja ? 'clean ' : '') . 'autogenerate code');
|
|
|
|
|
2022-06-06 19:52:56 +02:00
|
|
|
# Setup build if it does not exist
|
2022-07-27 16:32:32 +02:00
|
|
|
my $strGenerateCommand =
|
|
|
|
"ninja -C ${strBuildPath} src/build-code test/src/test-pgbackrest" .
|
|
|
|
($bMinGen ? '' : " && \\\n${strBuildPath}/src/build-code config ${strBackRestBase}/src") .
|
|
|
|
($bMinGen ? '' : " && \\\n${strBuildPath}/src/build-code error ${strBackRestBase}/src") .
|
2023-04-16 16:41:27 +02:00
|
|
|
($bMinGen ? '' : " && \\\n${strBuildPath}/src/build-code postgres-version ${strBackRestBase}/src") .
|
2022-07-27 16:32:32 +02:00
|
|
|
" && \\\n${strBuildPath}/src/build-code postgres ${strBackRestBase}/src ${strRepoCachePath}";
|
|
|
|
|
|
|
|
if (!-e $strBuildNinja)
|
2022-06-06 19:52:56 +02:00
|
|
|
{
|
2022-07-27 16:32:32 +02:00
|
|
|
$strGenerateCommand =
|
|
|
|
"meson setup -Dwerror=true -Dfatal-errors=true -Dbuildtype=debug ${strBuildPath} ${strBackRestBase} && \\\n" .
|
|
|
|
$strGenerateCommand;
|
2022-06-06 19:52:56 +02:00
|
|
|
}
|
2018-11-04 01:52:46 +02:00
|
|
|
|
2022-06-06 19:52:56 +02:00
|
|
|
# Build code
|
2021-07-20 18:01:10 +02:00
|
|
|
executeTest(
|
2022-07-27 16:32:32 +02:00
|
|
|
($strVm ne VM_NONE ? "docker exec -i -u ${\TEST_USER} test-build bash -l -c ' \\\n" : '') .
|
|
|
|
$strGenerateCommand . ($strVm ne VM_NONE ? "'" : ''));
|
2022-06-06 19:52:56 +02:00
|
|
|
|
|
|
|
if ($bGenOnly)
|
|
|
|
{
|
|
|
|
exit 0;
|
|
|
|
}
|
2018-11-04 01:52:46 +02:00
|
|
|
|
2022-07-27 16:32:32 +02:00
|
|
|
# Make a copy of the repo to track which files have been changed
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
executeTest(
|
|
|
|
"git -C ${strBackRestBase} ls-files -c --others --exclude-standard |" .
|
|
|
|
" rsync -rLtW --delete --files-from=- --exclude=test/result" .
|
|
|
|
# This option is not supported on MacOS. The eventual plan is to remove the need for it.
|
|
|
|
(trim(`uname`) ne 'Darwin' ? ' --ignore-missing-args' : '') .
|
|
|
|
" ${strBackRestBase}/ ${strRepoCachePath}");
|
|
|
|
|
2023-02-01 07:57:04 +02:00
|
|
|
# Format code with uncrustify and check permissions
|
2023-01-30 07:22:41 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
if ($bCodeFormat || $bCodeFormatCheck)
|
|
|
|
{
|
|
|
|
&log(INFO, 'code format' . ($bCodeFormatCheck ? ' check' : ''));
|
|
|
|
|
2023-02-01 07:57:04 +02:00
|
|
|
my $hRepoManifest = $oStorageTest->manifest($strRepoCachePath);
|
|
|
|
my $hManifest = $oStorageBackRest->manifest('');
|
2023-01-30 07:22:41 +02:00
|
|
|
my $strCommand =
|
|
|
|
"uncrustify -c ${strBackRestBase}/test/uncrustify.cfg" .
|
|
|
|
($bCodeFormatCheck ? ' --check' : ' --replace --no-backup');
|
|
|
|
|
|
|
|
foreach my $strFile (sort(keys(%{$hManifest})))
|
|
|
|
{
|
|
|
|
# Skip non-C files
|
|
|
|
next if $hManifest->{$strFile}{type} ne 'f' || ($strFile !~ /\.c$/ && $strFile !~ /\.h$/);
|
|
|
|
|
2023-02-01 07:57:04 +02:00
|
|
|
# Skip files that do are not version controlled
|
|
|
|
next if !defined($hRepoManifest->{$strFile});
|
2023-01-30 07:22:41 +02:00
|
|
|
|
|
|
|
# Skip specific file
|
|
|
|
next if
|
|
|
|
# Does not format correctly because it is a template
|
|
|
|
$strFile eq 'test/src/test.c' ||
|
|
|
|
# Contains code copied directly from PostgreSQL
|
|
|
|
$strFile eq 'src/postgres/interface/static.vendor.h' ||
|
|
|
|
$strFile eq 'src/postgres/interface/version.vendor.h';
|
|
|
|
|
|
|
|
$strCommand .= " ${strBackRestBase}/${strFile}";
|
|
|
|
}
|
|
|
|
|
|
|
|
executeTest($strCommand . " 2>&1");
|
|
|
|
|
2023-02-01 07:57:04 +02:00
|
|
|
# Check execute permissions to make sure nothing got munged
|
|
|
|
foreach my $strFile (sort(keys(%{$hManifest})))
|
|
|
|
{
|
|
|
|
next if ($strFile eq '.') || !defined($hRepoManifest->{$strFile});
|
|
|
|
|
|
|
|
my $strExpectedMode = sprintf('%04o', oct($hManifest->{$strFile}{mode}) & 0666);
|
|
|
|
|
|
|
|
if ($strFile eq 'doc/doc.pl' ||
|
|
|
|
$strFile eq 'doc/release.pl' ||
|
|
|
|
$strFile eq 'src/build/install-sh' ||
|
|
|
|
$strFile eq 'src/configure' ||
|
|
|
|
$strFile eq 'test/ci.pl' ||
|
|
|
|
$strFile eq 'test/test.pl' ||
|
|
|
|
$hManifest->{$strFile}{type} eq 'd')
|
|
|
|
{
|
|
|
|
$strExpectedMode = sprintf('%04o', oct($hManifest->{$strFile}{mode}) & 0777);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($hManifest->{$strFile}{mode} ne $strExpectedMode)
|
|
|
|
{
|
|
|
|
confess &log(
|
|
|
|
ERROR,
|
|
|
|
"expected mode for '${strExpectedMode}' for '${strFile}' but found '" . $hManifest->{$strFile}{mode} . "'");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-30 07:22:41 +02:00
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
|
2018-04-16 21:52:17 +02:00
|
|
|
# Generate code counts
|
2018-11-04 01:52:46 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2018-04-16 21:52:17 +02:00
|
|
|
if ($bCodeCount)
|
|
|
|
{
|
|
|
|
&log(INFO, "classify code files");
|
|
|
|
|
|
|
|
codeCountScan($oStorageBackRest, $strBackRestBase);
|
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
|
2017-11-28 04:19:59 +02:00
|
|
|
# Determine which tests to run
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
my $oyTestRun;
|
2018-05-22 18:53:08 +02:00
|
|
|
my $bBinRequired = $bBuildOnly;
|
2020-03-09 23:41:59 +02:00
|
|
|
my $bHostBinRequired = $bBuildOnly;
|
2017-11-28 04:19:59 +02:00
|
|
|
|
2018-02-14 17:33:21 +02:00
|
|
|
# Only get the test list when they can run
|
2017-11-28 04:19:59 +02:00
|
|
|
if (!$bBuildOnly)
|
|
|
|
{
|
|
|
|
# Get the test list
|
|
|
|
$oyTestRun = testListGet(
|
2020-03-27 02:36:09 +02:00
|
|
|
$strVm, \@stryModule, \@stryModuleTest, \@iyModuleTestRun, $strPgVersion, $bCoverageOnly, $bCOnly, $bContainerOnly,
|
|
|
|
$bNoPerformance);
|
2017-11-28 04:19:59 +02:00
|
|
|
|
2018-05-22 18:53:08 +02:00
|
|
|
# Determine if the C binary and test library need to be built
|
2017-11-28 04:19:59 +02:00
|
|
|
foreach my $hTest (@{$oyTestRun})
|
|
|
|
{
|
2018-05-22 18:53:08 +02:00
|
|
|
# Bin build required for all Perl tests or if a C unit test calls Perl
|
2019-12-14 00:55:41 +02:00
|
|
|
if (!$hTest->{&TEST_C} || $hTest->{&TEST_BIN_REQ})
|
2017-11-28 04:19:59 +02:00
|
|
|
{
|
2018-05-22 18:53:08 +02:00
|
|
|
$bBinRequired = true;
|
|
|
|
}
|
|
|
|
|
2020-03-09 23:41:59 +02:00
|
|
|
# Host bin required if a Perl test
|
2018-05-22 18:53:08 +02:00
|
|
|
if (!$hTest->{&TEST_C})
|
|
|
|
{
|
2020-03-09 23:41:59 +02:00
|
|
|
$bHostBinRequired = true;
|
2017-11-28 04:19:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-22 18:53:08 +02:00
|
|
|
my $strBuildRequired;
|
|
|
|
|
2020-03-09 23:41:59 +02:00
|
|
|
if ($bBinRequired || $bHostBinRequired)
|
2018-05-22 18:53:08 +02:00
|
|
|
{
|
|
|
|
if ($bBinRequired)
|
|
|
|
{
|
|
|
|
$strBuildRequired = "bin";
|
|
|
|
}
|
|
|
|
|
2020-03-09 23:41:59 +02:00
|
|
|
if ($bHostBinRequired)
|
2018-05-22 18:53:08 +02:00
|
|
|
{
|
2020-03-09 23:41:59 +02:00
|
|
|
$strBuildRequired .= ", bin host";
|
2018-05-22 18:53:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$strBuildRequired = "none";
|
|
|
|
}
|
|
|
|
|
|
|
|
&log(INFO, "builds required: ${strBuildRequired}");
|
|
|
|
|
2020-03-14 20:35:09 +02:00
|
|
|
# Build the binary and packages
|
2017-08-19 14:48:13 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2018-05-22 18:53:08 +02:00
|
|
|
if (!$bDryRun)
|
2016-12-13 01:54:07 +02:00
|
|
|
{
|
2017-11-27 01:43:51 +02:00
|
|
|
my $oVm = vmGet();
|
2018-05-22 18:53:08 +02:00
|
|
|
my $lTimestampLast;
|
2018-05-24 20:01:24 +02:00
|
|
|
my $rhBinBuild = {};
|
2017-11-27 01:43:51 +02:00
|
|
|
|
2018-05-24 20:01:24 +02:00
|
|
|
# Build the binary
|
2018-05-22 18:53:08 +02:00
|
|
|
#-----------------------------------------------------------------------------------------------------------------------
|
2018-05-24 20:01:24 +02:00
|
|
|
if ($bBinRequired)
|
2018-05-22 18:53:08 +02:00
|
|
|
{
|
2018-05-24 20:01:24 +02:00
|
|
|
# Find the lastest modified time for dirs that affect the bin build
|
2020-03-15 16:09:27 +02:00
|
|
|
$lTimestampLast = buildLastModTime($oStorageBackRest, $strBackRestBase, ['src']);
|
2017-11-27 01:43:51 +02:00
|
|
|
|
2018-05-24 20:01:24 +02:00
|
|
|
# Loop through VMs to do the C bin builds
|
|
|
|
my $bLogDetail = $strLogLevel eq 'detail';
|
|
|
|
my @stryBuildVm = $strVm eq VM_ALL ? VM_LIST : ($strVm);
|
2017-11-27 01:43:51 +02:00
|
|
|
|
2020-03-09 23:41:59 +02:00
|
|
|
# Build binary for the host
|
|
|
|
if ($bHostBinRequired)
|
|
|
|
{
|
|
|
|
push(@stryBuildVm, VM_NONE);
|
|
|
|
}
|
|
|
|
|
2018-05-24 20:01:24 +02:00
|
|
|
foreach my $strBuildVM (@stryBuildVm)
|
2017-11-27 01:43:51 +02:00
|
|
|
{
|
2022-06-03 20:13:56 +02:00
|
|
|
if ($strBuildVM eq VM_NONE)
|
|
|
|
{
|
2022-07-27 16:32:32 +02:00
|
|
|
my $strBuildPath = "${strTestPath}/build/${strBuildVM}";
|
|
|
|
my $strBuildNinja = "${strBuildPath}/build.ninja";
|
|
|
|
|
|
|
|
&log(INFO, " " . (!-e $strBuildNinja ? 'clean ' : '') . "bin build for ${strBuildVM} (${strBuildPath})");
|
2019-04-26 14:08:23 +02:00
|
|
|
|
2022-06-03 20:13:56 +02:00
|
|
|
# Setup build if it does not exist
|
2022-07-27 16:32:32 +02:00
|
|
|
my $strBuildCommand = "ninja -C ${strBuildPath} src/pgbackrest";
|
|
|
|
|
|
|
|
if (!-e $strBuildNinja)
|
2022-06-03 20:13:56 +02:00
|
|
|
{
|
2022-07-27 16:32:32 +02:00
|
|
|
$strBuildCommand =
|
2022-06-21 15:50:38 +02:00
|
|
|
"meson setup -Dwerror=true -Dfatal-errors=true -Dbuildtype=debug ${strBuildPath}" .
|
2022-07-27 16:32:32 +02:00
|
|
|
" ${strBackRestBase} && \\\n" .
|
|
|
|
$strBuildCommand;
|
2022-06-03 20:13:56 +02:00
|
|
|
}
|
2018-05-24 20:01:24 +02:00
|
|
|
|
2022-06-03 20:13:56 +02:00
|
|
|
# Build code
|
2022-07-27 16:32:32 +02:00
|
|
|
executeTest($strBuildCommand);
|
2022-06-03 20:13:56 +02:00
|
|
|
}
|
|
|
|
else
|
2019-04-26 14:08:23 +02:00
|
|
|
{
|
2022-07-27 16:32:32 +02:00
|
|
|
my $strBinPath = "${strTestPath}/bin";
|
|
|
|
my $strBuildPath = "${strBinPath}/${strBuildVM}";
|
|
|
|
|
2022-06-03 20:13:56 +02:00
|
|
|
&log(INFO, " bin build for ${strBuildVM} (${strBuildPath})");
|
|
|
|
|
|
|
|
my $bRebuild = false;
|
|
|
|
$rhBinBuild->{$strBuildVM} = false;
|
|
|
|
|
|
|
|
# Build configure/compile options and see if they have changed from the previous build
|
2023-01-11 06:19:26 +02:00
|
|
|
my $strCFlags = ($bDebugTestTrace ? ' -DDEBUG_TEST_TRACE' : '');
|
2022-06-03 20:13:56 +02:00
|
|
|
my $strConfigOptions = (vmDebugIntegration($strBuildVM) ? ' --enable-test' : '');
|
2023-01-11 06:19:26 +02:00
|
|
|
my $strBuildFlags = "CFLAGS_EXTRA=${strCFlags}\nCONFIGURE=${strConfigOptions}";
|
2022-06-03 20:13:56 +02:00
|
|
|
my $strBuildFlagFile = "${strBinPath}/${strBuildVM}/build.flags";
|
|
|
|
|
|
|
|
my $bBuildOptionsDiffer = buildPutDiffers($oStorageBackRest, $strBuildFlagFile, $strBuildFlags);
|
|
|
|
|
|
|
|
if ($bBuildOptionsDiffer ||
|
|
|
|
!-e "${strBuildPath}/Makefile" ||
|
|
|
|
stat("${strBackRestBase}/src/Makefile.in")->mtime > stat("${strBuildPath}/Makefile")->mtime ||
|
|
|
|
stat("${strBackRestBase}/src/configure")->mtime > stat("${strBuildPath}/Makefile")->mtime ||
|
|
|
|
stat("${strBackRestBase}/src/build.auto.h.in")->mtime > stat("${strBuildPath}/Makefile")->mtime)
|
|
|
|
{
|
|
|
|
&log(INFO, ' bin dependencies have changed, rebuilding');
|
2018-05-24 20:01:24 +02:00
|
|
|
|
2022-06-03 20:13:56 +02:00
|
|
|
# Remove old path if it exists and save the build flags
|
|
|
|
executeTest("rm -rf ${strBuildPath}");
|
|
|
|
buildPutDiffers($oStorageBackRest, $strBuildFlagFile, $strBuildFlags);
|
|
|
|
|
|
|
|
executeTest(
|
|
|
|
'docker exec -i -u ' . TEST_USER . ' test-build ' .
|
|
|
|
"bash -c 'cd ${strBuildPath} && ${strBackRestBase}/src/configure -q${strConfigOptions}'",
|
|
|
|
{bShowOutputAsync => $bLogDetail});
|
|
|
|
}
|
2018-05-24 20:01:24 +02:00
|
|
|
|
|
|
|
executeTest(
|
2022-06-03 20:13:56 +02:00
|
|
|
'docker exec -i -u ' . TEST_USER . ' test-build ' .
|
|
|
|
"${strMakeCmd} -s -j ${iBuildMax}" . ($bLogDetail ? '' : ' --silent') .
|
2023-01-11 06:19:26 +02:00
|
|
|
" --directory ${strBuildPath} CFLAGS_EXTRA='${strCFlags}'",
|
2018-05-24 20:01:24 +02:00
|
|
|
{bShowOutputAsync => $bLogDetail});
|
|
|
|
}
|
2018-05-22 18:53:08 +02:00
|
|
|
}
|
2018-05-24 20:01:24 +02:00
|
|
|
}
|
|
|
|
|
2022-07-27 16:32:32 +02:00
|
|
|
# Shut down the build vm
|
|
|
|
#-----------------------------------------------------------------------------------------------------------------------
|
|
|
|
if ($strVm ne VM_NONE)
|
|
|
|
{
|
|
|
|
executeTest("docker rm -f test-build");
|
|
|
|
}
|
|
|
|
|
2018-05-22 18:53:08 +02:00
|
|
|
# Build the package
|
|
|
|
#-----------------------------------------------------------------------------------------------------------------------
|
2020-03-14 20:35:09 +02:00
|
|
|
if ($bBuildPackage && $strVm ne VM_NONE)
|
2018-05-22 18:53:08 +02:00
|
|
|
{
|
2020-03-14 20:35:09 +02:00
|
|
|
my $strPackagePath = "${strBackRestBase}/test/result/package";
|
2017-08-19 14:48:13 +02:00
|
|
|
|
2018-05-22 18:53:08 +02:00
|
|
|
# Loop through VMs to do the package builds
|
2017-02-18 05:31:16 +02:00
|
|
|
my @stryBuildVm = $strVm eq VM_ALL ? VM_LIST : ($strVm);
|
2017-06-09 23:51:41 +02:00
|
|
|
$oStorageBackRest->pathCreate($strPackagePath, {bIgnoreExists => true, bCreateParent => true});
|
2017-02-18 05:31:16 +02:00
|
|
|
|
2018-05-22 18:53:08 +02:00
|
|
|
foreach my $strBuildVM (@stryBuildVm)
|
2017-02-18 05:31:16 +02:00
|
|
|
{
|
2020-03-14 20:35:09 +02:00
|
|
|
my $strBuildPath = "${strPackagePath}/${strBuildVM}";
|
2017-02-18 05:31:16 +02:00
|
|
|
|
2020-03-14 20:35:09 +02:00
|
|
|
if ($oVm->{$strBuildVM}{&VM_OS_BASE} eq VM_OS_BASE_DEBIAN)
|
2017-02-18 05:31:16 +02:00
|
|
|
{
|
2017-08-19 14:48:13 +02:00
|
|
|
&log(INFO, "build package for ${strBuildVM} (${strBuildPath})");
|
2017-02-18 05:31:16 +02:00
|
|
|
|
2019-10-12 15:45:18 +02:00
|
|
|
if ($strVm ne VM_NONE)
|
|
|
|
{
|
|
|
|
executeTest(
|
|
|
|
"docker run -itd -h test-build --name=test-build" .
|
2020-03-12 14:48:45 +02:00
|
|
|
" -v ${strBackRestBase}:${strBackRestBase} " . containerRepo() . ":${strBuildVM}-test",
|
2019-10-12 15:45:18 +02:00
|
|
|
{bSuppressStdErr => true});
|
|
|
|
}
|
2017-02-18 05:31:16 +02:00
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
$oStorageBackRest->pathCreate($strBuildPath, {bIgnoreExists => true, bCreateParent => true});
|
|
|
|
|
2020-03-12 14:48:45 +02:00
|
|
|
# Clone a copy of the debian package repo
|
|
|
|
executeTest(
|
|
|
|
($strVm ne VM_NONE ? "docker exec -i test-build " : '') .
|
|
|
|
"bash -c 'git clone https://salsa.debian.org/postgresql/pgbackrest.git /root/package-src 2>&1'");
|
|
|
|
|
2020-03-14 20:35:09 +02:00
|
|
|
executeTest(
|
2022-07-19 23:57:13 +02:00
|
|
|
"rsync -rL --exclude=.vagrant --exclude=.git --exclude=test/result ${strBackRestBase}/" .
|
2020-03-14 20:35:09 +02:00
|
|
|
" ${strBuildPath}/");
|
2017-02-18 05:31:16 +02:00
|
|
|
executeTest(
|
2019-10-12 15:45:18 +02:00
|
|
|
($strVm ne VM_NONE ? "docker exec -i test-build " : '') .
|
2019-10-15 13:27:03 +02:00
|
|
|
"bash -c 'cp -r /root/package-src/debian ${strBuildPath} && sudo chown -R " . TEST_USER .
|
|
|
|
" ${strBuildPath}'");
|
2017-02-18 05:31:16 +02:00
|
|
|
|
2017-11-27 01:43:51 +02:00
|
|
|
# Patch files in debian package builds
|
|
|
|
#
|
|
|
|
# Use these commands to create a new patch (may need to modify first line):
|
2022-06-06 22:32:20 +02:00
|
|
|
# BRDIR=/home/vagrant/pgbackrest;BRVM=u22;BRPATCHFILE=${BRDIR?}/test/patch/debian-package.patch
|
2020-03-15 16:09:27 +02:00
|
|
|
# DBDIR=${BRDIR?}/test/result/package/${BRVM}/debian
|
2017-11-27 01:43:51 +02:00
|
|
|
# diff -Naur ${DBDIR?}.old ${DBDIR}.new > ${BRPATCHFILE?}
|
|
|
|
my $strDebianPackagePatch = "${strBackRestBase}/test/patch/debian-package.patch";
|
|
|
|
|
|
|
|
if ($oStorageBackRest->exists($strDebianPackagePatch))
|
|
|
|
{
|
|
|
|
executeTest("cp -r ${strBuildPath}/debian ${strBuildPath}/debian.old");
|
|
|
|
executeTest("patch -d ${strBuildPath}/debian < ${strDebianPackagePatch}");
|
|
|
|
executeTest("cp -r ${strBuildPath}/debian ${strBuildPath}/debian.new");
|
|
|
|
}
|
|
|
|
|
2017-06-24 16:59:00 +02:00
|
|
|
# If dev build then disable static release date used for reproducibility
|
2021-01-22 19:52:30 +02:00
|
|
|
my $bVersionDev = PROJECT_VERSION =~ /dev$/;
|
|
|
|
|
2017-02-18 05:31:16 +02:00
|
|
|
if ($bVersionDev)
|
|
|
|
{
|
2017-06-09 23:51:41 +02:00
|
|
|
my $strRules = ${$oStorageBackRest->get("${strBuildPath}/debian/rules")};
|
2017-02-18 05:31:16 +02:00
|
|
|
|
2017-02-21 21:22:03 +02:00
|
|
|
$strRules =~ s/\-\-var\=release-date-static\=y/\-\-var\=release-date-static\=n/g;
|
|
|
|
$strRules =~ s/\-\-out\=html \-\-cache\-only/\-\-out\=html \-\-no\-exe/g;
|
2017-02-18 05:31:16 +02:00
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
$oStorageBackRest->put("${strBuildPath}/debian/rules", $strRules);
|
2017-02-18 05:31:16 +02:00
|
|
|
}
|
|
|
|
|
2017-06-22 18:37:21 +02:00
|
|
|
# Remove patches that should be applied to core code
|
2017-07-25 18:44:38 +02:00
|
|
|
$oStorageBackRest->remove("${strBuildPath}/debian/patches", {bRecurse => true, bIgnoreExists => true});
|
2017-06-22 18:37:21 +02:00
|
|
|
|
2017-02-18 05:31:16 +02:00
|
|
|
# Update changelog to add experimental version
|
2017-06-09 23:51:41 +02:00
|
|
|
$oStorageBackRest->put("${strBuildPath}/debian/changelog",
|
2021-01-22 19:52:30 +02:00
|
|
|
"pgbackrest (${\PROJECT_VERSION}-0." . ($bVersionDev ? 'D' : 'P') . strftime("%Y%m%d%H%M%S", gmtime) .
|
2017-02-18 05:31:16 +02:00
|
|
|
") experimental; urgency=medium\n" .
|
|
|
|
"\n" .
|
|
|
|
' * Automated experimental ' . ($bVersionDev ? 'development' : 'production') . " build.\n" .
|
|
|
|
"\n" .
|
|
|
|
' -- David Steele <david@pgbackrest.org> ' . strftime("%a, %e %b %Y %H:%M:%S %z", gmtime) . "\n\n" .
|
2017-06-09 23:51:41 +02:00
|
|
|
${$oStorageBackRest->get("${strBuildPath}/debian/changelog")});
|
2017-02-18 05:31:16 +02:00
|
|
|
|
|
|
|
executeTest(
|
2019-10-12 15:45:18 +02:00
|
|
|
($strVm ne VM_NONE ? "docker exec -i test-build " : '') .
|
2021-07-18 23:29:20 +02:00
|
|
|
"bash -c 'cd ${strBuildPath} && debuild -d -i -us -uc -b'");
|
2017-02-18 05:31:16 +02:00
|
|
|
|
|
|
|
executeTest(
|
2019-10-12 15:45:18 +02:00
|
|
|
($strVm ne VM_NONE ? "docker exec -i test-build " : '') .
|
2017-02-18 05:31:16 +02:00
|
|
|
"bash -c 'rm -f ${strPackagePath}/${strBuildVM}/*.build ${strPackagePath}/${strBuildVM}/*.changes" .
|
|
|
|
" ${strPackagePath}/${strBuildVM}/pgbackrest-doc*'");
|
|
|
|
|
2019-10-12 15:45:18 +02:00
|
|
|
if ($strVm ne VM_NONE)
|
|
|
|
{
|
|
|
|
executeTest("docker rm -f test-build");
|
|
|
|
}
|
2017-02-18 05:31:16 +02:00
|
|
|
}
|
2018-02-27 02:32:27 +02:00
|
|
|
|
2020-03-14 20:35:09 +02:00
|
|
|
if ($oVm->{$strBuildVM}{&VM_OS_BASE} eq VM_OS_BASE_RHEL)
|
2018-02-27 02:32:27 +02:00
|
|
|
{
|
|
|
|
&log(INFO, "build package for ${strBuildVM} (${strBuildPath})");
|
|
|
|
|
|
|
|
# Create build container
|
2019-10-12 15:45:18 +02:00
|
|
|
if ($strVm ne VM_NONE)
|
|
|
|
{
|
|
|
|
executeTest(
|
|
|
|
"docker run -itd -h test-build --name=test-build" .
|
2020-03-12 14:48:45 +02:00
|
|
|
" -v ${strBackRestBase}:${strBackRestBase} " . containerRepo() . ":${strBuildVM}-test",
|
2019-10-12 15:45:18 +02:00
|
|
|
{bSuppressStdErr => true});
|
|
|
|
}
|
2018-02-27 02:32:27 +02:00
|
|
|
|
2020-03-12 14:48:45 +02:00
|
|
|
# Fetching specific files is fragile but even a shallow clone of the entire pgrpms repo is very expensive.
|
|
|
|
# Using 'git archive' does not seem to work: access denied or repository not exported: /git/pgrpms.git.
|
|
|
|
executeTest(
|
|
|
|
($strVm ne VM_NONE ? "docker exec -i test-build " : '') .
|
|
|
|
"bash -c \"" .
|
|
|
|
"mkdir /root/package-src && " .
|
|
|
|
"wget -q -O /root/package-src/pgbackrest-conf.patch " .
|
2021-10-14 01:43:40 +02:00
|
|
|
"'https://git.postgresql.org/gitweb/?p=pgrpms.git;a=blob_plain;hb=refs/heads/mas"."ter;" .
|
|
|
|
"f=rpm/redhat/mas"."ter/common/pgbackrest/mas"."ter/pgbackrest-conf.patch' && " .
|
2020-06-01 18:24:19 +02:00
|
|
|
"wget -q -O /root/package-src/pgbackrest.logrotate " .
|
2021-10-14 01:43:40 +02:00
|
|
|
"'https://git.postgresql.org/gitweb/?p=pgrpms.git;a=blob_plain;hb=refs/heads/mas"."ter;" .
|
|
|
|
"f=rpm/redhat/mas"."ter/common/pgbackrest/mas"."ter/pgbackrest.logrotate' && " .
|
2020-03-12 14:48:45 +02:00
|
|
|
"wget -q -O /root/package-src/pgbackrest.spec " .
|
2021-10-14 01:43:40 +02:00
|
|
|
"'https://git.postgresql.org/gitweb/?p=pgrpms.git;a=blob_plain;hb=refs/heads/mas"."ter;" .
|
|
|
|
"f=rpm/redhat/mas"."ter/common/pgbackrest/mas"."ter/pgbackrest.spec'\"");
|
2020-03-12 14:48:45 +02:00
|
|
|
|
2018-02-27 02:32:27 +02:00
|
|
|
# Create build directories
|
|
|
|
$oStorageBackRest->pathCreate($strBuildPath, {bIgnoreExists => true, bCreateParent => true});
|
|
|
|
$oStorageBackRest->pathCreate("${strBuildPath}/SOURCES", {bIgnoreExists => true, bCreateParent => true});
|
|
|
|
$oStorageBackRest->pathCreate("${strBuildPath}/SPECS", {bIgnoreExists => true, bCreateParent => true});
|
|
|
|
$oStorageBackRest->pathCreate("${strBuildPath}/RPMS", {bIgnoreExists => true, bCreateParent => true});
|
|
|
|
$oStorageBackRest->pathCreate("${strBuildPath}/BUILD", {bIgnoreExists => true, bCreateParent => true});
|
|
|
|
|
2019-08-09 20:52:26 +02:00
|
|
|
# Install PostreSQL 11 development for package builds
|
2019-10-12 15:45:18 +02:00
|
|
|
executeTest(
|
|
|
|
($strVm ne VM_NONE ? "docker exec -i test-build " : '') .
|
|
|
|
"bash -c 'yum install -y postgresql11-devel 2>&1'");
|
2019-08-09 20:52:26 +02:00
|
|
|
|
2018-02-27 02:32:27 +02:00
|
|
|
# Copy source files
|
|
|
|
executeTest(
|
2021-01-22 19:52:30 +02:00
|
|
|
"tar --transform='s_^_pgbackrest-release-${\PROJECT_VERSION}/_'" .
|
|
|
|
" -czf ${strBuildPath}/SOURCES/${\PROJECT_VERSION}.tar.gz -C ${strBackRestBase}" .
|
2020-03-09 23:41:59 +02:00
|
|
|
" src LICENSE");
|
2018-02-27 02:32:27 +02:00
|
|
|
|
|
|
|
# Copy package files
|
|
|
|
executeTest(
|
2019-10-12 15:45:18 +02:00
|
|
|
($strVm ne VM_NONE ? "docker exec -i test-build " : '') . "bash -c '" .
|
2018-02-27 02:32:27 +02:00
|
|
|
"ln -s ${strBuildPath} /root/rpmbuild && " .
|
|
|
|
"cp /root/package-src/pgbackrest.spec ${strBuildPath}/SPECS && " .
|
|
|
|
"cp /root/package-src/*.patch ${strBuildPath}/SOURCES && " .
|
2020-06-01 18:24:19 +02:00
|
|
|
"cp /root/package-src/pgbackrest.logrotate ${strBuildPath}/SOURCES && " .
|
2018-02-27 02:32:27 +02:00
|
|
|
"sudo chown -R " . TEST_USER . " ${strBuildPath}'");
|
|
|
|
|
|
|
|
# Patch files in RHEL package builds
|
|
|
|
#
|
|
|
|
# Use these commands to create a new patch (may need to modify first line):
|
2022-06-03 20:13:56 +02:00
|
|
|
# BRDIR=/home/vagrant/pgbackrest;BRVM=rh7;BRPATCHFILE=${BRDIR?}/test/patch/rhel-package.patch
|
2020-03-15 16:09:27 +02:00
|
|
|
# PKDIR=${BRDIR?}/test/result/package/${BRVM}/SPECS
|
2018-02-27 02:32:27 +02:00
|
|
|
# diff -Naur ${PKDIR?}.old ${PKDIR}.new > ${BRPATCHFILE?}
|
|
|
|
my $strPackagePatch = "${strBackRestBase}/test/patch/rhel-package.patch";
|
|
|
|
|
|
|
|
if ($oStorageBackRest->exists($strPackagePatch))
|
|
|
|
{
|
|
|
|
executeTest("cp -r ${strBuildPath}/SPECS ${strBuildPath}/SPECS.old");
|
|
|
|
executeTest("patch -d ${strBuildPath}/SPECS < ${strPackagePatch}");
|
|
|
|
executeTest("cp -r ${strBuildPath}/SPECS ${strBuildPath}/SPECS.new");
|
|
|
|
}
|
|
|
|
|
|
|
|
# Update version number to match current version
|
|
|
|
my $strSpec = ${$oStorageBackRest->get("${strBuildPath}/SPECS/pgbackrest.spec")};
|
2021-01-22 19:52:30 +02:00
|
|
|
$strSpec =~ s/^Version\:.*$/Version\:\t${\PROJECT_VERSION}/gm;
|
2018-02-27 02:32:27 +02:00
|
|
|
$oStorageBackRest->put("${strBuildPath}/SPECS/pgbackrest.spec", $strSpec);
|
|
|
|
|
|
|
|
# Build package
|
|
|
|
executeTest(
|
2019-10-12 15:45:18 +02:00
|
|
|
($strVm ne VM_NONE ? "docker exec -i test-build " : '') .
|
|
|
|
"rpmbuild --define 'pgmajorversion %{nil}' -v -bb --clean root/rpmbuild/SPECS/pgbackrest.spec",
|
2018-02-27 02:32:27 +02:00
|
|
|
{bSuppressStdErr => true});
|
|
|
|
|
|
|
|
# Remove build container
|
2019-10-12 15:45:18 +02:00
|
|
|
if ($strVm ne VM_NONE)
|
|
|
|
{
|
|
|
|
executeTest("docker rm -f test-build");
|
|
|
|
}
|
2018-02-27 02:32:27 +02:00
|
|
|
}
|
2017-02-18 05:31:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Exit if only testing builds
|
|
|
|
exit 0 if $bBuildOnly;
|
|
|
|
}
|
|
|
|
|
2017-08-19 14:48:13 +02:00
|
|
|
# Perform static source code analysis
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
if (!$bDryRun)
|
|
|
|
{
|
|
|
|
logFileSet($oStorageTest, cwd() . "/test");
|
|
|
|
}
|
|
|
|
|
2017-11-28 04:19:59 +02:00
|
|
|
# Run the tests
|
2017-08-19 14:48:13 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2017-02-18 05:31:16 +02:00
|
|
|
if (@{$oyTestRun} == 0)
|
|
|
|
{
|
|
|
|
confess &log(ERROR, 'no tests were selected');
|
|
|
|
}
|
|
|
|
|
|
|
|
&log(INFO, @{$oyTestRun} . ' test' . (@{$oyTestRun} > 1 ? 's': '') . " selected\n");
|
|
|
|
|
2017-11-28 04:19:59 +02:00
|
|
|
# Don't allow --no-cleanup when more than one test will run. How would the prior results be preserved?
|
2017-02-18 05:31:16 +02:00
|
|
|
if ($bNoCleanup && @{$oyTestRun} > 1)
|
|
|
|
{
|
|
|
|
confess &log(ERROR, '--no-cleanup is not valid when more than one test will run')
|
2016-12-13 01:54:07 +02:00
|
|
|
}
|
|
|
|
|
2019-12-17 22:23:07 +02:00
|
|
|
# Disable file logging for integration tests when there is more than one test since it will be overwritten
|
|
|
|
if (@{$oyTestRun} > 1)
|
|
|
|
{
|
|
|
|
$strLogLevelTestFile = lc(OFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
# Don't allow --no-cleanup when more than one test will run. How would the prior results be preserved?
|
|
|
|
|
2017-11-28 04:19:59 +02:00
|
|
|
# Only use one vm for dry run so results are printed in order
|
2016-01-14 05:43:26 +02:00
|
|
|
if ($bDryRun)
|
|
|
|
{
|
2016-09-06 15:35:02 +02:00
|
|
|
$iVmMax = 1;
|
2016-01-14 05:43:26 +02:00
|
|
|
}
|
|
|
|
|
2016-01-09 15:21:53 +02:00
|
|
|
my $iTestIdx = 0;
|
2016-09-06 15:35:02 +02:00
|
|
|
my $iVmTotal;
|
2016-01-09 15:21:53 +02:00
|
|
|
my $iTestMax = @{$oyTestRun};
|
2016-09-06 15:35:02 +02:00
|
|
|
my $bShowOutputAsync = $bVmOut && (@{$oyTestRun} == 1 || $iVmMax == 1) && ! $bDryRun ? true : false;
|
2016-01-09 15:21:53 +02:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
2016-09-06 15:35:02 +02:00
|
|
|
$iVmTotal = 0;
|
2016-01-09 15:21:53 +02:00
|
|
|
|
2016-09-06 15:35:02 +02:00
|
|
|
for (my $iVmIdx = 0; $iVmIdx < $iVmMax; $iVmIdx++)
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2016-09-06 15:35:02 +02:00
|
|
|
if (defined($$oyProcess[$iVmIdx]))
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2017-02-21 15:59:23 +02:00
|
|
|
my ($bDone, $bFail) = $$oyProcess[$iVmIdx]->end();
|
2016-01-09 15:21:53 +02:00
|
|
|
|
2017-02-21 15:59:23 +02:00
|
|
|
if ($bDone)
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2017-02-21 15:59:23 +02:00
|
|
|
if ($bFail)
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2017-02-21 15:59:23 +02:00
|
|
|
if ($oyProcess->[$iVmIdx]->run())
|
|
|
|
{
|
|
|
|
$iTestRetry++;
|
|
|
|
$iVmTotal++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$iTestFail++;
|
|
|
|
$$oyProcess[$iVmIdx] = undef;
|
|
|
|
}
|
2016-01-09 15:21:53 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-02-21 15:59:23 +02:00
|
|
|
$$oyProcess[$iVmIdx] = undef;
|
2016-01-09 15:21:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-09-06 15:35:02 +02:00
|
|
|
$iVmTotal++;
|
2016-01-09 15:21:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-24 16:35:42 +02:00
|
|
|
# Only wait when all VMs are running or all tests have been assigned. Otherwise, there is something to do.
|
|
|
|
if ($iVmTotal == $iVmMax || $iTestIdx == @{$oyTestRun})
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2017-10-24 16:35:42 +02:00
|
|
|
waitHiRes(.05);
|
2016-01-09 15:21:53 +02:00
|
|
|
}
|
|
|
|
}
|
2016-09-06 15:35:02 +02:00
|
|
|
while ($iVmTotal == $iVmMax);
|
2016-01-09 15:21:53 +02:00
|
|
|
|
2016-09-06 15:35:02 +02:00
|
|
|
for (my $iVmIdx = 0; $iVmIdx < $iVmMax; $iVmIdx++)
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2016-09-06 15:35:02 +02:00
|
|
|
if (!defined($$oyProcess[$iVmIdx]) && $iTestIdx < @{$oyTestRun})
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2017-02-21 15:59:23 +02:00
|
|
|
my $oJob = new pgBackRestTest::Common::JobTest(
|
2021-07-17 17:09:53 +02:00
|
|
|
$oStorageTest, $strBackRestBase, $strTestPath, $$oyTestRun[$iTestIdx], $bDryRun, $bVmOut, $iVmIdx, $iVmMax,
|
|
|
|
$strMakeCmd, $iTestIdx, $iTestMax, $strLogLevel, $strLogLevelTest, $strLogLevelTestFile, !$bNoLogTimestamp,
|
2023-01-28 13:55:53 +02:00
|
|
|
$bShowOutputAsync, $bNoCleanup, $iRetry, !$bNoBackTrace, !$bNoValgrind, !$bNoCoverage, $bCoverageSummary,
|
|
|
|
!$bNoOptimize, $bProfile, $iScale, $strTimeZone, !$bNoDebug, $bDebugTestTrace,
|
2021-07-17 17:09:53 +02:00
|
|
|
$iBuildMax / $iVmMax < 1 ? 1 : int($iBuildMax / $iVmMax));
|
2016-01-09 15:21:53 +02:00
|
|
|
$iTestIdx++;
|
|
|
|
|
2017-02-21 15:59:23 +02:00
|
|
|
if ($oJob->run())
|
2016-01-09 15:21:53 +02:00
|
|
|
{
|
2017-02-21 15:59:23 +02:00
|
|
|
$$oyProcess[$iVmIdx] = $oJob;
|
2016-01-09 15:21:53 +02:00
|
|
|
}
|
|
|
|
|
2016-09-06 15:35:02 +02:00
|
|
|
$iVmTotal++;
|
2016-01-09 15:21:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-09-06 15:35:02 +02:00
|
|
|
while ($iVmTotal > 0);
|
2016-01-09 15:21:53 +02:00
|
|
|
|
2017-04-10 18:31:30 +02:00
|
|
|
# Write out coverage info and test coverage
|
2017-08-19 14:48:13 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2017-04-10 18:31:30 +02:00
|
|
|
my $iUncoveredCodeModuleTotal = 0;
|
|
|
|
|
2019-07-05 22:55:17 +02:00
|
|
|
if (vmCoverageC($strVm) && !$bNoCoverage && !$bDryRun && $iTestFail == 0)
|
2017-01-10 03:49:04 +02:00
|
|
|
{
|
2020-03-19 18:07:51 +02:00
|
|
|
$iUncoveredCodeModuleTotal = coverageValidateAndGenerate(
|
2020-06-17 21:07:30 +02:00
|
|
|
$oyTestRun, $oStorageBackRest, !$bNoCoverageReport, $bCoverageSummary, $strTestPath, "${strTestPath}/temp",
|
2020-03-23 18:17:34 +02:00
|
|
|
"${strBackRestBase}/test/result", "${strBackRestBase}/doc/xml/auto");
|
2017-01-10 03:49:04 +02:00
|
|
|
}
|
|
|
|
|
2016-06-24 14:12:58 +02:00
|
|
|
# Print test info and exit
|
2017-08-19 14:48:13 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2017-05-12 22:27:06 +02:00
|
|
|
&log(INFO,
|
|
|
|
($bDryRun ? 'DRY RUN COMPLETED' : 'TESTS COMPLETED') . ($iTestFail == 0 ? ' SUCCESSFULLY' .
|
|
|
|
($iUncoveredCodeModuleTotal == 0 ? '' : " WITH ${iUncoveredCodeModuleTotal} MODULE(S) MISSING COVERAGE") :
|
|
|
|
" WITH ${iTestFail} FAILURE(S)") . ($iTestRetry == 0 ? '' : ", ${iTestRetry} RETRY(IES)") .
|
2020-03-22 16:12:29 +02:00
|
|
|
($bNoLogTimestamp ? '' : ' (' . (time() - $lStartTime) . 's)'));
|
2017-04-10 18:31:30 +02:00
|
|
|
|
2019-05-15 19:04:56 +02:00
|
|
|
exit 1 if ($iTestFail > 0 || ($iUncoveredCodeModuleTotal > 0 && !$bCoverageSummary));
|
2016-01-09 15:21:53 +02:00
|
|
|
|
2017-04-10 18:31:30 +02:00
|
|
|
exit 0;
|
2016-01-09 15:21:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
################################################################################################################################
|
|
|
|
# Runs tests
|
|
|
|
################################################################################################################################
|
|
|
|
my $iRun = 0;
|
2014-07-17 06:38:38 +03:00
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
# Create host group for containers
|
2016-06-24 14:12:58 +02:00
|
|
|
my $oHostGroup = hostGroupGet();
|
2015-09-08 18:58:13 +02:00
|
|
|
|
2019-12-12 05:11:04 +02:00
|
|
|
# Set timezone
|
|
|
|
if (defined($strTimeZone))
|
|
|
|
{
|
|
|
|
$ENV{TZ} = $strTimeZone;
|
|
|
|
}
|
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
# Run the test
|
2017-01-05 01:29:13 +02:00
|
|
|
testRun($stryModule[0], $stryModuleTest[0])->process(
|
2016-12-23 15:22:59 +02:00
|
|
|
$strVm, $iVmId, # Vm info
|
|
|
|
$strBackRestBase, # Base backrest directory
|
|
|
|
$strTestPath, # Path where the tests will run
|
2020-03-15 16:09:27 +02:00
|
|
|
dirname($strTestPath) . "/bin/${strVm}/" . PROJECT_EXE, # Path to the pgbackrest binary
|
2022-07-27 16:32:32 +02:00
|
|
|
dirname($strTestPath) . "/build/" . VM_NONE . '/src/' . PROJECT_EXE, # Path to the pgbackrest storage helper
|
2018-02-04 01:27:38 +02:00
|
|
|
$strPgVersion ne 'minimal' ? $strPgSqlBin: undef, # Pg bin path
|
|
|
|
$strPgVersion ne 'minimal' ? $strPgVersion: undef, # Pg version
|
2017-01-05 01:29:13 +02:00
|
|
|
$stryModule[0], $stryModuleTest[0], \@iyModuleTestRun, # Module info
|
2022-05-10 19:18:26 +02:00
|
|
|
$bVmOut, $bDryRun, $bNoCleanup, # Test options
|
2019-12-17 22:23:07 +02:00
|
|
|
$strLogLevelTestFile, # Log options
|
2019-10-12 15:45:18 +02:00
|
|
|
TEST_USER, TEST_GROUP); # User/group info
|
2015-09-09 21:40:54 +02:00
|
|
|
|
2016-06-24 14:12:58 +02:00
|
|
|
if (!$bNoCleanup)
|
|
|
|
{
|
|
|
|
if ($oHostGroup->removeAll() > 0)
|
|
|
|
{
|
2019-10-12 15:45:18 +02:00
|
|
|
executeTest("rm -rf ${strTestPath}");
|
2015-06-14 00:25:49 +02:00
|
|
|
}
|
2015-02-28 06:31:39 +02:00
|
|
|
}
|
2015-06-14 00:25:49 +02:00
|
|
|
|
2016-09-06 15:44:50 +02:00
|
|
|
if (!$bDryRun && !$bVmOut)
|
2015-04-08 00:36:59 +02:00
|
|
|
{
|
2016-09-06 15:44:50 +02:00
|
|
|
&log(INFO, 'TESTS COMPLETED SUCCESSFULLY (DESPITE ANY ERROR MESSAGES YOU SAW)');
|
2015-04-08 00:36:59 +02:00
|
|
|
}
|
2015-06-14 00:25:49 +02:00
|
|
|
|
2016-09-06 15:44:50 +02:00
|
|
|
# Exit with success
|
|
|
|
exit 0;
|
2014-06-22 18:56:01 +03:00
|
|
|
}
|
2015-06-14 00:25:49 +02:00
|
|
|
|
2016-09-06 15:44:50 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# Check for errors
|
|
|
|
####################################################################################################################################
|
|
|
|
or do
|
2014-07-16 05:32:41 +03:00
|
|
|
{
|
2016-09-06 15:44:50 +02:00
|
|
|
# If a backrest exception then return the code
|
2018-03-15 17:03:28 +02:00
|
|
|
if (isException(\$EVAL_ERROR))
|
|
|
|
{
|
2019-10-17 14:00:18 +02:00
|
|
|
if ($EVAL_ERROR->code() != ERROR_OPTION_INVALID_VALUE)
|
|
|
|
{
|
|
|
|
syswrite(*STDOUT, $EVAL_ERROR->message() . "\n" . $EVAL_ERROR->trace());
|
|
|
|
}
|
|
|
|
|
2018-03-15 17:03:28 +02:00
|
|
|
exit $EVAL_ERROR->code();
|
|
|
|
}
|
2016-09-06 15:44:50 +02:00
|
|
|
|
|
|
|
# Else output the unhandled error
|
2017-08-25 22:47:47 +02:00
|
|
|
syswrite(*STDOUT, $EVAL_ERROR);
|
2016-09-06 15:44:50 +02:00
|
|
|
exit ERROR_UNHANDLED;
|
|
|
|
};
|
|
|
|
|
|
|
|
# It shouldn't be possible to get here
|
|
|
|
&log(ASSERT, 'execution reached invalid location in ' . __FILE__ . ', line ' . __LINE__);
|
|
|
|
exit ERROR_ASSERT;
|