Add TAP tests for pg_verify_checksums
All options available in the utility get coverage: - Tests with disabled page checksums. - Tests with enabled test checksums. - Emulation of corruption and broken checksums with a full scan and single relfilenode scan. This patch has been contributed mainly by Michael Banck and Magnus Hagander with things presented on various threads, and I have gathered all the contents into a single patch. Author: Michael Banck, Magnus Hagander, Michael Paquier Reviewed-by: Peter Eisentraut Discussion: https://postgr.es/m/20181005012645.GE1629@paquier.xyz
This commit is contained in:
parent
cda6a8d01d
commit
b34e84f160
@ -8,7 +8,7 @@ use Fcntl ':mode';
|
||||
use File::stat qw{lstat};
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use Test::More tests => 18;
|
||||
use Test::More tests => 22;
|
||||
|
||||
my $tempdir = TestLib::tempdir;
|
||||
my $xlogdir = "$tempdir/pgxlog";
|
||||
@ -58,6 +58,18 @@ mkdir $datadir;
|
||||
"check PGDATA permissions");
|
||||
}
|
||||
}
|
||||
|
||||
# Control file should tell that data checksums are disabled by default.
|
||||
command_like(['pg_controldata', $datadir],
|
||||
qr/Data page checksum version:.*0/,
|
||||
'checksums are disabled in control file');
|
||||
# pg_verify_checksums fails with checksums disabled by default. This is
|
||||
# not part of the tests included in pg_verify_checksums to save from
|
||||
# the creation of an extra instance.
|
||||
command_fails(
|
||||
[ 'pg_verify_checksums', '-D', $datadir],
|
||||
"pg_verify_checksums fails with data checksum disabled");
|
||||
|
||||
command_ok([ 'initdb', '-S', $datadir ], 'sync only');
|
||||
command_fails([ 'initdb', $datadir ], 'existing data directory');
|
||||
|
||||
|
2
src/bin/pg_verify_checksums/.gitignore
vendored
2
src/bin/pg_verify_checksums/.gitignore
vendored
@ -1 +1,3 @@
|
||||
/pg_verify_checksums
|
||||
|
||||
/tmp_check/
|
||||
|
@ -34,3 +34,9 @@ uninstall:
|
||||
clean distclean maintainer-clean:
|
||||
rm -f pg_verify_checksums$(X) $(OBJS)
|
||||
rm -rf tmp_check
|
||||
|
||||
check:
|
||||
$(prove_check)
|
||||
|
||||
installcheck:
|
||||
$(prove_installcheck)
|
||||
|
8
src/bin/pg_verify_checksums/t/001_basic.pl
Normal file
8
src/bin/pg_verify_checksums/t/001_basic.pl
Normal file
@ -0,0 +1,8 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use TestLib;
|
||||
use Test::More tests => 8;
|
||||
|
||||
program_help_ok('pg_verify_checksums');
|
||||
program_version_ok('pg_verify_checksums');
|
||||
program_options_handling_ok('pg_verify_checksums');
|
69
src/bin/pg_verify_checksums/t/002_actions.pl
Normal file
69
src/bin/pg_verify_checksums/t/002_actions.pl
Normal file
@ -0,0 +1,69 @@
|
||||
# Do basic sanity checks supported by pg_verify_checksums using
|
||||
# an initialized cluster.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use Test::More tests => 12;
|
||||
|
||||
# Initialize node with checksums enabled.
|
||||
my $node = get_new_node('node_checksum');
|
||||
$node->init(extra => ['--data-checksums']);
|
||||
my $pgdata = $node->data_dir;
|
||||
|
||||
# Control file should know that checksums are enabled.
|
||||
command_like(['pg_controldata', $pgdata],
|
||||
qr/Data page checksum version:.*1/,
|
||||
'checksums enabled in control file');
|
||||
|
||||
# Checksums pass on a newly-created cluster
|
||||
command_ok(['pg_verify_checksums', '-D', $pgdata],
|
||||
"succeeds with offline cluster");
|
||||
|
||||
# Checks cannot happen with an online cluster
|
||||
$node->start;
|
||||
command_fails(['pg_verify_checksums', '-D', $pgdata],
|
||||
"fails with online cluster");
|
||||
|
||||
# Create table to corrupt and get its relfilenode
|
||||
$node->safe_psql('postgres',
|
||||
"SELECT a INTO corrupt1 FROM generate_series(1,10000) AS a;
|
||||
ALTER TABLE corrupt1 SET (autovacuum_enabled=false);");
|
||||
|
||||
my $file_corrupted = $node->safe_psql('postgres',
|
||||
"SELECT pg_relation_filepath('corrupt1')");
|
||||
my $relfilenode_corrupted = $node->safe_psql('postgres',
|
||||
"SELECT relfilenode FROM pg_class WHERE relname = 'corrupt1';");
|
||||
|
||||
# Set page header and block size
|
||||
my $pageheader_size = 24;
|
||||
my $block_size = $node->safe_psql('postgres', 'SHOW block_size;');
|
||||
$node->stop;
|
||||
|
||||
# Checksums are correct for single relfilenode as the table is not
|
||||
# corrupted yet.
|
||||
command_ok(['pg_verify_checksums', '-D', $pgdata,
|
||||
'-r', $relfilenode_corrupted],
|
||||
"succeeds for single relfilenode with offline cluster");
|
||||
|
||||
# Time to create some corruption
|
||||
open my $file, '+<', "$pgdata/$file_corrupted";
|
||||
seek($file, $pageheader_size, 0);
|
||||
syswrite($file, '\0\0\0\0\0\0\0\0\0');
|
||||
close $file;
|
||||
|
||||
# Global checksum checks fail
|
||||
$node->command_checks_all([ 'pg_verify_checksums', '-D', $pgdata],
|
||||
1,
|
||||
[qr/Bad checksums:.*1/],
|
||||
[qr/checksum verification failed/],
|
||||
'fails with corrupted data');
|
||||
|
||||
# Checksum checks on single relfilenode fail
|
||||
$node->command_checks_all([ 'pg_verify_checksums', '-D', $pgdata, '-r',
|
||||
$relfilenode_corrupted],
|
||||
1,
|
||||
[qr/Bad checksums:.*1/],
|
||||
[qr/checksum verification failed/],
|
||||
'fails for corrupted data on single relfilenode');
|
Loading…
x
Reference in New Issue
Block a user