From f6d2d607aa0712b3d31f6d32f67c6bea29cc9242 Mon Sep 17 00:00:00 2001
From: Sehrope Sarkuni <sehrope@jackdb.com>
Date: Fri, 28 Aug 2026 23:57:26 +0000
Subject: [PATCH] Speed up pg_waldump TAP test

Most of the runtime was spent decoding and printing the full WAL range
over a dozen times per scenario. Decode it once and use --limit or a
start LSN near the end everywhere else.
---
 src/bin/pg_waldump/t/001_basic.pl | 69 +++++++++++++++++++++----------
 1 file changed, 48 insertions(+), 21 deletions(-)

diff --git a/src/bin/pg_waldump/t/001_basic.pl b/src/bin/pg_waldump/t/001_basic.pl
index 4fa507cfa20..5b0556bb9f0 100644
--- a/src/bin/pg_waldump/t/001_basic.pl
+++ b/src/bin/pg_waldump/t/001_basic.pl
@@ -243,8 +243,14 @@ command_fails_like(
 	[ 'pg_waldump', 'foo', 'bar' ],
 	qr/error: could not locate WAL file "foo"/,
 	'start file not found');
-command_like([ 'pg_waldump', $node->data_dir . '/pg_wal/' . $start_walfile ],
-	qr/./, 'runs with start segment specified');
+command_like(
+	[
+		'pg_waldump',
+		'--limit' => 1,
+		$node->data_dir . '/pg_wal/' . $start_walfile
+	],
+	qr/./,
+	'runs with start segment specified');
 command_fails_like(
 	[ 'pg_waldump', $node->data_dir . '/pg_wal/' . $start_walfile, 'bar' ],
 	qr/error: could not open file "bar"/,
@@ -252,6 +258,7 @@ command_fails_like(
 command_like(
 	[
 		'pg_waldump',
+		'--limit' => 1,
 		$node->data_dir . '/pg_wal/' . $start_walfile,
 		$node->data_dir . '/pg_wal/' . $end_walfile
 	],
@@ -260,6 +267,7 @@ command_like(
 command_like(
 	[
 		'pg_waldump', '--quiet',
+		'--limit' => 1,
 		'--path', $node->data_dir . '/pg_wal/',
 		$start_walfile
 	],
@@ -313,6 +321,7 @@ sub test_pg_waldump_skip_bytes
 		'--start' => $new_start,
 		'--end' => $endlsn,
 		'--path' => $path,
+		'--limit' => 1,
 	  ],
 	  '>' => \$stdout,
 	  '2>' => \$stderr;
@@ -370,6 +379,12 @@ sub generate_archive
 	chdir($cwd) || die "chdir: $!";
 }
 
+# Decode the full range once; everything below stops after a few records.
+{
+	my @lines = test_pg_waldump($node->data_dir, $start_lsn, $end_lsn);
+	is(grep(!/^rmgr: \w/, @lines), 0, 'all output lines are rmgr lines');
+}
+
 my $tmp_dir = PostgreSQL::Test::Utils::tempdir_short();
 
 my @scenarios = (
@@ -399,11 +414,11 @@ for my $scenario (@scenarios)
 
   SKIP:
 	{
-		skip "tar command is not available", 56
+		skip "tar command is not available", 52
 		  if (!defined $tar || $tar eq '') && $scenario->{'is_archive'};
 		skip
 		  "$scenario->{'compression_method'} compression not supported by this build",
-		  56
+		  52
 		  if !$scenario->{'enabled'} && $scenario->{'is_archive'};
 
 		# create pg_wal archive
@@ -425,6 +440,7 @@ for my $scenario (@scenarios)
 				'--path' => $path,
 				'--start' => $start_lsn,
 				'--end' => $end_lsn,
+				'--limit' => 1,
 			],
 			qr/./,
 			'runs with path option and start and end locations');
@@ -432,7 +448,7 @@ for my $scenario (@scenarios)
 			[
 				'pg_waldump',
 				'--path' => $path,
-				'--start' => $start_lsn,
+				'--start' => $contrecord_lsn,
 			],
 			qr/error: error in WAL record at/,
 			'falling off the end of the WAL results in an error');
@@ -441,17 +457,14 @@ for my $scenario (@scenarios)
 			[
 				'pg_waldump', '--quiet',
 				'--path' => $path,
-				'--start' => $start_lsn
+				'--start' => $contrecord_lsn
 			],
 			qr/error: error in WAL record at/,
 			'errors are shown with --quiet');
 
 		test_pg_waldump_skip_bytes($path, $start_lsn, $end_lsn);
 
-		my @lines = test_pg_waldump($path, $start_lsn, $end_lsn);
-		is(grep(!/^rmgr: \w/, @lines), 0, 'all output lines are rmgr lines');
-
-		@lines = test_pg_waldump($path, $contrecord_lsn, $end_lsn);
+		my @lines = test_pg_waldump($path, $contrecord_lsn, $end_lsn);
 		is(grep(!/^rmgr: \w/, @lines), 0, 'all output lines are rmgr lines');
 
 		test_pg_waldump_skip_bytes($path, $contrecord_lsn, $end_lsn);
@@ -459,28 +472,41 @@ for my $scenario (@scenarios)
 		@lines = test_pg_waldump($path, $start_lsn, $end_lsn, '--limit' => 6);
 		is(@lines, 6, 'limit option observed');
 
-		@lines = test_pg_waldump($path, $start_lsn, $end_lsn, '--fullpage');
+		@lines = test_pg_waldump($path, $start_lsn, $end_lsn,
+			'--fullpage', '--limit' => 5);
 		is(grep(!/^rmgr:.*\bFPW\b/, @lines), 0, 'all output lines are FPW');
 
-		@lines = test_pg_waldump($path, $start_lsn, $end_lsn, '--stats');
+		# --limit must come before a bare --stats: src/port/getopt_long.c,
+		# used on Windows, skips the argument after an optional_argument
+		# option given without "=".  Drop the ordering once that is fixed.
+		@lines = test_pg_waldump(
+			$path, $start_lsn, $end_lsn,
+			'--limit' => 5,
+			'--stats');
 		like($lines[0], qr/WAL statistics/, "statistics on stdout");
 		is(grep(/^rmgr:/, @lines), 0, 'no rmgr lines output');
 
-		@lines =
-		  test_pg_waldump($path, $start_lsn, $end_lsn, '--stats=record');
+		@lines = test_pg_waldump($path, $start_lsn, $end_lsn,
+			'--stats=record', '--limit' => 5);
 		like($lines[0], qr/WAL statistics/, "statistics on stdout");
 		is(grep(/^rmgr:/, @lines), 0, 'no rmgr lines output');
 
-		@lines =
-		  test_pg_waldump($path, $start_lsn, $end_lsn, '--rmgr' => 'Btree');
+		@lines = test_pg_waldump(
+			$path, $start_lsn, $end_lsn,
+			'--rmgr' => 'Btree',
+			'--limit' => 5);
 		is(grep(!/^rmgr: Btree/, @lines), 0, 'only Btree lines');
 
-		@lines =
-		  test_pg_waldump($path, $start_lsn, $end_lsn, '--fork' => 'init');
+		@lines = test_pg_waldump(
+			$path, $start_lsn, $end_lsn,
+			'--fork' => 'init',
+			'--limit' => 1);
 		is(grep(!/fork init/, @lines), 0, 'only init fork lines');
 
-		@lines = test_pg_waldump($path, $start_lsn, $end_lsn,
-			'--relation' => "$default_ts_oid/$postgres_db_oid/$rel_t1_oid");
+		@lines = test_pg_waldump(
+			$path, $start_lsn, $end_lsn,
+			'--relation' => "$default_ts_oid/$postgres_db_oid/$rel_t1_oid",
+			'--limit' => 1);
 		is( grep(!/rel $default_ts_oid\/$postgres_db_oid\/$rel_t1_oid/,
 				@lines),
 			0,
@@ -489,7 +515,8 @@ for my $scenario (@scenarios)
 		@lines = test_pg_waldump(
 			$path, $start_lsn, $end_lsn,
 			'--relation' => "$default_ts_oid/$postgres_db_oid/$rel_i1a_oid",
-			'--block' => 1);
+			'--block' => 1,
+			'--limit' => 1);
 		is(grep(!/\bblk 1\b/, @lines), 0, 'only lines for selected block');
 
 		# Cleanup.
-- 
2.55.0

