Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4525309
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
26 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/test/booth_path b/test/booth_path
index 6ea1402..db4ab26 100755
--- a/test/booth_path
+++ b/test/booth_path
@@ -1,35 +1,35 @@
#!/bin/sh
#
-# manage iptables rules for port 6666
+# manage iptables rules for the given port
#
[ $# -lt 1 ] && exit
action=$1
-port=6666
+port=${2:-9929}
testip() {
local chain=$1
iptables -L $chain | grep -wq ^DROP.*$port
}
logcmd() {
logger -p local7.info "$*"
eval $*
}
case "$action" in
start)
logcmd iptables -D INPUT -p udp --dport $port -j DROP
logcmd iptables -D OUTPUT -p udp --dport $port -j DROP
logcmd iptables -D INPUT -p udp --sport $port -j DROP
logcmd iptables -D OUTPUT -p udp --sport $port -j DROP
;;
stop)
testip INPUT && {
echo "packets from/to $port already being dropped!"
exit
}
logcmd iptables -A INPUT -p udp --dport $port -j DROP
logcmd iptables -A OUTPUT -p udp --dport $port -j DROP
logcmd iptables -A INPUT -p udp --sport $port -j DROP
logcmd iptables -A OUTPUT -p udp --sport $port -j DROP
;;
esac
diff --git a/test/live_test.sh b/test/live_test.sh
index b16ca12..97a841e 100755
--- a/test/live_test.sh
+++ b/test/live_test.sh
@@ -1,856 +1,862 @@
#!/bin/sh
#
# see README-testing for more information
# do some basic booth operation tests for the given config
#
PROG=`basename $0`
usage() {
cat<<EOF
usage:
[NETEM_ENV=<envfun>[:<val>]] $PROG <booth.conf> [<test> ...]
EOF
if [ $1 -eq 0 ]; then
list_all
examples
fi
exit
}
list_all() {
echo "Tests:"
grep "^test_.*{$" $0 | sed 's/test_//;s/(.*//;s/^/ /'
echo
echo "Netem functions:"
grep "^NETEM_ENV_.*{$" $0 | sed 's/NETEM_ENV_//;s/(.*//;s/^/ /'
}
examples() {
cat<<EOF
Examples:
$0 booth.conf
$0 booth-5node.conf grant revoke
NETEM_ENV=net_delay:150 $0 mybooth.conf
EOF
}
[ $# -eq 0 ] && usage 0
cnf=$1
shift 1
logf=test_booth.log
iprules=/usr/share/booth/tests/test/booth_path
: ${HA_LOGFACILITY:="syslog"}
logmsg() {
logger -t "BOOTHTEST" -p $HA_LOGFACILITY.info "$@"
}
ext_prog_log() {
local cmd="$@"
echo "run: $cmd" >&2
logmsg "$cmd"
$cmd
}
get_stat_fld() {
local fld=$1
sed "s/.* $fld=//;s/ .*//;s/'//g"
}
# tc netem, simulate packet loss, wan, etc
netem_delay() {
ext_prog_log tc qdisc add dev $1 root netem delay $2ms $(($2/10))ms
}
netem_loss() {
ext_prog_log tc qdisc add dev $1 root netem loss $2%
}
netem_reset() {
ext_prog_log tc qdisc del dev $1 root netem
}
local_netem_env() {
local fun=$1 arg=$2
local t netif=""
local my_addr
my_addr=`booth status | get_stat_fld booth_addr_string`
if [ -z "$my_addr" ]; then
echo "cannot find my address, booth running?" >&2
return 1
fi
for t in `ip link | grep '^[1-9]:' | sed 's/.: //;s/: .*//'`
do
if ip a l $t | fgrep -wq $my_addr; then
netif=$t
break
fi
done
if [ -n "$netif" ]; then
$fun $netif $arg
else
echo "cannot find netif for $my_addr, netem not set" >&2
fi
}
if [ "$1" = "__netem__" ]; then
shift 1
local_netem_env $@
exit
fi
is_function() {
test z"`command -v $1`" = z"$1"
}
runcmd() {
local h=$1 rc
shift 1
logmsg "$h: running '$@'"
if ip a l | fgrep -wq $h; then
$@
else
ssh $h $@
fi
rc=$?
if [ $rc -ne 0 ]; then
echo "$h: '$@' failed (exit code $rc)" >&2
logmsg "$h: '$@' failed (exit code $rc)"
fi
return $rc
}
manage_site() {
runcmd $1 crm resource $2 booth
}
manage_arbitrator() {
runcmd $1 systemctl $2 booth@booth.service
}
start_site() {
manage_site $1 start
}
start_arbitrator() {
manage_arbitrator $1 start
}
stop_site_clean() {
manage_site $1 stop &&
sleep 1 &&
runcmd $1 crm --force site ticket revoke $tkt
}
stop_site() {
manage_site $1 stop
}
stop_arbitrator() {
manage_arbitrator $1 stop
}
restart_site() {
manage_site $1 restart
}
restart_arbitrator() {
manage_arbitrator $1 restart
}
booth_status() {
test "`runcmd $1 booth status | get_stat_fld booth_state`" = "started"
}
stop_booth() {
local h
for h in $sites; do
stop_site $h
done >/dev/null 2>&1
for h in $arbitrators; do
stop_arbitrator $h
done >/dev/null 2>&1
wait_timeout
}
start_booth() {
local h
for h in $sites; do
start_site $h
done >/dev/null 2>&1
for h in $arbitrators; do
start_arbitrator $h
done >/dev/null 2>&1
wait_timeout
}
restart_booth() {
local h procs
for h in $sites; do
restart_site $h & procs="$! $procs"
done >/dev/null 2>&1
for h in $arbitrators; do
restart_arbitrator $h
done >/dev/null 2>&1
wait $procs
wait_timeout
}
sync_conf() {
local h rc=0
for h in $sites $arbitrators; do
rsync -q $cnf $h:/etc/booth/booth.conf
rc=$((rc|$?))
done
return $rc
}
dump_conf() {
echo "test configuration file $cnf:"
grep -v '^#' $cnf | grep -v '^[[:space:]]*$' | sed "s/^/$cnf: /"
}
forall() {
local h rc=0
for h in $sites $arbitrators; do
runcmd $h $@
rc=$((rc|$?))
done
return $rc
}
forall_sites() {
local h rc=0
for h in $sites; do
runcmd $h $@
rc=$((rc|$?))
done
return $rc
}
forall_fun() {
local h rc=0 f=$1
for h in $sites $arbitrators; do
$f $h
rc=$((rc|$?))
[ $rc -ne 0 ] && break
done
return $rc
}
# run on all hosts whatever function produced on stdout
forall_fun2() {
local h rc=0 f
f=$1
shift 1
for h in $sites $arbitrators; do
$f $@ | ssh $h
rc=$((rc|$?))
[ $rc -ne 0 ] && break
done
return $rc
}
run_site() {
local n=$1 h
shift 1
h=`echo $sites | awk '{print $'$n'}'`
runcmd $h $@
}
run_arbitrator() {
local n=$1 h
shift 1
h=`echo $arbitrators | awk '{print $'$n'}'`
runcmd $h $@
}
get_site() {
local n=$1
echo $sites | awk '{print $'$n'}'
}
+get_port() {
+ grep "^port" |
+ sed -n 's/.*="//;s/"//p'
+}
get_servers() {
grep "^$1" |
sed -n 's/.*="//;s/"//p'
}
get_rsc() {
awk '/before-acquire-handler/{print $NF}' $cnf
}
break_external_prog() {
echo "location __pref_booth_live_test `get_rsc` rule -inf: defined #uname" | run_site 1 crm configure
}
repair_external_prog() {
run_site $1 crm configure delete __pref_booth_live_test
}
get_tkt() {
grep "^ticket=" | head -1 | sed 's/ticket=//;s/"//g'
}
get_tkt_settings() {
awk '
n && /^ / && /expire|timeout/ {
sub(" = ", "=", $0);
sub("^ ", "T_", $0);
print
next
}
n && /^$/ {exit}
/^ticket.*'$tkt'/ {n=1}
' $cnf
}
wait_exp() {
sleep $T_expire
}
wait_half_exp() {
sleep $((T_expire/2))
}
wait_timeout() {
local t=2
[ "$T_timeout" -gt $t ] && t=$T_timeout
[ "$PKT_LOSS" ] && t=$((t+PKT_LOSS/6))
sleep $t
}
set_netem_env() {
local modfun args
modfun=`echo $1 | sed 's/:.*//'`
args=`echo $1 | sed 's/[^:]*://;s/:/ /g'`
if ! is_function NETEM_ENV_$modfun; then
echo "NETEM_ENV_$modfun: doesn't exist"
exit 1
fi
NETEM_ENV_$modfun $args
}
reset_netem_env() {
[ -z "$NETEM_ENV" ] && return
forall $0 $cnf __netem__ netem_reset
}
setup_netem() {
[ -z "$NETEM_ENV" ] && return
for env in $NETEM_ENV; do
set_netem_env $env
done
trap "reset_netem_env" EXIT
}
cib_status() {
local h=$1 stat
stat=`runcmd $h crm_ticket -L |
grep "^$tkt" | awk '{print $2}'`
test "$stat" != "-1"
}
is_cib_granted() {
local stat h=$1
stat=`runcmd $h crm_ticket -L |
grep "^$tkt" | awk '{print $2}'`
[ "$stat" = "granted" ]
}
check_cib_consistency() {
local h gh="" rc=0
for h in $sites; do
if is_cib_granted $h; then
[ -n "$gh" ] && rc=1 # granted twice
gh="$gh $h"
fi
done
[ -z "$gh" ] && gh="none"
if [ $rc -eq 0 ]; then
echo $gh
return $rc
fi
cat<<EOF >&2
CIB consistency test failed
ticket granted to $gh
EOF
return $rc
}
check_cib() {
local exp_grantee=$1 cib_grantee booth_grantee
local rc=0 pending
cib_grantee=`check_cib_consistency`
booth_grantee=`booth_where_granted`
pending=$?
if [ $pending -eq 0 ]; then
[ "$cib_grantee" = "$booth_grantee" ]
rc=$?
else
# ticket is not committed to cib yet
[ "$exp_grantee" = "$booth_grantee" ]
rc=$?
exp_grantee="" # cheat a bit
fi
case "$exp_grantee" in
"any") [ "$cib_grantee" != "none" ] ;;
"") [ "$cib_grantee" = "none" ] ;;
*) [ "$cib_grantee" = "$exp_grantee" ] ;;
esac
rc=$((rc|$?))
if [ $rc -ne 0 ]; then
cat<<EOF >&2
CIB check failed
CIB grantee: $cib_grantee
booth grantee: $booth_grantee
expected grantee: $exp_grantee
EOF
fi
return $rc
}
booth_where_granted() {
local grantee ticket_line
# we don't know which sites could be stopped, so run booth
# list on all of them (at least one should have booth
# running)
ticket_line=`forall_sites booth list | grep $tkt | sort -u | head -1`
grantee=`echo "$ticket_line" | sed 's/.*leader: //;s/,.*//'`
echo $grantee
[ "$grantee" = "none" ] && return
! runcmd $grantee booth list | grep -q "$tkt.*pending"
}
booth_list_fld() {
cut -d, -f $1 | sed 's/[^:]*://'
}
max_booth_time_diff() {
local l
booth_list_fld 3 |
while read l; do
date -d "$l" "+%s"
done |
awk '
{t[n++]=$0}
END{
for (i=0; i<n; i++)
for (j=i+1; j<n; j++) {
x=t[i]-t[j];
print x >= 0 ? x : -x;
}
}
' | sort -n | tail -1
}
booth_leader_consistency() {
test `booth_list_fld 2 | sort -u | wc -l` -eq 1
}
check_booth_consistency() {
local tlist rc maxdiff
tlist=`forall booth list 2>/dev/null | grep $tkt |
sed 's/commit:.*//;s/NONE/none/'`
maxdiff=`echo "$tlist" | max_booth_time_diff`
test "$maxdiff" -eq 0
rc=$?
echo "$tlist" | booth_leader_consistency
rc=$(($rc | $?<<1))
test $rc -eq 0 && return
cat<<EOF >&2
`if [ $rc -gt 1 ]; then
echo "booth list consistency failed (more than one leader!):"
else
echo "booth list consistency failed (max valid time diff: $maxdiff):"
fi`
===========
"$tlist"
===========
EOF
test $rc -le 1
}
check_consistency() {
local exp_grantee=$1
check_booth_consistency &&
check_cib $exp_grantee
}
reset_booth() {
start_booth
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
}
all_booth_status() {
forall_fun booth_status
}
can_run_test() {
if is_function applicable_$1; then
if ! applicable_$1; then
echo "(not applicable, skipping)"
return 1
fi
fi
if ! is_function test_$1 || ! is_function check_$1; then
echo "(test missing)"
return 1
fi
}
run_report() {
local start_ts=$1 end_ts=$2 name=$3
echo "running hb_report" >&2
hb_report -f "`date -d @$((start_ts-5))`" \
-t "`date -d @$((end_ts+60))`" \
-n "$sites $arbitrators" $name >&2
}
runtest() {
local start_ts end_ts rc booth_status
local start_time end_time
TEST=$1
start_time=`date`
start_ts=`date +%s`
echo -n "Testing: $1... "
can_run_test $1 || return 0
logmsg "starting booth test $1 ..."
setup_netem
test_$1 && check_$1
rc=$?
end_time=`date`
end_ts=`date +%s`
reset_netem_env
logmsg "finished booth test $1 (exit code $rc)"
is_function recover_$1 && recover_$1
sleep 3
all_booth_status
booth_status=$?
if [ $rc -eq 0 -a $booth_status -eq 0 ]; then
echo OK
[ "$GET_REPORT" ] && run_report $start_ts $end_ts $TEST
else
echo "FAIL (running hb_report ... $1.tar.bz2; see also $logf)"
[ $booth_status -ne 0 ] &&
echo "unexpected: some booth daemons not running"
run_report $start_ts $end_ts $TEST
fi
}
[ -f "$cnf" ] || {
ls $cnf
usage 1
}
sites=`get_servers site < $cnf`
arbitrators=`get_servers arbitrator < $cnf`
+port=`get_port < $cnf`
+: ${port:=9929}
site_cnt=`echo $sites | wc -w`
arbitrator_cnt=`echo $arbitrators | wc -w`
tkt=`get_tkt < $cnf`
eval `get_tkt_settings`
[ -z "$sites" ] && {
echo no sites in $cnf
usage 1
}
[ -z "$T_expire" ] && {
echo set $tkt expire time in $cnf
usage 1
}
exec 2>$logf
BASH_XTRACEFD=2
PS4='+ `date +"%T"`: '
set -x
#
# the tests
#
## TEST: grant ##
# just a grant
test_grant() {
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
run_site 1 booth grant $tkt >/dev/null
wait_timeout
}
check_grant() {
check_consistency `get_site 1`
}
## TEST: grant_noarb ##
# just a grant with no arbitrators
test_grant_noarb() {
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
local h
for h in $arbitrators; do
stop_arbitrator $h
done >/dev/null 2>&1
sleep 1
run_site 1 booth grant $tkt >/dev/null
wait_timeout
}
check_grant_noarb() {
check_consistency `get_site 1`
}
recover_grant_noarb() {
local h
for h in $arbitrators; do
start_arbitrator $h
done >/dev/null 2>&1
}
## TEST: revoke ##
# just a revoke
test_revoke() {
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
run_site 1 booth grant $tkt >/dev/null
wait_timeout
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
}
check_revoke() {
check_consistency
}
## TEST: grant_elsewhere ##
# just a grant to another site
test_grant_elsewhere() {
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
run_site 1 booth grant -s `get_site 2` $tkt >/dev/null
wait_timeout
}
check_grant_elsewhere() {
check_consistency `get_site 2`
}
## TEST: grant_site_lost ##
# grant with one site lost
test_grant_site_lost() {
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
stop_site `get_site 2`
wait_timeout
run_site 1 booth grant $tkt >/dev/null
wait_timeout
check_cib `get_site 1` || return 1
wait_exp
}
check_grant_site_lost() {
check_consistency `get_site 1`
}
recover_grant_site_lost() {
start_site `get_site 2`
}
## TEST: simultaneous_start_even ##
# simultaneous start of even number of members
test_simultaneous_start_even() {
local serv
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
run_site 2 booth grant $tkt >/dev/null
wait_timeout
stop_booth
wait_timeout
for serv in $(echo $sites | sed "s/`get_site 1` //"); do
start_site $serv &
done
for serv in $arbitrators; do
start_arbitrator $serv &
done
wait_half_exp
start_site `get_site 1`
wait_timeout
wait_timeout
}
check_simultaneous_start_even() {
check_consistency `get_site 2`
}
## TEST: slow_start_granted ##
# slow start
test_slow_start_granted() {
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
run_site 1 booth grant $tkt >/dev/null
wait_timeout
stop_booth
wait_timeout
for serv in $sites; do
start_site $serv
wait_timeout
done
for serv in $arbitrators; do
start_arbitrator $serv
wait_timeout
done
}
check_slow_start_granted() {
check_consistency `get_site 1`
}
## TEST: restart_granted ##
# restart with ticket granted
test_restart_granted() {
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
run_site 1 booth grant $tkt >/dev/null
wait_timeout
restart_site `get_site 1`
wait_timeout
}
check_restart_granted() {
check_consistency `get_site 1`
}
## TEST: restart_granted_nocib ##
# restart with ticket granted (but cib empty)
test_restart_granted_nocib() {
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
run_site 1 booth grant $tkt >/dev/null
wait_timeout
stop_site_clean `get_site 1` || return 1
wait_timeout
start_site `get_site 1`
wait_timeout
wait_timeout
wait_timeout
}
check_restart_granted_nocib() {
check_consistency `get_site 1`
}
## TEST: notgranted ##
# restart with ticket not granted
test_restart_notgranted() {
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
run_site 1 booth grant $tkt >/dev/null
wait_timeout
stop_site `get_site 2`
sleep 1
start_site `get_site 2`
wait_timeout
}
check_restart_notgranted() {
check_consistency `get_site 1`
}
## TEST: failover ##
# ticket failover
test_failover() {
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
run_site 1 booth grant $tkt >/dev/null
wait_timeout
stop_site_clean `get_site 1` || return 1
booth_status `get_site 1` && return 1
wait_exp
wait_timeout
}
check_failover() {
check_consistency any
}
recover_failover() {
start_site `get_site 1`
}
## TEST: split_leader ##
# split brain (leader alone)
test_split_leader() {
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
run_site 1 booth grant $tkt >/dev/null
wait_timeout
- run_site 1 $iprules stop >/dev/null
+ run_site 1 $iprules stop $port >/dev/null
wait_exp
wait_timeout
check_cib any || return 1
- run_site 1 $iprules start >/dev/null
+ run_site 1 $iprules start $port >/dev/null
wait_timeout
}
check_split_leader() {
check_consistency any
}
recover_split_leader() {
- run_site 1 $iprules start >/dev/null
+ run_site 1 $iprules start $port >/dev/null
}
## TEST: split_follower ##
# split brain (follower alone)
test_split_follower() {
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
run_site 1 booth grant $tkt >/dev/null
wait_timeout
- run_site 2 $iprules stop >/dev/null
+ run_site 2 $iprules stop $port >/dev/null
wait_exp
wait_timeout
- run_site 2 $iprules start >/dev/null
+ run_site 2 $iprules start $port >/dev/null
wait_timeout
}
check_split_follower() {
check_consistency `get_site 1`
}
## TEST: split_edge ##
# split brain (leader alone)
test_split_edge() {
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
run_site 1 booth grant $tkt >/dev/null
wait_timeout
- run_site 1 $iprules stop >/dev/null
+ run_site 1 $iprules stop $port >/dev/null
wait_exp
- run_site 1 $iprules start >/dev/null
+ run_site 1 $iprules start $port >/dev/null
wait_timeout
}
check_split_edge() {
check_consistency any
}
## TEST: external_prog_failed ##
# external test prog failed
test_external_prog_failed() {
run_site 1 booth revoke $tkt >/dev/null
wait_timeout
run_site 1 booth grant $tkt >/dev/null
sleep 1
break_external_prog 1
wait_half_exp
wait_timeout
}
check_external_prog_failed() {
check_consistency any &&
[ `booth_where_granted` != `get_site 1` ]
}
recover_external_prog_failed() {
repair_external_prog 1
}
applicable_external_prog_failed() {
[ -n `get_rsc` ]
}
#
# environment modifications
#
# packet loss at one site 30%
NETEM_ENV_single_loss() {
run_site 1 $0 $cnf __netem__ netem_loss ${1:-30}
PKT_LOSS=${1:-30}
}
# packet loss everywhere 30%
NETEM_ENV_loss() {
forall $0 $cnf __netem__ netem_loss ${1:-30}
PKT_LOSS=${1:-30}
}
# network delay 100ms
NETEM_ENV_net_delay() {
forall $0 $cnf __netem__ netem_delay ${1:-100}
}
sync_conf || exit
restart_booth
all_booth_status || {
reset_booth
all_booth_status || exit
}
dump_conf >&2
TESTS="$@"
: ${TESTS:="grant grant_noarb grant_elsewhere grant_site_lost revoke
simultaneous_start_even slow_start_granted
restart_granted restart_granted_nocib restart_notgranted
failover split_leader split_follower split_edge
external_prog_failed"}
for t in $TESTS; do
runtest $t
done
diff --git a/test/serverenv.py b/test/serverenv.py
index e8e271b..bbe7ff3 100755
--- a/test/serverenv.py
+++ b/test/serverenv.py
@@ -1,203 +1,203 @@
#!/usr/bin/python
import os
import re
import time
import unittest
from assertions import BoothAssertions
from boothrunner import BoothRunner
from boothtestenv import BoothTestEnvironment
from utils import get_IP
class ServerTestEnvironment(BoothTestEnvironment):
'''
boothd site/arbitrator will hang in setup phase while attempting to connect
to an unreachable peer during ticket_catchup(). In a test environment we don't
have any reachable peers. Fortunately, we can still successfully launch a
daemon by only listing our own IP in the config file.
'''
typical_config = """\
# This is like the config in the manual
transport="UDP"
-port="6666"
+port="9929"
# Here's another comment
#arbitrator="147.2.207.14"
site="147.4.215.19"
#site="147.18.2.1"
ticket="ticketA"
ticket="ticketB"
"""
site_re = re.compile('^site=".+"', re.MULTILINE)
working_config = re.sub(site_re, 'site="%s"' % get_IP(), typical_config, 1)
def run_booth(self, expected_exitcode, expected_daemon,
config_text=None, config_file=None, lock_file=True,
args=[], debug=False):
'''
Runs boothd. Defaults to using a temporary lock file and the
standard config file path. There are four possible types of
outcome:
- boothd exits non-zero without launching a daemon (setup phase failed,
e.g. due to invalid configuration file)
- boothd exits zero after launching a daemon (successful operation)
- boothd does not exit (running in foreground / debug mode)
- boothd does not exit (setup phase hangs, e.g. while attempting
to connect to peer during ticket_catchup())
Arguments:
config_text
a string containing the contents of a configuration file to use
config_file
path to a configuration file to use
lock_file
False: don't pass a lockfile parameter to booth via -l
True: pass a temporary lockfile parameter to booth via -l
string: pass the given lockfile path to booth via -l
args
array of extra args to pass to booth
expected_exitcode
an integer, or False if booth is not expected to terminate
within the timeout
expected_daemon
True iff a daemon is expected to be launched (this includes
running the server in debug / foreground mode via -D; even
though in this case the server's not technically not a daemon,
we still want to treat it like one by checking the lockfile
before and after we kill it)
debug
True means pass the -D parameter
Returns a (pid, return_code, stdout, stderr, runner) tuple,
where return_code/stdout/stderr are None iff pid is still running.
'''
if expected_daemon and expected_exitcode is not None and expected_exitcode != 0:
raise RuntimeError, \
"Shouldn't ever expect daemon to start and then failure"
if not expected_daemon and expected_exitcode == 0:
raise RuntimeError, \
"Shouldn't ever expect success without starting daemon"
self.init_log()
runner = BoothRunner(self.boothd_path, self.mode, args)
if config_text:
config_file = self.write_config_file(config_text)
if config_file:
runner.set_config_file(config_file)
if lock_file is True:
lock_file = os.path.join(self.test_path, 'boothd-lock.pid')
if lock_file:
runner.set_lock_file(lock_file)
if debug:
runner.set_debug()
runner.show_args()
(pid, return_code, stdout, stderr) = runner.run()
self.check_return_code(pid, return_code, expected_exitcode)
if expected_daemon:
self.check_daemon_handling(runner, expected_daemon)
elif return_code is None:
# This isn't strictly necessary because we ensure no
# daemon is running from within test setUp(), but it's
# probably a good idea to tidy up after ourselves anyway.
self.kill_pid(pid)
return (pid, return_code, stdout, stderr, runner)
def write_config_file(self, config_text):
config_file = self.get_tempfile('config')
c = open(config_file, 'w')
c.write(config_text)
c.close()
return config_file
def kill_pid(self, pid):
print "killing %d ..." % pid
os.kill(pid, 15)
print "killed"
def check_daemon_handling(self, runner, expected_daemon):
'''
Check that the lock file contains a pid referring to a running
daemon. Then kill the daemon, and ensure that the lock file
vanishes (bnc#749763).
'''
daemon_pid = self.get_daemon_pid_from_lock_file(runner.lock_file)
err = "lock file should contain pid"
if not expected_daemon:
err += ", even though we didn't expect a daemon"
self.assertTrue(daemon_pid is not None, err)
daemon_running = self.is_pid_running_daemon(daemon_pid)
err = "pid in lock file should referred to a running daemon"
self.assertTrue(daemon_running, err)
if daemon_running:
self.kill_pid(int(daemon_pid))
time.sleep(1)
daemon_pid = self.get_daemon_pid_from_lock_file(runner.lock_file)
self.assertTrue(daemon_pid is not None,
'bnc#749763: lock file should vanish after daemon is killed')
def get_daemon_pid_from_lock_file(self, lock_file):
'''
Returns the pid contained in lock_file, or None if it doesn't exist.
'''
if not os.path.exists(lock_file):
print "%s does not exist" % lock_file
return None
l = open(lock_file)
lines = l.readlines()
l.close()
self.assertEqual(len(lines), 1, "Lock file should contain one line")
pid = re.search('\\bbooth_pid="?(\\d+)"?', lines[0]).group(1)
print "lockfile contains: <%s>" % pid
return pid
def is_pid_running_daemon(self, pid):
'''
Returns true iff the given pid refers to a running boothd process.
'''
path = "/proc/%s" % pid
pid_running = os.path.isdir(path)
# print "======"
# import subprocess
# print subprocess.check_output(['lsof', '-p', pid])
# print subprocess.check_output(['ls', path])
# print subprocess.check_output(['cat', "/proc/%s/cmdline" % pid])
# print "======"
if not pid_running:
return False
c = open("/proc/%s/cmdline" % pid)
cmdline = "".join(c.readlines())
print cmdline
c.close()
if cmdline.find('boothd') == -1:
print 'no boothd in cmdline:', cmdline
return False
# self.assertRegexpMatches(
# cmdline,
# 'boothd',
# "lock file should refer to pid of running boothd"
# )
return True
def _test_buffer_overflow(self, expected_error, **args):
(pid, ret, stdout, stderr, runner) = \
self.run_booth(expected_exitcode=1, expected_daemon=False, **args)
self.assertRegexpMatches(stderr, expected_error)
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Jun 26, 6:21 PM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1942418
Default Alt Text
(26 KB)
Attached To
Mode
rB Booth
Attached
Detach File
Event Timeline
Log In to Comment