From 038be93902f01976f058fd4c04a590eeab34b043 Mon Sep 17 00:00:00 2001
From: Andrew Dunstan <andrew@dunslane.net>
Date: Fri, 3 Sep 2021 15:10:25 -0400
Subject: [PATCH] move perl test modules to Postgres::Test namespace

---
 contrib/amcheck/t/001_verify_heapam.pl        |   6 +-
 contrib/auto_explain/t/001_auto_explain.pl    |   6 +-
 contrib/bloom/t/001_wal.pl                    |   8 +-
 contrib/oid2name/t/001_basic.pl               |   2 +-
 contrib/test_decoding/t/001_repl_stats.pl     |   6 +-
 contrib/vacuumlo/t/001_basic.pl               |   2 +-
 src/bin/initdb/t/001_initdb.pl                |   6 +-
 src/bin/pg_amcheck/t/001_basic.pl             |   2 +-
 src/bin/pg_amcheck/t/002_nonesuch.pl          |   6 +-
 src/bin/pg_amcheck/t/003_check.pl             |   8 +-
 src/bin/pg_amcheck/t/004_verify_heapam.pl     |   6 +-
 src/bin/pg_amcheck/t/005_opclass_damage.pl    |   6 +-
 .../t/010_pg_archivecleanup.pl                |   4 +-
 src/bin/pg_basebackup/t/010_pg_basebackup.pl  |  18 +--
 src/bin/pg_basebackup/t/020_pg_receivewal.pl  |   6 +-
 src/bin/pg_basebackup/t/030_pg_recvlogical.pl |   6 +-
 src/bin/pg_checksums/t/001_basic.pl           |   2 +-
 src/bin/pg_checksums/t/002_actions.pl         |   8 +-
 src/bin/pg_config/t/001_pg_config.pl          |   2 +-
 .../pg_controldata/t/001_pg_controldata.pl    |   6 +-
 src/bin/pg_ctl/t/001_start_stop.pl            |  14 +-
 src/bin/pg_ctl/t/002_status.pl                |  10 +-
 src/bin/pg_ctl/t/003_promote.pl               |  12 +-
 src/bin/pg_ctl/t/004_logrotate.pl             |   6 +-
 src/bin/pg_dump/t/001_basic.pl                |   8 +-
 src/bin/pg_dump/t/002_pg_dump.pl              |  12 +-
 src/bin/pg_dump/t/003_pg_dump_with_server.pl  |  10 +-
 src/bin/pg_dump/t/010_dump_connstr.pl         |  16 +-
 src/bin/pg_resetwal/t/001_basic.pl            |   6 +-
 src/bin/pg_resetwal/t/002_corrupted.pl        |   6 +-
 src/bin/pg_rewind/t/001_basic.pl              |   2 +-
 src/bin/pg_rewind/t/002_databases.pl          |   2 +-
 src/bin/pg_rewind/t/003_extrafiles.pl         |   2 +-
 src/bin/pg_rewind/t/004_pg_xlog_symlink.pl    |   4 +-
 src/bin/pg_rewind/t/005_same_timeline.pl      |   2 +-
 src/bin/pg_rewind/t/006_options.pl            |   6 +-
 src/bin/pg_rewind/t/007_standby_source.pl     |  10 +-
 src/bin/pg_rewind/t/008_min_recovery_point.pl |  12 +-
 src/bin/pg_rewind/t/RewindTest.pm             |  14 +-
 src/bin/pg_test_fsync/t/001_basic.pl          |   2 +-
 src/bin/pg_test_timing/t/001_basic.pl         |   2 +-
 src/bin/pg_verifybackup/t/001_basic.pl        |   4 +-
 src/bin/pg_verifybackup/t/002_algorithm.pl    |   6 +-
 src/bin/pg_verifybackup/t/003_corruption.pl   |  10 +-
 src/bin/pg_verifybackup/t/004_options.pl      |   6 +-
 src/bin/pg_verifybackup/t/005_bad_manifest.pl |   6 +-
 src/bin/pg_verifybackup/t/006_encoding.pl     |   6 +-
 src/bin/pg_verifybackup/t/007_wal.pl          |   6 +-
 src/bin/pg_waldump/t/001_basic.pl             |   2 +-
 src/bin/pgbench/t/001_pgbench_with_server.pl  |  14 +-
 src/bin/pgbench/t/002_pgbench_no_server.pl    |   4 +-
 src/bin/psql/t/010_tab_completion.pl          |   8 +-
 src/bin/psql/t/020_cancel.pl                  |  10 +-
 src/bin/scripts/t/010_clusterdb.pl            |   6 +-
 src/bin/scripts/t/011_clusterdb_all.pl        |   6 +-
 src/bin/scripts/t/020_createdb.pl             |   6 +-
 src/bin/scripts/t/040_createuser.pl           |   6 +-
 src/bin/scripts/t/050_dropdb.pl               |   6 +-
 src/bin/scripts/t/070_dropuser.pl             |   6 +-
 src/bin/scripts/t/080_pg_isready.pl           |   6 +-
 src/bin/scripts/t/090_reindexdb.pl            |   8 +-
 src/bin/scripts/t/091_reindexdb_all.pl        |   4 +-
 src/bin/scripts/t/100_vacuumdb.pl             |   6 +-
 src/bin/scripts/t/101_vacuumdb_all.pl         |   4 +-
 src/bin/scripts/t/102_vacuumdb_stages.pl      |   4 +-
 src/bin/scripts/t/200_connstr.pl              |   6 +-
 src/test/authentication/t/001_password.pl     |   8 +-
 src/test/authentication/t/002_saslprep.pl     |   6 +-
 src/test/kerberos/t/001_auth.pl               |  24 +--
 src/test/ldap/t/001_auth.pl                   |  24 +--
 src/test/modules/brin/t/01_workitems.pl       |   6 +-
 src/test/modules/commit_ts/t/001_base.pl      |   6 +-
 src/test/modules/commit_ts/t/002_standby.pl   |   8 +-
 src/test/modules/commit_ts/t/003_standby_2.pl |   8 +-
 src/test/modules/commit_ts/t/004_restart.pl   |   6 +-
 .../libpq_pipeline/t/001_libpq_pipeline.pl    |  10 +-
 .../ssl_passphrase_callback/t/001_testfunc.pl |   8 +-
 .../test_misc/t/001_constraint_validation.pl  |   6 +-
 src/test/modules/test_pg_dump/t/001_base.pl   |  12 +-
 src/test/perl/Makefile                        |  22 +--
 .../Test/Cluster.pm}                          | 148 +++++++++---------
 .../{ => Postgres/Test}/PostgresVersion.pm    |  18 +--
 .../perl/{ => Postgres/Test}/RecursiveCopy.pm |  12 +-
 .../perl/{ => Postgres/Test}/SimpleTee.pm     |   2 +-
 .../{TestLib.pm => Postgres/Test/Utils.pm}    |  22 +--
 src/test/perl/README                          |   8 +-
 src/test/recovery/t/001_stream_rep.pl         |  10 +-
 src/test/recovery/t/002_archiving.pl          |  10 +-
 src/test/recovery/t/003_recovery_targets.pl   |  12 +-
 src/test/recovery/t/004_timeline_switch.pl    |  14 +-
 src/test/recovery/t/005_replay_delay.pl       |  10 +-
 src/test/recovery/t/006_logical_decoding.pl   |   6 +-
 src/test/recovery/t/007_sync_rep.pl           |  14 +-
 src/test/recovery/t/008_fsm_truncation.pl     |   8 +-
 src/test/recovery/t/009_twophase.pl           |   8 +-
 .../t/010_logical_decoding_timelines.pl       |   8 +-
 src/test/recovery/t/011_crash_recovery.pl     |   6 +-
 src/test/recovery/t/012_subtransactions.pl    |   8 +-
 src/test/recovery/t/013_crash_restart.pl      |  12 +-
 src/test/recovery/t/014_unlogged_reinit.pl    |  10 +-
 src/test/recovery/t/015_promotion_pages.pl    |   8 +-
 src/test/recovery/t/016_min_consistency.pl    |   8 +-
 src/test/recovery/t/017_shm.pl                |  12 +-
 src/test/recovery/t/018_wal_optimize.pl       |  12 +-
 src/test/recovery/t/019_replslot_limit.pl     |  22 +--
 src/test/recovery/t/020_archive_status.pl     |  12 +-
 src/test/recovery/t/021_row_visibility.pl     |  10 +-
 src/test/recovery/t/022_crash_temp_files.pl   |  12 +-
 src/test/recovery/t/023_pitr_prepared_xact.pl |   8 +-
 src/test/recovery/t/024_archive_recovery.pl   |   8 +-
 .../recovery/t/025_stuck_on_old_timeline.pl   |  16 +-
 src/test/regress/pg_regress.c                 |   2 +-
 src/test/ssl/t/001_ssltests.pl                |   6 +-
 src/test/ssl/t/002_scram.pl                   |   6 +-
 src/test/ssl/t/SSLServer.pm                   |   4 +-
 src/test/subscription/t/001_rep_changes.pl    |   8 +-
 src/test/subscription/t/002_types.pl          |   8 +-
 src/test/subscription/t/003_constraints.pl    |   8 +-
 src/test/subscription/t/004_sync.pl           |   8 +-
 src/test/subscription/t/005_encoding.pl       |   8 +-
 src/test/subscription/t/006_rewrite.pl        |   8 +-
 src/test/subscription/t/007_ddl.pl            |   8 +-
 src/test/subscription/t/008_diff_schema.pl    |   8 +-
 src/test/subscription/t/009_matviews.pl       |   8 +-
 src/test/subscription/t/010_truncate.pl       |   8 +-
 src/test/subscription/t/011_generated.pl      |   8 +-
 src/test/subscription/t/012_collation.pl      |   8 +-
 src/test/subscription/t/013_partition.pl      |  10 +-
 src/test/subscription/t/014_binary.pl         |   8 +-
 src/test/subscription/t/015_stream.pl         |   8 +-
 src/test/subscription/t/016_stream_subxact.pl |   8 +-
 src/test/subscription/t/017_stream_ddl.pl     |   8 +-
 .../t/018_stream_subxact_abort.pl             |   8 +-
 .../t/019_stream_subxact_ddl_abort.pl         |   8 +-
 src/test/subscription/t/020_messages.pl       |   8 +-
 src/test/subscription/t/021_twophase.pl       |   8 +-
 .../subscription/t/022_twophase_cascade.pl    |  10 +-
 .../subscription/t/023_twophase_stream.pl     |   8 +-
 src/test/subscription/t/024_add_drop_pub.pl   |   8 +-
 src/test/subscription/t/100_bugs.pl           |  18 +--
 140 files changed, 645 insertions(+), 645 deletions(-)
 rename src/test/perl/{PostgresNode.pm => Postgres/Test/Cluster.pm} (92%)
 rename src/test/perl/{ => Postgres/Test}/PostgresVersion.pm (84%)
 rename src/test/perl/{ => Postgres/Test}/RecursiveCopy.pm (91%)
 rename src/test/perl/{ => Postgres/Test}/SimpleTee.pm (95%)
 rename src/test/perl/{TestLib.pm => Postgres/Test/Utils.pm} (97%)

diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index 4f720a7ed0..656a2629e2 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,8 +4,8 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 
 use Fcntl qw(:seek);
 use Test::More tests => 80;
@@ -15,7 +15,7 @@ my ($node, $result);
 #
 # Test set-up
 #
-$node = PostgresNode->new('test');
+$node = Postgres::Test::Cluster->new('test');
 $node->init;
 $node->append_conf('postgresql.conf', 'autovacuum=off');
 $node->start;
diff --git a/contrib/auto_explain/t/001_auto_explain.pl b/contrib/auto_explain/t/001_auto_explain.pl
index 1773a37999..94f4052eb0 100644
--- a/contrib/auto_explain/t/001_auto_explain.pl
+++ b/contrib/auto_explain/t/001_auto_explain.pl
@@ -4,11 +4,11 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 4;
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->append_conf('postgresql.conf',
 	"shared_preload_libraries = 'auto_explain'");
diff --git a/contrib/bloom/t/001_wal.pl b/contrib/bloom/t/001_wal.pl
index 55ad35926f..b789e12723 100644
--- a/contrib/bloom/t/001_wal.pl
+++ b/contrib/bloom/t/001_wal.pl
@@ -4,8 +4,8 @@
 # Test generic xlog record work for bloom index replication.
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 31;
 
 my $node_primary;
@@ -43,7 +43,7 @@ SELECT * FROM tst WHERE i = 7 AND t = 'e';
 }
 
 # Initialize primary node
-$node_primary = PostgresNode->new('primary');
+$node_primary = Postgres::Test::Cluster->new('primary');
 $node_primary->init(allows_streaming => 1);
 $node_primary->start;
 my $backup_name = 'my_backup';
@@ -52,7 +52,7 @@ my $backup_name = 'my_backup';
 $node_primary->backup($backup_name);
 
 # Create streaming standby linking to primary
-$node_standby = PostgresNode->new('standby');
+$node_standby = Postgres::Test::Cluster->new('standby');
 $node_standby->init_from_backup($node_primary, $backup_name,
 	has_streaming => 1);
 $node_standby->start;
diff --git a/contrib/oid2name/t/001_basic.pl b/contrib/oid2name/t/001_basic.pl
index 8f0d4349a0..9a01d3dd7e 100644
--- a/contrib/oid2name/t/001_basic.pl
+++ b/contrib/oid2name/t/001_basic.pl
@@ -4,7 +4,7 @@
 use strict;
 use warnings;
 
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 8;
 
 #########################################
diff --git a/contrib/test_decoding/t/001_repl_stats.pl b/contrib/test_decoding/t/001_repl_stats.pl
index fdef6cb1ff..fccd6bf16f 100644
--- a/contrib/test_decoding/t/001_repl_stats.pl
+++ b/contrib/test_decoding/t/001_repl_stats.pl
@@ -6,12 +6,12 @@
 use strict;
 use warnings;
 use File::Path qw(rmtree);
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 2;
 
 # Test set-up
-my $node = PostgresNode->new('test');
+my $node = Postgres::Test::Cluster->new('test');
 $node->init(allows_streaming => 'logical');
 $node->append_conf('postgresql.conf', 'synchronous_commit = on');
 $node->start;
diff --git a/contrib/vacuumlo/t/001_basic.pl b/contrib/vacuumlo/t/001_basic.pl
index 2121f454e0..ae231c8d4d 100644
--- a/contrib/vacuumlo/t/001_basic.pl
+++ b/contrib/vacuumlo/t/001_basic.pl
@@ -4,7 +4,7 @@
 use strict;
 use warnings;
 
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 8;
 
 program_help_ok('vacuumlo');
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index 635ff79b47..c34132a61e 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -9,11 +9,11 @@ use strict;
 use warnings;
 use Fcntl ':mode';
 use File::stat qw{lstat};
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 22;
 
-my $tempdir = TestLib::tempdir;
+my $tempdir = Postgres::Test::Utils::tempdir;
 my $xlogdir = "$tempdir/pgxlog";
 my $datadir = "$tempdir/data";
 
diff --git a/src/bin/pg_amcheck/t/001_basic.pl b/src/bin/pg_amcheck/t/001_basic.pl
index 6f60e3ec1f..7ff2281bf3 100644
--- a/src/bin/pg_amcheck/t/001_basic.pl
+++ b/src/bin/pg_amcheck/t/001_basic.pl
@@ -4,7 +4,7 @@
 use strict;
 use warnings;
 
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 8;
 
 program_help_ok('pg_amcheck');
diff --git a/src/bin/pg_amcheck/t/002_nonesuch.pl b/src/bin/pg_amcheck/t/002_nonesuch.pl
index e30c1cc546..23497455b8 100644
--- a/src/bin/pg_amcheck/t/002_nonesuch.pl
+++ b/src/bin/pg_amcheck/t/002_nonesuch.pl
@@ -4,13 +4,13 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 76;
 
 # Test set-up
 my ($node, $port);
-$node = PostgresNode->new('test');
+$node = Postgres::Test::Cluster->new('test');
 $node->init;
 $node->start;
 $port = $node->port;
diff --git a/src/bin/pg_amcheck/t/003_check.pl b/src/bin/pg_amcheck/t/003_check.pl
index c26e5eda67..0bd8a1ac92 100644
--- a/src/bin/pg_amcheck/t/003_check.pl
+++ b/src/bin/pg_amcheck/t/003_check.pl
@@ -4,8 +4,8 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 
 use Fcntl qw(:seek);
 use Test::More tests => 63;
@@ -120,7 +120,7 @@ sub perform_all_corruptions()
 }
 
 # Test set-up
-$node = PostgresNode->new('test');
+$node = Postgres::Test::Cluster->new('test');
 $node->init;
 $node->append_conf('postgresql.conf', 'autovacuum=off');
 $node->start;
@@ -316,7 +316,7 @@ plan_to_remove_relation_file('db2', 's1.t1_btree');
 # Leave 'db3' uncorrupted
 #
 
-# Standard first arguments to TestLib functions
+# Standard first arguments to Postgres::Test::Utils functions
 my @cmd = ('pg_amcheck', '-p', $port);
 
 # Regular expressions to match various expected output
diff --git a/src/bin/pg_amcheck/t/004_verify_heapam.pl b/src/bin/pg_amcheck/t/004_verify_heapam.pl
index a9f485e527..09d4e8e3b3 100644
--- a/src/bin/pg_amcheck/t/004_verify_heapam.pl
+++ b/src/bin/pg_amcheck/t/004_verify_heapam.pl
@@ -4,8 +4,8 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 
 use Fcntl qw(:seek);
 use Test::More;
@@ -178,7 +178,7 @@ umask(0077);
 # Set up the node.  Once we create and corrupt the table,
 # autovacuum workers visiting the table could crash the backend.
 # Disable autovacuum so that won't happen.
-my $node = PostgresNode->new('test');
+my $node = Postgres::Test::Cluster->new('test');
 $node->init;
 $node->append_conf('postgresql.conf', 'autovacuum=off');
 
diff --git a/src/bin/pg_amcheck/t/005_opclass_damage.pl b/src/bin/pg_amcheck/t/005_opclass_damage.pl
index e87d81d7d4..3a27158712 100644
--- a/src/bin/pg_amcheck/t/005_opclass_damage.pl
+++ b/src/bin/pg_amcheck/t/005_opclass_damage.pl
@@ -6,11 +6,11 @@
 #
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 5;
 
-my $node = PostgresNode->new('test');
+my $node = Postgres::Test::Cluster->new('test');
 $node->init;
 $node->start;
 
diff --git a/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl b/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl
index 8134c2a62e..f888161a04 100644
--- a/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl
+++ b/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl
@@ -3,14 +3,14 @@
 
 use strict;
 use warnings;
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 42;
 
 program_help_ok('pg_archivecleanup');
 program_version_ok('pg_archivecleanup');
 program_options_handling_ok('pg_archivecleanup');
 
-my $tempdir = TestLib::tempdir;
+my $tempdir = Postgres::Test::Utils::tempdir;
 
 my @walfiles = (
 	'00000001000000370000000C.gz', '00000001000000370000000D',
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index a2cb2a7679..83ff53eab4 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -8,17 +8,17 @@ use Config;
 use File::Basename qw(basename dirname);
 use File::Path qw(rmtree);
 use Fcntl qw(:seek);
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 110;
 
 program_help_ok('pg_basebackup');
 program_version_ok('pg_basebackup');
 program_options_handling_ok('pg_basebackup');
 
-my $tempdir = TestLib::tempdir;
+my $tempdir = Postgres::Test::Utils::tempdir;
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 
 # Set umask so test directories and files are created with default permissions
 umask(0077);
@@ -238,14 +238,14 @@ $node->start;
 # to our physical temp location.  That way we can use shorter names
 # for the tablespace directories, which hopefully won't run afoul of
 # the 99 character length limit.
-my $sys_tempdir = TestLib::tempdir_short;
-my $real_sys_tempdir = TestLib::perl2host($sys_tempdir) . "/tempdir";
+my $sys_tempdir = Postgres::Test::Utils::tempdir_short;
+my $real_sys_tempdir = Postgres::Test::Utils::perl2host($sys_tempdir) . "/tempdir";
 my $shorter_tempdir =  $sys_tempdir . "/tempdir";
 dir_symlink "$tempdir", $shorter_tempdir;
 
 mkdir "$tempdir/tblspc1";
 my $realTsDir    = "$real_sys_tempdir/tblspc1";
-my $real_tempdir = TestLib::perl2host($tempdir);
+my $real_tempdir = Postgres::Test::Utils::perl2host($tempdir);
 $node->safe_psql('postgres',
 	"CREATE TABLESPACE tblspc1 LOCATION '$realTsDir';");
 $node->safe_psql('postgres',
@@ -270,7 +270,7 @@ SKIP:
 	skip "no tar program available", 1
 	  if (!defined $tar || $tar eq '');
 
-	my $node2 = PostgresNode->new('replica');
+	my $node2 = Postgres::Test::Cluster->new('replica');
 
 	# Recover main data directory
 	$node2->init_from_backup($node, 'tarbackup2', tar_program => $tar);
@@ -279,7 +279,7 @@ SKIP:
 	my $repTsDir     = "$tempdir/tblspc1replica";
 	my $realRepTsDir = "$real_sys_tempdir/tblspc1replica";
 	mkdir $repTsDir;
-	TestLib::system_or_bail($tar, 'xf', $tblspc_tars[0], '-C', $repTsDir);
+	Postgres::Test::Utils::system_or_bail($tar, 'xf', $tblspc_tars[0], '-C', $repTsDir);
 
 	# Update tablespace map to point to new directory.
 	# XXX Ideally pg_basebackup would handle this.
diff --git a/src/bin/pg_basebackup/t/020_pg_receivewal.pl b/src/bin/pg_basebackup/t/020_pg_receivewal.pl
index 0b33d73900..fc84c0a992 100644
--- a/src/bin/pg_basebackup/t/020_pg_receivewal.pl
+++ b/src/bin/pg_basebackup/t/020_pg_receivewal.pl
@@ -3,8 +3,8 @@
 
 use strict;
 use warnings;
-use TestLib;
-use PostgresNode;
+use Postgres::Test::Utils;
+use Postgres::Test::Cluster;
 use Test::More tests => 27;
 
 program_help_ok('pg_receivewal');
@@ -14,7 +14,7 @@ program_options_handling_ok('pg_receivewal');
 # Set umask so test directories and files are created with default permissions
 umask(0077);
 
-my $primary = PostgresNode->new('primary');
+my $primary = Postgres::Test::Cluster->new('primary');
 $primary->init(allows_streaming => 1);
 $primary->start;
 
diff --git a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl
index fe7fe76295..46beccdf86 100644
--- a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl
+++ b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl
@@ -3,15 +3,15 @@
 
 use strict;
 use warnings;
-use TestLib;
-use PostgresNode;
+use Postgres::Test::Utils;
+use Postgres::Test::Cluster;
 use Test::More tests => 20;
 
 program_help_ok('pg_recvlogical');
 program_version_ok('pg_recvlogical');
 program_options_handling_ok('pg_recvlogical');
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 
 # Initialize node without replication settings
 $node->init(allows_streaming => 1, has_archiving => 1);
diff --git a/src/bin/pg_checksums/t/001_basic.pl b/src/bin/pg_checksums/t/001_basic.pl
index 62e78a5043..5e8e02173d 100644
--- a/src/bin/pg_checksums/t/001_basic.pl
+++ b/src/bin/pg_checksums/t/001_basic.pl
@@ -3,7 +3,7 @@
 
 use strict;
 use warnings;
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 8;
 
 program_help_ok('pg_checksums');
diff --git a/src/bin/pg_checksums/t/002_actions.pl b/src/bin/pg_checksums/t/002_actions.pl
index a18c104a94..46097eaa45 100644
--- a/src/bin/pg_checksums/t/002_actions.pl
+++ b/src/bin/pg_checksums/t/002_actions.pl
@@ -6,8 +6,8 @@
 
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 
 use Fcntl qw(:seek);
 use Test::More tests => 63;
@@ -92,7 +92,7 @@ sub check_relation_corruption
 }
 
 # Initialize node with checksums disabled.
-my $node = PostgresNode->new('node_checksum');
+my $node = Postgres::Test::Cluster->new('node_checksum');
 $node->init();
 my $pgdata = $node->data_dir;
 
@@ -190,7 +190,7 @@ check_relation_corruption($node, 'corrupt1', 'pg_default');
 my $basedir        = $node->basedir;
 my $tablespace_dir = "$basedir/ts_corrupt_dir";
 mkdir($tablespace_dir);
-$tablespace_dir = TestLib::perl2host($tablespace_dir);
+$tablespace_dir = Postgres::Test::Utils::perl2host($tablespace_dir);
 $node->safe_psql('postgres',
 	"CREATE TABLESPACE ts_corrupt LOCATION '$tablespace_dir';");
 check_relation_corruption($node, 'corrupt2', 'ts_corrupt');
diff --git a/src/bin/pg_config/t/001_pg_config.pl b/src/bin/pg_config/t/001_pg_config.pl
index d8829faea6..3e0aacd53a 100644
--- a/src/bin/pg_config/t/001_pg_config.pl
+++ b/src/bin/pg_config/t/001_pg_config.pl
@@ -3,7 +3,7 @@
 
 use strict;
 use warnings;
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 20;
 
 program_help_ok('pg_config');
diff --git a/src/bin/pg_controldata/t/001_pg_controldata.pl b/src/bin/pg_controldata/t/001_pg_controldata.pl
index ce31cfbd3b..4bba3d1f5e 100644
--- a/src/bin/pg_controldata/t/001_pg_controldata.pl
+++ b/src/bin/pg_controldata/t/001_pg_controldata.pl
@@ -3,8 +3,8 @@
 
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 17;
 
 program_help_ok('pg_controldata');
@@ -14,7 +14,7 @@ command_fails(['pg_controldata'], 'pg_controldata without arguments fails');
 command_fails([ 'pg_controldata', 'nonexistent' ],
 	'pg_controldata with nonexistent directory fails');
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 
 command_like([ 'pg_controldata', $node->data_dir ],
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index 1d8d6bbb70..f1da39e381 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -7,12 +7,12 @@ use warnings;
 use Config;
 use Fcntl ':mode';
 use File::stat qw{lstat};
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 24;
 
-my $tempdir       = TestLib::tempdir;
-my $tempdir_short = TestLib::tempdir_short;
+my $tempdir       = Postgres::Test::Utils::tempdir;
+my $tempdir_short = Postgres::Test::Utils::tempdir_short;
 
 program_help_ok('pg_ctl');
 program_version_ok('pg_ctl');
@@ -25,11 +25,11 @@ command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data", '-o', '-N' ],
 	'pg_ctl initdb');
 command_ok([ $ENV{PG_REGRESS}, '--config-auth', "$tempdir/data" ],
 	'configure authentication');
-my $node_port = PostgresNode::get_free_port();
+my $node_port = Postgres::Test::Cluster::get_free_port();
 open my $conf, '>>', "$tempdir/data/postgresql.conf";
 print $conf "fsync = off\n";
 print $conf "port = $node_port\n";
-print $conf TestLib::slurp_file($ENV{TEMP_CONFIG})
+print $conf Postgres::Test::Utils::slurp_file($ENV{TEMP_CONFIG})
   if defined $ENV{TEMP_CONFIG};
 
 if ($use_unix_sockets)
@@ -44,7 +44,7 @@ else
 close $conf;
 my $ctlcmd = [
 	'pg_ctl', 'start', '-D', "$tempdir/data", '-l',
-	"$TestLib::log_path/001_start_stop_server.log"
+	"$Postgres::Test::Utils::log_path/001_start_stop_server.log"
 ];
 if ($Config{osname} ne 'msys')
 {
diff --git a/src/bin/pg_ctl/t/002_status.pl b/src/bin/pg_ctl/t/002_status.pl
index 56a06fafa3..58b6f589ff 100644
--- a/src/bin/pg_ctl/t/002_status.pl
+++ b/src/bin/pg_ctl/t/002_status.pl
@@ -4,17 +4,17 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 3;
 
-my $tempdir       = TestLib::tempdir;
-my $tempdir_short = TestLib::tempdir_short;
+my $tempdir       = Postgres::Test::Utils::tempdir;
+my $tempdir_short = Postgres::Test::Utils::tempdir_short;
 
 command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/nonexistent" ],
 	4, 'pg_ctl status with nonexistent directory');
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 
 command_exit_is([ 'pg_ctl', 'status', '-D', $node->data_dir ],
diff --git a/src/bin/pg_ctl/t/003_promote.pl b/src/bin/pg_ctl/t/003_promote.pl
index 547b3d8893..a45c37b5a0 100644
--- a/src/bin/pg_ctl/t/003_promote.pl
+++ b/src/bin/pg_ctl/t/003_promote.pl
@@ -4,18 +4,18 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 12;
 
-my $tempdir = TestLib::tempdir;
+my $tempdir = Postgres::Test::Utils::tempdir;
 
 command_fails_like(
 	[ 'pg_ctl', '-D', "$tempdir/nonexistent", 'promote' ],
 	qr/directory .* does not exist/,
 	'pg_ctl promote with nonexistent directory');
 
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 $node_primary->init(allows_streaming => 1);
 
 command_fails_like(
@@ -30,7 +30,7 @@ command_fails_like(
 	qr/not in standby mode/,
 	'pg_ctl promote of primary instance fails');
 
-my $node_standby = PostgresNode->new('standby');
+my $node_standby = Postgres::Test::Cluster->new('standby');
 $node_primary->backup('my_backup');
 $node_standby->init_from_backup($node_primary, 'my_backup',
 	has_streaming => 1);
@@ -47,7 +47,7 @@ ok( $node_standby->poll_query_until(
 	'promoted standby is not in recovery');
 
 # same again with default wait option
-$node_standby = PostgresNode->new('standby2');
+$node_standby = Postgres::Test::Cluster->new('standby2');
 $node_standby->init_from_backup($node_primary, 'my_backup',
 	has_streaming => 1);
 $node_standby->start;
diff --git a/src/bin/pg_ctl/t/004_logrotate.pl b/src/bin/pg_ctl/t/004_logrotate.pl
index fa14b98c7d..6d7016f17c 100644
--- a/src/bin/pg_ctl/t/004_logrotate.pl
+++ b/src/bin/pg_ctl/t/004_logrotate.pl
@@ -4,13 +4,13 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 5;
 use Time::HiRes qw(usleep);
 
 # Set up node with logging collector
-my $node = PostgresNode->new('primary');
+my $node = Postgres::Test::Cluster->new('primary');
 $node->init();
 $node->append_conf(
 	'postgresql.conf', qq(
diff --git a/src/bin/pg_dump/t/001_basic.pl b/src/bin/pg_dump/t/001_basic.pl
index d1a7e1db40..c4f0a4b8e5 100644
--- a/src/bin/pg_dump/t/001_basic.pl
+++ b/src/bin/pg_dump/t/001_basic.pl
@@ -5,12 +5,12 @@ use strict;
 use warnings;
 
 use Config;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 82;
 
-my $tempdir       = TestLib::tempdir;
-my $tempdir_short = TestLib::tempdir_short;
+my $tempdir       = Postgres::Test::Utils::tempdir;
+my $tempdir_short = Postgres::Test::Utils::tempdir_short;
 
 #########################################
 # Basic checks
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index be1f3a5175..da659d25ab 100644
--- a/src/bin/pg_dump/t/002_pg_dump.pl
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -5,12 +5,12 @@ use strict;
 use warnings;
 
 use Config;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More;
 
-my $tempdir       = TestLib::tempdir;
-my $tempdir_short = TestLib::tempdir_short;
+my $tempdir       = Postgres::Test::Utils::tempdir;
+my $tempdir_short = Postgres::Test::Utils::tempdir_short;
 
 ###############################################################
 # Definition of the pg_dump runs to make.
@@ -26,7 +26,7 @@ my $tempdir_short = TestLib::tempdir_short;
 # the full command and arguments to run.  Note that this is run
 # using $node->command_ok(), so the port does not need to be
 # specified and is pulled from $PGPORT, which is set by the
-# PostgresNode system.
+# Postgres::Test::Cluster system.
 #
 # restore_cmd is the pg_restore command to run, if any.  Note
 # that this should generally be used when the pg_dump goes to
@@ -3562,7 +3562,7 @@ my %tests = (
 #########################################
 # Create a PG instance to test actually dumping from
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
diff --git a/src/bin/pg_dump/t/003_pg_dump_with_server.pl b/src/bin/pg_dump/t/003_pg_dump_with_server.pl
index ba994aee82..d025071fe3 100644
--- a/src/bin/pg_dump/t/003_pg_dump_with_server.pl
+++ b/src/bin/pg_dump/t/003_pg_dump_with_server.pl
@@ -4,14 +4,14 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 3;
 
-my $tempdir       = TestLib::tempdir;
-my $tempdir_short = TestLib::tempdir_short;
+my $tempdir       = Postgres::Test::Utils::tempdir;
+my $tempdir_short = Postgres::Test::Utils::tempdir_short;
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 my $port = $node->port;
 
 $node->init;
diff --git a/src/bin/pg_dump/t/010_dump_connstr.pl b/src/bin/pg_dump/t/010_dump_connstr.pl
index c4b60c5d2a..40ee9ef9b3 100644
--- a/src/bin/pg_dump/t/010_dump_connstr.pl
+++ b/src/bin/pg_dump/t/010_dump_connstr.pl
@@ -4,11 +4,11 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More;
 
-if ($TestLib::is_msys2)
+if ($Postgres::Test::Utils::is_msys2)
 {
 	plan skip_all => 'High bit name tests fail on Msys2';
 }
@@ -34,7 +34,7 @@ my $dbname1 =
   . generate_ascii_string(1,  9)
   . generate_ascii_string(11, 12)
   . generate_ascii_string(14, 33)
-  . ($TestLib::windows_os ? '' : '"x"')   # IPC::Run mishandles '"' on Windows
+  . ($Postgres::Test::Utils::windows_os ? '' : '"x"')   # IPC::Run mishandles '"' on Windows
   . generate_ascii_string(35, 43)         # skip ','
   . generate_ascii_string(45, 54);
 my $dbname2 = 'regression' . generate_ascii_string(55, 65)    # skip 'B'-'W'
@@ -51,7 +51,7 @@ my $dbname4 = 'regression' . generate_ascii_string(203, 255);
 my $src_bootstrap_super = 'regress_postgres';
 my $dst_bootstrap_super = 'boot';
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init(extra =>
 	  [ '-U', $src_bootstrap_super, '--locale=C', '--encoding=LATIN1' ]);
 
@@ -175,13 +175,13 @@ system_log('cat', $plain);
 my ($stderr, $result);
 my $restore_super = qq{regress_a'b\\c=d\\ne"f};
 $restore_super =~ s/"//g
-  if $TestLib::windows_os;    # IPC::Run mishandles '"' on Windows
+  if $Postgres::Test::Utils::windows_os;    # IPC::Run mishandles '"' on Windows
 
 
 # Restore full dump through psql using environment variables for
 # dbname/user connection parameters
 
-my $envar_node = PostgresNode->new('destination_envar');
+my $envar_node = Postgres::Test::Cluster->new('destination_envar');
 $envar_node->init(
 	extra =>
 	  [ '-U', $dst_bootstrap_super, '--locale=C', '--encoding=LATIN1' ],
@@ -208,7 +208,7 @@ is($stderr, '', 'no dump errors');
 # dbname/user connection parameters.  "\connect dbname=" forgets
 # user/port from command line.
 
-my $cmdline_node = PostgresNode->new('destination_cmdline');
+my $cmdline_node = Postgres::Test::Cluster->new('destination_cmdline');
 $cmdline_node->init(
 	extra =>
 	  [ '-U', $dst_bootstrap_super, '--locale=C', '--encoding=LATIN1' ],
diff --git a/src/bin/pg_resetwal/t/001_basic.pl b/src/bin/pg_resetwal/t/001_basic.pl
index f01a4d2d48..afaad97a2c 100644
--- a/src/bin/pg_resetwal/t/001_basic.pl
+++ b/src/bin/pg_resetwal/t/001_basic.pl
@@ -4,15 +4,15 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 12;
 
 program_help_ok('pg_resetwal');
 program_version_ok('pg_resetwal');
 program_options_handling_ok('pg_resetwal');
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 
 command_like([ 'pg_resetwal', '-n', $node->data_dir ],
diff --git a/src/bin/pg_resetwal/t/002_corrupted.pl b/src/bin/pg_resetwal/t/002_corrupted.pl
index ac915ef91f..6c3125cc82 100644
--- a/src/bin/pg_resetwal/t/002_corrupted.pl
+++ b/src/bin/pg_resetwal/t/002_corrupted.pl
@@ -6,11 +6,11 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 6;
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 
 my $pg_control = $node->data_dir . '/global/pg_control';
diff --git a/src/bin/pg_rewind/t/001_basic.pl b/src/bin/pg_rewind/t/001_basic.pl
index d636f35f5e..429f55fe2d 100644
--- a/src/bin/pg_rewind/t/001_basic.pl
+++ b/src/bin/pg_rewind/t/001_basic.pl
@@ -3,7 +3,7 @@
 
 use strict;
 use warnings;
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 23;
 
 use FindBin;
diff --git a/src/bin/pg_rewind/t/002_databases.pl b/src/bin/pg_rewind/t/002_databases.pl
index 72c4b225a7..0e44af5a38 100644
--- a/src/bin/pg_rewind/t/002_databases.pl
+++ b/src/bin/pg_rewind/t/002_databases.pl
@@ -3,7 +3,7 @@
 
 use strict;
 use warnings;
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 7;
 
 use FindBin;
diff --git a/src/bin/pg_rewind/t/003_extrafiles.pl b/src/bin/pg_rewind/t/003_extrafiles.pl
index 672c5e586b..4e5486c4e3 100644
--- a/src/bin/pg_rewind/t/003_extrafiles.pl
+++ b/src/bin/pg_rewind/t/003_extrafiles.pl
@@ -5,7 +5,7 @@
 
 use strict;
 use warnings;
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 5;
 
 use File::Find;
diff --git a/src/bin/pg_rewind/t/004_pg_xlog_symlink.pl b/src/bin/pg_rewind/t/004_pg_xlog_symlink.pl
index 8fb0ab3ead..473e127e7f 100644
--- a/src/bin/pg_rewind/t/004_pg_xlog_symlink.pl
+++ b/src/bin/pg_rewind/t/004_pg_xlog_symlink.pl
@@ -8,7 +8,7 @@ use strict;
 use warnings;
 use File::Copy;
 use File::Path qw(rmtree);
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 5;
 
 use FindBin;
@@ -20,7 +20,7 @@ sub run_test
 {
 	my $test_mode = shift;
 
-	my $primary_xlogdir = "${TestLib::tmp_check}/xlog_primary";
+	my $primary_xlogdir = "${Postgres::Test::Utils::tmp_check}/xlog_primary";
 
 	rmtree($primary_xlogdir);
 	RewindTest::setup_cluster($test_mode);
diff --git a/src/bin/pg_rewind/t/005_same_timeline.pl b/src/bin/pg_rewind/t/005_same_timeline.pl
index efe1d4c77f..66b63e4bea 100644
--- a/src/bin/pg_rewind/t/005_same_timeline.pl
+++ b/src/bin/pg_rewind/t/005_same_timeline.pl
@@ -7,7 +7,7 @@
 #
 use strict;
 use warnings;
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 1;
 
 use FindBin;
diff --git a/src/bin/pg_rewind/t/006_options.pl b/src/bin/pg_rewind/t/006_options.pl
index 81793899e5..a75a90326e 100644
--- a/src/bin/pg_rewind/t/006_options.pl
+++ b/src/bin/pg_rewind/t/006_options.pl
@@ -6,15 +6,15 @@
 #
 use strict;
 use warnings;
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 12;
 
 program_help_ok('pg_rewind');
 program_version_ok('pg_rewind');
 program_options_handling_ok('pg_rewind');
 
-my $primary_pgdata = TestLib::tempdir;
-my $standby_pgdata = TestLib::tempdir;
+my $primary_pgdata = Postgres::Test::Utils::tempdir;
+my $standby_pgdata = Postgres::Test::Utils::tempdir;
 command_fails(
 	[
 		'pg_rewind',       '--debug',
diff --git a/src/bin/pg_rewind/t/007_standby_source.pl b/src/bin/pg_rewind/t/007_standby_source.pl
index 2a717f5a2e..8a6b774c20 100644
--- a/src/bin/pg_rewind/t/007_standby_source.pl
+++ b/src/bin/pg_rewind/t/007_standby_source.pl
@@ -26,16 +26,16 @@
 
 use strict;
 use warnings;
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 3;
 
 use FindBin;
 use lib $FindBin::RealBin;
 use File::Copy;
-use PostgresNode;
+use Postgres::Test::Cluster;
 use RewindTest;
 
-my $tmp_folder = TestLib::tempdir;
+my $tmp_folder = Postgres::Test::Utils::tempdir;
 
 my $node_a;
 my $node_b;
@@ -58,13 +58,13 @@ primary_psql("CHECKPOINT");
 #
 # A (primary) <--- B (standby) <--- C (standby)
 $node_a->backup('my_backup');
-$node_b = PostgresNode->new('node_b');
+$node_b = Postgres::Test::Cluster->new('node_b');
 $node_b->init_from_backup($node_a, 'my_backup', has_streaming => 1);
 $node_b->set_standby_mode();
 $node_b->start;
 
 $node_b->backup('my_backup');
-$node_c = PostgresNode->new('node_c');
+$node_c = Postgres::Test::Cluster->new('node_c');
 $node_c->init_from_backup($node_b, 'my_backup', has_streaming => 1);
 $node_c->set_standby_mode();
 $node_c->start;
diff --git a/src/bin/pg_rewind/t/008_min_recovery_point.pl b/src/bin/pg_rewind/t/008_min_recovery_point.pl
index 7a390f4abd..31c146ac5a 100644
--- a/src/bin/pg_rewind/t/008_min_recovery_point.pl
+++ b/src/bin/pg_rewind/t/008_min_recovery_point.pl
@@ -32,15 +32,15 @@
 
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 3;
 
 use File::Copy;
 
-my $tmp_folder = TestLib::tempdir;
+my $tmp_folder = Postgres::Test::Utils::tempdir;
 
-my $node_1 = PostgresNode->new('node_1');
+my $node_1 = Postgres::Test::Cluster->new('node_1');
 $node_1->init(allows_streaming => 1);
 $node_1->append_conf(
 	'postgresql.conf', qq(
@@ -60,11 +60,11 @@ $node_1->safe_psql('postgres', "INSERT INTO public.bar VALUES ('in both')");
 my $backup_name = 'my_backup';
 $node_1->backup($backup_name);
 
-my $node_2 = PostgresNode->new('node_2');
+my $node_2 = Postgres::Test::Cluster->new('node_2');
 $node_2->init_from_backup($node_1, $backup_name, has_streaming => 1);
 $node_2->start;
 
-my $node_3 = PostgresNode->new('node_3');
+my $node_3 = Postgres::Test::Cluster->new('node_3');
 $node_3->init_from_backup($node_1, $backup_name, has_streaming => 1);
 $node_3->start;
 
diff --git a/src/bin/pg_rewind/t/RewindTest.pm b/src/bin/pg_rewind/t/RewindTest.pm
index 367b99a438..c8cbefc69b 100644
--- a/src/bin/pg_rewind/t/RewindTest.pm
+++ b/src/bin/pg_rewind/t/RewindTest.pm
@@ -40,9 +40,9 @@ use Exporter 'import';
 use File::Copy;
 use File::Path qw(rmtree);
 use IPC::Run qw(run);
-use PostgresNode;
-use RecursiveCopy;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::RecursiveCopy;
+use Postgres::Test::Utils;
 use Test::More;
 
 our @EXPORT = qw(
@@ -128,7 +128,7 @@ sub setup_cluster
 
 	# Initialize primary, data checksums are mandatory
 	$node_primary =
-	  PostgresNode->new('primary' . ($extra_name ? "_${extra_name}" : ''));
+	  Postgres::Test::Cluster->new('primary' . ($extra_name ? "_${extra_name}" : ''));
 
 	# Set up pg_hba.conf and pg_ident.conf for the role running
 	# pg_rewind.  This role is used for all the tests, and has
@@ -176,7 +176,7 @@ sub create_standby
 	my $extra_name = shift;
 
 	$node_standby =
-	  PostgresNode->new('standby' . ($extra_name ? "_${extra_name}" : ''));
+	  Postgres::Test::Cluster->new('standby' . ($extra_name ? "_${extra_name}" : ''));
 	$node_primary->backup('my_backup');
 	$node_standby->init_from_backup($node_primary, 'my_backup');
 	my $connstr_primary = $node_primary->connstr();
@@ -226,7 +226,7 @@ sub run_pg_rewind
 	my $primary_pgdata  = $node_primary->data_dir;
 	my $standby_pgdata  = $node_standby->data_dir;
 	my $standby_connstr = $node_standby->connstr('postgres');
-	my $tmp_folder      = TestLib::tempdir;
+	my $tmp_folder      = Postgres::Test::Utils::tempdir;
 
 	# Append the rewind-specific role to the connection string.
 	$standby_connstr = "$standby_connstr user=rewind_user";
@@ -315,7 +315,7 @@ sub run_pg_rewind
 		# segments from the old primary to the archives.  These
 		# will be used by pg_rewind.
 		rmtree($node_primary->archive_dir);
-		RecursiveCopy::copypath($node_primary->data_dir . "/pg_wal",
+		Postgres::Test::RecursiveCopy::copypath($node_primary->data_dir . "/pg_wal",
 			$node_primary->archive_dir);
 
 		# Fast way to remove entire directory content
diff --git a/src/bin/pg_test_fsync/t/001_basic.pl b/src/bin/pg_test_fsync/t/001_basic.pl
index c0d0effd92..123438b5f5 100644
--- a/src/bin/pg_test_fsync/t/001_basic.pl
+++ b/src/bin/pg_test_fsync/t/001_basic.pl
@@ -5,7 +5,7 @@ use strict;
 use warnings;
 
 use Config;
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 12;
 
 #########################################
diff --git a/src/bin/pg_test_timing/t/001_basic.pl b/src/bin/pg_test_timing/t/001_basic.pl
index 72e5a42b6f..19c63cdea7 100644
--- a/src/bin/pg_test_timing/t/001_basic.pl
+++ b/src/bin/pg_test_timing/t/001_basic.pl
@@ -5,7 +5,7 @@ use strict;
 use warnings;
 
 use Config;
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 12;
 
 #########################################
diff --git a/src/bin/pg_verifybackup/t/001_basic.pl b/src/bin/pg_verifybackup/t/001_basic.pl
index 4ad1c3f0a9..a61919b8a5 100644
--- a/src/bin/pg_verifybackup/t/001_basic.pl
+++ b/src/bin/pg_verifybackup/t/001_basic.pl
@@ -3,10 +3,10 @@
 
 use strict;
 use warnings;
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 16;
 
-my $tempdir = TestLib::tempdir;
+my $tempdir = Postgres::Test::Utils::tempdir;
 
 program_help_ok('pg_verifybackup');
 program_version_ok('pg_verifybackup');
diff --git a/src/bin/pg_verifybackup/t/002_algorithm.pl b/src/bin/pg_verifybackup/t/002_algorithm.pl
index 7dc1af982a..5c71b4d21b 100644
--- a/src/bin/pg_verifybackup/t/002_algorithm.pl
+++ b/src/bin/pg_verifybackup/t/002_algorithm.pl
@@ -8,11 +8,11 @@ use warnings;
 use Cwd;
 use Config;
 use File::Path qw(rmtree);
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 19;
 
-my $primary = PostgresNode->new('primary');
+my $primary = Postgres::Test::Cluster->new('primary');
 $primary->init(allows_streaming => 1);
 $primary->start;
 
diff --git a/src/bin/pg_verifybackup/t/003_corruption.pl b/src/bin/pg_verifybackup/t/003_corruption.pl
index 509390f975..a258522269 100644
--- a/src/bin/pg_verifybackup/t/003_corruption.pl
+++ b/src/bin/pg_verifybackup/t/003_corruption.pl
@@ -8,17 +8,17 @@ use warnings;
 use Cwd;
 use Config;
 use File::Path qw(rmtree);
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 44;
 
-my $primary = PostgresNode->new('primary');
+my $primary = Postgres::Test::Cluster->new('primary');
 $primary->init(allows_streaming => 1);
 $primary->start;
 
 # Include a user-defined tablespace in the hopes of detecting problems in that
 # area.
-my $source_ts_path   = TestLib::perl2host(TestLib::tempdir_short());
+my $source_ts_path   = Postgres::Test::Utils::perl2host(Postgres::Test::Utils::tempdir_short());
 my $source_ts_prefix = $source_ts_path;
 $source_ts_prefix =~ s!(^[A-Z]:/[^/]*)/.*!$1!;
 
@@ -107,7 +107,7 @@ for my $scenario (@scenario)
 
 		# Take a backup and check that it verifies OK.
 		my $backup_path    = $primary->backup_dir . '/' . $name;
-		my $backup_ts_path = TestLib::perl2host(TestLib::tempdir_short());
+		my $backup_ts_path = Postgres::Test::Utils::perl2host(Postgres::Test::Utils::tempdir_short());
 		# The tablespace map parameter confuses Msys2, which tries to mangle
 		# it. Tell it not to.
 		# See https://www.msys2.org/wiki/Porting/#filesystem-namespaces
diff --git a/src/bin/pg_verifybackup/t/004_options.pl b/src/bin/pg_verifybackup/t/004_options.pl
index d4210fd293..854bdbffe0 100644
--- a/src/bin/pg_verifybackup/t/004_options.pl
+++ b/src/bin/pg_verifybackup/t/004_options.pl
@@ -8,12 +8,12 @@ use warnings;
 use Cwd;
 use Config;
 use File::Path qw(rmtree);
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 25;
 
 # Start up the server and take a backup.
-my $primary = PostgresNode->new('primary');
+my $primary = Postgres::Test::Cluster->new('primary');
 $primary->init(allows_streaming => 1);
 $primary->start;
 my $backup_path = $primary->backup_dir . '/test_options';
diff --git a/src/bin/pg_verifybackup/t/005_bad_manifest.pl b/src/bin/pg_verifybackup/t/005_bad_manifest.pl
index 4f5b8f5a49..eafd695ad4 100644
--- a/src/bin/pg_verifybackup/t/005_bad_manifest.pl
+++ b/src/bin/pg_verifybackup/t/005_bad_manifest.pl
@@ -8,11 +8,11 @@ use strict;
 use warnings;
 use Cwd;
 use Config;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 58;
 
-my $tempdir = TestLib::tempdir;
+my $tempdir = Postgres::Test::Utils::tempdir;
 
 test_bad_manifest(
 	'input string ended unexpectedly',
diff --git a/src/bin/pg_verifybackup/t/006_encoding.pl b/src/bin/pg_verifybackup/t/006_encoding.pl
index c0667b7f43..7208a61873 100644
--- a/src/bin/pg_verifybackup/t/006_encoding.pl
+++ b/src/bin/pg_verifybackup/t/006_encoding.pl
@@ -7,11 +7,11 @@ use strict;
 use warnings;
 use Cwd;
 use Config;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 5;
 
-my $primary = PostgresNode->new('primary');
+my $primary = Postgres::Test::Cluster->new('primary');
 $primary->init(allows_streaming => 1);
 $primary->start;
 my $backup_path = $primary->backup_dir . '/test_encoding';
diff --git a/src/bin/pg_verifybackup/t/007_wal.pl b/src/bin/pg_verifybackup/t/007_wal.pl
index 29b8a070d7..74ea853779 100644
--- a/src/bin/pg_verifybackup/t/007_wal.pl
+++ b/src/bin/pg_verifybackup/t/007_wal.pl
@@ -8,12 +8,12 @@ use warnings;
 use Cwd;
 use Config;
 use File::Path qw(rmtree);
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 9;
 
 # Start up the server and take a backup.
-my $primary = PostgresNode->new('primary');
+my $primary = Postgres::Test::Cluster->new('primary');
 $primary->init(allows_streaming => 1);
 $primary->start;
 my $backup_path = $primary->backup_dir . '/test_wal';
diff --git a/src/bin/pg_waldump/t/001_basic.pl b/src/bin/pg_waldump/t/001_basic.pl
index fb2f807dc3..d86c809881 100644
--- a/src/bin/pg_waldump/t/001_basic.pl
+++ b/src/bin/pg_waldump/t/001_basic.pl
@@ -3,7 +3,7 @@
 
 use strict;
 use warnings;
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 8;
 
 program_help_ok('pg_waldump');
diff --git a/src/bin/pgbench/t/001_pgbench_with_server.pl b/src/bin/pgbench/t/001_pgbench_with_server.pl
index ef53f6b2d9..3f45beb72c 100644
--- a/src/bin/pgbench/t/001_pgbench_with_server.pl
+++ b/src/bin/pgbench/t/001_pgbench_with_server.pl
@@ -4,13 +4,13 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More;
 use Config;
 
 # start a pgbench specific server
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
@@ -68,7 +68,7 @@ sub pgbench
 my $ts = $node->basedir . '/regress_pgbench_tap_1_ts_dir';
 mkdir $ts or die "cannot create directory $ts";
 # this takes care of WIN-specific path issues
-my $ets = TestLib::perl2host($ts);
+my $ets = Postgres::Test::Utils::perl2host($ts);
 
 # the next commands will issue a syntax error if the path contains a "'"
 $node->safe_psql('postgres',
@@ -300,7 +300,7 @@ select $$'Valame Dios!' dijo Sancho; 'no le dije yo a vuestra merced que mirase
 select column1::jsonb from (values (:value), (:long)) as q;
 ]
 	});
-my $log = TestLib::slurp_file($node->logfile);
+my $log = Postgres::Test::Utils::slurp_file($node->logfile);
 unlike(
 	$log,
 	qr[DETAIL:  parameters: \$1 = '\{ invalid ',],
@@ -341,7 +341,7 @@ select $$'Valame Dios!' dijo Sancho; 'no le dije yo a vuestra merced que mirase
 select column1::jsonb from (values (:value), (:long)) as q;
 ]
 	});
-$log = TestLib::slurp_file($node->logfile);
+$log = Postgres::Test::Utils::slurp_file($node->logfile);
 like(
 	$log,
 	qr[DETAIL:  parameters: \$1 = '\{ invalid ', \$2 = '''Valame Dios!'' dijo Sancho; ''no le dije yo a vuestra merced que mirase bien lo que hacia\?'''],
@@ -386,7 +386,7 @@ select $$'Valame Dios!' dijo Sancho; 'no le dije yo a vuestra merced que mirase
 select column1::jsonb from (values (:value), (:long)) as q;
 ]
 	});
-$log = TestLib::slurp_file($node->logfile);
+$log = Postgres::Test::Utils::slurp_file($node->logfile);
 like(
 	$log,
 	qr[DETAIL:  parameters: \$1 = '\{ inval\.\.\.', \$2 = '''Valame\.\.\.'],
diff --git a/src/bin/pgbench/t/002_pgbench_no_server.pl b/src/bin/pgbench/t/002_pgbench_no_server.pl
index da38d9b1d2..3514e8e396 100644
--- a/src/bin/pgbench/t/002_pgbench_no_server.pl
+++ b/src/bin/pgbench/t/002_pgbench_no_server.pl
@@ -8,7 +8,7 @@
 use strict;
 use warnings;
 
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More;
 
 # create a directory for scripts
@@ -16,7 +16,7 @@ my $testname = $0;
 $testname =~ s,.*/,,;
 $testname =~ s/\.pl$//;
 
-my $testdir = "$TestLib::tmp_check/t_${testname}_stuff";
+my $testdir = "$Postgres::Test::Utils::tmp_check/t_${testname}_stuff";
 mkdir $testdir
   or BAIL_OUT("could not create test directory \"${testdir}\": $!");
 
diff --git a/src/bin/psql/t/010_tab_completion.pl b/src/bin/psql/t/010_tab_completion.pl
index 8695d22545..fde5d11b23 100644
--- a/src/bin/psql/t/010_tab_completion.pl
+++ b/src/bin/psql/t/010_tab_completion.pl
@@ -4,8 +4,8 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More;
 use IPC::Run qw(pump finish timer);
 use Data::Dumper;
@@ -34,7 +34,7 @@ if ($@)
 }
 
 # start a new server
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
@@ -48,7 +48,7 @@ $node->safe_psql('postgres',
 # their ~/.psql_history, so be sure to redirect history into a temp file.
 # We might as well put it in the test log directory, so that buildfarm runs
 # capture the result for possible debugging purposes.
-my $historyfile = "${TestLib::log_path}/010_psql_history.txt";
+my $historyfile = "${Postgres::Test::Utils::log_path}/010_psql_history.txt";
 $ENV{PSQL_HISTORY} = $historyfile;
 
 # Another pitfall for developers is that they might have a ~/.inputrc
diff --git a/src/bin/psql/t/020_cancel.pl b/src/bin/psql/t/020_cancel.pl
index b3edaaf35d..c4cbb08e30 100644
--- a/src/bin/psql/t/020_cancel.pl
+++ b/src/bin/psql/t/020_cancel.pl
@@ -4,14 +4,14 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 2;
 use Time::HiRes qw(usleep);
 
-my $tempdir = TestLib::tempdir;
+my $tempdir = Postgres::Test::Utils::tempdir;
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
@@ -44,7 +44,7 @@ SKIP: {
 	pump $h while length $stdin;
 	my $count;
 	my $psql_pid;
-	until (-s "$tempdir/psql.pid" and ($psql_pid = TestLib::slurp_file("$tempdir/psql.pid")) =~ /^\d+\n/s)
+	until (-s "$tempdir/psql.pid" and ($psql_pid = Postgres::Test::Utils::slurp_file("$tempdir/psql.pid")) =~ /^\d+\n/s)
 	{
 		($count++ < 180 * 100) or die "pid file did not appear";
 		usleep(10_000)
diff --git a/src/bin/scripts/t/010_clusterdb.pl b/src/bin/scripts/t/010_clusterdb.pl
index aae5ea985b..9ad6f28437 100644
--- a/src/bin/scripts/t/010_clusterdb.pl
+++ b/src/bin/scripts/t/010_clusterdb.pl
@@ -4,15 +4,15 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 14;
 
 program_help_ok('clusterdb');
 program_version_ok('clusterdb');
 program_options_handling_ok('clusterdb');
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
diff --git a/src/bin/scripts/t/011_clusterdb_all.pl b/src/bin/scripts/t/011_clusterdb_all.pl
index 6ba71780de..74e0f1ee07 100644
--- a/src/bin/scripts/t/011_clusterdb_all.pl
+++ b/src/bin/scripts/t/011_clusterdb_all.pl
@@ -4,11 +4,11 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 2;
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index 3db2f13ae2..f75e7942f8 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -4,15 +4,15 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 22;
 
 program_help_ok('createdb');
 program_version_ok('createdb');
 program_options_handling_ok('createdb');
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
diff --git a/src/bin/scripts/t/040_createuser.pl b/src/bin/scripts/t/040_createuser.pl
index 3da8b7ae75..98a35d4847 100644
--- a/src/bin/scripts/t/040_createuser.pl
+++ b/src/bin/scripts/t/040_createuser.pl
@@ -4,15 +4,15 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 17;
 
 program_help_ok('createuser');
 program_version_ok('createuser');
 program_options_handling_ok('createuser');
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
diff --git a/src/bin/scripts/t/050_dropdb.pl b/src/bin/scripts/t/050_dropdb.pl
index b9f0592bca..e50d822a50 100644
--- a/src/bin/scripts/t/050_dropdb.pl
+++ b/src/bin/scripts/t/050_dropdb.pl
@@ -4,15 +4,15 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 13;
 
 program_help_ok('dropdb');
 program_version_ok('dropdb');
 program_options_handling_ok('dropdb');
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
diff --git a/src/bin/scripts/t/070_dropuser.pl b/src/bin/scripts/t/070_dropuser.pl
index 26dadaf4a5..15711320c4 100644
--- a/src/bin/scripts/t/070_dropuser.pl
+++ b/src/bin/scripts/t/070_dropuser.pl
@@ -4,15 +4,15 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 11;
 
 program_help_ok('dropuser');
 program_version_ok('dropuser');
 program_options_handling_ok('dropuser');
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
diff --git a/src/bin/scripts/t/080_pg_isready.pl b/src/bin/scripts/t/080_pg_isready.pl
index 4f1184953e..9792e57be5 100644
--- a/src/bin/scripts/t/080_pg_isready.pl
+++ b/src/bin/scripts/t/080_pg_isready.pl
@@ -4,8 +4,8 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 10;
 
 program_help_ok('pg_isready');
@@ -14,7 +14,7 @@ program_options_handling_ok('pg_isready');
 
 command_fails(['pg_isready'], 'fails with no server running');
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
diff --git a/src/bin/scripts/t/090_reindexdb.pl b/src/bin/scripts/t/090_reindexdb.pl
index 541504d8f0..182516c1c9 100644
--- a/src/bin/scripts/t/090_reindexdb.pl
+++ b/src/bin/scripts/t/090_reindexdb.pl
@@ -4,15 +4,15 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 58;
 
 program_help_ok('reindexdb');
 program_version_ok('reindexdb');
 program_options_handling_ok('reindexdb');
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
@@ -21,7 +21,7 @@ $ENV{PGOPTIONS} = '--client-min-messages=WARNING';
 # Create a tablespace for testing.
 my $tbspace_path = $node->basedir . '/regress_reindex_tbspace';
 mkdir $tbspace_path or die "cannot create directory $tbspace_path";
-$tbspace_path = TestLib::perl2host($tbspace_path);
+$tbspace_path = Postgres::Test::Utils::perl2host($tbspace_path);
 my $tbspace_name = 'reindex_tbspace';
 $node->safe_psql('postgres',
 	"CREATE TABLESPACE $tbspace_name LOCATION '$tbspace_path';");
diff --git a/src/bin/scripts/t/091_reindexdb_all.pl b/src/bin/scripts/t/091_reindexdb_all.pl
index 34174e4d71..6e48952e6c 100644
--- a/src/bin/scripts/t/091_reindexdb_all.pl
+++ b/src/bin/scripts/t/091_reindexdb_all.pl
@@ -4,10 +4,10 @@
 use strict;
 use warnings;
 
-use PostgresNode;
+use Postgres::Test::Cluster;
 use Test::More tests => 2;
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
diff --git a/src/bin/scripts/t/100_vacuumdb.pl b/src/bin/scripts/t/100_vacuumdb.pl
index 0f1e5bb278..a065073f9a 100644
--- a/src/bin/scripts/t/100_vacuumdb.pl
+++ b/src/bin/scripts/t/100_vacuumdb.pl
@@ -4,15 +4,15 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 58;
 
 program_help_ok('vacuumdb');
 program_version_ok('vacuumdb');
 program_options_handling_ok('vacuumdb');
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
diff --git a/src/bin/scripts/t/101_vacuumdb_all.pl b/src/bin/scripts/t/101_vacuumdb_all.pl
index a60fc79aae..7a0c667a96 100644
--- a/src/bin/scripts/t/101_vacuumdb_all.pl
+++ b/src/bin/scripts/t/101_vacuumdb_all.pl
@@ -4,10 +4,10 @@
 use strict;
 use warnings;
 
-use PostgresNode;
+use Postgres::Test::Cluster;
 use Test::More tests => 2;
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
diff --git a/src/bin/scripts/t/102_vacuumdb_stages.pl b/src/bin/scripts/t/102_vacuumdb_stages.pl
index c15057a763..74ea924bc1 100644
--- a/src/bin/scripts/t/102_vacuumdb_stages.pl
+++ b/src/bin/scripts/t/102_vacuumdb_stages.pl
@@ -4,10 +4,10 @@
 use strict;
 use warnings;
 
-use PostgresNode;
+use Postgres::Test::Cluster;
 use Test::More tests => 4;
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
diff --git a/src/bin/scripts/t/200_connstr.pl b/src/bin/scripts/t/200_connstr.pl
index f702e32f00..3c8ac18b47 100644
--- a/src/bin/scripts/t/200_connstr.pl
+++ b/src/bin/scripts/t/200_connstr.pl
@@ -4,8 +4,8 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 3;
 
 # Tests to check connection string handling in utilities
@@ -23,7 +23,7 @@ my $dbname2 =
 my $dbname3 = generate_ascii_string(130, 192);
 my $dbname4 = generate_ascii_string(193, 255);
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init(extra => [ '--locale=C', '--encoding=LATIN1' ]);
 $node->start;
 
diff --git a/src/test/authentication/t/001_password.pl b/src/test/authentication/t/001_password.pl
index 9498c18d7d..ee0b0b55c0 100644
--- a/src/test/authentication/t/001_password.pl
+++ b/src/test/authentication/t/001_password.pl
@@ -10,8 +10,8 @@
 
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More;
 if (!$use_unix_sockets)
 {
@@ -62,7 +62,7 @@ sub test_role
 }
 
 # Initialize primary node
-my $node = PostgresNode->new('primary');
+my $node = Postgres::Test::Cluster->new('primary');
 $node->init;
 $node->append_conf('postgresql.conf', "log_connections = on\n");
 $node->start;
@@ -134,7 +134,7 @@ $ENV{"PGCHANNELBINDING"} = 'require';
 test_role($node, 'scram_role', 'scram-sha-256', 2);
 
 # Test .pgpass processing; but use a temp file, don't overwrite the real one!
-my $pgpassfile = "${TestLib::tmp_check}/pgpass";
+my $pgpassfile = "${Postgres::Test::Utils::tmp_check}/pgpass";
 
 delete $ENV{"PGPASSWORD"};
 delete $ENV{"PGCHANNELBINDING"};
diff --git a/src/test/authentication/t/002_saslprep.pl b/src/test/authentication/t/002_saslprep.pl
index 4799e927db..6609911490 100644
--- a/src/test/authentication/t/002_saslprep.pl
+++ b/src/test/authentication/t/002_saslprep.pl
@@ -7,8 +7,8 @@
 
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More;
 if (!$use_unix_sockets)
 {
@@ -62,7 +62,7 @@ sub test_login
 
 # Initialize primary node. Force UTF-8 encoding, so that we can use non-ASCII
 # characters in the passwords below.
-my $node = PostgresNode->new('primary');
+my $node = Postgres::Test::Cluster->new('primary');
 $node->init(extra => [ '--locale=C', '--encoding=UTF8' ]);
 $node->start;
 
diff --git a/src/test/kerberos/t/001_auth.pl b/src/test/kerberos/t/001_auth.pl
index 34562045cb..a5c1858d3a 100644
--- a/src/test/kerberos/t/001_auth.pl
+++ b/src/test/kerberos/t/001_auth.pl
@@ -16,8 +16,8 @@
 
 use strict;
 use warnings;
-use TestLib;
-use PostgresNode;
+use Postgres::Test::Utils;
+use Postgres::Test::Cluster;
 use Test::More;
 use Time::HiRes qw(usleep);
 
@@ -69,15 +69,15 @@ my $host     = 'auth-test-localhost.postgresql.example.com';
 my $hostaddr = '127.0.0.1';
 my $realm    = 'EXAMPLE.COM';
 
-my $krb5_conf   = "${TestLib::tmp_check}/krb5.conf";
-my $kdc_conf    = "${TestLib::tmp_check}/kdc.conf";
-my $krb5_cache  = "${TestLib::tmp_check}/krb5cc";
-my $krb5_log    = "${TestLib::log_path}/krb5libs.log";
-my $kdc_log     = "${TestLib::log_path}/krb5kdc.log";
-my $kdc_port    = PostgresNode::get_free_port();
-my $kdc_datadir = "${TestLib::tmp_check}/krb5kdc";
-my $kdc_pidfile = "${TestLib::tmp_check}/krb5kdc.pid";
-my $keytab      = "${TestLib::tmp_check}/krb5.keytab";
+my $krb5_conf   = "${Postgres::Test::Utils::tmp_check}/krb5.conf";
+my $kdc_conf    = "${Postgres::Test::Utils::tmp_check}/kdc.conf";
+my $krb5_cache  = "${Postgres::Test::Utils::tmp_check}/krb5cc";
+my $krb5_log    = "${Postgres::Test::Utils::log_path}/krb5libs.log";
+my $kdc_log     = "${Postgres::Test::Utils::log_path}/krb5kdc.log";
+my $kdc_port    = Postgres::Test::Cluster::get_free_port();
+my $kdc_datadir = "${Postgres::Test::Utils::tmp_check}/krb5kdc";
+my $kdc_pidfile = "${Postgres::Test::Utils::tmp_check}/krb5kdc.pid";
+my $keytab      = "${Postgres::Test::Utils::tmp_check}/krb5.keytab";
 
 my $dbname      = 'postgres';
 my $username    = 'test1';
@@ -167,7 +167,7 @@ END
 
 note "setting up PostgreSQL instance";
 
-my $node = PostgresNode->new('node');
+my $node = Postgres::Test::Cluster->new('node');
 $node->init;
 $node->append_conf(
 	'postgresql.conf', qq{
diff --git a/src/test/ldap/t/001_auth.pl b/src/test/ldap/t/001_auth.pl
index 1d1282f8dc..4af9da5728 100644
--- a/src/test/ldap/t/001_auth.pl
+++ b/src/test/ldap/t/001_auth.pl
@@ -3,8 +3,8 @@
 
 use strict;
 use warnings;
-use TestLib;
-use PostgresNode;
+use Postgres::Test::Utils;
+use Postgres::Test::Cluster;
 use Test::More;
 
 if ($ENV{with_ldap} eq 'yes')
@@ -51,21 +51,21 @@ elsif ($^O eq 'freebsd')
 
 $ENV{PATH} = "$ldap_bin_dir:$ENV{PATH}" if $ldap_bin_dir;
 
-my $ldap_datadir  = "${TestLib::tmp_check}/openldap-data";
-my $slapd_certs   = "${TestLib::tmp_check}/slapd-certs";
-my $slapd_conf    = "${TestLib::tmp_check}/slapd.conf";
-my $slapd_pidfile = "${TestLib::tmp_check}/slapd.pid";
-my $slapd_logfile = "${TestLib::log_path}/slapd.log";
-my $ldap_conf     = "${TestLib::tmp_check}/ldap.conf";
+my $ldap_datadir  = "${Postgres::Test::Utils::tmp_check}/openldap-data";
+my $slapd_certs   = "${Postgres::Test::Utils::tmp_check}/slapd-certs";
+my $slapd_conf    = "${Postgres::Test::Utils::tmp_check}/slapd.conf";
+my $slapd_pidfile = "${Postgres::Test::Utils::tmp_check}/slapd.pid";
+my $slapd_logfile = "${Postgres::Test::Utils::log_path}/slapd.log";
+my $ldap_conf     = "${Postgres::Test::Utils::tmp_check}/ldap.conf";
 my $ldap_server   = 'localhost';
-my $ldap_port     = PostgresNode::get_free_port();
-my $ldaps_port    = PostgresNode::get_free_port();
+my $ldap_port     = Postgres::Test::Cluster::get_free_port();
+my $ldaps_port    = Postgres::Test::Cluster::get_free_port();
 my $ldap_url      = "ldap://$ldap_server:$ldap_port";
 my $ldaps_url     = "ldaps://$ldap_server:$ldaps_port";
 my $ldap_basedn   = 'dc=example,dc=net';
 my $ldap_rootdn   = 'cn=Manager,dc=example,dc=net';
 my $ldap_rootpw   = 'secret';
-my $ldap_pwfile   = "${TestLib::tmp_check}/ldappassword";
+my $ldap_pwfile   = "${Postgres::Test::Utils::tmp_check}/ldappassword";
 
 note "setting up slapd";
 
@@ -153,7 +153,7 @@ system_or_bail 'ldappasswd', '-x', '-y', $ldap_pwfile, '-s', 'secret2',
 
 note "setting up PostgreSQL instance";
 
-my $node = PostgresNode->new('node');
+my $node = Postgres::Test::Cluster->new('node');
 $node->init;
 $node->append_conf('postgresql.conf', "log_connections = on\n");
 $node->start;
diff --git a/src/test/modules/brin/t/01_workitems.pl b/src/test/modules/brin/t/01_workitems.pl
index ea2e2944a1..fbc0cc57ec 100644
--- a/src/test/modules/brin/t/01_workitems.pl
+++ b/src/test/modules/brin/t/01_workitems.pl
@@ -6,11 +6,11 @@
 use strict;
 use warnings;
 
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 2;
-use PostgresNode;
+use Postgres::Test::Cluster;
 
-my $node = PostgresNode->new('tango');
+my $node = Postgres::Test::Cluster->new('tango');
 $node->init;
 $node->append_conf('postgresql.conf', 'autovacuum_naptime=1s');
 $node->start;
diff --git a/src/test/modules/commit_ts/t/001_base.pl b/src/test/modules/commit_ts/t/001_base.pl
index 0c504421d4..4be30f1aa3 100644
--- a/src/test/modules/commit_ts/t/001_base.pl
+++ b/src/test/modules/commit_ts/t/001_base.pl
@@ -6,11 +6,11 @@
 use strict;
 use warnings;
 
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 2;
-use PostgresNode;
+use Postgres::Test::Cluster;
 
-my $node = PostgresNode->new('foxtrot');
+my $node = Postgres::Test::Cluster->new('foxtrot');
 $node->init;
 $node->append_conf('postgresql.conf', 'track_commit_timestamp = on');
 $node->start;
diff --git a/src/test/modules/commit_ts/t/002_standby.pl b/src/test/modules/commit_ts/t/002_standby.pl
index 227eddeda2..3bf712ef52 100644
--- a/src/test/modules/commit_ts/t/002_standby.pl
+++ b/src/test/modules/commit_ts/t/002_standby.pl
@@ -6,12 +6,12 @@
 use strict;
 use warnings;
 
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 4;
-use PostgresNode;
+use Postgres::Test::Cluster;
 
 my $bkplabel = 'backup';
-my $primary  = PostgresNode->new('primary');
+my $primary  = Postgres::Test::Cluster->new('primary');
 $primary->init(allows_streaming => 1);
 
 $primary->append_conf(
@@ -22,7 +22,7 @@ $primary->append_conf(
 $primary->start;
 $primary->backup($bkplabel);
 
-my $standby = PostgresNode->new('standby');
+my $standby = Postgres::Test::Cluster->new('standby');
 $standby->init_from_backup($primary, $bkplabel, has_streaming => 1);
 $standby->start;
 
diff --git a/src/test/modules/commit_ts/t/003_standby_2.pl b/src/test/modules/commit_ts/t/003_standby_2.pl
index 27c5bfbfb7..c43ac5508f 100644
--- a/src/test/modules/commit_ts/t/003_standby_2.pl
+++ b/src/test/modules/commit_ts/t/003_standby_2.pl
@@ -6,12 +6,12 @@
 use strict;
 use warnings;
 
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More tests => 4;
-use PostgresNode;
+use Postgres::Test::Cluster;
 
 my $bkplabel = 'backup';
-my $primary  = PostgresNode->new('primary');
+my $primary  = Postgres::Test::Cluster->new('primary');
 $primary->init(allows_streaming => 1);
 $primary->append_conf(
 	'postgresql.conf', qq{
@@ -21,7 +21,7 @@ $primary->append_conf(
 $primary->start;
 $primary->backup($bkplabel);
 
-my $standby = PostgresNode->new('standby');
+my $standby = Postgres::Test::Cluster->new('standby');
 $standby->init_from_backup($primary, $bkplabel, has_streaming => 1);
 $standby->start;
 
diff --git a/src/test/modules/commit_ts/t/004_restart.pl b/src/test/modules/commit_ts/t/004_restart.pl
index 5d92c5a2e6..6a46bfc4b9 100644
--- a/src/test/modules/commit_ts/t/004_restart.pl
+++ b/src/test/modules/commit_ts/t/004_restart.pl
@@ -4,11 +4,11 @@
 # Testing of commit timestamps preservation across restarts
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 16;
 
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 $node_primary->init(allows_streaming => 1);
 $node_primary->append_conf('postgresql.conf', 'track_commit_timestamp = on');
 $node_primary->start;
diff --git a/src/test/modules/libpq_pipeline/t/001_libpq_pipeline.pl b/src/test/modules/libpq_pipeline/t/001_libpq_pipeline.pl
index 49f211c827..bf9bc2d833 100644
--- a/src/test/modules/libpq_pipeline/t/001_libpq_pipeline.pl
+++ b/src/test/modules/libpq_pipeline/t/001_libpq_pipeline.pl
@@ -5,11 +5,11 @@ use strict;
 use warnings;
 
 use Config;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More;
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
@@ -20,7 +20,7 @@ my ($out, $err) = run_command([ 'libpq_pipeline', 'tests' ]);
 die "oops: $err" unless $err eq '';
 my @tests = split(/\s+/, $out);
 
-mkdir "$TestLib::tmp_check/traces";
+mkdir "$Postgres::Test::Utils::tmp_check/traces";
 
 for my $testname (@tests)
 {
@@ -30,7 +30,7 @@ for my $testname (@tests)
 		  pipeline_abort transaction disallowed_in_pipeline)) > 0;
 
 	# For a bunch of tests, generate a libpq trace file too.
-	my $traceout = "$TestLib::tmp_check/traces/$testname.trace";
+	my $traceout = "$Postgres::Test::Utils::tmp_check/traces/$testname.trace";
 	if ($cmptrace)
 	{
 		push @extraargs, "-t", $traceout;
diff --git a/src/test/modules/ssl_passphrase_callback/t/001_testfunc.pl b/src/test/modules/ssl_passphrase_callback/t/001_testfunc.pl
index 1f28f303f1..ce09a88e24 100644
--- a/src/test/modules/ssl_passphrase_callback/t/001_testfunc.pl
+++ b/src/test/modules/ssl_passphrase_callback/t/001_testfunc.pl
@@ -6,9 +6,9 @@ use warnings;
 
 use File::Copy;
 
-use TestLib;
+use Postgres::Test::Utils;
 use Test::More;
-use PostgresNode;
+use Postgres::Test::Cluster;
 
 unless (($ENV{with_ssl} || "") eq 'openssl')
 {
@@ -20,7 +20,7 @@ my $rot13pass = "SbbOnE1";
 
 # see the Makefile for how the certificate and key have been generated
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->append_conf('postgresql.conf',
 	"ssl_passphrase.passphrase = '$rot13pass'");
@@ -63,7 +63,7 @@ like(
 $node->append_conf('postgresql.conf', "ssl_passphrase.passphrase = 'blurfl'");
 
 # try to start the server again
-my $ret = TestLib::system_log('pg_ctl', '-D', $node->data_dir, '-l',
+my $ret = Postgres::Test::Utils::system_log('pg_ctl', '-D', $node->data_dir, '-l',
 	$node->logfile, 'start');
 
 
diff --git a/src/test/modules/test_misc/t/001_constraint_validation.pl b/src/test/modules/test_misc/t/001_constraint_validation.pl
index 7c1929f805..8f9b54b00a 100644
--- a/src/test/modules/test_misc/t/001_constraint_validation.pl
+++ b/src/test/modules/test_misc/t/001_constraint_validation.pl
@@ -5,12 +5,12 @@
 
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 42;
 
 # Initialize a test cluster
-my $node = PostgresNode->new('primary');
+my $node = Postgres::Test::Cluster->new('primary');
 $node->init();
 # Turn message level up to DEBUG1 so that we get the messages we want to see
 $node->append_conf('postgresql.conf', 'client_min_messages = DEBUG1');
diff --git a/src/test/modules/test_pg_dump/t/001_base.pl b/src/test/modules/test_pg_dump/t/001_base.pl
index ea7739d725..55ae455108 100644
--- a/src/test/modules/test_pg_dump/t/001_base.pl
+++ b/src/test/modules/test_pg_dump/t/001_base.pl
@@ -5,12 +5,12 @@ use strict;
 use warnings;
 
 use Config;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More;
 
-my $tempdir       = TestLib::tempdir;
-my $tempdir_short = TestLib::tempdir_short;
+my $tempdir       = Postgres::Test::Utils::tempdir;
+my $tempdir_short = Postgres::Test::Utils::tempdir_short;
 
 ###############################################################
 # This structure is based off of the src/bin/pg_dump/t test
@@ -29,7 +29,7 @@ my $tempdir_short = TestLib::tempdir_short;
 # the full command and arguments to run.  Note that this is run
 # using $node->command_ok(), so the port does not need to be
 # specified and is pulled from $PGPORT, which is set by the
-# PostgresNode system.
+# Postgres::Test::Cluster system.
 #
 # restore_cmd is the pg_restore command to run, if any.  Note
 # that this should generally be used when the pg_dump goes to
@@ -713,7 +713,7 @@ my %tests = (
 #########################################
 # Create a PG instance to test actually dumping from
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 $node->init;
 $node->start;
 
diff --git a/src/test/perl/Makefile b/src/test/perl/Makefile
index 3d3a95b52f..427ce916ec 100644
--- a/src/test/perl/Makefile
+++ b/src/test/perl/Makefile
@@ -16,20 +16,20 @@ include $(top_builddir)/src/Makefile.global
 ifeq ($(enable_tap_tests),yes)
 
 installdirs:
-	$(MKDIR_P) '$(DESTDIR)$(pgxsdir)/$(subdir)'
+	$(MKDIR_P) '$(DESTDIR)$(pgxsdir)/$(subdir)/Postgres/Test'
 
 install: all installdirs
-	$(INSTALL_DATA) $(srcdir)/TestLib.pm '$(DESTDIR)$(pgxsdir)/$(subdir)/TestLib.pm'
-	$(INSTALL_DATA) $(srcdir)/SimpleTee.pm '$(DESTDIR)$(pgxsdir)/$(subdir)/SimpleTee.pm'
-	$(INSTALL_DATA) $(srcdir)/RecursiveCopy.pm '$(DESTDIR)$(pgxsdir)/$(subdir)/RecursiveCopy.pm'
-	$(INSTALL_DATA) $(srcdir)/PostgresNode.pm '$(DESTDIR)$(pgxsdir)/$(subdir)/PostgresNode.pm'
-	$(INSTALL_DATA) $(srcdir)/PostgresVersion.pm '$(DESTDIR)$(pgxsdir)/$(subdir)/PostgresVersion.pm'
+	$(INSTALL_DATA) $(srcdir)/Postgres/Test/Utils.pm '$(DESTDIR)$(pgxsdir)/$(subdir)/Postgres/Test/Utils.pm'
+	$(INSTALL_DATA) $(srcdir)/Postgres/Test/SimpleTee.pm '$(DESTDIR)$(pgxsdir)/$(subdir)/Postgres/Test/SimpleTee.pm'
+	$(INSTALL_DATA) $(srcdir)/Postgres/Test/RecursiveCopy.pm '$(DESTDIR)$(pgxsdir)/$(subdir)/Postgres/Test/RecursiveCopy.pm'
+	$(INSTALL_DATA) $(srcdir)/Postgres/Test/Cluster.pm '$(DESTDIR)$(pgxsdir)/$(subdir)/Postgres/Test/Cluster.pm'
+	$(INSTALL_DATA) $(srcdir)/Postgres/Test/PostgresVersion.pm '$(DESTDIR)$(pgxsdir)/$(subdir)/Postgres/Test/PostgresVersion.pm'
 
 uninstall:
-	rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/TestLib.pm'
-	rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/SimpleTee.pm'
-	rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/RecursiveCopy.pm'
-	rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/PostgresNode.pm'
-	rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/PostgresVersion.pm'
+	rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/Postgres/Test/Utils.pm'
+	rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/Postgres/Test/SimpleTee.pm'
+	rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/Postgres/Test/RecursiveCopy.pm'
+	rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/Postgres/Test/Cluster.pm'
+	rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/Postgres/Test/PostgresVersion.pm'
 
 endif
diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/Postgres/Test/Cluster.pm
similarity index 92%
rename from src/test/perl/PostgresNode.pm
rename to src/test/perl/Postgres/Test/Cluster.pm
index c59da758c7..44621f3b4f 100644
--- a/src/test/perl/PostgresNode.pm
+++ b/src/test/perl/Postgres/Test/Cluster.pm
@@ -5,13 +5,13 @@
 
 =head1 NAME
 
-PostgresNode - class representing PostgreSQL server instance
+Postgres::Test::Cluster - class representing PostgreSQL server instance
 
 =head1 SYNOPSIS
 
-  use PostgresNode;
+  use Postgres::Test::Cluster;
 
-  my $node = PostgresNode->new('mynode');
+  my $node = Postgres::Test::Cluster->new('mynode');
 
   # Create a data directory with initdb
   $node->init();
@@ -61,7 +61,7 @@ PostgresNode - class representing PostgreSQL server instance
   my $ret = $node->backup_fs_cold('testbackup3')
 
   # Restore it to create a new independent node (not a replica)
-  my $other_node = PostgresNode->new('mycopy');
+  my $other_node = Postgres::Test::Cluster->new('mycopy');
   $other_node->init_from_backup($node, 'testbackup');
   $other_node->start;
 
@@ -69,15 +69,15 @@ PostgresNode - class representing PostgreSQL server instance
   $node->stop('fast');
 
   # Find a free, unprivileged TCP port to bind some other service to
-  my $port = PostgresNode::get_free_port();
+  my $port = Postgres::Test::Cluster::get_free_port();
 
 =head1 DESCRIPTION
 
-PostgresNode contains a set of routines able to work on a PostgreSQL node,
+Postgres::Test::Cluster contains a set of routines able to work on a PostgreSQL node,
 allowing to start, stop, backup and initialize it with various options.
 The set of nodes managed by a given test is also managed by this module.
 
-In addition to node management, PostgresNode instances have some wrappers
+In addition to node management, Postgres::Test::Cluster instances have some wrappers
 around Test::More functions to run commands with an environment set up to
 point to the instance.
 
@@ -85,7 +85,7 @@ The IPC::Run module is required.
 
 =cut
 
-package PostgresNode;
+package Postgres::Test::Cluster;
 
 use strict;
 use warnings;
@@ -100,11 +100,11 @@ use File::Spec;
 use File::stat qw(stat);
 use File::Temp ();
 use IPC::Run;
-use PostgresVersion;
-use RecursiveCopy;
+use Postgres::Test::PostgresVersion;
+use Postgres::Test::RecursiveCopy;
 use Socket;
 use Test::More;
-use TestLib ();
+use Postgres::Test::Utils ();
 use Time::HiRes qw(usleep);
 use Scalar::Util qw(blessed);
 
@@ -116,10 +116,10 @@ INIT
 
 	# Set PGHOST for backward compatibility.  This doesn't work for own_host
 	# nodes, so prefer to not rely on this when writing new tests.
-	$use_tcp            = !$TestLib::use_unix_sockets;
+	$use_tcp            = !$Postgres::Test::Utils::use_unix_sockets;
 	$test_localhost     = "127.0.0.1";
 	$last_host_assigned = 1;
-	$test_pghost        = $use_tcp ? $test_localhost : TestLib::tempdir_short;
+	$test_pghost        = $use_tcp ? $test_localhost : Postgres::Test::Utils::tempdir_short;
 	$ENV{PGHOST}        = $test_pghost;
 	$ENV{PGDATABASE}    = 'postgres';
 
@@ -369,8 +369,8 @@ sub set_replication_conf
 	  or croak "set_replication_conf only works with the default host";
 
 	open my $hba, '>>', "$pgdata/pg_hba.conf";
-	print $hba "\n# Allow replication (set up by PostgresNode.pm)\n";
-	if ($TestLib::windows_os && !$TestLib::use_unix_sockets)
+	print $hba "\n# Allow replication (set up by Postgres::Test::Cluster.pm)\n";
+	if ($Postgres::Test::Utils::windows_os && !$Postgres::Test::Utils::use_unix_sockets)
 	{
 		print $hba
 		  "host replication all $test_localhost/32 sspi include_realm=1 map=regress\n";
@@ -419,13 +419,13 @@ sub init
 	mkdir $self->backup_dir;
 	mkdir $self->archive_dir;
 
-	TestLib::system_or_bail('initdb', '-D', $pgdata, '-A', 'trust', '-N',
+	Postgres::Test::Utils::system_or_bail('initdb', '-D', $pgdata, '-A', 'trust', '-N',
 		@{ $params{extra} });
-	TestLib::system_or_bail($ENV{PG_REGRESS}, '--config-auth', $pgdata,
+	Postgres::Test::Utils::system_or_bail($ENV{PG_REGRESS}, '--config-auth', $pgdata,
 		@{ $params{auth_extra} });
 
 	open my $conf, '>>', "$pgdata/postgresql.conf";
-	print $conf "\n# Added by PostgresNode.pm\n";
+	print $conf "\n# Added by Postgres::Test::Cluster.pm\n";
 	print $conf "fsync = off\n";
 	print $conf "restart_after_crash = off\n";
 	print $conf "log_line_prefix = '%m [%p] %q%a '\n";
@@ -437,7 +437,7 @@ sub init
 	# TEMP_CONFIG.  Otherwise, print it before TEMP_CONFIG, thereby permitting
 	# overrides.  Settings that merely improve performance or ease debugging
 	# belong before TEMP_CONFIG.
-	print $conf TestLib::slurp_file($ENV{TEMP_CONFIG})
+	print $conf Postgres::Test::Utils::slurp_file($ENV{TEMP_CONFIG})
 	  if defined $ENV{TEMP_CONFIG};
 
 	# XXX Neutralize any stats_temp_directory in TEMP_CONFIG.  Nodes running
@@ -510,7 +510,7 @@ sub append_conf
 
 	my $conffile = $self->data_dir . '/' . $filename;
 
-	TestLib::append_to_file($conffile, $str . "\n");
+	Postgres::Test::Utils::append_to_file($conffile, $str . "\n");
 
 	chmod($self->group_access() ? 0640 : 0600, $conffile)
 	  or die("unable to set permissions for $conffile");
@@ -538,7 +538,7 @@ sub adjust_conf
 
 	my $conffile = $self->data_dir . '/' . $filename;
 
-	my $contents = TestLib::slurp_file($conffile);
+	my $contents = Postgres::Test::Utils::slurp_file($conffile);
 	my @lines    = split(/\n/, $contents);
 	my @result;
 	my $eq = $skip_equals ? '' : '= ';
@@ -587,7 +587,7 @@ sub backup
 	local %ENV = $self->_get_env();
 
 	print "# Taking pg_basebackup $backup_name from node \"$name\"\n";
-	TestLib::system_or_bail(
+	Postgres::Test::Utils::system_or_bail(
 		'pg_basebackup', '-D',
 		$backup_path,    '-h',
 		$self->host,     '-p',
@@ -652,7 +652,7 @@ sub _backup_fs
 		print "# pg_start_backup: $stdout\n";
 	}
 
-	RecursiveCopy::copypath(
+	Postgres::Test::RecursiveCopy::copypath(
 		$self->data_dir,
 		$backup_path,
 		filterfn => sub {
@@ -682,7 +682,7 @@ sub _backup_fs
 =item $node->init_from_backup(root_node, backup_name)
 
 Initialize a node from a backup, which may come from this node or a different
-node. root_node must be a PostgresNode reference, backup_name the string name
+node. root_node must be a Postgres::Test::Cluster reference, backup_name the string name
 of a backup previously created on that node with $node->backup.
 
 Does not start the node after initializing it.
@@ -732,10 +732,10 @@ sub init_from_backup
 	if (defined $params{tar_program})
 	{
 		mkdir($data_path);
-		TestLib::system_or_bail($params{tar_program}, 'xf',
+		Postgres::Test::Utils::system_or_bail($params{tar_program}, 'xf',
 			$backup_path . '/base.tar',
 			'-C', $data_path);
-		TestLib::system_or_bail(
+		Postgres::Test::Utils::system_or_bail(
 			$params{tar_program},         'xf',
 			$backup_path . '/pg_wal.tar', '-C',
 			$data_path . '/pg_wal');
@@ -743,7 +743,7 @@ sub init_from_backup
 	else
 	{
 		rmdir($data_path);
-		RecursiveCopy::copypath($backup_path, $data_path);
+		Postgres::Test::RecursiveCopy::copypath($backup_path, $data_path);
 	}
 	chmod(0700, $data_path);
 
@@ -827,13 +827,13 @@ sub start
 	# sub init) so that it does not get copied to standbys.
 	# -w is now the default but having it here does no harm and helps
 	# compatibility with older versions.
-	$ret = TestLib::system_log('pg_ctl', '-w', '-D', $self->data_dir, '-l',
+	$ret = Postgres::Test::Utils::system_log('pg_ctl', '-w', '-D', $self->data_dir, '-l',
 		$self->logfile, '-o', "--cluster-name=$name", 'start');
 
 	if ($ret != 0)
 	{
 		print "# pg_ctl start failed; logfile:\n";
-		print TestLib::slurp_file($self->logfile);
+		print Postgres::Test::Utils::slurp_file($self->logfile);
 		BAIL_OUT("pg_ctl start failed") unless $params{fail_ok};
 		return 0;
 	}
@@ -865,7 +865,7 @@ sub kill9
 	print "### Killing node \"$name\" using signal 9\n";
 	# kill(9, ...) fails under msys Perl 5.8.8, so fall back on pg_ctl.
 	kill(9, $self->{_pid})
-	  or TestLib::system_or_bail('pg_ctl', 'kill', 'KILL', $self->{_pid});
+	  or Postgres::Test::Utils::system_or_bail('pg_ctl', 'kill', 'KILL', $self->{_pid});
 	$self->{_pid} = undef;
 	return;
 }
@@ -894,7 +894,7 @@ sub stop
 	$mode = 'fast' unless defined $mode;
 	return unless defined $self->{_pid};
 	print "### Stopping node \"$name\" using mode $mode\n";
-	TestLib::system_or_bail('pg_ctl', '-D', $pgdata, '-m', $mode, 'stop');
+	Postgres::Test::Utils::system_or_bail('pg_ctl', '-D', $pgdata, '-m', $mode, 'stop');
 	$self->_update_pid(0);
 	return;
 }
@@ -917,7 +917,7 @@ sub reload
 	local %ENV = $self->_get_env();
 
 	print "### Reloading node \"$name\"\n";
-	TestLib::system_or_bail('pg_ctl', '-D', $pgdata, 'reload');
+	Postgres::Test::Utils::system_or_bail('pg_ctl', '-D', $pgdata, 'reload');
 	return;
 }
 
@@ -943,7 +943,7 @@ sub restart
 
 	# -w is now the default but having it here does no harm and helps
 	# compatibility with older versions.
-	TestLib::system_or_bail('pg_ctl', '-w', '-D', $pgdata, '-l', $logfile,
+	Postgres::Test::Utils::system_or_bail('pg_ctl', '-w', '-D', $pgdata, '-l', $logfile,
 		'restart');
 
 	$self->_update_pid(1);
@@ -969,7 +969,7 @@ sub promote
 	local %ENV = $self->_get_env();
 
 	print "### Promoting node \"$name\"\n";
-	TestLib::system_or_bail('pg_ctl', '-D', $pgdata, '-l', $logfile,
+	Postgres::Test::Utils::system_or_bail('pg_ctl', '-D', $pgdata, '-l', $logfile,
 		'promote');
 	return;
 }
@@ -993,7 +993,7 @@ sub logrotate
 	local %ENV = $self->_get_env();
 
 	print "### Rotating log in node \"$name\"\n";
-	TestLib::system_or_bail('pg_ctl', '-D', $pgdata, '-l', $logfile,
+	Postgres::Test::Utils::system_or_bail('pg_ctl', '-D', $pgdata, '-l', $logfile,
 		'logrotate');
 	return;
 }
@@ -1018,7 +1018,7 @@ primary_conninfo='$root_connstr'
 sub enable_restoring
 {
 	my ($self, $root_node, $standby) = @_;
-	my $path = TestLib::perl2host($root_node->archive_dir);
+	my $path = Postgres::Test::Utils::perl2host($root_node->archive_dir);
 	my $name = $self->name;
 
 	print "### Enabling WAL restore for node \"$name\"\n";
@@ -1029,9 +1029,9 @@ sub enable_restoring
 	# in this routine, using only one back-slash, need to be properly changed
 	# first. Paths also need to be double-quoted to prevent failures where
 	# the path contains spaces.
-	$path =~ s{\\}{\\\\}g if ($TestLib::windows_os);
+	$path =~ s{\\}{\\\\}g if ($Postgres::Test::Utils::windows_os);
 	my $copy_command =
-	  $TestLib::windows_os
+	  $Postgres::Test::Utils::windows_os
 	  ? qq{copy "$path\\\\%f" "%p"}
 	  : qq{cp "$path/%f" "%p"};
 
@@ -1086,7 +1086,7 @@ sub set_standby_mode
 sub enable_archiving
 {
 	my ($self) = @_;
-	my $path   = TestLib::perl2host($self->archive_dir);
+	my $path   = Postgres::Test::Utils::perl2host($self->archive_dir);
 	my $name   = $self->name;
 
 	print "### Enabling WAL archiving for node \"$name\"\n";
@@ -1097,9 +1097,9 @@ sub enable_archiving
 	# in this routine, using only one back-slash, need to be properly changed
 	# first. Paths also need to be double-quoted to prevent failures where
 	# the path contains spaces.
-	$path =~ s{\\}{\\\\}g if ($TestLib::windows_os);
+	$path =~ s{\\}{\\\\}g if ($Postgres::Test::Utils::windows_os);
 	my $copy_command =
-	  $TestLib::windows_os
+	  $Postgres::Test::Utils::windows_os
 	  ? qq{copy "%p" "$path\\\\%f"}
 	  : qq{cp "%p" "$path/%f"};
 
@@ -1141,9 +1141,9 @@ sub _update_pid
 
 =pod
 
-=item PostgresNode->new(node_name, %params)
+=item Postgres::Test::Cluster->new(node_name, %params)
 
-Build a new object of class C<PostgresNode> (or of a subclass, if you have
+Build a new object of class C<Postgres::Test::Cluster> (or of a subclass, if you have
 one), assigning a free port number.  Remembers the node, to prevent its port
 number from being reused for another node, and to ensure that it gets
 shut down when the test script exits.
@@ -1216,11 +1216,11 @@ sub new
 	my $node = {
 		_port    => $port,
 		_host    => $host,
-		_basedir => "$TestLib::tmp_check/t_${testname}_${name}_data",
+		_basedir => "$Postgres::Test::Utils::tmp_check/t_${testname}_${name}_data",
 		_name    => $name,
 		_logfile_generation => 0,
-		_logfile_base       => "$TestLib::log_path/${testname}_${name}",
-		_logfile            => "$TestLib::log_path/${testname}_${name}.log"
+		_logfile_base       => "$Postgres::Test::Utils::log_path/${testname}_${name}",
+		_logfile            => "$Postgres::Test::Utils::log_path/${testname}_${name}.log"
 	};
 
 	if ($params{install_path})
@@ -1242,7 +1242,7 @@ sub new
 
 	my $v = $node->{_pg_version};
 
-	carp("PostgresNode isn't fully compatible with version " . $v)
+	carp("Postgres::Test::Cluster isn't fully compatible with version " . $v)
 	  if $v < 12;
 
 	return $node;
@@ -1285,7 +1285,7 @@ sub _set_pg_version
 	my $version_line = qx{$pg_config --version};
 	BAIL_OUT("$pg_config failed: $!") if $?;
 
-	$self->{_pg_version} = PostgresVersion->new($version_line);
+	$self->{_pg_version} = Postgres::Test::PostgresVersion->new($version_line);
 
 	BAIL_OUT("could not parse pg_config --version output: $version_line")
 	  unless defined $self->{_pg_version};
@@ -1330,7 +1330,7 @@ sub _get_env
 	my $inst = $self->{_install_path};
 	if ($inst)
 	{
-		if ($TestLib::windows_os)
+		if ($Postgres::Test::Utils::windows_os)
 		{
 			# Windows picks up DLLs from the PATH rather than *LD_LIBRARY_PATH
 			# choose the right path separator
@@ -1393,14 +1393,14 @@ Locate an unprivileged (high) TCP port that's not currently bound to
 anything.  This is used by C<new()>, and also by some test cases that need to
 start other, non-Postgres servers.
 
-Ports assigned to existing PostgresNode objects are automatically
+Ports assigned to existing Postgres::Test::Cluster objects are automatically
 excluded, even if those servers are not currently running.
 
 XXX A port available now may become unavailable by the time we start
 the desired service.
 
 Note: this is not an instance method. As it's not exported it should be
-called from outside the module as C<PostgresNode::get_free_port()>.
+called from outside the module as C<Postgres::Test::Cluster::get_free_port()>.
 
 =cut
 
@@ -1439,7 +1439,7 @@ sub get_free_port
 		if ($found == 1)
 		{
 			foreach my $addr (qw(127.0.0.1),
-				($use_tcp && $TestLib::windows_os)
+				($use_tcp && $Postgres::Test::Utils::windows_os)
 				  ? qw(127.0.0.2 127.0.0.3 0.0.0.0)
 				  : ())
 			{
@@ -1473,7 +1473,7 @@ sub can_bind
 
 	# As in postmaster, don't use SO_REUSEADDR on Windows
 	setsockopt(SOCK, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
-	  unless $TestLib::windows_os;
+	  unless $Postgres::Test::Utils::windows_os;
 	my $ret = bind(SOCK, $paddr) && listen(SOCK, SOMAXCONN);
 	close(SOCK);
 	return $ret;
@@ -1495,7 +1495,7 @@ END
 		next if defined $ENV{'PG_TEST_NOCLEAN'};
 
 		# clean basedir on clean test invocation
-		$node->clean_node if $exit_code == 0 && TestLib::all_tests_passing();
+		$node->clean_node if $exit_code == 0 && Postgres::Test::Utils::all_tests_passing();
 	}
 
 	$? = $exit_code;
@@ -2059,7 +2059,7 @@ sub connect_ok
 	}
 	if (@log_like or @log_unlike)
 	{
-		my $log_contents = TestLib::slurp_file($self->logfile, $log_location);
+		my $log_contents = Postgres::Test::Utils::slurp_file($self->logfile, $log_location);
 
 		while (my $regex = shift @log_like)
 		{
@@ -2129,7 +2129,7 @@ sub connect_fails
 
 	if (@log_like or @log_unlike)
 	{
-		my $log_contents = TestLib::slurp_file($self->logfile, $log_location);
+		my $log_contents = Postgres::Test::Utils::slurp_file($self->logfile, $log_location);
 
 		while (my $regex = shift @log_like)
 		{
@@ -2208,8 +2208,8 @@ $stderr);
 
 =item $node->command_ok(...)
 
-Runs a shell command like TestLib::command_ok, but with PGHOST and PGPORT set
-so that the command will default to connecting to this PostgresNode.
+Runs a shell command like Postgres::Test::Utils::command_ok, but with PGHOST and PGPORT set
+so that the command will default to connecting to this Postgres::Test::Cluster.
 
 =cut
 
@@ -2221,7 +2221,7 @@ sub command_ok
 
 	local %ENV = $self->_get_env();
 
-	TestLib::command_ok(@_);
+	Postgres::Test::Utils::command_ok(@_);
 	return;
 }
 
@@ -2229,7 +2229,7 @@ sub command_ok
 
 =item $node->command_fails(...)
 
-TestLib::command_fails with our connection parameters. See command_ok(...)
+Postgres::Test::Utils::command_fails with our connection parameters. See command_ok(...)
 
 =cut
 
@@ -2241,7 +2241,7 @@ sub command_fails
 
 	local %ENV = $self->_get_env();
 
-	TestLib::command_fails(@_);
+	Postgres::Test::Utils::command_fails(@_);
 	return;
 }
 
@@ -2249,7 +2249,7 @@ sub command_fails
 
 =item $node->command_like(...)
 
-TestLib::command_like with our connection parameters. See command_ok(...)
+Postgres::Test::Utils::command_like with our connection parameters. See command_ok(...)
 
 =cut
 
@@ -2261,7 +2261,7 @@ sub command_like
 
 	local %ENV = $self->_get_env();
 
-	TestLib::command_like(@_);
+	Postgres::Test::Utils::command_like(@_);
 	return;
 }
 
@@ -2269,7 +2269,7 @@ sub command_like
 
 =item $node->command_fails_like(...)
 
-TestLib::command_fails_like with our connection parameters. See command_ok(...)
+Postgres::Test::Utils::command_fails_like with our connection parameters. See command_ok(...)
 
 =cut
 
@@ -2281,7 +2281,7 @@ sub command_fails_like
 
 	local %ENV = $self->_get_env();
 
-	TestLib::command_fails_like(@_);
+	Postgres::Test::Utils::command_fails_like(@_);
 	return;
 }
 
@@ -2289,7 +2289,7 @@ sub command_fails_like
 
 =item $node->command_checks_all(...)
 
-TestLib::command_checks_all with our connection parameters. See
+Postgres::Test::Utils::command_checks_all with our connection parameters. See
 command_ok(...)
 
 =cut
@@ -2302,7 +2302,7 @@ sub command_checks_all
 
 	local %ENV = $self->_get_env();
 
-	TestLib::command_checks_all(@_);
+	Postgres::Test::Utils::command_checks_all(@_);
 	return;
 }
 
@@ -2325,9 +2325,9 @@ sub issues_sql_like
 
 	my $log_location = -s $self->logfile;
 
-	my $result = TestLib::run_log($cmd);
+	my $result = Postgres::Test::Utils::run_log($cmd);
 	ok($result, "@$cmd exit code 0");
-	my $log = TestLib::slurp_file($self->logfile, $log_location);
+	my $log = Postgres::Test::Utils::slurp_file($self->logfile, $log_location);
 	like($log, $expected_sql, "$test_name: SQL found in server log");
 	return;
 }
@@ -2336,8 +2336,8 @@ sub issues_sql_like
 
 =item $node->run_log(...)
 
-Runs a shell command like TestLib::run_log, but with connection parameters set
-so that the command will default to connecting to this PostgresNode.
+Runs a shell command like Postgres::Test::Utils::run_log, but with connection parameters set
+so that the command will default to connecting to this Postgres::Test::Cluster.
 
 =cut
 
@@ -2347,7 +2347,7 @@ sub run_log
 
 	local %ENV = $self->_get_env();
 
-	TestLib::run_log(@_);
+	Postgres::Test::Utils::run_log(@_);
 	return;
 }
 
@@ -2428,8 +2428,8 @@ sub wait_for_catchup
 	  . join(', ', keys(%valid_modes))
 	  unless exists($valid_modes{$mode});
 
-	# Allow passing of a PostgresNode instance as shorthand
-	if (blessed($standby_name) && $standby_name->isa("PostgresNode"))
+	# Allow passing of a Postgres::Test::Cluster instance as shorthand
+	if (blessed($standby_name) && $standby_name->isa("Postgres::Test::Cluster"))
 	{
 		$standby_name = $standby_name->name;
 	}
diff --git a/src/test/perl/PostgresVersion.pm b/src/test/perl/Postgres/Test/PostgresVersion.pm
similarity index 84%
rename from src/test/perl/PostgresVersion.pm
rename to src/test/perl/Postgres/Test/PostgresVersion.pm
index 5ff701ce11..d447b8f05c 100644
--- a/src/test/perl/PostgresVersion.pm
+++ b/src/test/perl/Postgres/Test/PostgresVersion.pm
@@ -1,6 +1,6 @@
 ############################################################################
 #
-# PostgresVersion.pm
+# Postgres::Test::PostgresVersion.pm
 #
 # Module encapsulating Postgres Version numbers
 #
@@ -12,13 +12,13 @@
 
 =head1 NAME
 
-PostgresVersion - class representing PostgreSQL version numbers
+Postgres::Test::PostgresVersion - class representing PostgreSQL version numbers
 
 =head1 SYNOPSIS
 
-  use PostgresVersion;
+  use Postgres::Test::PostgresVersion;
 
-  my $version = PostgresVersion->new($version_arg);
+  my $version = Postgres::Test::PostgresVersion->new($version_arg);
 
   # compare two versions
   my $bool = $version1 <= $version2;
@@ -37,12 +37,12 @@ PostgresVersion - class representing PostgreSQL version numbers
 
 =head1 DESCRIPTION
 
-PostgresVersion encapsulates Postgres version numbers, providing parsing
+Postgres::Test::PostgresVersion encapsulates Postgres version numbers, providing parsing
 of common version formats and comparison operations.
 
 =cut
 
-package PostgresVersion;
+package Postgres::Test::PostgresVersion;
 
 use strict;
 use warnings;
@@ -60,9 +60,9 @@ use overload
 
 =over
 
-=item PostgresVersion->new($version)
+=item Postgres::Test::PostgresVersion->new($version)
 
-Create a new PostgresVersion instance.
+Create a new Postgres::Test::PostgresVersion instance.
 
 The argument can be a number like 12, or a string like '12.2' or the output
 of a Postgres command like `psql --version` or `pg_config --version`;
@@ -103,7 +103,7 @@ sub new
 
 # Routine which compares the _pg_version_array obtained for the two
 # arguments and returns -1, 0, or 1, allowing comparison between two
-# PostgresVersion objects or a PostgresVersion and a version string or number.
+# Postgres::Test::PostgresVersion objects or a Postgres::Test::PostgresVersion and a version string or number.
 #
 # If the second argument is not a blessed object we call the constructor
 # to make one.
diff --git a/src/test/perl/RecursiveCopy.pm b/src/test/perl/Postgres/Test/RecursiveCopy.pm
similarity index 91%
rename from src/test/perl/RecursiveCopy.pm
rename to src/test/perl/Postgres/Test/RecursiveCopy.pm
index 8a9cc722b5..a3f47833c1 100644
--- a/src/test/perl/RecursiveCopy.pm
+++ b/src/test/perl/Postgres/Test/RecursiveCopy.pm
@@ -5,18 +5,18 @@
 
 =head1 NAME
 
-RecursiveCopy - simple recursive copy implementation
+Postgres::Test::RecursiveCopy - simple recursive copy implementation
 
 =head1 SYNOPSIS
 
-use RecursiveCopy;
+use Postgres::Test::RecursiveCopy;
 
-RecursiveCopy::copypath($from, $to, filterfn => sub { return 1; });
-RecursiveCopy::copypath($from, $to);
+Postgres::Test::RecursiveCopy::copypath($from, $to, filterfn => sub { return 1; });
+Postgres::Test::RecursiveCopy::copypath($from, $to);
 
 =cut
 
-package RecursiveCopy;
+package Postgres::Test::RecursiveCopy;
 
 use strict;
 use warnings;
@@ -54,7 +54,7 @@ attempted.
 
 =head1 EXAMPLES
 
- RecursiveCopy::copypath('/some/path', '/empty/dir',
+ Postgres::Test::RecursiveCopy::copypath('/some/path', '/empty/dir',
     filterfn => sub {
 		# omit log/ and contents
 		my $src = shift;
diff --git a/src/test/perl/SimpleTee.pm b/src/test/perl/Postgres/Test/SimpleTee.pm
similarity index 95%
rename from src/test/perl/SimpleTee.pm
rename to src/test/perl/Postgres/Test/SimpleTee.pm
index 681a36a0f8..659c17c6df 100644
--- a/src/test/perl/SimpleTee.pm
+++ b/src/test/perl/Postgres/Test/SimpleTee.pm
@@ -10,7 +10,7 @@
 # method is currently implemented; that's all we need. We don't want to
 # depend on IO::Tee just for this.
 
-package SimpleTee;
+package Postgres::Test::SimpleTee;
 use strict;
 use warnings;
 
diff --git a/src/test/perl/TestLib.pm b/src/test/perl/Postgres/Test/Utils.pm
similarity index 97%
rename from src/test/perl/TestLib.pm
rename to src/test/perl/Postgres/Test/Utils.pm
index cbab1587cc..190fd70ee9 100644
--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/Postgres/Test/Utils.pm
@@ -5,11 +5,11 @@
 
 =head1 NAME
 
-TestLib - helper module for writing PostgreSQL's C<prove> tests.
+Postgres::Test::Utils - helper module for writing PostgreSQL's C<prove> tests.
 
 =head1 SYNOPSIS
 
-  use TestLib;
+  use Postgres::Test::Utils;
 
   # Test basic output of a command
   program_help_ok('initdb');
@@ -19,19 +19,19 @@ TestLib - helper module for writing PostgreSQL's C<prove> tests.
   # Test option combinations
   command_fails(['initdb', '--invalid-option'],
               'command fails with invalid option');
-  my $tempdir = TestLib::tempdir;
+  my $tempdir = Postgres::Test::Utils::tempdir;
   command_ok('initdb', '-D', $tempdir);
 
   # Miscellanea
-  print "on Windows" if $TestLib::windows_os;
-  my $path = TestLib::perl2host($backup_dir);
+  print "on Windows" if $Postgres::Test::Utils::windows_os;
+  my $path = Postgres::Test::Utils::perl2host($backup_dir);
   ok(check_mode_recursive($stream_dir, 0700, 0600),
     "check stream dir permissions");
-  TestLib::system_log('pg_ctl', 'kill', 'QUIT', $slow_pid);
+  Postgres::Test::Utils::system_log('pg_ctl', 'kill', 'QUIT', $slow_pid);
 
 =head1 DESCRIPTION
 
-C<TestLib> contains a set of routines dedicated to environment setup for
+C<Postgres::Test::Utils> contains a set of routines dedicated to environment setup for
 a PostgreSQL regression test run and includes some low-level routines
 aimed at controlling command execution, logging and test functions.
 
@@ -40,7 +40,7 @@ aimed at controlling command execution, logging and test functions.
 # This module should never depend on any other PostgreSQL regression test
 # modules.
 
-package TestLib;
+package Postgres::Test::Utils;
 
 use strict;
 use warnings;
@@ -56,7 +56,7 @@ use File::Spec;
 use File::stat qw(stat);
 use File::Temp ();
 use IPC::Run;
-use SimpleTee;
+use Postgres::Test::SimpleTee;
 
 # specify a recent enough version of Test::More to support the
 # done_testing() function
@@ -212,9 +212,9 @@ INIT
 	# in the log.
 	my $builder = Test::More->builder;
 	my $fh      = $builder->output;
-	tie *$fh, "SimpleTee", $orig_stdout, $testlog;
+	tie *$fh, "Postgres::Test::SimpleTee", $orig_stdout, $testlog;
 	$fh = $builder->failure_output;
-	tie *$fh, "SimpleTee", $orig_stderr, $testlog;
+	tie *$fh, "Postgres::Test::SimpleTee", $orig_stderr, $testlog;
 
 	# Enable auto-flushing for all the file handles. Stderr and stdout are
 	# redirected to the same file, and buffering causes the lines to appear
diff --git a/src/test/perl/README b/src/test/perl/README
index f04b2a2ea4..1e6e39dd96 100644
--- a/src/test/perl/README
+++ b/src/test/perl/README
@@ -40,15 +40,15 @@ Each test script should begin with:
 
     use strict;
     use warnings;
-    use PostgresNode;
-    use TestLib;
+    use Postgres::Test::Cluster;
+    use Postgres::Test::Utils;
     # Replace with the number of tests to execute:
     use Test::More tests => 1;
 
 then it will generally need to set up one or more nodes, run commands
 against them and evaluate the results. For example:
 
-    my $node = PostgresNode->new('primary');
+    my $node = Postgres::Test::Cluster->new('primary');
     $node->init;
     $node->start;
 
@@ -68,7 +68,7 @@ Read the Test::More documentation for more on how to write tests:
 For available PostgreSQL-specific test methods and some example tests read the
 perldoc for the test modules, e.g.:
 
-    perldoc src/test/perl/PostgresNode.pm
+    perldoc src/test/perl/Postgres::Test::Cluster.pm
 
 Required Perl
 -------------
diff --git a/src/test/recovery/t/001_stream_rep.pl b/src/test/recovery/t/001_stream_rep.pl
index ac581c1c07..20b883ac93 100644
--- a/src/test/recovery/t/001_stream_rep.pl
+++ b/src/test/recovery/t/001_stream_rep.pl
@@ -4,12 +4,12 @@
 # Minimal test testing streaming replication
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 49;
 
 # Initialize primary node
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 # A specific role is created to perform some tests related to replication,
 # and it needs proper authentication configuration.
 $node_primary->init(
@@ -22,7 +22,7 @@ my $backup_name = 'my_backup';
 $node_primary->backup($backup_name);
 
 # Create streaming standby linking to primary
-my $node_standby_1 = PostgresNode->new('standby_1');
+my $node_standby_1 = Postgres::Test::Cluster->new('standby_1');
 $node_standby_1->init_from_backup($node_primary, $backup_name,
 	has_streaming => 1);
 $node_standby_1->start;
@@ -37,7 +37,7 @@ $node_standby_1->backup('my_backup_2');
 $node_primary->start;
 
 # Create second standby node linking to standby 1
-my $node_standby_2 = PostgresNode->new('standby_2');
+my $node_standby_2 = Postgres::Test::Cluster->new('standby_2');
 $node_standby_2->init_from_backup($node_standby_1, $backup_name,
 	has_streaming => 1);
 $node_standby_2->start;
diff --git a/src/test/recovery/t/002_archiving.pl b/src/test/recovery/t/002_archiving.pl
index ce60159f03..757abc4329 100644
--- a/src/test/recovery/t/002_archiving.pl
+++ b/src/test/recovery/t/002_archiving.pl
@@ -4,13 +4,13 @@
 # test for archiving with hot standby
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 3;
 use File::Copy;
 
 # Initialize primary node, doing archives
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 $node_primary->init(
 	has_archiving    => 1,
 	allows_streaming => 1);
@@ -23,7 +23,7 @@ $node_primary->start;
 $node_primary->backup($backup_name);
 
 # Initialize standby node from backup, fetching WAL from archives
-my $node_standby = PostgresNode->new('standby');
+my $node_standby = Postgres::Test::Cluster->new('standby');
 $node_standby->init_from_backup($node_primary, $backup_name,
 	has_restoring => 1);
 $node_standby->append_conf('postgresql.conf',
@@ -62,7 +62,7 @@ is($result, qq(1000), 'check content from archives');
 # promoted.
 $node_standby->promote;
 
-my $node_standby2 = PostgresNode->new('standby2');
+my $node_standby2 = Postgres::Test::Cluster->new('standby2');
 $node_standby2->init_from_backup($node_primary, $backup_name,
 	has_restoring => 1);
 $node_standby2->start;
diff --git a/src/test/recovery/t/003_recovery_targets.pl b/src/test/recovery/t/003_recovery_targets.pl
index 7bd500ed95..d9273f42fc 100644
--- a/src/test/recovery/t/003_recovery_targets.pl
+++ b/src/test/recovery/t/003_recovery_targets.pl
@@ -4,8 +4,8 @@
 # Test for recovery targets: name, timestamp, XID
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 9;
 use Time::HiRes qw(usleep);
 
@@ -21,7 +21,7 @@ sub test_recovery_standby
 	my $num_rows        = shift;
 	my $until_lsn       = shift;
 
-	my $node_standby = PostgresNode->new($node_name);
+	my $node_standby = Postgres::Test::Cluster->new($node_name);
 	$node_standby->init_from_backup($node_primary, 'my_backup',
 		has_restoring => 1);
 
@@ -50,7 +50,7 @@ sub test_recovery_standby
 }
 
 # Initialize primary node
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 $node_primary->init(has_archiving => 1, allows_streaming => 1);
 
 # Bump the transaction ID epoch.  This is useful to stress the portability
@@ -136,7 +136,7 @@ test_recovery_standby('LSN', 'standby_5', $node_primary, \@recovery_params,
 test_recovery_standby('multiple overriding settings',
 	'standby_6', $node_primary, \@recovery_params, "3000", $lsn3);
 
-my $node_standby = PostgresNode->new('standby_7');
+my $node_standby = Postgres::Test::Cluster->new('standby_7');
 $node_standby->init_from_backup($node_primary, 'my_backup',
 	has_restoring => 1);
 $node_standby->append_conf(
@@ -156,7 +156,7 @@ ok($logfile =~ qr/multiple recovery targets specified/,
 
 # Check behavior when recovery ends before target is reached
 
-$node_standby = PostgresNode->new('standby_8');
+$node_standby = Postgres::Test::Cluster->new('standby_8');
 $node_standby->init_from_backup(
 	$node_primary, 'my_backup',
 	has_restoring => 1,
diff --git a/src/test/recovery/t/004_timeline_switch.pl b/src/test/recovery/t/004_timeline_switch.pl
index 07b1527043..16512f409c 100644
--- a/src/test/recovery/t/004_timeline_switch.pl
+++ b/src/test/recovery/t/004_timeline_switch.pl
@@ -5,8 +5,8 @@
 use strict;
 use warnings;
 use File::Path qw(rmtree);
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 3;
 
 $ENV{PGDATABASE} = 'postgres';
@@ -15,7 +15,7 @@ $ENV{PGDATABASE} = 'postgres';
 # on a new timeline.
 
 # Initialize primary node
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 $node_primary->init(allows_streaming => 1);
 $node_primary->start;
 
@@ -24,11 +24,11 @@ my $backup_name = 'my_backup';
 $node_primary->backup($backup_name);
 
 # Create two standbys linking to it
-my $node_standby_1 = PostgresNode->new('standby_1');
+my $node_standby_1 = Postgres::Test::Cluster->new('standby_1');
 $node_standby_1->init_from_backup($node_primary, $backup_name,
 	has_streaming => 1);
 $node_standby_1->start;
-my $node_standby_2 = PostgresNode->new('standby_2');
+my $node_standby_2 = Postgres::Test::Cluster->new('standby_2');
 $node_standby_2->init_from_backup($node_primary, $backup_name,
 	has_streaming => 1);
 $node_standby_2->start;
@@ -76,7 +76,7 @@ is($result, qq(2000), 'check content of standby 2');
 # when WAL archiving is enabled.
 
 # Initialize primary node
-my $node_primary_2 = PostgresNode->new('primary_2');
+my $node_primary_2 = Postgres::Test::Cluster->new('primary_2');
 $node_primary_2->init(allows_streaming => 1, has_archiving => 1);
 $node_primary_2->append_conf(
 	'postgresql.conf', qq(
@@ -88,7 +88,7 @@ $node_primary_2->start;
 $node_primary_2->backup($backup_name);
 
 # Create standby node
-my $node_standby_3 = PostgresNode->new('standby_3');
+my $node_standby_3 = Postgres::Test::Cluster->new('standby_3');
 $node_standby_3->init_from_backup($node_primary_2, $backup_name,
 	has_streaming => 1);
 
diff --git a/src/test/recovery/t/005_replay_delay.pl b/src/test/recovery/t/005_replay_delay.pl
index 0b56380e0a..281f4d849e 100644
--- a/src/test/recovery/t/005_replay_delay.pl
+++ b/src/test/recovery/t/005_replay_delay.pl
@@ -5,12 +5,12 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 3;
 
 # Initialize primary node
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 $node_primary->init(allows_streaming => 1);
 $node_primary->start;
 
@@ -23,7 +23,7 @@ my $backup_name = 'my_backup';
 $node_primary->backup($backup_name);
 
 # Create streaming standby from backup
-my $node_standby = PostgresNode->new('standby');
+my $node_standby = Postgres::Test::Cluster->new('standby');
 my $delay        = 3;
 $node_standby->init_from_backup($node_primary, $backup_name,
 	has_streaming => 1);
@@ -58,7 +58,7 @@ ok(time() - $primary_insert_time >= $delay,
 
 
 # Check that recovery can be paused or resumed expectedly.
-my $node_standby2 = PostgresNode->new('standby2');
+my $node_standby2 = Postgres::Test::Cluster->new('standby2');
 $node_standby2->init_from_backup($node_primary, $backup_name,
 	has_streaming => 1);
 $node_standby2->start;
diff --git a/src/test/recovery/t/006_logical_decoding.pl b/src/test/recovery/t/006_logical_decoding.pl
index cc116062c2..99a48ea531 100644
--- a/src/test/recovery/t/006_logical_decoding.pl
+++ b/src/test/recovery/t/006_logical_decoding.pl
@@ -8,13 +8,13 @@
 # are required.
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 14;
 use Config;
 
 # Initialize primary node
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 $node_primary->init(allows_streaming => 1);
 $node_primary->append_conf(
 	'postgresql.conf', qq(
diff --git a/src/test/recovery/t/007_sync_rep.pl b/src/test/recovery/t/007_sync_rep.pl
index 9d00e17f9f..60f46e783e 100644
--- a/src/test/recovery/t/007_sync_rep.pl
+++ b/src/test/recovery/t/007_sync_rep.pl
@@ -4,8 +4,8 @@
 # Minimal test testing synchronous replication sync_state transition
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 11;
 
 # Query checking sync_priority and sync_state of each standby
@@ -49,7 +49,7 @@ sub start_standby_and_wait
 }
 
 # Initialize primary node
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 $node_primary->init(allows_streaming => 1);
 $node_primary->start;
 my $backup_name = 'primary_backup';
@@ -61,19 +61,19 @@ $node_primary->backup($backup_name);
 # the ordering of each one of them in the WAL sender array of the primary.
 
 # Create standby1 linking to primary
-my $node_standby_1 = PostgresNode->new('standby1');
+my $node_standby_1 = Postgres::Test::Cluster->new('standby1');
 $node_standby_1->init_from_backup($node_primary, $backup_name,
 	has_streaming => 1);
 start_standby_and_wait($node_primary, $node_standby_1);
 
 # Create standby2 linking to primary
-my $node_standby_2 = PostgresNode->new('standby2');
+my $node_standby_2 = Postgres::Test::Cluster->new('standby2');
 $node_standby_2->init_from_backup($node_primary, $backup_name,
 	has_streaming => 1);
 start_standby_and_wait($node_primary, $node_standby_2);
 
 # Create standby3 linking to primary
-my $node_standby_3 = PostgresNode->new('standby3');
+my $node_standby_3 = Postgres::Test::Cluster->new('standby3');
 $node_standby_3->init_from_backup($node_primary, $backup_name,
 	has_streaming => 1);
 start_standby_and_wait($node_primary, $node_standby_3);
@@ -123,7 +123,7 @@ standby3|3|sync),
 start_standby_and_wait($node_primary, $node_standby_1);
 
 # Create standby4 linking to primary
-my $node_standby_4 = PostgresNode->new('standby4');
+my $node_standby_4 = Postgres::Test::Cluster->new('standby4');
 $node_standby_4->init_from_backup($node_primary, $backup_name,
 	has_streaming => 1);
 $node_standby_4->start;
diff --git a/src/test/recovery/t/008_fsm_truncation.pl b/src/test/recovery/t/008_fsm_truncation.pl
index b1082546a8..12a93188b4 100644
--- a/src/test/recovery/t/008_fsm_truncation.pl
+++ b/src/test/recovery/t/008_fsm_truncation.pl
@@ -8,11 +8,11 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 1;
 
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 $node_primary->init(allows_streaming => 1);
 
 $node_primary->append_conf(
@@ -28,7 +28,7 @@ autovacuum = off
 $node_primary->start;
 
 $node_primary->backup('primary_backup');
-my $node_standby = PostgresNode->new('standby');
+my $node_standby = Postgres::Test::Cluster->new('standby');
 $node_standby->init_from_backup($node_primary, 'primary_backup',
 	has_streaming => 1);
 $node_standby->start;
diff --git a/src/test/recovery/t/009_twophase.pl b/src/test/recovery/t/009_twophase.pl
index 78d4ef5b54..8840f02cf7 100644
--- a/src/test/recovery/t/009_twophase.pl
+++ b/src/test/recovery/t/009_twophase.pl
@@ -5,8 +5,8 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 24;
 
 my $psql_out = '';
@@ -29,7 +29,7 @@ sub configure_and_reload
 # Set up two nodes, which will alternately be primary and replication standby.
 
 # Setup london node
-my $node_london = PostgresNode->new("london");
+my $node_london = Postgres::Test::Cluster->new("london");
 $node_london->init(allows_streaming => 1);
 $node_london->append_conf(
 	'postgresql.conf', qq(
@@ -40,7 +40,7 @@ $node_london->start;
 $node_london->backup('london_backup');
 
 # Setup paris node
-my $node_paris = PostgresNode->new('paris');
+my $node_paris = Postgres::Test::Cluster->new('paris');
 $node_paris->init_from_backup($node_london, 'london_backup',
 	has_streaming => 1);
 $node_paris->start;
diff --git a/src/test/recovery/t/010_logical_decoding_timelines.pl b/src/test/recovery/t/010_logical_decoding_timelines.pl
index 2a9cf3b79c..a85682084a 100644
--- a/src/test/recovery/t/010_logical_decoding_timelines.pl
+++ b/src/test/recovery/t/010_logical_decoding_timelines.pl
@@ -24,8 +24,8 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 13;
 use File::Copy;
 use IPC::Run ();
@@ -34,7 +34,7 @@ use Scalar::Util qw(blessed);
 my ($stdout, $stderr, $ret);
 
 # Initialize primary node
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 $node_primary->init(allows_streaming => 1, has_archiving => 1);
 $node_primary->append_conf(
 	'postgresql.conf', q[
@@ -74,7 +74,7 @@ $node_primary->backup_fs_hot($backup_name);
 $node_primary->safe_psql('postgres',
 	q[SELECT pg_create_physical_replication_slot('phys_slot');]);
 
-my $node_replica = PostgresNode->new('replica');
+my $node_replica = Postgres::Test::Cluster->new('replica');
 $node_replica->init_from_backup(
 	$node_primary, $backup_name,
 	has_streaming => 1,
diff --git a/src/test/recovery/t/011_crash_recovery.pl b/src/test/recovery/t/011_crash_recovery.pl
index 72fc603e6d..3f1f4f8eb6 100644
--- a/src/test/recovery/t/011_crash_recovery.pl
+++ b/src/test/recovery/t/011_crash_recovery.pl
@@ -6,14 +6,14 @@
 #
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More;
 use Config;
 
 plan tests => 3;
 
-my $node = PostgresNode->new('primary');
+my $node = Postgres::Test::Cluster->new('primary');
 $node->init(allows_streaming => 1);
 $node->start;
 
diff --git a/src/test/recovery/t/012_subtransactions.pl b/src/test/recovery/t/012_subtransactions.pl
index a3655a076b..fb621dec9d 100644
--- a/src/test/recovery/t/012_subtransactions.pl
+++ b/src/test/recovery/t/012_subtransactions.pl
@@ -5,12 +5,12 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 12;
 
 # Setup primary node
-my $node_primary = PostgresNode->new("primary");
+my $node_primary = Postgres::Test::Cluster->new("primary");
 $node_primary->init(allows_streaming => 1);
 $node_primary->append_conf(
 	'postgresql.conf', qq(
@@ -22,7 +22,7 @@ $node_primary->backup('primary_backup');
 $node_primary->psql('postgres', "CREATE TABLE t_012_tbl (id int)");
 
 # Setup standby node
-my $node_standby = PostgresNode->new('standby');
+my $node_standby = Postgres::Test::Cluster->new('standby');
 $node_standby->init_from_backup($node_primary, 'primary_backup',
 	has_streaming => 1);
 $node_standby->start;
diff --git a/src/test/recovery/t/013_crash_restart.pl b/src/test/recovery/t/013_crash_restart.pl
index b5e3457753..6d0019637a 100644
--- a/src/test/recovery/t/013_crash_restart.pl
+++ b/src/test/recovery/t/013_crash_restart.pl
@@ -13,8 +13,8 @@
 #
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More;
 use Config;
 
@@ -27,11 +27,11 @@ plan tests => 18;
 # is really wrong.
 my $psql_timeout = IPC::Run::timer(60);
 
-my $node = PostgresNode->new('primary');
+my $node = Postgres::Test::Cluster->new('primary');
 $node->init(allows_streaming => 1);
 $node->start();
 
-# by default PostgresNode doesn't doesn't restart after a crash
+# by default Postgres::Test::Cluster doesn't doesn't restart after a crash
 $node->safe_psql(
 	'postgres',
 	q[ALTER SYSTEM SET restart_after_crash = 1;
@@ -105,7 +105,7 @@ $monitor_stdout = '';
 $monitor_stderr = '';
 
 # kill once with QUIT - we expect psql to exit, while emitting error message first
-my $ret = TestLib::system_log('pg_ctl', 'kill', 'QUIT', $pid);
+my $ret = Postgres::Test::Utils::system_log('pg_ctl', 'kill', 'QUIT', $pid);
 
 # Exactly process should have been alive to be killed
 is($ret, 0, "killed process with SIGQUIT");
@@ -184,7 +184,7 @@ $monitor_stderr = '';
 
 # kill with SIGKILL this time - we expect the backend to exit, without
 # being able to emit an error message
-$ret = TestLib::system_log('pg_ctl', 'kill', 'KILL', $pid);
+$ret = Postgres::Test::Utils::system_log('pg_ctl', 'kill', 'KILL', $pid);
 is($ret, 0, "killed process with KILL");
 
 # Check that psql sees the server as being terminated. No WARNING,
diff --git a/src/test/recovery/t/014_unlogged_reinit.pl b/src/test/recovery/t/014_unlogged_reinit.pl
index 4c22663b64..6205232d78 100644
--- a/src/test/recovery/t/014_unlogged_reinit.pl
+++ b/src/test/recovery/t/014_unlogged_reinit.pl
@@ -8,11 +8,11 @@
 
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 12;
 
-my $node = PostgresNode->new('main');
+my $node = Postgres::Test::Cluster->new('main');
 
 $node->init;
 $node->start;
@@ -31,9 +31,9 @@ ok(-f "$pgdata/$baseUnloggedPath",        'main fork in base exists');
 
 # Create an unlogged table in a tablespace.
 
-my $tablespaceDir = TestLib::tempdir;
+my $tablespaceDir = Postgres::Test::Utils::tempdir;
 
-my $realTSDir = TestLib::perl2host($tablespaceDir);
+my $realTSDir = Postgres::Test::Utils::perl2host($tablespaceDir);
 
 $node->safe_psql('postgres', "CREATE TABLESPACE ts1 LOCATION '$realTSDir'");
 $node->safe_psql('postgres',
diff --git a/src/test/recovery/t/015_promotion_pages.pl b/src/test/recovery/t/015_promotion_pages.pl
index 562c4cd3e4..7dc487ba1b 100644
--- a/src/test/recovery/t/015_promotion_pages.pl
+++ b/src/test/recovery/t/015_promotion_pages.pl
@@ -7,12 +7,12 @@
 # recovery point defined.
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 1;
 
 # Initialize primary node
-my $alpha = PostgresNode->new('alpha');
+my $alpha = Postgres::Test::Cluster->new('alpha');
 $alpha->init(allows_streaming => 1);
 # Setting wal_log_hints to off is important to get invalid page
 # references.
@@ -25,7 +25,7 @@ $alpha->start;
 
 # setup/start a standby
 $alpha->backup('bkp');
-my $bravo = PostgresNode->new('bravo');
+my $bravo = Postgres::Test::Cluster->new('bravo');
 $bravo->init_from_backup($alpha, 'bkp', has_streaming => 1);
 $bravo->append_conf('postgresql.conf', <<EOF);
 checkpoint_timeout=1h
diff --git a/src/test/recovery/t/016_min_consistency.pl b/src/test/recovery/t/016_min_consistency.pl
index 23f4c42745..87f622dd4b 100644
--- a/src/test/recovery/t/016_min_consistency.pl
+++ b/src/test/recovery/t/016_min_consistency.pl
@@ -9,8 +9,8 @@
 
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 1;
 
 # Find the largest LSN in the set of pages part of the given relation
@@ -43,7 +43,7 @@ sub find_largest_lsn
 }
 
 # Initialize primary node
-my $primary = PostgresNode->new('primary');
+my $primary = Postgres::Test::Cluster->new('primary');
 $primary->init(allows_streaming => 1);
 
 # Set shared_buffers to a very low value to enforce discard and flush
@@ -61,7 +61,7 @@ $primary->start;
 
 # setup/start a standby
 $primary->backup('bkp');
-my $standby = PostgresNode->new('standby');
+my $standby = Postgres::Test::Cluster->new('standby');
 $standby->init_from_backup($primary, 'bkp', has_streaming => 1);
 $standby->start;
 
diff --git a/src/test/recovery/t/017_shm.pl b/src/test/recovery/t/017_shm.pl
index 5548a1556d..336248e2d0 100644
--- a/src/test/recovery/t/017_shm.pl
+++ b/src/test/recovery/t/017_shm.pl
@@ -9,9 +9,9 @@ use warnings;
 use Config;
 use File::stat qw(stat);
 use IPC::Run 'run';
-use PostgresNode;
+use Postgres::Test::Cluster;
 use Test::More;
-use TestLib;
+use Postgres::Test::Utils;
 use Time::HiRes qw(usleep);
 
 # If we don't have shmem support, skip the whole thing
@@ -30,7 +30,7 @@ else
 	plan tests => 4;
 }
 
-my $tempdir = TestLib::tempdir;
+my $tempdir = Postgres::Test::Utils::tempdir;
 
 # Log "ipcs" diffs on a best-effort basis, swallowing any error.
 my $ipcs_before = "$tempdir/ipcs_before";
@@ -43,7 +43,7 @@ sub log_ipcs
 }
 
 # Node setup.
-my $gnat = PostgresNode->new('gnat');
+my $gnat = Postgres::Test::Cluster->new('gnat');
 $gnat->init;
 
 # Create a shmem segment that will conflict with gnat's first choice
@@ -116,7 +116,7 @@ log_ipcs();
 $gnat->start;
 log_ipcs();
 
-my $regress_shlib = TestLib::perl2host($ENV{REGRESS_SHLIB});
+my $regress_shlib = Postgres::Test::Utils::perl2host($ENV{REGRESS_SHLIB});
 $gnat->safe_psql('postgres', <<EOSQL);
 CREATE FUNCTION wait_pid(int)
    RETURNS void
@@ -175,7 +175,7 @@ like($single_stderr, $pre_existing_msg,
 log_ipcs();
 
 # cleanup slow backend
-TestLib::system_log('pg_ctl', 'kill', 'QUIT', $slow_pid);
+Postgres::Test::Utils::system_log('pg_ctl', 'kill', 'QUIT', $slow_pid);
 $slow_client->finish;    # client has detected backend termination
 log_ipcs();
 
diff --git a/src/test/recovery/t/018_wal_optimize.pl b/src/test/recovery/t/018_wal_optimize.pl
index 47cbc95955..1fe1565d44 100644
--- a/src/test/recovery/t/018_wal_optimize.pl
+++ b/src/test/recovery/t/018_wal_optimize.pl
@@ -12,8 +12,8 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 38;
 
 sub check_orphan_relfilenodes
@@ -43,7 +43,7 @@ sub run_wal_optimize
 {
 	my $wal_level = shift;
 
-	my $node = PostgresNode->new("node_$wal_level");
+	my $node = Postgres::Test::Cluster->new("node_$wal_level");
 	$node->init;
 	$node->append_conf(
 		'postgresql.conf', qq(
@@ -58,7 +58,7 @@ wal_skip_threshold = 0
 	# Setup
 	my $tablespace_dir = $node->basedir . '/tablespace_other';
 	mkdir($tablespace_dir);
-	$tablespace_dir = TestLib::perl2host($tablespace_dir);
+	$tablespace_dir = Postgres::Test::Utils::perl2host($tablespace_dir);
 	my $result;
 
 	# Test redo of CREATE TABLESPACE.
@@ -146,11 +146,11 @@ wal_skip_threshold = 0
 	# Data file for COPY query in subsequent tests
 	my $basedir   = $node->basedir;
 	my $copy_file = "$basedir/copy_data.txt";
-	TestLib::append_to_file(
+	Postgres::Test::Utils::append_to_file(
 		$copy_file, qq(20000,30000
 20001,30001
 20002,30002));
-	$copy_file = TestLib::perl2host($copy_file);
+	$copy_file = Postgres::Test::Utils::perl2host($copy_file);
 
 	# Test truncation with inserted tuples using both INSERT and COPY.  Tuples
 	# inserted after the truncation should be seen.
diff --git a/src/test/recovery/t/019_replslot_limit.pl b/src/test/recovery/t/019_replslot_limit.pl
index e065c5c008..b9974c832c 100644
--- a/src/test/recovery/t/019_replslot_limit.pl
+++ b/src/test/recovery/t/019_replslot_limit.pl
@@ -7,17 +7,17 @@
 use strict;
 use warnings;
 
-use TestLib;
-use PostgresNode;
+use Postgres::Test::Utils;
+use Postgres::Test::Cluster;
 
 use File::Path qw(rmtree);
-use Test::More tests => $TestLib::windows_os ? 16 : 20;
+use Test::More tests => $Postgres::Test::Utils::windows_os ? 16 : 20;
 use Time::HiRes qw(usleep);
 
 $ENV{PGDATABASE} = 'postgres';
 
 # Initialize primary node, setting wal-segsize to 1MB
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 $node_primary->init(allows_streaming => 1, extra => ['--wal-segsize=1']);
 $node_primary->append_conf(
 	'postgresql.conf', qq(
@@ -41,7 +41,7 @@ my $backup_name = 'my_backup';
 $node_primary->backup($backup_name);
 
 # Create a standby linking to it using the replication slot
-my $node_standby = PostgresNode->new('standby_1');
+my $node_standby = Postgres::Test::Cluster->new('standby_1');
 $node_standby->init_from_backup($node_primary, $backup_name,
 	has_streaming => 1);
 $node_standby->append_conf('postgresql.conf', "primary_slot_name = 'rep1'");
@@ -260,7 +260,7 @@ ok($failed, 'check that replication has been broken');
 $node_primary->stop;
 $node_standby->stop;
 
-my $node_primary2 = PostgresNode->new('primary2');
+my $node_primary2 = Postgres::Test::Cluster->new('primary2');
 $node_primary2->init(allows_streaming => 1);
 $node_primary2->append_conf(
 	'postgresql.conf', qq(
@@ -281,7 +281,7 @@ max_slot_wal_keep_size = 0
 ));
 $node_primary2->start;
 
-$node_standby = PostgresNode->new('standby_2');
+$node_standby = Postgres::Test::Cluster->new('standby_2');
 $node_standby->init_from_backup($node_primary2, $backup_name,
 	has_streaming => 1);
 $node_standby->append_conf('postgresql.conf', "primary_slot_name = 'rep1'");
@@ -305,7 +305,7 @@ $node_standby->stop;
 # The next test depends on Perl's `kill`, which apparently is not
 # portable to Windows.  (It would be nice to use Test::More's `subtest`,
 # but that's not in the ancient version we require.)
-if ($TestLib::windows_os)
+if ($Postgres::Test::Utils::windows_os)
 {
 	done_testing();
 	exit;
@@ -313,7 +313,7 @@ if ($TestLib::windows_os)
 
 # Get a slot terminated while the walsender is active
 # We do this by sending SIGSTOP to the walsender.  Skip this on Windows.
-my $node_primary3 = PostgresNode->new('primary3');
+my $node_primary3 = Postgres::Test::Cluster->new('primary3');
 $node_primary3->init(allows_streaming => 1, extra => ['--wal-segsize=1']);
 $node_primary3->append_conf(
 	'postgresql.conf', qq(
@@ -329,7 +329,7 @@ $node_primary3->safe_psql('postgres',
 $backup_name = 'my_backup';
 $node_primary3->backup($backup_name);
 # Create standby
-my $node_standby3 = PostgresNode->new('standby_3');
+my $node_standby3 = Postgres::Test::Cluster->new('standby_3');
 $node_standby3->init_from_backup($node_primary3, $backup_name,
 	has_streaming => 1);
 $node_standby3->append_conf('postgresql.conf', "primary_slot_name = 'rep3'");
@@ -419,7 +419,7 @@ sub find_in_log
 	my ($node, $pat, $off) = @_;
 
 	$off = 0 unless defined $off;
-	my $log = TestLib::slurp_file($node->logfile);
+	my $log = Postgres::Test::Utils::slurp_file($node->logfile);
 	return 0 if (length($log) <= $off);
 
 	$log = substr($log, $off);
diff --git a/src/test/recovery/t/020_archive_status.pl b/src/test/recovery/t/020_archive_status.pl
index cea65735a3..20726c860a 100644
--- a/src/test/recovery/t/020_archive_status.pl
+++ b/src/test/recovery/t/020_archive_status.pl
@@ -6,12 +6,12 @@
 #
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 16;
 use Config;
 
-my $primary = PostgresNode->new('primary');
+my $primary = Postgres::Test::Cluster->new('primary');
 $primary->init(
 	has_archiving    => 1,
 	allows_streaming => 1);
@@ -27,7 +27,7 @@ my $primary_data = $primary->data_dir;
 # a portable solution, use an archive command based on a command known to
 # work but will fail: copy with an incorrect original path.
 my $incorrect_command =
-  $TestLib::windows_os
+  $Postgres::Test::Utils::windows_os
   ? qq{copy "%p_does_not_exist" "%f_does_not_exist"}
   : qq{cp "%p_does_not_exist" "%f_does_not_exist"};
 $primary->safe_psql(
@@ -138,7 +138,7 @@ $primary->poll_query_until('postgres',
   or die "Timed out while waiting for archiving to finish";
 
 # Test standby with archive_mode = on.
-my $standby1 = PostgresNode->new('standby');
+my $standby1 = Postgres::Test::Cluster->new('standby');
 $standby1->init_from_backup($primary, 'backup', has_restoring => 1);
 $standby1->append_conf('postgresql.conf', "archive_mode = on");
 my $standby1_data = $standby1->data_dir;
@@ -174,7 +174,7 @@ ok( -f "$standby1_data/$segment_path_2_done",
 # command to fail to persist the .ready files.  Note that this node
 # has inherited the archive command of the previous cold backup that
 # will cause archiving failures.
-my $standby2 = PostgresNode->new('standby2');
+my $standby2 = Postgres::Test::Cluster->new('standby2');
 $standby2->init_from_backup($primary, 'backup', has_restoring => 1);
 $standby2->append_conf('postgresql.conf', 'archive_mode = always');
 my $standby2_data = $standby2->data_dir;
diff --git a/src/test/recovery/t/021_row_visibility.pl b/src/test/recovery/t/021_row_visibility.pl
index 7f40977976..a7acfc34e4 100644
--- a/src/test/recovery/t/021_row_visibility.pl
+++ b/src/test/recovery/t/021_row_visibility.pl
@@ -6,13 +6,13 @@
 use strict;
 use warnings;
 
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 10;
 use Config;
 
 # Initialize primary node
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 $node_primary->init(allows_streaming => 1);
 $node_primary->append_conf('postgresql.conf', 'max_prepared_transactions=10');
 $node_primary->start;
@@ -26,7 +26,7 @@ my $backup_name = 'my_backup';
 $node_primary->backup($backup_name);
 
 # Create streaming standby from backup
-my $node_standby = PostgresNode->new('standby');
+my $node_standby = Postgres::Test::Cluster->new('standby');
 $node_standby->init_from_backup($node_primary, $backup_name,
 	has_streaming => 1);
 $node_standby->append_conf('postgresql.conf', 'max_prepared_transactions=10');
@@ -187,7 +187,7 @@ sub send_query_and_wait
 	$$psql{run}->pump_nb();
 	while (1)
 	{
-		# See PostgresNode.pm's psql()
+		# See Postgres::Test::Cluster.pm's psql()
 		$$psql{stdout} =~ s/\r\n/\n/g if $Config{osname} eq 'msys';
 
 		last if $$psql{stdout} =~ /$untl/;
diff --git a/src/test/recovery/t/022_crash_temp_files.pl b/src/test/recovery/t/022_crash_temp_files.pl
index cc8c8664e2..d62d46d16c 100644
--- a/src/test/recovery/t/022_crash_temp_files.pl
+++ b/src/test/recovery/t/022_crash_temp_files.pl
@@ -4,8 +4,8 @@
 # Test remove of temporary files after a crash.
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More;
 use Config;
 
@@ -26,11 +26,11 @@ else
 # is really wrong.
 my $psql_timeout = IPC::Run::timer(60);
 
-my $node = PostgresNode->new('node_crash');
+my $node = Postgres::Test::Cluster->new('node_crash');
 $node->init();
 $node->start();
 
-# By default, PostgresNode doesn't restart after crash
+# By default, Postgres::Test::Cluster doesn't restart after crash
 # Reduce work_mem to generate temporary file with a few number of rows
 $node->safe_psql(
 	'postgres',
@@ -131,7 +131,7 @@ $killme_stdout2 = '';
 $killme_stderr2 = '';
 
 # Kill with SIGKILL
-my $ret = TestLib::system_log('pg_ctl', 'kill', 'KILL', $pid);
+my $ret = Postgres::Test::Utils::system_log('pg_ctl', 'kill', 'KILL', $pid);
 is($ret, 0, 'killed process with KILL');
 
 # Close psql session
@@ -220,7 +220,7 @@ $killme_stdout2 = '';
 $killme_stderr2 = '';
 
 # Kill with SIGKILL
-$ret = TestLib::system_log('pg_ctl', 'kill', 'KILL', $pid);
+$ret = Postgres::Test::Utils::system_log('pg_ctl', 'kill', 'KILL', $pid);
 is($ret, 0, 'killed process with KILL');
 
 # Close psql session
diff --git a/src/test/recovery/t/023_pitr_prepared_xact.pl b/src/test/recovery/t/023_pitr_prepared_xact.pl
index a1ff97d070..5341ecaa39 100644
--- a/src/test/recovery/t/023_pitr_prepared_xact.pl
+++ b/src/test/recovery/t/023_pitr_prepared_xact.pl
@@ -4,13 +4,13 @@
 # Test for point-in-time-recovery (PITR) with prepared transactions
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 1;
 use File::Compare;
 
 # Initialize and start primary node with WAL archiving
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 $node_primary->init(has_archiving => 1, allows_streaming => 1);
 $node_primary->append_conf(
 	'postgresql.conf', qq{
@@ -24,7 +24,7 @@ $node_primary->backup($backup_name);
 # Initialize node for PITR targeting a very specific restore point, just
 # after a PREPARE TRANSACTION is issued so as we finish with a promoted
 # node where this 2PC transaction needs an explicit COMMIT PREPARED.
-my $node_pitr = PostgresNode->new('node_pitr');
+my $node_pitr = Postgres::Test::Cluster->new('node_pitr');
 $node_pitr->init_from_backup(
 	$node_primary, $backup_name,
 	standby       => 0,
diff --git a/src/test/recovery/t/024_archive_recovery.pl b/src/test/recovery/t/024_archive_recovery.pl
index 32be5c4251..1175a6f529 100644
--- a/src/test/recovery/t/024_archive_recovery.pl
+++ b/src/test/recovery/t/024_archive_recovery.pl
@@ -4,14 +4,14 @@
 # Test for archive recovery of WAL generated with wal_level=minimal
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 2;
 use Time::HiRes qw(usleep);
 
 # Initialize and start node with wal_level = replica and WAL archiving
 # enabled.
-my $node = PostgresNode->new('orig');
+my $node = Postgres::Test::Cluster->new('orig');
 $node->init(has_archiving => 1, allows_streaming => 1);
 my $replica_config = q[
 wal_level = replica
@@ -66,7 +66,7 @@ sub test_recovery_wal_level_minimal
 {
 	my ($node_name, $node_text, $standby_setting) = @_;
 
-	my $recovery_node = PostgresNode->new($node_name);
+	my $recovery_node = Postgres::Test::Cluster->new($node_name);
 	$recovery_node->init_from_backup(
 		$node, $backup_name,
 		has_restoring => 1,
diff --git a/src/test/recovery/t/025_stuck_on_old_timeline.pl b/src/test/recovery/t/025_stuck_on_old_timeline.pl
index 00ee9fcaed..6a8ef5b0df 100644
--- a/src/test/recovery/t/025_stuck_on_old_timeline.pl
+++ b/src/test/recovery/t/025_stuck_on_old_timeline.pl
@@ -8,15 +8,15 @@
 # standby can follow the new primary (promoted standby).
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 
 use File::Basename;
 use FindBin;
 use Test::More tests => 1;
 
 # Initialize primary node
-my $node_primary = PostgresNode->new('primary');
+my $node_primary = Postgres::Test::Cluster->new('primary');
 
 # Set up an archive command that will copy the history file but not the WAL
 # files. No real archive command should behave this way; the point is to
@@ -28,10 +28,10 @@ $node_primary->init(allows_streaming => 1, has_archiving => 1);
 # Note: consistent use of forward slashes here avoids any escaping problems
 # that arise from use of backslashes. That means we need to double-quote all
 # the paths in the archive_command
-my $perlbin = TestLib::perl2host($^X);
-$perlbin =~ s!\\!/!g if $TestLib::windows_os;
+my $perlbin = Postgres::Test::Utils::perl2host($^X);
+$perlbin =~ s!\\!/!g if $Postgres::Test::Utils::windows_os;
 my $archivedir_primary = $node_primary->archive_dir;
-$archivedir_primary =~ s!\\!/!g if $TestLib::windows_os;
+$archivedir_primary =~ s!\\!/!g if $Postgres::Test::Utils::windows_os;
 $node_primary->append_conf(
 	'postgresql.conf', qq(
 archive_command = '"$perlbin" "$FindBin::RealBin/cp_history_files" "%p" "$archivedir_primary/%f"'
@@ -47,7 +47,7 @@ my $backup_name = 'my_backup';
 $node_primary->backup($backup_name);
 
 # Create streaming standby linking to primary
-my $node_standby = PostgresNode->new('standby');
+my $node_standby = Postgres::Test::Cluster->new('standby');
 $node_standby->init_from_backup(
 	$node_primary, $backup_name,
 	allows_streaming => 1,
@@ -60,7 +60,7 @@ $node_standby->backup($backup_name, backup_options => ['-Xnone']);
 
 # Create cascading standby but don't start it yet.
 # Must set up both streaming and archiving.
-my $node_cascade = PostgresNode->new('cascade');
+my $node_cascade = Postgres::Test::Cluster->new('cascade');
 $node_cascade->init_from_backup($node_standby, $backup_name,
 	has_streaming => 1);
 $node_cascade->enable_restoring($node_primary);
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index 05296f7ee1..aa087f9e55 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -820,7 +820,7 @@ initialize_environment(void)
 		 * won't mess things up.)  Also, set PGPORT to the temp port, and set
 		 * PGHOST depending on whether we are using TCP or Unix sockets.
 		 *
-		 * This list should be kept in sync with TestLib.pm.
+		 * This list should be kept in sync with Postgres/Test/Utils.pm.
 		 */
 		unsetenv("PGCHANNELBINDING");
 		/* PGCLIENTENCODING, see above */
diff --git a/src/test/ssl/t/001_ssltests.pl b/src/test/ssl/t/001_ssltests.pl
index 3bc711f4a7..3da38a8c47 100644
--- a/src/test/ssl/t/001_ssltests.pl
+++ b/src/test/ssl/t/001_ssltests.pl
@@ -3,8 +3,8 @@
 
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More;
 
 use File::Copy;
@@ -64,7 +64,7 @@ push @keys, 'client_wrongperms';
 #### Set up the server.
 
 note "setting up data directory";
-my $node = PostgresNode->new('primary');
+my $node = Postgres::Test::Cluster->new('primary');
 $node->init;
 
 # PGHOST is enforced here to set up the node, subsequent connections
diff --git a/src/test/ssl/t/002_scram.pl b/src/test/ssl/t/002_scram.pl
index 1dfa2b91f3..bf866535d2 100644
--- a/src/test/ssl/t/002_scram.pl
+++ b/src/test/ssl/t/002_scram.pl
@@ -5,8 +5,8 @@
 
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More;
 
 use File::Copy;
@@ -38,7 +38,7 @@ my $common_connstr;
 # Set up the server.
 
 note "setting up data directory";
-my $node = PostgresNode->new('primary');
+my $node = Postgres::Test::Cluster->new('primary');
 $node->init;
 
 # PGHOST is enforced here to set up the node, subsequent connections
diff --git a/src/test/ssl/t/SSLServer.pm b/src/test/ssl/t/SSLServer.pm
index 804d008245..370c34908d 100644
--- a/src/test/ssl/t/SSLServer.pm
+++ b/src/test/ssl/t/SSLServer.pm
@@ -30,8 +30,8 @@ package SSLServer;
 
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use File::Basename;
 use File::Copy;
 use Test::More;
diff --git a/src/test/subscription/t/001_rep_changes.pl b/src/test/subscription/t/001_rep_changes.pl
index d89875a98b..62669a06e7 100644
--- a/src/test/subscription/t/001_rep_changes.pl
+++ b/src/test/subscription/t/001_rep_changes.pl
@@ -4,17 +4,17 @@
 # Basic logical replication test
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 32;
 
 # Initialize publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
 # Create subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/002_types.pl b/src/test/subscription/t/002_types.pl
index 420876099a..461423bd59 100644
--- a/src/test/subscription/t/002_types.pl
+++ b/src/test/subscription/t/002_types.pl
@@ -5,17 +5,17 @@
 # by logical replication
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 4;
 
 # Initialize publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
 # Create subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/003_constraints.pl b/src/test/subscription/t/003_constraints.pl
index 3767d24f92..988303ed12 100644
--- a/src/test/subscription/t/003_constraints.pl
+++ b/src/test/subscription/t/003_constraints.pl
@@ -4,17 +4,17 @@
 # This test checks that constraints work on subscriber
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 6;
 
 # Initialize publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
 # Create subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/004_sync.pl b/src/test/subscription/t/004_sync.pl
index f07c306e5b..50c18c9122 100644
--- a/src/test/subscription/t/004_sync.pl
+++ b/src/test/subscription/t/004_sync.pl
@@ -4,17 +4,17 @@
 # Tests for logical replication table syncing
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 8;
 
 # Initialize publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
 # Create subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->append_conf('postgresql.conf',
 	"wal_retrieve_retry_interval = 1ms");
diff --git a/src/test/subscription/t/005_encoding.pl b/src/test/subscription/t/005_encoding.pl
index 9df474beb5..e4d462355b 100644
--- a/src/test/subscription/t/005_encoding.pl
+++ b/src/test/subscription/t/005_encoding.pl
@@ -4,17 +4,17 @@
 # Test replication between databases with different encodings
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 1;
 
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(
 	allows_streaming => 'logical',
 	extra            => [ '--locale=C', '--encoding=UTF8' ]);
 $node_publisher->start;
 
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(
 	allows_streaming => 'logical',
 	extra            => [ '--locale=C', '--encoding=LATIN1' ]);
diff --git a/src/test/subscription/t/006_rewrite.pl b/src/test/subscription/t/006_rewrite.pl
index ec4d641230..5b40d1c1b0 100644
--- a/src/test/subscription/t/006_rewrite.pl
+++ b/src/test/subscription/t/006_rewrite.pl
@@ -4,15 +4,15 @@
 # Test logical replication behavior with heap rewrites
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 2;
 
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/007_ddl.pl b/src/test/subscription/t/007_ddl.pl
index 1a3a1dcf14..ea000ee104 100644
--- a/src/test/subscription/t/007_ddl.pl
+++ b/src/test/subscription/t/007_ddl.pl
@@ -4,15 +4,15 @@
 # Test some logical replication DDL behavior
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 1;
 
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/008_diff_schema.pl b/src/test/subscription/t/008_diff_schema.pl
index 3af3d25604..0381575358 100644
--- a/src/test/subscription/t/008_diff_schema.pl
+++ b/src/test/subscription/t/008_diff_schema.pl
@@ -4,17 +4,17 @@
 # Test behavior with different schema on subscriber
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 5;
 
 # Create publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
 # Create subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/009_matviews.pl b/src/test/subscription/t/009_matviews.pl
index 2e7d0d4413..348fc2537b 100644
--- a/src/test/subscription/t/009_matviews.pl
+++ b/src/test/subscription/t/009_matviews.pl
@@ -4,15 +4,15 @@
 # Test materialized views behavior
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 1;
 
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/010_truncate.pl b/src/test/subscription/t/010_truncate.pl
index 0e6ecf9c2f..53906357b3 100644
--- a/src/test/subscription/t/010_truncate.pl
+++ b/src/test/subscription/t/010_truncate.pl
@@ -4,17 +4,17 @@
 # Test TRUNCATE
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 14;
 
 # setup
 
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->append_conf('postgresql.conf',
 	qq(max_logical_replication_workers = 6));
diff --git a/src/test/subscription/t/011_generated.pl b/src/test/subscription/t/011_generated.pl
index a8e7fbd9da..d6ba8e1756 100644
--- a/src/test/subscription/t/011_generated.pl
+++ b/src/test/subscription/t/011_generated.pl
@@ -4,17 +4,17 @@
 # Test generated columns
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 2;
 
 # setup
 
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/012_collation.pl b/src/test/subscription/t/012_collation.pl
index 0987391188..d88cfdc01e 100644
--- a/src/test/subscription/t/012_collation.pl
+++ b/src/test/subscription/t/012_collation.pl
@@ -5,8 +5,8 @@
 # (only works with ICU)
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More;
 
 if ($ENV{with_icu} eq 'yes')
@@ -18,13 +18,13 @@ else
 	plan skip_all => 'ICU not supported by this build';
 }
 
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(
 	allows_streaming => 'logical',
 	extra            => [ '--locale=C', '--encoding=UTF8' ]);
 $node_publisher->start;
 
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(
 	allows_streaming => 'logical',
 	extra            => [ '--locale=C', '--encoding=UTF8' ]);
diff --git a/src/test/subscription/t/013_partition.pl b/src/test/subscription/t/013_partition.pl
index c89d495221..41b74a8df5 100644
--- a/src/test/subscription/t/013_partition.pl
+++ b/src/test/subscription/t/013_partition.pl
@@ -4,21 +4,21 @@
 # Test logical replication with partitioned tables
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 62;
 
 # setup
 
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
-my $node_subscriber1 = PostgresNode->new('subscriber1');
+my $node_subscriber1 = Postgres::Test::Cluster->new('subscriber1');
 $node_subscriber1->init(allows_streaming => 'logical');
 $node_subscriber1->start;
 
-my $node_subscriber2 = PostgresNode->new('subscriber2');
+my $node_subscriber2 = Postgres::Test::Cluster->new('subscriber2');
 $node_subscriber2->init(allows_streaming => 'logical');
 $node_subscriber2->start;
 
diff --git a/src/test/subscription/t/014_binary.pl b/src/test/subscription/t/014_binary.pl
index 4e8aeb2e41..666229051e 100644
--- a/src/test/subscription/t/014_binary.pl
+++ b/src/test/subscription/t/014_binary.pl
@@ -5,17 +5,17 @@
 
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 5;
 
 # Create and initialize a publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
 # Create and initialize subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/015_stream.pl b/src/test/subscription/t/015_stream.pl
index da6761f81e..ea92ca4d50 100644
--- a/src/test/subscription/t/015_stream.pl
+++ b/src/test/subscription/t/015_stream.pl
@@ -4,19 +4,19 @@
 # Test streaming of simple large transaction
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 4;
 
 # Create publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->append_conf('postgresql.conf',
 	'logical_decoding_work_mem = 64kB');
 $node_publisher->start;
 
 # Create subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/016_stream_subxact.pl b/src/test/subscription/t/016_stream_subxact.pl
index 4aae98a66e..eb61b6097d 100644
--- a/src/test/subscription/t/016_stream_subxact.pl
+++ b/src/test/subscription/t/016_stream_subxact.pl
@@ -4,19 +4,19 @@
 # Test streaming of large transaction containing large subtransactions
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 2;
 
 # Create publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->append_conf('postgresql.conf',
 	'logical_decoding_work_mem = 64kB');
 $node_publisher->start;
 
 # Create subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/017_stream_ddl.pl b/src/test/subscription/t/017_stream_ddl.pl
index 50bd6e3117..3a168f7642 100644
--- a/src/test/subscription/t/017_stream_ddl.pl
+++ b/src/test/subscription/t/017_stream_ddl.pl
@@ -4,19 +4,19 @@
 # Test streaming of large transaction with DDL and subtransactions
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 3;
 
 # Create publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->append_conf('postgresql.conf',
 	'logical_decoding_work_mem = 64kB');
 $node_publisher->start;
 
 # Create subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/018_stream_subxact_abort.pl b/src/test/subscription/t/018_stream_subxact_abort.pl
index 63fe248a04..db372fe417 100644
--- a/src/test/subscription/t/018_stream_subxact_abort.pl
+++ b/src/test/subscription/t/018_stream_subxact_abort.pl
@@ -4,19 +4,19 @@
 # Test streaming of large transaction containing multiple subtransactions and rollbacks
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 4;
 
 # Create publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->append_conf('postgresql.conf',
 	'logical_decoding_work_mem = 64kB');
 $node_publisher->start;
 
 # Create subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/019_stream_subxact_ddl_abort.pl b/src/test/subscription/t/019_stream_subxact_ddl_abort.pl
index 176a702486..8e994483ba 100644
--- a/src/test/subscription/t/019_stream_subxact_ddl_abort.pl
+++ b/src/test/subscription/t/019_stream_subxact_ddl_abort.pl
@@ -5,19 +5,19 @@
 # rollbacks
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 2;
 
 # Create publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->append_conf('postgresql.conf',
 	'logical_decoding_work_mem = 64kB');
 $node_publisher->start;
 
 # Create subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/020_messages.pl b/src/test/subscription/t/020_messages.pl
index ecf9b192a3..4d55dff708 100644
--- a/src/test/subscription/t/020_messages.pl
+++ b/src/test/subscription/t/020_messages.pl
@@ -4,18 +4,18 @@
 # Tests that logical decoding messages
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 5;
 
 # Create publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->append_conf('postgresql.conf', 'autovacuum = off');
 $node_publisher->start;
 
 # Create subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/021_twophase.pl b/src/test/subscription/t/021_twophase.pl
index 19f096295f..fd9c215e08 100644
--- a/src/test/subscription/t/021_twophase.pl
+++ b/src/test/subscription/t/021_twophase.pl
@@ -4,8 +4,8 @@
 # logical replication of 2PC test
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 24;
 
 ###############################
@@ -13,14 +13,14 @@ use Test::More tests => 24;
 ###############################
 
 # Initialize publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->append_conf('postgresql.conf',
 	qq(max_prepared_transactions = 10));
 $node_publisher->start;
 
 # Create subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->append_conf('postgresql.conf',
 	qq(max_prepared_transactions = 10));
diff --git a/src/test/subscription/t/022_twophase_cascade.pl b/src/test/subscription/t/022_twophase_cascade.pl
index a38c5e78fe..f0a6ee1d82 100644
--- a/src/test/subscription/t/022_twophase_cascade.pl
+++ b/src/test/subscription/t/022_twophase_cascade.pl
@@ -7,8 +7,8 @@
 #
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 41;
 
 ###############################
@@ -18,7 +18,7 @@ use Test::More tests => 41;
 
 # Initialize nodes
 # node_A
-my $node_A = PostgresNode->new('node_A');
+my $node_A = Postgres::Test::Cluster->new('node_A');
 $node_A->init(allows_streaming => 'logical');
 $node_A->append_conf('postgresql.conf', qq(
 max_prepared_transactions = 10
@@ -26,7 +26,7 @@ logical_decoding_work_mem = 64kB
 ));
 $node_A->start;
 # node_B
-my $node_B = PostgresNode->new('node_B');
+my $node_B = Postgres::Test::Cluster->new('node_B');
 $node_B->init(allows_streaming => 'logical');
 $node_B->append_conf('postgresql.conf', qq(
 max_prepared_transactions = 10
@@ -34,7 +34,7 @@ logical_decoding_work_mem = 64kB
 ));
 $node_B->start;
 # node_C
-my $node_C = PostgresNode->new('node_C');
+my $node_C = Postgres::Test::Cluster->new('node_C');
 $node_C->init(allows_streaming => 'logical');
 $node_C->append_conf('postgresql.conf', qq(
 max_prepared_transactions = 10
diff --git a/src/test/subscription/t/023_twophase_stream.pl b/src/test/subscription/t/023_twophase_stream.pl
index c72c6b5ef4..21c32099f4 100644
--- a/src/test/subscription/t/023_twophase_stream.pl
+++ b/src/test/subscription/t/023_twophase_stream.pl
@@ -4,8 +4,8 @@
 # Test logical replication of 2PC with streaming.
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 18;
 
 ###############################
@@ -13,7 +13,7 @@ use Test::More tests => 18;
 ###############################
 
 # Initialize publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->append_conf('postgresql.conf', qq(
 max_prepared_transactions = 10
@@ -22,7 +22,7 @@ logical_decoding_work_mem = 64kB
 $node_publisher->start;
 
 # Create subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->append_conf('postgresql.conf', qq(
 max_prepared_transactions = 10
diff --git a/src/test/subscription/t/024_add_drop_pub.pl b/src/test/subscription/t/024_add_drop_pub.pl
index 24493a9c4e..9ea9e08df5 100644
--- a/src/test/subscription/t/024_add_drop_pub.pl
+++ b/src/test/subscription/t/024_add_drop_pub.pl
@@ -4,17 +4,17 @@
 # This test checks behaviour of ALTER SUBSCRIPTION ... ADD/DROP PUBLICATION
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 3;
 
 # Initialize publisher node
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
 # Create subscriber node
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
diff --git a/src/test/subscription/t/100_bugs.pl b/src/test/subscription/t/100_bugs.pl
index baa4a90771..8ef262bb2b 100644
--- a/src/test/subscription/t/100_bugs.pl
+++ b/src/test/subscription/t/100_bugs.pl
@@ -4,8 +4,8 @@
 # Tests for various bugs found over time
 use strict;
 use warnings;
-use PostgresNode;
-use TestLib;
+use Postgres::Test::Cluster;
+use Postgres::Test::Utils;
 use Test::More tests => 5;
 
 # Bug #15114
@@ -19,11 +19,11 @@ use Test::More tests => 5;
 # fix was to avoid the constant expressions simplification in
 # RelationGetIndexAttrBitmap(), so it's safe to call in more contexts.
 
-my $node_publisher = PostgresNode->new('publisher');
+my $node_publisher = Postgres::Test::Cluster->new('publisher');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
-my $node_subscriber = PostgresNode->new('subscriber');
+my $node_subscriber = Postgres::Test::Cluster->new('subscriber');
 $node_subscriber->init(allows_streaming => 'logical');
 $node_subscriber->start;
 
@@ -81,7 +81,7 @@ $node_subscriber->stop('fast');
 # identity set before accepting updates.  If it did not it would cause
 # an error when an update was attempted.
 
-$node_publisher = PostgresNode->new('publisher2');
+$node_publisher = Postgres::Test::Cluster->new('publisher2');
 $node_publisher->init(allows_streaming => 'logical');
 $node_publisher->start;
 
@@ -108,7 +108,7 @@ $node_publisher->stop('fast');
 #
 # Initial sync doesn't complete; the protocol was not being followed per
 # expectations after commit 07082b08cc5d.
-my $node_twoways = PostgresNode->new('twoways');
+my $node_twoways = Postgres::Test::Cluster->new('twoways');
 $node_twoways->init(allows_streaming => 'logical');
 $node_twoways->start;
 for my $db (qw(d1 d2))
@@ -158,15 +158,15 @@ is($node_twoways->safe_psql('d2', "SELECT count(f) FROM t2"),
 
 # Verify table data is synced with cascaded replication setup. This is mainly
 # to test whether the data written by tablesync worker gets replicated.
-my $node_pub = PostgresNode->new('testpublisher1');
+my $node_pub = Postgres::Test::Cluster->new('testpublisher1');
 $node_pub->init(allows_streaming => 'logical');
 $node_pub->start;
 
-my $node_pub_sub = PostgresNode->new('testpublisher_subscriber');
+my $node_pub_sub = Postgres::Test::Cluster->new('testpublisher_subscriber');
 $node_pub_sub->init(allows_streaming => 'logical');
 $node_pub_sub->start;
 
-my $node_sub = PostgresNode->new('testsubscriber1');
+my $node_sub = Postgres::Test::Cluster->new('testsubscriber1');
 $node_sub->init(allows_streaming => 'logical');
 $node_sub->start;
 
-- 
2.25.4

