On 1/28/21 9:24 AM, Alvaro Herrera wrote: > On 2021-Jan-28, Andrew Dunstan wrote: > > ... neat stuff, thanks. > >> + # Windows picks up DLLs from the PATH rather than >> *LD_LIBRARY_PATH >> + # choose the right path separator >> + if ($Config{osname} eq 'MSWin32') >> + { >> + $ENV{PATH} = "$inst/bin;$inst/lib;$ENV{PATH}"; >> + } >> + else >> + { >> + $ENV{PATH} = "$inst/bin:$inst/lib:$ENV{PATH}"; >> + } > Hmm, if only Windows needs lib/ in PATH, then we do we add $inst/lib to > PATH even when not Windows?
We could, but there's no point AFAICS. *nix dynamic loaders don't use the PATH on any platform to my knowledge. This is mainly so that Windows will find libpq.dll correctly. > >> + if (exists $ENV{DYLIB}) >> + { >> + $ENV{DYLIB} = "$inst/lib:$ENV{DYLIB}"; >> + } >> + else >> + { >> + $ENV{DYLIB} = "$inst/lib}"; > Note extra closing } in the string here. Oops. fixed, thanks cheers andrew -- Andrew Dunstan EDB: https://www.enterprisedb.com
diff --git a/src/test/perl/PostgresNodePath.pm b/src/test/perl/PostgresNodePath.pm new file mode 100644 index 0000000000..83fd371192 --- /dev/null +++ b/src/test/perl/PostgresNodePath.pm @@ -0,0 +1,169 @@ + +=pod + +=head1 NAME + +PostgresNodePath - subclass of PostgresNode using a given Postgres install + +=head1 SYNOPSIS + + use lib '/path/to/postgres/src/test/perl'; + use PostgresNodePath; + + my $node = get_new_node('/path/to/binary/installation','my_node'); + + or + + my $node = PostgresNodePath->get_new_node('/path/to/binary/installation', + 'my_node'); + + $node->init(); + $node->start(); + + ... + +=head1 DESCRIPTION + +PostgresNodePath is a subclass of PostgresNode which runs commands in the +context of a given PostgreSQL install path. The given path is +is expected to have a standard install, with bin and lib +subdirectories. + +The only API difference between this and PostgresNode is +that get_new_node() takes an additional parameter in position +1 that contains the install path. Everything else is either +inherited from PostgresNode or overridden but with identical +parameters. + +As with PostgresNode, the environment variable PG_REGRESS +must point to a binary of pg_regress, in order to init() a +node. + +=cut + + + +package PostgresNodePath; + +use strict; +use warnings; + +use parent qw(PostgresNode); + +use Exporter qw(import); +our @EXPORT = qw(get_new_node); + +use Config; +use TestLib(); + +sub get_new_node +{ + my $class = __PACKAGE__; + die 'no args' unless scalar(@_); + my $installpath = shift; + # check if we got a class name before the installpath + if ($installpath =~ /^[A-Za-z0-9_](::[A-Za-z0-9_])*/ + && !-e "$installpath/bin") + { + $class = $installpath; + $installpath = shift; + } + my $node = PostgresNode->get_new_node(@_); + bless $node, $class; # re-bless + $node->{_installpath} = $installpath; + return $node; +} + + +# class methods we don't override: +# new() # should probably be hidden +# get_free_port() +# can_bind() + + +# instance methods we don't override because we don't need to: +# port() host() basedir() name() logfile() connstr() group_access() data_dir() +# archive_dir() backup_dir() dump_info() ? set_replication_conf() append_conf() +# backup_fs_hot() backup_fs_cold() _backup_fs() init_from_backup() +# rotate_logfile() enable_streaming() enable_restoring() set_recovery_mode() +# set_standby_mode() enable_archiving() _update_pid teardown_node() +# clean_node() lsn() wait_for_catchup() wait_for_slot_catchup() query_hash() +# slot() + +# info is special - we add in the installpath spec +# no need for environment override +sub info +{ + my $node = shift; + my $inst = $node->{_installpath}; + my $res = $node->SUPER::info(); + $res .= "Install Path: $inst\n"; + return $res; +} + +BEGIN +{ + + # putting this in a BEGIN block means it's run and checked by perl -c + + + # everything other than info and get_new_node that we need to override. + # they are all instance methods, so we can use the same template for all. + my @instance_overrides = qw(init backup start kill9 stop reload restart + promote logrotate safe_psql psql background_psql + interactive_psql poll_query_until command_ok + command_fails command_like command_checks_all + issues_sql_like run_log pg_recvlogical_upto + ); + + my $dylib_name = + $Config{osname} eq 'darwin' ? "DYLD_LIBRARY_PATH" : "LD_LIBRARY_PATH"; + + my $template = <<' EOSUB'; + + sub SUBNAME + { + my $node=shift; + my $inst = $node->{_installpath}; + local %ENV = %ENV; + if ($TestLib::windows_os) + { + # Windows picks up DLLs from the PATH rather than *LD_LIBRARY_PATH + # choose the right path separator + if ($Config{osname} eq 'MSWin32') + { + $ENV{PATH} = "$inst/bin;$inst/lib;$ENV{PATH}"; + } + else + { + $ENV{PATH} = "$inst/bin:$inst/lib:$ENV{PATH}"; + } + } + else + { + $ENV{PATH} = "$inst/bin:$ENV{PATH}"; + if (exists $ENV{DYLIB}) + { + $ENV{DYLIB} = "$inst/lib:$ENV{DYLIB}"; + } + else + { + $ENV{DYLIB} = "$inst/lib"; + } + } + $node->SUPER::SUBNAME(@_); + } + + EOSUB + + foreach my $subname (@instance_overrides) + { + my $code = $template; + $code =~ s/SUBNAME/$subname/g; + $code =~ s/DYLIB/$dylib_name/g; + ## no critic (ProhibitStringyEval) + eval($code); + } +} + +1;