You've already forked pgbackrest
							
							
				mirror of
				https://github.com/pgbackrest/pgbackrest.git
				synced 2025-10-30 23:37:45 +02:00 
			
		
		
		
	Allow most unit tests to run outside of a container.
Three major changes were required to get this working: 1) Provide the path to pgbackrest in the build directory when running outside a container. Tests in a container will continue to install and run against /usr/bin/pgbackrest. 1) Set a per-test lock path so tests don't conflict on the default /tmp/pgbackrest path. Also set a per-test log-path while we are at it. 2) Use localhost instead of a custom host for TLS test connections. Tests in containers will continue to update /etc/hosts and use the custom host. Add infrastructure and update harnessCfgLoad*() to get the correct exe and paths loaded for testing. Since new tests are required to verify that running outside a container works, also rework the tests in Travis CI to provide coverage within a reasonable amount of time. Mainly, break up to doc tests by VM and run an abbreviated unit test suite on co6 and co7.
This commit is contained in:
		
							
								
								
									
										17
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -11,12 +11,17 @@ language: c | ||||
| services: | ||||
|   - docker | ||||
|  | ||||
| env: | ||||
|   - PGB_CI="doc" | ||||
|   - PGB_CI="--vm=u18 test" | ||||
|   - PGB_CI="--vm=co6 test" | ||||
|   - PGB_CI="--vm=co7 test" | ||||
|   - PGB_CI="--vm=u12 test" | ||||
| matrix: | ||||
|   include: | ||||
|     - env: PGB_CI="--vm=u12 test" | ||||
|     - env: PGB_CI="--vm=co6 test" | ||||
|     - env: PGB_CI="--vm=co7 test" | ||||
|     - env: PGB_CI="--vm=u18 test" | ||||
|     - env: PGB_CI="--vm=u18 doc" | ||||
|     - dist: bionic | ||||
|       env: PGB_CI="--vm=none test" | ||||
|     - env: PGB_CI="--vm=co7 doc" | ||||
|     - env: PGB_CI="--vm=co6 doc" | ||||
|  | ||||
| before_install: | ||||
|   - sudo apt-get -qq update || true | ||||
|   | ||||
| @@ -40,6 +40,7 @@ use pgBackRest::Version; | ||||
| use pgBackRestTest::Common::ExecuteTest; | ||||
| use pgBackRestTest::Common::Storage; | ||||
| use pgBackRestTest::Common::StoragePosix; | ||||
| use pgBackRestTest::Common::VmTest; | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Usage | ||||
| @@ -63,6 +64,7 @@ release.pl [options] | ||||
|    --build          Build the cache before release (should be included in the release commit) | ||||
|    --deploy         Deploy documentation to website (can be done as docs are updated) | ||||
|    --no-gen         Don't auto-generate | ||||
|    --vm             vm to build documentation for | ||||
| =cut | ||||
|  | ||||
| #################################################################################################################################### | ||||
| @@ -75,6 +77,7 @@ my $strLogLevel = 'info'; | ||||
| my $bBuild = false; | ||||
| my $bDeploy = false; | ||||
| my $bNoGen = false; | ||||
| my $strVm = undef; | ||||
|  | ||||
| GetOptions ('help' => \$bHelp, | ||||
|             'version' => \$bVersion, | ||||
| @@ -82,7 +85,8 @@ GetOptions ('help' => \$bHelp, | ||||
|             'log-level=s' => \$strLogLevel, | ||||
|             'build' => \$bBuild, | ||||
|             'deploy' => \$bDeploy, | ||||
|             'no-gen' => \$bNoGen) | ||||
|             'no-gen' => \$bNoGen, | ||||
|             'vm=s' => \$strVm) | ||||
|     or pod2usage(2); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| @@ -222,33 +226,55 @@ eval | ||||
|         executeTest('docker rm -f $(docker ps -a -q)', {bSuppressError => true}); | ||||
|  | ||||
|         # Generate deployment docs for RHEL/Centos 7 | ||||
|         &log(INFO, "Generate RHEL/CentOS 7 documentation"); | ||||
|         if (!defined($strVm) || $strVm eq VM_CO7) | ||||
|         { | ||||
|             &log(INFO, "Generate RHEL/CentOS 7 documentation"); | ||||
|  | ||||
|         executeTest("${strDocExe} --deploy --key-var=os-type=centos7 --out=pdf", {bShowOutputAsync => true}); | ||||
|         executeTest("${strDocExe} --deploy --cache-only --key-var=os-type=centos7 --out=pdf"); | ||||
|             executeTest("${strDocExe} --deploy --key-var=os-type=centos7 --out=pdf", {bShowOutputAsync => true}); | ||||
|  | ||||
|             if (!defined($strVm)) | ||||
|             { | ||||
|                 executeTest("${strDocExe} --deploy --cache-only --key-var=os-type=centos7 --out=pdf"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         # Generate deployment docs for RHEL/Centos 6 | ||||
|         &log(INFO, "Generate RHEL/CentOS 6 documentation"); | ||||
|         if (!defined($strVm) || $strVm eq VM_CO6) | ||||
|         { | ||||
|             &log(INFO, "Generate RHEL/CentOS 6 documentation"); | ||||
|  | ||||
|         executeTest("${strDocExe} --deploy --key-var=os-type=centos6 --out=pdf", {bShowOutputAsync => true}); | ||||
|         executeTest("${strDocExe} --deploy --cache-only --key-var=os-type=centos6 --out=pdf"); | ||||
|             executeTest("${strDocExe} --deploy --key-var=os-type=centos6 --out=html", {bShowOutputAsync => true}); | ||||
|  | ||||
|             if (!defined($strVm)) | ||||
|             { | ||||
|                 executeTest("${strDocExe} --deploy --cache-only --key-var=os-type=centos6 --out=html"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         # Generate deployment docs for Debian | ||||
|         &log(INFO, "Generate Debian/Ubuntu documentation"); | ||||
|         if (!defined($strVm) || $strVm eq VM_U18) | ||||
|         { | ||||
|             &log(INFO, "Generate Debian/Ubuntu documentation"); | ||||
|  | ||||
|         executeTest("${strDocExe} --deploy", {bShowOutputAsync => true}); | ||||
|             executeTest("${strDocExe} --deploy --out=man --out=html --out=markdown", {bShowOutputAsync => true}); | ||||
|         } | ||||
|  | ||||
|         # Generate a full copy of the docs for review | ||||
|         &log(INFO, "Generate full documentation for review"); | ||||
|         if (!defined($strVm)) | ||||
|         { | ||||
|             &log(INFO, "Generate full documentation for review"); | ||||
|  | ||||
|         executeTest("${strDocExe} --deploy --cache-only --key-var=os-type=centos7 --out=html --var=project-url-root=index.html"); | ||||
|         $oStorageDoc->move("$strDocHtml/user-guide.html", "$strDocHtml/user-guide-centos7.html"); | ||||
|         executeTest( | ||||
|             "${strDocExe} --deploy --out-preserve --cache-only --key-var=os-type=centos6 --out=html" . | ||||
|                 " --var=project-url-root=index.html"); | ||||
|         $oStorageDoc->move("$strDocHtml/user-guide.html", "$strDocHtml/user-guide-centos6.html"); | ||||
|             executeTest( | ||||
|             "${strDocExe} --deploy --cache-only --key-var=os-type=centos7 --out=html --var=project-url-root=index.html"); | ||||
|             $oStorageDoc->move("$strDocHtml/user-guide.html", "$strDocHtml/user-guide-centos7.html"); | ||||
|             executeTest( | ||||
|                 "${strDocExe} --deploy --out-preserve --cache-only --key-var=os-type=centos6 --out=html" . | ||||
|                     " --var=project-url-root=index.html"); | ||||
|             $oStorageDoc->move("$strDocHtml/user-guide.html", "$strDocHtml/user-guide-centos6.html"); | ||||
|  | ||||
|         executeTest("${strDocExe} --deploy --out-preserve --cache-only --out=man --out=html --var=project-url-root=index.html"); | ||||
|             executeTest( | ||||
|                 "${strDocExe} --deploy --out-preserve --cache-only --out=man --out=html --var=project-url-root=index.html"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if ($bDeploy) | ||||
|   | ||||
							
								
								
									
										16
									
								
								test/Vagrantfile
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								test/Vagrantfile
									
									
									
									
										vendored
									
									
								
							| @@ -46,6 +46,13 @@ Vagrant.configure(2) do |config| | ||||
|         sudo /etc/init.d/virtualbox-guest-utils stop | ||||
|         sudo /usr/sbin/VBoxService --timesync-set-on-restore --timesync-interval 5000 --timesync-set-threshold 1 | ||||
|  | ||||
|         # Create /tmp/pgbackrest and give ownership to root so we know unit tests are not writing there | ||||
|         #--------------------------------------------------------------------------------------------------------------------------- | ||||
|         echo 'Create /tmp/pgbackrest owned by root' && date | ||||
|         sudo mkdir -p /tmp/pgbackrest | ||||
|         sudo chown root:root /tmp/pgbackrest | ||||
|         sudo chmod 700 /tmp/pgbackrest | ||||
|  | ||||
|         # Mount tmpfs at /home/vagrant/test for faster testing | ||||
|         #--------------------------------------------------------------------------------------------------------------------------- | ||||
|         echo 'Mount tmpfs' && date | ||||
| @@ -60,7 +67,7 @@ Vagrant.configure(2) do |config| | ||||
|         #--------------------------------------------------------------------------------------------------------------------------- | ||||
|         echo 'Install Build Tools' && date | ||||
|         apt-get install -y devscripts build-essential lintian git lcov cloc txt2man debhelper libssl-dev zlib1g-dev libperl-dev \ | ||||
|              libxml2-dev liblz4-dev libpq-dev | ||||
|              libxml2-dev liblz4-dev libpq-dev valgrind | ||||
|  | ||||
|         #--------------------------------------------------------------------------------------------------------------------------- | ||||
|         echo 'Install AWS CLI' && date | ||||
| @@ -82,9 +89,10 @@ Vagrant.configure(2) do |config| | ||||
|         apt-get install -y vim htop | ||||
|  | ||||
|         #--------------------------------------------------------------------------------------------------------------------------- | ||||
|         echo 'Install TeX Live' && date | ||||
|         apt-get install -y --no-install-recommends texlive-latex-base texlive-latex-extra texlive-fonts-recommended | ||||
|         apt-get install -y texlive-font-utils | ||||
|         # echo 'Install TeX Live' && date | ||||
|         # Not installed by default since latex is only needed for releases and PDF development/testing | ||||
|         # apt-get install -y --no-install-recommends texlive-latex-base texlive-latex-extra texlive-fonts-recommended | ||||
|         # apt-get install -y texlive-font-utils | ||||
|  | ||||
|         #--------------------------------------------------------------------------------------------------------------------------- | ||||
|         echo 'Create Postgres Group & pgBackRest User' && date | ||||
|   | ||||
| @@ -17,6 +17,7 @@ | ||||
| #     * define-test - defines for the test harness | ||||
| #     * debugUnitSuppress - don't define DEBUG_UNIT for unit tests -- this is used to test unit test debugging macros | ||||
| #     * perlReq - is Perl required for this C test? | ||||
| #     * containerReq - is this test required to run in a container? | ||||
| # | ||||
| # Some options are unique to tests: | ||||
| #     * total - total runs in the test | ||||
| @@ -241,6 +242,7 @@ unit: | ||||
|       # ---------------------------------------------------------------------------------------------------------------------------- | ||||
|       - name: io-tls | ||||
|         total: 4 | ||||
|         containerReq: true | ||||
|  | ||||
|         coverage: | ||||
|           common/io/tls/client: full | ||||
| @@ -450,6 +452,7 @@ unit: | ||||
|       # ---------------------------------------------------------------------------------------------------------------------------- | ||||
|       - name: posix | ||||
|         total: 20 | ||||
|         containerReq: true | ||||
|  | ||||
|         coverage: | ||||
|           storage/posix/read: full | ||||
| @@ -463,6 +466,7 @@ unit: | ||||
|       # ---------------------------------------------------------------------------------------------------------------------------- | ||||
|       - name: remote | ||||
|         total: 11 | ||||
|         containerReq: true | ||||
|         perlReq: true | ||||
|  | ||||
|         coverage: | ||||
| @@ -503,6 +507,7 @@ unit: | ||||
|       # ---------------------------------------------------------------------------------------------------------------------------- | ||||
|       - name: protocol | ||||
|         total: 8 | ||||
|         containerReq: true | ||||
|         perlReq: true | ||||
|  | ||||
|         coverage: | ||||
| @@ -567,6 +572,7 @@ unit: | ||||
|       # ---------------------------------------------------------------------------------------------------------------------------- | ||||
|       - name: db | ||||
|         total: 2 | ||||
|         containerReq: true | ||||
|         perlReq: true | ||||
|  | ||||
|         coverage: | ||||
| @@ -694,6 +700,7 @@ unit: | ||||
|       # ---------------------------------------------------------------------------------------------------------------------------- | ||||
|       - name: restore | ||||
|         total: 11 | ||||
|         containerReq: true | ||||
|         perlReq: true | ||||
|  | ||||
|         coverage: | ||||
|   | ||||
| @@ -86,16 +86,22 @@ sub process | ||||
|         "services:\n" . | ||||
|         "  - docker\n" . | ||||
|         "\n" . | ||||
|         "env:\n"; | ||||
|  | ||||
|     $strConfig .= "  - PGB_CI=\"doc\"\n"; | ||||
|         "matrix:\n" . | ||||
|         "  include:\n"; | ||||
|  | ||||
|     # Iterate each OS | ||||
|     foreach my $strVm (VM_LIST) | ||||
|     { | ||||
|         $strConfig .= "  - PGB_CI=\"--vm=${strVm} test\"\n"; | ||||
|         $strConfig .= "    - env: PGB_CI=\"--vm=${strVm} test\"\n"; | ||||
|     } | ||||
|  | ||||
|     $strConfig .= | ||||
|         "    - env: PGB_CI=\"--vm=u18 doc\"\n" . | ||||
|         "    - dist: bionic\n" . | ||||
|         "      env: PGB_CI=\"--vm=none test\"\n" . | ||||
|         "    - env: PGB_CI=\"--vm=co7 doc\"\n" . | ||||
|         "    - env: PGB_CI=\"--vm=co6 doc\"\n"; | ||||
|  | ||||
|     # Configure install and script | ||||
|     $strConfig .= | ||||
|         "\n" . | ||||
|   | ||||
| @@ -43,7 +43,7 @@ use constant TEST_GROUP_ID                                          => getgrnam( | ||||
|  | ||||
| use constant BACKREST_USER                                          => 'pgbackrest'; | ||||
|     push @EXPORT, qw(BACKREST_USER); | ||||
| use constant BACKREST_USER_ID                                       => getpwnam(BACKREST_USER) . ''; | ||||
| use constant BACKREST_USER_ID                                   => getpwnam(BACKREST_USER) ? getpwnam(BACKREST_USER) . '' : undef; | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Package constants | ||||
|   | ||||
| @@ -41,6 +41,8 @@ use constant TESTDEF_DB                                             => 'db'; | ||||
|     push @EXPORT, qw(TESTDEF_DB); | ||||
| use constant TESTDEF_CONTAINER                                      => 'container'; | ||||
|     push @EXPORT, qw(TESTDEF_CONTAINER); | ||||
| use constant TESTDEF_CONTAINER_REQUIRED                             => 'containerReq'; | ||||
|     push @EXPORT, qw(TESTDEF_CONTAINER_REQUIRED); | ||||
| use constant TESTDEF_COVERAGE                                       => 'coverage'; | ||||
|     push @EXPORT, qw(TESTDEF_COVERAGE); | ||||
| use constant TESTDEF_EXPECT                                         => 'expect'; | ||||
| @@ -126,7 +128,8 @@ sub testDefLoad | ||||
|  | ||||
|                 # Resolve variables that can be set in the module or the test | ||||
|                 foreach my $strVar ( | ||||
|                     TESTDEF_DEFINE, TESTDEF_DEFINE_TEST, TESTDEF_DEBUG_UNIT_SUPPRESS, TESTDEF_DB, TESTDEF_PERL_REQ, TESTDEF_VM) | ||||
|                     TESTDEF_DEFINE, TESTDEF_DEFINE_TEST, TESTDEF_DEBUG_UNIT_SUPPRESS, TESTDEF_DB, TESTDEF_PERL_REQ, TESTDEF_VM, | ||||
|                     TESTDEF_CONTAINER_REQUIRED) | ||||
|                 { | ||||
|                     $hTestDefHash->{$strModule}{$strTest}{$strVar} = coalesce( | ||||
|                         $hModuleTest->{$strVar}, $hModule->{$strVar}, $strVar eq TESTDEF_VM ? undef : false); | ||||
|   | ||||
| @@ -55,6 +55,7 @@ sub new | ||||
|     # Set defaults | ||||
|     $self->{bSuppressError} = defined($self->{bSuppressError}) ? $self->{bSuppressError} : false; | ||||
|     $self->{bSuppressStdErr} = defined($self->{bSuppressStdErr}) ? $self->{bSuppressStdErr} : false; | ||||
|     $self->{bOutLogOnError} = defined($self->{bOutLogOnError}) ? $self->{bOutLogOnError} : true; | ||||
|     $self->{bShowOutput} = defined($self->{bShowOutput}) ? $self->{bShowOutput} : false; | ||||
|     $self->{bShowOutputAsync} = defined($self->{bShowOutputAsync}) ? $self->{bShowOutputAsync} : false; | ||||
|     $self->{iExpectedExitStatus} = defined($self->{iExpectedExitStatus}) ? $self->{iExpectedExitStatus} : 0; | ||||
| @@ -252,8 +253,10 @@ sub endRetry | ||||
|             { | ||||
|                 confess &log(ERROR, "command '$self->{strCommand}' returned " . $iExitStatus . | ||||
|                              ($self->{iExpectedExitStatus} != 0 ? ", but $self->{iExpectedExitStatus} was expected" : '') . "\n" . | ||||
|                              ($self->{strOutLog} ne '' ? "STDOUT (last 10,000 characters):\n" . substr($self->{strOutLog}, | ||||
|                                  length($self->{strOutLog}) > 10000 ? length($self->{strOutLog}) - 10000 : 0) : '') . | ||||
|                              ($self->{strOutLog} ne '' && $self->{bOutLogOnError} ? "STDOUT (last 10,000 characters):\n" . | ||||
|                                 substr( | ||||
|                                     $self->{strOutLog}, length($self->{strOutLog}) > 10000 ? | ||||
|                                     length($self->{strOutLog}) - 10000 : 0) : '') . | ||||
|                              ($self->{strErrorLog} ne '' ? "STDERR:\n$self->{strErrorLog}" : '')); | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -55,7 +55,6 @@ sub new | ||||
|         $self->{oStorageTest}, | ||||
|         $self->{strBackRestBase}, | ||||
|         $self->{strTestPath}, | ||||
|         $self->{strCoveragePath}, | ||||
|         $self->{oTest}, | ||||
|         $self->{bDryRun}, | ||||
|         $self->{bVmOut}, | ||||
| @@ -86,7 +85,6 @@ sub new | ||||
|             {name => 'oStorageTest'}, | ||||
|             {name => 'strBackRestBase'}, | ||||
|             {name => 'strTestPath'}, | ||||
|             {name => 'strCoveragePath'}, | ||||
|             {name => 'oTest'}, | ||||
|             {name => 'bDryRun'}, | ||||
|             {name => 'bVmOut'}, | ||||
| @@ -117,7 +115,7 @@ sub new | ||||
|  | ||||
|     # Setup the path where gcc coverage will be performed | ||||
|     $self->{strGCovPath} = "$self->{strTestPath}/gcov-$self->{oTest}->{&TEST_VM}-$self->{iVmIdx}"; | ||||
|     $self->{strExpectPath} = "$self->{strTestPath}/expect-$self->{iVmIdx}"; | ||||
|     $self->{strDataPath} = "$self->{strTestPath}/data-$self->{iVmIdx}"; | ||||
|  | ||||
|     # Return from function and log return values if any | ||||
|     return logDebugReturn | ||||
| @@ -189,24 +187,26 @@ sub run | ||||
|                 $bGCovExists = false; | ||||
|             } | ||||
|  | ||||
|             # Create expect directory | ||||
|             if ($self->{oTest}->{&TEST_C} && !$self->{oStorageTest}->pathExists($self->{strExpectPath})) | ||||
|             # Create data directory | ||||
|             if ($self->{oTest}->{&TEST_C} && !$self->{oStorageTest}->pathExists($self->{strDataPath})) | ||||
|             { | ||||
|                 $self->{oStorageTest}->pathCreate($self->{strExpectPath}, {strMode => '0770'}); | ||||
|                 $self->{oStorageTest}->pathCreate($self->{strDataPath}, {strMode => '0770'}); | ||||
|             } | ||||
|  | ||||
|             if ($self->{oTest}->{&TEST_CONTAINER}) | ||||
|             { | ||||
|                 executeTest( | ||||
|                     'docker run -itd -h ' . $self->{oTest}->{&TEST_VM} . "-test --name=${strImage}" . | ||||
|                     " -v $self->{strCoveragePath}:$self->{strCoveragePath} " . | ||||
|                     " -v ${strHostTestPath}:${strVmTestPath}" . | ||||
|                     ($self->{oTest}->{&TEST_C} ? " -v $self->{strGCovPath}:$self->{strGCovPath}" : '') . | ||||
|                     ($self->{oTest}->{&TEST_C} ? " -v $self->{strExpectPath}:$self->{strExpectPath}" : '') . | ||||
|                     " -v $self->{strBackRestBase}:$self->{strBackRestBase} " . | ||||
|                     containerRepo() . ':' . $self->{oTest}->{&TEST_VM} . | ||||
|                     "-test", | ||||
|                     {bSuppressStdErr => true}); | ||||
|                 if ($self->{oTest}->{&TEST_VM} ne VM_NONE) | ||||
|                 { | ||||
|                     executeTest( | ||||
|                         'docker run -itd -h ' . $self->{oTest}->{&TEST_VM} . "-test --name=${strImage}" . | ||||
|                         " -v ${strHostTestPath}:${strVmTestPath}" . | ||||
|                         ($self->{oTest}->{&TEST_C} ? " -v $self->{strGCovPath}:$self->{strGCovPath}" : '') . | ||||
|                         ($self->{oTest}->{&TEST_C} ? " -v $self->{strDataPath}:$self->{strDataPath}" : '') . | ||||
|                         " -v $self->{strBackRestBase}:$self->{strBackRestBase} " . | ||||
|                         containerRepo() . ':' . $self->{oTest}->{&TEST_VM} . | ||||
|                         "-test", | ||||
|                         {bSuppressStdErr => true}); | ||||
|                 } | ||||
|  | ||||
|                 # If testing C code copy source files to the test directory | ||||
|                 if ($self->{oTest}->{&TEST_C}) | ||||
| @@ -230,7 +230,7 @@ sub run | ||||
|                 } | ||||
|  | ||||
|                 # If testing Perl code (or C code that calls Perl code) install bin and Perl C Library | ||||
|                 if (!$self->{oTest}->{&TEST_C} || $self->{oTest}->{&TEST_PERL_REQ}) | ||||
|                 if ($self->{oTest}->{&TEST_VM} ne VM_NONE && (!$self->{oTest}->{&TEST_C} || $self->{oTest}->{&TEST_PERL_REQ})) | ||||
|                 { | ||||
|                     jobInstallC( | ||||
|                         $self->{strBackRestBase}, $self->{oTest}->{&TEST_VM}, $strImage, | ||||
| @@ -253,7 +253,8 @@ sub run | ||||
|         if ($self->{oTest}->{&TEST_C}) | ||||
|         { | ||||
|             $strCommand = | ||||
|                 'docker exec -i -u ' . TEST_USER . " ${strImage} bash -l -c '" . | ||||
|                 ($self->{oTest}->{&TEST_VM} ne VM_NONE  ? 'docker exec -i -u ' . TEST_USER . " ${strImage} " : '') . | ||||
|                 "bash -l -c '" . | ||||
|                 "cd $self->{strGCovPath} && " . | ||||
|                 "make -j $self->{iBuildMax} -s 2>&1 &&" . | ||||
|                 ($self->{oTest}->{&TEST_VM} ne VM_CO6 && $self->{bValgrindUnit} && | ||||
| @@ -372,9 +373,18 @@ sub run | ||||
|                         $strDepend; | ||||
|                 } | ||||
|  | ||||
|                 # Determine where the project exe is located | ||||
|                 my $strProjectExePath = $self->{oTest}->{&TEST_VM} eq VM_NONE ? | ||||
|                     "$self->{strBackRestBase}/test/.vagrant/bin/$self->{oTest}->{&TEST_VM}/src/" . PROJECT_EXE : PROJECT_EXE; | ||||
|  | ||||
|                 # Is this test running in a container? | ||||
|                 my $strContainer = $self->{oTest}->{&TEST_VM} eq VM_NONE ? 'false' : 'true'; | ||||
|  | ||||
|                 # Set globals | ||||
|                 $strTestC =~ s/\{\[C\_TEST\_CONTAINER\]\}/$strContainer/g; | ||||
|                 $strTestC =~ s/\{\[C\_TEST\_PROJECT\_EXE\]\}/$strProjectExePath/g; | ||||
|                 $strTestC =~ s/\{\[C\_TEST\_PATH\]\}/$strVmTestPath/g; | ||||
|                 $strTestC =~ s/\{\[C\_TEST\_EXPECT_PATH\]\}/$self->{strExpectPath}/g; | ||||
|                 $strTestC =~ s/\{\[C\_TEST\_DATA_PATH\]\}/$self->{strDataPath}/g; | ||||
|                 $strTestC =~ s/\{\[C\_TEST\_REPO_PATH\]\}/$self->{strBackRestBase}/g; | ||||
|                 $strTestC =~ s/\{\[C\_TEST\_SCALE\]\}/$self->{iScale}/g; | ||||
|  | ||||
| @@ -571,7 +581,7 @@ sub end | ||||
|         if ($iExitStatus == 0 && $self->{oTest}->{&TEST_C} && $self->{bProfile}) | ||||
|         { | ||||
|             executeTest( | ||||
|                 'docker exec -i -u ' . TEST_USER . " ${strImage} " . | ||||
|                 ($self->{oTest}->{&TEST_VM} ne VM_NONE  ? 'docker exec -i -u ' . TEST_USER . " ${strImage} " : '') . | ||||
|                     "gprof $self->{strGCovPath}/test.bin $self->{strGCovPath}/gmon.out > $self->{strGCovPath}/gprof.txt"); | ||||
|  | ||||
|             $self->{oStorageTest}->pathCreate("$self->{strBackRestBase}/test/profile", {strMode => '0750', bIgnoreExists => true}); | ||||
| @@ -606,7 +616,7 @@ sub end | ||||
|             my $strLCovOutTmp = $self->{strGCovPath} . '/test.tmp.lcov'; | ||||
|  | ||||
|             executeTest( | ||||
|                 'docker exec -i -u ' . TEST_USER . " ${strImage} " . | ||||
|                 ($self->{oTest}->{&TEST_VM} ne VM_NONE  ? 'docker exec -i -u ' . TEST_USER . " ${strImage} " : '') . | ||||
|                 "${strLCovExeBase} --capture --directory=$self->{strGCovPath} --o=${strLCovOut}"); | ||||
|  | ||||
|             # Generate coverage report for each module | ||||
| @@ -731,8 +741,12 @@ sub end | ||||
|         { | ||||
|             my $strHostTestPath = "$self->{strTestPath}/${strImage}"; | ||||
|  | ||||
|             containerRemove("test-$self->{iVmIdx}"); | ||||
|             executeTest("sudo rm -rf ${strHostTestPath}"); | ||||
|             if ($self->{oTest}->{&TEST_VM} ne VM_NONE) | ||||
|             { | ||||
|                 containerRemove("test-$self->{iVmIdx}"); | ||||
|             } | ||||
|  | ||||
|             executeTest(($self->{oTest}->{&TEST_VM} ne VM_NONE ? "sudo " : '') . "rm -rf ${strHostTestPath}"); | ||||
|         } | ||||
|  | ||||
|         $bDone = true; | ||||
|   | ||||
| @@ -65,6 +65,7 @@ sub testListGet | ||||
|     my $strDbVersion = shift; | ||||
|     my $bCoverageOnly = shift; | ||||
|     my $bCOnly = shift; | ||||
|     my $bContainerOnly = shift; | ||||
|  | ||||
|     my $oyVm = vmGet(); | ||||
|     my $oyTestRun = []; | ||||
| @@ -113,6 +114,18 @@ sub testListGet | ||||
|                         # Skip this test if only C tests are requested and this is not a C test | ||||
|                         next if ($bCOnly && !$hTest->{&TESTDEF_C}); | ||||
|  | ||||
|                         # Skip this test if it is integration and vm=none | ||||
|                         next if ($strVm eq VM_NONE && $hTest->{&TESTDEF_TYPE} eq TESTDEF_INTEGRATION); | ||||
|  | ||||
|                         # Skip this test if it is not C and vm=none.  Perl tests require libc which is not supported. | ||||
|                         next if ($strVm eq VM_NONE && !$hTest->{&TESTDEF_C}); | ||||
|  | ||||
|                         # Skip this test if a container is required and vm=none. | ||||
|                         next if ($strVm eq VM_NONE && $hTest->{&TESTDEF_CONTAINER_REQUIRED}); | ||||
|  | ||||
|                         # Skip this if it does not require a container and container only tests are required. | ||||
|                         next if ($bContainerOnly && $hTest->{&TESTDEF_C} && !$hTest->{&TESTDEF_CONTAINER_REQUIRED}); | ||||
|  | ||||
|                         for (my $iDbVersionIdx = $iDbVersionMax; $iDbVersionIdx >= $iDbVersionMin; $iDbVersionIdx--) | ||||
|                         { | ||||
|                             if ($iDbVersionIdx == -1 || $strDbVersion eq 'all' || $strDbVersion eq 'minimal' || | ||||
|   | ||||
| @@ -80,6 +80,9 @@ use constant VM_ARCH_AMD64                                          => 'amd64'; | ||||
| use constant VM_ALL                                                 => 'all'; | ||||
|     push @EXPORT, qw(VM_ALL); | ||||
|  | ||||
| use constant VM_NONE                                                => 'none'; | ||||
|     push @EXPORT, qw(VM_NONE); | ||||
|  | ||||
| use constant VM_CO6                                                 => 'co6'; | ||||
|     push @EXPORT, qw(VM_CO6); | ||||
| use constant VM_CO7                                                 => 'co7'; | ||||
| @@ -115,12 +118,33 @@ use constant VM3                                                    => VM_CO7; | ||||
| use constant VM4                                                    => VM_U18; | ||||
|     push @EXPORT, qw(VM4); | ||||
|  | ||||
| # List of default test VMs (in this order: newest, oldest, next newest, next oldest) | ||||
| use constant VM_LIST                                                => (VM4, VM1, VM3, VM2); | ||||
| # List of default test VMs | ||||
| use constant VM_LIST                                                => (VM2, VM1, VM3, VM4); | ||||
|     push @EXPORT, qw(VM_LIST); | ||||
|  | ||||
| my $oyVm = | ||||
| { | ||||
|     # None | ||||
|     &VM_NONE => | ||||
|     { | ||||
|         &VM_OS_BASE => VM_OS_BASE_RHEL, | ||||
|         &VM_OS => VM_OS_CENTOS, | ||||
|         &VM_ARCH => VM_ARCH_AMD64, | ||||
|         &VMDEF_COVERAGE_C => true, | ||||
|         &VMDEF_PGSQL_BIN => '/usr/pgsql-{[version]}/bin', | ||||
|         &VMDEF_PERL_ARCH_PATH => '/usr/local/lib64/perl5', | ||||
|  | ||||
|         &VM_DB => | ||||
|         [ | ||||
|             PG_VERSION_10, | ||||
|         ], | ||||
|  | ||||
|         &VM_DB_TEST => | ||||
|         [ | ||||
|             PG_VERSION_10, | ||||
|         ], | ||||
|     }, | ||||
|  | ||||
|     # CentOS 6 | ||||
|     &VM_CO6 => | ||||
|     { | ||||
|   | ||||
| @@ -3,18 +3,16 @@ Harness for Loading Test Configurations | ||||
| ***********************************************************************************************************************************/ | ||||
| #include "common/harnessDebug.h" | ||||
| #include "common/harnessLog.h" | ||||
| #include "common/harnessTest.h" | ||||
|  | ||||
| #include "config/load.h" | ||||
| #include "config/parse.h" | ||||
| #include "storage/helper.h" | ||||
| #include "version.h" | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Load a test configuration without any side effects | ||||
|  | ||||
| There's no need to open log files, acquire locks, reset log levels, etc. | ||||
| ***********************************************************************************************************************************/ | ||||
| /**********************************************************************************************************************************/ | ||||
| void | ||||
| harnessCfgLoad(unsigned int argListSize, const char *argList[]) | ||||
| harnessCfgLoadRaw(unsigned int argListSize, const char *argList[]) | ||||
| { | ||||
|     FUNCTION_HARNESS_BEGIN(); | ||||
|         FUNCTION_HARNESS_PARAM(UINT, argListSize); | ||||
| @@ -29,3 +27,34 @@ harnessCfgLoad(unsigned int argListSize, const char *argList[]) | ||||
|  | ||||
|     FUNCTION_HARNESS_RESULT_VOID(); | ||||
| } | ||||
|  | ||||
| /**********************************************************************************************************************************/ | ||||
| void | ||||
| harnessCfgLoad(ConfigCommand commandId, const StringList *argOriginalList) | ||||
| { | ||||
|     FUNCTION_HARNESS_BEGIN(); | ||||
|         FUNCTION_HARNESS_PARAM(ENUM, commandId); | ||||
|         FUNCTION_HARNESS_PARAM(STRING_LIST, argOriginalList); | ||||
|     FUNCTION_HARNESS_END(); | ||||
|  | ||||
|     // Make a copy of the arg list that we can modify | ||||
|     StringList *argList = strLstDup(argOriginalList); | ||||
|  | ||||
|     // Set log path if valid | ||||
|     if (cfgDefOptionValid(cfgCommandDefIdFromId(commandId), cfgDefOptLogPath)) | ||||
|         strLstInsert(argList, 0, strNewFmt("--" CFGOPT_LOG_PATH "=%s", testDataPath())); | ||||
|  | ||||
|     // Set lock path if valid | ||||
|     if (cfgDefOptionValid(cfgCommandDefIdFromId(commandId), cfgDefOptLockPath)) | ||||
|         strLstInsert(argList, 0, strNewFmt("--" CFGOPT_LOCK_PATH "=%s/lock", testDataPath())); | ||||
|  | ||||
|     // Insert the command so it does not interfere with parameters | ||||
|     strLstInsertZ(argList, 0, cfgCommandName(commandId)); | ||||
|  | ||||
|     // Insert the project exe | ||||
|     strLstInsert(argList, 0, STRDEF(testProjectExe())); | ||||
|  | ||||
|     harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|     FUNCTION_HARNESS_RESULT_VOID(); | ||||
| } | ||||
|   | ||||
| @@ -3,6 +3,12 @@ Harness for Loading Test Configurations | ||||
| ***********************************************************************************************************************************/ | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Functions | ||||
| Load a test configuration without any side effects | ||||
|  | ||||
| There's no need to open log files, acquire locks, reset log levels, etc. | ||||
| ***********************************************************************************************************************************/ | ||||
| void harnessCfgLoad(unsigned int argListSize, const char *argList[]); | ||||
| // Low-level version used in a few places to simulate special cases and error conditions.  Most tests should use harnessCfgLoad(). | ||||
| void harnessCfgLoadRaw(unsigned int argListSize, const char *argList[]); | ||||
|  | ||||
| // Automatically adds the exe, command, lock-path, and log-path so executing the binary works locally or in a container. | ||||
| void harnessCfgLoad(ConfigCommand commandId, const StringList *argList); | ||||
|   | ||||
| @@ -70,7 +70,7 @@ harnessLogInit(void) | ||||
|     logInit(logLevelTestDefault, logLevelOff, logLevelInfo, false, 99); | ||||
|     logFileBanner = true; | ||||
|  | ||||
|     snprintf(logFile, sizeof(logFile), "%s/expect.log", testExpectPath()); | ||||
|     snprintf(logFile, sizeof(logFile), "%s/expect.log", testDataPath()); | ||||
|     logHandleFile = harnessLogOpen(logFile, O_WRONLY | O_CREAT | O_TRUNC, 0640); | ||||
|     logAnySet(); | ||||
|  | ||||
|   | ||||
| @@ -32,7 +32,6 @@ static uint64_t timeMSecBegin; | ||||
| static const char *testExeData = NULL; | ||||
| static const char *testPathData = NULL; | ||||
| static const char *testRepoPathData = NULL; | ||||
| static const char *testExpectPathData = NULL; | ||||
|  | ||||
| static char testUserData[64]; | ||||
| static char testGroupData[64]; | ||||
| @@ -45,6 +44,30 @@ Extern functions | ||||
|     void harnessLogFinal(void); | ||||
| #endif | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Is this test running in a container? i.e., can we use sudo and system paths with impunity? | ||||
| ***********************************************************************************************************************************/ | ||||
| static bool testContainerData = false; | ||||
|  | ||||
| bool | ||||
| testContainer(void) | ||||
| { | ||||
|     FUNCTION_HARNESS_VOID(); | ||||
|     FUNCTION_HARNESS_RESULT(BOOL, testContainerData); | ||||
| } | ||||
|  | ||||
| void | ||||
| testContainerSet(bool testContainer) | ||||
| { | ||||
|     FUNCTION_HARNESS_BEGIN(); | ||||
|         FUNCTION_HARNESS_PARAM(BOOL, testContainer); | ||||
|     FUNCTION_HARNESS_END(); | ||||
|  | ||||
|     testContainerData = testContainer; | ||||
|  | ||||
|     FUNCTION_HARNESS_RESULT_VOID(); | ||||
| } | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Get and set the test exe | ||||
| ***********************************************************************************************************************************/ | ||||
| @@ -69,6 +92,30 @@ testExeSet(const char *testExe) | ||||
|     FUNCTION_HARNESS_RESULT_VOID(); | ||||
| } | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Get and set the project exe | ||||
| ***********************************************************************************************************************************/ | ||||
| static const char *testProjectExeData = NULL; | ||||
|  | ||||
| const char * | ||||
| testProjectExe(void) | ||||
| { | ||||
|     FUNCTION_HARNESS_VOID(); | ||||
|     FUNCTION_HARNESS_RESULT(STRINGZ, testProjectExeData); | ||||
| } | ||||
|  | ||||
| void | ||||
| testProjectExeSet(const char *testProjectExe) | ||||
| { | ||||
|     FUNCTION_HARNESS_BEGIN(); | ||||
|         FUNCTION_HARNESS_PARAM(STRINGZ, testProjectExe); | ||||
|     FUNCTION_HARNESS_END(); | ||||
|  | ||||
|     testProjectExeData = testProjectExe; | ||||
|  | ||||
|     FUNCTION_HARNESS_RESULT_VOID(); | ||||
| } | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Get and set the path for the pgbackrest repo | ||||
| ***********************************************************************************************************************************/ | ||||
| @@ -117,26 +164,24 @@ testPathSet(const char *testPath) | ||||
|     FUNCTION_HARNESS_RESULT_VOID(); | ||||
| } | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Get and set the expect path, i.e., the path where expect logs will be stored by the harnessLog module | ||||
| ***********************************************************************************************************************************/ | ||||
| /**********************************************************************************************************************************/ | ||||
| static const char *testDataPathData = NULL; | ||||
|  | ||||
| const char * | ||||
| testExpectPath(void) | ||||
| testDataPath(void) | ||||
| { | ||||
|     FUNCTION_HARNESS_VOID(); | ||||
|     FUNCTION_HARNESS_RESULT(STRINGZ, testExpectPathData); | ||||
|     FUNCTION_HARNESS_RESULT(STRINGZ, testDataPathData); | ||||
| } | ||||
|  | ||||
| void | ||||
| testExpectPathSet(const char *testExpectPath) | ||||
| testDataPathSet(const char *testDataPath) | ||||
| { | ||||
|     FUNCTION_HARNESS_BEGIN(); | ||||
|         FUNCTION_HARNESS_PARAM(STRINGZ, testExpectPath); | ||||
|  | ||||
|         FUNCTION_HARNESS_ASSERT(testExpectPath != NULL); | ||||
|         FUNCTION_HARNESS_PARAM(STRINGZ, testDataPath); | ||||
|     FUNCTION_HARNESS_END(); | ||||
|  | ||||
|     testExpectPathData = testExpectPath; | ||||
|     testDataPathData = testDataPath; | ||||
|  | ||||
|     FUNCTION_HARNESS_RESULT_VOID(); | ||||
| } | ||||
| @@ -273,7 +318,7 @@ testBegin(const char *name) | ||||
|  | ||||
|             // Clear out the test directory so the next test starts clean | ||||
|             char buffer[2048]; | ||||
|             snprintf(buffer, sizeof(buffer), "sudo rm -rf %s/" "*", testPath()); | ||||
|             snprintf(buffer, sizeof(buffer), "%srm -rf %s/" "*", testContainer() ? "sudo " : "", testPath()); | ||||
|  | ||||
|             if (system(buffer) != 0) | ||||
|             { | ||||
| @@ -281,6 +326,16 @@ testBegin(const char *name) | ||||
|                 fflush(stderr); | ||||
|                 exit(255); | ||||
|             } | ||||
|  | ||||
|             // Clear out the data directory so the next test starts clean | ||||
|             snprintf(buffer, sizeof(buffer), "%srm -rf %s/" "*", testContainer() ? "sudo " : "", testDataPath()); | ||||
|  | ||||
|             if (system(buffer) != 0) | ||||
|             { | ||||
|                 fprintf(stderr, "ERROR: unable to clear data path '%s'\n", testDataPath()); | ||||
|                 fflush(stderr); | ||||
|                 exit(255); | ||||
|             } | ||||
|         } | ||||
| #endif | ||||
|         // No longer the first test | ||||
| @@ -385,8 +440,10 @@ hrnReplaceKey(const char *string) | ||||
|  | ||||
|     strcpy(harnessReplaceKeyBuffer, string); | ||||
|     hrnReplaceStr(harnessReplaceKeyBuffer, sizeof(harnessReplaceKeyBuffer), "{[path]}", testPath()); | ||||
|     hrnReplaceStr(harnessReplaceKeyBuffer, sizeof(harnessReplaceKeyBuffer), "{[path-data]}", testDataPath()); | ||||
|     hrnReplaceStr(harnessReplaceKeyBuffer, sizeof(harnessReplaceKeyBuffer), "{[user]}", testUser()); | ||||
|     hrnReplaceStr(harnessReplaceKeyBuffer, sizeof(harnessReplaceKeyBuffer), "{[group]}", testGroup()); | ||||
|     hrnReplaceStr(harnessReplaceKeyBuffer, sizeof(harnessReplaceKeyBuffer), "{[project-exe]}", testProjectExe()); | ||||
|  | ||||
|     FUNCTION_HARNESS_RESULT(STRINGZ, harnessReplaceKeyBuffer); | ||||
| } | ||||
| @@ -456,17 +513,17 @@ hrnDiff(const char *actual, const char *expected) | ||||
|  | ||||
|     // Write actual file | ||||
|     char actualFile[1024]; | ||||
|     snprintf(actualFile, sizeof(actualFile), "%s/diff.actual", testExpectPath()); | ||||
|     snprintf(actualFile, sizeof(actualFile), "%s/diff.actual", testDataPath()); | ||||
|     hrnFileWrite(actualFile, (unsigned char *)actual, strlen(actual)); | ||||
|  | ||||
|     // Write expected file | ||||
|     char expectedFile[1024]; | ||||
|     snprintf(expectedFile, sizeof(expectedFile), "%s/diff.expected", testExpectPath()); | ||||
|     snprintf(expectedFile, sizeof(expectedFile), "%s/diff.expected", testDataPath()); | ||||
|     hrnFileWrite(expectedFile, (unsigned char *)expected, strlen(expected)); | ||||
|  | ||||
|     // Perform diff | ||||
|     char command[2048]; | ||||
|     snprintf(command, sizeof(command), "diff -u %s %s > %s/diff.result", actualFile, expectedFile, testExpectPath()); | ||||
|     snprintf(command, sizeof(command), "diff -u %s %s > %s/diff.result", actualFile, expectedFile, testDataPath()); | ||||
|  | ||||
|     if (system(command) == 2) | ||||
|     { | ||||
| @@ -477,7 +534,7 @@ hrnDiff(const char *actual, const char *expected) | ||||
|  | ||||
|     // Read result | ||||
|     char resultFile[1024]; | ||||
|     snprintf(resultFile, sizeof(resultFile), "%s/diff.result", testExpectPath()); | ||||
|     snprintf(resultFile, sizeof(resultFile), "%s/diff.result", testDataPath()); | ||||
|     hrnFileRead(resultFile, (unsigned char *)harnessDiffBuffer, sizeof(harnessDiffBuffer)); | ||||
|  | ||||
|     // Remove last linefeed from diff output | ||||
|   | ||||
| @@ -29,14 +29,21 @@ void testExeSet(const char *testExe); | ||||
|  | ||||
| const char *testPath(void); | ||||
| void testPathSet(const char *testPath); | ||||
| const char *testExpectPath(void); | ||||
| void testExpectPathSet(const char *testExpectPath); | ||||
| const char *testRepoPath(void); | ||||
| void testRepoPathSet(const char *testRepoPath); | ||||
|  | ||||
| const char *testUser(void); | ||||
| const char *testGroup(void); | ||||
|  | ||||
| // Is this test running in a container? | ||||
| bool testContainer(void); | ||||
|  | ||||
| // Location of the data path were the harness can write data that won't be visible to the test | ||||
| const char *testDataPath(void); | ||||
|  | ||||
| // Location of the project exe | ||||
| const char *testProjectExe(void); | ||||
|  | ||||
| // For scaling performance tests | ||||
| uint64_t testScale(void); | ||||
|  | ||||
|   | ||||
| @@ -14,8 +14,14 @@ Tls Test Harness | ||||
| #include "common/type/buffer.h" | ||||
| #include "common/wait.h" | ||||
|  | ||||
| #include "common/harnessTest.h" | ||||
| #include "common/harnessTls.h" | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Test defaults | ||||
| ***********************************************************************************************************************************/ | ||||
| #define TLS_TEST_HOST                                               "tls.test.pgbackrest.org" | ||||
|  | ||||
| static int testServerSocket = 0; | ||||
| static SSL_CTX *testServerContext = NULL; | ||||
| static int testClientSocket = 0; | ||||
| @@ -28,8 +34,11 @@ void | ||||
| harnessTlsServerInit(int port, const char *serverCert, const char *serverKey) | ||||
| { | ||||
|     // Add test hosts | ||||
|     if (system("echo \"127.0.0.1 " TLS_TEST_HOST "\" | sudo tee -a /etc/hosts > /dev/null") != 0) | ||||
|         THROW(AssertError, "unable to add test host to /etc/hosts"); | ||||
|     if (testContainer()) | ||||
|     { | ||||
|         if (system("echo \"127.0.0.1 " TLS_TEST_HOST "\" | sudo tee -a /etc/hosts > /dev/null") != 0) | ||||
|             THROW(AssertError, "unable to add test host to /etc/hosts"); | ||||
|     } | ||||
|  | ||||
|     // Initialize ssl and create a context | ||||
|     cryptoInit(); | ||||
| @@ -78,6 +87,21 @@ harnessTlsServerInit(int port, const char *serverCert, const char *serverKey) | ||||
|         THROW_SYS_ERROR(AssertError, "unable to listen on socket"); | ||||
| } | ||||
|  | ||||
| /**********************************************************************************************************************************/ | ||||
| void | ||||
| harnessTlsServerInitDefault(void) | ||||
| { | ||||
|     if (testContainer()) | ||||
|         harnessTlsServerInit(TLS_TEST_PORT, TLS_CERT_TEST_CERT, TLS_CERT_TEST_KEY); | ||||
|     else | ||||
|     { | ||||
|         harnessTlsServerInit( | ||||
|             TLS_TEST_PORT, | ||||
|             strPtr(strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".crt", testRepoPath())), | ||||
|             strPtr(strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".key", testRepoPath()))); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Expect an exact string from the client | ||||
|  | ||||
| @@ -150,3 +174,9 @@ harnessTlsServerClose(void) | ||||
|     SSL_free(testClientSSL); | ||||
|     close(testClientSocket); | ||||
| } | ||||
|  | ||||
| /**********************************************************************************************************************************/ | ||||
| const String *harnessTlsTestHost(void) | ||||
| { | ||||
|     return strNew(testContainer() ? TLS_TEST_HOST : "localhost"); | ||||
| } | ||||
|   | ||||
| @@ -6,10 +6,14 @@ Simple TLS server for testing TLS client functionality. | ||||
| #ifndef TEST_COMMON_HARNESS_TLS_H | ||||
| #define TEST_COMMON_HARNESS_TLS_H | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Path and prefix for test certificates | ||||
| ***********************************************************************************************************************************/ | ||||
| #define TEST_CERTIFICATE_PREFIX                                     "test/certificate/pgbackrest-test" | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Tls test defaults | ||||
| ***********************************************************************************************************************************/ | ||||
| #define TLS_TEST_HOST                                               "tls.test.pgbackrest.org" | ||||
| #define TLS_TEST_PORT                                               9443 | ||||
|  | ||||
| #define TLS_CERT_FAKE_PATH                                          "/etc/fake-cert" | ||||
| @@ -21,9 +25,18 @@ Functions | ||||
| ***********************************************************************************************************************************/ | ||||
| void harnessTlsServerInit(int port, const char *serverCert, const char *serverKey); | ||||
|  | ||||
| // Initialize TLS with default parameters | ||||
| void harnessTlsServerInitDefault(void); | ||||
|  | ||||
| void harnessTlsServerAccept(void); | ||||
| void harnessTlsServerExpect(const char *expected); | ||||
| void harnessTlsServerReply(const char *reply); | ||||
| void harnessTlsServerClose(void); | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Getters | ||||
| ***********************************************************************************************************************************/ | ||||
| // Hostname to use for testing -- this will vary based on whether the test is running in a container | ||||
| const String *harnessTlsTestHost(void); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -25,13 +25,11 @@ testRun(void) | ||||
|     if (testBegin("archiveAsyncStatus()")) | ||||
|     { | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAdd(argList, strNewFmt("--spool-path=%s", testPath())); | ||||
|         strLstAddZ(argList, "--archive-async"); | ||||
|         strLstAddZ(argList, "--archive-timeout=1"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "archive-push"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchivePush, argList); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         String *segment = strNew("000000010000000100000001"); | ||||
| @@ -112,11 +110,10 @@ testRun(void) | ||||
|     if (testBegin("archiveAsyncStatusErrorWrite() and archiveAsyncStatusOkWrite()")) | ||||
|     { | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAdd(argList, strNewFmt("--spool-path=%s", testPath())); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "archive-get-async"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGetAsync, argList); | ||||
|  | ||||
|         String *walSegment = strNew("000000010000000100000001"); | ||||
|  | ||||
| @@ -191,11 +188,10 @@ testRun(void) | ||||
|     { | ||||
|         // Load configuration to set repo-path and stanza | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAdd(argList, strNewFmt("--repo-path=%s", testPath())); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGet, argList); | ||||
|  | ||||
|         TEST_RESULT_PTR(walSegmentFind(storageRepo(), strNew("9.6-2"), strNew("123456781234567812345678"), 0), NULL, "no path"); | ||||
|  | ||||
|   | ||||
| @@ -38,12 +38,10 @@ testRun(void) | ||||
|     { | ||||
|         // Load Parameters | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s/db", testPath())); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGet, argList); | ||||
|  | ||||
|         // Create pg_control file | ||||
|         storagePutNP( | ||||
| @@ -127,12 +125,10 @@ testRun(void) | ||||
|     { | ||||
|         // Load Parameters | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s/db", testPath())); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGet, argList); | ||||
|  | ||||
|         // Create pg_control file | ||||
|         storagePutNP( | ||||
| @@ -222,15 +218,13 @@ testRun(void) | ||||
|         // Check protocol function directly | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s/db", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--spool-path=%s/spool", testPath())); | ||||
|         strLstAddZ(argList, "--repo1-cipher-type=aes-256-cbc"); | ||||
|         strLstAddZ(argList, "archive-get-async"); | ||||
|         setenv("PGBACKREST_REPO1_CIPHER_PASS", "12345678", true); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGetAsync, argList); | ||||
|         unsetenv("PGBACKREST_REPO1_CIPHER_PASS"); | ||||
|  | ||||
|         storagePathCreateNP(storageTest, strNew("spool/archive/test1/in")); | ||||
| @@ -255,12 +249,10 @@ testRun(void) | ||||
|     if (testBegin("queueNeed()")) | ||||
|     { | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "--archive-async"); | ||||
|         strLstAdd(argList, strNewFmt("--spool-path=%s/spool", testPath())); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGet, argList); | ||||
|  | ||||
|         size_t queueSize = 16 * 1024 * 1024; | ||||
|         size_t walSegmentSize = 16 * 1024 * 1024; | ||||
| @@ -330,13 +322,11 @@ testRun(void) | ||||
|         harnessLogLevelSet(logLevelDetail); | ||||
|  | ||||
|         StringList *argCleanList = strLstNew(); | ||||
|         strLstAddZ(argCleanList, "pgbackrest"); | ||||
|         strLstAdd(argCleanList, strNewFmt("--pg1-path=%s/pg", testPath())); | ||||
|         strLstAdd(argCleanList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAdd(argCleanList, strNewFmt("--spool-path=%s/spool", testPath())); | ||||
|         strLstAddZ(argCleanList, "--stanza=test2"); | ||||
|         strLstAddZ(argCleanList, "archive-get-async"); | ||||
|         harnessCfgLoad(strLstSize(argCleanList), strLstPtr(argCleanList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGetAsync, argCleanList); | ||||
|  | ||||
|         TEST_ERROR(cmdArchiveGetAsync(), ParamInvalidError, "at least one wal segment is required"); | ||||
|  | ||||
| @@ -359,7 +349,7 @@ testRun(void) | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         StringList *argList = strLstDup(argCleanList); | ||||
|         strLstAddZ(argList, "000000010000000100000001"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGetAsync, argList); | ||||
|  | ||||
|         storagePathCreateNP(storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN)); | ||||
|  | ||||
| @@ -388,7 +378,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "000000010000000100000001"); | ||||
|         strLstAddZ(argList, "000000010000000100000002"); | ||||
|         strLstAddZ(argList, "000000010000000100000003"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGetAsync, argList); | ||||
|  | ||||
|         storagePathCreateNP(storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN)); | ||||
|  | ||||
| @@ -455,7 +445,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "000000010000000100000001"); | ||||
|         strLstAddZ(argList, "000000010000000100000002"); | ||||
|         strLstAddZ(argList, "000000010000000100000003"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             cmdArchiveGetAsync(), ExecuteError, | ||||
| @@ -489,12 +479,13 @@ testRun(void) | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest-bogus");                    // Break this until async tests are setup correctly | ||||
|         strLstAddZ(argList, "--archive-timeout=1"); | ||||
|         strLstAdd(argList, strNewFmt("--lock-path=%s/lock", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--log-path=%s", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--log-level-file=debug")); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         HARNESS_FORK_BEGIN() | ||||
|         { | ||||
| @@ -510,7 +501,7 @@ testRun(void) | ||||
|         StringList *argListTemp = strLstDup(argList); | ||||
|         String *walSegment = strNew("000000010000000100000001"); | ||||
|         strLstAdd(argListTemp, walSegment); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoadRaw(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|  | ||||
|         HARNESS_FORK_BEGIN() | ||||
|         { | ||||
| @@ -532,7 +523,7 @@ testRun(void) | ||||
|         String *walFile = strNewFmt("%s/db/pg_wal/RECOVERYXLOG", testPath()); | ||||
|         strLstAdd(argListTemp, walFile); | ||||
|         strLstAdd(argListTemp, strNewFmt("--pg1-path=%s/db", testPath())); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoadRaw(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|  | ||||
|         // Test this in a fork so we can use different Perl options in later tests | ||||
|         HARNESS_FORK_BEGIN() | ||||
| @@ -563,7 +554,7 @@ testRun(void) | ||||
|         strLstAddZ(argListTemp, "00000001.history"); | ||||
|         strLstAdd(argListTemp, walFile); | ||||
|         strLstAddZ(argListTemp, "--archive-async"); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoadRaw(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|  | ||||
|         // Test this in a fork so we can use different Perl options in later tests | ||||
|         HARNESS_FORK_BEGIN() | ||||
| @@ -595,7 +586,7 @@ testRun(void) | ||||
|         strLstAdd(argList, walSegment); | ||||
|         strLstAddZ(argList, "pg_wal/RECOVERYXLOG"); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s/db", testPath())); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         HARNESS_FORK_BEGIN() | ||||
|         { | ||||
| @@ -657,7 +648,7 @@ testRun(void) | ||||
|         // Write more WAL segments (in this case queue should be full) | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         strLstAddZ(argList, "--archive-get-queue-max=48"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         String *walSegment2 = strNew("000000010000000100000002"); | ||||
|  | ||||
| @@ -702,7 +693,7 @@ testRun(void) | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         strLstAddZ(argList, BOGUS_STR); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_ERROR(cmdArchiveGet(), ParamInvalidError, "extra parameters found"); | ||||
|     } | ||||
|   | ||||
| @@ -39,12 +39,10 @@ testRun(void) | ||||
|     if (testBegin("archivePushReadyList(), archivePushProcessList(), and archivePushDrop()")) | ||||
|     { | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s/db", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--spool-path=%s/spool", testPath())); | ||||
|         strLstAddZ(argList, "archive-push-async"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchivePushAsync, argList); | ||||
|  | ||||
|         storagePathCreateNP(storagePgWrite(), strNew("pg_wal/archive_status")); | ||||
|         storagePathCreateNP(storageTest, strNew("spool/archive/db/out")); | ||||
| @@ -81,7 +79,7 @@ testRun(void) | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         StringList *argListDrop = strLstDup(argList); | ||||
|         strLstAdd(argListDrop, strNewFmt("--archive-push-queue-max=%zu", (size_t)1024 * 1024 * 1024)); | ||||
|         harnessCfgLoad(strLstSize(argListDrop), strLstPtr(argListDrop)); | ||||
|         harnessCfgLoad(cfgCmdArchivePushAsync, argListDrop); | ||||
|  | ||||
|         // Write the files that we claim are in pg_wal | ||||
|         Buffer *walBuffer = bufNew((size_t)16 * 1024 * 1024); | ||||
| @@ -102,7 +100,7 @@ testRun(void) | ||||
|         // Now set queue max low enough that WAL will be dropped | ||||
|         argListDrop = strLstDup(argList); | ||||
|         strLstAdd(argListDrop, strNewFmt("--archive-push-queue-max=%zu", (size_t)16 * 1024 * 1024 * 2)); | ||||
|         harnessCfgLoad(strLstSize(argListDrop), strLstPtr(argListDrop)); | ||||
|         harnessCfgLoad(cfgCmdArchivePushAsync, argListDrop); | ||||
|  | ||||
|         TEST_RESULT_BOOL( | ||||
|             archivePushDrop(strNew("pg_wal"), archivePushProcessList(strNewFmt("%s/db/pg_wal", testPath()))), true, | ||||
| @@ -113,12 +111,10 @@ testRun(void) | ||||
|     if (testBegin("archivePushCheck()")) | ||||
|     { | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test"); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s/pg", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAddZ(argList, "archive-push"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchivePush, argList); | ||||
|  | ||||
|         // Check mismatched pg_control and archive.info | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -180,17 +176,15 @@ testRun(void) | ||||
|     if (testBegin("Synchronous cmdArchivePush(), archivePushFile() and archivePushProtocol()")) | ||||
|     { | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test"); | ||||
|         strLstAddZ(argList, "archive-push"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchivePush, argList); | ||||
|  | ||||
|         TEST_ERROR(cmdArchivePush(), ParamRequiredError, "WAL segment to push required"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         StringList *argListTemp = strLstDup(argList); | ||||
|         strLstAddZ(argListTemp, "pg_wal/000000010000000100000001"); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoad(cfgCmdArchivePush, argListTemp); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             cmdArchivePush(), OptionRequiredError, | ||||
| @@ -205,7 +199,7 @@ testRun(void) | ||||
|  | ||||
|         argListTemp = strLstDup(argList); | ||||
|         strLstAddZ(argListTemp, "pg_wal/000000010000000100000001"); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoad(cfgCmdArchivePush, argListTemp); | ||||
|  | ||||
|         storagePutNP( | ||||
|             storageNewWriteNP(storageTest, strNew("pg/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL)), | ||||
| @@ -287,7 +281,7 @@ testRun(void) | ||||
|         // Save it to a new file instead | ||||
|         argListTemp = strLstDup(argList); | ||||
|         strLstAddZ(argListTemp, "pg_wal/000000010000000100000002"); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoad(cfgCmdArchivePush, argListTemp); | ||||
|  | ||||
|         storagePutNP(storageNewWriteNP(storagePgWrite(), strNew("pg_wal/000000010000000100000002")), walBuffer2); | ||||
|  | ||||
| @@ -306,7 +300,7 @@ testRun(void) | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argListTemp = strLstDup(argList); | ||||
|         strLstAddZ(argListTemp, "pg_wal/00000001.history"); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoad(cfgCmdArchivePush, argListTemp); | ||||
|  | ||||
|         storagePutNP(storageNewWriteNP(storagePgWrite(), strNew("pg_wal/00000001.history")), BUFSTRDEF("FAKEHISTORY")); | ||||
|  | ||||
| @@ -324,7 +318,7 @@ testRun(void) | ||||
|         argListTemp = strLstDup(argList); | ||||
|         strLstAddZ(argListTemp, "--archive-push-queue-max=16m"); | ||||
|         strLstAddZ(argListTemp, "pg_wal/000000010000000100000002"); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoad(cfgCmdArchivePush, argListTemp); | ||||
|  | ||||
|         TEST_RESULT_VOID(cmdArchivePush(), "drop WAL file"); | ||||
|         harnessLogResult("P00   WARN: dropped WAL file '000000010000000100000002' because archive queue exceeded 16MB"); | ||||
| @@ -332,7 +326,7 @@ testRun(void) | ||||
|         argListTemp = strLstDup(argList); | ||||
|         strLstAddZ(argListTemp, "--archive-push-queue-max=1GB"); | ||||
|         strLstAddZ(argListTemp, "pg_wal/000000010000000100000002"); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoad(cfgCmdArchivePush, argListTemp); | ||||
|  | ||||
|         TEST_RESULT_VOID(cmdArchivePush(), "push WAL file again"); | ||||
|         harnessLogResult( | ||||
| @@ -395,7 +389,7 @@ testRun(void) | ||||
|         strLstAddZ(argListTemp, "--repo1-cipher-type=aes-256-cbc"); | ||||
|         strLstAddZ(argListTemp, "--no-compress"); | ||||
|         setenv("PGBACKREST_REPO1_CIPHER_PASS", "badpassphrase", true); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoad(cfgCmdArchivePush, argListTemp); | ||||
|         unsetenv("PGBACKREST_REPO1_CIPHER_PASS"); | ||||
|  | ||||
|         TEST_RESULT_VOID(cmdArchivePush(), "push the WAL segment"); | ||||
| @@ -422,12 +416,13 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--stanza=test"); | ||||
|         strLstAddZ(argList, "--archive-async"); | ||||
|         strLstAddZ(argList, "--archive-timeout=1"); | ||||
|         strLstAdd(argList, strNewFmt("--lock-path=%s/lock", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--spool-path=%s/spool", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s/pg", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAddZ(argList, "archive-push"); | ||||
|         strLstAddZ(argList, "pg_wal/bogus"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             cmdArchivePush(), ArchiveTimeoutError, | ||||
| @@ -436,19 +431,14 @@ testRun(void) | ||||
|         // Create pg_control and archive.info | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test"); | ||||
|         strLstAddZ(argList, "--archive-async"); | ||||
|         strLstAddZ(argList, "--no-compress"); | ||||
|         strLstAdd(argList, strNewFmt("--spool-path=%s/spool", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s/pg", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--log-path=%s/log", testPath())); | ||||
|         strLstAddZ(argList, "--log-level-file=trace"); | ||||
|         strLstAddZ(argList, "--log-subprocess"); | ||||
|         strLstAddZ(argList, "archive-push"); | ||||
|  | ||||
|         storagePathCreateNP(storageTest, strNew("log")); | ||||
|         storagePutNP( | ||||
|             storageNewWriteNP(storageTest, strNew("pg/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL)), | ||||
|             pgControlTestToBuffer((PgControl){.version = PG_VERSION_94, .systemId = 0xAAAABBBBCCCCDDDD})); | ||||
| @@ -466,7 +456,7 @@ testRun(void) | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         StringList *argListTemp = strLstDup(argList); | ||||
|         strLstAdd(argListTemp, strNewFmt("%s/pg/pg_xlog/000000010000000100000001", testPath())); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoad(cfgCmdArchivePush, argListTemp); | ||||
|  | ||||
|         storagePathCreateNP(storagePgWrite(), strNew("pg_xlog/archive_status")); | ||||
|  | ||||
| @@ -483,7 +473,7 @@ testRun(void) | ||||
|         argListTemp = strLstDup(argList); | ||||
|         strLstAdd(argListTemp, strNewFmt("%s/pg/pg_xlog/000000010000000100000001", testPath())); | ||||
|         strLstAddZ(argListTemp, "--archive-timeout=1"); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoad(cfgCmdArchivePush, argListTemp); | ||||
|  | ||||
|         HARNESS_FORK_BEGIN() | ||||
|         { | ||||
| @@ -531,7 +521,7 @@ testRun(void) | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argListTemp = strLstDup(argList); | ||||
|         strLstAdd(argListTemp, strNewFmt("%s/pg/pg_xlog/000000010000000100000001", testPath())); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoad(cfgCmdArchivePush, argListTemp); | ||||
|  | ||||
|         storagePutNP(storageNewWriteNP(storagePgWrite(), strNew("pg_xlog/archive_status/000000010000000100000001.ready")), NULL); | ||||
|  | ||||
| @@ -556,17 +546,13 @@ testRun(void) | ||||
|         // Direct tests of the async function | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test"); | ||||
|         strLstAddZ(argList, "--no-compress"); | ||||
|         strLstAdd(argList, strNewFmt("--spool-path=%s/spool", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s/pg", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--log-path=%s/log", testPath())); | ||||
|         strLstAddZ(argList, "--log-level-file=trace"); | ||||
|         strLstAddZ(argList, "--log-subprocess"); | ||||
|         strLstAddZ(argList, "archive-push-async"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchivePushAsync, argList); | ||||
|  | ||||
|         TEST_ERROR(cmdArchivePushAsync(), ParamRequiredError, "WAL path to push required"); | ||||
|  | ||||
| @@ -583,7 +569,7 @@ testRun(void) | ||||
|         storagePathCreateNP(storagePgWrite(), strNew("pg_xlog/archive_status")); | ||||
|  | ||||
|         strLstAdd(argList, strNewFmt("%s/pg/pg_xlog", testPath())); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchivePushAsync, argList); | ||||
|  | ||||
|         TEST_ERROR(cmdArchivePushAsync(), AssertError, "no WAL files to process"); | ||||
|  | ||||
| @@ -635,7 +621,7 @@ testRun(void) | ||||
|  | ||||
|         argListTemp = strLstDup(argList); | ||||
|         strLstAddZ(argListTemp, "--archive-push-queue-max=1gb"); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoad(cfgCmdArchivePushAsync, argListTemp); | ||||
|  | ||||
|         TEST_RESULT_VOID(cmdArchivePushAsync(), "push WAL segments"); | ||||
|         harnessLogResult( | ||||
| @@ -662,7 +648,7 @@ testRun(void) | ||||
|  | ||||
|         argListTemp = strLstDup(argList); | ||||
|         strLstAddZ(argListTemp, "--archive-push-queue-max=16m"); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoad(cfgCmdArchivePushAsync, argListTemp); | ||||
|  | ||||
|         TEST_RESULT_VOID(cmdArchivePushAsync(), "push WAL segments"); | ||||
|         harnessLogResult( | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| /*********************************************************************************************************************************** | ||||
| Test Common Functions and Definitions for Backup and Expire Commands | ||||
| ***********************************************************************************************************************************/ | ||||
| #include "common/harnessConfig.h" | ||||
| #include "common/io/bufferWrite.h" | ||||
| #include "common/regExp.h" | ||||
| #include "common/type/json.h" | ||||
|   | ||||
| @@ -44,13 +44,11 @@ testRun(void) | ||||
|     { | ||||
|         // Load Parameters | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s/pg", testPath())); | ||||
|         strLstAddZ(argList, "--repo1-retention-full=1"); | ||||
|         strLstAddZ(argList, "backup"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdBackup, argList); | ||||
|  | ||||
|         // Create the pg path | ||||
|         storagePathCreateP(storagePgWrite(), NULL, .mode = 0700); | ||||
| @@ -359,15 +357,13 @@ testRun(void) | ||||
|     { | ||||
|         // Load Parameters | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s/pg", testPath())); | ||||
|         strLstAddZ(argList, "--repo1-retention-full=1"); | ||||
|         strLstAddZ(argList, "--repo1-cipher-type=aes-256-cbc"); | ||||
|         strLstAddZ(argList, "backup"); | ||||
|         setenv("PGBACKREST_REPO1_CIPHER_PASS", "12345678", true); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdBackup, argList); | ||||
|         unsetenv("PGBACKREST_REPO1_CIPHER_PASS"); | ||||
|  | ||||
|         // Create the pg path | ||||
|   | ||||
| @@ -24,13 +24,11 @@ testRun(void) | ||||
|     if (testBegin("cmdCheck()")) | ||||
|     { | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, pg1PathOpt); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAddZ(argList, "--archive-timeout=.5"); | ||||
|         strLstAddZ(argList, "check"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdCheck, argList); | ||||
|  | ||||
|         TEST_ERROR_FMT( | ||||
|             cmdCheck(), FileMissingError, | ||||
| @@ -107,13 +105,11 @@ testRun(void) | ||||
|         // Single standby | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, pg1PathOpt); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAddZ(argList, "--archive-timeout=.5"); | ||||
|         strLstAddZ(argList, "check"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdCheck, argList); | ||||
|  | ||||
|         // Set script | ||||
|         harnessPqScriptSet((HarnessPq []) | ||||
| @@ -131,12 +127,10 @@ testRun(void) | ||||
|     if (testBegin("checkDbConfig()")) | ||||
|     { | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, pg1PathOpt); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAddZ(argList, "check"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdCheck, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(checkDbConfig(PG_VERSION_92, 1, PG_VERSION_92, pg1Path), "valid db config"); | ||||
|  | ||||
|   | ||||
| @@ -16,81 +16,73 @@ testRun(void) | ||||
|     FUNCTION_HARNESS_VOID(); | ||||
|  | ||||
|     // Create default storage object for testing | ||||
|     Storage *storageTest = storagePosixNew( | ||||
|         strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL); | ||||
|     Storage *storageData = storagePosixNew( | ||||
|         strNew(testDataPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL); | ||||
|  | ||||
|     // ***************************************************************************************************************************** | ||||
|     if (testBegin("lockStopFileName()")) | ||||
|     { | ||||
|         // Load configuration so lock path is set | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "--lock-path=/path/to/lock"); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGet, argList); | ||||
|  | ||||
|         TEST_RESULT_STR(strPtr(lockStopFileName(NULL)), "/path/to/lock/all" STOP_FILE_EXT, "stop file for all stanzas"); | ||||
|         TEST_RESULT_STR(strPtr(lockStopFileName(strNew("db"))), "/path/to/lock/db" STOP_FILE_EXT, "stop file for on stanza"); | ||||
|         TEST_RESULT_STR( | ||||
|             strPtr(lockStopFileName(NULL)), hrnReplaceKey("{[path-data]}/lock/all" STOP_FILE_EXT), "stop file for all stanzas"); | ||||
|         TEST_RESULT_STR( | ||||
|             strPtr(lockStopFileName(strNew("db"))), hrnReplaceKey("{[path-data]}/lock/db" STOP_FILE_EXT), | ||||
|             "stop file for on stanza"); | ||||
|     } | ||||
|  | ||||
|     // ***************************************************************************************************************************** | ||||
|     if (testBegin("lockStopTest(), cmdStart()")) | ||||
|     { | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAdd(argList, strNewFmt("--lock-path=%s", testPath())); | ||||
|         strLstAddZ(argList, "start"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStart, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(lockStopTest(), "no stop files without stanza"); | ||||
|         TEST_RESULT_VOID(cmdStart(), "    cmdStart - no stanza, no stop files"); | ||||
|         harnessLogResult("P00   WARN: stop file does not exist"); | ||||
|  | ||||
|         TEST_RESULT_VOID(storagePutNP(storageNewWriteNP(storageTest, strNew("all" STOP_FILE_EXT)), NULL), "create stop file"); | ||||
|         TEST_RESULT_VOID(storagePutNP(storageNewWriteNP(storageData, strNew("lock/all" STOP_FILE_EXT)), NULL), "create stop file"); | ||||
|         TEST_RESULT_VOID(cmdStart(), "    cmdStart - no stanza, stop file exists"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageTest, strNew("all" STOP_FILE_EXT)), false, "    stop file removed"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageData, strNew("lock/all" STOP_FILE_EXT)), false, "    stop file removed"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAdd(argList, strNewFmt("--lock-path=%s", testPath())); | ||||
|         strLstAddZ(argList, "start"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStart, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(lockStopTest(), "no stop files with stanza"); | ||||
|         TEST_RESULT_VOID(cmdStart(), "    cmdStart - stanza, no stop files"); | ||||
|         harnessLogResult("P00   WARN: stop file does not exist for stanza db"); | ||||
|  | ||||
|         storagePutNP(storageNewWriteNP(storageTest, strNew("all" STOP_FILE_EXT)), NULL); | ||||
|         storagePutNP(storageNewWriteNP(storageData, strNew("lock/all" STOP_FILE_EXT)), NULL); | ||||
|         TEST_ERROR(lockStopTest(), StopError, "stop file exists for all stanzas"); | ||||
|  | ||||
|         storagePutNP(storageNewWriteNP(storageTest, strNew("db" STOP_FILE_EXT)), NULL); | ||||
|         storagePutNP(storageNewWriteNP(storageData, strNew("lock/db" STOP_FILE_EXT)), NULL); | ||||
|         TEST_ERROR(lockStopTest(), StopError, "stop file exists for stanza db"); | ||||
|  | ||||
|         TEST_RESULT_VOID(cmdStart(), "cmdStart - stanza, stop file exists"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageTest, strNew("db" STOP_FILE_EXT)), false, "    stanza stop file removed"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageTest, strNew("all" STOP_FILE_EXT)), true, "    all stop file not removed"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageData, strNew("lock/db" STOP_FILE_EXT)), false, "    stanza stop file removed"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageData, strNew("lock/all" STOP_FILE_EXT)), true, "    all stop file not removed"); | ||||
|     } | ||||
|  | ||||
|     // ***************************************************************************************************************************** | ||||
|     if (testBegin("cmdStop()")) | ||||
|     { | ||||
|         String *lockPath = strNewFmt("%s/lockpath", testPath()); | ||||
|         String *lockPath = strNewFmt("%s/lock", testDataPath()); | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAdd(argList, strNewFmt("--lock-path=%s", strPtr(lockPath))); | ||||
|         strLstAddZ(argList, "stop"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStop, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(cmdStop(), "no stanza, create stop file"); | ||||
|         StorageInfo info = {0}; | ||||
|         TEST_ASSIGN(info, storageInfoNP(storageTest, lockPath), "    get path info"); | ||||
|         TEST_ASSIGN(info, storageInfoNP(storageData, lockPath), "    get path info"); | ||||
|         TEST_RESULT_INT(info.mode, 0770, "    check path mode"); | ||||
|         TEST_RESULT_BOOL( | ||||
|             storageExistsNP(storageTest, strNewFmt("%s/all" STOP_FILE_EXT, strPtr(lockPath))), true, "    all stop file created"); | ||||
|         TEST_ASSIGN(info, storageInfoNP(storageTest, strNewFmt("%s/all" STOP_FILE_EXT, strPtr(lockPath))), "    get file info"); | ||||
|             storageExistsNP(storageData, strNewFmt("%s/all" STOP_FILE_EXT, strPtr(lockPath))), true, "    all stop file created"); | ||||
|         TEST_ASSIGN( | ||||
|             info, storageInfoNP(storageData, strNewFmt("%s/all" STOP_FILE_EXT, strPtr(lockPath))), "    get file info"); | ||||
|         TEST_RESULT_INT(info.mode, 0640, "    check file mode"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -98,62 +90,63 @@ testRun(void) | ||||
|         harnessLogResult("P00   WARN: stop file already exists for all stanzas"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_RESULT_VOID(storageRemoveNP(storageTest, strNew("lockpath/all" STOP_FILE_EXT)), "remove stop file"); | ||||
|         TEST_RESULT_INT(system(strPtr(strNewFmt("sudo chmod 444 %s", strPtr(lockPath)))), 0, "change perms"); | ||||
|         TEST_RESULT_VOID(storageRemoveNP(storageData, strNew("lockpath/all" STOP_FILE_EXT)), "remove stop file"); | ||||
|         TEST_RESULT_INT(system(strPtr(strNewFmt("chmod 444 %s", strPtr(lockPath)))), 0, "change perms"); | ||||
|         TEST_ERROR_FMT( | ||||
|             cmdStop(), FileOpenError, "unable to stat '%s/all.stop': [13] Permission denied", strPtr(lockPath)); | ||||
|         TEST_RESULT_INT(system(strPtr(strNewFmt("chmod 700 %s", strPtr(lockPath)))), 0, "change perms"); | ||||
|         TEST_RESULT_VOID( | ||||
|             storagePathRemoveP(storageTest, lockPath, .recurse = true, .errorOnMissing = true), "    remove the lock path"); | ||||
|             storagePathRemoveP(storageData, lockPath, .recurse = true, .errorOnMissing = true), "    remove the lock path"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         String *stanzaStopFile = strNewFmt("%s/db" STOP_FILE_EXT, strPtr(lockPath)); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStop, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(cmdStop(), "stanza, create stop file"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageTest, stanzaStopFile), true, "    stanza stop file created"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageData, stanzaStopFile), true, "    stanza stop file created"); | ||||
|  | ||||
|         StringList *lockPathList = NULL; | ||||
|         TEST_ASSIGN(lockPathList, storageListP(storageTest, strNew("lockpath"), .errorOnMissing = true), "    get file list"); | ||||
|         TEST_ASSIGN(lockPathList, storageListP(storageData, strNew("lock"), .errorOnMissing = true), "    get file list"); | ||||
|         TEST_RESULT_INT(strLstSize(lockPathList), 1, "    only file in lock path"); | ||||
|         TEST_RESULT_STR(strPtr(strLstGet(lockPathList, 0)), "db" STOP_FILE_EXT, "    stanza stop exists"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_RESULT_VOID(cmdStop(), "stanza, stop file already exists"); | ||||
|         harnessLogResult("P00   WARN: stop file already exists for stanza db"); | ||||
|         TEST_RESULT_VOID(storageRemoveNP(storageTest, stanzaStopFile), "    remove stop file"); | ||||
|         TEST_RESULT_VOID(storageRemoveNP(storageData, stanzaStopFile), "    remove stop file"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         strLstAddZ(argList, "--force"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStop, argList); | ||||
|         TEST_RESULT_VOID(cmdStop(), "stanza, create stop file, force"); | ||||
|         TEST_RESULT_VOID(storageRemoveNP(storageTest, stanzaStopFile), "    remove stop file"); | ||||
|         TEST_RESULT_VOID(storageRemoveNP(storageData, stanzaStopFile), "    remove stop file"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_RESULT_VOID( | ||||
|             storagePutNP( | ||||
|                 storageNewWriteP(storageTest, strNewFmt("%s/bad" LOCK_FILE_EXT, strPtr(lockPath)), .modeFile = 0222), NULL), | ||||
|                 storageNewWriteP(storageData, strNewFmt("%s/bad" LOCK_FILE_EXT, strPtr(lockPath)), .modeFile = 0222), NULL), | ||||
|             "create a lock file that cannot be opened"); | ||||
|         TEST_RESULT_VOID(cmdStop(), "    stanza, create stop file but unable to open lock file"); | ||||
|         harnessLogResult(strPtr(strNewFmt("P00   WARN: unable to open lock file %s/bad" LOCK_FILE_EXT, strPtr(lockPath)))); | ||||
|         TEST_RESULT_VOID( | ||||
|             storagePathRemoveP(storageTest, lockPath, .recurse = true, .errorOnMissing = true), "    remove the lock path"); | ||||
|             storagePathRemoveP(storageData, lockPath, .recurse = true, .errorOnMissing = true), "    remove the lock path"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_RESULT_VOID( | ||||
|             storagePutNP(storageNewWriteNP(storageTest, strNewFmt("%s/empty" LOCK_FILE_EXT, strPtr(lockPath))), NULL), | ||||
|             storagePutNP(storageNewWriteNP(storageData, strNewFmt("%s/empty" LOCK_FILE_EXT, strPtr(lockPath))), NULL), | ||||
|             "create empty lock file"); | ||||
|         TEST_RESULT_VOID(cmdStop(), "    stanza, create stop file, force - empty lock file"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageTest, stanzaStopFile), true, "    stanza stop file created"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageData, stanzaStopFile), true, "    stanza stop file created"); | ||||
|         TEST_RESULT_BOOL( | ||||
|             storageExistsNP(storageTest, strNewFmt("%s/empty" LOCK_FILE_EXT, strPtr(lockPath))), false, | ||||
|             storageExistsNP(storageData, strNewFmt("%s/empty" LOCK_FILE_EXT, strPtr(lockPath))), false, | ||||
|             "    no other process lock, lock file was removed"); | ||||
|  | ||||
|         // empty lock file with another process lock, processId == NULL | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_RESULT_VOID(storageRemoveNP(storageTest, stanzaStopFile), "remove stop file"); | ||||
|         TEST_RESULT_VOID(storageRemoveNP(storageData, stanzaStopFile), "remove stop file"); | ||||
|         TEST_RESULT_VOID( | ||||
|             storagePutNP(storageNewWriteNP(storageTest, strNewFmt("%s/empty" LOCK_FILE_EXT, strPtr(lockPath))), NULL), | ||||
|             storagePutNP(storageNewWriteNP(storageData, strNewFmt("%s/empty" LOCK_FILE_EXT, strPtr(lockPath))), NULL), | ||||
|             "    create empty lock file"); | ||||
|  | ||||
|         HARNESS_FORK_BEGIN() | ||||
| @@ -195,7 +188,7 @@ testRun(void) | ||||
|                     cmdStop(), | ||||
|                     "    stanza, create stop file, force - empty lock file with another process lock, processId == NULL"); | ||||
|                 TEST_RESULT_BOOL( | ||||
|                     storageExistsNP(storageTest, strNewFmt("%s/empty" LOCK_FILE_EXT, strPtr(lockPath))), false, | ||||
|                     storageExistsNP(storageData, strNewFmt("%s/empty" LOCK_FILE_EXT, strPtr(lockPath))), false, | ||||
|                     "    lock file was removed"); | ||||
|  | ||||
|                 // Notify the child to release the lock | ||||
| @@ -208,9 +201,9 @@ testRun(void) | ||||
|  | ||||
|         // not empty lock file with another process lock, processId size trimmed to 0 | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_RESULT_VOID(storageRemoveNP(storageTest, stanzaStopFile), "remove stop file"); | ||||
|         TEST_RESULT_VOID(storageRemoveNP(storageData, stanzaStopFile), "remove stop file"); | ||||
|         TEST_RESULT_VOID( | ||||
|             storagePutNP(storageNewWriteNP(storageTest, strNewFmt("%s/empty" LOCK_FILE_EXT, strPtr(lockPath))), BUFSTRDEF(" ")), | ||||
|             storagePutNP(storageNewWriteNP(storageData, strNewFmt("%s/empty" LOCK_FILE_EXT, strPtr(lockPath))), BUFSTRDEF(" ")), | ||||
|             "    create non-empty lock file"); | ||||
|  | ||||
|         HARNESS_FORK_BEGIN() | ||||
| @@ -251,7 +244,7 @@ testRun(void) | ||||
|                 TEST_RESULT_VOID( | ||||
|                     cmdStop(), "    stanza, create stop file, force - empty lock file with another process lock, processId size 0"); | ||||
|                 TEST_RESULT_BOOL( | ||||
|                     storageExistsNP(storageTest, strNewFmt("%s/empty" LOCK_FILE_EXT, strPtr(lockPath))), false, | ||||
|                     storageExistsNP(storageData, strNewFmt("%s/empty" LOCK_FILE_EXT, strPtr(lockPath))), false, | ||||
|                     "    lock file was removed"); | ||||
|  | ||||
|                 // Notify the child to release the lock | ||||
| @@ -264,7 +257,7 @@ testRun(void) | ||||
|  | ||||
|         // lock file with another process lock, processId is valid | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_RESULT_VOID(storageRemoveNP(storageTest, stanzaStopFile), "remove stop file"); | ||||
|         TEST_RESULT_VOID(storageRemoveNP(storageData, stanzaStopFile), "remove stop file"); | ||||
|         HARNESS_FORK_BEGIN() | ||||
|         { | ||||
|             HARNESS_FORK_CHILD_BEGIN(0, true) | ||||
| @@ -308,10 +301,10 @@ testRun(void) | ||||
|  | ||||
|         // lock file with another process lock, processId is invalid | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_RESULT_VOID(storageRemoveNP(storageTest, stanzaStopFile), "remove stop file"); | ||||
|         TEST_RESULT_VOID(storageRemoveNP(storageData, stanzaStopFile), "remove stop file"); | ||||
|         TEST_RESULT_VOID( | ||||
|             storagePutNP( | ||||
|                 storageNewWriteNP(storageTest, strNewFmt("%s/badpid" LOCK_FILE_EXT, strPtr(lockPath))), BUFSTRDEF("-32768")), | ||||
|                 storageNewWriteNP(storageData, strNewFmt("%s/badpid" LOCK_FILE_EXT, strPtr(lockPath))), BUFSTRDEF("-32768")), | ||||
|             "create lock file with invalid PID"); | ||||
|  | ||||
|         HARNESS_FORK_BEGIN() | ||||
| @@ -335,7 +328,7 @@ testRun(void) | ||||
|                 ioReadLine(read); | ||||
|  | ||||
|                 // Remove the file and close the handle | ||||
|                 storageRemoveNP(storageTest, strNewFmt("%s/badpid" LOCK_FILE_EXT, strPtr(lockPath))); | ||||
|                 storageRemoveNP(storageData, strNewFmt("%s/badpid" LOCK_FILE_EXT, strPtr(lockPath))); | ||||
|                 close(lockHandle); | ||||
|             } | ||||
|             HARNESS_FORK_CHILD_END(); | ||||
| @@ -353,7 +346,7 @@ testRun(void) | ||||
|                 TEST_RESULT_VOID( | ||||
|                     cmdStop(), "    stanza, create stop file, force - lock file with another process lock, processId is invalid"); | ||||
|                 harnessLogResult("P00   WARN: unable to send term signal to process -32768"); | ||||
|                 TEST_RESULT_BOOL(storageExistsNP(storageTest, stanzaStopFile), true, "    stanza stop file not removed"); | ||||
|                 TEST_RESULT_BOOL(storageExistsNP(storageData, stanzaStopFile), true, "    stanza stop file not removed"); | ||||
|  | ||||
|                 // Notify the child to release the lock | ||||
|                 ioWriteLine(write, bufNew(0)); | ||||
|   | ||||
| @@ -77,10 +77,8 @@ testRun(void) | ||||
|     String *archiveInfoFileName = strNewFmt("%s/archive.info", strPtr(archiveStanzaPath)); | ||||
|  | ||||
|     StringList *argListBase = strLstNew(); | ||||
|     strLstAddZ(argListBase, "pgbackrest"); | ||||
|     strLstAddZ(argListBase, "--stanza=db"); | ||||
|     strLstAdd(argListBase, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|     strLstAddZ(argListBase, "expire"); | ||||
|  | ||||
|     StringList *argListAvoidWarn = strLstDup(argListBase); | ||||
|     strLstAddZ(argListAvoidWarn, "--repo1-retention-full=1");  // avoid warning | ||||
| @@ -165,7 +163,7 @@ testRun(void) | ||||
|  | ||||
|         // Load Parameters | ||||
|         StringList *argList = strLstDup(argListAvoidWarn); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID( | ||||
|             storagePutNP( | ||||
| @@ -208,7 +206,7 @@ testRun(void) | ||||
|  | ||||
|         // Load Parameters | ||||
|         StringList *argList = strLstDup(argListBase); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_UINT(expireFullBackup(infoBackup), 0, "retention-full not set"); | ||||
|         harnessLogResult( | ||||
| @@ -218,7 +216,7 @@ testRun(void) | ||||
|  | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         strLstAddZ(argList, "--repo1-retention-full=2"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_UINT(expireFullBackup(infoBackup), 1, "retention-full=2 - one full backup expired"); | ||||
|         TEST_RESULT_UINT(infoBackupDataTotal(infoBackup), 5, "  current backups reduced by 1 full - no dependencies"); | ||||
| @@ -231,7 +229,7 @@ testRun(void) | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstDup(argListBase); | ||||
|         strLstAddZ(argList, "--repo1-retention-full=1"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_UINT(expireFullBackup(infoBackup), 3, "retention-full=1 - one full backup and dependencies expired"); | ||||
|         TEST_RESULT_UINT(infoBackupDataTotal(infoBackup), 2, "  current backups reduced by 1 full and dependencies"); | ||||
| @@ -260,7 +258,7 @@ testRun(void) | ||||
|  | ||||
|         // Load Parameters | ||||
|         StringList *argList = strLstDup(argListAvoidWarn); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_UINT(expireDiffBackup(infoBackup), 0, "retention-diff not set - nothing expired"); | ||||
|         TEST_RESULT_UINT(infoBackupDataTotal(infoBackup), 6, "  current backups not expired"); | ||||
| @@ -269,14 +267,14 @@ testRun(void) | ||||
|         // Add retention-diff | ||||
|         StringList *argListTemp = strLstDup(argList); | ||||
|         strLstAddZ(argListTemp, "--repo1-retention-diff=6"); | ||||
|         harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argListTemp); | ||||
|  | ||||
|         TEST_RESULT_UINT(expireDiffBackup(infoBackup), 0, "retention-diff set - too soon to expire"); | ||||
|         TEST_RESULT_UINT(infoBackupDataTotal(infoBackup), 6, "  current backups not expired"); | ||||
|  | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         strLstAddZ(argList, "--repo1-retention-diff=2"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_UINT(expireDiffBackup(infoBackup), 2, "retention-diff set - full considered in diff"); | ||||
|         TEST_RESULT_UINT(infoBackupDataTotal(infoBackup), 4, "  current backups reduced by 1 diff and dependent increment"); | ||||
| @@ -336,7 +334,7 @@ testRun(void) | ||||
|         // Load parameters | ||||
|         argList = strLstDup(argListAvoidWarn); | ||||
|         strLstAddZ(argList, "--repo1-retention-diff=1"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_UINT(expireDiffBackup(infoBackup), 1, "retention-diff set - only oldest diff expired"); | ||||
|         TEST_RESULT_UINT(infoBackupDataTotal(infoBackup), 2, "  current backups reduced by one"); | ||||
| @@ -401,7 +399,7 @@ testRun(void) | ||||
|         // Load Parameters | ||||
|         StringList *argList = strLstDup(argListBase); | ||||
|         strLstAddZ(argList, "--repo1-retention-full=1"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(removeExpiredBackup(infoBackup), "remove backups not in backup.info current"); | ||||
|  | ||||
| @@ -444,7 +442,7 @@ testRun(void) | ||||
|     { | ||||
|         // Load Parameters | ||||
|         StringList *argList = strLstDup(argListBase); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         // Create backup.info without current backups | ||||
|         storagePutNP( | ||||
| @@ -474,7 +472,7 @@ testRun(void) | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         // Set archive retention, archive retention type default but no current backups - code path test | ||||
|         strLstAddZ(argList, "--repo1-retention-archive=4"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(removeExpiredArchive(infoBackup), "archive retention set, retention type default, no current backups"); | ||||
|         harnessLogResult( | ||||
| @@ -603,7 +601,7 @@ testRun(void) | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstDup(argListAvoidWarn); | ||||
|         strLstAddZ(argList, "--repo1-retention-archive=2"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(removeExpiredArchive(infoBackup), "archive retention type = full (default), repo1-retention-archive=2"); | ||||
|  | ||||
| @@ -626,7 +624,7 @@ testRun(void) | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstDup(argListAvoidWarn); | ||||
|         strLstAddZ(argList, "--repo1-retention-archive=1"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(removeExpiredArchive(infoBackup), "archive retention type = full (default), repo1-retention-archive=1"); | ||||
|  | ||||
| @@ -651,7 +649,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--repo1-retention-archive=2"); | ||||
|         strLstAddZ(argList, "--repo1-retention-archive-type=diff"); | ||||
|         strLstAddZ(argList, "--repo1-retention-diff=2"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID( | ||||
|             removeExpiredArchive(infoBackup), | ||||
| @@ -686,7 +684,7 @@ testRun(void) | ||||
|         argList = strLstDup(argListAvoidWarn); | ||||
|         strLstAddZ(argList, "--repo1-retention-archive=4"); | ||||
|         strLstAddZ(argList, "--repo1-retention-archive-type=incr"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         // Regenerate archive | ||||
|         archiveGenerate(storageTest, archiveStanzaPath, 1, 10, "9.4-1", "0000000200000000"); | ||||
| @@ -723,7 +721,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--repo1-retention-diff=3"); | ||||
|         strLstAddZ(argList, "--repo1-retention-archive=2"); | ||||
|         strLstAddZ(argList, "--repo1-retention-archive-type=diff"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(cmdExpire(), "expire last backup in archive sub path and remove sub path"); | ||||
|         TEST_RESULT_BOOL( | ||||
| @@ -734,7 +732,7 @@ testRun(void) | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstDup(argListAvoidWarn); | ||||
|         strLstAddZ(argList, "--repo1-retention-archive=1"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(cmdExpire(), "expire last backup in archive path and remove path"); | ||||
|         TEST_RESULT_BOOL( | ||||
| @@ -800,7 +798,7 @@ testRun(void) | ||||
|         argList = strLstDup(argListAvoidWarn); | ||||
|         strLstAddZ(argList, "--repo1-retention-archive=2"); | ||||
|         strLstAddZ(argList, "--repo1-retention-archive-type=full"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID( | ||||
|             removeExpiredArchive(infoBackup), "backup selected for retention does not have archive-start so do nothing"); | ||||
| @@ -813,7 +811,7 @@ testRun(void) | ||||
|         argList = strLstDup(argListAvoidWarn); | ||||
|         strLstAddZ(argList, "--repo1-retention-archive=4"); | ||||
|         strLstAddZ(argList, "--repo1-retention-archive-type=incr"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID( | ||||
|             removeExpiredArchive(infoBackup), "full count as incr but not enough backups, retention set to first full"); | ||||
| @@ -828,7 +826,7 @@ testRun(void) | ||||
|         argList = strLstDup(argListAvoidWarn); | ||||
|         strLstAddZ(argList, "--repo1-retention-archive=1"); | ||||
|         strLstAddZ(argList, "--repo1-retention-archive-type=full"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|         harnessLogLevelSet(logLevelDetail); | ||||
|  | ||||
|         TEST_RESULT_VOID( | ||||
| @@ -847,7 +845,7 @@ testRun(void) | ||||
|         // Load Parameters | ||||
|         StringList *argList = strLstDup(argListBase); | ||||
|         strLstAddZ(argList, "--repo1-retention-full=2"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         // archive.info has only current db with different db history id as backup.info | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -1009,7 +1007,7 @@ testRun(void) | ||||
|  | ||||
|         argList = strLstDup(argListBase); | ||||
|         strLstAddZ(argList, "--repo1-retention-full=1"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdExpire, argList); | ||||
|  | ||||
|         // Here, although backup 20181119-152138F of 10-1 will be expired, the WAL in 10-1 will not since the archive.info | ||||
|         // does not know about that dir. Again, not really realistic since if it is on disk and reconstructed it would have. So | ||||
|   | ||||
| @@ -25,19 +25,17 @@ testRun(void) | ||||
|     if (testBegin("infoRender()")) | ||||
|     { | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAdd(argList, strNewFmt("--repo-path=%s/", strPtr(repoPath))); | ||||
|         strLstAddZ(argList, "info"); | ||||
|         StringList *argListText = strLstDup(argList); | ||||
|  | ||||
|         strLstAddZ(argList, "--output=json"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList); | ||||
|  | ||||
|         // No stanzas have been created | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_RESULT_STR(strPtr(infoRender()), "[]\n", "json - repo but no stanzas"); | ||||
|  | ||||
|         harnessCfgLoad(strLstSize(argListText), strLstPtr(argListText)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argListText); | ||||
|         TEST_RESULT_STR(strPtr(infoRender()), "No stanzas exist in the repository.\n", "text - no stanzas"); | ||||
|  | ||||
|         storagePathCreateNP(storageLocalWrite(), archivePath); | ||||
| @@ -52,7 +50,7 @@ testRun(void) | ||||
|             "    status: error (missing stanza data)\n" | ||||
|             "    cipher: none\n", "text - missing stanza data"); | ||||
|  | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList); | ||||
|         TEST_RESULT_STR(strPtr(infoRender()), | ||||
|             "[\n" | ||||
|             "    {\n" | ||||
| @@ -162,7 +160,7 @@ testRun(void) | ||||
|             "    }\n" | ||||
|             "]\n", "json - single stanza, no valid backups"); | ||||
|  | ||||
|         harnessCfgLoad(strLstSize(argListText), strLstPtr(argListText)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argListText); | ||||
|         TEST_RESULT_STR(strPtr(infoRender()), | ||||
|             "stanza: stanza1\n" | ||||
|             "    status: error (no valid backups)\n" | ||||
| @@ -183,7 +181,7 @@ testRun(void) | ||||
|  | ||||
|         StringList *argList2 = strLstDup(argListText); | ||||
|         strLstAddZ(argList2, "--stanza=stanza1"); | ||||
|         harnessCfgLoad(strLstSize(argList2), strLstPtr(argList2)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList2); | ||||
|  | ||||
|         TEST_RESULT_STR(strPtr(infoRender()), | ||||
|             "stanza: stanza1\n" | ||||
| @@ -216,7 +214,7 @@ testRun(void) | ||||
|         String *archiveDb1_3 = strNewFmt("%s/9.4-1/0000000300000000", strPtr(archiveStanza1Path)); | ||||
|         TEST_RESULT_VOID(storagePathCreateNP(storageLocalWrite(), archiveDb1_3), "create db1 archive WAL3 directory"); | ||||
|  | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList); | ||||
|         content = strNew | ||||
|         ( | ||||
|             "[db]\n" | ||||
| @@ -326,7 +324,7 @@ testRun(void) | ||||
|             "    }\n" | ||||
|             "]\n", "json - single stanza, valid backup, no priors, no archives in latest DB"); | ||||
|  | ||||
|         harnessCfgLoad(strLstSize(argListText), strLstPtr(argListText)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argListText); | ||||
|         TEST_RESULT_STR(strPtr(infoRender()), | ||||
|             "stanza: stanza1\n" | ||||
|             "    status: ok\n" | ||||
| @@ -572,7 +570,7 @@ testRun(void) | ||||
|             storagePutNP(storageNewWriteNP(storageLocalWrite(), strNewFmt("%s/backup.info", strPtr(backupStanza2Path))), | ||||
|                 harnessInfoChecksum(content)), "put backup info to file - stanza2"); | ||||
|  | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList); | ||||
|         TEST_RESULT_STR(strPtr(infoRender()), | ||||
|             "[\n" | ||||
|             "    {\n" | ||||
| @@ -735,7 +733,7 @@ testRun(void) | ||||
|             "    }\n" | ||||
|             "]\n", "json - multiple stanzas, one with valid backups, archives in latest DB"); | ||||
|  | ||||
|         harnessCfgLoad(strLstSize(argListText), strLstPtr(argListText)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argListText); | ||||
|         TEST_RESULT_STR(strPtr(infoRender()), | ||||
|             "stanza: stanza1\n" | ||||
|             "    status: ok\n" | ||||
| @@ -780,7 +778,7 @@ testRun(void) | ||||
|         argList2 = strLstDup(argListText); | ||||
|         strLstAddZ(argList2, "--stanza=stanza1"); | ||||
|         strLstAddZ(argList2, "--set=20181119-152138F_20181119-152152I"); | ||||
|         harnessCfgLoad(strLstSize(argList2), strLstPtr(argList2)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList2); | ||||
|  | ||||
|         TEST_RESULT_STR(strPtr(infoRender()), | ||||
|  | ||||
| @@ -807,7 +805,7 @@ testRun(void) | ||||
|             , "text - backup set requested"); | ||||
|  | ||||
|         strLstAddZ(argList2, "--output=json"); | ||||
|         harnessCfgLoad(strLstSize(argList2), strLstPtr(argList2)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList2); | ||||
|  | ||||
|         TEST_ERROR(strPtr(infoRender()), ConfigError, "option 'set' is currently only valid for text output"); | ||||
|  | ||||
| @@ -816,7 +814,7 @@ testRun(void) | ||||
|         argList2 = strLstDup(argListText); | ||||
|         strLstAddZ(argList2, "--stanza=stanza1"); | ||||
|         strLstAddZ(argList2, "--set=20181119-152138F_20181119-152152I"); | ||||
|         harnessCfgLoad(strLstSize(argList2), strLstPtr(argList2)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList2); | ||||
|  | ||||
|         #define TEST_MANIFEST_TARGET_NO_LINK                                                                                       \ | ||||
|             "\n"                                                                                                                   \ | ||||
| @@ -866,7 +864,7 @@ testRun(void) | ||||
|         argList2 = strLstDup(argListText); | ||||
|         strLstAddZ(argList2, "--stanza=stanza1"); | ||||
|         strLstAddZ(argList2, "--set=20181119-152138F_20181119-152152I"); | ||||
|         harnessCfgLoad(strLstSize(argList2), strLstPtr(argList2)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList2); | ||||
|  | ||||
|         #define TEST_MANIFEST_NO_DB                                                                                                \ | ||||
|             "\n"                                                                                                                   \ | ||||
| @@ -915,7 +913,7 @@ testRun(void) | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList2 = strLstDup(argList); | ||||
|         strLstAddZ(argList2, "--stanza=silly"); | ||||
|         harnessCfgLoad(strLstSize(argList2), strLstPtr(argList2)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList2); | ||||
|         TEST_RESULT_STR(strPtr(infoRender()), | ||||
|             "[\n" | ||||
|             "    {\n" | ||||
| @@ -931,7 +929,7 @@ testRun(void) | ||||
|  | ||||
|         StringList *argListText2 = strLstDup(argListText); | ||||
|         strLstAddZ(argListText2, "--stanza=silly"); | ||||
|         harnessCfgLoad(strLstSize(argListText2), strLstPtr(argListText2)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argListText2); | ||||
|         TEST_RESULT_STR(strPtr(infoRender()), | ||||
|         "stanza: silly\n" | ||||
|         "    status: error (missing stanza path)\n" | ||||
| @@ -940,7 +938,7 @@ testRun(void) | ||||
|         // Stanza found | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         strLstAddZ(argList, "--stanza=stanza2"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList); | ||||
|         TEST_RESULT_STR(strPtr(infoRender()), | ||||
|             "[\n" | ||||
|             "    {\n" | ||||
| @@ -973,7 +971,7 @@ testRun(void) | ||||
|             , "json - multiple stanzas - selected found"); | ||||
|  | ||||
|         strLstAddZ(argListText, "--stanza=stanza2"); | ||||
|         harnessCfgLoad(strLstSize(argListText), strLstPtr(argListText)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argListText); | ||||
|         TEST_RESULT_STR(strPtr(infoRender()), | ||||
|             "stanza: stanza2\n" | ||||
|             "    status: error (no valid backups)\n" | ||||
| @@ -996,7 +994,7 @@ testRun(void) | ||||
|                 BUFSTR(content)), "put pgbackrest.conf file"); | ||||
|         strLstAddZ(argListText, "--repo-cipher-type=aes-256-cbc"); | ||||
|         strLstAdd(argListText, strNewFmt("--config=%s/pgbackrest.conf", testPath())); | ||||
|         harnessCfgLoad(strLstSize(argListText), strLstPtr(argListText)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argListText); | ||||
|         TEST_ERROR_FMT( | ||||
|             infoRender(), CryptoError, | ||||
|             "unable to load info file '%s/backup.info' or '%s/backup.info.copy':\n" | ||||
| @@ -1067,10 +1065,8 @@ testRun(void) | ||||
|     if (testBegin("cmdInfo()")) | ||||
|     { | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAdd(argList, strNewFmt("--repo-path=%s", strPtr(repoPath))); | ||||
|         strLstAddZ(argList, "info"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList); | ||||
|  | ||||
|         storagePathCreateNP(storageLocalWrite(), archivePath); | ||||
|         storagePathCreateNP(storageLocalWrite(), backupPath); | ||||
| @@ -1097,12 +1093,11 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--set=bogus"); | ||||
|  | ||||
|         TEST_ERROR_FMT( | ||||
|             harnessCfgLoad(strLstSize(argList), strLstPtr(argList)), OptionInvalidError, | ||||
|             "option 'set' not valid without option 'stanza'"); | ||||
|             harnessCfgLoad(cfgCmdInfo, argList), OptionInvalidError, "option 'set' not valid without option 'stanza'"); | ||||
|  | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         strLstAddZ(argList, "--stanza=stanza1"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList); | ||||
|  | ||||
|         TEST_ERROR_FMT( | ||||
|                 cmdInfo(), FileMissingError, "manifest does not exist for backup 'bogus'\n" | ||||
|   | ||||
| @@ -31,14 +31,12 @@ testRun(void) | ||||
|             HARNESS_FORK_CHILD_BEGIN(0, true) | ||||
|             { | ||||
|                 StringList *argList = strLstNew(); | ||||
|                 strLstAddZ(argList, "pgbackrest"); | ||||
|                 strLstAddZ(argList, "--stanza=test1"); | ||||
|                 strLstAddZ(argList, "--command=archive-get-async"); | ||||
|                 strLstAddZ(argList, "--process=1"); | ||||
|                 strLstAddZ(argList, "--type=backup"); | ||||
|                 strLstAddZ(argList, "--host-id=1"); | ||||
|                 strLstAddZ(argList, "local"); | ||||
|                 harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|                 harnessCfgLoad(cfgCmdLocal, argList); | ||||
|  | ||||
|                 cmdLocal(HARNESS_FORK_CHILD_READ(), HARNESS_FORK_CHILD_WRITE()); | ||||
|             } | ||||
|   | ||||
| @@ -21,10 +21,6 @@ testRun(void) | ||||
|     // ***************************************************************************************************************************** | ||||
|     if (testBegin("cmdRemote()")) | ||||
|     { | ||||
|         // Create default storage object for testing | ||||
|         Storage *storageTest = storagePosixNew( | ||||
|             strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL); | ||||
|  | ||||
|         // No remote lock required | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         HARNESS_FORK_BEGIN() | ||||
| @@ -32,13 +28,11 @@ testRun(void) | ||||
|             HARNESS_FORK_CHILD_BEGIN(0, true) | ||||
|             { | ||||
|                 StringList *argList = strLstNew(); | ||||
|                 strLstAddZ(argList, "pgbackrest"); | ||||
|                 strLstAddZ(argList, "--stanza=test1"); | ||||
|                 strLstAddZ(argList, "--command=info"); | ||||
|                 strLstAddZ(argList, "--process=1"); | ||||
|                 strLstAddZ(argList, "--type=backup"); | ||||
|                 strLstAddZ(argList, "remote"); | ||||
|                 harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|                 harnessCfgLoad(cfgCmdRemote, argList); | ||||
|  | ||||
|                 cmdRemote(HARNESS_FORK_CHILD_READ(), HARNESS_FORK_CHILD_WRITE()); | ||||
|             } | ||||
| @@ -66,13 +60,13 @@ testRun(void) | ||||
|             HARNESS_FORK_CHILD_BEGIN(0, true) | ||||
|             { | ||||
|                 StringList *argList = strLstNew(); | ||||
|                 strLstAddZ(argList, "pgbackrest"); | ||||
|                 strLstAddZ(argList, testProjectExe()); | ||||
|                 strLstAddZ(argList, "--command=archive-get-async"); | ||||
|                 strLstAddZ(argList, "--process=0"); | ||||
|                 strLstAddZ(argList, "--type=backup"); | ||||
|                 strLstAddZ(argList, "--lock-path=/bogus"); | ||||
|                 strLstAddZ(argList, "remote"); | ||||
|                 harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|                 harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|                 cmdRemote(HARNESS_FORK_CHILD_READ(), HARNESS_FORK_CHILD_WRITE()); | ||||
|             } | ||||
| @@ -101,14 +95,14 @@ testRun(void) | ||||
|             HARNESS_FORK_CHILD_BEGIN(0, true) | ||||
|             { | ||||
|                 StringList *argList = strLstNew(); | ||||
|                 strLstAddZ(argList, "pgbackrest"); | ||||
|                 strLstAddZ(argList, testProjectExe()); | ||||
|                 strLstAddZ(argList, "--stanza=test"); | ||||
|                 strLstAddZ(argList, "--command=archive-push-async"); | ||||
|                 strLstAddZ(argList, "--process=0"); | ||||
|                 strLstAddZ(argList, "--type=backup"); | ||||
|                 strLstAddZ(argList, "--lock-path=/bogus"); | ||||
|                 strLstAddZ(argList, "remote"); | ||||
|                 harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|                 harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|                 cmdRemote(HARNESS_FORK_CHILD_READ(), HARNESS_FORK_CHILD_WRITE()); | ||||
|             } | ||||
| @@ -136,14 +130,11 @@ testRun(void) | ||||
|             HARNESS_FORK_CHILD_BEGIN(0, true) | ||||
|             { | ||||
|                 StringList *argList = strLstNew(); | ||||
|                 strLstAddZ(argList, "pgbackrest"); | ||||
|                 strLstAddZ(argList, "--stanza=test"); | ||||
|                 strLstAddZ(argList, "--command=archive-push-async"); | ||||
|                 strLstAddZ(argList, "--process=0"); | ||||
|                 strLstAddZ(argList, "--type=backup"); | ||||
|                 strLstAdd(argList, strNewFmt("--lock-path=%s/lock", testPath())); | ||||
|                 strLstAddZ(argList, "remote"); | ||||
|                 harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|                 harnessCfgLoad(cfgCmdRemote, argList); | ||||
|  | ||||
|                 cmdRemote(HARNESS_FORK_CHILD_READ(), HARNESS_FORK_CHILD_WRITE()); | ||||
|             } | ||||
| @@ -160,7 +151,11 @@ testRun(void) | ||||
|                 TEST_ASSIGN(client, protocolClientNew(strNew("test"), PROTOCOL_SERVICE_REMOTE_STR, read, write), "create client"); | ||||
|                 protocolClientNoOp(client); | ||||
|  | ||||
|                 storageExistsNP(storageTest, strNewFmt("--lock-path=%s/lock/test-archive" LOCK_FILE_EXT, testPath())); | ||||
|                 TEST_RESULT_BOOL( | ||||
|                     storageExistsNP( | ||||
|                         storagePosixNew(strNew(testDataPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL), | ||||
|                         STRDEF("lock/test-archive" LOCK_FILE_EXT)), | ||||
|                     true, "lock exists"); | ||||
|  | ||||
|                 protocolClientFree(client); | ||||
|             } | ||||
|   | ||||
| @@ -164,12 +164,10 @@ testRun(void) | ||||
|  | ||||
|         // Load Parameters | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s/pg", testPath())); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         // Create the pg path | ||||
|         storagePathCreateP(storagePgWrite(), NULL, .mode = 0700); | ||||
| @@ -378,12 +376,10 @@ testRun(void) | ||||
|         TEST_TITLE("error on data directory missing"); | ||||
|  | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_ERROR_FMT(restorePathValidate(), PathMissingError, "$PGDATA directory '%s/pg' does not exist", testPath()); | ||||
|  | ||||
| @@ -408,13 +404,11 @@ testRun(void) | ||||
|         TEST_TITLE("error on data directory does not look valid"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--delta"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(restorePathValidate(), "restore --delta with invalid PGDATA"); | ||||
|         TEST_RESULT_BOOL(cfgOptionBool(cfgOptDelta), false, "--delta set to false"); | ||||
| @@ -423,19 +417,17 @@ testRun(void) | ||||
|                 " confirm that this is a valid $PGDATA directory.  --delta and --force have been disabled and if any files" | ||||
|                 " exist in the destination directories the restore will be aborted."); | ||||
|  | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|         storagePutNP(storageNewWriteNP(storagePgWrite(), strNew("backup.manifest")), NULL); | ||||
|         TEST_RESULT_VOID(restorePathValidate(), "restore --delta with valid PGDATA"); | ||||
|         storageRemoveP(storagePgWrite(), strNew("backup.manifest"), .errorOnMissing = true); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s/pg", testPath())); | ||||
|         strLstAddZ(argList, "--force"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(restorePathValidate(), "restore --force with invalid PGDATA"); | ||||
|         TEST_RESULT_BOOL(cfgOptionBool(cfgOptForce), false, "--force set to false"); | ||||
| @@ -444,7 +436,7 @@ testRun(void) | ||||
|                 " confirm that this is a valid $PGDATA directory.  --delta and --force have been disabled and if any files" | ||||
|                 " exist in the destination directories the restore will be aborted."); | ||||
|  | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|         storagePutNP(storageNewWriteNP(storagePgWrite(), strNew(PG_FILE_PGVERSION)), NULL); | ||||
|         TEST_RESULT_VOID(restorePathValidate(), "restore --force with valid PGDATA"); | ||||
|         storageRemoveP(storagePgWrite(), strNew(PG_FILE_PGVERSION), .errorOnMissing = true); | ||||
| @@ -457,12 +449,10 @@ testRun(void) | ||||
|         const String *repoPath = strNewFmt("%s/repo", testPath()); | ||||
|  | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_TITLE("error when no backups are present"); | ||||
| @@ -477,13 +467,11 @@ testRun(void) | ||||
|             ioBufferReadNew(harnessInfoChecksumZ(TEST_RESTORE_BACKUP_INFO "\n" TEST_RESTORE_BACKUP_INFO_DB))); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--set=BOGUS"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_ERROR(restoreBackupSet(infoBackup), BackupSetInvalidError, "backup set BOGUS is not valid"); | ||||
|     } | ||||
| @@ -513,12 +501,10 @@ testRun(void) | ||||
|         TEST_TITLE("remap data directory"); | ||||
|  | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(restoreManifestMap(manifest), "base directory is not remapped"); | ||||
|         TEST_RESULT_STR_STR( | ||||
| @@ -528,12 +514,10 @@ testRun(void) | ||||
|         pgPath = strNewFmt("%s/pg2", testPath()); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(restoreManifestMap(manifest), "base directory is remapped"); | ||||
|         TEST_RESULT_STR_STR(manifestTargetFind(manifest, MANIFEST_TARGET_PGDATA_STR)->path, pgPath, "base directory is remapped"); | ||||
| @@ -543,13 +527,11 @@ testRun(void) | ||||
|         TEST_TITLE("remap tablespaces"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--tablespace-map=bogus=/bogus"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_ERROR(restoreManifestMap(manifest), TablespaceMapError, "unable to remap invalid tablespace 'bogus'"); | ||||
|  | ||||
| @@ -569,28 +551,24 @@ testRun(void) | ||||
|  | ||||
|         // Error on different paths | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--tablespace-map=2=/2"); | ||||
|         strLstAddZ(argList, "--tablespace-map=ts2=/ts2"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             restoreManifestMap(manifest), TablespaceMapError, "tablespace remapped by name 'ts2' and id 2 with different paths"); | ||||
|  | ||||
|         // Remap one tablespace using the id and another with the name | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--tablespace-map=1=/1-2"); | ||||
|         strLstAddZ(argList, "--tablespace-map=ts2=/2-2"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(restoreManifestMap(manifest), "remap tablespaces"); | ||||
|         TEST_RESULT_STR_Z(manifestTargetFind(manifest, STRDEF("pg_tblspc/1"))->path, "/1-2", "    check tablespace 1 target"); | ||||
| @@ -606,14 +584,12 @@ testRun(void) | ||||
|  | ||||
|         // Remap a tablespace using just the id and map the rest with tablespace-map-all | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--tablespace-map=2=/2-3"); | ||||
|         strLstAddZ(argList, "--tablespace-map-all=/all"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(restoreManifestMap(manifest), "remap tablespaces"); | ||||
|         TEST_RESULT_STR_Z(manifestTargetFind(manifest, STRDEF("pg_tblspc/1"))->path, "/all/1", "    check tablespace 1 target"); | ||||
| @@ -631,13 +607,11 @@ testRun(void) | ||||
|         manifest->data.pgVersion = PG_VERSION_92; | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--tablespace-map-all=/all2"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(restoreManifestMap(manifest), "remap tablespaces"); | ||||
|         TEST_RESULT_STR_Z(manifestTargetFind(manifest, STRDEF("pg_tblspc/1"))->path, "/all2/1", "    check tablespace 1 target"); | ||||
| @@ -656,13 +630,11 @@ testRun(void) | ||||
|         TEST_TITLE("remap links"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--link-map=bogus=bogus"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_ERROR(restoreManifestMap(manifest), LinkMapError, "unable to remap invalid link 'bogus'"); | ||||
|  | ||||
| @@ -680,13 +652,11 @@ testRun(void) | ||||
|  | ||||
|         // Error on invalid file link path | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--link-map=pg_hba.conf=bogus"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             restoreManifestMap(manifest), LinkMapError, | ||||
| @@ -696,14 +666,12 @@ testRun(void) | ||||
|  | ||||
|         // Remap both links | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--link-map=pg_hba.conf=../conf2/pg_hba2.conf"); | ||||
|         strLstAddZ(argList, "--link-map=pg_wal=/wal2"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(restoreManifestMap(manifest), "remap links"); | ||||
|         TEST_RESULT_STR_Z(manifestTargetFind(manifest, STRDEF("pg_data/pg_hba.conf"))->path, "../conf2", "    check link path"); | ||||
| @@ -720,13 +688,11 @@ testRun(void) | ||||
|  | ||||
|         // Leave all links as they are | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--link-all"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(restoreManifestMap(manifest), "leave links as they are"); | ||||
|         TEST_RESULT_STR_Z(manifestTargetFind(manifest, STRDEF("pg_data/pg_hba.conf"))->path, "../conf2", "    check link path"); | ||||
| @@ -739,12 +705,10 @@ testRun(void) | ||||
|  | ||||
|         // Remove all links | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(restoreManifestMap(manifest), "remove all links"); | ||||
|         TEST_ERROR( | ||||
| @@ -819,12 +783,10 @@ testRun(void) | ||||
|         TEST_TITLE("owner is root and ownership is good"); | ||||
|  | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "--repo1-path=/repo"); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         manifest = testManifestMinimal(STRDEF("20161219-212741F_20161219-21275D"), PG_VERSION_96, pgPath); | ||||
|         userLocalData.userRoot = true; | ||||
| @@ -856,21 +818,24 @@ testRun(void) | ||||
|         TEST_RESULT_LOG("P00   WARN: unknown user in backup manifest mapped to '{[user]}'"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_TITLE("owner is root and ownership of pg_data is bad"); | ||||
|         if (testContainer()) | ||||
|         { | ||||
|             TEST_TITLE("owner is root and ownership of pg_data is bad"); | ||||
|  | ||||
|         manifestPathAdd(manifest, &path); | ||||
|         manifestFileAdd(manifest, &file); | ||||
|             manifestPathAdd(manifest, &path); | ||||
|             manifestFileAdd(manifest, &file); | ||||
|  | ||||
|         TEST_SYSTEM_FMT("sudo chown 77777:77777 %s", strPtr(pgPath)); | ||||
|             TEST_SYSTEM_FMT("sudo chown 77777:77777 %s", strPtr(pgPath)); | ||||
|  | ||||
|         userLocalData.userName = STRDEF("root"); | ||||
|         userLocalData.groupName = STRDEF("root"); | ||||
|             userLocalData.userName = STRDEF("root"); | ||||
|             userLocalData.groupName = STRDEF("root"); | ||||
|  | ||||
|         TEST_RESULT_VOID(restoreManifestOwner(manifest), "check ownership"); | ||||
|             TEST_RESULT_VOID(restoreManifestOwner(manifest), "check ownership"); | ||||
|  | ||||
|         TEST_RESULT_LOG( | ||||
|             "P00   WARN: unknown user in backup manifest mapped to 'root'\n" | ||||
|             "P00   WARN: unknown group in backup manifest mapped to 'root'"); | ||||
|             TEST_RESULT_LOG( | ||||
|                 "P00   WARN: unknown user in backup manifest mapped to 'root'\n" | ||||
|                 "P00   WARN: unknown group in backup manifest mapped to 'root'"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // ***************************************************************************************************************************** | ||||
| @@ -908,12 +873,10 @@ testRun(void) | ||||
|         Manifest *manifest = testManifestMinimal(STRDEF("20161219-212741F_20161219-21275D"), PG_VERSION_96, pgPath); | ||||
|  | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         storagePathCreateP(storagePgWrite(), NULL, .mode = 0600); | ||||
|  | ||||
| @@ -999,13 +962,11 @@ testRun(void) | ||||
|         TEST_SYSTEM_FMT("rm -rf %s/*", strPtr(pgPath)); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--type=preserve"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(restoreCleanBuild(manifest), "restore"); | ||||
|  | ||||
| @@ -1063,12 +1024,10 @@ testRun(void) | ||||
|         TEST_SYSTEM_FMT("rm -rf %s/*", strPtr(pgPath)); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(restoreCleanBuild(manifest), "restore"); | ||||
|  | ||||
| @@ -1088,15 +1047,13 @@ testRun(void) | ||||
|         TEST_TITLE("no valid databases"); | ||||
|  | ||||
|         StringList *argListClean = strLstNew(); | ||||
|         strLstAddZ(argListClean, "pgbackrest"); | ||||
|         strLstAddZ(argListClean, "--stanza=test1"); | ||||
|         strLstAddZ(argListClean, "--repo1-path=/repo"); | ||||
|         strLstAddZ(argListClean, "--pg1-path=/pg"); | ||||
|         strLstAddZ(argListClean, "restore"); | ||||
|  | ||||
|         StringList *argList = strLstDup(argListClean); | ||||
|         strLstAddZ(argList, "--db-include=test1"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         Manifest *manifest = NULL; | ||||
|  | ||||
| @@ -1154,7 +1111,7 @@ testRun(void) | ||||
|  | ||||
|         argList = strLstDup(argListClean); | ||||
|         strLstAddZ(argList, "--db-include=1"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             restoreSelectiveExpression(manifest), DbInvalidError, | ||||
| @@ -1167,7 +1124,7 @@ testRun(void) | ||||
|  | ||||
|         argList = strLstDup(argListClean); | ||||
|         strLstAddZ(argList, "--db-include=7777777"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_ERROR(restoreSelectiveExpression(manifest), DbMissingError, "database to include '7777777' does not exist"); | ||||
|  | ||||
| @@ -1186,7 +1143,7 @@ testRun(void) | ||||
|  | ||||
|         argList = strLstDup(argListClean); | ||||
|         strLstAddZ(argList, "--db-include=16384"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_STR_Z(restoreSelectiveExpression(manifest), "(^pg_data/base/32768/)", "check expression"); | ||||
|  | ||||
| @@ -1238,11 +1195,9 @@ testRun(void) | ||||
|     if (testBegin("restoreRecoveryOption() and restoreRecoveryConf()")) | ||||
|     { | ||||
|         StringList *argBaseList = strLstNew(); | ||||
|         strLstAddZ(argBaseList, "pgbackrest"); | ||||
|         strLstAddZ(argBaseList, "--stanza=test1"); | ||||
|         strLstAddZ(argBaseList, "--repo1-path=/repo"); | ||||
|         strLstAddZ(argBaseList, "--pg1-path=/pg"); | ||||
|         strLstAddZ(argBaseList, "restore"); | ||||
|  | ||||
|         const String *restoreLabel = STRDEF("LABEL"); | ||||
|         #define RECOVERY_SETTING_HEADER                             "# Recovery settings generated by pgBackRest restore on LABEL\n" | ||||
| @@ -1253,14 +1208,16 @@ testRun(void) | ||||
|         StringList *argList = strLstDup(argBaseList); | ||||
|         strLstAddZ(argList, "--recovery-option=a-setting=a"); | ||||
|         strLstAddZ(argList, "--recovery-option=b_setting=b"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_STR_Z( | ||||
|             restoreRecoveryConf(PG_VERSION_94, restoreLabel), | ||||
|             RECOVERY_SETTING_HEADER | ||||
|             "a_setting = 'a'\n" | ||||
|             hrnReplaceKey( | ||||
|                 RECOVERY_SETTING_HEADER | ||||
|                 "a_setting = 'a'\n" | ||||
|                 "b_setting = 'b'\n" | ||||
|                 "restore_command = 'pgbackrest --pg1-path=/pg --repo1-path=/repo --stanza=test1 archive-get %f \"%p\"'\n", | ||||
|                 "restore_command = '{[project-exe]} --lock-path={[path-data]}/lock --log-path={[path-data]} --pg1-path=/pg" | ||||
|                     " --repo1-path=/repo --stanza=test1 archive-get %f \"%p\"'\n"), | ||||
|             "check recovery options"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -1268,7 +1225,7 @@ testRun(void) | ||||
|  | ||||
|         strLstAddZ(argBaseList, "--recovery-option=restore-command=my_restore_command"); | ||||
|         argList = strLstDup(argBaseList); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_STR_Z( | ||||
|             restoreRecoveryConf(PG_VERSION_94, restoreLabel), | ||||
| @@ -1281,7 +1238,7 @@ testRun(void) | ||||
|  | ||||
|         argList = strLstDup(argBaseList); | ||||
|         strLstAddZ(argList, "--type=immediate"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_STR_Z( | ||||
|             restoreRecoveryConf(PG_VERSION_94, restoreLabel), | ||||
| @@ -1297,7 +1254,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--type=time"); | ||||
|         strLstAddZ(argList, "--target=TIME"); | ||||
|         strLstAddZ(argList, "--target-timeline=3"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_STR_Z( | ||||
|             restoreRecoveryConf(PG_VERSION_94, restoreLabel), | ||||
| @@ -1314,7 +1271,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--type=time"); | ||||
|         strLstAddZ(argList, "--target=TIME"); | ||||
|         strLstAddZ(argList, "--target-exclusive"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_STR_Z( | ||||
|             restoreRecoveryConf(PG_VERSION_94, restoreLabel), | ||||
| @@ -1330,7 +1287,7 @@ testRun(void) | ||||
|         argList = strLstDup(argBaseList); | ||||
|         strLstAddZ(argList, "--type=name"); | ||||
|         strLstAddZ(argList, "--target=NAME"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_STR_Z( | ||||
|             restoreRecoveryConf(PG_VERSION_94, restoreLabel), | ||||
| @@ -1345,7 +1302,7 @@ testRun(void) | ||||
|         argList = strLstDup(argBaseList); | ||||
|         strLstAddZ(argList, "--type=immediate"); | ||||
|         strLstAddZ(argList, "--target-action=shutdown"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_STR_Z( | ||||
|             restoreRecoveryConf(PG_VERSION_95, restoreLabel), | ||||
| @@ -1365,7 +1322,7 @@ testRun(void) | ||||
|         argList = strLstDup(argBaseList); | ||||
|         strLstAddZ(argList, "--type=immediate"); | ||||
|         strLstAddZ(argList, "--target-action=promote"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_STR_Z( | ||||
|             restoreRecoveryConf(PG_VERSION_94, restoreLabel), | ||||
| @@ -1384,7 +1341,7 @@ testRun(void) | ||||
|  | ||||
|         argList = strLstDup(argBaseList); | ||||
|         strLstAddZ(argList, "--type=standby"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_STR_Z( | ||||
|             restoreRecoveryConf(PG_VERSION_94, restoreLabel), | ||||
| @@ -1399,7 +1356,7 @@ testRun(void) | ||||
|         argList = strLstDup(argBaseList); | ||||
|         strLstAddZ(argList, "--type=standby"); | ||||
|         strLstAddZ(argList, "--target-timeline=current"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_STR_Z( | ||||
|             restoreRecoveryConf(PG_VERSION_94, restoreLabel), | ||||
| @@ -1414,7 +1371,7 @@ testRun(void) | ||||
|  | ||||
|         argList = strLstDup(argBaseList); | ||||
|         strLstAddZ(argList, "--type=standby"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_RESULT_STR_Z( | ||||
|             restoreRecoveryConf(PG_VERSION_12, restoreLabel), | ||||
| @@ -1436,14 +1393,12 @@ testRun(void) | ||||
|         TEST_TITLE("error when standby_mode setting is present"); | ||||
|  | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "--repo1-path=/repo"); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--type=default"); | ||||
|         strLstAddZ(argList, "--recovery-option=standby-mode=on"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             restoreRecoveryWriteAutoConf(PG_VERSION_12, restoreLabel), OptionInvalidError, | ||||
| @@ -1456,13 +1411,11 @@ testRun(void) | ||||
|         TEST_TITLE("PG12 restore missing postgresql.auto.conf"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "--repo1-path=/repo"); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--type=none"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         restoreRecoveryWriteAutoConf(PG_VERSION_12, restoreLabel); | ||||
|  | ||||
| @@ -1512,14 +1465,12 @@ testRun(void) | ||||
|                 "recovery_target_inclusive = false\n")); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "--repo1-path=/repo"); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--recovery-option=restore-command=my_restore_command"); | ||||
|         strLstAddZ(argList, "--type=standby"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         restoreRecoveryWriteAutoConf(PG_VERSION_12, restoreLabel); | ||||
|  | ||||
| @@ -1548,13 +1499,11 @@ testRun(void) | ||||
|         storagePutNP(storageNewWriteNP(storagePgWrite(), PG_FILE_STANDBYSIGNAL_STR), NULL); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "--repo1-path=/repo"); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--type=preserve"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         restoreRecoveryWrite(manifest); | ||||
|  | ||||
| @@ -1574,12 +1523,10 @@ testRun(void) | ||||
|             BUFSTRDEF("# DO NOT MODIFY\n")); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "--repo1-path=/repo"); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         restoreRecoveryWrite(manifest); | ||||
|  | ||||
| @@ -1615,13 +1562,11 @@ testRun(void) | ||||
|         TEST_TITLE("incorrect locality"); | ||||
|  | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--pg1-host=pg1"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         TEST_ERROR(cmdRestore(), HostInvalidError, "restore command must be run on the PostgreSQL host"); | ||||
|  | ||||
| @@ -1635,13 +1580,11 @@ testRun(void) | ||||
|         TEST_TITLE("full restore without delta"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--set=20161219-212741F"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         #define TEST_LABEL                                          "20161219-212741F" | ||||
|         #define TEST_PGDATA                                         MANIFEST_TARGET_PGDATA "/" | ||||
| @@ -1761,15 +1704,13 @@ testRun(void) | ||||
|         TEST_TITLE("full restore with force"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
|         strLstAddZ(argList, "--type=preserve"); | ||||
|         strLstAddZ(argList, "--set=20161219-212741F"); | ||||
|         strLstAddZ(argList, "--force"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         // Make sure existing backup.manifest file is ignored | ||||
|         storagePutNP(storageNewWriteNP(storagePgWrite(), BACKUP_MANIFEST_FILE_STR), NULL); | ||||
| @@ -1871,7 +1812,6 @@ testRun(void) | ||||
|         TEST_TITLE("incremental delta selective restore"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
| @@ -1880,8 +1820,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--link-map=pg_wal=../wal"); | ||||
|         strLstAddZ(argList, "--link-map=postgresql.conf=../config/postgresql.conf"); | ||||
|         strLstAddZ(argList, "--link-map=pg_hba.conf=../config/pg_hba.conf"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         #define TEST_LABEL                                          "20161219-212741F_20161219-212918I" | ||||
|         #define TEST_PGDATA                                         MANIFEST_TARGET_PGDATA "/" | ||||
| @@ -2229,7 +2168,6 @@ testRun(void) | ||||
|         TEST_TITLE("incremental delta selective restore"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(repoPath))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pgPath))); | ||||
| @@ -2239,8 +2177,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--link-map=postgresql.conf=../config/postgresql.conf"); | ||||
|         strLstAddZ(argList, "--link-map=pg_hba.conf=../config/pg_hba.conf"); | ||||
|         strLstAddZ(argList, "--db-include=16384"); | ||||
|         strLstAddZ(argList, "restore"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdRestore, argList); | ||||
|  | ||||
|         // Write recovery.conf so we don't get a preserve warning | ||||
|         storagePutNP(storageNewWriteNP(storagePgWrite(), PG_FILE_RECOVERYCONF_STR), BUFSTRDEF("Some Settings")); | ||||
|   | ||||
| @@ -28,7 +28,6 @@ testRun(void) | ||||
|     String *archiveInfoFileName = strNewFmt("%s/archive.info", strPtr(archiveStanzaPath)); | ||||
|  | ||||
|     StringList *argListBase = strLstNew(); | ||||
|     strLstAddZ(argListBase, "pgbackrest"); | ||||
|     strLstAddZ(argListBase, "--no-online"); | ||||
|     strLstAdd(argListBase, strNewFmt("--stanza=%s", strPtr(stanza))); | ||||
|     strLstAdd(argListBase, strNewFmt("--pg1-path=%s/%s", testPath(), strPtr(stanza))); | ||||
| @@ -40,16 +39,14 @@ testRun(void) | ||||
|         // Load Parameters | ||||
|         StringList *argList = strLstDup(argListBase); | ||||
|         strLstAddZ(argList, "--repo1-host=/repo/not/local"); | ||||
|         strLstAddZ(argList, "stanza-create"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaCreate, argList); | ||||
|  | ||||
|         TEST_ERROR_FMT( | ||||
|             cmdStanzaCreate(), HostInvalidError, "stanza-create command must be run on the repository host"); | ||||
|  | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstDup(argListBase); | ||||
|         strLstAddZ(argList, "stanza-create"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaCreate, argList); | ||||
|  | ||||
|         // Create the stop file | ||||
|         TEST_RESULT_VOID( | ||||
| @@ -62,8 +59,7 @@ testRun(void) | ||||
|  | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstDup(argListBase); | ||||
|         strLstAddZ(argList, "stanza-create"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaCreate, argList); | ||||
|  | ||||
|         // Create pg_control | ||||
|         storagePutNP( | ||||
| @@ -426,7 +422,7 @@ testRun(void) | ||||
|         // Repeat last test using --force (deprecated) | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         strLstAddZ(argList, "--force"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaCreate, argList); | ||||
|         TEST_ERROR_FMT(cmdStanzaCreate(), PathNotEmptyError, "archive directory not empty"); | ||||
|         harnessLogResult("P00   WARN: option --force is no longer supported"); | ||||
|     } | ||||
| @@ -439,12 +435,10 @@ testRun(void) | ||||
|  | ||||
|         // Load Parameters | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAdd(argList, strNewFmt("--stanza=%s", strPtr(stanza))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", strPtr(pg1Path))); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAddZ(argList, "stanza-create"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaCreate, argList); | ||||
|  | ||||
|         // pgControl and database match | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -519,14 +513,12 @@ testRun(void) | ||||
|         // Primary at pg2 | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAdd(argList, strNewFmt("--stanza=%s", strPtr(stanza))); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--pg2-path=%s", strPtr(pg1Path))); | ||||
|         strLstAddZ(argList, "--pg2-port=5434"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|         strLstAddZ(argList, "stanza-create"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaCreate, argList); | ||||
|  | ||||
|         // Create pg_control for master | ||||
|         storagePutNP( | ||||
| @@ -559,8 +551,7 @@ testRun(void) | ||||
|         StringList *argList = strLstDup(argListBase); | ||||
|         strLstAddZ(argList, "--repo1-cipher-type=aes-256-cbc"); | ||||
|         setenv("PGBACKREST_REPO1_CIPHER_PASS", "12345678", true); | ||||
|         strLstAddZ(argList, "stanza-create"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaCreate, argList); | ||||
|  | ||||
|         // Create pg_control | ||||
|         storagePutNP( | ||||
| @@ -592,16 +583,14 @@ testRun(void) | ||||
|         // Load Parameters | ||||
|         StringList *argList = strLstDup(argListBase); | ||||
|         strLstAddZ(argList, "--repo1-host=/repo/not/local"); | ||||
|         strLstAddZ(argList, "stanza-upgrade"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaUpgrade, argList); | ||||
|  | ||||
|         TEST_ERROR_FMT( | ||||
|             cmdStanzaUpgrade(), HostInvalidError, "stanza-upgrade command must be run on the repository host"); | ||||
|  | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstDup(argListBase); | ||||
|         strLstAddZ(argList, "stanza-upgrade"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaUpgrade, argList); | ||||
|  | ||||
|         // Create the stop file | ||||
|         TEST_RESULT_VOID( | ||||
| @@ -615,8 +604,7 @@ testRun(void) | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         // Load Parameters | ||||
|         argList = strLstDup(argListBase); | ||||
|         strLstAddZ(argList, "stanza-create"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaCreate, argList); | ||||
|  | ||||
|         // Create pg_control | ||||
|         storagePutNP( | ||||
| @@ -627,8 +615,7 @@ testRun(void) | ||||
|  | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstDup(argListBase); | ||||
|         strLstAddZ(argList, "stanza-upgrade"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaUpgrade, argList); | ||||
|  | ||||
|         TEST_RESULT_VOID(cmdStanzaUpgrade(), "stanza upgrade - files already exist and both are valid"); | ||||
|         harnessLogResult("P00   INFO: stanza 'db' is already up to date"); | ||||
| @@ -890,15 +877,13 @@ testRun(void) | ||||
|     { | ||||
|         // Load Parameters | ||||
|         StringList *argListCmd = strLstNew(); | ||||
|         strLstAddZ(argListCmd, "pgbackrest"); | ||||
|         strLstAdd(argListCmd, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|  | ||||
|         StringList *argList = strLstDup(argListCmd); | ||||
|         strLstAddZ(argList, "--repo1-host=/repo/not/local"); | ||||
|         strLstAdd(argList, strNewFmt("--stanza=%s", strPtr(stanza))); | ||||
|         strLstAdd(argList,strNewFmt("--pg1-path=%s/%s", testPath(), strPtr(stanza))); | ||||
|         strLstAddZ(argList,"stanza-delete"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaDelete, argList); | ||||
|  | ||||
|         TEST_ERROR_FMT( | ||||
|             cmdStanzaDelete(), HostInvalidError, "stanza-delete command must be run on the repository host"); | ||||
| @@ -911,8 +896,7 @@ testRun(void) | ||||
|         strLstAdd(argList, strNewFmt("--stanza=%s", strPtr(stanzaOther))); | ||||
|         strLstAdd(argList,strNewFmt("--pg1-path=%s/%s", testPath(), strPtr(stanzaOther))); | ||||
|         strLstAddZ(argList, "--no-online"); | ||||
|         strLstAddZ(argList,"stanza-create"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaCreate, argList); | ||||
|  | ||||
|         // Create pg_control for stanza-create | ||||
|         storagePutNP( | ||||
| @@ -924,8 +908,7 @@ testRun(void) | ||||
|         argList = strLstDup(argListCmd); | ||||
|         strLstAdd(argList, strNewFmt("--stanza=%s", strPtr(stanza))); | ||||
|         strLstAdd(argList,strNewFmt("--pg1-path=%s/%s", testPath(), strPtr(stanza))); | ||||
|         strLstAddZ(argList,"stanza-delete"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaDelete, argList); | ||||
|  | ||||
|         // stanza already deleted | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -941,8 +924,7 @@ testRun(void) | ||||
|         strLstAdd(argList, strNewFmt("--stanza=%s", strPtr(stanza))); | ||||
|         strLstAdd(argList,strNewFmt("--pg1-path=%s/%s", testPath(), strPtr(stanza))); | ||||
|         strLstAddZ(argList, "--no-online"); | ||||
|         strLstAddZ(argList,"stanza-create"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaCreate, argList); | ||||
|  | ||||
|         // Create pg_control for stanza-create | ||||
|         storagePutNP( | ||||
| @@ -956,8 +938,7 @@ testRun(void) | ||||
|         argList = strLstDup(argListCmd); | ||||
|         strLstAdd(argList, strNewFmt("--stanza=%s", strPtr(stanza))); | ||||
|         strLstAdd(argList,strNewFmt("--pg1-path=%s/%s", testPath(), strPtr(stanza))); | ||||
|         strLstAddZ(argList,"stanza-delete"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaDelete, argList); | ||||
|  | ||||
|         TEST_ERROR_FMT( | ||||
|             cmdStanzaDelete(), FileMissingError, "stop file does not exist for stanza 'db'\n" | ||||
| @@ -1093,7 +1074,7 @@ testRun(void) | ||||
|  | ||||
|         // Force deletion | ||||
|         strLstAddZ(argList,"--force"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdStanzaDelete, argList); | ||||
|         TEST_RESULT_VOID(cmdStanzaDelete(), "stanza delete --force"); | ||||
|         TEST_RESULT_BOOL( | ||||
|             storagePathExistsNP(storageTest, strNewFmt("repo/backup/%s", strPtr(stanza))), false, "    stanza deleted"); | ||||
|   | ||||
| @@ -22,12 +22,10 @@ testRun(void) | ||||
|     if (testBegin("cmdStorageList() and storageListRender()")) | ||||
|     { | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAdd(argList, strNewFmt("--repo-path=%s/repo", testPath())); | ||||
|         strLstAddZ(argList, "--output=text"); | ||||
|         strLstAddZ(argList, "--sort=none"); | ||||
|         strLstAddZ(argList, "ls"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdLs, argList); | ||||
|  | ||||
|         // Missing directory | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -65,12 +63,7 @@ testRun(void) | ||||
|         cfgOptionSet(cfgOptSort, cfgSourceParam, VARSTRDEF("asc")); | ||||
|  | ||||
|         storagePathCreateNP(storageTest, strNew("repo/bbb")); | ||||
|         ASSERT(system(strPtr(strNewFmt("sudo chown :77777 %s/repo/bbb", testPath()))) == 0); | ||||
|  | ||||
|         storagePutNP(storageNewWriteNP(storageTest, strNew("repo/aaa")), BUFSTRDEF("TESTDATA")); | ||||
|         ASSERT(system(strPtr(strNewFmt("sudo chown 77777 %s/repo/aaa", testPath()))) == 0); | ||||
|         ASSERT(system(strPtr(strNewFmt("sudo chmod 000 %s/repo/aaa", testPath()))) == 0); | ||||
|  | ||||
|         storagePutNP(storageNewWriteNP(storageTest, strNew("repo/bbb/ccc")), BUFSTRDEF("TESTDATA2")); | ||||
|  | ||||
|         ASSERT(system(strPtr(strNewFmt("ln -s ../bbb %s/repo/link", testPath()))) == 0); | ||||
| @@ -128,7 +121,7 @@ testRun(void) | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         StringList *argListTmp = strLstDup(argList); | ||||
|         strLstAddZ(argListTmp, "bbb"); | ||||
|         harnessCfgLoad(strLstSize(argListTmp), strLstPtr(argListTmp)); | ||||
|         harnessCfgLoad(cfgCmdLs, argListTmp); | ||||
|  | ||||
|         output = bufNew(0); | ||||
|         cfgOptionSet(cfgOptOutput, cfgSourceParam, VARSTRDEF("text")); | ||||
| @@ -153,7 +146,7 @@ testRun(void) | ||||
|         // Too many paths | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         strLstAddZ(argListTmp, "ccc"); | ||||
|         harnessCfgLoad(strLstSize(argListTmp), strLstPtr(argListTmp)); | ||||
|         harnessCfgLoad(cfgCmdLs, argListTmp); | ||||
|  | ||||
|         output = bufNew(0); | ||||
|         TEST_ERROR(storageListRender(ioBufferWriteNew(output)), ParamInvalidError, "only one path may be specified"); | ||||
|   | ||||
| @@ -14,7 +14,7 @@ testHttpServer(void) | ||||
| { | ||||
|     if (fork() == 0) | ||||
|     { | ||||
|         harnessTlsServerInit(TLS_TEST_PORT, TLS_CERT_TEST_CERT, TLS_CERT_TEST_KEY); | ||||
|         harnessTlsServerInitDefault(); | ||||
|  | ||||
|         // Test no output from server | ||||
|         harnessTlsServerAccept(); | ||||
| @@ -410,22 +410,22 @@ testRun(void) | ||||
|         httpClientStatLocal = (HttpClientStat){0}; | ||||
|         TEST_RESULT_STR(httpClientStatStr(), NULL, "no stats yet"); | ||||
|  | ||||
|         TEST_ASSIGN(client, httpClientNew(strNew("localhost"), TLS_TEST_PORT, 500, true, NULL, NULL), "new client"); | ||||
|         TEST_ASSIGN(client, httpClientNew(strNew("localhost"), TLS_TEST_PORT, 500, testContainer(), NULL, NULL), "new client"); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|         TEST_ERROR_FMT( | ||||
|             httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, NULL, false), HostConnectError, | ||||
|             "unable to connect to 'localhost:9443': [111] Connection refused"); | ||||
|             "unable to connect to 'localhost:%d': [111] Connection refused", TLS_TEST_PORT); | ||||
|  | ||||
|         // Start http test server | ||||
|         testHttpServer(); | ||||
|  | ||||
|         // Test no output from server | ||||
|         TEST_ASSIGN(client, httpClientNew(strNew(TLS_TEST_HOST), TLS_TEST_PORT, 500, true, NULL, NULL), "new client"); | ||||
|         TEST_ASSIGN(client, httpClientNew(harnessTlsTestHost(), TLS_TEST_PORT, 500, testContainer(), NULL, NULL), "new client"); | ||||
|         client->timeout = 0; | ||||
|  | ||||
|         TEST_ERROR( | ||||
|         TEST_ERROR_FMT( | ||||
|             httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, NULL, false), FileReadError, | ||||
|             "timeout after 500ms waiting for read from '" TLS_TEST_HOST ":9443'"); | ||||
|             "timeout after 500ms waiting for read from '%s:%d'", strPtr(harnessTlsTestHost()), TLS_TEST_PORT); | ||||
|  | ||||
|         // Test invalid http version | ||||
|         TEST_ERROR( | ||||
|   | ||||
| @@ -7,11 +7,6 @@ Test Tls Client | ||||
|  | ||||
| #include "common/harnessTls.h" | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Path and prefix for test certificates | ||||
| ***********************************************************************************************************************************/ | ||||
| #define TEST_CERTIFICATE_PREFIX                                     "test/certificate/pgbackrest-test" | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Test server with subject alternate names | ||||
| ***********************************************************************************************************************************/ | ||||
| @@ -29,17 +24,20 @@ testTlsServerAltName(void) | ||||
|         harnessTlsServerAccept(); | ||||
|         harnessTlsServerClose(); | ||||
|  | ||||
|         // Success on valid ca file and match common name | ||||
|         harnessTlsServerAccept(); | ||||
|         harnessTlsServerClose(); | ||||
|         if (testContainer()) | ||||
|         { | ||||
|             // Success on valid ca file and match common name | ||||
|             harnessTlsServerAccept(); | ||||
|             harnessTlsServerClose(); | ||||
|  | ||||
|         // Success on valid ca file and match alt name | ||||
|         harnessTlsServerAccept(); | ||||
|         harnessTlsServerClose(); | ||||
|             // Success on valid ca file and match alt name | ||||
|             harnessTlsServerAccept(); | ||||
|             harnessTlsServerClose(); | ||||
|  | ||||
|         // Unable to find matching hostname in certificate | ||||
|         harnessTlsServerAccept(); | ||||
|         harnessTlsServerClose(); | ||||
|             // Unable to find matching hostname in certificate | ||||
|             harnessTlsServerAccept(); | ||||
|             harnessTlsServerClose(); | ||||
|         } | ||||
|  | ||||
|         // Certificate error | ||||
|         harnessTlsServerAccept(); | ||||
| @@ -61,7 +59,7 @@ testTlsServer(void) | ||||
| { | ||||
|     if (fork() == 0) | ||||
|     { | ||||
|         harnessTlsServerInit(TLS_TEST_PORT, TLS_CERT_TEST_CERT, TLS_CERT_TEST_KEY); | ||||
|         harnessTlsServerInitDefault(); | ||||
|  | ||||
|         // First protocol exchange | ||||
|         harnessTlsServerAccept(); | ||||
| @@ -123,7 +121,7 @@ testRun(void) | ||||
|     { | ||||
|         TlsClient *client = NULL; | ||||
|  | ||||
|         TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), 9443, 0, true, NULL, NULL), "new client"); | ||||
|         TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), TLS_TEST_PORT, 0, true, NULL, NULL), "new client"); | ||||
|  | ||||
|         TEST_RESULT_BOOL(tlsError(client, SSL_ERROR_WANT_READ), true, "continue after want read"); | ||||
|         TEST_RESULT_BOOL(tlsError(client, SSL_ERROR_ZERO_RETURN), false, "check connection closed error"); | ||||
| @@ -137,57 +135,69 @@ testRun(void) | ||||
|  | ||||
|         // Connection errors | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), 9443, 0, true, NULL, NULL), "new client"); | ||||
|         TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), TLS_TEST_PORT, 0, true, NULL, NULL), "new client"); | ||||
|         TEST_ERROR( | ||||
|             tlsClientOpen(client), HostConnectError, "unable to get address for '99.99.99.99.99': [-2] Name or service not known"); | ||||
|  | ||||
|         TEST_ASSIGN(client, tlsClientNew(strNew("localhost"), 9443, 100, true, NULL, NULL), "new client"); | ||||
|         TEST_ERROR(tlsClientOpen(client), HostConnectError, "unable to connect to 'localhost:9443': [111] Connection refused"); | ||||
|         TEST_ASSIGN(client, tlsClientNew(strNew("localhost"), TLS_TEST_PORT, 100, true, NULL, NULL), "new client"); | ||||
|         TEST_ERROR_FMT( | ||||
|             tlsClientOpen(client), HostConnectError, "unable to connect to 'localhost:%d': [111] Connection refused", | ||||
|             TLS_TEST_PORT); | ||||
|  | ||||
|         // Certificate location and validation errors | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         // Add test hosts | ||||
|         if (system(                                                                                 // {uncoverable_branch} | ||||
|                 "echo \"127.0.0.1 test.pgbackrest.org host.test2.pgbackrest.org test3.pgbackrest.org\" |" | ||||
|                     " sudo tee -a /etc/hosts > /dev/null") != 0) | ||||
|         if (testContainer()) | ||||
|         { | ||||
|             THROW(AssertError, "unable to add test hosts to /etc/hosts");                           // {uncovered+} | ||||
|             if (system(                                                                                 // {uncoverable_branch} | ||||
|                     "echo \"127.0.0.1 test.pgbackrest.org host.test2.pgbackrest.org test3.pgbackrest.org\" |" | ||||
|                         " sudo tee -a /etc/hosts > /dev/null") != 0) | ||||
|             { | ||||
|                 THROW(AssertError, "unable to add test hosts to /etc/hosts");                           // {uncovered+} | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Start server to test various certificate errors | ||||
|         testTlsServerAltName(); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             tlsClientOpen(tlsClientNew(strNew("localhost"), 9443, 500, true, strNew("bogus.crt"), strNew("/bogus"))), | ||||
|             tlsClientOpen(tlsClientNew(strNew("localhost"), TLS_TEST_PORT, 500, true, strNew("bogus.crt"), strNew("/bogus"))), | ||||
|             CryptoError, "unable to set user-defined CA certificate location: [33558530] No such file or directory"); | ||||
|         TEST_ERROR( | ||||
|             tlsClientOpen(tlsClientNew(strNew("localhost"), 9443, 500, true, NULL, strNew("/bogus"))), | ||||
|             CryptoError, "unable to verify certificate presented by 'localhost:9443': [20] unable to get local issuer certificate"); | ||||
|         TEST_ERROR_FMT( | ||||
|             tlsClientOpen(tlsClientNew(strNew("localhost"), TLS_TEST_PORT, 500, true, NULL, strNew("/bogus"))), | ||||
|             CryptoError, "unable to verify certificate presented by 'localhost:%d': [20] unable to get local issuer certificate", | ||||
|             TLS_TEST_PORT); | ||||
|  | ||||
|         TEST_RESULT_VOID( | ||||
|             tlsClientOpen( | ||||
|                 tlsClientNew(strNew("test.pgbackrest.org"), 9443, 500, true, | ||||
|                 strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)), | ||||
|             "success on valid ca file and match common name"); | ||||
|         TEST_RESULT_VOID( | ||||
|             tlsClientOpen( | ||||
|                 tlsClientNew(strNew("host.test2.pgbackrest.org"), 9443, 500, true, | ||||
|                 strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)), | ||||
|             "success on valid ca file and match alt name"); | ||||
|         TEST_ERROR( | ||||
|             tlsClientOpen( | ||||
|                 tlsClientNew(strNew("test3.pgbackrest.org"), 9443, 500, true, | ||||
|                 strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)), | ||||
|             CryptoError, "unable to find hostname 'test3.pgbackrest.org' in certificate common name or subject alternative names"); | ||||
|         if (testContainer()) | ||||
|         { | ||||
|             TEST_RESULT_VOID( | ||||
|                 tlsClientOpen( | ||||
|                     tlsClientNew(strNew("test.pgbackrest.org"), TLS_TEST_PORT, 500, true, | ||||
|                     strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)), | ||||
|                 "success on valid ca file and match common name"); | ||||
|             TEST_RESULT_VOID( | ||||
|                 tlsClientOpen( | ||||
|                     tlsClientNew(strNew("host.test2.pgbackrest.org"), TLS_TEST_PORT, 500, true, | ||||
|                     strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)), | ||||
|                 "success on valid ca file and match alt name"); | ||||
|             TEST_ERROR( | ||||
|                 tlsClientOpen( | ||||
|                     tlsClientNew(strNew("test3.pgbackrest.org"), TLS_TEST_PORT, 500, true, | ||||
|                     strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)), | ||||
|                 CryptoError, | ||||
|                 "unable to find hostname 'test3.pgbackrest.org' in certificate common name or subject alternative names"); | ||||
|         } | ||||
|  | ||||
|         TEST_ERROR( | ||||
|         TEST_ERROR_FMT( | ||||
|             tlsClientOpen( | ||||
|                 tlsClientNew(strNew("localhost"), 9443, 500, true, strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".crt", testRepoPath()), | ||||
|                 tlsClientNew( | ||||
|                     strNew("localhost"), TLS_TEST_PORT, 500, true, strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".crt", testRepoPath()), | ||||
|                 NULL)), | ||||
|             CryptoError, "unable to verify certificate presented by 'localhost:9443': [20] unable to get local issuer certificate"); | ||||
|             CryptoError, "unable to verify certificate presented by 'localhost:%d': [20] unable to get local issuer certificate", | ||||
|             TLS_TEST_PORT); | ||||
|  | ||||
|         TEST_RESULT_VOID( | ||||
|             tlsClientOpen(tlsClientNew(strNew("localhost"), 9443, 500, false, NULL, NULL)), "success on no verify"); | ||||
|             tlsClientOpen(tlsClientNew(strNew("localhost"), TLS_TEST_PORT, 500, false, NULL, NULL)), "success on no verify"); | ||||
|     } | ||||
|     // ***************************************************************************************************************************** | ||||
|     if (testBegin("TlsClient general usage")) | ||||
| @@ -201,7 +211,7 @@ testRun(void) | ||||
|         testTlsServer(); | ||||
|         ioBufferSizeSet(12); | ||||
|  | ||||
|         TEST_ASSIGN(client, tlsClientNew(strNew(TLS_TEST_HOST), 9443, 500, true, NULL, NULL), "new client"); | ||||
|         TEST_ASSIGN(client, tlsClientNew(harnessTlsTestHost(), TLS_TEST_PORT, 500, testContainer(), NULL, NULL), "new client"); | ||||
|         TEST_RESULT_VOID(tlsClientOpen(client), "open client"); | ||||
|  | ||||
|         const Buffer *input = BUFSTRDEF("some protocol info"); | ||||
| @@ -222,9 +232,9 @@ testRun(void) | ||||
|         TEST_RESULT_BOOL(ioReadEof(tlsClientIoRead(client)), false, "    check eof = false"); | ||||
|  | ||||
|         output = bufNew(12); | ||||
|         TEST_ERROR( | ||||
|         TEST_ERROR_FMT( | ||||
|             ioRead(tlsClientIoRead(client), output), FileReadError, | ||||
|             "timeout after 500ms waiting for read from 'tls.test.pgbackrest.org:9443'"); | ||||
|             "timeout after 500ms waiting for read from '%s:%d'", strPtr(harnessTlsTestHost()), TLS_TEST_PORT); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         input = BUFSTRDEF("more protocol info"); | ||||
|   | ||||
| @@ -59,7 +59,7 @@ testRun(void) | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         String *dirLock = strNewFmt("%s/dir" LOCK_FILE_EXT, testPath()); | ||||
|  | ||||
|         TEST_RESULT_INT(system(strPtr(strNewFmt("sudo mkdir -p 750 %s", strPtr(dirLock)))), 0, "create dirtest.lock dir"); | ||||
|         TEST_RESULT_INT(system(strPtr(strNewFmt("mkdir -p 750 %s", strPtr(dirLock)))), 0, "create dirtest.lock dir"); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             lockAcquireFile(dirLock, 0, true), LockAcquireError, | ||||
| @@ -67,7 +67,8 @@ testRun(void) | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         String *noPermLock = strNewFmt("%s/noperm/noperm", testPath()); | ||||
|         TEST_RESULT_INT(system(strPtr(strNewFmt("sudo mkdir -p 700 %s", strPtr(strPath(noPermLock))))), 0, "create noperm dir"); | ||||
|         TEST_RESULT_INT(system(strPtr(strNewFmt("mkdir -p 750 %s", strPtr(strPath(noPermLock))))), 0, "create noperm dir"); | ||||
|         TEST_RESULT_INT(system(strPtr(strNewFmt("chmod 000 %s", strPtr(strPath(noPermLock))))), 0, "chmod noperm dir"); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             lockAcquireFile(noPermLock, 100, true), LockAcquireError, | ||||
|   | ||||
| @@ -27,7 +27,7 @@ testRun(void) | ||||
|  | ||||
|         // Set repo1-cipher-pass to make sure it is not passed on the command line | ||||
|         setenv("PGBACKREST_REPO1_CIPHER_PASS", "1234", true); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|         unsetenv("PGBACKREST_REPO1_CIPHER_PASS"); | ||||
|  | ||||
|         TEST_RESULT_STR( | ||||
| @@ -52,7 +52,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "restore"); | ||||
|  | ||||
|         setenv("PGBACKREST_REPO1_HOST", "bogus", true); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|         unsetenv("PGBACKREST_REPO1_HOST"); | ||||
|  | ||||
|         KeyValue *optionReplace = kvNew(); | ||||
|   | ||||
| @@ -162,23 +162,19 @@ testRun(void) | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAdd(argList, strNew("pgbackrest")); | ||||
|         strLstAdd(argList, strNew("help")); | ||||
|         strLstAdd(argList, strNew("backup")); | ||||
|         strLstAdd(argList, strNew("process-max")); | ||||
|  | ||||
|         harnessLogLevelSet(logLevelWarn); | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(strLstSize(argList), strLstPtr(argList)), "load help config -- no retention warning"); | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(cfgCmdHelp, argList), "load help config -- no retention warning"); | ||||
|         TEST_RESULT_BOOL(cfgCommandHelp(), true, "    command is help"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAdd(argList, strNew("pgbackrest")); | ||||
|         strLstAdd(argList, strNew("--stanza=db")); | ||||
|         strLstAdd(argList, strNew("--no-log-timestamp")); | ||||
|         strLstAdd(argList, strNew("expire")); | ||||
|  | ||||
|         harnessLogLevelSet(logLevelWarn); | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(strLstSize(argList), strLstPtr(argList)), "load config for retention warning"); | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(cfgCmdExpire, argList), "load config for retention warning"); | ||||
|         harnessLogResult( | ||||
|             "P00   WARN: option repo1-retention-full is not set, the repository may run out of space\n" | ||||
|             "            HINT: to retain full backups indefinitely (without warning), set option" | ||||
| @@ -187,7 +183,7 @@ testRun(void) | ||||
|  | ||||
|         strLstAdd(argList, strNew("--repo1-retention-full=1")); | ||||
|  | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(strLstSize(argList), strLstPtr(argList)), "load config no retention warning"); | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(cfgCmdExpire, argList), "load config no retention warning"); | ||||
|         TEST_RESULT_INT(cfgOptionInt(cfgOptRepoRetentionArchive), 1, "    repo1-retention-archive set"); | ||||
|  | ||||
|         // Munge repo-type for coverage.  This will go away when there are multiple repos. | ||||
| @@ -195,13 +191,11 @@ testRun(void) | ||||
|         TEST_RESULT_VOID(cfgLoadUpdateOption(), "load config no repo-type"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAdd(argList, strNew("pgbackrest")); | ||||
|         strLstAdd(argList, strNew("--stanza=db")); | ||||
|         strLstAdd(argList, strNew("--no-log-timestamp")); | ||||
|         strLstAdd(argList, strNew("--repo1-retention-archive-type=incr")); | ||||
|         strLstAdd(argList, strNew("expire")); | ||||
|  | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(strLstSize(argList), strLstPtr(argList)), "load config for retention warning"); | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(cfgCmdExpire, argList), "load config for retention warning"); | ||||
|         harnessLogResult( | ||||
|             "P00   WARN: option repo1-retention-full is not set, the repository may run out of space\n" | ||||
|                 "            HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full'" | ||||
| @@ -211,13 +205,11 @@ testRun(void) | ||||
|         TEST_RESULT_BOOL(cfgOptionTest(cfgOptRepoRetentionArchive), false, "    repo1-retention-archive not set"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAdd(argList, strNew("pgbackrest")); | ||||
|         strLstAdd(argList, strNew("--stanza=db")); | ||||
|         strLstAdd(argList, strNew("--no-log-timestamp")); | ||||
|         strLstAdd(argList, strNew("--repo1-retention-archive-type=diff")); | ||||
|         strLstAdd(argList, strNew("expire")); | ||||
|  | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(strLstSize(argList), strLstPtr(argList)), "load config for retention warning"); | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(cfgCmdExpire, argList), "load config for retention warning"); | ||||
|         harnessLogResult( | ||||
|             "P00   WARN: option repo1-retention-full is not set, the repository may run out of space\n" | ||||
|             "            HINT: to retain full backups indefinitely (without warning), set option" | ||||
| @@ -228,7 +220,7 @@ testRun(void) | ||||
|  | ||||
|         strLstAdd(argList, strNew("--repo1-retention-diff=2")); | ||||
|  | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(strLstSize(argList), strLstPtr(argList)), "load config for retention warning"); | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(cfgCmdExpire, argList), "load config for retention warning"); | ||||
|         harnessLogResult( | ||||
|             "P00   WARN: option repo1-retention-full is not set, the repository may run out of space\n" | ||||
|             "            HINT: to retain full backups indefinitely (without warning), set option" | ||||
| @@ -236,31 +228,27 @@ testRun(void) | ||||
|         TEST_RESULT_INT(cfgOptionInt(cfgOptRepoRetentionArchive), 2, "    repo1-retention-archive set to retention-diff"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAdd(argList, strNew("pgbackrest")); | ||||
|         strLstAdd(argList, strNew("--stanza=db")); | ||||
|         strLstAdd(argList, strNew("--no-log-timestamp")); | ||||
|         strLstAdd(argList, strNew("--repo1-retention-archive-type=diff")); | ||||
|         strLstAdd(argList, strNew("--repo1-retention-archive=3")); | ||||
|         strLstAdd(argList, strNew("--repo1-retention-full=1")); | ||||
|         strLstAdd(argList, strNew("expire")); | ||||
|  | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(strLstSize(argList), strLstPtr(argList)), "load config for retention warning"); | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(cfgCmdExpire, argList), "load config for retention warning"); | ||||
|         harnessLogResult( | ||||
|             "P00   WARN: option 'repo1-retention-diff' is not set for 'repo1-retention-archive-type=diff'\n" | ||||
|             "            HINT: to retain differential backups indefinitely (without warning), set option 'repo1-retention-diff'" | ||||
|                 " to the maximum."); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAdd(argList, strNew("pgbackrest")); | ||||
|         strLstAdd(argList, strNew("--stanza=db")); | ||||
|         strLstAdd(argList, strNew("--no-log-timestamp")); | ||||
|         strLstAdd(argList, strNew("--repo1-retention-archive-type=diff")); | ||||
|         strLstAdd(argList, strNew("--repo1-retention-archive=3")); | ||||
|         strLstAdd(argList, strNew("--repo1-retention-diff=2")); | ||||
|         strLstAdd(argList, strNew("--repo1-retention-full=1")); | ||||
|         strLstAdd(argList, strNew("expire")); | ||||
|  | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(strLstSize(argList), strLstPtr(argList)), "load config with success"); | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(cfgCmdExpire, argList), "load config with success"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         setenv("PGBACKREST_REPO1_S3_KEY", "mykey", true); | ||||
| @@ -268,17 +256,15 @@ testRun(void) | ||||
|  | ||||
|         // Invalid bucket name with verification enabled fails | ||||
|         argList = strLstNew(); | ||||
|         strLstAdd(argList, strNew("pgbackrest")); | ||||
|         strLstAdd(argList, strNew("--stanza=db")); | ||||
|         strLstAdd(argList, strNew("--repo1-type=s3")); | ||||
|         strLstAdd(argList, strNew("--repo1-s3-bucket=bogus.bucket")); | ||||
|         strLstAdd(argList, strNew("--repo1-s3-region=region")); | ||||
|         strLstAdd(argList, strNew("--repo1-s3-endpoint=endpoint")); | ||||
|         strLstAdd(argList, strNew("--repo1-path=/repo")); | ||||
|         strLstAdd(argList, strNew("archive-get")); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             harnessCfgLoad(strLstSize(argList), strLstPtr(argList)), OptionInvalidValueError, | ||||
|             harnessCfgLoad(cfgCmdArchiveGet, argList), OptionInvalidValueError, | ||||
|             "'bogus.bucket' is not valid for option 'repo1-s3-bucket'" | ||||
|                 "\nHINT: RFC-2818 forbids dots in wildcard matches." | ||||
|                 "\nHINT: TLS/SSL verification cannot proceed with this bucket name." | ||||
| @@ -286,7 +272,6 @@ testRun(void) | ||||
|  | ||||
|         // Invalid bucket name with verification disabled succeeds | ||||
|         argList = strLstNew(); | ||||
|         strLstAdd(argList, strNew("pgbackrest")); | ||||
|         strLstAdd(argList, strNew("--stanza=db")); | ||||
|         strLstAdd(argList, strNew("--repo1-type=s3")); | ||||
|         strLstAdd(argList, strNew("--repo1-s3-bucket=bogus.bucket")); | ||||
| @@ -294,23 +279,20 @@ testRun(void) | ||||
|         strLstAdd(argList, strNew("--repo1-s3-endpoint=endpoint")); | ||||
|         strLstAdd(argList, strNew("--no-repo1-s3-verify-ssl")); | ||||
|         strLstAdd(argList, strNew("--repo1-path=/repo")); | ||||
|         strLstAdd(argList, strNew("archive-get")); | ||||
|  | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(strLstSize(argList), strLstPtr(argList)), "invalid bucket with no verification"); | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(cfgCmdArchiveGet, argList), "invalid bucket with no verification"); | ||||
|         TEST_RESULT_STR(strPtr(cfgOptionStr(cfgOptRepoS3Bucket)), "bogus.bucket", "    check bucket value"); | ||||
|  | ||||
|         // Valid bucket name | ||||
|         argList = strLstNew(); | ||||
|         strLstAdd(argList, strNew("pgbackrest")); | ||||
|         strLstAdd(argList, strNew("--stanza=db")); | ||||
|         strLstAdd(argList, strNew("--repo1-type=s3")); | ||||
|         strLstAdd(argList, strNew("--repo1-s3-bucket=cool-bucket")); | ||||
|         strLstAdd(argList, strNew("--repo1-s3-region=region")); | ||||
|         strLstAdd(argList, strNew("--repo1-s3-endpoint=endpoint")); | ||||
|         strLstAdd(argList, strNew("--repo1-path=/repo")); | ||||
|         strLstAdd(argList, strNew("archive-get")); | ||||
|  | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(strLstSize(argList), strLstPtr(argList)), "valid bucket name"); | ||||
|         TEST_RESULT_VOID(harnessCfgLoad(cfgCmdArchiveGet, argList), "valid bucket name"); | ||||
|         TEST_RESULT_STR(strPtr(cfgOptionStr(cfgOptRepoS3Bucket)), "cool-bucket", "    check bucket value"); | ||||
|  | ||||
|         unsetenv("PGBACKREST_REPO1_S3_KEY"); | ||||
| @@ -324,6 +306,7 @@ testRun(void) | ||||
|         strLstAdd(argList, strNew("pgbackrest")); | ||||
|         strLstAdd(argList, strNew("--stanza=db")); | ||||
|         strLstAdd(argList, strNew("--pg1-path=/path")); | ||||
|         strLstAdd(argList, strNewFmt("--lock-path=%s/lock", testDataPath())); | ||||
|         strLstAdd(argList, strNew("--log-path=/bogus")); | ||||
|         strLstAdd(argList, strNew("--log-level-file=info")); | ||||
|         strLstAdd(argList, strNew("backup")); | ||||
| @@ -415,6 +398,7 @@ testRun(void) | ||||
|         strLstAdd(argList, strNew("--stanza=db")); | ||||
|         strLstAdd(argList, strNew("--pg1-path=/path")); | ||||
|         strLstAdd(argList, strNew("--repo1-retention-full=1")); | ||||
|         strLstAdd(argList, strNewFmt("--lock-path=%s/lock", testDataPath())); | ||||
|         strLstAdd(argList, strNewFmt("--log-path=%s", testPath())); | ||||
|         strLstAdd(argList, strNew("--log-level-console=off")); | ||||
|         strLstAdd(argList, strNew("--log-level-stderr=off")); | ||||
|   | ||||
| @@ -475,7 +475,7 @@ testRun(void) | ||||
|         // config default and config-include-path passed - but no config files in the include path - only in the default path | ||||
|         // rm command is split below because code counter is confused by what looks like a comment. | ||||
|         //-------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_RESULT_INT(system(strPtr(strNewFmt("sudo rm -rf %s/" "*", strPtr(configIncludePath)))), 0, "remove all include files"); | ||||
|         TEST_RESULT_INT(system(strPtr(strNewFmt("rm -rf %s/" "*", strPtr(configIncludePath)))), 0, "remove all include files"); | ||||
|  | ||||
|         value = strLstNew(); | ||||
|         strLstAdd(value, configIncludePath); | ||||
|   | ||||
| @@ -30,12 +30,10 @@ testRun(void) | ||||
|                 ioWriteOpen(write); | ||||
|  | ||||
|                 StringList *argList = strLstNew(); | ||||
|                 strLstAddZ(argList, "pgbackrest"); | ||||
|                 strLstAddZ(argList, "--stanza=test1"); | ||||
|                 strLstAddZ(argList, "--repo1-host=repo-host"); | ||||
|                 strLstAddZ(argList, "--repo1-host-user=repo-host-user"); | ||||
|                 strLstAddZ(argList, "archive-get"); | ||||
|                 harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|                 harnessCfgLoad(cfgCmdArchiveGet, argList); | ||||
|  | ||||
|                 ProtocolServer *server = protocolServerNew(strNew("test"), strNew("config"), read, write); | ||||
|                 protocolServerHandlerAdd(server, configProtocol); | ||||
|   | ||||
| @@ -31,14 +31,12 @@ testRun(void) | ||||
|  | ||||
|                 // Set options | ||||
|                 StringList *argList = strLstNew(); | ||||
|                 strLstAddZ(argList, "pgbackrest"); | ||||
|                 strLstAddZ(argList, "--stanza=test1"); | ||||
|                 strLstAddZ(argList, "--pg1-path=/path/to/pg"); | ||||
|                 strLstAddZ(argList, "--command=backup"); | ||||
|                 strLstAddZ(argList, "--type=db"); | ||||
|                 strLstAddZ(argList, "--process=0"); | ||||
|                 strLstAddZ(argList, "remote"); | ||||
|                 harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|                 harnessCfgLoad(cfgCmdRemote, argList); | ||||
|  | ||||
|                 // Set script | ||||
|                 harnessPqScriptSet((HarnessPq []) | ||||
| @@ -106,12 +104,10 @@ testRun(void) | ||||
|         // Error connecting to primary | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "--repo1-retention-full=1"); | ||||
|         strLstAddZ(argList, "--pg1-path=/path/to/pg"); | ||||
|         strLstAddZ(argList, "backup"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdBackup, argList); | ||||
|  | ||||
|         harnessPqScriptSet((HarnessPq []) | ||||
|         { | ||||
| @@ -164,14 +160,12 @@ testRun(void) | ||||
|         // More than one primary found | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "--repo1-retention-full=1"); | ||||
|         strLstAddZ(argList, "--pg1-path=/path/to/pg1"); | ||||
|         strLstAddZ(argList, "--pg8-path=/path/to/pg2"); | ||||
|         strLstAddZ(argList, "--pg8-port=5433"); | ||||
|         strLstAddZ(argList, "backup"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdBackup, argList); | ||||
|  | ||||
|         harnessPqScriptSet((HarnessPq []) | ||||
|         { | ||||
| @@ -226,7 +220,6 @@ testRun(void) | ||||
|         // Primary and standby found | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "--repo1-retention-full=1"); | ||||
|         strLstAddZ(argList, "--pg1-path=/path/to/pg1"); | ||||
| @@ -237,8 +230,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--pg5-path=/path/to/pg5"); | ||||
|         strLstAddZ(argList, "--pg8-path=/path/to/pg8"); | ||||
|         strLstAddZ(argList, "--pg8-port=5434"); | ||||
|         strLstAddZ(argList, "backup"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdBackup, argList); | ||||
|  | ||||
|         harnessPqScriptSet((HarnessPq []) | ||||
|         { | ||||
|   | ||||
| @@ -106,7 +106,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_RESULT_BOOL(repoIsLocal(), true, "repo is local"); | ||||
|         TEST_RESULT_VOID(repoIsLocalVerify(), "    local verified"); | ||||
| @@ -117,7 +117,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "--repo1-host=remote-host"); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_RESULT_BOOL(repoIsLocal(), false, "repo is remote"); | ||||
|         TEST_ERROR_FMT(repoIsLocalVerify(), HostInvalidError, "archive-get command must be run on the repository host"); | ||||
| @@ -129,7 +129,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--pg1-path=/path/to"); | ||||
|         strLstAddZ(argList, "--repo1-retention-full=1"); | ||||
|         strLstAddZ(argList, "backup"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_RESULT_BOOL(pgIsLocal(1), true, "pg is local"); | ||||
|  | ||||
| @@ -144,7 +144,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--type=db"); | ||||
|         strLstAddZ(argList, "--process=0"); | ||||
|         strLstAddZ(argList, "local"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_RESULT_BOOL(pgIsLocal(7), false, "pg is remote"); | ||||
|     } | ||||
| @@ -156,7 +156,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_RESULT_STR( | ||||
|             strPtr(strLstJoin(protocolLocalParam(protocolStorageTypeRepo, 0), "|")), | ||||
| @@ -172,7 +172,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--stanza=test1"); | ||||
|         strLstAddZ(argList, "--log-subprocess"); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_RESULT_STR( | ||||
|             strPtr(strLstJoin(protocolLocalParam(protocolStorageTypeRepo, 1), "|")), | ||||
| @@ -198,7 +198,7 @@ testRun(void) | ||||
|         strLstAdd(argList, strNewFmt("--config-include-path=%s", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--config-path=%s", testPath())); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_RESULT_STR( | ||||
|             strPtr(strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 0, 0), "|")), | ||||
| @@ -221,7 +221,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--repo1-host-config-path=/path/config"); | ||||
|         strLstAddZ(argList, "--repo1-host-user=repo-host-user"); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_RESULT_STR( | ||||
|             strPtr(strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 1, 0), "|")), | ||||
| @@ -243,7 +243,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--type=backup"); | ||||
|         strLstAddZ(argList, "--repo1-host=repo-host"); | ||||
|         strLstAddZ(argList, "local"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_RESULT_STR( | ||||
|             strPtr(strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 66, 0), "|")), | ||||
| @@ -262,7 +262,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--pg1-host=pg1-host"); | ||||
|         strLstAddZ(argList, "--repo1-retention-full=1"); | ||||
|         strLstAddZ(argList, "backup"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_RESULT_STR( | ||||
|             strPtr(strLstJoin(protocolRemoteParam(protocolStorageTypePg, 1, 0), "|")), | ||||
| @@ -287,7 +287,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--pg2-host=pg2-host"); | ||||
|         strLstAddZ(argList, "--type=db"); | ||||
|         strLstAddZ(argList, "local"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_RESULT_STR( | ||||
|             strPtr(strLstJoin(protocolRemoteParam(protocolStorageTypePg, 1, 1), "|")), | ||||
| @@ -312,7 +312,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--pg3-port=3333"); | ||||
|         strLstAddZ(argList, "--type=db"); | ||||
|         strLstAddZ(argList, "local"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); | ||||
|  | ||||
|         TEST_RESULT_STR( | ||||
|             strPtr(strLstJoin(protocolRemoteParam(protocolStorageTypePg, 1, 2), "|")), | ||||
| @@ -790,13 +790,11 @@ testRun(void) | ||||
|         // Simple protocol start | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "/usr/bin/pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "--protocol-timeout=10"); | ||||
|         strLstAddZ(argList, "--repo1-host=localhost"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", testPath())); | ||||
|         strLstAddZ(argList, "info"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList); | ||||
|  | ||||
|         ProtocolClient *client = NULL; | ||||
|  | ||||
| @@ -819,7 +817,6 @@ testRun(void) | ||||
|                 "repo1-cipher-pass=acbd\n")); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "/usr/bin/pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "--protocol-timeout=10"); | ||||
|         strLstAdd(argList, strNewFmt("--config=%s/pgbackrest.conf", testPath())); | ||||
| @@ -829,8 +826,7 @@ testRun(void) | ||||
|         strLstAddZ(argList, "--command=archive-get"); | ||||
|         strLstAddZ(argList, "--host-id=1"); | ||||
|         strLstAddZ(argList, "--type=db"); | ||||
|         strLstAddZ(argList, "local"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdLocal, argList); | ||||
|  | ||||
|         TEST_RESULT_STR(strPtr(cfgOptionStr(cfgOptRepoCipherPass)), "acbd", "check cipher pass before"); | ||||
|         TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypeRepo, 1), "get remote protocol"); | ||||
| @@ -849,14 +845,12 @@ testRun(void) | ||||
|                 "repo1-cipher-pass=dcba\n")); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "/usr/bin/pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "--protocol-timeout=10"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-host-config=%s/pgbackrest.conf", testPath())); | ||||
|         strLstAddZ(argList, "--repo1-host=localhost"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", testPath())); | ||||
|         strLstAddZ(argList, "info"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList); | ||||
|  | ||||
|         TEST_RESULT_PTR(cfgOptionStr(cfgOptRepoCipherPass), NULL, "check cipher pass before"); | ||||
|         TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypeRepo, 1), "get remote protocol"); | ||||
| @@ -867,27 +861,23 @@ testRun(void) | ||||
|         // Start db protocol | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "/usr/bin/pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "--protocol-timeout=10"); | ||||
|         strLstAddZ(argList, "--repo1-retention-full=1"); | ||||
|         strLstAddZ(argList, "--pg1-host=localhost"); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-host-user=%s", testUser())); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s", testPath())); | ||||
|         strLstAddZ(argList, "backup"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdBackup, argList); | ||||
|  | ||||
|         TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypePg, 1), "get remote protocol"); | ||||
|  | ||||
|         // Start local protocol | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "/usr/bin/pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "--protocol-timeout=10"); | ||||
|         strLstAddZ(argList, "--process-max=2"); | ||||
|         strLstAddZ(argList, "archive-get-async"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGetAsync, argList); | ||||
|  | ||||
|         TEST_ASSIGN(client, protocolLocalGet(protocolStorageTypeRepo, 1), "get local protocol"); | ||||
|         TEST_RESULT_PTR(protocolLocalGet(protocolStorageTypeRepo, 1), client, "get local cached protocol"); | ||||
|   | ||||
| @@ -16,12 +16,10 @@ testRun(void) | ||||
|     { | ||||
|         // Load configuration | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "--repo1-type=cifs"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", testPath())); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGet, argList); | ||||
|  | ||||
|         const Storage *storage = NULL; | ||||
|         TEST_ASSIGN(storage, storageRepoGet(strNew(STORAGE_TYPE_CIFS), true), "get cifs repo storage"); | ||||
|   | ||||
| @@ -1059,11 +1059,9 @@ testRun(void) | ||||
|     { | ||||
|         // Load configuration to set repo-path and stanza | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAdd(argList, strNewFmt("--repo-path=%s", testPath())); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGet, argList); | ||||
|  | ||||
|         TEST_ERROR(storageRepoGet(strNew(BOGUS_STR), false), AssertError, "invalid storage type 'BOGUS'"); | ||||
|  | ||||
| @@ -1103,10 +1101,8 @@ testRun(void) | ||||
|         // Change the stanza to NULL with the stanzaInit flag still true, make sure helper does not fail when stanza option not set | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAdd(argList, strNewFmt("--repo-path=%s", testPath())); | ||||
|         strLstAddZ(argList, "info"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList); | ||||
|  | ||||
|         TEST_ASSIGN(storage, storageRepo(), "new repo storage no stanza"); | ||||
|         TEST_RESULT_PTR(storageHelper.stanza, NULL, "stanza NULL"); | ||||
| @@ -1140,14 +1136,12 @@ testRun(void) | ||||
|  | ||||
|         // Load configuration to set spool-path and stanza | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "--archive-async"); | ||||
|         strLstAdd(argList, strNewFmt("--spool-path=%s", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--pg1-path=%s/db", testPath())); | ||||
|         strLstAdd(argList, strNewFmt("--pg2-path=%s/db2", testPath())); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGet, argList); | ||||
|  | ||||
|         TEST_RESULT_PTR(storageHelper.storageSpool, NULL, "storage not cached"); | ||||
|         TEST_ASSIGN(storage, storageSpool(), "new storage"); | ||||
| @@ -1217,10 +1211,8 @@ testRun(void) | ||||
|         storageHelper.stanza = NULL; | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAdd(argList, strNewFmt("--repo-path=%s", testPath())); | ||||
|         strLstAddZ(argList, "info"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdInfo, argList); | ||||
|  | ||||
|         TEST_ERROR(storageSpool(), AssertError, "stanza cannot be NULL for this storage object"); | ||||
|         TEST_ERROR(storageSpoolWrite(), AssertError, "stanza cannot be NULL for this storage object"); | ||||
|   | ||||
| @@ -23,14 +23,12 @@ testRun(void) | ||||
|  | ||||
|     // Load configuration to set repo-path and stanza | ||||
|     StringList *argList = strLstNew(); | ||||
|     strLstAddZ(argList, "/usr/bin/pgbackrest"); | ||||
|     strLstAddZ(argList, "--stanza=db"); | ||||
|     strLstAddZ(argList, "--protocol-timeout=10"); | ||||
|     strLstAddZ(argList, "--buffer-size=16384"); | ||||
|     strLstAddZ(argList, "--repo1-host=localhost"); | ||||
|     strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath())); | ||||
|     strLstAddZ(argList, "info"); | ||||
|     harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|     harnessCfgLoad(cfgCmdInfo, argList); | ||||
|  | ||||
|     // Set type since we'll be running local and remote tests here | ||||
|     cfgOptionSet(cfgOptType, cfgSourceParam, VARSTRDEF("backup")); | ||||
|   | ||||
| @@ -82,7 +82,7 @@ testS3Server(void) | ||||
| { | ||||
|     if (fork() == 0) | ||||
|     { | ||||
|         harnessTlsServerInit(TLS_TEST_PORT, TLS_CERT_TEST_CERT, TLS_CERT_TEST_KEY); | ||||
|         harnessTlsServerInitDefault(); | ||||
|         harnessTlsServerAccept(); | ||||
|  | ||||
|         // storageS3NewRead() and StorageS3FileRead | ||||
| @@ -509,7 +509,7 @@ testRun(void) | ||||
|     const String *bucket = strNew("bucket"); | ||||
|     const String *region = strNew("us-east-1"); | ||||
|     const String *endPoint = strNew("s3.amazonaws.com"); | ||||
|     const String *host = strNew(TLS_TEST_HOST); | ||||
|     const String *host = harnessTlsTestHost(); | ||||
|     const unsigned int port = TLS_TEST_PORT; | ||||
|     const String *accessKey = strNew("AKIAIOSFODNN7EXAMPLE"); | ||||
|     const String *secretAccessKey = strNew("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"); | ||||
| @@ -524,7 +524,6 @@ testRun(void) | ||||
|         // Only required options | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         StringList *argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "--repo1-type=s3"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(path))); | ||||
| @@ -533,8 +532,7 @@ testRun(void) | ||||
|         strLstAdd(argList, strNewFmt("--repo1-s3-endpoint=%s", strPtr(endPoint))); | ||||
|         setenv("PGBACKREST_REPO1_S3_KEY", strPtr(accessKey), true); | ||||
|         setenv("PGBACKREST_REPO1_S3_KEY_SECRET", strPtr(secretAccessKey), true); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGet, argList); | ||||
|  | ||||
|         Storage *storage = NULL; | ||||
|         TEST_ASSIGN(storage, storageRepoGet(strNew(STORAGE_TYPE_S3), false), "get S3 repo storage"); | ||||
| @@ -554,7 +552,6 @@ testRun(void) | ||||
|         // Add default options | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "--repo1-type=s3"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(path))); | ||||
| @@ -567,8 +564,7 @@ testRun(void) | ||||
|         setenv("PGBACKREST_REPO1_S3_KEY", strPtr(accessKey), true); | ||||
|         setenv("PGBACKREST_REPO1_S3_KEY_SECRET", strPtr(secretAccessKey), true); | ||||
|         setenv("PGBACKREST_REPO1_S3_TOKEN", strPtr(securityToken), true); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGet, argList); | ||||
|  | ||||
|         TEST_ASSIGN(storage, storageRepoGet(strNew(STORAGE_TYPE_S3), false), "get S3 repo storage with options"); | ||||
|         TEST_RESULT_STR(strPtr(((StorageS3 *)storage->driver)->bucket), strPtr(bucket), "    check bucket"); | ||||
| @@ -586,7 +582,6 @@ testRun(void) | ||||
|         // Add a port to the endpoint | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "--repo1-type=s3"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(path))); | ||||
| @@ -598,8 +593,7 @@ testRun(void) | ||||
|         setenv("PGBACKREST_REPO1_S3_KEY", strPtr(accessKey), true); | ||||
|         setenv("PGBACKREST_REPO1_S3_KEY_SECRET", strPtr(secretAccessKey), true); | ||||
|         setenv("PGBACKREST_REPO1_S3_TOKEN", strPtr(securityToken), true); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGet, argList); | ||||
|  | ||||
|         TEST_ASSIGN(storage, storageRepoGet(strNew(STORAGE_TYPE_S3), false), "get S3 repo storage with options"); | ||||
|         TEST_RESULT_STR(strPtr(((StorageS3 *)storage->driver)->bucket), strPtr(bucket), "    check bucket"); | ||||
| @@ -617,7 +611,6 @@ testRun(void) | ||||
|         // Also add port to the host | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "--repo1-type=s3"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(path))); | ||||
| @@ -630,8 +623,7 @@ testRun(void) | ||||
|         setenv("PGBACKREST_REPO1_S3_KEY", strPtr(accessKey), true); | ||||
|         setenv("PGBACKREST_REPO1_S3_KEY_SECRET", strPtr(secretAccessKey), true); | ||||
|         setenv("PGBACKREST_REPO1_S3_TOKEN", strPtr(securityToken), true); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGet, argList); | ||||
|  | ||||
|         TEST_ASSIGN(storage, storageRepoGet(strNew(STORAGE_TYPE_S3), false), "get S3 repo storage with options"); | ||||
|         TEST_RESULT_STR(strPtr(((StorageS3 *)storage->driver)->bucket), strPtr(bucket), "    check bucket"); | ||||
| @@ -649,7 +641,6 @@ testRun(void) | ||||
|         // Use the port option to override both | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
|         strLstAddZ(argList, "pgbackrest"); | ||||
|         strLstAddZ(argList, "--stanza=db"); | ||||
|         strLstAddZ(argList, "--repo1-type=s3"); | ||||
|         strLstAdd(argList, strNewFmt("--repo1-path=%s", strPtr(path))); | ||||
| @@ -663,8 +654,7 @@ testRun(void) | ||||
|         setenv("PGBACKREST_REPO1_S3_KEY", strPtr(accessKey), true); | ||||
|         setenv("PGBACKREST_REPO1_S3_KEY_SECRET", strPtr(secretAccessKey), true); | ||||
|         setenv("PGBACKREST_REPO1_S3_TOKEN", strPtr(securityToken), true); | ||||
|         strLstAddZ(argList, "archive-get"); | ||||
|         harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); | ||||
|         harnessCfgLoad(cfgCmdArchiveGet, argList); | ||||
|  | ||||
|         TEST_ASSIGN(storage, storageRepoGet(strNew(STORAGE_TYPE_S3), false), "get S3 repo storage with options"); | ||||
|         TEST_RESULT_STR(strPtr(((StorageS3 *)storage->driver)->bucket), strPtr(bucket), "    check bucket"); | ||||
| @@ -688,7 +678,8 @@ testRun(void) | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         StorageS3 *driver = (StorageS3 *)storageDriver( | ||||
|             storageS3New( | ||||
|                 path, true, NULL, bucket, endPoint, region, accessKey, secretAccessKey, NULL, 16, 2, NULL, 0, 0, true, NULL, NULL)); | ||||
|                 path, true, NULL, bucket, endPoint, region, accessKey, secretAccessKey, NULL, 16, 2, NULL, 0, 0, testContainer(), | ||||
|                 NULL, NULL)); | ||||
|  | ||||
|         HttpHeader *header = httpHeaderNew(NULL); | ||||
|  | ||||
| @@ -735,8 +726,8 @@ testRun(void) | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         driver = (StorageS3 *)storageDriver( | ||||
|             storageS3New( | ||||
|                 path, true, NULL, bucket, endPoint, region, accessKey, secretAccessKey, securityToken, 16, 2, NULL, 0, 0, true, | ||||
|                 NULL, NULL)); | ||||
|                 path, true, NULL, bucket, endPoint, region, accessKey, secretAccessKey, securityToken, 16, 2, NULL, 0, 0, | ||||
|                 testContainer(), NULL, NULL)); | ||||
|  | ||||
|         TEST_RESULT_VOID( | ||||
|             storageS3Auth(driver, strNew("GET"), strNew("/"), query, strNew("20170606T121212Z"), header, HASH_TYPE_SHA256_ZERO_STR), | ||||
| @@ -755,8 +746,8 @@ testRun(void) | ||||
|         testS3Server(); | ||||
|  | ||||
|         Storage *s3 = storageS3New( | ||||
|             path, true, NULL, bucket, endPoint, region, accessKey, secretAccessKey, NULL, 16, 2, host, port, 1000, true, NULL, | ||||
|             NULL); | ||||
|             path, true, NULL, bucket, endPoint, region, accessKey, secretAccessKey, NULL, 16, 2, host, port, 1000, testContainer(), | ||||
|             NULL, NULL); | ||||
|  | ||||
|         // Coverage for noop functions | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|   | ||||
| @@ -30,7 +30,10 @@ The test code is included directly so it can freely interact with the included C | ||||
| #include "common/harnessDebug.h" | ||||
| #include "common/harnessTest.h" | ||||
|  | ||||
| extern void testScaleSet(uint64_t testScale); | ||||
| void testContainerSet(bool testContainer); | ||||
| void testDataPathSet(const char *testDataPath); | ||||
| void testScaleSet(uint64_t testScale); | ||||
| void testProjectExeSet(const char *testProjectExe); | ||||
|  | ||||
| #ifndef NO_LOG | ||||
|     #include "common/harnessLog.h" | ||||
| @@ -80,9 +83,11 @@ main(int argListSize, const char *argList[]) | ||||
|  | ||||
|     // Set globals | ||||
|     testExeSet(argList[0]); | ||||
|     testProjectExeSet("{[C_TEST_PROJECT_EXE]}"); | ||||
|     testContainerSet({[C_TEST_CONTAINER]}); | ||||
|     testPathSet("{[C_TEST_PATH]}"); | ||||
|     testRepoPathSet("{[C_TEST_REPO_PATH]}"); | ||||
|     testExpectPathSet("{[C_TEST_EXPECT_PATH]}"); | ||||
|     testDataPathSet("{[C_TEST_DATA_PATH]}"); | ||||
|     testScaleSet({[C_TEST_SCALE]}); | ||||
|  | ||||
|     // Set default test log level | ||||
|   | ||||
							
								
								
									
										50
									
								
								test/test.pl
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								test/test.pl
									
									
									
									
									
								
							| @@ -81,6 +81,7 @@ test.pl [options] | ||||
|    --build-max          max processes to use for builds (default 4) | ||||
|    --coverage-only      only run coverage tests (as a subset of selected tests) | ||||
|    --c-only             only run C tests | ||||
|    --container-only     only run tests that must be run in a container | ||||
|    --gen-only           only run auto-generation | ||||
|    --no-gen             do not run code generation | ||||
|    --code-count         generate code counts | ||||
| @@ -151,6 +152,7 @@ my $bCoverageOnly = false; | ||||
| my $bCoverageSummary = false; | ||||
| my $bNoCoverage = false; | ||||
| my $bCOnly = false; | ||||
| my $bContainerOnly = false; | ||||
| my $bGenOnly = false; | ||||
| my $bNoGen = false; | ||||
| my $bCodeCount = false; | ||||
| @@ -200,6 +202,7 @@ GetOptions ('q|quiet' => \$bQuiet, | ||||
|             'coverage-summary' => \$bCoverageSummary, | ||||
|             'no-coverage' => \$bNoCoverage, | ||||
|             'c-only' => \$bCOnly, | ||||
|             'container-only' => \$bContainerOnly, | ||||
|             'gen-only' => \$bGenOnly, | ||||
|             'no-gen' => \$bNoGen, | ||||
|             'code-count' => \$bCodeCount, | ||||
| @@ -711,13 +714,16 @@ eval | ||||
|         my $iTestFail = 0; | ||||
|         my $iTestRetry = 0; | ||||
|         my $oyProcess = []; | ||||
|         my $strCoveragePath = "${strTestPath}/cover_db"; | ||||
|         my $strCodePath = "${strBackRestBase}/test/.vagrant/code"; | ||||
|  | ||||
|         if (!$bDryRun || $bVmOut) | ||||
|         { | ||||
|             &log(INFO, "cleanup old data and containers"); | ||||
|             containerRemove('test-([0-9]+|build)'); | ||||
|             &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++) | ||||
|             { | ||||
| @@ -725,9 +731,9 @@ eval | ||||
|             } | ||||
|  | ||||
|             executeTest( | ||||
|                 "sudo rm -rf ${strTestPath}/cover_db ${strTestPath}/test-* ${strTestPath}/expect-*" . | ||||
|                 "sudo rm -rf ${strTestPath}/test-* ${strTestPath}/data-*" . | ||||
|                 ($bDev ? '' : " ${strTestPath}/gcov-*")); | ||||
|             $oStorageTest->pathCreate($strCoveragePath, {strMode => '0770', bIgnoreExists => true, bCreateParent => true}); | ||||
|             $oStorageTest->pathCreate($strTestPath, {strMode => '0770', bIgnoreExists => true, bCreateParent => true}); | ||||
|  | ||||
|             # Remove old coverage dirs -- do it this way so the dirs stay open in finder/explorer, etc. | ||||
|             executeTest("rm -rf ${strBackRestBase}/test/coverage/c/*"); | ||||
| @@ -760,7 +766,7 @@ eval | ||||
|         { | ||||
|             # Get the test list | ||||
|             $oyTestRun = testListGet( | ||||
|                 $strVm, \@stryModule, \@stryModuleTest, \@iyModuleTestRun, $strPgVersion, $bCoverageOnly, $bCOnly); | ||||
|                 $strVm, \@stryModule, \@stryModuleTest, \@iyModuleTestRun, $strPgVersion, $bCoverageOnly, $bCOnly, $bContainerOnly); | ||||
|  | ||||
|             # Determine if the C binary and test library need to be built | ||||
|             foreach my $hTest (@{$oyTestRun}) | ||||
| @@ -869,10 +875,13 @@ eval | ||||
|                     { | ||||
|                         &log(INFO, "    build bin for ${strBuildVM} (${strBuildPath})"); | ||||
|  | ||||
|                         executeTest( | ||||
|                             "docker run -itd -h test-build --name=test-build" . | ||||
|                             " -v ${strBackRestBase}:${strBackRestBase} " . containerRepo() . ":${strBuildVM}-build", | ||||
|                             {bSuppressStdErr => true}); | ||||
|                         if ($strBuildVM ne VM_NONE) | ||||
|                         { | ||||
|                             executeTest( | ||||
|                                 "docker run -itd -h test-build --name=test-build" . | ||||
|                                 " -v ${strBackRestBase}:${strBackRestBase} " . containerRepo() . ":${strBuildVM}-build", | ||||
|                                 {bSuppressStdErr => true}); | ||||
|                         } | ||||
|  | ||||
|                         foreach my $strBinSrcPath (@stryBinSrcPath) | ||||
|                         { | ||||
| @@ -889,17 +898,21 @@ eval | ||||
|                         if ($bBuildOptionsDiffer || !$oStorageBackRest->exists("${strBuildPath}/Makefile")) | ||||
|                         { | ||||
|                             executeTest( | ||||
|                                 "docker exec -i test-build bash -c 'cd ${strBuildPath} && ./configure${strConfigOptions}'", | ||||
|                                 ($strBuildVM ne VM_NONE ? 'docker exec -i test-build ' : '') . | ||||
|                                 "bash -c 'cd ${strBuildPath} && ./configure${strConfigOptions}'", | ||||
|                                 {bShowOutputAsync => $bLogDetail}); | ||||
|                         } | ||||
|  | ||||
|                         executeTest( | ||||
|                             'docker exec -i test-build' . | ||||
|                             " make -j ${iBuildMax}" . ($bLogDetail ? '' : ' --silent') . | ||||
|                             ($strBuildVM ne VM_NONE ? 'docker exec -i test-build ' : '') . | ||||
|                             "make -j ${iBuildMax}" . ($bLogDetail ? '' : ' --silent') . | ||||
|                                 " --directory ${strBuildPath} CFLAGS='${strCFlags}' LDFLAGS='${strLdFlags}'", | ||||
|                             {bShowOutputAsync => $bLogDetail}); | ||||
|  | ||||
|                         executeTest("docker rm -f test-build"); | ||||
|                         if ($strBuildVM ne VM_NONE) | ||||
|                         { | ||||
|                             executeTest("docker rm -f test-build"); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| @@ -908,6 +921,11 @@ eval | ||||
|             #----------------------------------------------------------------------------------------------------------------------- | ||||
|             if ($bLibCHostRequired || $bLibCVmRequired) | ||||
|             { | ||||
|                 if ($strVm eq VM_NONE) | ||||
|                 { | ||||
|                     confess &log(ASSERT, "c library build not yet supported for vm=none"); | ||||
|                 } | ||||
|  | ||||
|                 my $strLibCPath = "${strVagrantPath}/bin"; | ||||
|  | ||||
|                 # Loop through VMs to do the C Library builds | ||||
| @@ -1026,7 +1044,7 @@ eval | ||||
|  | ||||
|             # Build the package | ||||
|             #----------------------------------------------------------------------------------------------------------------------- | ||||
|             if (!$bNoPackage) | ||||
|             if (!$bNoPackage && $strVm ne VM_NONE) | ||||
|             { | ||||
|                 my $strPackagePath = "${strVagrantPath}/package"; | ||||
|                 my $strPackageSmart = "${strPackagePath}/build.timestamp"; | ||||
| @@ -1301,7 +1319,7 @@ eval | ||||
|                 if (!defined($$oyProcess[$iVmIdx]) && $iTestIdx < @{$oyTestRun}) | ||||
|                 { | ||||
|                     my $oJob = new pgBackRestTest::Common::JobTest( | ||||
|                         $oStorageTest, $strBackRestBase, $strTestPath, $strCoveragePath, $$oyTestRun[$iTestIdx], $bDryRun, $bVmOut, | ||||
|                         $oStorageTest, $strBackRestBase, $strTestPath, $$oyTestRun[$iTestIdx], $bDryRun, $bVmOut, | ||||
|                         $iVmIdx, $iVmMax, $iTestIdx, $iTestMax, $strLogLevel, $strLogLevelTest, $bLogForce, $bShowOutputAsync, | ||||
|                         $bNoCleanup, $iRetry, !$bNoValgrind, !$bNoCoverage, $bCoverageSummary, !$bNoOptimize, $bBackTrace, | ||||
|                         $bProfile, $iScale, !$bNoDebug, $bDebugTestTrace, $iBuildMax / $iVmMax < 1 ? 1 : int($iBuildMax / $iVmMax)); | ||||
|   | ||||
| @@ -70,9 +70,18 @@ sub processBegin | ||||
|     $lProcessBegin = time(); | ||||
| } | ||||
|  | ||||
| sub processExec | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $rhParam = shift; | ||||
|  | ||||
|     &log(INFO, "    Exec ${strCommand}"); | ||||
|     executeTest($strCommand, $rhParam); | ||||
| } | ||||
|  | ||||
| sub processEnd | ||||
| { | ||||
|     &log(INFO, "End ${strProcessTitle} (" . (time() - $lProcessBegin) . 's)'); | ||||
|     &log(INFO, "    End ${strProcessTitle} (" . (time() - $lProcessBegin) . 's)'); | ||||
| } | ||||
|  | ||||
| #################################################################################################################################### | ||||
| @@ -97,6 +106,12 @@ eval | ||||
|         pod2usage(); | ||||
|     } | ||||
|  | ||||
|     # VM must be defined | ||||
|     if (!defined($strVm)) | ||||
|     { | ||||
|         confess &log(ERROR, '--vm is required'); | ||||
|     } | ||||
|  | ||||
|     ################################################################################################################################ | ||||
|     # Paths | ||||
|     ################################################################################################################################ | ||||
| @@ -111,15 +126,18 @@ eval | ||||
|     ################################################################################################################################ | ||||
|     if ($ARGV[0] eq 'doc') | ||||
|     { | ||||
|         processBegin('LaTeX install'); | ||||
|         executeTest( | ||||
|             'sudo apt-get install -y --no-install-recommends texlive-latex-base texlive-latex-extra texlive-fonts-recommended', | ||||
|             {bSuppressStdErr => true}); | ||||
|         executeTest('sudo apt-get install -y texlive-font-utils latex-xcolor', {bSuppressStdErr => true}); | ||||
|         processEnd(); | ||||
|         if ($strVm eq VM_CO7) | ||||
|         { | ||||
|             processBegin('LaTeX install'); | ||||
|             processExec( | ||||
|                 'sudo apt-get install -y --no-install-recommends texlive-latex-base texlive-latex-extra texlive-fonts-recommended', | ||||
|                 {bSuppressStdErr => true}); | ||||
|             processExec('sudo apt-get install -y texlive-font-utils latex-xcolor', {bSuppressStdErr => true}); | ||||
|             processEnd(); | ||||
|         } | ||||
|  | ||||
|         processBegin('release documentation doc'); | ||||
|         executeTest("${strReleaseExe} --build --no-gen", {bShowOutputAsync => true}); | ||||
|         processBegin('release documentation'); | ||||
|         processExec("${strReleaseExe} --build --no-gen --vm=${strVm}", {bShowOutputAsync => true, bOutLogOnError => false}); | ||||
|         processEnd(); | ||||
|     } | ||||
|  | ||||
| @@ -128,19 +146,47 @@ eval | ||||
|     ################################################################################################################################ | ||||
|     elsif ($ARGV[0] eq 'test') | ||||
|     { | ||||
|         # VM must be defined | ||||
|         if (!defined($strVm)) | ||||
|         # Run tests that can be run without a container | ||||
|         my $strParam = ""; | ||||
|         my $strVmHost = VM_U14; | ||||
|  | ||||
|         if ($strVm eq VM_NONE) | ||||
|         { | ||||
|             confess &log(ERROR, '--vm is required'); | ||||
|             processBegin('debug tools install'); | ||||
|             processExec('sudo apt-get install -y valgrind', {bSuppressStdErr => true}); | ||||
|             processEnd(); | ||||
|  | ||||
|             processBegin('/tmp/pgbackrest owned by root so tests cannot use it'); | ||||
|             processExec('sudo mkdir -p /tmp/pgbackrest && sudo chown root:root /tmp/pgbackrest && sudo chmod 700 /tmp/pgbackrest'); | ||||
|             processEnd(); | ||||
|  | ||||
|             $strVmHost = VM_U18; | ||||
|         } | ||||
|         # Else run tests that require a container | ||||
|         else | ||||
|         { | ||||
|             # Build the container | ||||
|             processBegin("${strVm} build"); | ||||
|             processExec("${strTestExe} --vm-build --vm=${strVm}", {bShowOutputAsync => true, bOutLogOnError => false}); | ||||
|             processEnd(); | ||||
|  | ||||
|             # Run tests | ||||
|             $strParam .= " --vm-max=2"; | ||||
|  | ||||
|             if ($strVm eq VM_U18) | ||||
|             { | ||||
|                 $strParam .= " --container-only"; | ||||
|             } | ||||
|             elsif ($strVm ne VM_U12) | ||||
|             { | ||||
|                 $strParam .= " --module=command --module=mock --module=real --module=storage --module=performance"; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         processBegin("${strVm} build"); | ||||
|         executeTest("${strTestExe} --vm-build --vm=${strVm}", {bShowOutputAsync => true}); | ||||
|         processEnd(); | ||||
|  | ||||
|         processBegin("${strVm} test"); | ||||
|         executeTest( | ||||
|             "${strTestExe} --no-gen --no-ci-config --vm-host=" . VM_U14 . " --vm-max=2 --vm=${strVm}", {bShowOutputAsync => true}); | ||||
|         processBegin(($strVm eq VM_NONE ? "no container" : $strVm) . ' test'); | ||||
|         processExec( | ||||
|             "${strTestExe} --no-gen --no-ci-config --vm-host=${strVmHost} --vm=${strVm}${strParam}", | ||||
|             {bShowOutputAsync => true, bOutLogOnError => false}); | ||||
|         processEnd(); | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user