On Sun, Feb 06, 2022 at 02:09:45PM +0900, Michael Paquier wrote:
> Actually, I am thinking that we should implement it before retiring
> completely check_guc, but not in the fashion you are suggesting.  I
> would be tempted to add something in the TAP tests as of
> src/test/misc/, where we initialize an instance to get the information
> about all the GUCs from SQL, and map that to the sample file located
> at pg_config --sharedir.  I actually have in my patch set for
> pg_upgrade's TAP a perl routine that could be used for this purpose,
> as of the following in Cluster.pm:

I have been poking at that, and this is finishing to be pretty
elegant as of the attached.  With this in place, we are able to
cross-check GUCs marked as NOT_IN_SAMPLE (or not) with the contents of 
postgresql.conf.sample, so as check_guc could get retired without us
losing much.

I am planning to apply the Cluster.pm part of the patch separately,
for clarity, as I want this routine in place for some other patch.
--
Michael
From 5c3fbf6af5111927aa7a61025abfce87a9bd230e Mon Sep 17 00:00:00 2001
From: Michael Paquier <mich...@paquier.xyz>
Date: Mon, 7 Feb 2022 11:32:17 +0900
Subject: [PATCH] Add TAP test to automate check_guc

---
 src/test/modules/test_misc/t/003_check_guc.pl | 77 +++++++++++++++++++
 src/test/perl/PostgreSQL/Test/Cluster.pm      | 25 ++++++
 2 files changed, 102 insertions(+)
 create mode 100644 src/test/modules/test_misc/t/003_check_guc.pl

diff --git a/src/test/modules/test_misc/t/003_check_guc.pl b/src/test/modules/test_misc/t/003_check_guc.pl
new file mode 100644
index 0000000000..cd64fb8b49
--- /dev/null
+++ b/src/test/modules/test_misc/t/003_check_guc.pl
@@ -0,0 +1,77 @@
+# Tests to cross-check the consistency of GUC parameters with
+# postgresql.conf.sample.
+
+use strict;
+use warnings;
+use PostgreSQL::Test::Cluster;
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+my $node = PostgreSQL::Test::Cluster->new('main');
+$node->init;
+$node->start;
+
+# Grab the names of all the parameters that can be listed in the
+# configuration sample file.
+my $all_params = $node->safe_psql(
+	'postgres',
+	"SELECT name
+     FROM pg_settings
+   WHERE NOT 'NOT_IN_SAMPLE' = ANY (pg_settings_get_flags(name))
+     ORDER BY 1");
+# Note the lower-case conversion, for consistency.
+my @all_params_array = split("\n", lc($all_params));
+
+# Grab the names of all parameters marked as NOT_IN_SAMPLE.
+my $not_in_sample = $node->safe_psql(
+	'postgres',
+	"SELECT name
+     FROM pg_settings
+   WHERE 'NOT_IN_SAMPLE' = ANY (pg_settings_get_flags(name))
+     ORDER BY 1");
+# Note the lower-case conversion, for consistency.
+my @not_in_sample_array = split("\n", lc($not_in_sample));
+
+# Find the location of postgresql.conf.sample, based on the information
+# provided by pg_config.
+my $sample_file =
+  $node->config_data('--sharedir') . '/postgresql.conf.sample';
+
+# Read the sample file line-by-line, checking its contents.
+my $num_tests = 0;
+open(my $contents, '<', $sample_file)
+  || die "Could not open $sample_file: $!";
+while (my $line = <$contents>)
+{
+	# Check if this line matches a GUC parameter.
+	if ($line =~ m/^#?([_[:alpha:]]+) (= .*|[^ ]*$)/)
+	{
+		# Lower-case conversion matters for some of the GUCs.
+		my $param_name = lc($1);
+
+		# Ignore some exceptions.
+		next if $param_name eq "include";
+		next if $param_name eq "include_dir";
+		next if $param_name eq "include_if_exists";
+
+		my $marked_all_params = grep(/^$param_name$/, @all_params_array);
+		my $marked_not_in_sample =
+		  grep(/^$param_name$/, @not_in_sample_array);
+
+		# All parameters marked as NOT_IN_SAMPLE cannot be in
+		# the sample file.
+		is($marked_not_in_sample, 0,
+			"checked $param_name not marked with NOT_IN_SAMPLE");
+		# All parameters *not* marked as NOT_IN_SAMPLE can be
+		# in the sample file.
+		is($marked_all_params, 1,
+			"checked $param_name in postgresql.conf.sample");
+
+		# Update test count.
+		$num_tests += 2;
+	}
+}
+
+close $contents;
+
+plan tests => $num_tests;
diff --git a/src/test/perl/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pm
index 265f3ae657..832d119f2e 100644
--- a/src/test/perl/PostgreSQL/Test/Cluster.pm
+++ b/src/test/perl/PostgreSQL/Test/Cluster.pm
@@ -327,6 +327,31 @@ sub install_path
 
 =pod
 
+=item $node->config_data($option)
+
+Grab some data from pg_config, with $option being the option switch
+used to grab the wanted data.
+
+=cut
+
+sub config_data
+{
+	my ($self, $option) = @_;
+	local %ENV = $self->_get_env();
+
+	my ($stdout, $stderr);
+	my $result =
+	  IPC::Run::run [ $self->installed_command('pg_config'), $option ],
+	  '>', \$stdout, '2>', \$stderr
+	  or die "could not execute pg_config";
+	chomp($stdout);
+	$stdout =~ s/\r$//;
+
+	return $stdout;
+}
+
+=pod
+
 =item $node->info()
 
 Return a string containing human-readable diagnostic information (paths, etc)
-- 
2.34.1

Attachment: signature.asc
Description: PGP signature

Reply via email to