mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-26 16:21:09 +00:00
7f0fef2209
The quit-on-monitor-client-disconnect test was non-deterministic depending on load (eg, other concurrently running tests). Under load, it was likely that the server did not process the "monitor quit" command before checking for disconnect, so the server did not terminate. The fix was to make the monitor interface read and process all queued input from the client before checking for HUP or ERR condition on the socket. With this fix, the "sleep 1" kludges before and after the echo "monitor quit" to the console command are no longer needed. In the process the monitor interface code was modernised: eg, now it calls read_nonblock() instead of read(2).
358 lines
10 KiB
Bash
Executable File
358 lines
10 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Tests for Serval DNA server operations.
|
|
#
|
|
# Copyright 2012 Serval Project, Inc.
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
source "${0%/*}/../testframework.sh"
|
|
source "${0%/*}/../testdefs.sh"
|
|
|
|
setup() {
|
|
setup_servald
|
|
assert_no_servald_processes
|
|
}
|
|
|
|
teardown() {
|
|
get_servald_server_pidfile && stop_servald_server
|
|
kill_all_servald_processes
|
|
assert_no_servald_processes
|
|
report_all_servald_servers
|
|
}
|
|
|
|
configure_servald_server() {
|
|
executeOk_servald config \
|
|
set log.console.level debug \
|
|
set log.console.show_time true \
|
|
set log.console.show_pid true
|
|
}
|
|
|
|
doc_StartCreateInstanceDir="Starting server creates instance directory"
|
|
setup_StartCreateInstanceDir() {
|
|
# Ensure there is initially no instance directory.
|
|
configure_servald_server() {
|
|
:
|
|
}
|
|
setup
|
|
assert [ ! -d "$SERVALINSTANCE_PATH" ]
|
|
}
|
|
test_StartCreateInstanceDir() {
|
|
executeOk $servald start
|
|
assert [ -d "$SERVALINSTANCE_PATH" ]
|
|
executeOk $servald stop
|
|
tfw_cat --stdout --stderr
|
|
}
|
|
|
|
doc_StartLogfile="Starting server gives no errors"
|
|
setup_StartLogfile() {
|
|
setup
|
|
executeOk_servald config set log.file.directory_path "$PWD/log"
|
|
}
|
|
test_StartLogfile() {
|
|
start_servald_server
|
|
assert_servald_server_no_errors
|
|
}
|
|
|
|
doc_StartNoInterfaces="Starting server with no configured interfaces gives warning"
|
|
setup_StartNoInterfaces() {
|
|
setup
|
|
}
|
|
test_StartNoInterfaces() {
|
|
start_servald_server
|
|
sleep 0.1
|
|
assertGrep --message="log contains 'no interfaces' warning" "$instance_servald_log" '^WARN:.*interfaces'
|
|
tfw_cat "$instance_servald_log"
|
|
}
|
|
|
|
doc_StartNoErrors="Starting server on dummy file interface gives no errors"
|
|
setup_StartNoErrors() {
|
|
setup
|
|
add_servald_interface --file
|
|
}
|
|
test_StartNoErrors() {
|
|
start_servald_server
|
|
wait_until grep "Interface .* is up" $instance_servald_log
|
|
assert_servald_server_no_errors
|
|
tfw_cat "$instance_servald_log"
|
|
}
|
|
|
|
doc_StartLocalNoErrors="Starting server on local interface gives no errors"
|
|
setup_StartLocalNoErrors() {
|
|
setup
|
|
add_servald_interface
|
|
}
|
|
test_StartLocalNoErrors() {
|
|
start_servald_server
|
|
wait_until grep "Interface .* is up" $instance_servald_log
|
|
assert_servald_server_no_errors
|
|
tfw_cat "$instance_servald_log"
|
|
}
|
|
|
|
doc_StartRealNoErrors="Starting server with real interface config gives no errors"
|
|
setup_StartRealNoErrors() {
|
|
setup
|
|
executeOk_servald config \
|
|
set interfaces.0.match BAD0 \
|
|
set interfaces.1.match BAD1 \
|
|
set interfaces.2.match BAD2
|
|
}
|
|
test_StartRealNoErrors() {
|
|
start_servald_server
|
|
assert_servald_server_no_errors
|
|
tfw_cat "$instance_servald_log"
|
|
}
|
|
|
|
doc_StartStart="Start server while already running"
|
|
setup_StartStart() {
|
|
setup
|
|
start_servald_server
|
|
}
|
|
test_StartStart() {
|
|
execute --exit-status=10 $servald start
|
|
extract_stdout_keyvalue start_instance_path 'instancepath' '.*'
|
|
extract_stdout_keyvalue start_pid 'pid' '[0-9]\+'
|
|
assert [ "$start_instance_path" = "$SERVALINSTANCE_PATH" ]
|
|
assert [ "$servald_pid" = "$start_pid" ]
|
|
}
|
|
|
|
doc_StartTwice="Attempt to start the server twice at the same time"
|
|
setup_StartTwice() {
|
|
setup
|
|
export SERVALD_SERVER_START_DELAY=2000
|
|
set_instance +A
|
|
executeOk_servald config set debug.io on
|
|
}
|
|
start_other(){
|
|
start_servald_server
|
|
echo $servald_pid > other_pid
|
|
}
|
|
test_StartTwice() {
|
|
fork %server start_other
|
|
start_servald_server
|
|
fork_wait %server
|
|
# both servald start commands should return success with the same PID
|
|
assertGrep other_pid "^$servald_pid$"
|
|
stop_servald_server
|
|
assert_no_servald_processes
|
|
}
|
|
|
|
doc_MonitorQuit="Server stops due to monitor client disconnection"
|
|
setup_MonitorQuit() {
|
|
configure_servald_server() {
|
|
executeOk_servald config \
|
|
set log.console.level debug \
|
|
set log.console.show_time true \
|
|
set log.console.show_pid true \
|
|
set debug.monitor on
|
|
}
|
|
setup
|
|
start_servald_server
|
|
}
|
|
test_MonitorQuit() {
|
|
executeOk_servald console < <(echo "monitor quit")
|
|
tfw_cat --stdout --stderr
|
|
wait_until ! kill -0 $servald_pid 2>/dev/null
|
|
}
|
|
|
|
doc_NoZombie="Server process does not become a zombie"
|
|
setup_NoZombie() {
|
|
setup
|
|
export SERVALD_START_POST_SLEEP=10000
|
|
servald_start &
|
|
start_pid=$!
|
|
wait_until get_servald_server_pidfile servald_pid
|
|
assert kill -0 $start_pid
|
|
}
|
|
test_NoZombie() {
|
|
tfw_log "Before kill -KILL $servald_pid"
|
|
ps -l $start_pid $servald_pid
|
|
assert kill -KILL $servald_pid
|
|
tfw_log "After kill -KILL $servald_pid"
|
|
ps -l $start_pid $servald_pid
|
|
wait_until --timeout=2 ! kill -0 $servald_pid 2>/dev/null
|
|
tfw_log "After waiting"
|
|
ps -l $start_pid $servald_pid
|
|
assert --message="zombie servald process does not exist" ! kill -0 $servald_pid 2>/dev/null
|
|
}
|
|
teardown_NoZombie() {
|
|
kill -TERM $start_pid
|
|
kill_all_servald_processes
|
|
assert_no_servald_processes
|
|
}
|
|
|
|
doc_ServerWatchdog="Server process invokes watchdog periodically"
|
|
setup_ServerWatchdog() {
|
|
cat >watchdog <<EOF
|
|
#!/bin/sh
|
|
date >> $PWD/trace
|
|
EOF
|
|
chmod 0550 watchdog
|
|
>trace
|
|
setup
|
|
executeOk_servald config \
|
|
set log.console.level debug \
|
|
set log.console.show_time true \
|
|
set log.console.show_pid true \
|
|
set debug.watchdog on \
|
|
set server.watchdog.executable "$PWD/watchdog" \
|
|
set server.watchdog.interval_ms 100
|
|
start_servald_server
|
|
}
|
|
test_ServerWatchdog() {
|
|
wait_until --sleep=0.1 --timeout=15 line_count_at_least trace 10
|
|
stop_servald_server
|
|
assert_servald_server_no_errors
|
|
}
|
|
line_count_at_least() {
|
|
local file="$1"
|
|
local lines="$2"
|
|
[ $(wc -l <"$file") -ge "$lines" ]
|
|
}
|
|
|
|
doc_ReloadConfigAuto="Server automatically reloads configuration"
|
|
setup_ReloadConfigAuto() {
|
|
cat >watchdog1 <<EOF
|
|
#!/bin/sh
|
|
date >> $PWD/trace1
|
|
EOF
|
|
cat >watchdog2 <<EOF
|
|
#!/bin/sh
|
|
date >> $PWD/trace2
|
|
EOF
|
|
chmod 0550 watchdog1 watchdog2
|
|
>trace1
|
|
>trace2
|
|
setup
|
|
executeOk_servald config \
|
|
set log.console.level debug \
|
|
set log.console.show_time true \
|
|
set log.console.show_pid true \
|
|
set debug.watchdog on \
|
|
set server.watchdog.executable "$PWD/watchdog1" \
|
|
set server.watchdog.interval_ms 100
|
|
start_servald_server
|
|
}
|
|
test_ReloadConfigAuto() {
|
|
wait_until --sleep=0.5 --timeout=15 line_count_at_least trace1 3
|
|
assert [ $(wc -l <trace2) -eq 0 ]
|
|
executeOk_servald config \
|
|
set server.watchdog.executable "$PWD/watchdog2"
|
|
tfw_cat --stderr
|
|
wait_until --sleep=0.5 --timeout=15 line_count_at_least trace2 3
|
|
stop_servald_server
|
|
assert_servald_server_no_errors
|
|
}
|
|
|
|
doc_ReloadConfigSync="Server configuration sync"
|
|
setup_ReloadConfigSync() {
|
|
cat >watchdog1 <<EOF
|
|
#!/bin/sh
|
|
date >> $PWD/trace1
|
|
EOF
|
|
cat >watchdog2 <<EOF
|
|
#!/bin/sh
|
|
date >> $PWD/trace2
|
|
EOF
|
|
chmod 0550 watchdog1 watchdog2
|
|
>trace1
|
|
>trace2
|
|
setup
|
|
executeOk_servald config \
|
|
set log.console.level debug \
|
|
set log.console.show_time true \
|
|
set log.console.show_pid true \
|
|
set debug.config on \
|
|
set debug.watchdog on \
|
|
set debug.mdprequests on \
|
|
set server.config_reload_interval_ms 600000 \
|
|
set server.watchdog.executable "$PWD/watchdog1" \
|
|
set server.watchdog.interval_ms 100
|
|
start_servald_server
|
|
}
|
|
test_ReloadConfigSync() {
|
|
wait_until --sleep=0.5 --timeout=15 line_count_at_least trace1 10
|
|
assert [ $(wc -l <trace2) -eq 0 ]
|
|
executeOk_servald config set server.watchdog.executable "$PWD/watchdog2"
|
|
tfw_cat --stderr
|
|
>trace1
|
|
wait_until --sleep=0.5 --timeout=15 line_count_at_least trace1 3
|
|
assert [ $(wc -l <trace2) -eq 0 ]
|
|
executeOk_servald config sync
|
|
tfw_cat --stderr
|
|
>trace1
|
|
wait_until --sleep=0.5 --timeout=15 line_count_at_least trace2 3
|
|
assert [ $(wc -l <trace1) -eq 0 ]
|
|
stop_servald_server
|
|
assert_servald_server_no_errors
|
|
}
|
|
|
|
doc_ReloadConfigSetSync="Server configuration always syncs after set"
|
|
setup_ReloadConfigSetSync() {
|
|
setup_curl 7
|
|
setup
|
|
set_instance +A
|
|
create_single_identity
|
|
executeOk_servald config \
|
|
set log.console.level debug \
|
|
set log.console.show_time true \
|
|
set log.console.show_pid true \
|
|
set debug.config on \
|
|
set debug.mdprequests on \
|
|
set server.config_reload_interval_ms 600000 \
|
|
set server.motd "Abcdef"
|
|
start_servald_server
|
|
get_servald_http_server_port PORTA +A
|
|
conf_size=$(wc -l <"$SERVALINSTANCE_PATH/serval.conf")
|
|
assert [ "$conf_size" -gt 0 ]
|
|
}
|
|
test_ReloadConfigSetSync() {
|
|
# Set the MOTD without changing the config file size and sync it, and the
|
|
# HTTP server returns it in the root page immediately.
|
|
executeOk_servald config set server.motd "Yoicks" sync
|
|
tfw_cat --stderr
|
|
assert [ $conf_size -eq $(wc -l <"$SERVALINSTANCE_PATH/serval.conf") ]
|
|
executeOk curl \
|
|
--silent --fail --show-error \
|
|
--output root.html \
|
|
--dump-header http.headers \
|
|
"http://$addr_localhost:$PORTA/"
|
|
assertGrep root.html Yoicks
|
|
# Set the MOTD without changing the config file size but do not sync it, and
|
|
# the HTTP server still returns the prior value of the MOTD.
|
|
executeOk_servald config set server.motd "Flarng"
|
|
tfw_cat --stderr
|
|
assert [ $conf_size -eq $(wc -l <"$SERVALINSTANCE_PATH/serval.conf") ]
|
|
executeOk curl \
|
|
--silent --fail --show-error \
|
|
--output root.html \
|
|
--dump-header http.headers \
|
|
"http://$addr_localhost:$PORTA/"
|
|
assertGrep root.html Yoicks
|
|
# Sync the config to the daemon, and now the HTTP server returns the new
|
|
# MOTD.
|
|
executeOk_servald config sync
|
|
executeOk curl \
|
|
--silent --fail --show-error \
|
|
--output root.html \
|
|
--dump-header http.headers \
|
|
"http://$addr_localhost:$PORTA/"
|
|
assertGrep root.html Flarng
|
|
stop_servald_server
|
|
assert_servald_server_no_errors
|
|
}
|
|
|
|
runTests "$@"
|