Skip to content

Commit 2e51b72

Browse files
committed
PG-1411 Add pg_resetwal tap tests for TDE setup
These tests are copy of original pg_resetwal tests with enalbed WAL encryption and removed flags validation as we interested here only in proper enrypted WAL handling.
1 parent 2b55cf9 commit 2e51b72

File tree

2 files changed

+242
-0
lines changed

2 files changed

+242
-0
lines changed

contrib/pg_tde/t/pg_resetwal_basic.pl

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
2+
# Copyright (c) 2021-2024, PostgreSQL Global Development Group
3+
4+
use strict;
5+
use warnings FATAL => 'all';
6+
7+
use PostgreSQL::Test::Cluster;
8+
use PostgreSQL::Test::Utils;
9+
use Test::More;
10+
11+
unlink('/tmp/pg_resetwal_basic.per');
12+
13+
my $node = PostgreSQL::Test::Cluster->new('main');
14+
$node->init;
15+
$node->append_conf(
16+
'postgresql.conf', q{
17+
track_commit_timestamp = on
18+
19+
# WAL Encryption
20+
shared_preload_libraries = 'pg_tde'
21+
});
22+
23+
$node->start;
24+
$node->safe_psql('postgres', "CREATE EXTENSION pg_tde;");
25+
$node->safe_psql('postgres',
26+
"SELECT pg_tde_add_global_key_provider_file('file-keyring-wal', '/tmp/pg_resetwal_basic.per');"
27+
);
28+
$node->safe_psql('postgres',
29+
"SELECT pg_tde_create_key_using_global_key_provider('server-key', 'file-keyring-wal');"
30+
);
31+
$node->safe_psql('postgres',
32+
"SELECT pg_tde_set_server_key_using_global_key_provider('server-key', 'file-keyring-wal');"
33+
);
34+
35+
$node->append_conf(
36+
'postgresql.conf', q{
37+
pg_tde.wal_encrypt = on
38+
});
39+
$node->stop;
40+
41+
42+
command_like([ 'pg_resetwal', '-n', $node->data_dir ],
43+
qr/checkpoint/, 'pg_resetwal -n produces output');
44+
45+
46+
# Permissions on PGDATA should be default
47+
SKIP:
48+
{
49+
skip "unix-style permissions not supported on Windows", 1
50+
if ($windows_os);
51+
52+
ok(check_mode_recursive($node->data_dir, 0700, 0600),
53+
'check PGDATA permissions');
54+
}
55+
56+
command_ok([ 'pg_resetwal', '-D', $node->data_dir ], 'pg_resetwal runs');
57+
$node->start;
58+
is($node->safe_psql("postgres", "SELECT 1;"),
59+
1, 'server running and working after reset');
60+
61+
command_fails_like(
62+
[ 'pg_resetwal', $node->data_dir ],
63+
qr/lock file .* exists/,
64+
'fails if server running');
65+
66+
$node->stop('immediate');
67+
command_fails_like(
68+
[ 'pg_resetwal', $node->data_dir ],
69+
qr/database server was not shut down cleanly/,
70+
'does not run after immediate shutdown');
71+
command_ok(
72+
[ 'pg_resetwal', '-f', $node->data_dir ],
73+
'runs after immediate shutdown with force');
74+
$node->start;
75+
is($node->safe_psql("postgres", "SELECT 1;"),
76+
1, 'server running and working after forced reset');
77+
78+
$node->stop;
79+
80+
# check various command-line handling
81+
82+
# Note: This test intends to check that a nonexistent data directory
83+
# gives a reasonable error message. Because of the way the code is
84+
# currently structured, you get an error about readings permissions,
85+
# which is perhaps suboptimal, so feel free to update this test if
86+
# this gets improved.
87+
88+
89+
# run with control override options
90+
91+
my $out = (run_command([ 'pg_resetwal', '-n', $node->data_dir ]))[0];
92+
$out =~ /^Database block size: *(\d+)$/m or die;
93+
my $blcksz = $1;
94+
95+
my @cmd = ('pg_resetwal', '-D', $node->data_dir);
96+
97+
# some not-so-critical hardcoded values
98+
push @cmd, '-e', 1;
99+
push @cmd, '-l', '00000001000000320000004B';
100+
push @cmd, '-o', 100_000;
101+
push @cmd, '--wal-segsize', 1;
102+
103+
# these use the guidance from the documentation
104+
105+
sub get_slru_files
106+
{
107+
opendir(my $dh, $node->data_dir . '/' . $_[0]) or die $!;
108+
my @files = sort grep { /[0-9A-F]+/ } readdir $dh;
109+
closedir $dh;
110+
return @files;
111+
}
112+
113+
my (@files, $mult);
114+
115+
@files = get_slru_files('pg_commit_ts');
116+
# XXX: Should there be a multiplier, similar to the other options?
117+
# -c argument is "old,new"
118+
push @cmd,
119+
'-c',
120+
sprintf("%d,%d", hex($files[0]) == 0 ? 3 : hex($files[0]), hex($files[-1]));
121+
122+
@files = get_slru_files('pg_multixact/offsets');
123+
$mult = 32 * $blcksz / 4;
124+
# -m argument is "new,old"
125+
push @cmd, '-m',
126+
sprintf("%d,%d",
127+
(hex($files[-1]) + 1) * $mult,
128+
hex($files[0]) == 0 ? 1 : hex($files[0] * $mult));
129+
130+
@files = get_slru_files('pg_multixact/members');
131+
$mult = 32 * int($blcksz / 20) * 4;
132+
push @cmd, '-O', (hex($files[-1]) + 1) * $mult;
133+
134+
@files = get_slru_files('pg_xact');
135+
$mult = 32 * $blcksz * 4;
136+
push @cmd,
137+
'-u', (hex($files[0]) == 0 ? 3 : hex($files[0]) * $mult),
138+
'-x', ((hex($files[-1]) + 1) * $mult);
139+
140+
command_ok([ @cmd, '-n' ], 'runs with control override options, dry run');
141+
command_ok(\@cmd, 'runs with control override options');
142+
command_like(
143+
[ 'pg_resetwal', '-n', $node->data_dir ],
144+
qr/^Latest checkpoint's NextOID: *100000$/m,
145+
'spot check that control changes were applied');
146+
147+
$node->start;
148+
ok(1, 'server started after reset');
149+
150+
done_testing();
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
2+
# Copyright (c) 2021-2024, PostgreSQL Global Development Group
3+
4+
# Tests for handling a corrupted pg_control
5+
6+
use strict;
7+
use warnings FATAL => 'all';
8+
9+
use PostgreSQL::Test::Cluster;
10+
use PostgreSQL::Test::Utils;
11+
use Test::More;
12+
13+
unlink('/tmp/pg_resetwal_corrupted.per');
14+
15+
my $node = PostgreSQL::Test::Cluster->new('main');
16+
$node->init;
17+
$node->append_conf(
18+
'postgresql.conf', q{
19+
20+
# WAL Encryption
21+
shared_preload_libraries = 'pg_tde'
22+
});
23+
24+
$node->start;
25+
$node->safe_psql('postgres', "CREATE EXTENSION pg_tde;");
26+
$node->safe_psql('postgres',
27+
"SELECT pg_tde_add_global_key_provider_file('file-keyring-wal', '/tmp/pg_waldump_corrupted.per');"
28+
);
29+
$node->safe_psql('postgres',
30+
"SELECT pg_tde_create_key_using_global_key_provider('server-key', 'file-keyring-wal');"
31+
);
32+
$node->safe_psql('postgres',
33+
"SELECT pg_tde_set_server_key_using_global_key_provider('server-key', 'file-keyring-wal');"
34+
);
35+
36+
$node->append_conf(
37+
'postgresql.conf', q{
38+
pg_tde.wal_encrypt = on
39+
});
40+
$node->stop;
41+
42+
my $pg_control = $node->data_dir . '/global/pg_control';
43+
my $size = -s $pg_control;
44+
45+
# Read out the head of the file to get PG_CONTROL_VERSION in
46+
# particular.
47+
my $data;
48+
open my $fh, '<', $pg_control or BAIL_OUT($!);
49+
binmode $fh;
50+
read $fh, $data, 16 or die $!;
51+
close $fh;
52+
53+
# Fill pg_control with zeros
54+
open $fh, '>', $pg_control or BAIL_OUT($!);
55+
binmode $fh;
56+
print $fh pack("x[$size]");
57+
close $fh;
58+
59+
command_checks_all(
60+
[ 'pg_resetwal', '-n', $node->data_dir ],
61+
0,
62+
[qr/pg_control version number/],
63+
[
64+
qr/pg_resetwal: warning: pg_control exists but is broken or wrong version; ignoring it/
65+
],
66+
'processes corrupted pg_control all zeroes');
67+
68+
# Put in the previously saved header data. This uses a different code
69+
# path internally, allowing us to process a zero WAL segment size.
70+
open $fh, '>', $pg_control or BAIL_OUT($!);
71+
binmode $fh;
72+
print $fh $data, pack("x[" . ($size - 16) . "]");
73+
close $fh;
74+
75+
command_checks_all(
76+
[ 'pg_resetwal', '-n', $node->data_dir ],
77+
0,
78+
[qr/pg_control version number/],
79+
[
80+
qr/\Qpg_resetwal: warning: pg_control specifies invalid WAL segment size (0 bytes); proceed with caution\E/
81+
],
82+
'processes zero WAL segment size');
83+
84+
# now try to run it
85+
command_fails_like(
86+
[ 'pg_resetwal', $node->data_dir ],
87+
qr/not proceeding because control file values were guessed/,
88+
'does not run when control file values were guessed');
89+
command_ok([ 'pg_resetwal', '-f', $node->data_dir ],
90+
'runs with force when control file values were guessed');
91+
92+
done_testing();

0 commit comments

Comments
 (0)