On Sun, Feb 06, 2022 at 09:04:14PM -0600, Justin Pryzby wrote:
> Your test is checking that stuff in sample.conf is actually a GUC and not
> marked NOT_IN_SAMPLE.  But those are both unlikely mistakes to make.

Yeah, you are right.  Still, I don't see any reason to not include both.

> I'd first parse the GUC-like lines in the file, making a list of gucs_in_file
> and then compare the two lists.

This is a good idea, and makes the tests faster because there is no
need to test each GUC separately.  While testing a bit more, I got
recalled by the fact that config_file is not marked as NOT_IN_SAMPLE
and not in postgresql.conf.sample, so the new case you suggested was
failing.

What do you think about the updated version attached?  I have applied
the addition of config_data() separately.
--
Michael
From dd9f0cb34960e89dd1ea5c12ab03ee1bc6884e1f Mon Sep 17 00:00:00 2001
From: Michael Paquier <mich...@paquier.xyz>
Date: Tue, 8 Feb 2022 10:10:42 +0900
Subject: [PATCH v2] Add TAP test to automate check_guc

---
 src/test/modules/test_misc/t/003_check_guc.pl | 105 ++++++++++++++++++
 1 file changed, 105 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..01f954e09c
--- /dev/null
+++ b/src/test/modules/test_misc/t/003_check_guc.pl
@@ -0,0 +1,105 @@
+# 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 tests => 3;
+
+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.  config_file is an exception.  It is not
+# in postgresql.conf.sample but is part of the lists from guc.c.
+my $all_params = $node->safe_psql(
+	'postgres',
+	"SELECT name
+     FROM pg_settings
+   WHERE NOT 'NOT_IN_SAMPLE' = ANY (pg_settings_get_flags(name)) AND
+       name <> 'config_file'
+     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';
+
+# List of all the GUCs found in the sample file.
+my @gucs_in_file;
+
+# Read the sample file line-by-line, checking its contents to build a list
+# of everything known as a GUC.
+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";
+
+		# Update the list of GUCs found in the sample file, for the
+		# follow-up tests.
+		push @gucs_in_file, $param_name;
+	}
+}
+
+close $contents;
+
+# Cross-check that all the GUCs found in the sample file match the ones
+# fetched above.  This maps the arrays to a hash, making the creation of
+# each exclude and intersection list easier.
+my %gucs_in_file_hash  = map { $_ => 1 } @gucs_in_file;
+my %all_params_hash    = map { $_ => 1 } @all_params_array;
+my %not_in_sample_hash = map { $_ => 1 } @not_in_sample_array;
+
+my @missing_from_file = grep(!$gucs_in_file_hash{$_}, @all_params_array);
+is(scalar(@missing_from_file),
+	0, "no parameters missing from postgresql.conf.sample");
+
+my @missing_from_list = grep(!$all_params_hash{$_}, @gucs_in_file);
+is(scalar(@missing_from_list), 0, "no parameters missing from guc.c");
+
+my @sample_intersect = grep($not_in_sample_hash{$_}, @gucs_in_file);
+is(scalar(@sample_intersect),
+	0, "no parameters marked as NOT_IN_SAMPLE in postgresql.conf.sample");
+
+# These would log some information only on errors.
+foreach my $param (@missing_from_file)
+{
+	print("found GUC $param in guc.c, missing from postgresql.conf.sample\n");
+}
+foreach my $param (@missing_from_list)
+{
+	print(
+		"found GUC $param in postgresql.conf.sample, with incorrect info in guc.c\n"
+	);
+}
+foreach my $param (@sample_intersect)
+{
+	print(
+		"found GUC $param in postgresql.conf.sample, marked as NOT_IN_SAMPLE\n"
+	);
+}
-- 
2.34.1

Attachment: signature.asc
Description: PGP signature

Reply via email to