From 524bf580185dd86d8818ad5092f9f285951b49ae Mon Sep 17 00:00:00 2001 From: Mark Dilger Date: Wed, 31 Mar 2021 19:19:26 -0700 Subject: [PATCH v1 2/2] Adding modules/test_cross_version This creates a framework for checking interactions between various installed versions of PostgreSQL. This is still very much a work in progress. --- src/test/modules/Makefile | 1 + .../test_cross_version/CrossVersion.pm | 115 ++++++++++++++++++ src/test/modules/test_cross_version/Makefile | 20 +++ src/test/modules/test_cross_version/README | 15 +++ .../test_cross_version/t/001_verify_paths.pl | 42 +++++++ .../test_cross_version.control | 5 + .../modules/test_cross_version/versions.dat | 32 +++++ 7 files changed, 230 insertions(+) create mode 100644 src/test/modules/test_cross_version/CrossVersion.pm create mode 100644 src/test/modules/test_cross_version/Makefile create mode 100644 src/test/modules/test_cross_version/README create mode 100644 src/test/modules/test_cross_version/t/001_verify_paths.pl create mode 100644 src/test/modules/test_cross_version/test_cross_version.control create mode 100644 src/test/modules/test_cross_version/versions.dat diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile index 93e7829c67..25956f1cb3 100644 --- a/src/test/modules/Makefile +++ b/src/test/modules/Makefile @@ -14,6 +14,7 @@ SUBDIRS = \ plsample \ snapshot_too_old \ test_bloomfilter \ + test_cross_version \ test_ddl_deparse \ test_extensions \ test_ginpostinglist \ diff --git a/src/test/modules/test_cross_version/CrossVersion.pm b/src/test/modules/test_cross_version/CrossVersion.pm new file mode 100644 index 0000000000..55bfbe7833 --- /dev/null +++ b/src/test/modules/test_cross_version/CrossVersion.pm @@ -0,0 +1,115 @@ + +=pod + +=head1 NAME + +CrossVersion - class representing multiple PostgreSQL server version information + +=head1 SYNOPSIS + + use CrossVersion; + +=head1 DESCRIPTION + +CrossVersion + +=cut + +package CrossVersion; + +use strict; +use warnings; +use Test::More; + +sub config_info +{ + my ($node) = @_; + + my %config; + my $node_name = $node->name(); + + local %ENV = $node->_get_env(); + my $fh = IO::File->new("pg_config |") + or BAIL_OUT("Cannot run pg_config for node $node_name: $!"); + while (my $line = <$fh>) + { + if ($line =~ m/^(.+?) = (.*)$/) + { + $config{$1} = $2; + } + else + { + die "Cannot parse config output for node $node_name: $line"; + } + } + + %config; +} + +sub nodes +{ + my ($versions, %params) = @_; + my @parsed; + my %seen; + + $versions = "versions.dat" unless (defined $versions); + + # Parse all name/path pairs + my $fh = IO::File->new($versions) + or BAIL_OUT("Cannot open \"$versions\" for reading: $!"); + while (my $line = <$fh>) + { + # Strip comments + $line =~ s/\s*#.*$//; + + # Skip blank lines + next unless $line =~ m/\S/; + + # Node names cannot contain whitespace characters + my $namere = qr/\S+/; + + # Paths must begin and end with non-whitespace characters + my $pathre = qr/\S+(?:.*\S)?/; + + # Data lines should be a name and path, whitespace separated + if ($line =~ m/^\s*($namere)\s+($pathre)\s*$/) + { + my ($node_name, $path) = ($1, $2); + + # PostgresNode will fail with a filesystem error if given the + # same name twice. Complaining here makes it easier for the + # user to debug and fix the problem + BAIL_OUT(sprintf("%s line %d: duplicate node name: %s: previously appeared on line %d", + $versions, $fh->input_line_number, $node_name, $seen{$node_name})) + if ($seen{$node_name}); + + # # PostgresNode will happily create a node for a bogus directory, + # # resulting in harder to debug errors later in the test case. + # # Complain loudly and early if the directory seems wrong. + # BAIL_OUT(sprintf("%s line %d: directory not found: %s", + # $versions, $fh->input_line_number, $path)) + # unless (-d $path); + # BAIL_OUT(sprintf("%s line %d: directory does not appear to be a postgresql installation: %s", + # $versions, $fh->input_line_number, $path)) + # unless (-d "$path/bin" and -x "$path/bin/pg_config"); + + push (@parsed, { node_name => $node_name, path => $path }); + $seen{$node_name} = $fh->input_line_number; + } + else + { + BAIL_OUT(sprintf("syntax error: %s line %d: $line", + $versions, $fh->input_line_number)); + } + } + $fh->close; + + map { PostgresNode->get_new_node($_->{node_name}, + %params, + install_path => $_->{path}) } @parsed; +} + +use strict; +use warnings; + +1; diff --git a/src/test/modules/test_cross_version/Makefile b/src/test/modules/test_cross_version/Makefile new file mode 100644 index 0000000000..1a8113daa0 --- /dev/null +++ b/src/test/modules/test_cross_version/Makefile @@ -0,0 +1,20 @@ +# src/test/modules/test_cross_version/Makefile + +MODULE = test_cross_version +PGFILEDESC = "test_cross_version - Test PostgreSQL across multiple server versions" + +EXTENSION = test_cross_version + +# REGRESS = test_cross_version +TAP_TESTS = 1 + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/test_cross_version +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/test_cross_version/README b/src/test/modules/test_cross_version/README new file mode 100644 index 0000000000..5cfaf115da --- /dev/null +++ b/src/test/modules/test_cross_version/README @@ -0,0 +1,15 @@ +The test_cross_version module exists to perform any tests requiring a database +cluster that has been upgraded from one or more prior versions, or multiple +database clusters running differing versions of PostgreSQL. It is not intended +to be used in production. + +Rationale +========= + +Usage +===== + +Author +====== + +Mark Dilger diff --git a/src/test/modules/test_cross_version/t/001_verify_paths.pl b/src/test/modules/test_cross_version/t/001_verify_paths.pl new file mode 100644 index 0000000000..c289819676 --- /dev/null +++ b/src/test/modules/test_cross_version/t/001_verify_paths.pl @@ -0,0 +1,42 @@ +use strict; +use warnings; + +use Config; +use PostgresNode; +use TestLib; +use Test::More; +use CrossVersion; + +my @nodes = CrossVersion::nodes(); + +# By default, versions.dat is empty and no testing is done +plan skip_all => "No older PostgreSQL installation directories supplied" + unless @nodes; + +# Ok, versions.dat must have contained entries. Calculate how many tests we +# will perform. +plan tests => 4 * scalar(@nodes); + +my $new = get_new_node('new'); + +for my $old (@nodes) +{ + my $name = $old->name(); + + $old->init(); + ok(1, "$name initialize without error"); + + $old->start(); + ok(1, "$name starts without error"); + + my $oldname = $old->name(); + + my $oldport = $old->port(); + + # old psql => old server + my $result = $old->safe_psql('postgres', 'SHOW port'); + is($result, $oldport, "psql connects to old server on port $oldport"); + + $old->teardown_node(); + ok(1, "$name tears down without error"); +} diff --git a/src/test/modules/test_cross_version/test_cross_version.control b/src/test/modules/test_cross_version/test_cross_version.control new file mode 100644 index 0000000000..2ac2a6935a --- /dev/null +++ b/src/test/modules/test_cross_version/test_cross_version.control @@ -0,0 +1,5 @@ +comment = 'test PostgreSQL across version upgrades' +default_version = '1.0' +module_pathname = '$libdir/test_cross_version' +relocatable = false +trusted = false diff --git a/src/test/modules/test_cross_version/versions.dat b/src/test/modules/test_cross_version/versions.dat new file mode 100644 index 0000000000..2c452ee407 --- /dev/null +++ b/src/test/modules/test_cross_version/versions.dat @@ -0,0 +1,32 @@ +# When testing one or more older versions of PostgreSQL against the version +# being developed, append this file with the paths to all installed older +# PostgreSQL versions you wish to test, one name and path per line. Lines +# starting with a '#' are ignored. Blank lines are ignored. Leading and +# trailing whitespace are ignored. The first non-whitespace token is treated +# as the node name, and everything else (including embedded whitespace) will be +# treated as part of the installation path. +# +# For each PATH, $PATH/bin and $PATH/lib should exist and contain the postgres +# binaries and library files. No support exists for installations configured +# with alternate --bindir or --libdir options. + +### These fail on PostgresNode::start() +### +# 8.4 /Users/mark.dilger/versions/8.4 +# 9.0.23 /Users/mark.dilger/versions/9.0.23 + +### These fail on $old->safe_psql() +### +# 9.1.24 /Users/mark.dilger/versions/9.1.24 +# 9.2.24 /Users/mark.dilger/versions/9.2.24 + +### These work +### +9.3.25 /Users/mark.dilger/versions/9.3.25 +9.4.26 /Users/mark.dilger/versions/9.4.26 +9.5.25 /Users/mark.dilger/versions/9.5.25 +9.6 /Users/mark.dilger/versions/9.6 +10 /Users/mark.dilger/versions/10 +11 /Users/mark.dilger/versions/11 +12 /Users/mark.dilger/versions/12 +13 /Users/mark.dilger/versions/13 -- 2.21.1 (Apple Git-122.3)