Files
postgresql/src/test/perl
Tom Lane 08af921906 Fix order of shutdown cleanup operations in PostgresNode.pm.
Previously, database clusters created by a TAP test were shut down by
DESTROY methods attached to the PostgresNode objects representing them.
The trouble with that is that if the objects survive into the final global
destruction phase (which they do), Perl executes the DESTROY methods in an
unspecified order.  Thus, the order of shutdown of multiple clusters was
indeterminate, which might lead to not-very-reproducible errors getting
logged (eg from a slave whose master might or might not get killed first).
Worse, the File::Temp objects representing the temporary PGDATA directories
might get destroyed before the PostgresNode objects, resulting in attempts
to delete PGDATA directories that still have live servers in them.  On
Windows, this would lead to directory deletion failures; on Unix, it
usually had no effects worse than erratic "could not open temporary
statistics file "pg_stat/global.tmp": No such file or directory" log
messages.

While none of this would affect the reported result of the TAP test, which
is already determined, it could be very confusing when one is trying to
understand from the logs what went wrong with a failed test.

To fix, do the postmaster shutdowns in an END block rather than at object
destruction time.  The END block will execute at a well-defined (and
reasonable) time during script termination, and it will stop the
postmasters in order of PostgresNode object creation.  (Perhaps we should
change that to be reverse order of creation, but the main point here is
that we now have control which we did not before.)  Use "pg_ctl stop", not
an asynchronous kill(SIGQUIT), so that we wait for the postmasters to shut
down before proceeding with directory deletion.

Deletion of temporary directories still happens in an unspecified order
during global destruction, but I can see no reason to care about that
once the postmasters are stopped.
2016-04-26 12:43:03 -04:00
..
2016-03-03 13:21:35 -03:00

Perl-based TAP tests
====================

src/test/perl/ contains shared infrastructure that's used by Perl-based tests
across the source tree, particularly tests in src/bin and src/test. It's used
to drive tests for backup and restore, replication, etc - anything that can't
really be expressed using pg_regress or the isolation test framework.

You should prefer to write tests using pg_regress in src/test/regress, or
isolation tester specs in src/test/isolation, if possible. If not, check to
see if your new tests make sense under an existing tree in src/test, like
src/test/ssl, or should be added to one of the suites for an existing utility.

Note that all tests and test tools should have perltidy run on them before
patches are submitted, using perltidy --profile=src/tools/pgindent/perltidyrc

Writing tests
-------------

Tests are written using Perl's Test::More with some PostgreSQL-specific
infrastructure from src/test/perl providing node management, support for
invoking 'psql' to run queries and get results, etc. You should read the
documentation for Test::More before trying to write tests.

Test scripts in the t/ subdirectory of a suite are executed in alphabetical
order.

Each test script should begin with:

    use strict;
    use warnings;
    use PostgresNode;
    use TestLib;
    # 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 = get_new_node('master');
    $node->init;
    $node->start;

    my $ret = $node->psql('postgres', 'SELECT 1');
    is($ret, '1', 'SELECT 1 returns 1');

    $node->stop('fast');

Read the Test::More documentation for more on how to write tests:

    perldoc Test::More

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