On Mon, 2005-08-08 at 16:59 -0400, Tom Lane wrote: > Matt Miller <[EMAIL PROTECTED]> writes: > > I want to write some regression tests that confirm the behavior of > > multiple connections simultaneously going at the same tables/rows. Is > > there something like this already, e.g. in src/test/regress? > > No. ... but surely we need one.
The attached patch allows src/test/regress/pg_regress.sh to recognize lines that begin with "curr_test:" in the schedule file. Tests named on such a line are run concurrently across multiple connections. To make use of this facility each test in the group must begin with the line: select * from concurrency_test where key = '<test_name>' for update; where <test_name> is replace by the name of that test. This will enable pg_regress to start this test at the same time as the other tests in the group. Is this a reasonable starting point for a concurrent testing framework? This does not address the issue of how to interpret the test output. Maybe the simplest solution is to force test writers to generate output that does not depend on the relative progress of any concurrent tests. Or, maybe the "ignore:" directive in the schedule file could be employed somehow.
Index: pg_regress.sh =================================================================== RCS file: /var/local/pgcvs/pgsql/src/test/regress/pg_regress.sh,v retrieving revision 1.59 diff -c -r1.59 pg_regress.sh *** pg_regress.sh 17 Jul 2005 18:28:45 -0000 1.59 --- pg_regress.sh 15 Aug 2005 21:20:03 -0000 *************** *** 623,628 **** --- 623,632 ---- do # Count line numbers lno=`expr $lno + 1` + + # Init concurrency flag + concurrent= + [ -z "$line" ] && continue set X $line; shift *************** *** 631,636 **** --- 635,647 ---- shift ignore_list="$ignore_list $@" continue + elif [ x"$1" = x"curr_test:" ]; then + # init support for concurrent test group + concurrent=1 + cat /dev/null >"$inputdir/sql/concurrency_test_init.sql" + echo "create table concurrency_test (key varchar primary key);" >>"$inputdir/sql/concurrency_test_init.sql" + ( $PSQL -d "$dbname" <"$inputdir/sql/concurrency_test_init.sql" >"$outputdir/results/concurrency_test_init.out" 2>&1 )& + wait elif [ x"$1" != x"test:" ]; then echo "$me:$schedule:$lno: syntax error" (exit 2); exit *************** *** 649,671 **** ( $PSQL -d "$dbname" <"$inputdir/sql/$1.sql" >"$outputdir/results/$1.out" 2>&1 )& wait else ! # Start a parallel group ! $ECHO_N "parallel group ($# tests): $ECHO_C" ! if [ $maxconnections -gt 0 ] ; then ! connnum=0 ! test $# -gt $maxconnections && $ECHO_N "(in groups of $maxconnections) $ECHO_C" ! fi ! for name do ! ( ! $PSQL -d "$dbname" <"$inputdir/sql/$name.sql" >"$outputdir/results/$name.out" 2>&1 ! $ECHO_N " $name$ECHO_C" ! ) & if [ $maxconnections -gt 0 ] ; then ! connnum=`expr \( $connnum + 1 \) % $maxconnections` ! test $connnum -eq 0 && wait fi ! done ! wait echo fi --- 660,717 ---- ( $PSQL -d "$dbname" <"$inputdir/sql/$1.sql" >"$outputdir/results/$1.out" 2>&1 )& wait else ! # ---------- ! # If this is a concurrent test group then write the script "concurrent_test.sql" ! # which will spawn and synchronize each test in the group. ! # ! # Concurrent test groups do not respect $maxconnections. ! # ! # If this is not a concurrent test group then just run each test directly. ! # ---------- ! ! if [ "$concurrent" = "1" ]; then ! $ECHO_N "concurrent group ($# tests): $ECHO_C" ! ! # insert a lock record for each test ! cat /dev/null >"$inputdir/sql/concurrency_test.sql" ! echo "BEGIN;" >>"$inputdir/sql/concurrency_test.sql" ! for name do ! echo "insert into concurrency_test values ('$name');" >>"$inputdir/sql/concurrency_test.sql" ! done ! echo "COMMIT;" >>"$inputdir/sql/concurrency_test.sql" ! ! # for each test, acquire the lock and then spawn the test ! echo "BEGIN;" >>"$inputdir/sql/concurrency_test.sql" ! for name do ! echo "select * from concurrency_test where key = '$name' for update;" >>"$inputdir/sql/concurrency_test.sql" ! echo "\! $PSQL -d \"$dbname\" <\"$inputdir/sql/$name.sql\" >\"$outputdir/results/$name.out\" 2>&1 &" >>"$inputdir/sql/concurrency_test.sql" ! done ! ! # release all locks, concurrently launching all tests ! echo "ROLLBACK;" >>"$inputdir/sql/concurrency_test.sql" ! ! # done writing the script. fire it. ! ( $PSQL -d "$dbname" <"$inputdir/sql/concurrency_test.sql" >"$outputdir/results/concurrency_test.out" 2>&1 )& ! wait ! else ! $ECHO_N "parallel group ($# tests): $ECHO_C" if [ $maxconnections -gt 0 ] ; then ! connnum=0 ! test $# -gt $maxconnections && $ECHO_N "(in groups of $maxconnections) $ECHO_C" fi ! ! for name do ! ( ! $PSQL -d "$dbname" <"$inputdir/sql/$name.sql" >"$outputdir/results/$name.out" 2>&1 ! $ECHO_N " $name$ECHO_C" ! ) & ! if [ $maxconnections -gt 0 ] ; then ! connnum=`expr \( $connnum + 1 \) % $maxconnections` ! test $connnum -eq 0 && wait ! fi ! done ! wait ! fi echo fi
---------------------------(end of broadcast)--------------------------- TIP 2: Don't 'kill -9' the postmaster