2020-12-03 11:19:15 +02:00
|
|
|
#!/bin/sh
|
|
|
|
|
2020-12-14 04:20:40 -08:00
|
|
|
# Copyright (C) 2014-2020 Internet Systems Consortium, Inc. ("ISC")
|
2014-05-23 16:21:38 +02:00
|
|
|
#
|
2015-12-15 21:37:34 +01:00
|
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
2014-05-23 16:21:38 +02:00
|
|
|
|
2020-12-16 00:35:54 +02:00
|
|
|
# shellcheck disable=SC1091
|
|
|
|
# SC1091: Not following: ... was not specified as input (see shellcheck -x).
|
|
|
|
|
2020-12-03 11:19:15 +02:00
|
|
|
# shellcheck disable=SC2034
|
|
|
|
# SC2034: ... appears unused. Verify use (or export if used externally).
|
|
|
|
|
|
|
|
# shellcheck disable=SC2039
|
|
|
|
# SC2039: In POSIX sh, 'local' is undefined.
|
|
|
|
|
|
|
|
# shellcheck disable=SC2153
|
|
|
|
# SC2153: Possible misspelling: ... may not be assigned, but ... is.
|
|
|
|
|
|
|
|
# shellcheck disable=SC2154
|
|
|
|
# SC2154: bin_path is referenced but not assigned.
|
|
|
|
|
|
|
|
# Exit with error if commands exit with non-zero and if undefined variables are
|
|
|
|
# used.
|
|
|
|
set -eu
|
|
|
|
|
2020-12-16 00:35:54 +02:00
|
|
|
# Include XML reporting library.
|
|
|
|
. "@abs_top_builddir@/src/lib/testutils/xml_reporting_test_lib.sh"
|
|
|
|
|
2020-12-03 11:19:15 +02:00
|
|
|
prefix="@prefix@"
|
|
|
|
|
|
|
|
# Expected version
|
|
|
|
EXPECTED_VERSION="@PACKAGE_VERSION@"
|
2014-06-09 18:19:43 +02:00
|
|
|
|
2020-12-11 18:49:43 +02:00
|
|
|
# A list of Kea processes, mainly used by the cleanup functions.
|
|
|
|
KEA_PROCS="kea-dhcp4 kea-dhcp6 kea-dhcp-ddns kea-ctrl-agent"
|
2020-12-10 22:18:47 +02:00
|
|
|
|
2020-12-13 21:31:56 +02:00
|
|
|
### Colors ###
|
|
|
|
|
|
|
|
if test -t 1; then
|
|
|
|
green='\033[92m'
|
|
|
|
red='\033[91m'
|
|
|
|
reset='\033[0m'
|
|
|
|
fi
|
|
|
|
|
2014-06-11 19:05:39 +02:00
|
|
|
### Logging functions ###
|
|
|
|
|
|
|
|
# Prints error message.
|
|
|
|
test_lib_error() {
|
2014-06-27 11:20:02 +02:00
|
|
|
local s=${1} # Error message.
|
|
|
|
local no_new_line=${2} # If specified, the message not terminated with
|
|
|
|
# new line.
|
|
|
|
printf "ERROR/test_lib: %s" "${s}"
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${no_new_line}" ]; then
|
|
|
|
printf '\n'
|
2014-06-27 11:20:02 +02:00
|
|
|
fi
|
2014-06-11 19:05:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Prints info message.
|
|
|
|
test_lib_info() {
|
2014-06-27 11:20:02 +02:00
|
|
|
local s=${1} # Info message.
|
|
|
|
local no_new_line=${2} # If specified, the message is not terminated with
|
|
|
|
# new line.
|
|
|
|
printf "INFO/test_lib: %s" "${s}"
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${no_new_line}" ]; then
|
|
|
|
printf '\n'
|
2014-06-27 11:20:02 +02:00
|
|
|
fi
|
2014-06-11 19:05:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
### Assertions ###
|
|
|
|
|
2014-06-11 11:23:27 +02:00
|
|
|
# Assertion that checks if two numbers are equal.
|
|
|
|
# If numbers are not equal, the mismatched values are presented and the
|
|
|
|
# detailed error is printed. The detailed error must use the printf
|
|
|
|
# formatting like this:
|
|
|
|
# "Expected that some value 1 %d is equal to some other value %d".
|
2014-06-09 18:19:43 +02:00
|
|
|
assert_eq() {
|
2014-06-11 11:23:27 +02:00
|
|
|
val1=${1} # Reference value
|
|
|
|
val2=${2} # Tested value
|
|
|
|
detailed_err=${3} # Detailed error format string
|
|
|
|
# If nothing found, present an error an exit.
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ "${val1}" -ne "${val2}" ]; then
|
2020-12-17 20:49:16 +02:00
|
|
|
printf "Assertion failure: %s != %s, for val1=%s, val2=%s\n" \
|
|
|
|
"${val1}" "${val2}" "${val1}" "${val2}"
|
|
|
|
# shellcheck disable=SC2059
|
|
|
|
# SC2059: Don't use variables in the printf format string. Use printf '..%s..' "$foo"
|
|
|
|
ERROR=$(printf "${detailed_err}" "${val1}" "${val2}")
|
|
|
|
printf '%s\n%s\n' "${ERROR}" "${OUTPUT}" >&2
|
2014-06-09 18:19:43 +02:00
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2014-11-05 14:36:25 +01:00
|
|
|
# Assertion that checks if two strings are equal.
|
|
|
|
# If numbers are not equal, the mismatched values are presented and the
|
|
|
|
# detailed error is printed. The detailed error must use the printf
|
|
|
|
# formatting like this:
|
|
|
|
# "Expected that some value 1 %d is equal to some other value %d".
|
|
|
|
assert_str_eq() {
|
|
|
|
val1=${1} # Reference value
|
|
|
|
val2=${2} # Tested value
|
|
|
|
detailed_err=${3} # Detailed error format string
|
|
|
|
# If nothing found, present an error an exit.
|
|
|
|
if [ "${val1}" != "${val2}" ]; then
|
2020-12-03 11:19:15 +02:00
|
|
|
printf 'Assertion failure: %s != %s, for val1=%s, val2=%s\n' \
|
|
|
|
"${val1}" "${val2}" "${val1}" "${val2}"
|
|
|
|
# shellcheck disable=SC2059
|
|
|
|
# SC2059: SC2059: Don't use variables in the printf format string. Use printf '..%s..' "$foo".
|
2020-12-17 20:49:16 +02:00
|
|
|
ERROR=$(printf "${detailed_err}" "${val1}" "${val2}")
|
|
|
|
printf '%s\n%s\n' "${ERROR}" "${OUTPUT}" >&2
|
2014-11-05 14:36:25 +01:00
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2014-06-11 11:23:27 +02:00
|
|
|
# Assertion that checks if one string contains another string.
|
|
|
|
# If assertion fails, both strings are displayed and the detailed
|
|
|
|
# error is printed. The detailed error must use the printf formatting
|
|
|
|
# like this:
|
|
|
|
# "Expected some string to contain this string: %s".
|
|
|
|
assert_string_contains() {
|
2014-06-26 21:19:10 +02:00
|
|
|
pattern="${1}" # Substring or awk pattern
|
|
|
|
text="${2}" # Text to be searched for substring
|
|
|
|
detailed_err="${3}" # Detailed error format string
|
2014-06-11 11:23:27 +02:00
|
|
|
# Search for a pattern
|
|
|
|
match=$( printf "%s" "${text}" | awk /"${pattern}"/ )
|
|
|
|
# If nothing found, present an error and exit.
|
|
|
|
if [ -z "${match}" ]; then
|
2020-12-17 20:49:16 +02:00
|
|
|
ERROR=$(printf \
|
|
|
|
"Assertion failure:
|
|
|
|
\"%s\"
|
2020-12-03 11:19:15 +02:00
|
|
|
|
|
|
|
does not contain pattern:
|
2020-12-17 20:49:16 +02:00
|
|
|
\"%s\"
|
2020-12-03 11:19:15 +02:00
|
|
|
|
2020-12-17 20:49:16 +02:00
|
|
|
${detailed_err}
|
|
|
|
" "${text}" "${pattern}" "${pattern}")
|
|
|
|
printf '%s\n%s\n' "${ERROR}" "${OUTPUT}" >&2
|
2014-06-11 11:23:27 +02:00
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2020-12-03 11:19:15 +02:00
|
|
|
# Runs all the given arguments as a single command. Maintains quoting. Places
|
|
|
|
# output in ${OUTPUT} and exit code in ${EXIT_CODE}. Does not support pipes and
|
|
|
|
# redirections. Support for them could be added through eval and single
|
|
|
|
# parameter assignment, but eval is not recommended.
|
|
|
|
# shellcheck disable=SC2034
|
|
|
|
# SC2034: ... appears unused. Verify use (or export if used externally).
|
2020-12-11 15:56:11 +02:00
|
|
|
run_command() {
|
2020-12-03 11:19:15 +02:00
|
|
|
if test -n "${DEBUG+x}"; then
|
|
|
|
printf '%s\n' "${*}" >&2
|
|
|
|
fi
|
|
|
|
set +e
|
|
|
|
OUTPUT=$("${@}")
|
|
|
|
EXIT_CODE=${?}
|
|
|
|
set -e
|
|
|
|
}
|
|
|
|
|
2020-12-07 17:32:41 +02:00
|
|
|
# Enable traps to print FAILED status when a command fails unexpectedly or when
|
|
|
|
# the user sends a SIGINT. Used in `test_start`.
|
|
|
|
traps_on() {
|
2020-12-13 21:31:56 +02:00
|
|
|
for t in HUP INT QUIT KILL TERM EXIT; do
|
|
|
|
# shellcheck disable=SC2064
|
|
|
|
# SC2064: Use single quotes, otherwise this expands now rather than when signalled.
|
|
|
|
# reason: we want ${red-} and ${reset-} to expand here, at trap-time
|
|
|
|
# they will be empty or have other values
|
|
|
|
trap "
|
|
|
|
exit_code=\${?}
|
|
|
|
printf '${red-}[ FAILED ]${reset-} %s (exit code: %d)\n' \
|
|
|
|
\"\${TEST_NAME}\" \"\${exit_code}\"
|
|
|
|
" "${t}"
|
|
|
|
done
|
2020-12-07 17:32:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Disable traps so that a double status is not printed. Used in `test_finish`
|
|
|
|
# after the status has been printed explicitly.
|
|
|
|
traps_off() {
|
2020-12-13 21:31:56 +02:00
|
|
|
for t in HUP INT QUIT KILL TERM EXIT; do
|
|
|
|
trap - "${t}"
|
|
|
|
done
|
2020-12-07 17:32:41 +02:00
|
|
|
}
|
|
|
|
|
2020-12-16 00:35:54 +02:00
|
|
|
# Print UNIX time with millisecond resolution.
|
|
|
|
get_current_time() {
|
|
|
|
local time
|
|
|
|
time=$(date +%s%3N)
|
|
|
|
|
|
|
|
# In some systems, particularly BSD-based, `+%3N` millisecond resolution is
|
|
|
|
# not supported. It instead prints the literal '3N', but we check for any
|
|
|
|
# alphabetical character. If we do find one, revert to second resolution and
|
|
|
|
# convert to milliseconds.
|
|
|
|
if printf '%s' "${time}" | grep -E '[A-Za-z]' > /dev/null 2>&1; then
|
|
|
|
time=$(date +%s)
|
|
|
|
time=$((1000 * time))
|
|
|
|
fi
|
|
|
|
|
|
|
|
printf '%s' "${time}"
|
|
|
|
}
|
|
|
|
|
2017-07-23 15:36:14 -04:00
|
|
|
# Begins a test by printing its name.
|
2014-05-23 16:21:38 +02:00
|
|
|
test_start() {
|
2014-06-11 19:05:39 +02:00
|
|
|
TEST_NAME=${1}
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${TEST_NAME}" ]; then
|
2014-06-11 19:05:39 +02:00
|
|
|
test_lib_error "test_start requires test name as an argument"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
2020-12-07 17:32:41 +02:00
|
|
|
|
|
|
|
# Set traps first to fail if something goes wrong.
|
|
|
|
traps_on
|
|
|
|
|
|
|
|
# Announce test start.
|
2020-12-13 21:31:56 +02:00
|
|
|
printf "${green-}[ RUN ]${reset-} %s\n" "${TEST_NAME}"
|
2020-12-16 00:35:54 +02:00
|
|
|
|
2020-12-17 20:49:16 +02:00
|
|
|
# Reset variables that are used in error reporting.
|
|
|
|
ERROR=
|
|
|
|
OUTPUT=
|
|
|
|
|
2020-12-16 00:35:54 +02:00
|
|
|
# Start timer in milliseconds.
|
|
|
|
START_TIME=$(get_current_time)
|
2014-05-23 16:21:38 +02:00
|
|
|
}
|
|
|
|
|
2014-06-11 19:05:39 +02:00
|
|
|
# Prints test result an cleans up after the test.
|
2014-06-11 11:23:27 +02:00
|
|
|
test_finish() {
|
2020-12-16 00:35:54 +02:00
|
|
|
# Exit code to be returned by the exit function
|
|
|
|
local exit_code=${1}
|
|
|
|
|
|
|
|
# Stop timer and set duration.
|
|
|
|
FINISH_TIME=$(get_current_time)
|
|
|
|
local duration
|
|
|
|
duration=$((FINISH_TIME - START_TIME))
|
|
|
|
|
|
|
|
# Add the test result to the XML.
|
|
|
|
report_test_result_in_xml "${TEST_NAME}" "${exit_code}" "${duration}"
|
|
|
|
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ "${exit_code}" -eq 0 ]; then
|
2014-06-11 11:23:27 +02:00
|
|
|
cleanup
|
2020-12-14 10:44:03 +01:00
|
|
|
printf "${green-}[ OK ]${reset-} %s\n" "${TEST_NAME}"
|
2014-06-11 11:23:27 +02:00
|
|
|
else
|
2014-11-05 20:46:51 +01:00
|
|
|
# Dump log file for debugging purposes if specified and exists.
|
|
|
|
# Otherwise the code below would simply call cat.
|
2020-12-11 16:23:27 +02:00
|
|
|
# Use ${var+x} to test if ${var} is defined.
|
2020-12-03 11:19:15 +02:00
|
|
|
if test -n "${LOG_FILE+x}" && test -s "${LOG_FILE}"; then
|
|
|
|
printf 'Log file dump:\n'
|
|
|
|
cat "${LOG_FILE}"
|
2014-06-11 11:23:27 +02:00
|
|
|
fi
|
|
|
|
cleanup
|
2020-12-13 21:31:56 +02:00
|
|
|
printf "${red-}[ FAILED ]${reset-} %s\n" "${TEST_NAME}"
|
2014-06-11 11:23:27 +02:00
|
|
|
fi
|
2020-12-07 17:32:41 +02:00
|
|
|
|
|
|
|
# Reset traps.
|
|
|
|
traps_off
|
2020-12-11 21:13:47 +02:00
|
|
|
|
|
|
|
# Explicitly return ${exit_code}. The effect should be for `make check` to
|
|
|
|
# return with the exit same code or at least another non-zero exit code thus
|
|
|
|
# reporting a failure.
|
|
|
|
return "${exit_code}"
|
2014-06-11 11:23:27 +02:00
|
|
|
}
|
|
|
|
|
2014-05-23 16:21:38 +02:00
|
|
|
# Stores the configuration specified as a parameter in the configuration
|
|
|
|
# file which name has been set in the ${CFG_FILE} variable.
|
|
|
|
create_config() {
|
2014-06-26 21:19:10 +02:00
|
|
|
local cfg="${1}" # Configuration string.
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${CFG_FILE}" ]; then
|
2014-06-11 19:05:39 +02:00
|
|
|
test_lib_error "create_config requires CFG_FILE variable be set"
|
|
|
|
clean_exit 1
|
|
|
|
|
|
|
|
elif [ -z "${cfg}" ]; then
|
|
|
|
test_lib_error "create_config requires argument holding a configuration"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
2020-12-03 11:19:15 +02:00
|
|
|
printf 'Creating Kea configuration file: %s.\n' "${CFG_FILE}"
|
|
|
|
printf '%b' "${cfg}" > "${CFG_FILE}"
|
2014-05-23 16:21:38 +02:00
|
|
|
}
|
|
|
|
|
2019-01-08 23:35:58 +01:00
|
|
|
# Stores the DHCP4 configuration specified as a parameter in the
|
|
|
|
# configuration file which name has been set in the ${DHCP4_CFG_FILE}
|
2018-12-06 16:45:55 +01:00
|
|
|
# variable.
|
2019-01-08 23:35:58 +01:00
|
|
|
create_dhcp4_config() {
|
2018-12-06 16:45:55 +01:00
|
|
|
local cfg="${1}" # Configuration string.
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${DHCP4_CFG_FILE}" ]; then
|
2019-01-08 23:35:58 +01:00
|
|
|
test_lib_error "create_dhcp4_config requires DHCP4_CFG_FILE \
|
2018-12-06 16:45:55 +01:00
|
|
|
variable be set"
|
|
|
|
clean_exit 1
|
|
|
|
|
|
|
|
elif [ -z "${cfg}" ]; then
|
2019-01-08 23:35:58 +01:00
|
|
|
test_lib_error "create_dhcp4_config requires argument holding a \
|
2018-12-06 16:45:55 +01:00
|
|
|
configuration"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
2020-12-03 11:19:15 +02:00
|
|
|
printf 'Creating Dhcp4 configuration file: %s.\n' "${DHCP4_CFG_FILE}"
|
|
|
|
printf '%b' "${cfg}" > "${DHCP4_CFG_FILE}"
|
2019-01-08 23:35:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Stores the DHCP6 configuration specified as a parameter in the
|
|
|
|
# configuration file which name has been set in the ${DHCP6_CFG_FILE}
|
|
|
|
# variable.
|
|
|
|
create_dhcp6_config() {
|
|
|
|
local cfg="${1}" # Configuration string.
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${DHCP6_CFG_FILE}" ]; then
|
2019-01-08 23:35:58 +01:00
|
|
|
test_lib_error "create_dhcp6_config requires DHCP6_CFG_FILE \
|
|
|
|
variable be set"
|
|
|
|
clean_exit 1
|
|
|
|
|
|
|
|
elif [ -z "${cfg}" ]; then
|
|
|
|
test_lib_error "create_dhcp6_config requires argument holding a \
|
|
|
|
configuration"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
2020-12-03 11:19:15 +02:00
|
|
|
printf 'Creating Dhcp6 configuration file: %s.\n' "${DHCP6_CFG_FILE}"
|
|
|
|
printf '%b' "${cfg}" > "${DHCP6_CFG_FILE}"
|
2019-01-08 23:35:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Stores the D2 configuration specified as a parameter in the
|
|
|
|
# configuration file which name has been set in the ${D2_CFG_FILE}
|
|
|
|
# variable.
|
|
|
|
create_d2_config() {
|
|
|
|
local cfg="${1}" # Configuration string.
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${D2_CFG_FILE}" ]; then
|
2019-01-08 23:35:58 +01:00
|
|
|
test_lib_error "create_d2_config requires D2_CFG_FILE \
|
|
|
|
variable be set"
|
|
|
|
clean_exit 1
|
|
|
|
|
|
|
|
elif [ -z "${cfg}" ]; then
|
|
|
|
test_lib_error "create_d2_config requires argument holding a \
|
|
|
|
configuration"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
2020-12-03 11:19:15 +02:00
|
|
|
printf 'Creating D2 configuration file: %s.\n' "${D2_CFG_FILE}"
|
|
|
|
printf '%b' "${cfg}" > "${D2_CFG_FILE}"
|
2019-01-08 23:35:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Stores the CA configuration specified as a parameter in the
|
|
|
|
# configuration file which name has been set in the ${CA_CFG_FILE}
|
|
|
|
# variable.
|
|
|
|
create_ca_config() {
|
|
|
|
local cfg="${1}" # Configuration string.
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${CA_CFG_FILE}" ]; then
|
2019-01-08 23:35:58 +01:00
|
|
|
test_lib_error "create_ca_config requires CA_CFG_FILE \
|
|
|
|
variable be set"
|
|
|
|
clean_exit 1
|
|
|
|
|
|
|
|
elif [ -z "${cfg}" ]; then
|
|
|
|
test_lib_error "create_ca_config requires argument holding a \
|
|
|
|
configuration"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
2020-12-03 11:19:15 +02:00
|
|
|
printf 'Creating Ca configuration file: %s.\n' "${CA_CFG_FILE}"
|
|
|
|
printf '%b' "${cfg}" > "${CA_CFG_FILE}"
|
2019-01-08 23:35:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Stores the NC configuration specified as a parameter in the
|
|
|
|
# configuration file which name has been set in the ${NC_CFG_FILE}
|
|
|
|
# variable.
|
|
|
|
create_nc_config() {
|
|
|
|
local cfg="${1}" # Configuration string.
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${NC_CFG_FILE}" ]; then
|
2019-01-08 23:35:58 +01:00
|
|
|
test_lib_error "create_nc_config requires NC_CFG_FILE \
|
|
|
|
variable be set"
|
|
|
|
clean_exit 1
|
|
|
|
|
|
|
|
elif [ -z "${cfg}" ]; then
|
|
|
|
test_lib_error "create_nc_config requires argument holding a \
|
|
|
|
configuration"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
2020-12-03 11:19:15 +02:00
|
|
|
printf 'Creating Nc configuration file: %s.\n' "${NC_CFG_FILE}"
|
|
|
|
printf '%b' "${cfg}" > "${NC_CFG_FILE}"
|
2018-12-06 16:45:55 +01:00
|
|
|
}
|
|
|
|
|
2014-06-11 19:05:39 +02:00
|
|
|
# Stores the keactrl configuration specified as a parameter in the
|
|
|
|
# configuration file which name has been set in the ${KEACTRL_CFG_FILE}
|
|
|
|
# variable.
|
2014-06-09 18:19:43 +02:00
|
|
|
create_keactrl_config() {
|
2014-06-26 21:19:10 +02:00
|
|
|
local cfg="${1}" # Configuration string.
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${KEACTRL_CFG_FILE}" ]; then
|
2014-06-11 19:05:39 +02:00
|
|
|
test_lib_error "create_keactrl_config requires KEACTRL_CFG_FILE \
|
|
|
|
variable be set"
|
|
|
|
clean_exit 1
|
|
|
|
|
|
|
|
elif [ -z "${cfg}" ]; then
|
|
|
|
test_lib_error "create_keactrl_config requires argument holding a \
|
|
|
|
configuration"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
2020-12-03 11:19:15 +02:00
|
|
|
printf 'Creating keactrl configuration file: %s.\n' "${KEACTRL_CFG_FILE}"
|
|
|
|
printf '%b' "${cfg}" > "${KEACTRL_CFG_FILE}"
|
2014-06-09 18:19:43 +02:00
|
|
|
}
|
|
|
|
|
2014-05-23 16:21:38 +02:00
|
|
|
# Sets Kea logger to write to the file specified by the global value
|
|
|
|
# ${LOG_FILE}.
|
|
|
|
set_logger() {
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${LOG_FILE}" ]; then
|
2017-07-23 16:04:51 -04:00
|
|
|
test_lib_error "set_logger requires LOG_FILE variable be set"
|
2014-06-11 19:05:39 +02:00
|
|
|
clean_exit 1
|
|
|
|
fi
|
2020-12-03 11:19:15 +02:00
|
|
|
printf 'Kea log will be stored in %s.\n' "${LOG_FILE}"
|
2014-08-06 12:46:00 +02:00
|
|
|
export KEA_LOGGER_DESTINATION=${LOG_FILE}
|
2014-05-23 16:21:38 +02:00
|
|
|
}
|
|
|
|
|
2019-05-31 17:29:29 +02:00
|
|
|
# PID file path is by default <kea-install-dir>/var/run/kea, but can be
|
2017-07-23 15:19:44 -04:00
|
|
|
# overridden by the environmental variable.
|
2020-12-03 11:19:15 +02:00
|
|
|
PID_FILE_PATH="@runstatedir@/@PACKAGE@/"
|
2020-12-11 16:23:27 +02:00
|
|
|
# Use ${var+x} to test if ${var} is defined.
|
|
|
|
if test -n "${KEA_PIDFILE_DIR+x}" && test -n "${KEA_PIDFILE_DIR}"; then
|
2015-12-11 15:26:44 +01:00
|
|
|
PID_FILE_PATH="${KEA_PIDFILE_DIR}"
|
|
|
|
fi
|
|
|
|
|
2015-12-15 20:42:36 +01:00
|
|
|
# Checks if specified process is running.
|
|
|
|
#
|
|
|
|
# This function uses PID file to obtain the PID and then calls
|
|
|
|
# 'kill -0 <pid>' to check if the process is alive.
|
|
|
|
# The PID files are expected to be located in the ${PID_FILE_PATH},
|
2017-01-24 20:32:40 +01:00
|
|
|
# and their names should match the following pattern:
|
2015-12-15 20:42:36 +01:00
|
|
|
# <cfg_file_name>.<proc_name>.pid. If the <cfg_file_name> is not
|
|
|
|
# specified a 'test_config' is used by default.
|
|
|
|
#
|
|
|
|
# Return value:
|
2015-12-11 15:26:44 +01:00
|
|
|
# _GET_PID: holds a PID if process is running
|
2015-12-15 20:42:36 +01:00
|
|
|
# _GET_PIDS_NUM: holds 1 if process is running, 0 otherwise
|
2015-12-11 15:26:44 +01:00
|
|
|
get_pid() {
|
2020-12-03 11:19:15 +02:00
|
|
|
local proc_name=${1} # Process name
|
|
|
|
local cfg_file_name=${2-} # Configuration file name without extension.
|
2015-12-11 15:26:44 +01:00
|
|
|
|
|
|
|
# PID file name includes process name. The process name is required.
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${proc_name}" ]; then
|
2015-12-11 15:26:44 +01:00
|
|
|
test_lib_error "get_pid requires process name"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# PID file name includes server configuration file name. For most of
|
|
|
|
# the tests it is 'test-config' (excluding .json extension). It is
|
|
|
|
# possible to specify custom name if required.
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${cfg_file_name}" ]; then
|
2015-12-11 15:26:44 +01:00
|
|
|
cfg_file_name="test_config"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Get the absolute location of the PID file for the specified process
|
|
|
|
# name.
|
|
|
|
abs_pidfile_path="${PID_FILE_PATH}/${cfg_file_name}.${proc_name}.pid"
|
|
|
|
_GET_PID=0
|
|
|
|
_GET_PIDS_NUM=0
|
|
|
|
|
|
|
|
# If the PID file exists, get the PID and see if the process is alive.
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -e "${abs_pidfile_path}" ]; then
|
|
|
|
pid=$(cat "${abs_pidfile_path}")
|
|
|
|
if kill -0 "${pid}" > /dev/null 2>&1; then
|
2015-12-11 15:26:44 +01:00
|
|
|
_GET_PID=${pid}
|
|
|
|
_GET_PIDS_NUM=1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2020-12-10 22:18:47 +02:00
|
|
|
# Get the name of the process identified by PID.
|
|
|
|
get_process_name() {
|
|
|
|
local pid=${1}
|
|
|
|
ps "${pid}" | tr -s ' ' | cut -d ' ' -f 6- | head -n 2 | tail -n 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# Wait for file to be created.
|
|
|
|
wait_for_file() {
|
|
|
|
local file=${1}
|
2020-12-14 19:12:25 +02:00
|
|
|
timeout='4' # seconds
|
|
|
|
deadline=$(($(date +%s) + timeout))
|
2020-12-11 19:47:09 +02:00
|
|
|
while ! test -f "${file}"; do
|
2020-12-10 22:18:47 +02:00
|
|
|
if test "${deadline}" -lt "$(date +%s)"; then
|
|
|
|
# Time is up.
|
|
|
|
printf 'ERROR: file "%s" was not created in time.\n' "${file}" >&2
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
printf 'Waiting for file "%s" to be created...\n' "${file}"
|
2020-12-17 16:56:09 +02:00
|
|
|
sleep 1
|
2020-12-10 22:18:47 +02:00
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
# Wait for process identified by PID to die.
|
|
|
|
wait_for_process_to_die() {
|
|
|
|
local pid=${1}
|
2020-12-14 19:12:25 +02:00
|
|
|
timeout='4' # seconds
|
|
|
|
deadline=$(($(date +%s) + timeout))
|
2020-12-10 22:18:47 +02:00
|
|
|
while ps "${pid}" >/dev/null; do
|
|
|
|
if test "${deadline}" -lt "$(date +%s)"; then
|
|
|
|
# Time is up.
|
|
|
|
printf 'ERROR: %s does not want to die.\n' "$(get_process_name "${pid}")" >&2
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
printf 'Waiting for %s to die...\n' "$(get_process_name "${pid}")"
|
2020-12-17 16:56:09 +02:00
|
|
|
sleep 1
|
2020-12-10 22:18:47 +02:00
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2015-12-18 17:40:00 +01:00
|
|
|
# Kills processes specified by name.
|
|
|
|
#
|
|
|
|
# This function kills all processes having a specified name.
|
|
|
|
# It uses 'pgrep' to obtain pids of those processes.
|
|
|
|
# This function should be used when identifying process by
|
|
|
|
# the value in its PID file is not relevant.
|
2020-12-11 19:02:04 +02:00
|
|
|
#
|
|
|
|
# Linux limitation for pgrep: The process name used for matching is
|
|
|
|
# limited to the 15 characters. If you call this with long process
|
|
|
|
# names, add this before pgrep:
|
|
|
|
# proc_name=$(printf '%s' "${proc_name}" | cut -c1-15)
|
2015-12-21 10:14:10 -05:00
|
|
|
kill_processes_by_name() {
|
2015-12-18 17:40:00 +01:00
|
|
|
local proc_name=${1} # Process name
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${proc_name}" ]; then
|
2015-12-18 17:40:00 +01:00
|
|
|
test_lib_error "get_pids requires process name"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
# Obtain PIDs of running processes.
|
2020-12-03 11:19:15 +02:00
|
|
|
local pids
|
2020-12-11 19:02:04 +02:00
|
|
|
pids=$(pgrep "${proc_name}" || true)
|
2015-12-18 17:40:00 +01:00
|
|
|
# For each PID found, send kill signal.
|
|
|
|
for pid in ${pids}
|
|
|
|
do
|
2020-12-03 11:19:15 +02:00
|
|
|
printf 'Shutting down Kea process %s having pid %d.\n' "${proc_name}" "${pid}"
|
|
|
|
kill -9 "${pid}"
|
2015-12-18 17:40:00 +01:00
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2014-06-11 19:05:39 +02:00
|
|
|
# Returns the number of occurrences of the Kea log message in the log file.
|
|
|
|
# Return value:
|
|
|
|
# _GET_LOG_MESSAGES: number of log message occurrences.
|
2014-05-23 16:21:38 +02:00
|
|
|
get_log_messages() {
|
2014-06-26 21:19:10 +02:00
|
|
|
local msg="${1}" # Message id, e.g. DHCP6_SHUTDOWN
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${msg}" ]; then
|
2014-06-11 19:05:39 +02:00
|
|
|
test_lib_error "get_log_messages require message identifier"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
2014-06-09 18:19:43 +02:00
|
|
|
_GET_LOG_MESSAGES=0
|
2014-06-11 19:05:39 +02:00
|
|
|
# If log file is not present, the number of occurrences is 0.
|
2020-12-11 16:23:27 +02:00
|
|
|
# Use ${var+x} to test if ${var} is defined.
|
2020-12-03 11:19:15 +02:00
|
|
|
if test -n "${LOG_FILE+x}" && test -s "${LOG_FILE}"; then
|
2015-02-27 10:48:45 +01:00
|
|
|
# Grep log file for the logger message occurrences and remove
|
|
|
|
# whitespaces, if any.
|
2020-12-03 11:19:15 +02:00
|
|
|
_GET_LOG_MESSAGES=$(grep -Fo "${msg}" "${LOG_FILE}" | wc -w | tr -d " ")
|
2014-06-09 18:19:43 +02:00
|
|
|
fi
|
2014-05-23 16:21:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Returns the number of server configurations performed so far. Also
|
|
|
|
# returns the number of configuration errors.
|
2014-06-11 19:05:39 +02:00
|
|
|
# Return values:
|
|
|
|
# _GET_RECONFIGS: number of configurations so far.
|
|
|
|
# _GET_RECONFIG_ERRORS: number of configuration errors.
|
2014-05-23 16:21:38 +02:00
|
|
|
get_reconfigs() {
|
2017-01-24 20:32:40 +01:00
|
|
|
# Grep log file for CONFIG_COMPLETE occurrences. There should
|
|
|
|
# be one occurrence per (re)configuration.
|
2020-12-03 11:19:15 +02:00
|
|
|
_GET_RECONFIGS=$(grep -Fo CONFIG_COMPLETE "${LOG_FILE}" | wc -w)
|
2014-06-11 19:05:39 +02:00
|
|
|
# Grep log file for CONFIG_LOAD_FAIL to check for configuration
|
2014-05-23 16:21:38 +02:00
|
|
|
# failures.
|
2020-12-03 11:19:15 +02:00
|
|
|
_GET_RECONFIG_ERRORS=$(grep -Fo CONFIG_LOAD_FAIL "${LOG_FILE}" | wc -w)
|
2014-05-23 16:21:38 +02:00
|
|
|
# Remove whitespaces
|
|
|
|
${_GET_RECONFIGS##*[! ]}
|
|
|
|
${_GET_RECONFIG_ERRORS##*[! ]}
|
|
|
|
}
|
|
|
|
|
2021-01-07 00:57:49 +02:00
|
|
|
# Remove the given directories or files if they exist.
|
2020-12-03 11:19:15 +02:00
|
|
|
remove_if_exists() {
|
2021-01-07 00:57:49 +02:00
|
|
|
while test ${#} -gt 0; do
|
|
|
|
if test -e "${1}"; then
|
2020-12-03 11:19:15 +02:00
|
|
|
rm -rf "${1}"
|
|
|
|
fi
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2014-06-11 19:05:39 +02:00
|
|
|
# Performs cleanup after test.
|
2014-05-23 16:21:38 +02:00
|
|
|
# It shuts down running Kea processes and removes temporary files.
|
2014-06-11 19:05:39 +02:00
|
|
|
# The location of the log file and the configuration files should be set
|
2014-06-09 18:19:43 +02:00
|
|
|
# in the ${LOG_FILE}, ${CFG_FILE} and ${KEACTRL_CFG_FILE} variables
|
2017-07-23 16:00:28 -04:00
|
|
|
# respectively, prior to calling this function.
|
2014-05-23 16:21:38 +02:00
|
|
|
cleanup() {
|
2014-11-05 20:46:51 +01:00
|
|
|
# If there is no KEA_PROCS set, just return
|
|
|
|
if [ -z "${KEA_PROCS}" ]; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
2014-06-11 19:05:39 +02:00
|
|
|
# KEA_PROCS holds the name of all Kea processes. Shut down each
|
|
|
|
# of them if running.
|
2014-06-09 18:19:43 +02:00
|
|
|
for proc_name in ${KEA_PROCS}
|
2014-05-23 16:21:38 +02:00
|
|
|
do
|
2020-12-03 11:19:15 +02:00
|
|
|
get_pid "${proc_name}"
|
2015-12-11 15:26:44 +01:00
|
|
|
# Shut down running Kea process.
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ "${_GET_PIDS_NUM}" -ne 0 ]; then
|
|
|
|
printf 'Shutting down Kea process having pid %d.\n' "${_GET_PID}"
|
|
|
|
kill -9 "${_GET_PID}"
|
2015-12-11 15:26:44 +01:00
|
|
|
fi
|
2014-05-23 16:21:38 +02:00
|
|
|
done
|
2014-11-05 20:46:51 +01:00
|
|
|
|
2015-12-18 17:40:00 +01:00
|
|
|
# Kill any running LFC processes. Even though 'kea-lfc' creates PID
|
|
|
|
# file we rather want to use 'pgrep' to find the process PID, because
|
|
|
|
# kea-lfc execution is not controlled from the test and thus there
|
|
|
|
# is possibility that process is already/still running but the PID
|
|
|
|
# file doesn't exist for it. As a result, the process will not
|
|
|
|
# be killed. This is not a problem for other processes because
|
|
|
|
# tests control launching them and monitor when they are shut down.
|
2015-12-21 10:14:10 -05:00
|
|
|
kill_processes_by_name "kea-lfc"
|
2015-12-18 17:40:00 +01:00
|
|
|
|
2014-05-23 16:21:38 +02:00
|
|
|
# Remove temporary files.
|
2020-12-11 16:49:18 +02:00
|
|
|
remove_if_exists \
|
|
|
|
"${CA_CFG_FILE-}" \
|
|
|
|
"${CFG_FILE-}" \
|
|
|
|
"${D2_CFG_FILE-}" \
|
|
|
|
"${DHCP4_CFG_FILE-}" \
|
|
|
|
"${DHCP6_CFG_FILE-}" \
|
|
|
|
"${KEACTRL_CFG_FILE-}" \
|
|
|
|
"${NC_CFG_FILE-}"
|
|
|
|
|
2020-12-11 16:23:27 +02:00
|
|
|
# Use ${var+x} to test if ${var} is defined.
|
|
|
|
if test -n "${LOG_FILE+x}" && test -n "${LOG_FILE}"; then
|
2020-12-03 11:19:15 +02:00
|
|
|
rm -rf "${LOG_FILE}"
|
|
|
|
rm -rf "${LOG_FILE}.lock"
|
|
|
|
fi
|
2015-09-28 14:45:46 +02:00
|
|
|
# Use asterisk to remove all files starting with the given name,
|
|
|
|
# in case the LFC has been run. LFC creates files with postfixes
|
|
|
|
# appended to the lease file name.
|
2020-12-11 16:23:27 +02:00
|
|
|
if test -n "${LEASE_FILE+x}" && test -n "${LEASE_FILE}"; then
|
2020-12-03 11:19:15 +02:00
|
|
|
rm -rf "${LEASE_FILE}"*
|
|
|
|
fi
|
2014-05-23 16:21:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Exists the test in the clean way.
|
2017-07-23 15:27:45 -04:00
|
|
|
# It performs the cleanup and prints whether the test has passed or failed.
|
2014-05-23 16:21:38 +02:00
|
|
|
# If a test fails, the Kea log is dumped.
|
|
|
|
clean_exit() {
|
2014-05-28 13:08:14 +02:00
|
|
|
exit_code=${1} # Exit code to be returned by the exit function.
|
2014-06-11 19:05:39 +02:00
|
|
|
case ${exit_code} in
|
|
|
|
''|*[!0-9]*)
|
|
|
|
test_lib_error "argument passed to clean_exit must be a number" ;;
|
|
|
|
esac
|
2014-06-11 11:23:27 +02:00
|
|
|
# Print test result and perform a cleanup
|
2020-12-03 11:19:15 +02:00
|
|
|
test_finish "${exit_code}"
|
|
|
|
exit "${exit_code}"
|
2014-05-23 16:21:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Starts Kea process in background using a configuration file specified
|
2014-06-11 19:05:39 +02:00
|
|
|
# in the global variable ${CFG_FILE}.
|
2014-05-23 16:21:38 +02:00
|
|
|
start_kea() {
|
2014-06-13 10:46:13 +02:00
|
|
|
local bin=${1}
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${bin}" ]; then
|
2014-06-11 19:05:39 +02:00
|
|
|
test_lib_error "binary name must be specified for start_kea"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
printf "Running command %s.\n" "\"${bin} -c ${CFG_FILE}\""
|
2020-12-03 11:19:15 +02:00
|
|
|
"${bin}" -c "${CFG_FILE}" &
|
2014-05-23 16:21:38 +02:00
|
|
|
}
|
|
|
|
|
2014-06-11 19:05:39 +02:00
|
|
|
# Waits with timeout for Kea to start.
|
2017-07-23 11:48:05 -04:00
|
|
|
# This function repeatedly checks if the Kea log file has been created
|
2014-05-23 16:21:38 +02:00
|
|
|
# and is non-empty. If it is, the function assumes that Kea has started.
|
2014-05-28 13:08:14 +02:00
|
|
|
# It doesn't check the contents of the log file though.
|
2014-05-23 16:21:38 +02:00
|
|
|
# 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.
|
2014-06-11 19:05:39 +02:00
|
|
|
# Return value:
|
|
|
|
# _WAIT_FOR_KEA: 0 if Kea hasn't started, 1 otherwise
|
2014-05-23 16:21:38 +02:00
|
|
|
wait_for_kea() {
|
2014-06-11 19:05:39 +02:00
|
|
|
local timeout=${1} # Desired timeout in seconds.
|
|
|
|
case ${timeout} in
|
|
|
|
''|*[!0-9]*)
|
|
|
|
test_lib_error "argument passed to wait_for_kea must be a number"
|
|
|
|
clean_exit 1 ;;
|
|
|
|
esac
|
|
|
|
local loops=0 # Loops counter
|
2014-05-23 16:21:38 +02:00
|
|
|
_WAIT_FOR_KEA=0
|
2014-06-27 11:20:02 +02:00
|
|
|
test_lib_info "wait_for_kea " "skip-new-line"
|
2020-12-03 11:19:15 +02:00
|
|
|
while [ ! -s "${LOG_FILE}" ] && [ "${loops}" -le "${timeout}" ]; do
|
2014-05-23 16:21:38 +02:00
|
|
|
printf "."
|
|
|
|
sleep 1
|
2020-12-03 11:19:15 +02:00
|
|
|
loops=$(( loops + 1 ))
|
2014-05-23 16:21:38 +02:00
|
|
|
done
|
2020-12-03 11:19:15 +02:00
|
|
|
printf '\n'
|
|
|
|
if [ "${loops}" -le "${timeout}" ]; then
|
2014-05-23 16:21:38 +02:00
|
|
|
_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.
|
2014-05-23 16:53:32 +02:00
|
|
|
# This function waits a specified number of seconds for the number
|
|
|
|
# of message occurrences to show up. If the expected number of
|
|
|
|
# message doesn't occur, the error status is returned.
|
2014-06-11 19:05:39 +02:00
|
|
|
# Return value:
|
2017-01-24 20:32:40 +01:00
|
|
|
# _WAIT_FOR_MESSAGE: 0 if the message hasn't occurred, 1 otherwise.
|
2014-05-23 16:21:38 +02:00
|
|
|
wait_for_message() {
|
2014-06-11 19:05:39 +02:00
|
|
|
local timeout=${1} # Expected timeout value in seconds.
|
2014-06-26 21:19:10 +02:00
|
|
|
local message="${2}" # Expected message id.
|
2014-06-11 19:05:39 +02:00
|
|
|
local occurrences=${3} # Number of expected occurrences.
|
|
|
|
|
|
|
|
# Validate timeout
|
|
|
|
case ${timeout} in
|
|
|
|
''|*[!0-9]*)
|
|
|
|
test_lib_error "argument timeout passed to wait_for_message must \
|
|
|
|
be a number"
|
|
|
|
clean_exit 1 ;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
# Validate message
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${message}" ]; then
|
2014-06-11 19:05:39 +02:00
|
|
|
test_lib_error "message id is a required argument for wait_for_message"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Validate occurrences
|
|
|
|
case ${occurrences} in
|
|
|
|
''|*[!0-9]*)
|
|
|
|
test_lib_error "argument occurrences passed to wait_for_message \
|
|
|
|
must be a number"
|
|
|
|
clean_exit 1 ;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
local loops=0 # Number of loops performed so far.
|
2014-05-23 16:21:38 +02:00
|
|
|
_WAIT_FOR_MESSAGE=0
|
2014-06-27 11:20:02 +02:00
|
|
|
test_lib_info "wait_for_message ${message}: " "skip-new-line"
|
2014-05-23 16:21:38 +02:00
|
|
|
# Check if log file exists and if we reached timeout.
|
2020-12-03 11:19:15 +02:00
|
|
|
while [ "${loops}" -le "${timeout}" ]; do
|
2014-05-23 17:07:03 +02:00
|
|
|
printf "."
|
2014-05-23 16:21:38 +02:00
|
|
|
# Check if the message has been logged.
|
2020-12-03 11:19:15 +02:00
|
|
|
get_log_messages "${message}"
|
|
|
|
if [ "${_GET_LOG_MESSAGES}" -ge "${occurrences}" ]; then
|
|
|
|
printf '\n'
|
2014-05-28 13:08:14 +02:00
|
|
|
_WAIT_FOR_MESSAGE=1
|
2014-05-23 16:21:38 +02:00
|
|
|
return
|
|
|
|
fi
|
|
|
|
# Message not recorded. Keep going.
|
|
|
|
sleep 1
|
2020-12-03 11:19:15 +02:00
|
|
|
loops=$(( loops + 1 ))
|
2014-05-23 16:21:38 +02:00
|
|
|
done
|
2020-12-03 11:19:15 +02:00
|
|
|
printf '\n'
|
2014-05-23 16:21:38 +02:00
|
|
|
# Timeout.
|
|
|
|
}
|
|
|
|
|
2014-06-27 11:20:02 +02:00
|
|
|
# Waits for server to be down.
|
|
|
|
# Return value:
|
2017-01-24 20:32:40 +01:00
|
|
|
# _WAIT_FOR_SERVER_DOWN: 1 if server is down, 0 if timeout occurred and the
|
2014-06-27 11:20:02 +02:00
|
|
|
# server is still running.
|
|
|
|
wait_for_server_down() {
|
|
|
|
local timeout=${1} # Timeout specified in seconds.
|
|
|
|
local proc_name=${2} # Server process name.
|
|
|
|
|
|
|
|
case ${timeout} in
|
|
|
|
''|*[!0-9]*)
|
|
|
|
test_lib_error "argument passed to wait_for_server_down must be a number"
|
|
|
|
clean_exit 1 ;;
|
|
|
|
esac
|
|
|
|
local loops=0 # Loops counter
|
|
|
|
_WAIT_FOR_SERVER_DOWN=0
|
|
|
|
test_lib_info "wait_for_server_down ${proc_name}: " "skip-new-line"
|
2020-12-03 11:19:15 +02:00
|
|
|
while [ "${loops}" -le "${timeout}" ]; do
|
2014-06-27 11:20:02 +02:00
|
|
|
printf "."
|
2020-12-03 11:19:15 +02:00
|
|
|
get_pid "${proc_name}"
|
|
|
|
if [ "${_GET_PIDS_NUM}" -eq 0 ]; then
|
|
|
|
printf '\n'
|
2014-06-27 11:20:02 +02:00
|
|
|
_WAIT_FOR_SERVER_DOWN=1
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
sleep 1
|
2020-12-03 11:19:15 +02:00
|
|
|
loops=$(( loops + 1 ))
|
2014-06-27 11:20:02 +02:00
|
|
|
done
|
2020-12-03 11:19:15 +02:00
|
|
|
printf '\n'
|
2014-06-27 11:20:02 +02:00
|
|
|
}
|
|
|
|
|
2014-05-23 16:21:38 +02:00
|
|
|
# Sends specified signal to the Kea process.
|
|
|
|
send_signal() {
|
2014-06-11 19:05:39 +02:00
|
|
|
local sig=${1} # Signal number.
|
|
|
|
local proc_name=${2} # Process name
|
|
|
|
|
|
|
|
# Validate signal
|
|
|
|
case ${sig} in
|
|
|
|
''|*[!0-9]*)
|
|
|
|
test_lib_error "signal number passed to send_signal \
|
2014-06-13 10:46:13 +02:00
|
|
|
must be a number"
|
2014-06-11 19:05:39 +02:00
|
|
|
clean_exit 1 ;;
|
|
|
|
esac
|
|
|
|
# Validate process name
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${proc_name}" ]; then
|
2014-06-11 19:05:39 +02:00
|
|
|
test_lib_error "send_signal requires process name be passed as argument"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
2014-05-23 16:21:38 +02:00
|
|
|
# Get Kea pid.
|
2020-12-03 11:19:15 +02:00
|
|
|
get_pid "${proc_name}"
|
|
|
|
if [ "${_GET_PIDS_NUM}" -ne 1 ]; then
|
2014-06-05 10:29:08 +02:00
|
|
|
printf "ERROR: expected one Kea process to be started.\
|
|
|
|
Found %d processes started.\n" ${_GET_PIDS_NUM}
|
2014-05-23 16:21:38 +02:00
|
|
|
clean_exit 1
|
2014-05-28 13:08:14 +02:00
|
|
|
fi
|
2020-12-03 11:19:15 +02:00
|
|
|
printf "Sending signal %s to Kea process (pid=%s).\n" "${sig}" "${_GET_PID}"
|
2014-05-23 16:21:38 +02:00
|
|
|
# Actually send a signal.
|
2020-12-03 11:19:15 +02:00
|
|
|
kill "-${sig}" "${_GET_PID}"
|
2014-05-23 16:21:38 +02:00
|
|
|
}
|
2014-08-11 17:33:15 +02:00
|
|
|
|
2015-07-02 14:42:58 -04:00
|
|
|
# Verifies that a server is up running by its PID file
|
|
|
|
# The PID file is constructed from the given config file name and
|
|
|
|
# binary name. If it exists and the PID it contains refers to a
|
|
|
|
# live process it sets _SERVER_PID_FILE and _SERVER_PID to the
|
|
|
|
# corresponding values. Otherwise, it emits an error and exits.
|
|
|
|
verify_server_pid() {
|
|
|
|
local bin_name="${1}" # binary name of the server
|
|
|
|
local cfg_file="${2}" # config file name
|
|
|
|
|
|
|
|
# We will construct the PID file name based on the server config
|
|
|
|
# and binary name
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${bin_name}" ]; then
|
2015-07-02 14:42:58 -04:00
|
|
|
test_lib_error "verify_server_pid requires binary name"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${cfg_file}" ]; then
|
2015-07-02 14:42:58 -04:00
|
|
|
test_lib_error "verify_server_pid requires config file name"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
|
2015-07-08 09:01:53 -04:00
|
|
|
# Only the file name portion of the config file is used, try and
|
2015-07-02 14:42:58 -04:00
|
|
|
# extract it. NOTE if this "algorithm" changes this code will need
|
|
|
|
# to be updated.
|
2020-12-03 11:19:15 +02:00
|
|
|
fname=$(basename "${cfg_file}")
|
|
|
|
fname=$(echo "${fname}" | cut -f1 -d'.')
|
2015-07-02 14:42:58 -04:00
|
|
|
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ -z "${fname}" ]; then
|
2015-07-02 14:42:58 -04:00
|
|
|
test_lib_error "verify_server_pid could not extract config name"
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Now we can build the name:
|
|
|
|
pid_file="$KEA_PIDFILE_DIR/$fname.$bin_name.pid"
|
|
|
|
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ ! -e "${pid_file}" ]; then
|
|
|
|
printf "ERROR: PID file:[%s] does not exist\n" "${pid_file}"
|
2015-07-02 14:42:58 -04:00
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# File exists, does its PID point to a live process?
|
2020-12-03 11:19:15 +02:00
|
|
|
pid=$(cat "${pid_file}")
|
|
|
|
if ! kill -0 "${pid}"; then
|
2015-07-02 14:42:58 -04:00
|
|
|
printf "ERROR: PID file:[%s] exists but PID:[%d] does not\n" \
|
2020-12-03 11:19:15 +02:00
|
|
|
"${pid_file}" "${pid}"
|
2015-07-02 14:42:58 -04:00
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Make the values accessible to the caller
|
|
|
|
_SERVER_PID="${pid}"
|
|
|
|
_SERVER_PID_FILE="${pid_file}"
|
|
|
|
}
|
|
|
|
|
2014-08-11 22:37:29 +02:00
|
|
|
# This test verifies that the binary is reporting its version properly.
|
2014-08-11 17:33:15 +02:00
|
|
|
version_test() {
|
2020-12-10 22:18:47 +02:00
|
|
|
test_name=${1} # Test name
|
|
|
|
long_version=${2-} # Test long version?
|
2014-08-11 17:33:15 +02:00
|
|
|
|
|
|
|
# Log the start of the test and print test name.
|
2020-12-03 11:19:15 +02:00
|
|
|
test_start "${test_name}"
|
2014-08-11 17:33:15 +02:00
|
|
|
|
|
|
|
# Remove dangling Kea instances and remove log files.
|
|
|
|
cleanup
|
|
|
|
|
2020-12-10 22:18:47 +02:00
|
|
|
# If set to anything other than empty string, reset it to the long version
|
|
|
|
# parameter.
|
|
|
|
if test -n "${long_version}"; then
|
|
|
|
long_version='--version'
|
2014-08-11 17:33:15 +02:00
|
|
|
fi
|
2020-12-10 22:18:47 +02:00
|
|
|
|
2020-12-11 21:07:07 +02:00
|
|
|
# Keep ${long_version} unquoted so that it is not included as an empty
|
|
|
|
# string if not given as argument.
|
|
|
|
for v in -v ${long_version}; do
|
2020-12-03 11:19:15 +02:00
|
|
|
run_command \
|
|
|
|
"${bin_path}/${bin}" "${v}"
|
2020-12-10 22:18:47 +02:00
|
|
|
|
2020-12-11 19:56:20 +02:00
|
|
|
if test "${OUTPUT}" != "${EXPECTED_VERSION}"; then
|
2020-12-10 22:18:47 +02:00
|
|
|
printf 'ERROR: Expected version "%s", got "%s" when calling "%s"\n' \
|
|
|
|
"${EXPECTED_VERSION}" "${OUTPUT}" "${bin} ${v}"
|
|
|
|
test_finish 1
|
|
|
|
fi
|
|
|
|
done
|
2020-12-11 19:56:20 +02:00
|
|
|
|
|
|
|
test_finish 0
|
2014-08-11 17:33:15 +02:00
|
|
|
}
|
2014-09-15 16:29:26 +02:00
|
|
|
|
|
|
|
# This test verifies that the server is using logger variable
|
|
|
|
# KEA_LOCKFILE_DIR properly (it should be used to point out to the directory,
|
|
|
|
# where lockfile should be created. Also, "none" value means to not create
|
|
|
|
# the lockfile at all).
|
|
|
|
logger_vars_test() {
|
|
|
|
test_name=${1} # Test name
|
|
|
|
|
|
|
|
# Log the start of the test and print test name.
|
2020-12-03 11:19:15 +02:00
|
|
|
test_start "${test_name}"
|
2014-09-15 16:29:26 +02:00
|
|
|
# Remove dangling Kea instances and remove log files.
|
|
|
|
cleanup
|
|
|
|
|
|
|
|
# Create bogus configuration file. We don't really want the server to start,
|
|
|
|
# just want it to log something and die. Empty config is an easy way to
|
|
|
|
# enforce that behavior.
|
|
|
|
create_config "{ }"
|
|
|
|
printf "Please ignore any config error messages.\n"
|
|
|
|
|
|
|
|
# Remember old KEA_LOCKFILE_DIR
|
|
|
|
KEA_LOCKFILE_DIR_OLD=${KEA_LOCKFILE_DIR}
|
|
|
|
|
|
|
|
# Set lockfile directory to current directory.
|
|
|
|
KEA_LOCKFILE_DIR=.
|
|
|
|
|
|
|
|
# Start Kea.
|
2020-12-03 11:19:15 +02:00
|
|
|
start_kea "${bin_path}/${bin}"
|
2014-09-15 16:29:26 +02:00
|
|
|
|
|
|
|
# Wait for Kea to process the invalid configuration and die.
|
|
|
|
sleep 1
|
|
|
|
|
|
|
|
# Check if it is still running. It should have terminated.
|
2020-12-03 11:19:15 +02:00
|
|
|
get_pid "${bin}"
|
|
|
|
if [ "${_GET_PIDS_NUM}" -ne 0 ]; then
|
|
|
|
printf 'ERROR: expected Kea process to not start. '
|
|
|
|
printf 'Found %d processes running.\n' "${_GET_PIDS_NUM}"
|
2014-09-15 16:29:26 +02:00
|
|
|
|
|
|
|
# Revert to the old KEA_LOCKFILE_DIR value
|
|
|
|
KEA_LOCKFILE_DIR=${KEA_LOCKFILE_DIR_OLD}
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ ! -f "./logger_lockfile" ]; then
|
2020-12-03 11:19:15 +02:00
|
|
|
printf 'ERROR: Expect %s to create logger_lockfile in the ' "${bin}"
|
|
|
|
printf 'current directory, but no such file exists.\n'
|
2014-09-15 16:29:26 +02:00
|
|
|
|
|
|
|
# Revert to the old KEA_LOCKFILE_DIR value
|
|
|
|
KEA_LOCKFILE_DIR=${KEA_LOCKFILE_DIR__OLD}
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Remove the lock file
|
|
|
|
rm -f ./logger_lockfile
|
|
|
|
|
|
|
|
# Tell Kea to NOT create logfiles at all
|
|
|
|
KEA_LOCKFILE_DIR="none"
|
|
|
|
|
|
|
|
# Start Kea.
|
2020-12-03 11:19:15 +02:00
|
|
|
start_kea "${bin_path}/${bin}"
|
2014-09-15 16:29:26 +02:00
|
|
|
|
|
|
|
# Wait for Kea to process the invalid configuration and die.
|
|
|
|
sleep 1
|
|
|
|
|
|
|
|
# Check if it is still running. It should have terminated.
|
2020-12-03 11:19:15 +02:00
|
|
|
get_pid "${bin}"
|
|
|
|
if [ "${_GET_PIDS_NUM}" -ne 0 ]; then
|
|
|
|
printf 'ERROR: expected Kea process to not start. '
|
|
|
|
printf 'Found %d processes running.\n' "${_GET_PIDS_NUM}"
|
2014-09-15 16:29:26 +02:00
|
|
|
|
|
|
|
# Revert to the old KEA_LOCKFILE_DIR value
|
|
|
|
KEA_LOCKFILE_DIR=${KEA_LOCKFILE_DIR_OLD}
|
|
|
|
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -f "./logger_lockfile" ]; then
|
2020-12-03 11:19:15 +02:00
|
|
|
printf 'ERROR: Expect %s to NOT create logger_lockfile in the ' "${bin}"
|
|
|
|
printf 'current directory, but the file exists.\n'
|
2014-09-15 16:29:26 +02:00
|
|
|
|
|
|
|
# Revert to the old KEA_LOCKFILE_DIR value
|
|
|
|
KEA_LOCKFILE_DIR=${KEA_LOCKFILE_DIR_OLD}
|
|
|
|
|
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Revert to the old KEA_LOCKFILE_DIR value
|
2020-12-03 11:19:15 +02:00
|
|
|
printf 'Reverting KEA_LOCKFILE_DIR to %s\n' "${KEA_LOCKFILE_DIR_OLD}"
|
2014-09-15 16:29:26 +02:00
|
|
|
KEA_LOCKFILE_DIR=${KEA_LOCKFILE_DIR_OLD}
|
|
|
|
|
|
|
|
test_finish 0
|
|
|
|
}
|
2015-07-02 16:49:53 -04:00
|
|
|
|
|
|
|
# This test verifies server PID file management
|
|
|
|
# 1. It verifies that upon startup, the server creates a PID file
|
|
|
|
# 2. It verifies the an attempt to start a second instance fails
|
|
|
|
# due to pre-existing PID File/PID detection
|
|
|
|
server_pid_file_test() {
|
|
|
|
local server_cfg="${1}"
|
|
|
|
local log_id="${2}"
|
|
|
|
|
|
|
|
# Log the start of the test and print test name.
|
|
|
|
test_start "${bin}.server_pid_file_test"
|
|
|
|
# Remove dangling DHCP4 instances and remove log files.
|
|
|
|
cleanup
|
|
|
|
# Create new configuration file.
|
|
|
|
create_config "${CONFIG}"
|
|
|
|
# Instruct server to log to the specific file.
|
|
|
|
set_logger
|
|
|
|
# Start server
|
2020-12-03 11:19:15 +02:00
|
|
|
start_kea "${bin_path}/${bin}"
|
2015-07-02 16:49:53 -04:00
|
|
|
# Wait up to 20s for server to start.
|
|
|
|
wait_for_kea 20
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ "${_WAIT_FOR_KEA}" -eq 0 ]; then
|
|
|
|
printf 'ERROR: timeout waiting for %s to start.\n' "${bin}"
|
2015-07-02 16:49:53 -04:00
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Verify server is still running
|
2020-12-03 11:19:15 +02:00
|
|
|
verify_server_pid "${bin}" "${CFG_FILE}"
|
2015-07-02 16:49:53 -04:00
|
|
|
|
2020-12-03 11:19:15 +02:00
|
|
|
printf 'PID file is [%s], PID is [%d]' "${_SERVER_PID_FILE}" "${_SERVER_PID}"
|
2015-07-02 16:49:53 -04:00
|
|
|
|
|
|
|
# Now try to start a second one
|
2020-12-03 11:19:15 +02:00
|
|
|
start_kea "${bin_path}/${bin}"
|
2015-07-02 16:49:53 -04:00
|
|
|
|
|
|
|
wait_for_message 10 "${log_id}" 1
|
2020-12-03 11:19:15 +02:00
|
|
|
if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
|
|
|
|
printf 'ERROR: Second %s instance started? ' "${bin}"
|
|
|
|
printf 'PID conflict not reported.\n'
|
2015-07-02 16:49:53 -04:00
|
|
|
clean_exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Verify server is still running
|
2020-12-03 11:19:15 +02:00
|
|
|
verify_server_pid "${bin}" "${CFG_FILE}"
|
2015-07-02 16:49:53 -04:00
|
|
|
|
|
|
|
# All ok. Shut down the server and exit.
|
|
|
|
test_finish 0
|
|
|
|
}
|