summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Paquier2025-03-27 07:01:38 +0000
committerMichael Paquier2025-03-27 07:01:38 +0000
commit72c2f36d572763201430a35414138c1b9ec3a106 (patch)
tree3b41eabab336c2612f60bb79e831fc591c95d773 /src
parentad9a23bc4f51eea829ee99c7d9940b7ac9f523e3 (diff)
libpq: Add TAP tests for service files and names
This commit adds a set of regression tests that checks various patterns with service names and service files, with: - Service file with no contents, used as default for PGSERVICEFILE to prevent any lookups at the HOME directory of an environment where the test is run. - Service file with valid service name and its section. - Service file at the root of PGSYSCONFDIR, named pg_service.conf. - Missing service file. - Service name defined as a connection parameter or as PGSERVICE. Note that PGSYSCONFDIR is set to always point at a temporary directory created by the test, so as we never try to look at SYSCONFDIR. This set of tests has come up as a useful independent addition while discussing a patch that adds an equivalent of PGSERVICEFILE as a connection parameter as there have never been any tests for service files and service names. Torsten Foertsch and Ryo Kanbayashi have provided a basic implementation, that I have expanded to what is introduced in this commit. Author: Torsten Foertsch <[email protected]> Author: Ryo Kanbayashi <[email protected]> Author: Michael Paquier <[email protected]> Discussion: https://postgr.es/m/CAKkG4_nCjx3a_F3gyXHSPWxD8Sd8URaM89wey7fG_9g7KBkOCQ@mail.gmail.com
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/libpq/meson.build1
-rw-r--r--src/interfaces/libpq/t/006_service.pl141
2 files changed, 142 insertions, 0 deletions
diff --git a/src/interfaces/libpq/meson.build b/src/interfaces/libpq/meson.build
index 19f4a52a97a..292fecf3320 100644
--- a/src/interfaces/libpq/meson.build
+++ b/src/interfaces/libpq/meson.build
@@ -122,6 +122,7 @@ tests += {
't/003_load_balance_host_list.pl',
't/004_load_balance_dns.pl',
't/005_negotiate_encryption.pl',
+ 't/006_service.pl',
],
'env': {
'with_ssl': ssl_library,
diff --git a/src/interfaces/libpq/t/006_service.pl b/src/interfaces/libpq/t/006_service.pl
new file mode 100644
index 00000000000..d3ecfa6b6fc
--- /dev/null
+++ b/src/interfaces/libpq/t/006_service.pl
@@ -0,0 +1,141 @@
+# Copyright (c) 2025, PostgreSQL Global Development Group
+use strict;
+use warnings FATAL => 'all';
+use File::Copy;
+use PostgreSQL::Test::Utils;
+use PostgreSQL::Test::Cluster;
+use Test::More;
+
+# This tests scenarios related to the service name and the service file,
+# for the connection options and their environment variables.
+
+my $node = PostgreSQL::Test::Cluster->new('node');
+$node->init;
+$node->start;
+
+my $td = PostgreSQL::Test::Utils::tempdir;
+
+# Windows vs non-Windows: CRLF vs LF for the file's newline, relying on
+# the fact that libpq uses fgets() when reading the lines of a service file.
+my $newline = $windows_os ? "\r\n" : "\n";
+
+# Create the set of service files used in the tests.
+# File that includes a valid service name, that uses a decomposed connection
+# string for its contents, split on spaces.
+my $srvfile_valid = "$td/pg_service_valid.conf";
+append_to_file($srvfile_valid, "[my_srv]", $newline);
+append_to_file($srvfile_valid, split(/\s+/, $node->connstr) . $newline);
+
+# File defined with no contents, used as default value for PGSERVICEFILE,
+# so as no lookup is attempted in the user's home directory.
+my $srvfile_empty = "$td/pg_service_empty.conf";
+append_to_file($srvfile_empty, '');
+
+# Default service file in PGSYSCONFDIR.
+my $srvfile_default = "$td/pg_service.conf";
+
+# Missing service file.
+my $srvfile_missing = "$td/pg_service_missing.conf";
+
+# Set the fallback directory lookup of the service file to the temporary
+# directory of this test. PGSYSCONFDIR is used if the service file
+# defined in PGSERVICEFILE cannot be found, or when a service file is
+# found but not the service name.
+local $ENV{PGSYSCONFDIR} = $td;
+# Force PGSERVICEFILE to a default location, so as this test never
+# tries to look at a home directory. This value needs to remain
+# at the top of this script before running any tests, and should never
+# be changed.
+local $ENV{PGSERVICEFILE} = "$srvfile_empty";
+
+# Checks combinations of service name and a valid service file.
+{
+ local $ENV{PGSERVICEFILE} = $srvfile_valid;
+ $node->connect_ok(
+ 'service=my_srv',
+ 'connection with correct "service" string and PGSERVICEFILE',
+ sql => "SELECT 'connect1_1'",
+ expected_stdout => qr/connect1_1/);
+
+ $node->connect_ok(
+ 'postgres://?service=my_srv',
+ 'connection with correct "service" URI and PGSERVICEFILE',
+ sql => "SELECT 'connect1_2'",
+ expected_stdout => qr/connect1_2/);
+
+ $node->connect_fails(
+ 'service=undefined-service',
+ 'connection with incorrect "service" string and PGSERVICEFILE',
+ expected_stderr =>
+ qr/definition of service "undefined-service" not found/);
+
+ local $ENV{PGSERVICE} = 'my_srv';
+ $node->connect_ok(
+ '',
+ 'connection with correct PGSERVICE and PGSERVICEFILE',
+ sql => "SELECT 'connect1_3'",
+ expected_stdout => qr/connect1_3/);
+
+ local $ENV{PGSERVICE} = 'undefined-service';
+ $node->connect_fails(
+ '',
+ 'connection with incorrect PGSERVICE and PGSERVICEFILE',
+ expected_stdout =>
+ qr/definition of service "undefined-service" not found/);
+}
+
+# Checks case of incorrect service file.
+{
+ local $ENV{PGSERVICEFILE} = $srvfile_missing;
+ $node->connect_fails(
+ 'service=my_srv',
+ 'connection with correct "service" string and incorrect PGSERVICEFILE',
+ expected_stderr =>
+ qr/service file ".*pg_service_missing.conf" not found/);
+}
+
+# Checks case of service file named "pg_service.conf" in PGSYSCONFDIR.
+{
+ # Create copy of valid file
+ my $srvfile_default = "$td/pg_service.conf";
+ copy($srvfile_valid, $srvfile_default);
+
+ $node->connect_ok(
+ 'service=my_srv',
+ 'connection with correct "service" string and pg_service.conf',
+ sql => "SELECT 'connect2_1'",
+ expected_stdout => qr/connect2_1/);
+
+ $node->connect_ok(
+ 'postgres://?service=my_srv',
+ 'connection with correct "service" URI and default pg_service.conf',
+ sql => "SELECT 'connect2_2'",
+ expected_stdout => qr/connect2_2/);
+
+ $node->connect_fails(
+ 'service=undefined-service',
+ 'connection with incorrect "service" string and default pg_service.conf',
+ expected_stderr =>
+ qr/definition of service "undefined-service" not found/);
+
+ local $ENV{PGSERVICE} = 'my_srv';
+ $node->connect_ok(
+ '',
+ 'connection with correct PGSERVICE and default pg_service.conf',
+ sql => "SELECT 'connect2_3'",
+ expected_stdout => qr/connect2_3/);
+
+ local $ENV{PGSERVICE} = 'undefined-service';
+ $node->connect_fails(
+ '',
+ 'connection with incorrect PGSERVICE and default pg_service.conf',
+ expected_stdout =>
+ qr/definition of service "undefined-service" not found/);
+
+ # Remove default pg_service.conf.
+ unlink($srvfile_default);
+}
+
+$node->teardown_node;
+
+done_testing();