Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+46-102
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)