Skip to content

Commit 860593e

Browse files
committed
Fix portability issues in new amcheck test.
The tests added by commit 866e24d failed on big-endian machines due to lack of attention to endianness considerations. Fix that. While here, improve a few small cosmetic things, such as running it through perltidy. Mark Dilger Discussion: https://postgr.es/m/30B8E99A-2D9C-48D4-A55C-741C9D5F1563@enterprisedb.com
1 parent 87a174c commit 860593e

File tree

1 file changed

+46
-102
lines changed

1 file changed

+46
-102
lines changed

contrib/amcheck/t/001_verify_heapam.pl

Lines changed: 46 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use PostgresNode;
55
use TestLib;
66

7-
use Test::More tests => 65;
7+
use Test::More tests => 55;
88

99
my ($node, $result);
1010

@@ -28,19 +28,17 @@
2828
#
2929
fresh_test_table('test');
3030
corrupt_first_page('test');
31-
detects_corruption(
32-
"verify_heapam('test')",
33-
"plain corrupted table");
34-
detects_corruption(
31+
detects_heap_corruption("verify_heapam('test')", "plain corrupted table");
32+
detects_heap_corruption(
3533
"verify_heapam('test', skip := 'all-visible')",
3634
"plain corrupted table skipping all-visible");
37-
detects_corruption(
35+
detects_heap_corruption(
3836
"verify_heapam('test', skip := 'all-frozen')",
3937
"plain corrupted table skipping all-frozen");
40-
detects_corruption(
38+
detects_heap_corruption(
4139
"verify_heapam('test', check_toast := false)",
4240
"plain corrupted table skipping toast");
43-
detects_corruption(
41+
detects_heap_corruption(
4442
"verify_heapam('test', startblock := 0, endblock := 0)",
4543
"plain corrupted table checking only block zero");
4644

@@ -50,79 +48,20 @@
5048
fresh_test_table('test');
5149
$node->safe_psql('postgres', q(VACUUM FREEZE test));
5250
corrupt_first_page('test');
53-
detects_corruption(
54-
"verify_heapam('test')",
51+
detects_heap_corruption("verify_heapam('test')",
5552
"all-frozen corrupted table");
5653
detects_no_corruption(
5754
"verify_heapam('test', skip := 'all-frozen')",
5855
"all-frozen corrupted table skipping all-frozen");
5956

60-
#
61-
# Check a corrupt table with corrupt page header
62-
#
63-
fresh_test_table('test');
64-
corrupt_first_page_and_header('test');
65-
detects_corruption(
66-
"verify_heapam('test')",
67-
"corrupted test table with bad page header");
68-
69-
#
70-
# Check an uncorrupted table with corrupt toast page header
71-
#
72-
fresh_test_table('test');
73-
my $toast = get_toast_for('test');
74-
corrupt_first_page_and_header($toast);
75-
detects_corruption(
76-
"verify_heapam('test', check_toast := true)",
77-
"table with corrupted toast page header checking toast");
78-
detects_no_corruption(
79-
"verify_heapam('test', check_toast := false)",
80-
"table with corrupted toast page header skipping toast");
81-
detects_corruption(
82-
"verify_heapam('$toast')",
83-
"corrupted toast page header");
84-
85-
#
86-
# Check an uncorrupted table with corrupt toast
87-
#
88-
fresh_test_table('test');
89-
$toast = get_toast_for('test');
90-
corrupt_first_page($toast);
91-
detects_corruption(
92-
"verify_heapam('test', check_toast := true)",
93-
"table with corrupted toast checking toast");
94-
detects_no_corruption(
95-
"verify_heapam('test', check_toast := false)",
96-
"table with corrupted toast skipping toast");
97-
detects_corruption(
98-
"verify_heapam('$toast')",
99-
"corrupted toast table");
100-
101-
#
102-
# Check an uncorrupted all-frozen table with corrupt toast
103-
#
104-
fresh_test_table('test');
105-
$node->safe_psql('postgres', q(VACUUM FREEZE test));
106-
$toast = get_toast_for('test');
107-
corrupt_first_page($toast);
108-
detects_corruption(
109-
"verify_heapam('test', check_toast := true)",
110-
"all-frozen table with corrupted toast checking toast");
111-
detects_no_corruption(
112-
"verify_heapam('test', check_toast := false)",
113-
"all-frozen table with corrupted toast skipping toast");
114-
detects_corruption(
115-
"verify_heapam('$toast')",
116-
"corrupted toast table of all-frozen table");
117-
11857
# Returns the filesystem path for the named relation.
11958
sub relation_filepath
12059
{
12160
my ($relname) = @_;
12261

12362
my $pgdata = $node->data_dir;
124-
my $rel = $node->safe_psql('postgres',
125-
qq(SELECT pg_relation_filepath('$relname')));
63+
my $rel = $node->safe_psql('postgres',
64+
qq(SELECT pg_relation_filepath('$relname')));
12665
die "path not found for relation $relname" unless defined $rel;
12766
return "$pgdata/$rel";
12867
}
@@ -131,7 +70,9 @@ sub relation_filepath
13170
sub get_toast_for
13271
{
13372
my ($relname) = @_;
134-
$node->safe_psql('postgres', qq(
73+
74+
return $node->safe_psql(
75+
'postgres', qq(
13576
SELECT 'pg_toast.' || t.relname
13677
FROM pg_catalog.pg_class c, pg_catalog.pg_class t
13778
WHERE c.relname = '$relname'
@@ -142,7 +83,9 @@ sub get_toast_for
14283
sub fresh_test_table
14384
{
14485
my ($relname) = @_;
145-
$node->safe_psql('postgres', qq(
86+
87+
return $node->safe_psql(
88+
'postgres', qq(
14689
DROP TABLE IF EXISTS $relname CASCADE;
14790
CREATE TABLE $relname (a integer, b text);
14891
ALTER TABLE $relname SET (autovacuum_enabled=false);
@@ -154,55 +97,54 @@ sub fresh_test_table
15497

15598
# Stops the test node, corrupts the first page of the named relation, and
15699
# restarts the node.
157-
sub corrupt_first_page_internal
100+
sub corrupt_first_page
158101
{
159-
my ($relname, $corrupt_header) = @_;
102+
my ($relname) = @_;
160103
my $relpath = relation_filepath($relname);
161104

162105
$node->stop;
106+
163107
my $fh;
164-
open($fh, '+<', $relpath);
108+
open($fh, '+<', $relpath)
109+
or BAIL_OUT("open failed: $!");
165110
binmode $fh;
166111

167-
# If we corrupt the header, postgres won't allow the page into the buffer.
168-
syswrite($fh, '\xFF\xFF\xFF\xFF', 8) if ($corrupt_header);
112+
# Corrupt two line pointers. To be stable across platforms, we use
113+
# 0x55555555 and 0xAAAAAAAA for the two, which are bitwise reverses of each
114+
# other.
115+
seek($fh, 32, 0)
116+
or BAIL_OUT("seek failed: $!");
117+
syswrite($fh, pack("L*", 0x55555555, 0xAAAAAAAA))
118+
or BAIL_OUT("syswrite failed: $!");
119+
close($fh)
120+
or BAIL_OUT("close failed: $!");
169121

170-
# Corrupt at least the line pointers. Exactly what this corrupts will
171-
# depend on the page, as it may run past the line pointers into the user
172-
# data. We stop short of writing 2048 bytes (2k), the smallest supported
173-
# page size, as we don't want to corrupt the next page.
174-
seek($fh, 32, 0);
175-
syswrite($fh, '\x77\x77\x77\x77', 500);
176-
close($fh);
177122
$node->start;
178123
}
179124

180-
sub corrupt_first_page
125+
sub detects_heap_corruption
181126
{
182-
corrupt_first_page_internal($_[0], undef);
183-
}
127+
my ($function, $testname) = @_;
184128

185-
sub corrupt_first_page_and_header
186-
{
187-
corrupt_first_page_internal($_[0], 1);
129+
detects_corruption($function, $testname,
130+
qr/line pointer redirection to item at offset \d+ exceeds maximum offset \d+/
131+
);
188132
}
189133

190134
sub detects_corruption
191135
{
192-
my ($function, $testname) = @_;
136+
my ($function, $testname, $re) = @_;
193137

194-
my $result = $node->safe_psql('postgres',
195-
qq(SELECT COUNT(*) > 0 FROM $function));
196-
is($result, 't', $testname);
138+
my $result = $node->safe_psql('postgres', qq(SELECT * FROM $function));
139+
like($result, $re, $testname);
197140
}
198141

199142
sub detects_no_corruption
200143
{
201144
my ($function, $testname) = @_;
202145

203-
my $result = $node->safe_psql('postgres',
204-
qq(SELECT COUNT(*) = 0 FROM $function));
205-
is($result, 't', $testname);
146+
my $result = $node->safe_psql('postgres', qq(SELECT * FROM $function));
147+
is($result, '', $testname);
206148
}
207149

208150
# Check various options are stable (don't abort) and do not report corruption
@@ -215,6 +157,7 @@ sub detects_no_corruption
215157
sub check_all_options_uncorrupted
216158
{
217159
my ($relname, $prefix) = @_;
160+
218161
for my $stop (qw(true false))
219162
{
220163
for my $check_toast (qw(true false))
@@ -225,11 +168,12 @@ sub check_all_options_uncorrupted
225168
{
226169
for my $endblock (qw(NULL 0))
227170
{
228-
my $opts = "on_error_stop := $stop, " .
229-
"check_toast := $check_toast, " .
230-
"skip := $skip, " .
231-
"startblock := $startblock, " .
232-
"endblock := $endblock";
171+
my $opts =
172+
"on_error_stop := $stop, "
173+
. "check_toast := $check_toast, "
174+
. "skip := $skip, "
175+
. "startblock := $startblock, "
176+
. "endblock := $endblock";
233177

234178
detects_no_corruption(
235179
"verify_heapam('$relname', $opts)",

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy