Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 96063e2

Browse files
committed
pg_waldump: Add more tests
This adds tests for most command-line options and tests for most rmgrdesc routines. Based on patch by Dong Wook Lee <sh95119@gmail.com>. Reviewed-by: Tristen Raab <tristen.raab@highgo.ca> Discussion: https://www.postgresql.org/message-id/flat/CAAcByaKM7zyJSDkPWv6_%2BapupY4fXXM3q3SRXas9MMNVPUGcsQ%40mail.gmail.com
1 parent 5e8068f commit 96063e2

File tree

1 file changed

+194
-0
lines changed

1 file changed

+194
-0
lines changed

src/bin/pg_waldump/t/001_basic.pl

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,205 @@
33

44
use strict;
55
use warnings;
6+
use PostgreSQL::Test::Cluster;
67
use PostgreSQL::Test::Utils;
78
use Test::More;
89

910
program_help_ok('pg_waldump');
1011
program_version_ok('pg_waldump');
1112
program_options_handling_ok('pg_waldump');
1213

14+
# wrong number of arguments
15+
command_fails_like([ 'pg_waldump', ], qr/error: no arguments/, 'no arguments');
16+
command_fails_like([ 'pg_waldump', 'foo', 'bar', 'baz' ], qr/error: too many command-line arguments/, 'too many arguments');
17+
18+
# invalid option arguments
19+
command_fails_like([ 'pg_waldump', '--block', 'bad' ], qr/error: invalid block number/, 'invalid block number');
20+
command_fails_like([ 'pg_waldump', '--fork', 'bad' ], qr/error: invalid fork name/, 'invalid fork name');
21+
command_fails_like([ 'pg_waldump', '--limit', 'bad' ], qr/error: invalid value/, 'invalid limit');
22+
command_fails_like([ 'pg_waldump', '--relation', 'bad' ], qr/error: invalid relation/, 'invalid relation specification');
23+
command_fails_like([ 'pg_waldump', '--rmgr', 'bad' ], qr/error: resource manager .* does not exist/, 'invalid rmgr name');
24+
command_fails_like([ 'pg_waldump', '--start', 'bad' ], qr/error: invalid WAL location/, 'invalid start LSN');
25+
command_fails_like([ 'pg_waldump', '--end', 'bad' ], qr/error: invalid WAL location/, 'invalid end LSN');
26+
27+
# rmgr list: If you add one to the list, consider also adding a test
28+
# case exercising the new rmgr below.
29+
command_like([ 'pg_waldump', '--rmgr=list'], qr/^XLOG
30+
Transaction
31+
Storage
32+
CLOG
33+
Database
34+
Tablespace
35+
MultiXact
36+
RelMap
37+
Standby
38+
Heap2
39+
Heap
40+
Btree
41+
Hash
42+
Gin
43+
Gist
44+
Sequence
45+
SPGist
46+
BRIN
47+
CommitTs
48+
ReplicationOrigin
49+
Generic
50+
LogicalMessage$/,
51+
'rmgr list');
52+
53+
54+
my $node = PostgreSQL::Test::Cluster->new('main');
55+
$node->init;
56+
$node->append_conf('postgresql.conf', q{
57+
autovacuum = off
58+
checkpoint_timeout = 1h
59+
60+
# for standbydesc
61+
archive_mode=on
62+
archive_command=''
63+
64+
# for XLOG_HEAP_TRUNCATE
65+
wal_level=logical
66+
});
67+
$node->start;
68+
69+
my ($start_lsn, $start_walfile) = split /\|/, $node->safe_psql('postgres', q{SELECT pg_current_wal_insert_lsn(), pg_walfile_name(pg_current_wal_insert_lsn())});
70+
71+
$node->safe_psql('postgres', q{
72+
-- heap, btree, hash, sequence
73+
CREATE TABLE t1 (a int GENERATED ALWAYS AS IDENTITY, b text);
74+
CREATE INDEX i1a ON t1 USING btree (a);
75+
CREATE INDEX i1b ON t1 USING hash (b);
76+
INSERT INTO t1 VALUES (default, 'one'), (default, 'two');
77+
DELETE FROM t1 WHERE b = 'one';
78+
TRUNCATE t1;
79+
80+
-- abort
81+
START TRANSACTION;
82+
INSERT INTO t1 VALUES (default, 'three');
83+
ROLLBACK;
84+
85+
-- unlogged/init fork
86+
CREATE UNLOGGED TABLE t2 (x int);
87+
CREATE INDEX i2 ON t2 USING btree (x);
88+
INSERT INTO t2 SELECT generate_series(1, 10);
89+
90+
-- gin
91+
CREATE TABLE gin_idx_tbl (id bigserial PRIMARY KEY, data jsonb);
92+
CREATE INDEX gin_idx ON gin_idx_tbl USING gin (data);
93+
INSERT INTO gin_idx_tbl
94+
WITH random_json AS (
95+
SELECT json_object_agg(key, trunc(random() * 10)) as json_data
96+
FROM unnest(array['a', 'b', 'c']) as u(key))
97+
SELECT generate_series(1,500), json_data FROM random_json;
98+
99+
-- gist, spgist
100+
CREATE TABLE gist_idx_tbl (p point);
101+
CREATE INDEX gist_idx ON gist_idx_tbl USING gist (p);
102+
CREATE INDEX spgist_idx ON gist_idx_tbl USING spgist (p);
103+
INSERT INTO gist_idx_tbl (p) VALUES (point '(1, 1)'), (point '(3, 2)'), (point '(6, 3)');
104+
105+
-- brin
106+
CREATE TABLE brin_idx_tbl (col1 int, col2 text, col3 text );
107+
CREATE INDEX brin_idx ON brin_idx_tbl USING brin (col1, col2, col3) WITH (autosummarize=on);
108+
INSERT INTO brin_idx_tbl SELECT generate_series(1, 10000), 'dummy', 'dummy';
109+
UPDATE brin_idx_tbl SET col2 = 'updated' WHERE col1 BETWEEN 1 AND 5000;
110+
SELECT brin_summarize_range('brin_idx', 0);
111+
SELECT brin_desummarize_range('brin_idx', 0);
112+
113+
VACUUM;
114+
115+
-- logical message
116+
SELECT pg_logical_emit_message(true, 'foo', 'bar');
117+
118+
-- relmap
119+
VACUUM FULL pg_authid;
120+
121+
-- database
122+
CREATE DATABASE d1;
123+
DROP DATABASE d1;
124+
});
125+
126+
my $tblspc_path = PostgreSQL::Test::Utils::tempdir_short();
127+
128+
$node->safe_psql('postgres', qq{
129+
CREATE TABLESPACE ts1 LOCATION '$tblspc_path';
130+
DROP TABLESPACE ts1;
131+
});
132+
133+
my ($end_lsn, $end_walfile) = split /\|/, $node->safe_psql('postgres', q{SELECT pg_current_wal_insert_lsn(), pg_walfile_name(pg_current_wal_insert_lsn())});
134+
135+
my $default_ts_oid = $node->safe_psql('postgres', q{SELECT oid FROM pg_tablespace WHERE spcname = 'pg_default'});
136+
my $postgres_db_oid = $node->safe_psql('postgres', q{SELECT oid FROM pg_database WHERE datname = 'postgres'});
137+
my $rel_t1_oid = $node->safe_psql('postgres', q{SELECT oid FROM pg_class WHERE relname = 't1'});
138+
my $rel_i1a_oid = $node->safe_psql('postgres', q{SELECT oid FROM pg_class WHERE relname = 'i1a'});
139+
140+
$node->stop;
141+
142+
143+
# various ways of specifying WAL range
144+
command_fails_like([ 'pg_waldump', 'foo', 'bar' ], qr/error: could not locate WAL file "foo"/, 'start file not found');
145+
command_like([ 'pg_waldump', $node->data_dir . '/pg_wal/' . $start_walfile ], qr/./, 'runs with start segment specified');
146+
command_fails_like([ 'pg_waldump', $node->data_dir . '/pg_wal/' . $start_walfile, 'bar' ], qr/error: could not open file "bar"/, 'end file not found');
147+
command_like([ 'pg_waldump', $node->data_dir . '/pg_wal/' . $start_walfile, $node->data_dir . '/pg_wal/' . $end_walfile ], qr/./, 'runs with start and end segment specified');
148+
command_fails_like([ 'pg_waldump', '-p', $node->data_dir ], qr/error: no start WAL location given/, 'path option requires start location');
149+
command_like([ 'pg_waldump', '-p', $node->data_dir, '--start', $start_lsn, '--end', $end_lsn ], qr/./, 'runs with path option and start and end locations');
150+
command_fails_like([ 'pg_waldump', '-p', $node->data_dir, '--start', $start_lsn ], qr/error: error in WAL record at/, 'falling off the end of the WAL results in an error');
151+
152+
command_like([ 'pg_waldump', '--quiet', $node->data_dir . '/pg_wal/' . $start_walfile ], qr/^$/, 'no output with --quiet option');
153+
command_fails_like([ 'pg_waldump', '--quiet', '-p', $node->data_dir, '--start', $start_lsn ], qr/error: error in WAL record at/, 'errors are shown with --quiet');
154+
155+
156+
# Helper function to test various options. Pass options as arguments.
157+
# Output lines are returned as array.
158+
sub test_pg_waldump
159+
{
160+
local $Test::Builder::Level = $Test::Builder::Level + 1;
161+
my @opts = @_;
162+
163+
my (@cmd, $stdout, $stderr, $result, @lines);
164+
165+
@cmd = ('pg_waldump', '-p', $node->data_dir, '--start', $start_lsn, '--end', $end_lsn);
166+
push @cmd, @opts;
167+
$result = IPC::Run::run \@cmd, '>', \$stdout, '2>', \$stderr;
168+
ok($result, "pg_waldump @opts: runs ok");
169+
is($stderr, '', "pg_waldump @opts: no stderr");
170+
@lines = split /\n/, $stdout;
171+
ok(@lines > 0, "pg_waldump @opts: some lines are output");
172+
return @lines;
173+
}
174+
175+
my @lines;
176+
177+
@lines = test_pg_waldump;
178+
is(grep(!/^rmgr: \w/, @lines), 0, 'all output lines are rmgr lines');
179+
180+
@lines = test_pg_waldump('--limit', 6);
181+
is(@lines, 6, 'limit option observed');
182+
183+
@lines = test_pg_waldump('--fullpage');
184+
is(grep(!/^rmgr:.*\bFPW\b/, @lines), 0, 'all output lines are FPW');
185+
186+
@lines = test_pg_waldump('--stats');
187+
like($lines[0], qr/WAL statistics/, "statistics on stdout");
188+
is(grep(/^rmgr:/, @lines), 0, 'no rmgr lines output');
189+
190+
@lines = test_pg_waldump('--stats=record');
191+
like($lines[0], qr/WAL statistics/, "statistics on stdout");
192+
is(grep(/^rmgr:/, @lines), 0, 'no rmgr lines output');
193+
194+
@lines = test_pg_waldump('--rmgr', 'Btree');
195+
is(grep(!/^rmgr: Btree/, @lines), 0, 'only Btree lines');
196+
197+
@lines = test_pg_waldump('--fork', 'init');
198+
is(grep(!/fork init/, @lines), 0, 'only init fork lines');
199+
200+
@lines = test_pg_waldump('--relation', "$default_ts_oid/$postgres_db_oid/$rel_t1_oid");
201+
is(grep(!/rel $default_ts_oid\/$postgres_db_oid\/$rel_t1_oid/, @lines), 0, 'only lines for selected relation');
202+
203+
@lines = test_pg_waldump('--relation', "$default_ts_oid/$postgres_db_oid/$rel_i1a_oid", '--block', 1);
204+
is(grep(!/\bblk 1\b/, @lines), 0, 'only lines for selected block');
205+
206+
13207
done_testing();

0 commit comments

Comments
 (0)