From 252dcb32397f64a5e1ceac05b29a271ab19aa960 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Thu, 24 Aug 2023 14:17:03 -0700 Subject: Use "template" data directory in tests When running all (or just many) of our tests, a significant portion of both CPU time and IO is spent running initdb. Most of those initdb runs don't specify any options influencing properties of the created data directory. Avoid most of that overhead by creating a "template" data directory, alongside the temporary installation. Instead of running initdb, pg_regress and tap tests can copy that data directory. When a tap test specifies options to initdb, the template data directory is not used. That could be relaxed for some options, but it's not clear it's worth the effort. There unfortunately is some duplication between pg_regress.c and Cluster.pm, but there are no easy ways of sharing that code without introducing additional complexity. Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/20220120021859.3zpsfqn4z7ob7afz@alap3.anarazel.de --- src/test/perl/PostgreSQL/Test/Cluster.pm | 46 ++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'src/test/perl/PostgreSQL/Test/Cluster.pm') diff --git a/src/test/perl/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pm index 41409ba1bed..426f94ff09c 100644 --- a/src/test/perl/PostgreSQL/Test/Cluster.pm +++ b/src/test/perl/PostgreSQL/Test/Cluster.pm @@ -522,8 +522,50 @@ sub init mkdir $self->backup_dir; mkdir $self->archive_dir; - PostgreSQL::Test::Utils::system_or_bail('initdb', '-D', $pgdata, '-A', - 'trust', '-N', @{ $params{extra} }); + # If available and if there aren't any parameters, use a previously + # initdb'd cluster as a template by copying it. For a lot of tests, that's + # substantially cheaper. Do so only if there aren't parameters, it doesn't + # seem worth figuring out whether they affect compatibility. + # + # There's very similar code in pg_regress.c, but we can't easily + # deduplicate it until we require perl at build time. + if (defined $params{extra} or !defined $ENV{INITDB_TEMPLATE}) + { + note("initializing database system by running initdb"); + PostgreSQL::Test::Utils::system_or_bail('initdb', '-D', $pgdata, '-A', + 'trust', '-N', @{ $params{extra} }); + } + else + { + my @copycmd; + my $expected_exitcode; + + note("initializing database system by copying initdb template"); + + if ($PostgreSQL::Test::Utils::windows_os) + { + @copycmd = qw(robocopy /E /NJS /NJH /NFL /NDL /NP); + $expected_exitcode = 1; # 1 denotes files were copied + } + else + { + @copycmd = qw(cp -a); + $expected_exitcode = 0; + } + + @copycmd = (@copycmd, $ENV{INITDB_TEMPLATE}, $pgdata); + + my $ret = PostgreSQL::Test::Utils::system_log(@copycmd); + + # See http://perldoc.perl.org/perlvar.html#%24CHILD_ERROR + if ($ret & 127 or $ret >> 8 != $expected_exitcode) + { + BAIL_OUT( + sprintf("failed to execute command \"%s\": $ret", + join(" ", @copycmd))); + } + } + PostgreSQL::Test::Utils::system_or_bail($ENV{PG_REGRESS}, '--config-auth', $pgdata, @{ $params{auth_extra} }); -- cgit v1.2.3