Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 96063e2

Browse filesBrowse 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
Copy full SHA for 96063e2

File tree

1 file changed

+194
-0
lines changed
Filter options

1 file changed

+194
-0
lines changed

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

Copy file name to clipboardExpand all lines: src/bin/pg_waldump/t/001_basic.pl
+194Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.