diff --git a/tests/Makefile.in b/tests/Makefile.in
index ef98813bec..00e29dbf35 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -18,10 +18,12 @@ SUBDIRS= progs
BUILD_MDB=@BUILD_MDB@
BUILD_SQL=@BUILD_SQL@
+BUILD_BALANCER=@BUILD_BALANCER@
# test primary backends (default)
test tests:
@$(MAKE) mdb
+ @$(MAKE) lloadd
# test all backends
alltests: tests
@@ -48,6 +50,14 @@ ldif test-ldif: FORCE
@echo "Initiating LDAP tests for LDIF..."
@$(RUN) -b ldif all
+lloadd test-lloadd: lloadd-$(BUILD_BALANCER)
+lloadd-no:
+ @echo "run configure with --enable-balancer to run the Load Balancer tests"
+
+lloadd-yes: FORCE
+ @echo "Initiating LDAP tests for the Load Balancer..."
+ @$(RUN) lloadd-all
+
regressions: FORCE
@echo "Testing (available) ITS regressions"
@$(MAKE) mdb-its
diff --git a/tests/data/lloadd-anon.conf b/tests/data/lloadd-anon.conf
new file mode 100644
index 0000000000..4233ac323c
--- /dev/null
+++ b/tests/data/lloadd-anon.conf
@@ -0,0 +1,38 @@
+# Load balancer config -- for testing
+# $OpenLDAP$
+## This work is part of OpenLDAP Software .
+##
+## Copyright 1998-2020 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## .
+
+# allow big PDUs from anonymous (for testing purposes)
+sockbuf_max_incoming 4194303
+
+backend uri=@URI2@
+ numconns=3
+ bindconns=2
+ retry=5000
+ max-pending-ops=5
+ conn-max-pending=3
+
+backend uri=@URI3@
+ numconns=3
+ bindconns=2
+ retry=5000
+ max-pending-ops=5
+ conn-max-pending=3
+
+backend uri=@URI4@
+ numconns=3
+ bindconns=2
+ retry=5000
+ max-pending-ops=5
+ conn-max-pending=3
diff --git a/tests/data/lloadd.conf b/tests/data/lloadd.conf
new file mode 100644
index 0000000000..30f5edf5cd
--- /dev/null
+++ b/tests/data/lloadd.conf
@@ -0,0 +1,49 @@
+# Load balancer config -- for testing
+# $OpenLDAP$
+## This work is part of OpenLDAP Software .
+##
+## Copyright 1998-2020 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## .
+
+# allow big PDUs from anonymous (for testing purposes)
+sockbuf_max_incoming 4194303
+
+feature proxyauthz
+
+backend uri=@URI2@
+ bindmethod=simple
+ binddn="cn=Manager,dc=example,dc=com"
+ credentials=secret
+ numconns=3
+ bindconns=2
+ retry=5000
+ max-pending-ops=5
+ conn-max-pending=3
+
+backend uri=@URI3@
+ bindmethod=simple
+ binddn="cn=Manager,dc=example,dc=com"
+ credentials=secret
+ numconns=3
+ bindconns=2
+ retry=5000
+ max-pending-ops=5
+ conn-max-pending=3
+
+backend uri=@URI4@
+ bindmethod=simple
+ binddn="cn=Manager,dc=example,dc=com"
+ credentials=secret
+ numconns=3
+ bindconns=2
+ retry=5000
+ max-pending-ops=5
+ conn-max-pending=3
diff --git a/tests/scripts/defines.sh b/tests/scripts/defines.sh
index b454f83685..1c76132e2f 100755
--- a/tests/scripts/defines.sh
+++ b/tests/scripts/defines.sh
@@ -151,6 +151,9 @@ VALREGEXCONF=$DATADIR/slapd-valregex.conf
DYNAMICCONF=$DATADIR/slapd-dynamic.ldif
+LLOADDCONF=$DATADIR/lloadd.conf
+LLOADDANONCONF=$DATADIR/lloadd-anon.conf
+
# generated files
CONF1=$TESTDIR/slapd.1.conf
CONF2=$TESTDIR/slapd.2.conf
@@ -196,6 +199,7 @@ CMP="diff -i"
BCMP="diff -iB"
CMPOUT=/dev/null
SLAPD="$TESTWD/../servers/slapd/slapd -s0"
+LLOADD="$TESTWD/../servers/lloadd/lloadd -s0"
LDAPPASSWD="$CLIENTDIR/ldappasswd $TOOLARGS"
LDAPSASLSEARCH="$CLIENTDIR/ldapsearch $SASLARGS $TOOLPROTO $LDAP_TOOLARGS -LLL"
LDAPSASLWHOAMI="$CLIENTDIR/ldapwhoami $SASLARGS $LDAP_TOOLARGS"
diff --git a/tests/scripts/lloadd-all b/tests/scripts/lloadd-all
new file mode 100755
index 0000000000..fae874cfcb
--- /dev/null
+++ b/tests/scripts/lloadd-all
@@ -0,0 +1,102 @@
+#! /bin/sh
+# $OpenLDAP$
+## This work is part of OpenLDAP Software .
+##
+## Copyright 1998-2020 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## .
+
+. $SRCDIR/scripts/defines.sh
+
+TB="" TN=""
+if test -t 1 ; then
+ TB=`$SHTOOL echo -e "%B" 2>/dev/null`
+ TN=`$SHTOOL echo -e "%b" 2>/dev/null`
+fi
+
+FAILCOUNT=0
+SKIPCOUNT=0
+SLEEPTIME=10
+
+echo ">>>>> Executing all LDAP tests for the Load Balancer"
+
+if [ -n "$NOEXIT" ]; then
+ echo "Result Test" > $TESTWD/results
+fi
+
+for CMD in $SRCDIR/scripts/lloadd/test*; do
+ case "$CMD" in
+ *~) continue;;
+ *.bak) continue;;
+ *.orig) continue;;
+ *.sav) continue;;
+ *) test -f "$CMD" || continue;;
+ esac
+
+ # remove cruft from prior test
+ if test $PRESERVE = yes ; then
+ /bin/rm -rf $TESTDIR/db.*
+ else
+ /bin/rm -rf $TESTDIR
+ fi
+ if test $BACKEND = ndb ; then
+ mysql --user root <>>>> Starting ${TB}$BCMD${TN} for $BACKEND..."
+ $CMD
+ RC=$?
+ if test $RC -eq 0 ; then
+ echo ">>>>> $BCMD completed ${TB}OK${TN} for $BACKEND."
+ else
+ echo ">>>>> $BCMD ${TB}failed${TN} for $BACKEND"
+ FAILCOUNT=`expr $FAILCOUNT + 1`
+
+ if [ -n "$NOEXIT" ]; then
+ echo "Continuing."
+ else
+ echo "(exit $RC)"
+ exit $RC
+ fi
+ fi
+ else
+ echo ">>>>> Skipping ${TB}$BCMD${TN} for $BACKEND."
+ SKIPCOUNT=`expr $SKIPCOUNT + 1`
+ RC="-"
+ fi
+
+ if [ -n "$NOEXIT" ]; then
+ echo "$RC $BCMD" >> $TESTWD/results
+ fi
+
+# echo ">>>>> waiting $SLEEPTIME seconds for things to exit"
+# sleep $SLEEPTIME
+ echo ""
+done
+
+if [ -n "$NOEXIT" ]; then
+ if [ "$FAILCOUNT" -gt 0 ]; then
+ cat $TESTWD/results
+ echo "$FAILCOUNT tests for $BACKEND ${TB}failed${TN}. Please review the test log."
+ else
+ echo "All executed tests for $BACKEND ${TB}succeeded${TN}."
+ fi
+fi
+
+echo "$SKIPCOUNT tests for the Load Balancer were ${TB}skipped${TN}."
diff --git a/tests/scripts/lloadd/test000-rootdse b/tests/scripts/lloadd/test000-rootdse
new file mode 100755
index 0000000000..a92f315501
--- /dev/null
+++ b/tests/scripts/lloadd/test000-rootdse
@@ -0,0 +1,109 @@
+#! /bin/sh
+# $OpenLDAP$
+## This work is part of OpenLDAP Software .
+##
+## Copyright 1998-2020 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## .
+
+echo "running defines.sh"
+. $SRCDIR/scripts/defines.sh
+
+mkdir -p $TESTDIR $DBDIR1
+
+echo "Starting slapd on TCP/IP port $PORT2..."
+. $CONFFILTER $BACKEND < $SCHEMACONF > $CONF2
+$SLAPD -f $CONF2 -h $URI2 -d $LVL > $LOG2 2>&1 &
+PID=$!
+if test $WAIT != 0 ; then
+ echo PID $PID
+ read foo
+fi
+KILLPIDS="$PID"
+
+echo "Starting a second slapd on TCP/IP port $PORT3..."
+. $CONFFILTER $BACKEND < $SCHEMACONF > $CONF3
+$SLAPD -f $CONF3 -h $URI3 -d $LVL > $LOG3 2>&1 &
+PID=$!
+if test $WAIT != 0 ; then
+ echo PID $PID
+ read foo
+fi
+KILLPIDS="$KILLPIDS $PID"
+
+echo "Starting a third slapd on TCP/IP port $PORT4..."
+. $CONFFILTER $BACKEND < $SCHEMACONF > $CONF4
+$SLAPD -f $CONF4 -h $URI4 -d $LVL > $LOG4 2>&1 &
+PID=$!
+if test $WAIT != 0 ; then
+ echo PID $PID
+ read foo
+fi
+KILLPIDS="$KILLPIDS $PID"
+
+echo "Starting lloadd on TCP/IP port $PORT1..."
+. $CONFFILTER $BACKEND < $LLOADDANONCONF > $CONF1
+$LLOADD -f $CONF1 -h $URI1 -d $LVL > $LOG1 2>&1 &
+PID=$!
+if test $WAIT != 0 ; then
+ echo PID $PID
+ read foo
+fi
+KILLPIDS="$KILLPIDS $PID"
+
+sleep $SLEEP0
+
+echo "Using ldapsearch to retrieve the root DSE..."
+for i in 0 1 2 3 4 5; do
+ $LDAPSEARCH -b "" -s base -H $URI1 \
+ '@extensibleObject' > $SEARCHOUT 2>&1
+ RC=$?
+ if test $RC = 0 ; then
+ break
+ fi
+ echo "Waiting $SLEEP1 seconds for lloadd to start..."
+ sleep $SLEEP1
+done
+
+if test $RC = 0 ; then
+ echo "Using ldapsearch to retrieve the cn=Subschema..."
+ $LDAPSEARCH -b "cn=Subschema" -s base -H $URI1 \
+ '(&(objectClasses=top)(objectClasses=2.5.6.0))' cn objectClass \
+ >> $SEARCHOUT 2>&1
+ RC=$?
+
+fi
+
+if test $RC = 0 ; then
+ echo "Using ldapsearch to retrieve the cn=Monitor..."
+ $LDAPSEARCH -b "cn=Monitor" -s base -H $URI1 \
+ '@monitor' >> $SEARCHOUT 2>&1
+ RC=$?
+fi
+
+test $KILLSERVERS != no && kill -HUP $KILLPIDS
+
+count=3
+if test $RC != 0 ; then
+ echo ">>>>> Test failed"
+else
+ RC=`grep '^dn:' $SEARCHOUT | wc -l`
+ if test $RC != $count ; then
+ echo ">>>>> Test failed: expected $count entries, got" $RC
+ RC=1
+ else
+ echo ">>>>> Test succeeded"
+ RC=0
+ fi
+fi
+
+test $KILLSERVERS != no && wait
+
+exit $RC