From fd48b26a175370dd64264c48ac2d61aef1b9494b Mon Sep 17 00:00:00 2001 From: Georgios Kokolatos Date: Tue, 13 Jul 2021 15:28:57 +0000 Subject: [PATCH v6] Introduce pg_receivewal gzip compression tests There exists a non trivial amount of code that handles gzip compression. The current patch introduces tests that cover creation of gzip compressed WAL files and the handling of the partial segments. The integrity of the compressed files is verified as is the ability to start streaming from the correct location regardless of compression. --- src/bin/pg_basebackup/Makefile | 6 +- src/bin/pg_basebackup/t/020_pg_receivewal.pl | 79 +++++++++++++++++++- 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/src/bin/pg_basebackup/Makefile b/src/bin/pg_basebackup/Makefile index 66e0070f1a..459d514183 100644 --- a/src/bin/pg_basebackup/Makefile +++ b/src/bin/pg_basebackup/Makefile @@ -18,8 +18,12 @@ subdir = src/bin/pg_basebackup top_builddir = ../../.. include $(top_builddir)/src/Makefile.global -# make this available to TAP test scripts +# make these available to TAP test scripts export TAR +# Note that GZIP cannot be used directly as this environment variable is +# used by the command "gzip" to pass down options, so stick with a different +# name. +export GZIP_PROGRAM=$(GZIP) override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils $(libpq_pgport) diff --git a/src/bin/pg_basebackup/t/020_pg_receivewal.pl b/src/bin/pg_basebackup/t/020_pg_receivewal.pl index a547c97ef1..26caa64246 100644 --- a/src/bin/pg_basebackup/t/020_pg_receivewal.pl +++ b/src/bin/pg_basebackup/t/020_pg_receivewal.pl @@ -5,7 +5,7 @@ use strict; use warnings; use TestLib; use PostgresNode; -use Test::More tests => 19; +use Test::More tests => 27; program_help_ok('pg_receivewal'); program_version_ok('pg_receivewal'); @@ -66,6 +66,83 @@ $primary->command_ok( ], 'streaming some WAL with --synchronous'); +# Verify that one partial file was generated and keep track of it +my @partial_wals = glob "$stream_dir/*\.partial"; +is(scalar(@partial_wals), 1, + "one partial WAL segment was created"); + +# Check ZLIB compression if available. +SKIP: +{ + skip "postgres was not build with ZLIB support", 5 + if (!check_pg_config("#define HAVE_LIBZ 1")); + + # Generate more WAL. + $primary->psql('postgres', 'SELECT pg_switch_wal();'); + $nextlsn = + $primary->safe_psql('postgres', 'SELECT pg_current_wal_insert_lsn();'); + chomp($nextlsn); + $primary->psql('postgres', + 'INSERT INTO test_table VALUES (generate_series(100,200));'); + $primary->psql('postgres', 'SELECT pg_switch_wal();'); + + $primary->command_ok( + [ + 'pg_receivewal', '-D', $stream_dir, '--verbose', + '--endpos', $nextlsn, '--compress', '1' + ], + "streaming some WAL using ZLIB compression"); + + # Verify that the stored files are generated with the expected names. + my @zlib_wals = glob "$stream_dir/*.gz"; + is(scalar(@zlib_wals), 1, + "one WAL segment compressed with ZLIB was created"); + my @zlib_partial_wals = glob "$stream_dir/*.gz.partial"; + is(scalar(@zlib_partial_wals), + 1, "one partial WAL segment compressed with ZLIB was created"); + + # Verify that the start streaming position is computed correctly by + # comparing with the previous partial file + $partial_wals[0] =~ s/\.partial$/.gz/; + is($zlib_wals[0] =~ m/$partial_wals[0]/, 1, + "one partial WAL segment is now completed"); + + # Update the partial wals with the current values + @partial_wals = @zlib_partial_wals; + + # There is one complete and one partial file compressed with ZLIB. Check + # the integrity of both. + my $gzip = $ENV{GZIP_PROGRAM}; + skip "program gzip is not found in your system", 1 + if ( !defined $gzip + || $gzip eq '' + || system_log($gzip, '--version') != 0); + + push(@zlib_wals, @zlib_partial_wals); + my $gzip_is_valid = system_log($gzip, '--test', @zlib_wals); + is($gzip_is_valid, 0, + "gzip verified the integrity of compressed WAL segments"); +} + +# Verify that the start streaming position is computed and that the value is +# correct regardless of whether ZLIB is available. +$primary->psql('postgres', 'SELECT pg_switch_wal();'); +$nextlsn = $primary->safe_psql('postgres', 'SELECT pg_current_wal_insert_lsn();'); +chomp($nextlsn); +$primary->psql('postgres', + 'INSERT INTO test_table VALUES (generate_series(200,300));'); +$primary->psql('postgres', 'SELECT pg_switch_wal();'); +$primary->command_ok( + [ + 'pg_receivewal', '-D', $stream_dir, '--verbose', + '--endpos', $nextlsn + ], + "streaming some WAL"); +$primary->psql('postgres', 'SELECT pg_switch_wal();'); + +$partial_wals[0] =~ s/(\.gz)?.partial//; +ok(-e $partial_wals[0], "check that previously partial WAL is now complete"); + # Permissions on WAL files should be default SKIP: { -- 2.25.1