]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[3406] Implemented test checking graceful server shutdown.
authorMarcin Siodelski <marcin@isc.org>
Fri, 23 May 2014 14:21:38 +0000 (16:21 +0200)
committerMarcin Siodelski <marcin@isc.org>
Fri, 23 May 2014 14:21:38 +0000 (16:21 +0200)
src/bin/dhcp6/tests/Makefile.am
src/bin/dhcp6/tests/dhcp6_shutdown_test.sh [new file with mode: 0755]
src/bin/dhcp6/tests/dhcp6_sigint_test.sh [new file with mode: 0755]
src/bin/dhcp6/tests/dhcp6_sigterm_test.sh [new file with mode: 0755]
src/bin/dhcp6/tests/dhcp6_test_func.sh [new file with mode: 0755]

index ed47eddd9a579f2a6cb87d6c57cc04be75dbdb2d..6afab0e40986fefb783e382f4167f7e53e3c0d92 100644 (file)
@@ -1,12 +1,16 @@
 PYCOVERAGE_RUN = @PYCOVERAGE_RUN@
 PYTESTS = dhcp6_test.py
+SHLIBS =
 SHTESTS =
 # The test of dynamic reconfiguration based on signals will work only
 # if we are using file based configuration approach.
 if CONFIG_BACKEND_JSON
+SHLIBS  += dhcp6_test_func.sh
 SHTESTS += dhcp6_reconfigure_test.sh
+SHTESTS += dhcp6_sigterm_test.sh
+SHTESTS += dhcp6_sigint_test.sh
 endif
-EXTRA_DIST = $(PYTESTS) $(SHTESTS)
+EXTRA_DIST = $(PYTESTS) $(SHTESTS) $(SHLIBS)
 
 # Explicitly specify paths to dynamic libraries required by loadable python
 # modules. That is required on Mac OS systems. Otherwise we will get exception
diff --git a/src/bin/dhcp6/tests/dhcp6_shutdown_test.sh b/src/bin/dhcp6/tests/dhcp6_shutdown_test.sh
new file mode 100755 (executable)
index 0000000..aa7307d
--- /dev/null
@@ -0,0 +1,106 @@
+# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+if [ $# -ne 2 ]; then
+    printf "USAGE: dhcp6_shutdown_test.sh <test_name> <signal_num>\n"
+    exit 1
+fi
+
+# Test name
+TEST_NAME=$1
+# Signal number to be used for this test.
+SIG_NUM=$2
+# Path to the temporary configuration file.
+CFG_FILE="test_config.json"
+# Path to the Kea log file.
+LOG_FILE="test.log"
+# Kea configuration to be stored in the configuration file.
+CONFIG="{
+    \"Dhcp6\":
+    {
+        \"interfaces\": [ ],
+        \"preferred-lifetime\": 3000,
+        \"valid-lifetime\": 4000,
+        \"renew-timer\": 1000,
+        \"rebind-timer\": 2000,
+        \"lease-database\":
+        {
+            \"type\": \"memfile\",
+            \"persist\": false
+        },
+        \"subnet6\": [
+        {
+            \"subnet\": \"2001:db8:1::/64\",
+            \"pool\": [ \"2001:db8:1::10-2001:db8:1::100\" ]
+        } ]
+    }
+}"
+
+# Import common test library.
+. dhcp6_test_func.sh
+
+# Log the start of the test and print test name.
+test_start
+# Remove dangling Kea instances and remove log files.
+cleanup
+# Create new configuration file.
+create_config "${CONFIG}"
+# Instruct Kea to log to the specific file.
+set_logger
+# Start Kea.
+start_kea
+# Wait up to 20s for Kea to start.
+wait_for_kea 20
+if [ ${_WAIT_FOR_KEA} -eq 0 ]; then
+    printf "ERROR: timeout waiting for Kea to start.\n"
+    clean_exit 1
+fi
+
+# Check if it is still running. It could have terminated (e.g. as a result
+# of configuration failure).
+get_pids
+if [ ${_GET_PIDS_NUM} -ne 1 ]; then
+    printf "ERROR: expected one Kea process to be started. Found %d processes started.\n" ${_GET_PIDS_NUM}
+    clean_exit 1
+fi
+
+# Check in the log file, how many times server has been configured. It should
+# be just once on startup.
+get_reconfigs
+if [ ${_GET_RECONFIGS} -ne 1 ]; then
+    printf "ERROR: server hasn't been configured.\n"
+    clean_exit 1
+else
+    printf "Server successfully configured.\n"
+fi
+
+# Send signal to Kea (SIGTERM, SIGINT etc.)
+send_signal ${SIG_NUM}
+
+# Wait up to 10s for the server's graceful shutdown. The graceful shut down
+# should be recorded in the log file with the appropriate message.
+wait_for_message 10 "DHCP6_SHUTDOWN"
+if [ ${_WAIT_FOR_MESSAGE} -eq 0 ]; then
+    printf "ERROR: Server did not record shutdown in the log.\n"
+    clean_exit 1
+fi
+
+# Server should have shut down.
+get_pids
+if [ ${_GET_PIDS_NUM} -ne 0 ]; then
+    printf "ERROR: Kea did not shut down after receiving signal.\n" ${_GET_PIDS_NUM}
+    clean_exit 1
+fi
+
+clean_exit 0
diff --git a/src/bin/dhcp6/tests/dhcp6_sigint_test.sh b/src/bin/dhcp6/tests/dhcp6_sigint_test.sh
new file mode 100755 (executable)
index 0000000..cf81d8b
--- /dev/null
@@ -0,0 +1,16 @@
+# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# Run a test that sends SIGINT to Kea and checks if it shuts down gracefully.
+./dhcp6_shutdown_test.sh "Sigint" 2
diff --git a/src/bin/dhcp6/tests/dhcp6_sigterm_test.sh b/src/bin/dhcp6/tests/dhcp6_sigterm_test.sh
new file mode 100755 (executable)
index 0000000..28c1aab
--- /dev/null
@@ -0,0 +1,16 @@
+# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# Run a test that sends SIGTERM to Kea and checks if it shuts down gracefully.
+./dhcp6_shutdown_test.sh "Sigterm" 15
diff --git a/src/bin/dhcp6/tests/dhcp6_test_func.sh b/src/bin/dhcp6/tests/dhcp6_test_func.sh
new file mode 100755 (executable)
index 0000000..15a0ca1
--- /dev/null
@@ -0,0 +1,183 @@
+# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# Name of the Kea executable.
+BIN="../b10-dhcp6"
+
+# Begins a test by prining its name.
+# It requires the ${TEST_NAME} variable to be hold the test name.
+test_start() {
+    printf "\nSTART TEST ${TEST_NAME}\n"
+}
+
+# Stores the configuration specified as a parameter in the configuration
+# file which name has been set in the ${CFG_FILE} variable.
+create_config() {
+    printf "Creating Kea configuration file: %s.\n" ${CFG_FILE}
+    printf "%b" ${1} > ${CFG_FILE}
+}
+
+# Sets Kea logger to write to the file specified by the global value
+# ${LOG_FILE}.
+set_logger() {
+    printf "Kea log will be stored in %s.\n" ${LOG_FILE}
+    export B10_LOGGER_DESTINATION=${LOG_FILE}
+}
+
+# Returns the number of running b10-dhcp6 process pids and
+# the list of pids.
+_GET_PIDS=     # Holds space separated list of DHCPv6 pids.
+_GET_PIDS_NUM= # Holds the number of DHCPv6 server pids.
+get_pids() {
+    _GET_PIDS=`ps -o pid,command | grep b10-dhcp6 | grep -v grep | awk '{print $1}'`
+    _GET_PIDS_NUM=`printf "%s" "${_GET_PIDS}" | wc -w | awk '{print $1}'`
+}
+
+# Returns the number of occurrences of the Kea log message in the
+# log file.
+_GET_LOG_MESSAGES= # Holds the number of log message occurrences.
+get_log_messages() {
+    # Grep log file for the logger message occurrences.
+    _GET_LOG_MESSAGES=`grep -o ${1} ${LOG_FILE} | wc -w`
+    # Remove whitespaces.
+    ${_GET_LOG_MESSAGES##*[! ]}
+}
+
+# Returns the number of server configurations performed so far. Also
+# returns the number of configuration errors.
+_GET_RECONFIGS=      # Number of configurations so far.
+_GET_RECONFIG_ERRORS=  # Number of configuration errors.
+get_reconfigs() {
+    # Grep log file for DHCP6_CONFIG_COMPLETE occurences. There should
+    # be one occurence per (re)configuration.
+    _GET_RECONFIGS=`grep -o DHCP6_CONFIG_COMPLETE ${LOG_FILE} | wc -w`
+    # Grep log file for DHCP6_CONFIG_LOAD_FAIL to check for configuration
+    # failures.
+    _GET_RECONFIG_ERRORS=`grep -o DHCP6_CONFIG_LOAD_FAIL ${LOG_FILE} | wc -w`
+    # Remove whitespaces
+    ${_GET_RECONFIGS##*[! ]}
+    ${_GET_RECONFIG_ERRORS##*[! ]}
+}
+
+# Performs cleanup for a test.
+# It shuts down running Kea processes and removes temporary files.
+cleanup() {
+    get_pids
+    # Shut down running Kea processes.
+    for pid in ${_GET_PIDS}
+    do
+        printf "Shutting down Kea proccess having pid %d.\n" ${pid}
+        kill -9 ${pid}
+    done
+    # Remove temporary files.
+    rm -rf ${LOG_FILE}
+    rm -rf ${CFG_FILE}
+}
+
+# Exists the test in the clean way.
+# It peformes the cleanup and prints whether the test has passed or failed.
+# If a test fails, the Kea log is dumped.
+clean_exit() {
+    if [ $1 -eq 0 ]; then
+        cleanup
+        printf "PASSED ${TEST_NAME}\n\n"
+    else
+        # Dump log file if exists for debugging purposes.
+        if [ -s ${LOG_FILE} ]; then
+            printf "Log file dump:\n"
+            cat ${LOG_FILE}
+        fi
+        cleanup
+        printf "FAILED ${TEST_NAME}\n\n"
+    fi
+    exit $1
+}
+
+# Starts Kea process in background using a configuration file specified
+# in the global variable ${CFG_FILE}
+start_kea() {
+    printf "Running command %s.\n" "\"$BIN -c ${CFG_FILE}\""
+    $BIN -c ${CFG_FILE} &
+}
+
+# Waits for Kea to startup with timeout.
+# This function repeatedly checs if the Kea log file has been created
+# and is non-empty. If it is, the function assumes that Kea has started.
+# It doesn't check the contents of the log file though. 
+# If the log file doesn't exist the function sleeps for a second and
+# checks again. This is repeated until timeout is reached or non-empty
+# log file is found. If timeout is reached, the function reports an
+# error.
+_WAIT_FOR_KEA=0  # Holds 0 if Kea hasn't started, 1 otherwise
+wait_for_kea() {
+    timeout=${1} # Desired timeout in seconds.
+    loops=0
+    _WAIT_FOR_KEA=0
+    while [ ! -s ${LOG_FILE} ] && [ ${loops} -le ${timeout} ]; do
+        printf "."
+        sleep 1
+        loops=`expr $loops + 1`
+    done
+    printf "\n"
+    if [ ${loops} -le ${timeout} ]; then
+        _WAIT_FOR_KEA=1
+    fi
+}
+
+# Waits for a specific message to occur in the Kea log file.
+# This function is called when the test expects specific message
+# to show up in the log file as a result of some action that has
+# been taken. Typically, the test expects that the message
+# is logged when the SIGHUP or SIGTERM signal has been sent to the
+# Kea process.
+# This function waits a specified number of seconds for the message
+# to occur. If the expected message doesn't occur, the error status
+# is returned.
+_WAIT_FOR_MESSAGE=0  # Holds 0 if the message hasn't occured, 1 otherwise.
+wait_for_message() {
+    timeout=${1}  # Timeout value in seconds.
+    message=${2}  # Expected message id.
+    loops=0       # Number of loops performed so far.
+    _WAIT_FOR_MESSAGE=0
+    # Check if log file exists and if we reached timeout.
+    while [ ! -s {LOG_FILE} ] && [ ${loops} -le ${timeout} ]; do
+        # Check if the message has been logged.
+        get_log_messages ${message}
+        if [ ${_GET_LOG_MESSAGES} -gt 0 ]; then
+            printf "\n"
+            _WAIT_FOR_MESSAGE=1            
+            return
+        fi
+        # Message not recorded. Keep going.
+        printf "."
+        sleep 1
+        loops=`expr ${loops} + 1`
+    done
+    printf "\n"
+    # Timeout.
+}
+
+# Sends specified signal to the Kea process.
+send_signal() {
+    sig=$1   # Signal number.
+    # Get Kea pid.
+    get_pids
+    if [ ${_GET_PIDS_NUM} -ne 1 ]; then
+        printf "ERROR: expected one Kea process to be started. Found %d processes started.\n" ${_GET_PIDS_NUM}
+        clean_exit 1
+    fi 
+    printf "Sending signal ${sig} to Kea process (pid=%s).\n" ${_GET_PIDS}
+    # Actually send a signal.
+    kill -${sig} ${_GET_PIDS}
+}