Dirty SQL test system
* Added a system that allows "dirty" tests to be written. These tests actually need to change the database, so a temporary test database must be created to run them.
This commit is contained in:
parent
04e550709a
commit
c18bdc2d1f
5 changed files with 114 additions and 17 deletions
|
@ -9,8 +9,8 @@ user=tests
|
|||
password=tests
|
||||
EOF
|
||||
fi
|
||||
TEST_DATABASE="`grep ^db= db-config.txt | sed -e s/.*=//`"
|
||||
TEST_USER="`grep ^user= db-config.txt | sed -e s/.*=//`"
|
||||
export TEST_DATABASE="`grep ^db= db-config.txt | sed -e s/.*=//`"
|
||||
export TEST_USER="`grep ^user= db-config.txt | sed -e s/.*=//`"
|
||||
|
||||
echo
|
||||
echo
|
||||
|
@ -53,3 +53,6 @@ fi
|
|||
if [ -d user ]; then
|
||||
pg_prove -U $TEST_USER -d $TEST_DATABASE `find user/ -type f -name '*.sql'` || exit 1
|
||||
fi
|
||||
if [ -x dirty/run-dirty-tests.sql ]; then
|
||||
( cd dirty; exec ./run-dirty-tests.sql ) || exit 1
|
||||
fi
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Dirty test system self-check
|
||||
*
|
||||
* Insert an address, it should exist during the main test. Also create a
|
||||
* function and a table which are used to synchronise execution.
|
||||
*/
|
||||
BEGIN;
|
||||
INSERT INTO users.addresses ( address )
|
||||
VALUES ( 'prepare@example.org' );
|
||||
|
||||
CREATE TABLE _barriers( _barrier BIGINT );
|
||||
|
||||
CREATE FUNCTION _synchronise_tests( _lock BIGINT )
|
||||
RETURNS VOID
|
||||
AS $$
|
||||
BEGIN
|
||||
WHILE pg_try_advisory_lock( _lock )
|
||||
LOOP
|
||||
PERFORM pg_advisory_unlock( _lock );
|
||||
END LOOP;
|
||||
END;
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
COMMIT;
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Dirty test system self-check
|
||||
*
|
||||
* Insert an address, it should exist during the main test.
|
||||
*/
|
||||
BEGIN;
|
||||
SELECT no_plan( );
|
||||
|
||||
SELECT pg_advisory_lock( 1 );
|
||||
|
||||
SELECT diag_test_name( 'Dirty test system self-check - prepare.sql was executed' );
|
||||
SELECT is( COUNT(*)::INT , 1 )
|
||||
FROM users.addresses
|
||||
WHERE address = 'prepare@example.org';
|
||||
|
||||
SELECT * FROM finish( );
|
||||
ROLLBACK;
|
37
legacyworlds-server-data/db-structure/tests/dirty/run-dirty-tests.sh
Executable file
37
legacyworlds-server-data/db-structure/tests/dirty/run-dirty-tests.sh
Executable file
|
@ -0,0 +1,37 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$TEST_DATABASE" ]; then
|
||||
echo "Missing TEST_DATABASE environment variable"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
echo
|
||||
echo 'Running "dirty" database tests'
|
||||
echo
|
||||
|
||||
find -mindepth 1 -maxdepth 1 -type d | sort | while read testdir; do
|
||||
|
||||
[ -f "$testdir/run-test.sql" ] || continue
|
||||
|
||||
echo "Dirty test $testdir"
|
||||
echo "--------------------------------------------"
|
||||
echo
|
||||
|
||||
echo "Creating temporary database ..."
|
||||
echo "DROP DATABASE IF EXISTS dirty_tests; CREATE DATABASE dirty_tests TEMPLATE $TEST_DATABASE;" \
|
||||
| psql -vQUIET=1 -vON_ERROR_STOP=1 $TEST_DATABASE || exit 1
|
||||
|
||||
if [ -f "$testdir/prepare.sql" ]; then
|
||||
echo "Preparing database ..."
|
||||
( cd .. && exec psql -vQUIET=1 -vON_ERROR_STOP=1 --file "dirty/$testdir/prepare.sql" dirty_tests ) || exit 1
|
||||
fi
|
||||
|
||||
echo "Running main test ..."
|
||||
( cd .. && pg_prove -d dirty_tests dirty/$testdir/run-test.sql ) || exit 1
|
||||
|
||||
echo "Dropping temporary database ..."
|
||||
echo -e "DROP DATABASE IF EXISTS dirty_tests;" \
|
||||
| psql -vQUIET=1 -vON_ERROR_STOP=1 $TEST_DATABASE || exit 1
|
||||
|
||||
echo
|
||||
done
|
|
@ -63,19 +63,30 @@ framework as well as the tests themselves. See below for more information.
|
|||
Unit tests
|
||||
----------
|
||||
|
||||
There are three sub-directories in the tests/ directory. The admin/ directory
|
||||
There are four sub-directories in the tests/ directory. The admin/ directory
|
||||
contains tests that require administrative permissions on the database
|
||||
(therefore most functionality checks can be found there), while the user/
|
||||
sub-directory contains unit tests that must be executed as the standard
|
||||
user (for example privileges checks). Finally, the utils/ sub-directory
|
||||
contains scripts used by tests from the admin/ directory to create test
|
||||
data.
|
||||
user (for example privileges checks).
|
||||
|
||||
In both directories, files are organised in a manner that is parallel to the
|
||||
contents of the database creation scripts. For each actual SQL file, a
|
||||
sub-directory with the same name (minus the ".sql" extension) can be created,
|
||||
each sub-directory containing the test suites for the definitions and
|
||||
functions from the corresponding file.
|
||||
The dirty/ sub-directory contains tests which require actual changes to
|
||||
be committed to the database; while unit tests are not supposed to be executed
|
||||
on a loaded database anyway, these specific tests could cause problems with
|
||||
other tests, and therefore run on copies of the database.
|
||||
|
||||
Finally, the utils/ sub-directory contains scripts used by tests from both the
|
||||
admin/ and dirty/ sub-directories to create test data.
|
||||
|
||||
In both the admin/ and user/ directories, files are organised in a manner that
|
||||
is parallel to the contents of the database creation scripts. For each actual
|
||||
SQL file, a sub-directory with the same name (minus the ".sql" extension) can
|
||||
be created, each sub-directory containing the test suites for the definitions
|
||||
and functions from the corresponding file.
|
||||
|
||||
The dirty/ sub-directory contains a script which can be used to run the
|
||||
"dirty" test suites, as well as one directory per test suite. Each test suite
|
||||
directory may contain a "prepare.sql" script, to be executed before the actual
|
||||
tests, as well as a "run-test.sql" which runs the actual tests.
|
||||
|
||||
In order to run the database unit tests, the following steps must be taken:
|
||||
|
||||
|
@ -93,14 +104,20 @@ In order to run the database unit tests, the following steps must be taken:
|
|||
4) The tests/pgtap.sql script must be loaded into the database as the
|
||||
administrative user.
|
||||
|
||||
At this point, it becomes possible to launch the test suites by issuing a
|
||||
At this point, it becomes possible to launch the basic test suites by issuing a
|
||||
command similar to:
|
||||
|
||||
pg_prove -d $DATABASE -U $USER \
|
||||
`find $DIR/ -type f -name '*.sql' | sort`
|
||||
|
||||
where $DATABASE is the name of the database, $USER the name of the user that
|
||||
will execute the tests and $DIR being either admin or user.
|
||||
will execute the tests and $DIR being either admin or user. The "dirty" test
|
||||
suite can be launched by running:
|
||||
|
||||
TEST_DATABASE=$DATABASE ./run-dirty-tests.sh
|
||||
|
||||
Note that the dirty tests will fail unless all existing connections to the
|
||||
main database are closed.
|
||||
|
||||
|
||||
Build system
|
||||
|
@ -109,5 +126,5 @@ Build system
|
|||
The build system will attempt to create the database using the scripts. It will
|
||||
stop at the first unsuccessful command. On success, it will proceed to loading
|
||||
pgTAP, then run all available unit tests: first it will execute tests from the
|
||||
admin/ sub-directory, then tests from the user/ sub-directory. A failure will
|
||||
cause the build to be aborted.
|
||||
admin/ sub-directory, then tests from the user/ sub-directory, and finally the
|
||||
dirty tests. A failure will cause the build to be aborted.
|
||||
|
|
Reference in a new issue