summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/recovery/t/022_page_check.pl231
-rw-r--r--src/test/regress/expected/pagefuncs.out72
-rw-r--r--src/test/regress/parallel_schedule2
-rw-r--r--src/test/regress/serial_schedule1
-rw-r--r--src/test/regress/sql/pagefuncs.sql41
5 files changed, 1 insertions, 346 deletions
diff --git a/src/test/recovery/t/022_page_check.pl b/src/test/recovery/t/022_page_check.pl
deleted file mode 100644
index 9dd4225c5a0..00000000000
--- a/src/test/recovery/t/022_page_check.pl
+++ /dev/null
@@ -1,231 +0,0 @@
-# Emulate on-disk corruptions of relation pages and find such corruptions
-# using pg_relation_check_pages().
-
-use strict;
-use warnings;
-
-use PostgresNode;
-use TestLib;
-use Test::More tests => 20;
-
-our $CHECKSUM_UINT16_OFFSET = 4;
-our $PD_UPPER_UINT16_OFFSET = 7;
-our $BLOCKSIZE;
-our $TOTAL_NB_ERR = 0;
-
-# Grab a relation page worth a size of BLOCKSIZE from given $filename.
-# $blkno is the same block number as for a relation file.
-sub read_page
-{
- my ($filename, $blkno) = @_;
- my $block;
-
- open(my $infile, '<', $filename) or die;
- binmode($infile);
-
- my $success = read($infile, $block, $BLOCKSIZE, ($blkno * $BLOCKSIZE));
- die($!) if !defined($success);
-
- close($infile);
-
- return ($block);
-}
-
-# Update an existing page of size BLOCKSIZE with new contents in given
-# $filename. $blkno is the block number assigned in the relation file.
-sub write_page
-{
- my ($filename, $block, $blkno) = @_;
-
- open(my $outfile, '>', $filename) or die;
- binmode($outfile);
-
- my $nb = syswrite($outfile, $block, $BLOCKSIZE, ($blkno * $BLOCKSIZE));
-
- die($!) if not defined $nb;
- die("Write error") if ($nb != $BLOCKSIZE);
-
- $outfile->flush();
-
- close($outfile);
- return;
-}
-
-# Read 2 bytes from relation page at a given offset.
-sub get_uint16_from_page
-{
- my ($block, $offset) = @_;
-
- return (unpack("S*", $block))[$offset];
-}
-
-# Write 2 bytes to relation page at a given offset.
-sub set_uint16_to_page
-{
- my ($block, $data, $offset) = @_;
-
- my $pack = pack("S", $data);
-
- # vec with 16B or more won't preserve endianness.
- vec($block, 2 * $offset, 8) = (unpack('C*', $pack))[0];
- vec($block, (2 * $offset) + 1, 8) = (unpack('C*', $pack))[1];
-
- return $block;
-}
-
-# Sanity check on pg_stat_database looking after the number of checksum
-# failures.
-sub check_pg_stat_database
-{
- my ($node, $test_prefix) = @_;
-
- my $stdout = $node->safe_psql('postgres',
- "SELECT "
- . " sum(checksum_failures)"
- . " FROM pg_catalog.pg_stat_database");
- is($stdout, $TOTAL_NB_ERR,
- "$test_prefix: pg_stat_database should have $TOTAL_NB_ERR error");
-
- return;
-}
-
-# Run a round of page checks for any relation present in this test run.
-# $expected_broken is the psql output marking all the pages found as
-# corrupted using relname|blkno as format for each tuple returned. $nb
-# is the new number of checksum errors added to the global counter
-# matched with the contents of pg_stat_database.
-#
-# Note that this has no need to check system relations as these would have
-# no corruptions: this test does not manipulate them and should by no mean
-# break the cluster.
-sub run_page_checks
-{
- my ($node, $num_checksum, $expected_broken, $test_prefix) = @_;
-
- my $stdout = $node->safe_psql('postgres',
- "SELECT relname, failed_block_num"
- . " FROM (SELECT relname, (pg_catalog.pg_relation_check_pages(oid)).*"
- . " FROM pg_class "
- . " WHERE relkind in ('r','i', 'm') AND oid >= 16384) AS s");
-
- # Check command result
- is($stdout, $expected_broken,
- "$test_prefix: output mismatch with pg_relation_check_pages()");
-
- $TOTAL_NB_ERR += $num_checksum;
- return;
-}
-
-# Perform various tests that modify a specified block at the given
-# offset, checking that a page corruption is correctly detected. The
-# original contents of the page are restored back once done.
-# $broken_pages is the set of pages that are expected to be broken
-# as of the returned result of pg_relation_check_pages(). $num_checksum
-# is the number of checksum failures expected to be added to the contents
-# of pg_stat_database after this function is done.
-sub corrupt_and_test_block
-{
- my ($node, $filename, $blkno, $offset, $broken_pages, $num_checksum,
- $test_prefix)
- = @_;
- my $fake_data = hex '0x0000';
-
- # Stop the server cleanly to flush any pages, and to prevent any
- # concurrent updates on what is going to be updated.
- $node->stop;
- my $original_block = read_page($filename, 0);
- my $original_data = get_uint16_from_page($original_block, $offset);
-
- isnt($original_data, $fake_data,
- "$test_prefix: fake data at offset $offset should be different from the existing one"
- );
-
- my $new_block = set_uint16_to_page($original_block, $fake_data, $offset);
- isnt(
- $original_data,
- get_uint16_from_page($new_block, $offset),
- "$test_prefix: The data at offset $offset should have been changed in memory"
- );
-
- write_page($filename, $new_block, 0);
-
- my $written_data = get_uint16_from_page(read_page($filename, 0), $offset);
-
- # Some offline checks to validate that the corrupted data is in place.
- isnt($original_data, $written_data,
- "$test_prefix: data written at offset $offset should be different from the original one"
- );
- is( get_uint16_from_page($new_block, $offset),
- $written_data,
- "$test_prefix: data written at offset $offset should be the same as the one in memory"
- );
- is($written_data, $fake_data,
- "$test_prefix: The data written at offset $offset should be the one we wanted to write"
- );
-
- # The corruption is in place, start the server to run the checks.
- $node->start;
- run_page_checks($node, $num_checksum, $broken_pages, $test_prefix);
-
- # Stop the server, put the original page back in place.
- $node->stop;
-
- $new_block = set_uint16_to_page($original_block, $original_data, $offset);
- is( $original_data,
- get_uint16_from_page($new_block, $offset),
- "$test_prefix: data at offset $offset should have been restored in memory"
- );
-
- write_page($filename, $new_block, 0);
- is( $original_data,
- get_uint16_from_page(read_page($filename, $blkno), $offset),
- "$test_prefix: data at offset $offset should have been restored on disk"
- );
-
- # There should be no errors now that the contents are back in place.
- $node->start;
- run_page_checks($node, 0, '', $test_prefix);
-}
-
-# Data checksums are necessary for this test.
-my $node = get_new_node('main');
-$node->init(extra => ['--data-checksums']);
-$node->start;
-
-my $stdout =
- $node->safe_psql('postgres', "SELECT" . " current_setting('block_size')");
-
-$BLOCKSIZE = $stdout;
-
-# Basic schema to corrupt and check
-$node->safe_psql(
- 'postgres', q|
- CREATE TABLE public.t1(id integer);
- INSERT INTO public.t1 SELECT generate_series(1, 100);
- CHECKPOINT;
-|);
-
-# Get the path to the relation file that will get manipulated by the
-# follow-up tests with some on-disk corruptions.
-$stdout = $node->safe_psql('postgres',
- "SELECT"
- . " current_setting('data_directory') || '/' || pg_relation_filepath('t1')"
-);
-
-my $filename = $stdout;
-
-# Normal case without corruptions, this passes, with pg_stat_database
-# reporting no errors.
-check_pg_stat_database($node, 'start');
-
-# Test with a modified checksum.
-corrupt_and_test_block($node, $filename, 0, $CHECKSUM_UINT16_OFFSET, 't1|0',
- 1, 'broken checksum');
-
-# Test corruption making the block looking like it validates PageIsNew().
-corrupt_and_test_block($node, $filename, 0, $PD_UPPER_UINT16_OFFSET, 't1|0',
- 0, 'new page');
-
-# Check that the number of errors in pg_stat_database match what we
-# expect with the corruptions previously introduced.
-check_pg_stat_database($node, 'end');
diff --git a/src/test/regress/expected/pagefuncs.out b/src/test/regress/expected/pagefuncs.out
deleted file mode 100644
index 38a72b01b3f..00000000000
--- a/src/test/regress/expected/pagefuncs.out
+++ /dev/null
@@ -1,72 +0,0 @@
---
--- Tests for functions related to relation pages
---
--- Restricted to superusers by default
-CREATE ROLE regress_pgfunc_user;
-SET ROLE regress_pgfunc_user;
-SELECT pg_relation_check_pages('pg_class'); -- error
-ERROR: permission denied for function pg_relation_check_pages
-SELECT pg_relation_check_pages('pg_class', 'main'); -- error
-ERROR: permission denied for function pg_relation_check_pages
-RESET ROLE;
-DROP ROLE regress_pgfunc_user;
--- NULL and simple sanity checks
-SELECT pg_relation_check_pages(NULL); -- empty result
- pg_relation_check_pages
--------------------------
-(0 rows)
-
-SELECT pg_relation_check_pages(NULL, NULL); -- empty result
- pg_relation_check_pages
--------------------------
-(0 rows)
-
-SELECT pg_relation_check_pages('pg_class', 'invalid_fork'); -- error
-ERROR: invalid fork name
-HINT: Valid fork names are "main", "fsm", "vm", and "init".
--- Relation types that are supported
-CREATE TABLE pgfunc_test_tab (id int);
-CREATE INDEX pgfunc_test_ind ON pgfunc_test_tab(id);
-INSERT INTO pgfunc_test_tab VALUES (generate_series(1,1000));
-SELECT pg_relation_check_pages('pgfunc_test_tab');
- pg_relation_check_pages
--------------------------
-(0 rows)
-
-SELECT pg_relation_check_pages('pgfunc_test_ind');
- pg_relation_check_pages
--------------------------
-(0 rows)
-
-DROP TABLE pgfunc_test_tab;
-CREATE MATERIALIZED VIEW pgfunc_test_matview AS SELECT 1;
-SELECT pg_relation_check_pages('pgfunc_test_matview');
- pg_relation_check_pages
--------------------------
-(0 rows)
-
-DROP MATERIALIZED VIEW pgfunc_test_matview;
-CREATE SEQUENCE pgfunc_test_seq;
-SELECT pg_relation_check_pages('pgfunc_test_seq');
- pg_relation_check_pages
--------------------------
-(0 rows)
-
-DROP SEQUENCE pgfunc_test_seq;
--- pg_relation_check_pages() returns no results if passed relations that
--- do not support the operation, like relations without storage or temporary
--- relations.
-CREATE TEMPORARY TABLE pgfunc_test_temp AS SELECT generate_series(1,10) AS a;
-SELECT pg_relation_check_pages('pgfunc_test_temp');
- pg_relation_check_pages
--------------------------
-(0 rows)
-
-DROP TABLE pgfunc_test_temp;
-CREATE VIEW pgfunc_test_view AS SELECT 1;
-SELECT pg_relation_check_pages('pgfunc_test_view');
- pg_relation_check_pages
--------------------------
-(0 rows)
-
-DROP VIEW pgfunc_test_view;
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 7a46a132525..ae89ed7f0b4 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -112,7 +112,7 @@ test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion tr
# ----------
# Another group of parallel tests
# ----------
-test: partition_join partition_prune reloptions hash_part indexing partition_aggregate partition_info tuplesort explain pagefuncs
+test: partition_join partition_prune reloptions hash_part indexing partition_aggregate partition_info tuplesort explain
# event triggers cannot run concurrently with any test that runs DDL
test: event_trigger
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index 9a80b80f73a..525bdc804f6 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -197,7 +197,6 @@ test: hash_part
test: indexing
test: partition_aggregate
test: partition_info
-test: pagefuncs
test: tuplesort
test: explain
test: event_trigger
diff --git a/src/test/regress/sql/pagefuncs.sql b/src/test/regress/sql/pagefuncs.sql
deleted file mode 100644
index 12d32eeae47..00000000000
--- a/src/test/regress/sql/pagefuncs.sql
+++ /dev/null
@@ -1,41 +0,0 @@
---
--- Tests for functions related to relation pages
---
-
--- Restricted to superusers by default
-CREATE ROLE regress_pgfunc_user;
-SET ROLE regress_pgfunc_user;
-SELECT pg_relation_check_pages('pg_class'); -- error
-SELECT pg_relation_check_pages('pg_class', 'main'); -- error
-RESET ROLE;
-DROP ROLE regress_pgfunc_user;
-
--- NULL and simple sanity checks
-SELECT pg_relation_check_pages(NULL); -- empty result
-SELECT pg_relation_check_pages(NULL, NULL); -- empty result
-SELECT pg_relation_check_pages('pg_class', 'invalid_fork'); -- error
-
--- Relation types that are supported
-CREATE TABLE pgfunc_test_tab (id int);
-CREATE INDEX pgfunc_test_ind ON pgfunc_test_tab(id);
-INSERT INTO pgfunc_test_tab VALUES (generate_series(1,1000));
-SELECT pg_relation_check_pages('pgfunc_test_tab');
-SELECT pg_relation_check_pages('pgfunc_test_ind');
-DROP TABLE pgfunc_test_tab;
-
-CREATE MATERIALIZED VIEW pgfunc_test_matview AS SELECT 1;
-SELECT pg_relation_check_pages('pgfunc_test_matview');
-DROP MATERIALIZED VIEW pgfunc_test_matview;
-CREATE SEQUENCE pgfunc_test_seq;
-SELECT pg_relation_check_pages('pgfunc_test_seq');
-DROP SEQUENCE pgfunc_test_seq;
-
--- pg_relation_check_pages() returns no results if passed relations that
--- do not support the operation, like relations without storage or temporary
--- relations.
-CREATE TEMPORARY TABLE pgfunc_test_temp AS SELECT generate_series(1,10) AS a;
-SELECT pg_relation_check_pages('pgfunc_test_temp');
-DROP TABLE pgfunc_test_temp;
-CREATE VIEW pgfunc_test_view AS SELECT 1;
-SELECT pg_relation_check_pages('pgfunc_test_view');
-DROP VIEW pgfunc_test_view;