From c1db07a8bba54e6b903766585f1b521ef526de12 Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <postgres@jeltef.nl>
Date: Mon, 26 Jan 2026 09:09:11 +0100
Subject: [PATCH v1 2/5] perl tap: Show failed command output

This adds the output of failed commands to the TAP output. Before a
failed libpq_pipeline test would look like this:

  Failed test 'libpq_pipeline cancel'
  at /home/jelte/work/postgres-3/src/test/modules/libpq_pipeline/t/001_libpq_pipeline.pl line 55.

Now you can actually see the reason of the failure:

  Failed test 'libpq_pipeline cancel'
  at /home/jelte/work/postgres-3/src/test/modules/libpq_pipeline/t/001_libpq_pipeline.pl line 55.
----- command failed -----
libpq_pipeline -r 700 cancel port=14309 host=/tmp/htMib451qD dbname='postgres' max_protocol_version=latest
--------- stderr ---------
test cancellations...
libpq_pipeline:315: unexpected number of rows received: 1
--------------------------
---
 src/test/perl/PostgreSQL/Test/Utils.pm | 36 +++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/test/perl/PostgreSQL/Test/Utils.pm b/src/test/perl/PostgreSQL/Test/Utils.pm
index ff843eecc6e..bd1e981c6f0 100644
--- a/src/test/perl/PostgreSQL/Test/Utils.pm
+++ b/src/test/perl/PostgreSQL/Test/Utils.pm
@@ -955,8 +955,22 @@ sub command_ok
 {
 	local $Test::Builder::Level = $Test::Builder::Level + 1;
 	my ($cmd, $test_name) = @_;
-	my $result = run_log($cmd);
-	ok($result, $test_name);
+	# Doesn't rely on detecting end of file on the file descriptors,
+	# which can fail, causing the process to hang, notably on Msys
+	# when used with 'pg_ctl start'
+	my $stdoutfile = File::Temp->new();
+	my $stderrfile = File::Temp->new();
+	my $result = IPC::Run::run $cmd, '>' => $stdoutfile, '2>' => $stderrfile;
+	ok($result, $test_name) or do
+	{
+		my $stdout = slurp_file($stdoutfile);
+		my $stderr = slurp_file($stderrfile);
+		diag("----- command failed -----");
+		diag(join(" ", @$cmd));
+		diag("--------- stdout ---------"), diag($stdout) if $stdout;
+		diag("--------- stderr ---------"), diag($stderr) if $stderr;
+		diag("--------------------------");
+	};
 	return;
 }
 
@@ -972,8 +986,22 @@ sub command_fails
 {
 	local $Test::Builder::Level = $Test::Builder::Level + 1;
 	my ($cmd, $test_name) = @_;
-	my $result = run_log($cmd);
-	ok(!$result, $test_name);
+	# Doesn't rely on detecting end of file on the file descriptors,
+	# which can fail, causing the process to hang, notably on Msys
+	# when used with 'pg_ctl start'
+	my $stdoutfile = File::Temp->new();
+	my $stderrfile = File::Temp->new();
+	my $result = IPC::Run::run $cmd, '>' => $stdoutfile, '2>' => $stderrfile;
+	ok(!$result, $test_name) or do
+	{
+		my $stdout = slurp_file($stdoutfile);
+		my $stderr = slurp_file($stderrfile);
+		diag("-- command succeeded unexpectedly --");
+		diag(join(" ", @$cmd));
+		diag("-------------- stdout --------------"), diag($stdout) if $stdout;
+		diag("-------------- stderr --------------"), diag($stderr) if $stderr;
+		diag("------------------------------------");
+	};
 	return;
 }
 
-- 
2.52.0

