I wrote a few more small tests for psql to address uncovered territory
in SendQuery() especially:
- \timing
- client encoding handling
- notifications
What's still missing is:
- \watch
- pagers
For \watch, I think one would need something like the current cancel
test (since you need to get the psql pid to send a signal to stop the
watch). It would work in principle, but it will require more work to
refactor the cancel test.
For pagers, I don't know. I would be pretty easy to write a simple
script that acts as a pass-through pager and check that it is called.
There were some discussions earlier in the thread that some version of
some patch had broken some use of pagers. Does anyone remember details?
Anything worth testing specifically?From 6e75c1bec73f2128b94131305e6a37b97257f7c3 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 22 Feb 2022 13:42:38 +0100
Subject: [PATCH 1/2] Improve some psql test code
Split psql_like() into two functions psql_like() and psql_fails_like()
and make them mirror the existing command_like() and
command_fails_like() more closely. In particular, follow the
universal convention that the test name is the last argument.
---
src/bin/psql/t/001_basic.pl | 59 ++++++++++++++++++-------------------
1 file changed, 29 insertions(+), 30 deletions(-)
diff --git a/src/bin/psql/t/001_basic.pl b/src/bin/psql/t/001_basic.pl
index ba3dd846ba..f416e0ab5e 100644
--- a/src/bin/psql/t/001_basic.pl
+++ b/src/bin/psql/t/001_basic.pl
@@ -12,40 +12,36 @@
program_version_ok('psql');
program_options_handling_ok('psql');
-my ($stdout, $stderr);
-my $result;
-
-# Execute a psql command and check its result patterns.
+# Execute a psql command and check its output.
sub psql_like
{
local $Test::Builder::Level = $Test::Builder::Level + 1;
- my $node = shift;
- my $test_name = shift;
- my $query = shift;
- my $expected_stdout = shift;
- my $expected_stderr = shift;
+ my ($node, $sql, $expected_stdout, $test_name) = @_;
+
+ my ($ret, $stdout, $stderr) = $node->psql('postgres', $sql);
+
+ is($ret, 0, "$test_name: exit code 0");
+ is($stderr, '', "$test_name: no stderr");
+ like($stdout, $expected_stdout, "$test_name: matches");
+
+ return;
+}
+
+# Execute a psql command and check that it fails and check the stderr.
+sub psql_fails_like
+{
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
- die "cannot specify both expected stdout and stderr here"
- if (defined($expected_stdout) && defined($expected_stderr));
+ my ($node, $sql, $expected_stderr, $test_name) = @_;
# Use the context of a WAL sender, some of the tests rely on that.
my ($ret, $stdout, $stderr) = $node->psql(
- 'postgres', $query,
- on_error_die => 0,
+ 'postgres', $sql,
replication => 'database');
- if (defined($expected_stdout))
- {
- is($ret, 0, "$test_name: expected result code");
- is($stderr, '', "$test_name: no stderr");
- like($stdout, $expected_stdout, "$test_name: stdout matches");
- }
- if (defined($expected_stderr))
- {
- isnt($ret, 0, "$test_name: expected result code");
- like($stderr, $expected_stderr, "$test_name: stderr matches");
- }
+ isnt($ret, 0, "$test_name: exit code not 0");
+ like($stderr, $expected_stderr, "$test_name: matches");
return;
}
@@ -53,6 +49,9 @@ sub psql_like
# test --help=foo, analogous to program_help_ok()
foreach my $arg (qw(commands variables))
{
+ my ($stdout, $stderr);
+ my $result;
+
$result = IPC::Run::run [ 'psql', "--help=$arg" ], '>', \$stdout, '2>',
\$stderr;
ok($result, "psql --help=$arg exit code 0");
@@ -70,15 +69,15 @@ sub psql_like
});
$node->start;
-psql_like($node, '\copyright', '\copyright', qr/Copyright/, undef);
-psql_like($node, '\help without arguments', '\help', qr/ALTER/, undef);
-psql_like($node, '\help with argument', '\help SELECT', qr/SELECT/, undef);
+psql_like($node, '\copyright', qr/Copyright/, '\copyright');
+psql_like($node, '\help', qr/ALTER/, '\help without arguments');
+psql_like($node, '\help SELECT', qr/SELECT/, '\help with argument');
# Test clean handling of unsupported replication command responses
-psql_like(
+psql_fails_like(
$node,
- 'handling of unexpected PQresultStatus',
'START_REPLICATION 0/0',
- undef, qr/unexpected PQresultStatus: 8$/);
+ qr/unexpected PQresultStatus: 8$/,
+ 'handling of unexpected PQresultStatus');
done_testing();
--
2.35.1
From 189e977e47c505230195551833e0a61ec71dced3 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 22 Feb 2022 14:20:05 +0100
Subject: [PATCH 2/2] psql: Additional tests
Add a few TAP tests for things that happen while a user query is being sent:
- \timing
- client encoding handling
- notifications
---
src/bin/psql/t/001_basic.pl | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/src/bin/psql/t/001_basic.pl b/src/bin/psql/t/001_basic.pl
index f416e0ab5e..44ecd05add 100644
--- a/src/bin/psql/t/001_basic.pl
+++ b/src/bin/psql/t/001_basic.pl
@@ -60,7 +60,7 @@ sub psql_fails_like
}
my $node = PostgreSQL::Test::Cluster->new('main');
-$node->init;
+$node->init(extra => [ '--locale=C', '--encoding=UTF8' ]);
$node->append_conf(
'postgresql.conf', q{
wal_level = 'logical'
@@ -80,4 +80,39 @@ sub psql_fails_like
qr/unexpected PQresultStatus: 8$/,
'handling of unexpected PQresultStatus');
+# test \timing
+psql_like(
+ $node,
+ '\timing on
+SELECT 1',
+ qr/^1$
+^Time: \d+.\d\d\d ms/m,
+ '\timing');
+
+# test that ENCODING variable is set and that it is updated when
+# client encoding is changed
+psql_like(
+ $node,
+ '\echo :ENCODING
+set client_encoding = LATIN1;
+\echo :ENCODING',
+ qr/^UTF8$
+^LATIN1$/m,
+ 'ENCODING variable is set and updated');
+
+# test LISTEN/NOTIFY
+psql_like(
+ $node,
+ 'LISTEN foo;
+NOTIFY foo;',
+ qr/^Asynchronous notification "foo" received from server process with
PID \d+\.$/,
+ 'notification');
+
+psql_like(
+ $node,
+ "LISTEN foo;
+NOTIFY foo, 'bar';",
+ qr/^Asynchronous notification "foo" with payload "bar" received from
server process with PID \d+\.$/,
+ 'notification with payload');
+
done_testing();
--
2.35.1