#! /bin/sh
# $OpenLDAP$
## This work is part of OpenLDAP Software .
##
## Copyright 1998-2017 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
if test $SYNCPROV = syncprovno; then
echo "Syncrepl provider overlay not available, test skipped"
exit 0
fi
if test $ACCESSLOG = accesslogno; then
echo "Accesslog overlay not available, test skipped"
exit 0
fi
if test $BACKEND = ldif ; then
echo "$BACKEND backend unsuitable, test skipped"
exit 0
fi
dtest=`date +%N|sed s/...$//`
if test $dtest = N; then
echo "nanosecond date values not supported, test skipped"
exit 0
fi
echo "This test tracks a case where slapd deadlocks during a significant write load"
echo "See http://www.openldap.org/its/index.cgi/?findid=8752 for more information."
MMR=4
XDIR=$TESTDIR/srv
mkdir -p $TESTDIR
ITS=8752
ITSDIR=$DATADIR/regressions/its$ITS
n=1
while [ $n -le $MMR ]; do
DBDIR=${XDIR}$n/db
mkdir -p ${XDIR}$n $DBDIR.1 $DBDIR.2
n=`expr $n + 1`
done
KILLPIDS=
echo "Starting slapd on TCP/IP port $PORT1..."
. $CONFFILTER $BACKEND $MONITORDB < $ITSDIR/slapd.conf > $CONF1
$SLAPD -f $CONF1 -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 &
PID=$!
if test $WAIT != 0 ; then
echo PID $PID
read foo
fi
KILLPIDS="$PID"
sleep 1
echo "Using ldapsearch to check that slapd is running..."
for i in 0 1 2 3 4 5; do
$LDAPSEARCH -s base -b "$MONITOR" -h $LOCALHOST -p $PORT1 \
'objectclass=*' > /dev/null 2>&1
RC=$?
if test $RC = 0 ; then
break
fi
echo "Waiting 5 seconds for slapd to start..."
sleep 5
done
if test $RC != 0 ; then
echo "ldapsearch failed ($RC)!"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit $RC
fi
echo "Populating database on first provider..."
$LDAPADD -D $MANAGERDN -H $URI1 -w $PASSWD << EOMODS >> $TESTOUT 2>&1
dn: $BASEDN
objectClass: organization
objectClass: dcObject
o: Example, Inc.
dc: example
dn: ou=People,$BASEDN
objectClass: organizationalUnit
ou: People
dn: ou=Groups,$BASEDN
objectClass: organizationalUnit
ou: Groups
dn: cn=Roger Rabbit,ou=People,$BASEDN
objectClass: inetOrgPerson
cn: Roger Rabbit
sn: Rabbit
dn: cn=Baby Herman,ou=People,$BASEDN
objectClass: inetOrgPerson
cn: Baby Herman
sn: Herman
dn: cn=Jessica_Rabbit,ou=People,$BASEDN
objectClass: inetOrgPerson
cn: Jessica_Rabbit
sn: Rabbit
dn: cn=Bugs_Bunny,ou=People,$BASEDN
objectClass: inetOrgPerson
cn: Bugs_Bunny
sn: Bunny
dn: cn=Daffy_Duck,ou=People,$BASEDN
objectClass: inetOrgPerson
cn: Daffy_Duck
sn: Duck
dn: cn=Elmer_Fudd,ou=People,$BASEDN
objectClass: inetOrgPerson
cn: Elmer_Fudd
sn: Fudd
dn: cn=Cartoonia,ou=Groups,$BASEDN
objectClass: groupOfNames
cn: Cartoonia
member: cn=Roger Rabbit,ou=People,$BASEDN
member: cn=Baby Herman,ou=People,$BASEDN
EOMODS
RC=$?
if test $RC != 0 ; then
echo "ldapadd failed ($RC)!"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit $RC
fi
echo "Stopping slapd and reworking configuration for MMR..."
test $KILLSERVERS != no && kill -HUP $KILLPIDS
KILLPIDS=
n=1
while [ $n -le $MMR ]; do
MYURI=`eval echo '$URI'$n`
MYLOG=`eval echo '$LOG'$n`
MYCONF=`eval echo '$CONF'$n`
echo "Starting provider slapd on TCP/IP URI $MYURI"
. $CONFFILTER $BACKEND $MONITORDB < $ITSDIR/slapd.conf.mmr > $CONF
sed -e "s/MMR/$n/g" $CONF > $MYCONF
j=1
while [ $j -le $MMR ]; do
MMCURI=`eval echo '$URI'$j`
sed -e "s|MMC${j}|${MMCURI}|" $MYCONF > $CONF
mv $CONF $MYCONF
j=`expr $j + 1`
done
if [ -f $CONF ]; then
rm -f $CONF
fi
$SLAPD -f $MYCONF -h $MYURI -d $LVL $TIMING > $MYLOG 2>&1 &
PID=$!
if test $WAIT != 0 ; then
echo PID $PID
read foo
fi
KILLPIDS="$PID $KILLPIDS"
sleep 1
echo "Using ldapsearch to check that provider slapd is running..."
for i in 0 1 2 3 4 5; do
$LDAPSEARCH -s base -b "" -H $MYURI \
'objectclass=*' > /dev/null 2>&1
RC=$?
if test $RC = 0 ; then
break
fi
echo "Waiting 5 seconds for slapd to start..."
sleep 5
done
if test $RC != 0 ; then
echo "ldapsearch failed ($RC)!"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit $RC
fi
n=`expr $n + 1`
done
echo "Setting up accesslog on each master..."
n=1
while [ $n -le $MMR ]; do
echo "Modifying dn: cn=Elmer_Fudd,ou=People,dc=example,dc=com on master $n"
MYURI=`eval echo '$URI'$n`
$LDAPMODIFY -v -D "$MANAGERDN" -H $MYURI -w $PASSWD > \
$TESTOUT 2>&1 << EOMODS
dn: cn=Elmer_Fudd,ou=People,$BASEDN
changetype: modify
replace: sn
sn: Fudd
EOMODS
sleep 5
n=`expr $n + 1`
done
echo "Sleeping 30 seconds to ensure replication is reconciled between all nodes"
echo "The next step of the test will perform 20000 random write operations and may take some time."
echo "As this test is for a deadlock, it will take manual intervention to exit the test if one occurs."
sleep 30
echo "Starting random master/entry modifications..."
DN1="cn=Elmer_Fudd,ou=People,$BASEDN"
VAL1="Fudd"
DN2="cn=Jessica_Rabbit,ou=People,$BASEDN"
VAL2="Rabbit"
DN3="cn=Bugs_Bunny,ou=People,$BASEDN"
VAL3="Bunny"
DN4="cn=Daffy_Duck,ou=People,$BASEDN"
VAL4="Duck"
n=1
while [ $n -le 20000 ]; do
seed=`date +%N|sed s/...$//`
rvalue=`echo|awk "BEGIN {srand($seed)
{print int(1+rand()*4)}}"`
MYURI=`eval echo '$URI'$rvalue`
seed=`date +%N|sed s/...$//`
rvalue=`echo|awk "BEGIN {srand($seed)
{print int(1+rand()*4)}}"`
MYDN=`eval echo '$DN'$rvalue`
MYVAL=`eval echo '$VAL'$rvalue`
echo "Modifying $MYURI entry $MYDN with value $MYVAL iteration $n of 20000"
$LDAPMODIFY -v -D "$MANAGERDN" -H $MYURI -w $PASSWD > \
$TESTOUT 2>&1 << EOMODS
dn: $MYDN
changetype: modify
replace: sn
sn: $MYVAL
EOMODS
n=`expr $n + 1`
done
test $KILLSERVERS != no && kill -HUP $KILLPIDS
echo ">>>>> Test succeeded"
test $KILLSERVERS != no && wait
exit 0