--- /dev/null
+;; database name = connect string
+[databases]
+
+p0 = port=6666 host=localhost dbname=p0 user=bouncer pool_size=2
+p1 = port=6666 host=localhost dbname=p1 user=bouncer
+p2 = port=6668 host=localhost dbname=p2 user=bouncer
+
+;; Configuation section
+[pgbouncer]
+
+;;;
+;;; Administrative settings
+;;;
+
+logfile = tmp/test.log
+pidfile = tmp/test.pid
+
+;;;
+;;; Where to wait for clients
+;;;
+
+; ip address or * which means all ip-s
+listen_addr = 127.0.0.1
+listen_port = 6667
+unix_socket_dir = /tmp
+
+;;;
+;;; Authentication settings
+;;;
+
+; any, trust, plain, crypt, md5
+;auth_type = trust
+auth_file = tmp/userlist.txt
+
+;;;
+;;; Pooler personality questions
+;;;
+
+; When server connection is released back to pool:
+; session - after client disconnects
+; transaction - after transaction finishes
+; statement - after statement finishes
+pool_mode = statement
+
+; When taking idle server into use, this query is ran first.
+;
+; Query for session pooling:
+; ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT
+; Query for statement/transaction pooling:
+; SELECT 1
+; Empty query disables the functionality
+server_check_query = select 1
+
+; If server was used more recently that this many seconds ago,
+; skip the check query. If 0, the check query is always ran.
+server_check_delay = 10
+
+;;;
+;;; Connection limits
+;;;
+
+; total number of clients that can connect
+max_client_conn = 10
+default_pool_size = 5
+
+;;;
+;;; Timeouts
+;;;
+
+; Close server connection if its been connected longer.
+server_lifetime = 120
+
+; Close server connection if its not been used in this time.
+; Allows to clean unneccessary connections from pool after peak.
+server_idle_timeout = 60
+
+; Cancel connection attepmt if server does not answer takes longer.
+server_connect_timeout = 15
+
+; If server login failed (server_connect_timeout or auth failure)
+; then wait this many second.
+server_login_retry = 15
+
+; Dangerous. Server connection is closed if query does not return
+; in this time. Should be used to survive network problems,
+; _not_ as statement_timeout. (default: 0)
+query_timeout = 0
+
+; Dangerous. Client connection is closed if no activity in this time.
+; Should be used to survive network problems. (default: 0)
+client_idle_timeout = 0
+
+
--- /dev/null
+#! /bin/sh
+
+rm -rf TestCA1
+
+(
+./newca.sh TestCA1 C=QQ O=Org1 CN="TestCA1"
+./newsite.sh TestCA1 localhost C=QQ O=Org1 L=computer OU=db
+./newsite.sh TestCA1 bouncer C=QQ O=Org1 L=computer OU=Dev
+./newsite.sh TestCA1 random C=QQ O=Org1 L=computer OU=Dev
+) > /dev/null
+
+export PATH=/usr/lib/postgresql/9.4/bin:$PATH
+export PGDATA=$PWD/pgdata
+export PGHOST=localhost
+export PGPORT=6667
+export EF_ALLOW_MALLOC_0=1
+
+mkdir -p tmp
+
+BOUNCER_LOG=tmp/test.log
+BOUNCER_INI=test.ini
+BOUNCER_PID=tmp/test.pid
+BOUNCER_PORT=`sed -n '/^listen_port/s/listen_port.*=[^0-9]*//p' $BOUNCER_INI`
+BOUNCER_EXE="../../pgbouncer"
+
+LOGDIR=tmp
+NC_PORT=6668
+PG_PORT=6666
+PG_LOG=$LOGDIR/pg.log
+
+pgctl() {
+ pg_ctl -o "-p $PG_PORT" -D $PGDATA $@ >>$PG_LOG 2>&1
+}
+
+rm -f core
+ulimit -c unlimited
+
+for f in pgdata/postmaster.pid tmp/test.pid; do
+ test -f $f && { kill `cat $f` || true; }
+done
+
+mkdir -p $LOGDIR
+rm -fr $BOUNCER_LOG $PG_LOG
+rm -rr $PGDATA
+
+if [ ! -d $PGDATA ]; then
+ echo "initdb"
+ mkdir $PGDATA
+ initdb --nosync >> $PG_LOG 2>&1
+ sed -r -i "/unix_socket_director/s:.*(unix_socket_director.*=).*:\\1 '/tmp':" pgdata/postgresql.conf
+ echo "port = $PG_PORT" >> pgdata/postgresql.conf
+ echo "log_connections = on" >> pgdata/postgresql.conf
+ echo "log_disconnections = on" >> pgdata/postgresql.conf
+ cp pgdata/postgresql.conf pgdata/postgresql.conf.orig
+ cp pgdata/pg_hba.conf pgdata/pg_hba.conf.orig
+ cp pgdata/pg_ident.conf pgdata/pg_ident.conf.orig
+
+ cp -p TestCA1/sites/01-localhost.crt pgdata/server.crt
+ cp -p TestCA1/sites/01-localhost.key pgdata/server.key
+ cp -p TestCA1/ca.crt pgdata/root.crt
+
+ echo '"bouncer" "zzz"' > tmp/userlist.txt
+
+ chmod 600 pgdata/server.key
+ chmod 600 tmp/userlist.txt
+fi
+
+pgctl start
+sleep 5
+
+echo "createdb"
+psql -p $PG_PORT -l | grep p0 > /dev/null || {
+ psql -p $PG_PORT -c "create user bouncer" template1
+ createdb -p $PG_PORT p0
+ createdb -p $PG_PORT p1
+}
+
+$BOUNCER_EXE -d $BOUNCER_INI
+sleep 1
+
+reconf_bouncer() {
+ cp test.ini tmp/test.ini
+ for ln in "$@"; do
+ echo "$ln" >> tmp/test.ini
+ done
+ test -f tmp/test.pid && kill `cat tmp/test.pid`
+ sleep 1
+ $BOUNCER_EXE -v -v -v -d tmp/test.ini
+}
+
+reconf_pgsql() {
+ cp pgdata/postgresql.conf.orig pgdata/postgresql.conf
+ for ln in "$@"; do
+ echo "$ln" >> pgdata/postgresql.conf
+ done
+ pgctl stop
+ pgctl start
+ sleep 1
+}
+
+
+#
+# fw hacks
+#
+
+#
+# util functions
+#
+
+complete() {
+ test -f $BOUNCER_PID && kill `cat $BOUNCER_PID` >/dev/null 2>&1
+ pgctl -m fast stop
+ rm -f $BOUNCER_PID
+}
+
+die() {
+ echo $@
+ complete
+ exit 1
+}
+
+admin() {
+ psql -h /tmp -U pgbouncer pgbouncer -c "$@;" || die "Cannot contact bouncer!"
+}
+
+runtest() {
+ echo -n "`date` running $1 ... "
+ eval $1 >$LOGDIR/$1.log 2>&1
+ if [ $? -eq 0 ]; then
+ echo "ok"
+ else
+ echo "FAILED"
+ fi
+ date >> $LOGDIR/$1.log
+
+ # allow background processing to complete
+ wait
+ # start with fresh config
+ kill -HUP `cat $BOUNCER_PID`
+}
+
+psql_pg() {
+ psql -U bouncer -h 127.0.0.1 -p $PG_PORT "$@"
+}
+
+psql_bouncer() {
+ PGUSER=bouncer psql "$@"
+}
+
+# server_lifetime
+test_server_ssl() {
+ reconf_bouncer "auth_type = trust" "server_tls_sslmode = require"
+ echo "hostssl all all 127.0.0.1/32 trust" > pgdata/pg_hba.conf
+ reconf_pgsql "ssl=on" "ssl_ca_file='root.crt'"
+ psql_bouncer -q -d p0 -c "select 'ssl-connect'" | tee tmp/test.tmp0
+ grep -q "ssl-connect" tmp/test.tmp0
+ rc=$?
+ return $rc
+}
+
+test_server_ssl_verify() {
+ reconf_bouncer "auth_type = trust" \
+ "server_tls_sslmode = verify-full" \
+ "server_tls_ca_file = TestCA1/ca.crt"
+
+ echo "hostssl all all 127.0.0.1/32 trust" > pgdata/pg_hba.conf
+ reconf_pgsql "ssl=on" "ssl_ca_file='root.crt'"
+ psql_bouncer -q -d p0 -c "select 'ssl-full-connect'" | tee tmp/test.tmp1
+ grep -q "ssl-full-connect" tmp/test.tmp1
+ rc=$?
+ return $rc
+}
+
+test_server_ssl_pg_auth() {
+ reconf_bouncer "auth_type = trust" \
+ "server_tls_sslmode = verify-full" \
+ "server_tls_ca_file = TestCA1/ca.crt" \
+ "server_tls_key_file = TestCA1/sites/02-bouncer.key" \
+ "server_tls_cert_file = TestCA1/sites/02-bouncer.crt"
+
+ echo "hostssl all all 127.0.0.1/32 cert" > pgdata/pg_hba.conf
+ reconf_pgsql "ssl=on" "ssl_ca_file='root.crt'"
+ psql_bouncer -q -d p0 -c "select 'ssl-cert-connect'" | tee tmp/test.tmp2
+ grep "ssl-cert-connect" tmp/test.tmp2
+ rc=$?
+ return $rc
+}
+
+test_client_ssl() {
+ reconf_bouncer "auth_type = trust" "server_tls_sslmode = prefer" \
+ "client_tls_sslmode = require" \
+ "client_tls_key_file = TestCA1/sites/01-localhost.key" \
+ "client_tls_cert_file = TestCA1/sites/01-localhost.crt"
+ echo "host all all 127.0.0.1/32 trust" > pgdata/pg_hba.conf
+ reconf_pgsql "ssl=on" "ssl_ca_file='root.crt'"
+ psql_bouncer -q -d "dbname=p0 sslmode=require" -c "select 'client-ssl-connect'" | tee tmp/test.tmp
+ grep -q "client-ssl-connect" tmp/test.tmp
+ rc=$?
+ return $rc
+}
+
+test_client_ssl() {
+ reconf_bouncer "auth_type = trust" "server_tls_sslmode = prefer" \
+ "client_tls_sslmode = require" \
+ "client_tls_key_file = TestCA1/sites/01-localhost.key" \
+ "client_tls_cert_file = TestCA1/sites/01-localhost.crt"
+ echo "host all all 127.0.0.1/32 trust" > pgdata/pg_hba.conf
+ reconf_pgsql "ssl=on" "ssl_ca_file='root.crt'"
+ psql_bouncer -q -d "dbname=p0 sslmode=verify-full sslrootcert=TestCA1/ca.crt" -c "select 'client-ssl-connect'" | tee tmp/test.tmp 2>&1
+ grep -q "client-ssl-connect" tmp/test.tmp
+ rc=$?
+ return $rc
+}
+
+test_client_ssl_auth() {
+ reconf_bouncer "auth_type = cert" "server_tls_sslmode = prefer" \
+ "client_tls_sslmode = verify-full" \
+ "client_tls_ca_file = TestCA1/ca.crt" \
+ "client_tls_key_file = TestCA1/sites/01-localhost.key" \
+ "client_tls_cert_file = TestCA1/sites/01-localhost.crt"
+ echo "host all all 127.0.0.1/32 trust" > pgdata/pg_hba.conf
+ reconf_pgsql "ssl=on" "ssl_ca_file='root.crt'"
+ psql_bouncer -q -d "dbname=p0 sslmode=require sslkey=TestCA1/sites/02-bouncer.key sslcert=TestCA1/sites/02-bouncer.crt" \
+ -c "select 'client-ssl-connect'" | tee tmp/test.tmp 2>&1
+ grep -q "client-ssl-connect" tmp/test.tmp
+ rc=$?
+ return $rc
+}
+
+testlist="
+test_server_ssl
+test_server_ssl_verify
+test_server_ssl_pg_auth
+test_client_ssl
+test_client_ssl_auth
+"
+if [ $# -gt 0 ]; then
+ testlist="$*"
+fi
+
+for test in $testlist
+do
+ runtest $test
+done
+
+complete
+
+# vim: sts=0 sw=8 noet nosmarttab: