@@ -355,6 +355,8 @@ sub info
355355 print $fh " Archive directory: " . $self -> archive_dir . " \n " ;
356356 print $fh " Connection string: " . $self -> connstr . " \n " ;
357357 print $fh " Log file: " . $self -> logfile . " \n " ;
358+ print $fh " Install Path: " , $self -> {_install_path } . " \n "
359+ if $self -> {_install_path };
358360 close $fh or die ;
359361 return $_info;
360362}
@@ -428,6 +430,8 @@ sub init
428430 my $pgdata = $self -> data_dir;
429431 my $host = $self -> host;
430432
433+ local %ENV = $self -> _get_env();
434+
431435 $params {allows_streaming } = 0 unless defined $params {allows_streaming };
432436 $params {has_archiving } = 0 unless defined $params {has_archiving };
433437
@@ -555,6 +559,8 @@ sub backup
555559 my $backup_path = $self -> backup_dir . ' /' . $backup_name ;
556560 my $name = $self -> name;
557561
562+ local %ENV = $self -> _get_env();
563+
558564 print " # Taking pg_basebackup $backup_name from node \" $name \"\n " ;
559565 TestLib::system_or_bail(
560566 ' pg_basebackup' , ' -D' , $backup_path , ' -h' ,
@@ -784,18 +790,15 @@ sub start
784790
785791 print (" ### Starting node \" $name \"\n " );
786792
787- {
788- # Temporarily unset PGAPPNAME so that the server doesn't
789- # inherit it. Otherwise this could affect libpqwalreceiver
790- # connections in confusing ways.
791- local %ENV = %ENV ;
792- delete $ENV {PGAPPNAME };
793-
794- # Note: We set the cluster_name here, not in postgresql.conf (in
795- # sub init) so that it does not get copied to standbys.
796- $ret = TestLib::system_log(' pg_ctl' , ' -D' , $self -> data_dir, ' -l' ,
797- $self -> logfile, ' -o' , " --cluster-name=$name " , ' start' );
798- }
793+ # Temporarily unset PGAPPNAME so that the server doesn't
794+ # inherit it. Otherwise this could affect libpqwalreceiver
795+ # connections in confusing ways.
796+ local %ENV = $self -> _get_env(PGAPPNAME => undef );
797+
798+ # Note: We set the cluster_name here, not in postgresql.conf (in
799+ # sub init) so that it does not get copied to standbys.
800+ $ret = TestLib::system_log(' pg_ctl' , ' -D' , $self -> data_dir, ' -l' ,
801+ $self -> logfile, ' -o' , " --cluster-name=$name " , ' start' );
799802
800803 if ($ret != 0)
801804 {
@@ -826,6 +829,9 @@ sub kill9
826829 my ($self ) = @_ ;
827830 my $name = $self -> name;
828831 return unless defined $self -> {_pid };
832+
833+ local %ENV = $self -> _get_env();
834+
829835 print " ### Killing node \" $name \" using signal 9\n " ;
830836 # kill(9, ...) fails under msys Perl 5.8.8, so fall back on pg_ctl.
831837 kill (9, $self -> {_pid })
@@ -852,6 +858,9 @@ sub stop
852858 my $port = $self -> port;
853859 my $pgdata = $self -> data_dir;
854860 my $name = $self -> name;
861+
862+ local %ENV = $self -> _get_env();
863+
855864 $mode = ' fast' unless defined $mode ;
856865 return unless defined $self -> {_pid };
857866 print " ### Stopping node \" $name \" using mode $mode \n " ;
@@ -874,6 +883,9 @@ sub reload
874883 my $port = $self -> port;
875884 my $pgdata = $self -> data_dir;
876885 my $name = $self -> name;
886+
887+ local %ENV = $self -> _get_env();
888+
877889 print " ### Reloading node \" $name \"\n " ;
878890 TestLib::system_or_bail(' pg_ctl' , ' -D' , $pgdata , ' reload' );
879891 return ;
@@ -895,15 +907,12 @@ sub restart
895907 my $logfile = $self -> logfile;
896908 my $name = $self -> name;
897909
898- print " ### Restarting node \" $name \"\n " ;
910+ local %ENV = $self -> _get_env( PGAPPNAME => undef ) ;
899911
900- {
901- local %ENV = %ENV ;
902- delete $ENV {PGAPPNAME };
912+ print " ### Restarting node \" $name \"\n " ;
903913
904- TestLib::system_or_bail(' pg_ctl' , ' -D' , $pgdata , ' -l' , $logfile ,
905- ' restart' );
906- }
914+ TestLib::system_or_bail(' pg_ctl' , ' -D' , $pgdata , ' -l' , $logfile ,
915+ ' restart' );
907916
908917 $self -> _update_pid(1);
909918 return ;
@@ -924,6 +933,9 @@ sub promote
924933 my $pgdata = $self -> data_dir;
925934 my $logfile = $self -> logfile;
926935 my $name = $self -> name;
936+
937+ local %ENV = $self -> _get_env();
938+
927939 print " ### Promoting node \" $name \"\n " ;
928940 TestLib::system_or_bail(' pg_ctl' , ' -D' , $pgdata , ' -l' , $logfile ,
929941 ' promote' );
@@ -945,6 +957,9 @@ sub logrotate
945957 my $pgdata = $self -> data_dir;
946958 my $logfile = $self -> logfile;
947959 my $name = $self -> name;
960+
961+ local %ENV = $self -> _get_env();
962+
948963 print " ### Rotating log in node \" $name \"\n " ;
949964 TestLib::system_or_bail(' pg_ctl' , ' -D' , $pgdata , ' -l' , $logfile ,
950965 ' logrotate' );
@@ -1117,6 +1132,14 @@ By default, all nodes use the same PGHOST value. If specified, generate a
11171132PGHOST specific to this node. This allows multiple nodes to use the same
11181133port.
11191134
1135+ =item install_path => '/path/to/postgres/installation'
1136+
1137+ Using this parameter is it possible to have nodes pointing to different
1138+ installations, for testing different versions together or the same version
1139+ with different build parameters. The provided path must be the parent of the
1140+ installation's 'bin' and 'lib' directories. In the common case where this is
1141+ not provided, Postgres binaries will be found in the caller's PATH.
1142+
11201143=back
11211144
11221145For backwards compatibility, it is also exported as a standalone function,
@@ -1165,12 +1188,89 @@ sub get_new_node
11651188 # Lock port number found by creating a new node
11661189 my $node = $class -> new($name , $host , $port );
11671190
1191+ if ($params {install_path })
1192+ {
1193+ $node -> {_install_path } = $params {install_path };
1194+ }
1195+
11681196 # Add node to list of nodes
11691197 push (@all_nodes , $node );
11701198
11711199 return $node ;
11721200}
11731201
1202+ # Private routine to return a copy of the environment with the PATH and
1203+ # (DY)LD_LIBRARY_PATH correctly set when there is an install path set for
1204+ # the node.
1205+ #
1206+ # Routines that call Postgres binaries need to call this routine like this:
1207+ #
1208+ # local %ENV = $self->_get_env{[%extra_settings]);
1209+ #
1210+ # A copy of the environment is taken and node's host and port settings are
1211+ # added as PGHOST and PGPORT, Then the extra settings (if any) are applied.
1212+ # Any setting in %extra_settings with a value that is undefined is deleted
1213+ # the remainder are# set. Then the PATH and (DY)LD_LIBRARY_PATH are adjusted
1214+ # if the node's install path is set, and the copy environment is returned.
1215+ #
1216+ # The install path set in get_new_node needs to be a directory containing
1217+ # bin and lib subdirectories as in a standard PostgreSQL installation, so this
1218+ # can't be used with installations where the bin and lib directories don't have
1219+ # a common parent directory.
1220+ sub _get_env
1221+ {
1222+ my $self = shift ;
1223+ my %inst_env = (%ENV , PGHOST => $self -> {_host }, PGPORT => $self -> {_port });
1224+ # the remaining arguments are modifications to make to the environment
1225+ my %mods = (@_ );
1226+ while (my ($k , $v ) = each %mods )
1227+ {
1228+ if (defined $v )
1229+ {
1230+ $inst_env {$k } = " $v " ;
1231+ }
1232+ else
1233+ {
1234+ delete $inst_env {$k };
1235+ }
1236+ }
1237+ # now fix up the new environment for the install path
1238+ my $inst = $self -> {_install_path };
1239+ if ($inst )
1240+ {
1241+ if ($TestLib::windows_os )
1242+ {
1243+ # Windows picks up DLLs from the PATH rather than *LD_LIBRARY_PATH
1244+ # choose the right path separator
1245+ if ($Config {osname } eq ' MSWin32' )
1246+ {
1247+ $inst_env {PATH } = " $inst /bin;$inst /lib;$ENV {PATH}" ;
1248+ }
1249+ else
1250+ {
1251+ $inst_env {PATH } = " $inst /bin:$inst /lib:$ENV {PATH}" ;
1252+ }
1253+ }
1254+ else
1255+ {
1256+ my $dylib_name =
1257+ $Config {osname } eq ' darwin'
1258+ ? " DYLD_LIBRARY_PATH"
1259+ : " LD_LIBRARY_PATH" ;
1260+ $inst_env {PATH } = " $inst /bin:$ENV {PATH}" ;
1261+ if (exists $ENV {$dylib_name })
1262+ {
1263+ $inst_env {$dylib_name } = " $inst /lib:$ENV {$dylib_name }" ;
1264+ }
1265+ else
1266+ {
1267+ $inst_env {$dylib_name } = " $inst /lib" ;
1268+ }
1269+ }
1270+ }
1271+ return (%inst_env );
1272+ }
1273+
11741274=pod
11751275
11761276=item get_free_port()
@@ -1330,6 +1430,8 @@ sub safe_psql
13301430{
13311431 my ($self , $dbname , $sql , %params ) = @_ ;
13321432
1433+ local %ENV = $self -> _get_env();
1434+
13331435 my ($stdout , $stderr );
13341436
13351437 my $ret = $self -> psql(
@@ -1441,6 +1543,8 @@ sub psql
14411543{
14421544 my ($self , $dbname , $sql , %params ) = @_ ;
14431545
1546+ local %ENV = $self -> _get_env();
1547+
14441548 my $stdout = $params {stdout };
14451549 my $stderr = $params {stderr };
14461550 my $replication = $params {replication };
@@ -1634,6 +1738,8 @@ sub background_psql
16341738{
16351739 my ($self , $dbname , $stdin , $stdout , $timer , %params ) = @_ ;
16361740
1741+ local %ENV = $self -> _get_env();
1742+
16371743 my $replication = $params {replication };
16381744
16391745 my @psql_params = (
@@ -1712,6 +1818,8 @@ sub interactive_psql
17121818{
17131819 my ($self , $dbname , $stdin , $stdout , $timer , %params ) = @_ ;
17141820
1821+ local %ENV = $self -> _get_env();
1822+
17151823 my @psql_params = (' psql' , ' -XAt' , ' -d' , $self -> connstr($dbname ));
17161824
17171825 push @psql_params , @{ $params {extra_params } }
@@ -1755,6 +1863,8 @@ sub poll_query_until
17551863{
17561864 my ($self , $dbname , $query , $expected ) = @_ ;
17571865
1866+ local %ENV = $self -> _get_env();
1867+
17581868 $expected = ' t' unless defined ($expected ); # default value
17591869
17601870 my $cmd = [ ' psql' , ' -XAt' , ' -c' , $query , ' -d' , $self -> connstr($dbname ) ];
@@ -1810,8 +1920,7 @@ sub command_ok
18101920
18111921 my $self = shift ;
18121922
1813- local $ENV {PGHOST } = $self -> host;
1814- local $ENV {PGPORT } = $self -> port;
1923+ local %ENV = $self -> _get_env();
18151924
18161925 TestLib::command_ok(@_ );
18171926 return ;
@@ -1831,8 +1940,7 @@ sub command_fails
18311940
18321941 my $self = shift ;
18331942
1834- local $ENV {PGHOST } = $self -> host;
1835- local $ENV {PGPORT } = $self -> port;
1943+ local %ENV = $self -> _get_env();
18361944
18371945 TestLib::command_fails(@_ );
18381946 return ;
@@ -1852,8 +1960,7 @@ sub command_like
18521960
18531961 my $self = shift ;
18541962
1855- local $ENV {PGHOST } = $self -> host;
1856- local $ENV {PGPORT } = $self -> port;
1963+ local %ENV = $self -> _get_env();
18571964
18581965 TestLib::command_like(@_ );
18591966 return ;
@@ -1874,8 +1981,7 @@ sub command_checks_all
18741981
18751982 my $self = shift ;
18761983
1877- local $ENV {PGHOST } = $self -> host;
1878- local $ENV {PGPORT } = $self -> port;
1984+ local %ENV = $self -> _get_env();
18791985
18801986 TestLib::command_checks_all(@_ );
18811987 return ;
@@ -1899,8 +2005,7 @@ sub issues_sql_like
18992005
19002006 my ($self , $cmd , $expected_sql , $test_name ) = @_ ;
19012007
1902- local $ENV {PGHOST } = $self -> host;
1903- local $ENV {PGPORT } = $self -> port;
2008+ local %ENV = $self -> _get_env();
19042009
19052010 truncate $self -> logfile, 0;
19062011 my $result = TestLib::run_log($cmd );
@@ -1923,8 +2028,7 @@ sub run_log
19232028{
19242029 my $self = shift ;
19252030
1926- local $ENV {PGHOST } = $self -> host;
1927- local $ENV {PGPORT } = $self -> port;
2031+ local %ENV = $self -> _get_env();
19282032
19292033 TestLib::run_log(@_ );
19302034 return ;
@@ -2174,6 +2278,9 @@ sub pg_recvlogical_upto
21742278{
21752279 my ($self , $dbname , $slot_name , $endpos , $timeout_secs , %plugin_options )
21762280 = @_ ;
2281+
2282+ local %ENV = $self -> _get_env();
2283+
21772284 my ($stdout , $stderr );
21782285
21792286 my $timeout_exception = ' pg_recvlogical timed out' ;
0 commit comments