Home | History | Annotate | Line # | Download | only in lloadd
      1 #! /bin/sh
      2 # $OpenLDAP$
      3 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
      4 ##
      5 ## Copyright 1998-2024 The OpenLDAP Foundation.
      6 ## All rights reserved.
      7 ##
      8 ## Redistribution and use in source and binary forms, with or without
      9 ## modification, are permitted only as authorized by the OpenLDAP
     10 ## Public License.
     11 ##
     12 ## A copy of this license is available in the file LICENSE in the
     13 ## top-level directory of the distribution or, alternatively, at
     14 ## <http://www.OpenLDAP.org/license.html>.
     15 
     16 echo "running defines.sh"
     17 . $SRCDIR/scripts/defines.sh
     18 
     19 mkdir -p $TESTDIR $DBDIR1 $DBDIR2
     20 
     21 $SLAPPASSWD -g -n >$CONFIGPWF
     22 echo "rootpw `$SLAPPASSWD -T $CONFIGPWF`" >$TESTDIR/configpw.conf
     23 
     24 # Cannot assess where operations went without monitor yet
     25 if test $AC_lloadd = lloaddyes ; then
     26 	echo "Load balancer module not available, skipping..."
     27 	exit 0
     28 fi
     29 
     30 # Monitor counts are unstable in the face of concurrency, since different
     31 # clients may get different upstreams assigned for their operations.
     32 # Another constraint is that some global counts are updated by the statistics
     33 # collection task scheduled to run every second.
     34 #
     35 # This test assumes current round-robin policy:
     36 # - default backend is rotated every time we successfully pick an upstream
     37 #   (except when already linked)
     38 # - upstream connections within the same backend are rotated in the same way
     39 # - the monitor entry order for upstream connections reflects the connection
     40 #   order within its CIRCLEQ_
     41 
     42 echo "Starting the first slapd on TCP/IP port $PORT2..."
     43 . $CONFFILTER $BACKEND < $CONF > $CONF2
     44 $SLAPADD -f $CONF2 -l $LDIFORDERED
     45 RC=$?
     46 if test $RC != 0 ; then
     47 	echo "slapadd failed ($RC)!"
     48 	exit $RC
     49 fi
     50 
     51 echo "Running slapindex to index slapd database..."
     52 $SLAPINDEX -f $CONF2
     53 RC=$?
     54 if test $RC != 0 ; then
     55 	echo "warning: slapindex failed ($RC)"
     56 	echo "  assuming no indexing support"
     57 fi
     58 
     59 $SLAPD -f $CONF2 -h $URI2 -d $LVL > $LOG2 2>&1 &
     60 PID=$!
     61 if test $WAIT != 0 ; then
     62 	echo PID $PID
     63 	read foo
     64 fi
     65 PID2="$PID"
     66 KILLPIDS="$PID"
     67 
     68 echo "Testing slapd searching..."
     69 for i in 0 1 2 3 4 5; do
     70 	$LDAPSEARCH -s base -b "$MONITOR" -H $URI2 \
     71 		'(objectclass=*)' > /dev/null 2>&1
     72 	RC=$?
     73 	if test $RC = 0 ; then
     74 		break
     75 	fi
     76 	echo "Waiting $SLEEP1 seconds for slapd to start..."
     77 	sleep $SLEEP1
     78 done
     79 if test $RC != 0 ; then
     80 	echo "ldapsearch failed ($RC)!"
     81 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
     82 	exit $RC
     83 fi
     84 
     85 echo "Running slapadd to build slapd database..."
     86 . $CONFFILTER $BACKEND < $CONFTWO > $CONF3
     87 $SLAPADD -f $CONF3 -l $LDIFORDERED
     88 RC=$?
     89 if test $RC != 0 ; then
     90 	echo "slapadd failed ($RC)!"
     91 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
     92 	exit $RC
     93 fi
     94 
     95 echo "Running slapindex to index slapd database..."
     96 $SLAPINDEX -f $CONF3
     97 RC=$?
     98 if test $RC != 0 ; then
     99 	echo "warning: slapindex failed ($RC)"
    100 	echo "  assuming no indexing support"
    101 fi
    102 
    103 echo "Starting second slapd on TCP/IP port $PORT3..."
    104 $SLAPD -f $CONF3 -h $URI3 -d $LVL > $LOG3 2>&1 &
    105 PID=$!
    106 if test $WAIT != 0 ; then
    107 	echo PID $PID
    108 	read foo
    109 fi
    110 PID3="$PID"
    111 KILLPIDS="$KILLPIDS $PID"
    112 
    113 sleep $SLEEP0
    114 
    115 echo "Testing slapd searching..."
    116 for i in 0 1 2 3 4 5; do
    117 	$LDAPSEARCH -s base -b "$MONITOR" -H $URI3 \
    118 		'(objectclass=*)' > /dev/null 2>&1
    119 	RC=$?
    120 	if test $RC = 0 ; then
    121 		break
    122 	fi
    123 	echo "Waiting $SLEEP1 seconds for slapd to start..."
    124 	sleep $SLEEP1
    125 done
    126 if test $RC != 0 ; then
    127 	echo "ldapsearch failed ($RC)!"
    128 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    129 	exit $RC
    130 fi
    131 
    132 echo "Starting lloadd on TCP/IP port $PORT1..."
    133 . $CONFFILTER $BACKEND < $LLOADDEMPTYCONF > $CONF1.lloadd
    134 . $CONFFILTER $BACKEND < $SLAPDLLOADCONF > $CONF1.slapd
    135 $SLAPD -f $CONF1.slapd -h $URI6 -d $LVL > $LOG1 2>&1 &
    136 PID=$!
    137 if test $WAIT != 0 ; then
    138 	echo PID $PID
    139 	read foo
    140 fi
    141 KILLPIDS="$KILLPIDS $PID"
    142 
    143 echo "Testing slapd searching..."
    144 for i in 0 1 2 3 4 5; do
    145 	$LDAPSEARCH -s base -b "$MONITOR" -H $URI6 \
    146 		'(objectclass=*)' > /dev/null 2>&1
    147 	RC=$?
    148 	if test $RC = 0 ; then
    149 		break
    150 	fi
    151 	echo "Waiting $SLEEP1 seconds for lloadd to start..."
    152 	sleep $SLEEP1
    153 done
    154 
    155 if test $RC != 0 ; then
    156 	echo "ldapsearch failed ($RC)!"
    157 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    158 	exit $RC
    159 fi
    160 
    161 echo "Setting up restrictions..."
    162 $LDAPMODIFY -D cn=config -H $URI6 -y $CONFIGPWF <<EOF >> $TESTOUT 2>&1
    163 dn: olcBackend={0}lload,cn=config
    164 changetype: modify
    165 replace: olcBkLloadWriteCoherence
    166 olcBkLloadWriteCoherence: 3
    167 -
    168 add: olcBkLloadRestrictExop
    169 # Modify Password Exop
    170 olcBkLloadRestrictExop: 1.3.6.1.4.1.4203.1.11.1 write
    171 # LDAP Transaction Exop
    172 olcBkLloadRestrictExop: 1.3.6.1.1.21.1 connection
    173 # Cancel Exop
    174 olcBkLloadRestrictExop: 1.3.6.1.1.8 reject
    175 -
    176 add: olcBkLloadRestrictControl
    177 # assert control
    178 olcBkLloadRestrictControl: 1.3.6.1.1.12 backend
    179 # paged results control
    180 olcBkLloadRestrictControl: 1.2.840.113556.1.4.319 connection
    181 # dontUseCopy control
    182 olcBkLloadRestrictControl: 1.3.6.1.1.22 reject
    183 EOF
    184 RC=$?
    185 if test $RC != 0 ; then
    186 	echo "ldapmodify failed for backend ($RC)!"
    187 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    188 	exit $RC
    189 fi
    190 
    191 if test $RC != 0 ; then
    192 	echo "ldapsearch failed ($RC)!"
    193 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    194 	exit $RC
    195 fi
    196 
    197 echo "Sending a search request to prime the counters..."
    198 $LDAPSEARCH -b "$BASEDN" -s base -H $URI1 >> $TESTOUT 2>&1
    199 RC=$?
    200 if test $RC != 52 ; then
    201 	echo "ldapsearch should have failed ($RC != 52)!"
    202 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    203 	exit $RC
    204 fi
    205 
    206 echo "Adding first tier..."
    207 $LDAPMODIFY -D cn=config -H $URI6 -y $CONFIGPWF <<EOF >> $TESTOUT 2>&1
    208 dn: cn=first,olcBackend={0}lload,cn=config
    209 changetype: add
    210 objectClass: olcBkLloadTierConfig
    211 olcBkLloadTierType: roundrobin
    212 EOF
    213 RC=$?
    214 if test $RC != 0 ; then
    215 	echo "ldapadd failed for backend ($RC)!"
    216 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    217 	exit $RC
    218 fi
    219 
    220 echo "Adding first backend server..."
    221 $LDAPMODIFY -D cn=config -H $URI6 -y $CONFIGPWF <<EOF >> $TESTOUT 2>&1
    222 dn: cn=backend,cn={0}first,olcBackend={0}lload,cn=config
    223 changetype: add
    224 objectClass: olcBkLloadBackendConfig
    225 olcBkLloadBackendUri: $URI2
    226 olcBkLloadMaxPendingConns: 3
    227 olcBkLloadMaxPendingOps: 5
    228 olcBkLloadRetry: 1000
    229 olcBkLloadNumconns: 2
    230 olcBkLloadBindconns: 2
    231 EOF
    232 RC=$?
    233 if test $RC != 0 ; then
    234 	echo "ldapadd failed for backend ($RC)!"
    235 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    236 	exit $RC
    237 fi
    238 
    239 # At the moment, the global counters are updated by a recurring job,
    240 # wait for it to settle
    241 echo "Waiting until connections are established..."
    242 for i in 0 1 2 3 4 5; do
    243 	$LDAPCOMPARE "cn=Load Balancer,cn=Backends,cn=monitor" -H $URI6 \
    244 		'olmOutgoingConnections:4' > /dev/null 2>&1
    245 	RC=$?
    246 	if test $RC = 6 ; then
    247 		break
    248 	fi
    249 	echo "Waiting $SLEEP1 seconds until connections are established..."
    250 	sleep $SLEEP1
    251 done
    252 if test $RC != 6 ; then
    253 	echo "ldapcompare failed ($RC)!"
    254 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    255 	exit $RC
    256 fi
    257 
    258 echo "Retrieving data from cn=monitor..."
    259 echo "# Retrieving data from lload's cn=monitor..." >>$SEARCHOUT
    260 echo "# Operations received:" >>$SEARCHOUT
    261 echo "#	 Bind: 1 (0 forwarded)" >>$SEARCHOUT
    262 echo "#	 Unbind: 1" >>$SEARCHOUT
    263 $LDAPSEARCH -b "cn=Load Balancer,cn=Backends,cn=monitor" -H $URI6 \
    264 	olmBalancer olmBalancerServer olmBalancerOperation olmBalancerConnection >> $SEARCHOUT 2>&1
    265 RC=$?
    266 if test $RC != 0 ; then
    267 	echo "ldapsearch failed ($RC)!"
    268 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    269 	exit $RC
    270 fi
    271 
    272 echo "Adding another backend server..."
    273 $LDAPMODIFY -D cn=config -H $URI6 -y $CONFIGPWF <<EOF >> $TESTOUT 2>&1
    274 dn: cn=server 2,cn={0}first,olcBackend={0}lload,cn=config
    275 changetype: add
    276 objectClass: olcBkLloadBackendConfig
    277 olcBkLloadBackendUri: $URI3
    278 olcBkLloadMaxPendingConns: 3
    279 olcBkLloadMaxPendingOps: 5
    280 olcBkLloadRetry: 1000
    281 olcBkLloadNumconns: 4
    282 olcBkLloadBindconns: 5
    283 EOF
    284 RC=$?
    285 if test $RC != 0 ; then
    286 	echo "ldapadd failed for backend ($RC)!"
    287 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    288 	exit $RC
    289 fi
    290 
    291 # At the moment, the global counters are updated by a recurring job,
    292 # wait for it to settle
    293 echo "Waiting until connections are established..."
    294 for i in 0 1 2 3 4 5; do
    295 	$LDAPCOMPARE "cn=Load Balancer,cn=Backends,cn=monitor" -H $URI6 \
    296 		'olmOutgoingConnections:13' > /dev/null 2>&1
    297 	RC=$?
    298 	if test $RC = 6 ; then
    299 		break
    300 	fi
    301 	echo "Waiting $SLEEP1 seconds until connections are established..."
    302 	sleep $SLEEP1
    303 done
    304 if test $RC != 6 ; then
    305 	echo "ldapcompare failed ($RC)!"
    306 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    307 	exit $RC
    308 fi
    309 
    310 echo "Sending a search request with dontUseCopy (fails with Unwilling to Perform)..."
    311 $LDAPSEARCH -b "$BASEDN" -s base -H $URI1 -E '!dontUseCopy' >> $TESTOUT 2>&1
    312 RC=$?
    313 if test $RC != 53 ; then
    314 	echo "ldapsearch should have failed ($RC != 53)!"
    315 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    316 	exit $RC
    317 fi
    318 
    319 echo "Sending a search request with paged results=1 (19 requests forwarded over the same connection)..."
    320 $LDAPSEARCH -b "$BASEDN" -H $URI1 -E '!pr=1/noprompt' >> $TESTOUT 2>&1
    321 RC=$?
    322 if test $RC != 0 ; then
    323 	echo "ldapsearch failed ($RC)!"
    324 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    325 	exit $RC
    326 fi
    327 
    328 echo "Sending a passmod request..."
    329 $LDAPPASSWD -H $URI1 -D "$MANAGERDN" -w $PASSWD \
    330 	-s bjensen2 "$BABSDN" >> $TESTOUT 2>&1
    331 RC=$?
    332 if test $RC != 0 ; then
    333 	echo "ldappasswd failed ($RC)!"
    334 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    335 	exit $RC
    336 fi
    337 
    338 # At the moment, the global counters are updated by a recurring job,
    339 # wait for it to settle
    340 echo "Waiting until global counters are updated..."
    341 for i in 0 1 2 3 4 5; do
    342 	$LDAPCOMPARE "cn=Other,cn=Operations,cn=Load Balancer,cn=Backends,cn=monitor" -H $URI6 \
    343 		'olmCompletedOps:20' > /dev/null 2>&1
    344 	RC=$?
    345 	if test $RC = 6 ; then
    346 		break
    347 	fi
    348 	echo "Waiting $SLEEP1 seconds until counters are updated..."
    349 	sleep $SLEEP1
    350 done
    351 if test $RC != 6 ; then
    352 	echo "ldapcompare failed ($RC)!"
    353 	echo >>$SEARCHOUT
    354 	$LDAPSEARCH -b "cn=Load Balancer,cn=Backends,cn=monitor" -H $URI6 \
    355 		olmBalancer olmBalancerServer olmBalancerOperation olmBalancerConnection >> $SEARCHOUT 2>&1
    356 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    357 	exit $RC
    358 fi
    359 
    360 echo "Retrieving data from cn=monitor again..."
    361 echo >>$SEARCHOUT
    362 echo "# Retrieving data after recent ops..." >>$SEARCHOUT
    363 echo "# Operations now received:" >>$SEARCHOUT
    364 echo "#	 Bind: +3 (+3 forwarded)" >>$SEARCHOUT
    365 echo "#	 Search: +20" >>$SEARCHOUT
    366 echo "#	 Extended: +1 (Password modify)" >>$SEARCHOUT
    367 echo "#	 Unbind: +3" >>$SEARCHOUT
    368 $LDAPSEARCH -b "cn=Load Balancer,cn=Backends,cn=monitor" -H $URI6 \
    369 	olmBalancer olmBalancerServer olmBalancerOperation olmBalancerConnection >> $SEARCHOUT 2>&1
    370 RC=$?
    371 if test $RC != 0 ; then
    372 	echo "ldapsearch failed ($RC)!"
    373 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    374 	exit $RC
    375 fi
    376 
    377 echo "Sending a few writes (some of them will stick to the same backend)..."
    378 {
    379 cat <<EOMOD
    380 dn: $BABSDN
    381 changetype: modify
    382 replace: description
    383 description: changed
    384 
    385 dn: $BJORNSDN
    386 changetype: modify
    387 replace: description
    388 description: changed too
    389 
    390 EOMOD
    391 # If we had full control over the connection, we'd know when the last operation
    392 # finished and so when the grace period ends. We only write to a pipe, just
    393 # have to wait a bit longer than necessary...
    394 sleep 5
    395 cat <<EOMOD
    396 dn: $JAJDN
    397 changetype: modify
    398 replace: description
    399 description: modified
    400 
    401 EOMOD
    402 } | \
    403 $LDAPMODIFY -D "$MANAGERDN" -w $PASSWD -H $URI1 >> $TESTOUT 2>&1
    404 RC=$?
    405 if test $RC != 0 ; then
    406 	echo "ldapmodify failed ($RC)!"
    407 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    408 	exit $RC
    409 fi
    410 
    411 echo "Sending a few writes within a TXN..."
    412 {
    413 cat <<EOMOD
    414 dn: $BABSDN
    415 changetype: modify
    416 replace: description
    417 description: changed
    418 
    419 dn: $BJORNSDN
    420 changetype: modify
    421 replace: description
    422 description: changed too
    423 
    424 EOMOD
    425 sleep 4
    426 cat <<EOMOD
    427 dn: $JAJDN
    428 changetype: modify
    429 replace: description
    430 description: modified
    431 
    432 EOMOD
    433 } | \
    434 $LDAPMODIFY -D "$MANAGERDN" -w $PASSWD -H $URI1 \
    435 	-e assert='(objectclass=*)' -E txn=abort >> $TESTOUT 2>&1
    436 RC=$?
    437 if test $RC != 0 ; then
    438 	echo "ldapmodify failed ($RC)!"
    439 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    440 	exit $RC
    441 fi
    442 
    443 # At the moment, the global counters are updated by a recurring job,
    444 # wait for it to settle
    445 echo "Waiting until global counters are updated..."
    446 for i in 0 1 2 3 4 5; do
    447 	$LDAPCOMPARE "cn=Other,cn=Operations,cn=Load Balancer,cn=Backends,cn=monitor" -H $URI6 \
    448 		'olmCompletedOps:28' > /dev/null 2>&1
    449 	RC=$?
    450 	if test $RC = 6 ; then
    451 		break
    452 	fi
    453 	echo "Waiting $SLEEP1 seconds until counters are updated..."
    454 	sleep $SLEEP1
    455 done
    456 if test $RC != 6 ; then
    457 	echo "ldapcompare failed ($RC)!"
    458 	echo >>$SEARCHOUT
    459 	$LDAPSEARCH -b "cn=Load Balancer,cn=Backends,cn=monitor" -H $URI6 \
    460 		olmBalancer olmBalancerServer olmBalancerOperation olmBalancerConnection >> $SEARCHOUT 2>&1
    461 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    462 	exit $RC
    463 fi
    464 
    465 echo "Retrieving data from cn=monitor again..."
    466 echo >>$SEARCHOUT
    467 echo "# Retrieving data after recent writes..." >>$SEARCHOUT
    468 echo "# Operations received:" >>$SEARCHOUT
    469 echo "#	 Bind: +2 (+2 forwarded)" >>$SEARCHOUT
    470 echo "#	 Modify: +6" >>$SEARCHOUT
    471 echo "#	 Extended: +2 (TXN+TXN Abort)" >>$SEARCHOUT
    472 echo "#	 Unbind: +2" >>$SEARCHOUT
    473 $LDAPSEARCH -b "cn=Load Balancer,cn=Backends,cn=monitor" -H $URI6 \
    474 	olmBalancer olmBalancerServer olmBalancerOperation olmBalancerConnection >> $SEARCHOUT 2>&1
    475 RC=$?
    476 if test $RC != 0 ; then
    477 	echo "ldapsearch failed ($RC)!"
    478 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
    479 	exit $RC
    480 fi
    481 
    482 test $KILLSERVERS != no && kill -HUP $KILLPIDS
    483 
    484 LDIF=$DATADIR/lloadd/test007-monitor.ldif
    485 
    486 echo "Filtering ldapsearch results..."
    487 # For now, we don't make sure olmIncomingConnections is reflective of current
    488 # state (=no connections open) since olmIncomingConnections can be != 0 for a
    489 # second after it's closed
    490 $LDIFFILTER < $SEARCHOUT | grep -v '^olmIncomingConnections:' > $SEARCHFLT
    491 echo "Filtering original ldif used to create database..."
    492 $LDIFFILTER < $LDIF | sed \
    493     -e "s|@URI2@|$URI2|g" \
    494     -e "s|@URI3@|$URI3|g" \
    495     > $LDIFFLT
    496 echo "Comparing filter output..."
    497 $CMP $SEARCHFLT $LDIFFLT > $CMPOUT
    498 
    499 if test $? != 0 ; then
    500 	echo "Comparison failed"
    501 	exit 1
    502 fi
    503 
    504 echo ">>>>> Test succeeded"
    505 
    506 test $KILLSERVERS != no && wait
    507 
    508 exit 0
    509