CFLAGS=$CFLAGS_SAVED
CXXFLAGS=$CXXFLAGS_SAVED
+# Libtool puts libraries in .libs/ subdirs: substitute it outside Makefiles.
+dotlibs=".libs/"
+AC_SUBST(dotlibs)
+
# Use C++ language
AC_LANG([C++])
+++ /dev/null
-// Copyright (C) 2020-2025 Internet Systems Consortium, Inc. ("ISC")
-//
-// 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/.
-
-#ifndef AGENT_TEST_BASIC_AUTH_LIBRARIES_H
-#define AGENT_TEST_BASIC_AUTH_LIBRARIES_H
-
-#include <config.h>
-
-namespace {
-
-// Names of the libraries used in these tests. These libraries are built using
-// libtool, so we need to look in the hidden ".libs" directory to locate the
-// .so file. Note that we access the .so file - libtool creates this as a
-// like to the real shared library.
-
-// Basic HTTP authentication as a callout library.
-static const char* BASIC_AUTH_LIBRARY = "@abs_builddir@/libbasicauth.so";
-
-} // anonymous namespace
-
-#endif // TEST_BASIC_AUTH_LIBRARIES_H
+++ /dev/null
-// Copyright (C) 2017-2025 Internet Systems Consortium, Inc. ("ISC")
-//
-// 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/.
-
-#ifndef AGENT_TEST_CALLOUT_LIBRARIES_H
-#define AGENT_TEST_CALLOUT_LIBRARIES_H
-
-#include <config.h>
-
-namespace {
-
-// Names of the libraries used in these tests. These libraries are built using
-// libtool, so we need to look in the hidden ".libs" directory to locate the
-// .so file. Note that we access the .so file - libtool creates this as a
-// like to the real shared library.
-
-// Basic callout library with context_create and three "standard" callouts.
-static const char* CALLOUT_LIBRARY = "@abs_builddir@/libcallout.so";
-
-} // anonymous namespace
-
-#endif // TEST_LIBRARIES_H
kea_agent_tests_data.set('abs_top_builddir', TOP_BUILD_DIR)
kea_agent_tests_data.set('abs_top_srcdir', TOP_SOURCE_DIR)
kea_agent_tests_data.set('abs_builddir', current_build_dir)
+kea_agent_tests_data.set('dotlibs', '')
ca_process_tests = configure_file(
input: 'ca_process_tests.sh.in',
output: 'ca_process_tests.sh',
priority: -1,
)
configure_file(
- input: 'meson-test_basic_auth_libraries.h.in',
+ input: 'test_basic_auth_libraries.h.in',
output: 'test_basic_auth_libraries.h',
configuration: kea_agent_tests_data,
)
configure_file(
- input: 'meson-test_callout_libraries.h.in',
+ input: 'test_callout_libraries.h.in',
output: 'test_callout_libraries.h',
configuration: kea_agent_tests_data,
)
-// Copyright (C) 2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2025 Internet Systems Consortium, Inc. ("ISC")
//
// 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
// like to the real shared library.
// Basic HTTP authentication as a callout library.
-static const char* BASIC_AUTH_LIBRARY = "@abs_builddir@/.libs/libbasicauth.so";
+static const char* BASIC_AUTH_LIBRARY = "@abs_builddir@/@dotlibs@libbasicauth.so";
} // anonymous namespace
-// Copyright (C) 2017-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2025 Internet Systems Consortium, Inc. ("ISC")
//
// 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
// like to the real shared library.
// Basic callout library with context_create and three "standard" callouts.
-static const char* CALLOUT_LIBRARY = "@abs_builddir@/.libs/libcallout.so";
+static const char* CALLOUT_LIBRARY = "@abs_builddir@/@dotlibs@libcallout.so";
} // anonymous namespace
+++ /dev/null
-// Copyright (C) 2021-2025 Internet Systems Consortium, Inc. ("ISC")
-//
-// 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/.
-
-#ifndef D2_TEST_CALLOUT_LIBRARIES_H
-#define D2_TEST_CALLOUT_LIBRARIES_H
-
-#include <config.h>
-
-namespace {
-
-// Names of the libraries used in these tests. These libraries are built using
-// libtool, so we need to look in the hidden ".libs" directory to locate the
-// .so file. Note that we access the .so file - libtool creates this as a
-// like to the real shared library.
-
-// Basic callout library with context_create and three "standard" callouts.
-static const char* CALLOUT_LIBRARY = "@abs_builddir@/libcallout.so";
-
-} // anonymous namespace
-
-#endif // D2_TEST_CALLOUT_LIBRARIES_H
+++ /dev/null
-// Copyright (C) 2021-2025 Internet Systems Consortium, Inc. ("ISC")
-//
-// 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/.
-
-#ifndef D2_TEST_CONFIGURED_LIBRARIES_H
-#define D2_TEST_CONFIGURED_LIBRARIES_H
-
-#include <config.h>
-
-namespace {
-
-// Names of the libraries used in these tests. These libraries are built using
-// libtool, so we need to look in the hidden ".libs" directory to locate the
-// .so file. Note that we access the .so file - libtool creates this as a
-// like to the real shared library.
-
-// Configured library with d2_srv_configured testing: if there is a toplevel
-// user context with an error entry the returned status is DROP with the
-// content of the error entry.
-static const char* CONFIGURED_LIBRARY = "@abs_builddir@/libconfigured.so";
-
-} // anonymous namespace
-
-#endif // D2_TEST_CONFIGURED_LIBRARIES_H
kea_d2_tests_data.set('abs_top_builddir', TOP_BUILD_DIR)
kea_d2_tests_data.set('abs_top_srcdir', TOP_SOURCE_DIR)
kea_d2_tests_data.set('abs_builddir', current_build_dir)
+kea_d2_tests_data.set('dotlibs', '')
d2_process_tests = configure_file(
input: 'd2_process_tests.sh.in',
output: 'd2_process_tests.sh',
priority: -1,
)
configure_file(
- input: 'meson-test_callout_libraries.h.in',
+ input: 'test_callout_libraries.h.in',
output: 'test_callout_libraries.h',
configuration: kea_d2_tests_data,
)
configuration: kea_d2_tests_data,
)
configure_file(
- input: 'meson-test_configured_libraries.h.in',
+ input: 'test_configured_libraries.h.in',
output: 'test_configured_libraries.h',
configuration: kea_d2_tests_data,
)
-// Copyright (C) 2021 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2021-2025 Internet Systems Consortium, Inc. ("ISC")
//
// 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
// like to the real shared library.
// Basic callout library with context_create and three "standard" callouts.
-static const char* CALLOUT_LIBRARY = "@abs_builddir@/.libs/libcallout.so";
+static const char* CALLOUT_LIBRARY = "@abs_builddir@/@dotlibs@libcallout.so";
} // anonymous namespace
-// Copyright (C) 2021 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2021-2025 Internet Systems Consortium, Inc. ("ISC")
//
// 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
// Configured library with d2_srv_configured testing: if there is a toplevel
// user context with an error entry the returned status is DROP with the
// content of the error entry.
-static const char* CONFIGURED_LIBRARY = "@abs_builddir@/.libs/libconfigured.so";
+static const char* CONFIGURED_LIBRARY = "@abs_builddir@/@dotlibs@libconfigured.so";
} // anonymous namespace
# Path to the Kea LFC application
export KEA_LFC_EXECUTABLE="@abs_top_builddir@/src/bin/lfc/kea-lfc"
# Path to test hooks library
-HOOK_FAIL_LOAD_PATH="@abs_top_builddir@/src/bin/dhcp4/tests/.libs/libco3.so"
+HOOK_FAIL_LOAD_PATH="@abs_top_builddir@/src/bin/dhcp4/tests/@dotlibs@libco3.so"
# Path to test hooks library
-HOOK_FAIL_POLL_PATH="@abs_top_builddir@/src/bin/dhcp4/tests/.libs/libco4.so"
+HOOK_FAIL_POLL_PATH="@abs_top_builddir@/src/bin/dhcp4/tests/@dotlibs@libco4.so"
# Kea configuration to be stored in the configuration file.
CONFIG="{
\"Dhcp4\":
+++ /dev/null
-#!/bin/sh
-
-# Copyright (C) 2014-2025 Internet Systems Consortium, Inc. ("ISC")
-#
-# 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/.
-
-# Exit with error if commands exit with non-zero and if undefined variables are
-# used.
-set -eu
-
-# Path to the temporary configuration file.
-CFG_FILE="@abs_top_builddir@/src/bin/dhcp4/tests/test_config.json"
-# Path to the Kea log file.
-LOG_FILE="@abs_top_builddir@/src/bin/dhcp4/tests/test.log"
-# Path to the Kea lease file.
-LEASE_FILE="@abs_top_builddir@/src/bin/dhcp4/tests/test_leases.csv"
-# Path to the Kea LFC application
-export KEA_LFC_EXECUTABLE="@abs_top_builddir@/src/bin/lfc/kea-lfc"
-# Path to test hooks library
-HOOK_FAIL_LOAD_PATH="@abs_top_builddir@/src/bin/dhcp4/tests/libco3.so"
-# Path to test hooks library
-HOOK_FAIL_POLL_PATH="@abs_top_builddir@/src/bin/dhcp4/tests/libco4.so"
-# Kea configuration to be stored in the configuration file.
-CONFIG="{
- \"Dhcp4\":
- {
- \"interfaces-config\": {
- \"interfaces\": [ ]
- },
- \"valid-lifetime\": 4000,
- \"renew-timer\": 1000,
- \"rebind-timer\": 2000,
- \"lease-database\":
- {
- \"type\": \"memfile\",
- \"name\": \"$LEASE_FILE\",
- \"persist\": false,
- \"lfc-interval\": 0
- },
- \"subnet4\": [
- {
- \"id\": 1,
- \"subnet\": \"10.0.0.0/8\",
- \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ]
- } ],
- \"ddns-qualifying-suffix\": \"\",
- \"dhcp-ddns\": {
- \"enable-updates\": true
- },
- \"loggers\": [
- {
- \"name\": \"kea-dhcp4\",
- \"output-options\": [
- {
- \"output\": \"$LOG_FILE\"
- }
- ],
- \"severity\": \"INFO\"
- }
- ]
- }
-}"
-
-# Invalid configuration (syntax error) to check that Kea can check syntax.
-# This config has following errors:
-# - it should be interfaces-config/interfaces, not interfaces
-# - it should be subnet4/pools, no subnet4/pool
-CONFIG_BAD_SYNTAX="{
- \"Dhcp4\":
- {
- \"interfaces\": [ ],
- \"valid-lifetime\": 4000,
- \"renew-timer\": 1000,
- \"rebind-timer\": 2000,
- \"lease-database\":
- {
- \"type\": \"memfile\",
- \"persist\": false
- },
- \"subnet4\": [
- {
- \"id\": 1,
- \"subnet\": \"10.0.0.0/8\",
- \"pool\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ]
- } ],
- \"loggers\": [
- {
- \"name\": \"kea-dhcp4\",
- \"output-options\": [
- {
- \"output\": \"$LOG_FILE\"
- }
- ],
- \"severity\": \"INFO\"
- }
- ]
- }
-}"
-
-# This config has bad pool values. The pool it out of scope for the subnet
-# it is defined in. Syntactically the config is correct, though.
-CONFIG_BAD_VALUES="{
- \"Dhcp4\":
- {
- \"interfaces-config\": {
- \"interfaces\": [ ]
- },
- \"valid-lifetime\": 4000,
- \"renew-timer\": 1000,
- \"rebind-timer\": 2000,
- \"lease-database\":
- {
- \"type\": \"memfile\",
- \"persist\": false
- },
- \"subnet4\": [
- {
- \"id\": 1,
- \"subnet\": \"10.0.0.0/8\",
- \"pools\": [ { \"pool\": \"192.168.0.10-192.168.0.100\" } ]
- } ],
- \"loggers\": [
- {
- \"name\": \"kea-dhcp4\",
- \"output-options\": [
- {
- \"output\": \"$LOG_FILE\"
- }
- ],
- \"severity\": \"INFO\"
- }
- ]
- }
-}"
-
-# Invalid configuration (negative valid-lifetime) to check that Kea
-# gracefully handles reconfiguration errors.
-CONFIG_INVALID="{
- \"Dhcp4\":
- {
- \"interfaces-config\": {
- \"interfaces\": [ ]
- },
- \"valid-lifetime\": -3,
- \"renew-timer\": 1000,
- \"rebind-timer\": 2000,
- \"lease-database\":
- {
- \"type\": \"memfile\",
- \"persist\": false
- },
- \"subnet4\": [
- {
- \"id\": 1,
- \"subnet\": \"10.0.0.0/8\",
- \"pool\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ]
- } ],
- \"loggers\": [
- {
- \"name\": \"kea-dhcp4\",
- \"output-options\": [
- {
- \"output\": \"$LOG_FILE\"
- }
- ],
- \"severity\": \"INFO\"
- }
- ]
- }
-}"
-
-# Invalid configuration (hook explicitly fails to load) to check that performing
-# extra configuration checks detects the error.
-INVALID_CONFIG_HOOKS_LOAD="{
- \"Dhcp4\":
- {
- \"interfaces-config\": {
- \"interfaces\": [ ]
- },
- \"multi-threading\": {
- \"enable-multi-threading\": false
- },
- \"valid-lifetime\": 4000,
- \"renew-timer\": 1000,
- \"rebind-timer\": 2000,
- \"lease-database\":
- {
- \"type\": \"memfile\",
- \"name\": \"$LEASE_FILE\",
- \"persist\": false,
- \"lfc-interval\": 0
- },
- \"subnet4\": [
- {
- \"id\": 1,
- \"subnet\": \"10.0.0.0/8\",
- \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ]
- } ],
- \"ddns-qualifying-suffix\": \"\",
- \"dhcp-ddns\": {
- \"enable-updates\": true
- },
- \"hooks-libraries\": [
- {
- \"library\": \"$HOOK_FAIL_LOAD_PATH\",
- \"parameters\": {
- \"mode\": \"fail-on-load\"
- }
- } ],
- \"loggers\": [
- {
- \"name\": \"kea-dhcp4\",
- \"output-options\": [
- {
- \"output\": \"$LOG_FILE\"
- }
- ],
- \"severity\": \"INFO\"
- }
- ]
- }
-}"
-
-# Invalid configuration (hook point returns error) to check that performing
-# extra configuration checks detects the error.
-INVALID_CONFIG_HOOKS_CALLOUT_FAIL_ON_LOAD="{
- \"Dhcp4\":
- {
- \"interfaces-config\": {
- \"interfaces\": [ ]
- },
- \"multi-threading\": {
- \"enable-multi-threading\": false
- },
- \"valid-lifetime\": 4000,
- \"renew-timer\": 1000,
- \"rebind-timer\": 2000,
- \"lease-database\":
- {
- \"type\": \"memfile\",
- \"name\": \"$LEASE_FILE\",
- \"persist\": false,
- \"lfc-interval\": 0
- },
- \"subnet4\": [
- {
- \"id\": 1,
- \"subnet\": \"10.0.0.0/8\",
- \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ]
- } ],
- \"ddns-qualifying-suffix\": \"\",
- \"dhcp-ddns\": {
- \"enable-updates\": true
- },
- \"hooks-libraries\": [
- {
- \"library\": \"$HOOK_FAIL_LOAD_PATH\",
- \"parameters\": {
- \"mode\": \"fail-without-error\"
- }
- } ],
- \"loggers\": [
- {
- \"name\": \"kea-dhcp4\",
- \"output-options\": [
- {
- \"output\": \"$LOG_FILE\"
- }
- ],
- \"severity\": \"INFO\"
- }
- ]
- }
-}"
-
-# Invalid configuration (poll after load throws exception) to check that performing
-# extra configuration checks detects the error.
-INVALID_CONFIG_HOOKS_CALLOUT_FAIL_ON_POLL="{
- \"Dhcp4\":
- {
- \"interfaces-config\": {
- \"interfaces\": [ ]
- },
- \"multi-threading\": {
- \"enable-multi-threading\": false
- },
- \"valid-lifetime\": 4000,
- \"renew-timer\": 1000,
- \"rebind-timer\": 2000,
- \"lease-database\":
- {
- \"type\": \"memfile\",
- \"name\": \"$LEASE_FILE\",
- \"persist\": false,
- \"lfc-interval\": 0
- },
- \"subnet4\": [
- {
- \"id\": 1,
- \"subnet\": \"10.0.0.0/8\",
- \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ]
- } ],
- \"ddns-qualifying-suffix\": \"\",
- \"dhcp-ddns\": {
- \"enable-updates\": true
- },
- \"hooks-libraries\": [
- {
- \"library\": \"$HOOK_FAIL_POLL_PATH\",
- \"parameters\": {
- \"mode\": \"fail-without-error\"
- }
- } ],
- \"loggers\": [
- {
- \"name\": \"kea-dhcp4\",
- \"output-options\": [
- {
- \"output\": \"$LOG_FILE\"
- }
- ],
- \"severity\": \"INFO\"
- }
- ]
- }
-}"
-
-# Set the location of the executable.
-bin="kea-dhcp4"
-bin_path="@abs_top_builddir@/src/bin/dhcp4"
-
-# Import common test library.
-# shellcheck source=src/lib/testutils/dhcp_test_lib.sh.in
-. "@abs_top_builddir@/src/lib/testutils/dhcp_test_lib.sh"
-
-# This test verifies that syntax checking works properly. This function
-# requires 3 parameters:
-# test_name
-# config - string with a content of the config (will be written to a file)
-# expected_code - expected exit code returned by kea (0 - success, 1 - failure)
-syntax_check_test() {
- local test_name="${1}"
- local config="${2}"
- local expected_code="${3}"
- local check_type="${4}"
-
- # Log the start of the test and print test name.
- test_start "${test_name}"
- # Create correct configuration file.
- create_config "${config}"
- # Check it
- printf "Running command %s.\n" "\"${bin_path}/${bin} ${check_type} ${CFG_FILE}\""
- run_command \
- "${bin_path}/${bin}" "${check_type}" "${CFG_FILE}"
- if [ "${EXIT_CODE}" -ne "${expected_code}" ]; then
- printf 'ERROR: expected exit code %s, got %s\n' "${expected_code}" "${EXIT_CODE}"
- clean_exit 1
- fi
- test_finish 0
-}
-
-# This test verifies that DHCPv4 can be reconfigured with a SIGHUP signal.
-dynamic_reconfiguration_test() {
- # Log the start of the test and print test name.
- test_start "dhcpv4_srv.dynamic_reconfiguration"
- # Create new configuration file.
- create_config "${CONFIG}"
- # Instruct Kea to log to the specific file.
- set_logger
- # Start Kea.
- start_kea "${bin_path}/${bin}"
- # 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_pid "${bin}"
- 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
-
- # Now use invalid configuration.
- create_config "${CONFIG_INVALID}"
-
- # Try to reconfigure by sending SIGHUP
- send_signal 1 "${bin}"
-
- # The configuration should fail and the error message should be there.
- wait_for_message 10 "DHCP4_CONFIG_LOAD_FAIL" 1
-
- # After receiving SIGHUP the server should try to reconfigure itself.
- # The configuration provided is invalid so it should result in
- # reconfiguration failure but the server should still be running.
- get_reconfigs
- if [ "${_GET_RECONFIGS}" -ne 1 ]; then
- printf "ERROR: server has been reconfigured despite bogus configuration.\n"
- clean_exit 1
- elif [ "${_GET_RECONFIG_ERRORS}" -ne 1 ]; then
- printf "ERROR: server did not report reconfiguration error despite attempt\
- to configure it with invalid configuration.\n"
- clean_exit 1
- fi
-
- # Make sure the server is still operational.
- get_pid "${bin}"
- if [ "${_GET_PIDS_NUM}" -ne 1 ]; then
- printf "ERROR: Kea process was killed when attempting reconfiguration.\n"
- clean_exit 1
- fi
-
- # Restore the good configuration.
- create_config "${CONFIG}"
-
- # Reconfigure the server with SIGHUP.
- send_signal 1 "${bin}"
-
- # There should be two occurrences of the DHCP4_CONFIG_COMPLETE messages.
- # Wait for it up to 10s.
- wait_for_message 10 "DHCP4_CONFIG_COMPLETE" 2
-
- # After receiving SIGHUP the server should get reconfigured and the
- # reconfiguration should be noted in the log file. We should now
- # have two configurations logged in the log file.
- if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
- printf "ERROR: server hasn't been reconfigured.\n"
- clean_exit 1
- else
- printf "Server successfully reconfigured.\n"
- fi
-
- # Make sure the server is still operational.
- get_pid "${bin}"
- if [ "${_GET_PIDS_NUM}" -ne 1 ]; then
- printf "ERROR: Kea process was killed when attempting reconfiguration.\n"
- clean_exit 1
- fi
-
- # When the server receives a signal the call to select() function is
- # interrupted. This should not be logged as an error.
- get_log_messages "DHCP4_PACKET_RECEIVE_FAIL"
- assert_eq 0 "${_GET_LOG_MESSAGES}" \
- "Expected get_log_messages DHCP4_PACKET_RECEIVE_FAIL return %d, \
-returned %d."
-
- # All ok. Shut down Kea and exit.
- test_finish 0
-}
-
-# This test verifies that DHCPv4 server is shut down gracefully when it
-# receives a SIGINT or SIGTERM signal.
-shutdown_test() {
- test_name=${1} # Test name
- signum=${2} # Signal number
- # Log the start of the test and print test name.
- test_start "${test_name}"
- # Create new configuration file.
- create_config "${CONFIG}"
- # Instruct Kea to log to the specific file.
- set_logger
- # Start Kea.
- start_kea "${bin_path}/${bin}"
- # 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_pid "${bin}"
- 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 "${signum}" "${bin}"
-
- # 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 "DHCP4_SHUTDOWN" 1
- if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
- printf "ERROR: Server did not record shutdown in the log.\n"
- clean_exit 1
- fi
-
- # Make sure the server is down.
- wait_for_server_down 5 "${bin}"
- assert_eq 1 "${_WAIT_FOR_SERVER_DOWN}" \
- "Expected wait_for_server_down return %d, returned %d"
-
- # When the server receives a signal the call to select() function is
- # interrupted. This should not be logged as an error.
- get_log_messages "DHCP4_PACKET_RECEIVE_FAIL"
- assert_eq 0 "${_GET_LOG_MESSAGES}" \
- "Expected get_log_messages return %d, returned %d."
-
- test_finish 0
-}
-
-# This test verifies that DHCPv4 can be configured to run lease file cleanup
-# periodically.
-lfc_timer_test() {
- # Log the start of the test and print test name.
- test_start "dhcpv4_srv.lfc_timer_test"
- # Create a configuration with the LFC enabled, by replacing the section
- # with the lfc-interval and persist parameters.
- LFC_CONFIG=$(printf '%s' "${CONFIG}" | sed -e 's/\"lfc-interval\": 0/\"lfc-interval\": 3/g' \
- | sed -e 's/\"persist\": false/\"persist\": true/g')
- # Create new configuration file.
- create_config "${LFC_CONFIG}"
- # Instruct Kea to log to the specific file.
- set_logger
- # Start Kea.
- start_kea "${bin_path}/${bin}"
- # 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_pid "${bin}"
- 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 if Kea emits the log message indicating that LFC is started.
- wait_for_message 10 "DHCPSRV_MEMFILE_LFC_EXECUTE" 1
- if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
- printf "ERROR: Server did not execute LFC.\n"
- clean_exit 1
- fi
-
- # Give it a short time to run.
- sleep 1
-
- # Modify the interval.
- LFC_CONFIG=$(printf '%s' "${LFC_CONFIG}" | sed -e 's/\"lfc-interval\": 3/\"lfc-interval\": 4/g')
- # Create new configuration file.
- create_config "${LFC_CONFIG}"
-
- # Reconfigure the server with SIGHUP.
- send_signal 1 "${bin}"
-
- # There should be two occurrences of the DHCP4_CONFIG_COMPLETE messages.
- # Wait for it up to 10s.
- wait_for_message 10 "DHCP4_CONFIG_COMPLETE" 2
-
- # After receiving SIGHUP the server should get reconfigured and the
- # reconfiguration should be noted in the log file. We should now
- # have two configurations logged in the log file.
- if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
- printf "ERROR: server hasn't been reconfigured.\n"
- clean_exit 1
- else
- printf "Server successfully reconfigured.\n"
- fi
-
- # Make sure the server is still operational.
- get_pid "${bin}"
- if [ "${_GET_PIDS_NUM}" -ne 1 ]; then
- printf "ERROR: Kea process was killed when attempting reconfiguration.\n"
- clean_exit 1
- fi
-
- # Wait for the LFC to run the second time.
- wait_for_message 10 "DHCPSRV_MEMFILE_LFC_EXECUTE" 2
- if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
- printf "ERROR: Server did not execute LFC.\n"
- clean_exit 1
- fi
-
- # Send signal to Kea SIGTERM
- send_signal 15 "${bin}"
-
- # 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 "DHCP4_SHUTDOWN" 1
- if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
- printf "ERROR: Server did not record shutdown in the log.\n"
- clean_exit 1
- fi
-
- # Make sure the server is down.
- wait_for_server_down 5 "${bin}"
- assert_eq 1 "${_WAIT_FOR_SERVER_DOWN}" \
- "Expected wait_for_server_down return %d, returned %d"
-
- # All ok. Shut down Kea and exit.
- test_finish 0
-}
-
-server_pid_file_test "${CONFIG}" DHCP4_ALREADY_RUNNING
-dynamic_reconfiguration_test
-shutdown_test "dhcpv4.sigterm_test" 15
-shutdown_test "dhcpv4.sigint_test" 2
-version_test "dhcpv4.version"
-logger_vars_test "dhcpv4.variables"
-lfc_timer_test
-syntax_check_test "dhcpv4.syntax_check_success" "${CONFIG}" 0 -t
-syntax_check_test "dhcpv4.syntax_check_bad_syntax" "${CONFIG_BAD_SYNTAX}" 1 -t
-syntax_check_test "dhcpv4.syntax_check_bad_values" "${CONFIG_BAD_VALUES}" 1 -t
-syntax_check_test "dhcpv4.syntax_check_hooks_load_fail" "${INVALID_CONFIG_HOOKS_LOAD}" 1 -T
-syntax_check_test "dhcpv4.syntax_check_hooks_callout_fail_on_load" "${INVALID_CONFIG_HOOKS_CALLOUT_FAIL_ON_LOAD}" 1 -T
-syntax_check_test "dhcpv4.syntax_check_hooks_callout_fail_on_poll" "${INVALID_CONFIG_HOOKS_CALLOUT_FAIL_ON_POLL}" 1 -T
-password_redact_test "dhcpv4.password_redact_test" "$(kea_dhcp_config 4)" 0
+++ /dev/null
-// Copyright (C) 2013-2025 Internet Systems Consortium, Inc. ("ISC")
-//
-// 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/.
-
-#ifndef TEST_LIBRARIES_H
-#define TEST_LIBRARIES_H
-
-#include <config.h>
-
-namespace {
-
-#define DLL_SUFFIX ".so"
-
-// Names of the libraries used in these tests. These libraries are built using
-// libtool, so we need to look in the hidden ".libs" directory to locate the
-// shared library.
-
-// Library with load/unload functions creating marker files to check their
-// operation.
-const char* const CALLOUT_LIBRARY_1 = "@abs_builddir@/libco1.so";
-const char* const CALLOUT_LIBRARY_2 = "@abs_builddir@/libco2.so";
-const char* const CALLOUT_LIBRARY_3 = "@abs_builddir@/libco3.so";
-const char* const CALLOUT_LIBRARY_4 = "@abs_builddir@/libco4.so";
-
-// Name of a library which is not present.
-const char* const NOT_PRESENT_LIBRARY = "@abs_builddir@/libnothere.so";
-
-} // anonymous namespace
-
-
-#endif // TEST_LIBRARIES_H
dhcp4_tests_conf_data.set('abs_top_builddir', TOP_BUILD_DIR)
dhcp4_tests_conf_data.set('abs_top_srcdir', TOP_SOURCE_DIR)
dhcp4_tests_conf_data.set('abs_builddir', current_build_dir)
+dhcp4_tests_conf_data.set('dotlibs', '')
dhcp4_process_tests = configure_file(
- input: 'meson-dhcp4_process_tests.sh.in',
+ input: 'dhcp4_process_tests.sh.in',
output: 'dhcp4_process_tests.sh',
configuration: dhcp4_tests_conf_data,
)
configuration: dhcp4_tests_conf_data,
)
configure_file(
- input: 'meson-test_libraries.h.in',
+ input: 'test_libraries.h.in',
output: 'test_libraries.h',
configuration: dhcp4_tests_conf_data,
)
-// Copyright (C) 2013-2024 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2025 Internet Systems Consortium, Inc. ("ISC")
//
// 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
// Library with load/unload functions creating marker files to check their
// operation.
-const char* const CALLOUT_LIBRARY_1 = "@abs_builddir@/.libs/libco1.so";
-const char* const CALLOUT_LIBRARY_2 = "@abs_builddir@/.libs/libco2.so";
-const char* const CALLOUT_LIBRARY_3 = "@abs_builddir@/.libs/libco3.so";
-const char* const CALLOUT_LIBRARY_4 = "@abs_builddir@/.libs/libco4.so";
+const char* const CALLOUT_LIBRARY_1 = "@abs_builddir@/@dotlibs@libco1.so";
+const char* const CALLOUT_LIBRARY_2 = "@abs_builddir@/@dotlibs@libco2.so";
+const char* const CALLOUT_LIBRARY_3 = "@abs_builddir@/@dotlibs@libco3.so";
+const char* const CALLOUT_LIBRARY_4 = "@abs_builddir@/@dotlibs@libco4.so";
// Name of a library which is not present.
-const char* const NOT_PRESENT_LIBRARY = "@abs_builddir@/.libs/libnothere.so";
+const char* const NOT_PRESENT_LIBRARY = "@abs_builddir@/@dotlibs@libnothere.so";
} // anonymous namespace
# Path to the Kea LFC application
export KEA_LFC_EXECUTABLE="@abs_top_builddir@/src/bin/lfc/kea-lfc"
# Path to test hooks library
-HOOK_FAIL_LOAD_PATH="@abs_top_builddir@/src/bin/dhcp6/tests/.libs/libco3.so"
+HOOK_FAIL_LOAD_PATH="@abs_top_builddir@/src/bin/dhcp6/tests/@dotlibs@libco3.so"
# Path to test hooks library
-HOOK_FAIL_POLL_PATH="@abs_top_builddir@/src/bin/dhcp6/tests/.libs/libco4.so"
+HOOK_FAIL_POLL_PATH="@abs_top_builddir@/src/bin/dhcp6/tests/@dotlibs@libco4.so"
# Kea configuration to be stored in the configuration file.
CONFIG="{
\"Dhcp6\":
+++ /dev/null
-#!/bin/sh
-
-# Copyright (C) 2014-2025 Internet Systems Consortium, Inc. ("ISC")
-#
-# 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/.
-
-# Exit with error if commands exit with non-zero and if undefined variables are
-# used.
-set -eu
-
-# Path to the temporary configuration file.
-CFG_FILE="@abs_top_builddir@/src/bin/dhcp6/tests/test_config.json"
-# Path to the Kea log file.
-LOG_FILE="@abs_top_builddir@/src/bin/dhcp6/tests/test.log"
-# Path to the Kea lease file.
-LEASE_FILE="@abs_top_builddir@/src/bin/dhcp6/tests/test_leases.csv"
-# Path to the Kea LFC application
-export KEA_LFC_EXECUTABLE="@abs_top_builddir@/src/bin/lfc/kea-lfc"
-# Path to test hooks library
-HOOK_FAIL_LOAD_PATH="@abs_top_builddir@/src/bin/dhcp6/tests/libco3.so"
-# Path to test hooks library
-HOOK_FAIL_POLL_PATH="@abs_top_builddir@/src/bin/dhcp6/tests/libco4.so"
-# Kea configuration to be stored in the configuration file.
-CONFIG="{
- \"Dhcp6\":
- {
- \"interfaces-config\": {
- \"interfaces\": [ ]
- },
- \"server-id\": {
- \"type\": \"LLT\",
- \"persist\": false
- },
- \"preferred-lifetime\": 3000,
- \"valid-lifetime\": 4000,
- \"renew-timer\": 1000,
- \"rebind-timer\": 2000,
- \"lease-database\":
- {
- \"type\": \"memfile\",
- \"name\": \"$LEASE_FILE\",
- \"persist\": false,
- \"lfc-interval\": 0
- },
- \"subnet6\": [
- {
- \"subnet\": \"2001:db8:1::/64\",
- \"id\": 1,
- \"pools\": [ { \"pool\": \"2001:db8:1::10-2001:db8:1::100\" } ]
- } ],
- \"ddns-qualifying-suffix\": \"\",
- \"dhcp-ddns\": {
- \"enable-updates\": true
- },
- \"loggers\": [
- {
- \"name\": \"kea-dhcp6\",
- \"output-options\": [
- {
- \"output\": \"$LOG_FILE\"
- }
- ],
- \"severity\": \"INFO\"
- }
- ]
- }
-}"
-
-# Invalid configuration (syntax error) to check that Kea can check syntax.
-# This config has following errors:
-# - it should be interfaces-config/interfaces, not interfaces
-# - it should be subnet6/pools, no subnet6/pool
-CONFIG_BAD_SYNTAX="{
- \"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\",
- \"id\": 1,
- \"pool\": [ { \"pool\": \"2001:db8:1::10-2001:db8:1::100\" } ]
- } ],
- \"loggers\": [
- {
- \"name\": \"kea-dhcp6\",
- \"output-options\": [
- {
- \"output\": \"$LOG_FILE\"
- }
- ],
- \"severity\": \"INFO\"
- }
- ]
- }
-}"
-
-# Invalid configuration (negative preferred-lifetime) to check that Kea
-# gracefully handles reconfiguration errors.
-CONFIG_INVALID="{
- \"Dhcp6\":
- {
- \"interfaces-config\": {
- \"interfaces\": [ ]
- },
- \"preferred-lifetime\": -3,
- \"valid-lifetime\": 4000,
- \"renew-timer\": 1000,
- \"rebind-timer\": 2000,
- \"lease-database\":
- {
- \"type\": \"memfile\",
- \"persist\": false
- },
- \"subnet6\": [
- {
- \"subnet\": \"2001:db8:1::/64\",
- \"id\": 1,
- \"pool\": [ { \"pool\": \"2001:db8:1::10-2001:db8:1::100\" } ]
- } ],
- \"loggers\": [
- {
- \"name\": \"kea-dhcp6\",
- \"output-options\": [
- {
- \"output\": \"$LOG_FILE\"
- }
- ],
- \"severity\": \"INFO\"
- }
- ]
- }
-}"
-
-# This config has bad pool values. The pool it out of scope for the subnet
-# it is defined in. Syntactically the config is correct, though.
-CONFIG_BAD_VALUES="{
- \"Dhcp6\":
- {
- \"interfaces-config\": {
- \"interfaces\": [ ]
- },
- \"server-id\": {
- \"type\": \"LLT\",
- \"persist\": false
- },
- \"preferred-lifetime\": 3000,
- \"valid-lifetime\": 4000,
- \"renew-timer\": 1000,
- \"rebind-timer\": 2000,
- \"lease-database\":
- {
- \"type\": \"memfile\",
- \"name\": \"$LEASE_FILE\",
- \"persist\": false,
- \"lfc-interval\": 0
- },
- \"subnet6\": [
- {
- \"subnet\": \"2001:db8::/64\",
- \"id\": 1,
- \"pools\": [ { \"pool\": \"3000::-3000::ffff\" } ]
- } ],
- \"ddns-qualifying-suffix\": \"\",
- \"dhcp-ddns\": {
- \"enable-updates\": true
- }
- }
-}"
-
-# Invalid configuration (hook explicitly fails to load) to check that performing
-# extra configuration checks detects the error.
-INVALID_CONFIG_HOOKS_LOAD="{
- \"Dhcp6\":
- {
- \"interfaces-config\": {
- \"interfaces\": [ ]
- },
- \"multi-threading\": {
- \"enable-multi-threading\": false
- },
- \"server-id\": {
- \"type\": \"LLT\",
- \"persist\": false
- },
- \"preferred-lifetime\": 3000,
- \"valid-lifetime\": 4000,
- \"renew-timer\": 1000,
- \"rebind-timer\": 2000,
- \"lease-database\":
- {
- \"type\": \"memfile\",
- \"name\": \"$LEASE_FILE\",
- \"persist\": false,
- \"lfc-interval\": 0
- },
- \"subnet6\": [
- {
- \"subnet\": \"2001:db8:1::/64\",
- \"id\": 1,
- \"pools\": [ { \"pool\": \"2001:db8:1::10-2001:db8:1::100\" } ]
- } ],
- \"ddns-qualifying-suffix\": \"\",
- \"dhcp-ddns\": {
- \"enable-updates\": true
- },
- \"hooks-libraries\": [
- {
- \"library\": \"$HOOK_FAIL_LOAD_PATH\",
- \"parameters\": {
- \"mode\": \"fail-on-load\"
- }
- } ],
- \"loggers\": [
- {
- \"name\": \"kea-dhcp6\",
- \"output-options\": [
- {
- \"output\": \"$LOG_FILE\"
- }
- ],
- \"severity\": \"INFO\"
- }
- ]
- }
-}"
-
-# Invalid configuration (hook point returns error) to check that performing
-# extra configuration checks detects the error.
-INVALID_CONFIG_HOOKS_CALLOUT_FAIL_ON_LOAD="{
- \"Dhcp6\":
- {
- \"interfaces-config\": {
- \"interfaces\": [ ]
- },
- \"multi-threading\": {
- \"enable-multi-threading\": false
- },
- \"server-id\": {
- \"type\": \"LLT\",
- \"persist\": false
- },
- \"preferred-lifetime\": 3000,
- \"valid-lifetime\": 4000,
- \"renew-timer\": 1000,
- \"rebind-timer\": 2000,
- \"lease-database\":
- {
- \"type\": \"memfile\",
- \"name\": \"$LEASE_FILE\",
- \"persist\": false,
- \"lfc-interval\": 0
- },
- \"subnet6\": [
- {
- \"subnet\": \"2001:db8:1::/64\",
- \"id\": 1,
- \"pools\": [ { \"pool\": \"2001:db8:1::10-2001:db8:1::100\" } ]
- } ],
- \"ddns-qualifying-suffix\": \"\",
- \"dhcp-ddns\": {
- \"enable-updates\": true
- },
- \"hooks-libraries\": [
- {
- \"library\": \"$HOOK_FAIL_LOAD_PATH\",
- \"parameters\": {
- \"mode\": \"fail-without-error\"
- }
- } ],
- \"loggers\": [
- {
- \"name\": \"kea-dhcp6\",
- \"output-options\": [
- {
- \"output\": \"$LOG_FILE\"
- }
- ],
- \"severity\": \"INFO\"
- }
- ]
- }
-}"
-
-# Invalid configuration (poll after load throws exception) to check that performing
-# extra configuration checks detects the error.
-INVALID_CONFIG_HOOKS_CALLOUT_FAIL_ON_POLL="{
- \"Dhcp6\":
- {
- \"interfaces-config\": {
- \"interfaces\": [ ]
- },
- \"multi-threading\": {
- \"enable-multi-threading\": false
- },
- \"server-id\": {
- \"type\": \"LLT\",
- \"persist\": false
- },
- \"preferred-lifetime\": 3000,
- \"valid-lifetime\": 4000,
- \"renew-timer\": 1000,
- \"rebind-timer\": 2000,
- \"lease-database\":
- {
- \"type\": \"memfile\",
- \"name\": \"$LEASE_FILE\",
- \"persist\": false,
- \"lfc-interval\": 0
- },
- \"subnet6\": [
- {
- \"subnet\": \"2001:db8:1::/64\",
- \"id\": 1,
- \"pools\": [ { \"pool\": \"2001:db8:1::10-2001:db8:1::100\" } ]
- } ],
- \"ddns-qualifying-suffix\": \"\",
- \"dhcp-ddns\": {
- \"enable-updates\": true
- },
- \"hooks-libraries\": [
- {
- \"library\": \"$HOOK_FAIL_POLL_PATH\",
- \"parameters\": {
- \"mode\": \"fail-without-error\"
- }
- } ],
- \"loggers\": [
- {
- \"name\": \"kea-dhcp6\",
- \"output-options\": [
- {
- \"output\": \"$LOG_FILE\"
- }
- ],
- \"severity\": \"INFO\"
- }
- ]
- }
-}"
-
-# Set the location of the executable.
-bin="kea-dhcp6"
-bin_path="@abs_top_builddir@/src/bin/dhcp6"
-
-# Import common test library.
-# shellcheck source=src/lib/testutils/dhcp_test_lib.sh.in
-. "@abs_top_builddir@/src/lib/testutils/dhcp_test_lib.sh"
-
-# This test verifies that syntax checking works properly. This function
-# requires 3 parameters:
-# test_name
-# config - string with a content of the config (will be written to a file)
-# expected_code - expected exit code returned by kea (0 - success, 1 - failure)
-syntax_check_test() {
- local test_name="${1}"
- local config="${2}"
- local expected_code="${3}"
- local check_type="${4}"
-
- # Log the start of the test and print test name.
- test_start "${test_name}"
- # Create correct configuration file.
- create_config "${config}"
- # Check it
- printf "Running command %s.\n" "\"${bin_path}/${bin} ${check_type} ${CFG_FILE}\""
- run_command \
- "${bin_path}/${bin}" "${check_type}" "${CFG_FILE}"
- if [ "${EXIT_CODE}" -ne "${expected_code}" ]; then
- printf 'ERROR: expected exit code %s, got %s\n' "${expected_code}" "${EXIT_CODE}"
- clean_exit 1
- fi
-
- test_finish 0
-}
-
-# This test verifies that DHCPv6 can be reconfigured with a SIGHUP signal.
-dynamic_reconfiguration_test() {
- # Log the start of the test and print test name.
- test_start "dhcpv6_srv.dynamic_reconfiguration"
- # Create new configuration file.
- create_config "${CONFIG}"
- # Instruct Kea to log to the specific file.
- set_logger
- # Start Kea.
- start_kea "${bin_path}/${bin}"
- # 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_pid "${bin}"
- 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
-
- # Now use invalid configuration.
- create_config "${CONFIG_INVALID}"
-
- # Try to reconfigure by sending SIGHUP
- send_signal 1 "${bin}"
-
- # The configuration should fail and the error message should be there.
- wait_for_message 10 "DHCP6_CONFIG_LOAD_FAIL" 1
-
- # After receiving SIGHUP the server should try to reconfigure itself.
- # The configuration provided is invalid so it should result in
- # reconfiguration failure but the server should still be running.
- get_reconfigs
- if [ "${_GET_RECONFIGS}" -ne 1 ]; then
- printf "ERROR: server has been reconfigured despite bogus configuration.\n"
- clean_exit 1
- elif [ "${_GET_RECONFIG_ERRORS}" -ne 1 ]; then
- printf "ERROR: server did not report reconfiguration error despite attempt\
- to configure it with invalid configuration.\n"
- clean_exit 1
- fi
-
- # Make sure the server is still operational.
- get_pid "${bin}"
- if [ "${_GET_PIDS_NUM}" -ne 1 ]; then
- printf "ERROR: Kea process was killed when attempting reconfiguration.\n"
- clean_exit 1
- fi
-
- # Restore the good configuration.
- create_config "${CONFIG}"
-
- # Reconfigure the server with SIGHUP.
- send_signal 1 "${bin}"
-
- # There should be two occurrences of the DHCP6_CONFIG_COMPLETE messages.
- # Wait for it up to 10s.
- wait_for_message 10 "DHCP6_CONFIG_COMPLETE" 2
-
- # After receiving SIGHUP the server should get reconfigured and the
- # reconfiguration should be noted in the log file. We should now
- # have two configurations logged in the log file.
- if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
- printf "ERROR: server hasn't been reconfigured.\n"
- clean_exit 1
- else
- printf "Server successfully reconfigured.\n"
- fi
-
- # Make sure the server is still operational.
- get_pid "${bin}"
- if [ "${_GET_PIDS_NUM}" -ne 1 ]; then
- printf "ERROR: Kea process was killed when attempting reconfiguration.\n"
- clean_exit 1
- fi
-
- # When the server receives a signal the call to select() function is
- # interrupted. This should not be logged as an error.
- get_log_messages "DHCP6_PACKET_RECEIVE_FAIL"
- assert_eq 0 "${_GET_LOG_MESSAGES}" \
- "Expected get_log_messages DHCP6_PACKET_RECEIVE_FAIL return %d, \
-returned %d."
-
- # All ok. Shut down Kea and exit.
- test_finish 0
-}
-
-# This test verifies that DHCPv6 server is shut down gracefully when it
-# receives a SIGINT or SIGTERM signal.
-shutdown_test() {
- local test_name="${1}" # Test name
- local signum="${2}" # Signal number
-
- # Log the start of the test and print test name.
- test_start "${test_name}"
- # Create new configuration file.
- create_config "${CONFIG}"
- # Instruct Kea to log to the specific file.
- set_logger
- # Start Kea.
- start_kea "${bin_path}/${bin}"
- # 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_pid "${bin}"
- 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 "${signum}" "${bin}"
-
- # 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" 1
- if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
- printf "ERROR: Server did not record shutdown in the log.\n"
- clean_exit 1
- fi
-
- # Make sure the server is down.
- wait_for_server_down 5 "${bin}"
- assert_eq 1 "${_WAIT_FOR_SERVER_DOWN}" \
- "Expected wait_for_server_down return %d, returned %d"
-
- # When the server receives a signal the call to select() function is
- # interrupted. This should not be logged as an error.
- get_log_messages "DHCP6_PACKET_RECEIVE_FAIL"
- assert_eq 0 "${_GET_LOG_MESSAGES}" \
- "Expected get_log_messages DHCP6_PACKET_RECEIVE_FAIL return %d, \
-returned %d."
-
- test_finish 0
-}
-
-# This test verifies that DHCPv6 can be configured to run lease file cleanup
-# periodically.
-lfc_timer_test() {
- # Log the start of the test and print test name.
- test_start "dhcpv6_srv.lfc_timer_test"
- # Create a configuration with the LFC enabled, by replacing the section
- # with the lfc-interval and persist parameters.
- LFC_CONFIG=$(printf '%s' "${CONFIG}" | sed -e 's/\"lfc-interval\": 0/\"lfc-interval\": 3/g' \
- | sed -e 's/\"persist\": false,/\"persist\": true,/g')
- # Create new configuration file.
- create_config "${LFC_CONFIG}"
- # Instruct Kea to log to the specific file.
- set_logger
- # Start Kea.
- start_kea "${bin_path}/${bin}"
- # 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_pid "${bin}"
- 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 if Kea emits the log message indicating that LFC is started.
- wait_for_message 10 "DHCPSRV_MEMFILE_LFC_EXECUTE" 1
- if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
- printf "ERROR: Server did not execute LFC.\n"
- clean_exit 1
- fi
-
- # Give it a short time to run.
- sleep 1
-
- # Modify the interval.
- LFC_CONFIG=$(printf '%s' "${LFC_CONFIG}" | sed -e 's/\"lfc-interval\": 3/\"lfc-interval\": 4/g')
- # Create new configuration file.
- create_config "${LFC_CONFIG}"
-
- # Reconfigure the server with SIGHUP.
- send_signal 1 "${bin}"
-
- # There should be two occurrences of the DHCP4_CONFIG_COMPLETE messages.
- # Wait for it up to 10s.
- wait_for_message 10 "DHCP6_CONFIG_COMPLETE" 2
-
- # After receiving SIGHUP the server should get reconfigured and the
- # reconfiguration should be noted in the log file. We should now
- # have two configurations logged in the log file.
- if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
- printf "ERROR: server hasn't been reconfigured.\n"
- clean_exit 1
- else
- printf "Server successfully reconfigured.\n"
- fi
-
- # Make sure the server is still operational.
- get_pid "${bin}"
- if [ "${_GET_PIDS_NUM}" -ne 1 ]; then
- printf "ERROR: Kea process was killed when attempting reconfiguration.\n"
- clean_exit 1
- fi
-
- # Wait for the LFC to run the second time.
- wait_for_message 10 "DHCPSRV_MEMFILE_LFC_EXECUTE" 2
- if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
- printf "ERROR: Server did not execute LFC.\n"
- clean_exit 1
- fi
-
- # Send signal to Kea SIGTERM
- send_signal 15 "${bin}"
-
- # 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" 1
- if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
- printf "ERROR: Server did not record shutdown in the log.\n"
- clean_exit 1
- fi
-
- # Make sure the server is down.
- wait_for_server_down 5 "${bin}"
- assert_eq 1 "${_WAIT_FOR_SERVER_DOWN}" \
- "Expected wait_for_server_down return %d, returned %d"
-
- # All ok. Shut down Kea and exit.
- test_finish 0
-}
-
-server_pid_file_test "${CONFIG}" DHCP6_ALREADY_RUNNING
-dynamic_reconfiguration_test
-shutdown_test "dhcpv6.sigterm_test" 15
-shutdown_test "dhcpv6.sigint_test" 2
-version_test "dhcpv6.version"
-logger_vars_test "dhcpv6.variables"
-lfc_timer_test
-syntax_check_test "dhcpv6.syntax_check_success" "${CONFIG}" 0 -t
-syntax_check_test "dhcpv6.syntax_check_bad_syntax" "${CONFIG_BAD_SYNTAX}" 1 -t
-syntax_check_test "dhcpv6.syntax_check_bad_values" "${CONFIG_BAD_VALUES}" 1 -t
-syntax_check_test "dhcpv6.syntax_check_hooks_load_fail" "${INVALID_CONFIG_HOOKS_LOAD}" 1 -T
-syntax_check_test "dhcpv6.syntax_check_hooks_callout_fail_on_load" "${INVALID_CONFIG_HOOKS_CALLOUT_FAIL_ON_LOAD}" 1 -T
-syntax_check_test "dhcpv6.syntax_check_hooks_callout_fail_on_poll" "${INVALID_CONFIG_HOOKS_CALLOUT_FAIL_ON_POLL}" 1 -T
-password_redact_test "dhcpv6.password_redact_test" "$(kea_dhcp_config 6)" 0
+++ /dev/null
-// Copyright (C) 2013-2025 Internet Systems Consortium, Inc. ("ISC")
-//
-// 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/.
-
-#ifndef TEST_LIBRARIES_H
-#define TEST_LIBRARIES_H
-
-#include <config.h>
-
-namespace {
-
-// Names of the libraries used in these tests. These libraries are built using
-// libtool, so we need to look in the hidden ".libs" directory to locate the
-// shared library.
-
-// Library with load/unload functions creating marker files to check their
-// operation.
-const char* const CALLOUT_LIBRARY_1 = "@abs_builddir@/libco1.so";
-const char* const CALLOUT_LIBRARY_2 = "@abs_builddir@/libco2.so";
-const char* const CALLOUT_LIBRARY_3 = "@abs_builddir@/libco3.so";
-const char* const CALLOUT_LIBRARY_4 = "@abs_builddir@/libco4.so";
-
-// Name of a library which is not present.
-const char* const NOT_PRESENT_LIBRARY = "@abs_builddir@/libnothere.so";
-
-} // anonymous namespace
-
-
-#endif // TEST_LIBRARIES_H
dhcp6_tests_conf_data.set('abs_top_builddir', TOP_BUILD_DIR)
dhcp6_tests_conf_data.set('abs_top_srcdir', TOP_SOURCE_DIR)
dhcp6_tests_conf_data.set('abs_builddir', current_build_dir)
+dhcp6_tests_conf_data.set('dotlibs', '')
dhcp6_process_tests = configure_file(
- input: 'meson-dhcp6_process_tests.sh.in',
+ input: 'dhcp6_process_tests.sh.in',
output: 'dhcp6_process_tests.sh',
configuration: dhcp6_tests_conf_data,
)
configuration: dhcp6_tests_conf_data,
)
configure_file(
- input: 'meson-test_libraries.h.in',
+ input: 'test_libraries.h.in',
output: 'test_libraries.h',
configuration: dhcp6_tests_conf_data,
)
-// Copyright (C) 2013-2024 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2025 Internet Systems Consortium, Inc. ("ISC")
//
// 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
// Library with load/unload functions creating marker files to check their
// operation.
-const char* const CALLOUT_LIBRARY_1 = "@abs_builddir@/.libs/libco1.so";
-const char* const CALLOUT_LIBRARY_2 = "@abs_builddir@/.libs/libco2.so";
-const char* const CALLOUT_LIBRARY_3 = "@abs_builddir@/.libs/libco3.so";
-const char* const CALLOUT_LIBRARY_4 = "@abs_builddir@/.libs/libco4.so";
+const char* const CALLOUT_LIBRARY_1 = "@abs_builddir@/@dotlibs@libco1.so";
+const char* const CALLOUT_LIBRARY_2 = "@abs_builddir@/@dotlibs@libco2.so";
+const char* const CALLOUT_LIBRARY_3 = "@abs_builddir@/@dotlibs@libco3.so";
+const char* const CALLOUT_LIBRARY_4 = "@abs_builddir@/@dotlibs@libco4.so";
// Name of a library which is not present.
-const char* const NOT_PRESENT_LIBRARY = "@abs_builddir@/.libs/libnothere.so";
+const char* const NOT_PRESENT_LIBRARY = "@abs_builddir@/@dotlibs@libnothere.so";
} // anonymous namespace
+++ /dev/null
-// Copyright (C) 2013-2025 Internet Systems Consortium, Inc. ("ISC")
-//
-// 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/.
-
-#ifndef TEST_LIBRARIES_H
-#define TEST_LIBRARIES_H
-
-#include <config.h>
-
-namespace {
-
-// Names of the libraries used in these tests. These libraries are built using
-// libtool, so we need to look in the hidden ".libs" directory to locate the
-// shared library.
-
-// Library with load/unload functions creating marker files to check their
-// operation.
-static const char* CALLOUT_LIBRARY_1 = "@abs_builddir@/libco1.so";
-static const char* CALLOUT_LIBRARY_2 = "@abs_builddir@/libco2.so";
-
-// This library will try to get the following parameters:
-// - svalue (and will expect its value to be "string value")
-// - ivalue (and will expect its value to be 42)
-// - bvalue (and will expect its value to be true)
-static const char* CALLOUT_PARAMS_LIBRARY = "@abs_builddir@/libco3.so";
-
-// Name of a library which is not present.
-static const char* NOT_PRESENT_LIBRARY = "@abs_builddir@/libnothere.so";
-
-} // anonymous namespace
-
-
-#endif // TEST_LIBRARIES_H
)
kea_dhcpsrv_conf_data = configuration_data()
kea_dhcpsrv_conf_data.set('abs_builddir', current_build_dir)
+kea_dhcpsrv_conf_data.set('dotlibs', '')
configure_file(
- input: 'meson-test_libraries.h.in',
+ input: 'test_libraries.h.in',
output: 'test_libraries.h',
configuration: kea_dhcpsrv_conf_data,
)
-// Copyright (C) 2013-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2025 Internet Systems Consortium, Inc. ("ISC")
//
// 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
// Library with load/unload functions creating marker files to check their
// operation.
-static const char* CALLOUT_LIBRARY_1 = "@abs_builddir@/.libs/libco1.so";
-static const char* CALLOUT_LIBRARY_2 = "@abs_builddir@/.libs/libco2.so";
+static const char* CALLOUT_LIBRARY_1 = "@abs_builddir@/@dotlibs@libco1.so";
+static const char* CALLOUT_LIBRARY_2 = "@abs_builddir@/@dotlibs@libco2.so";
// This library will try to get the following parameters:
// - svalue (and will expect its value to be "string value")
// - ivalue (and will expect its value to be 42)
// - bvalue (and will expect its value to be true)
-static const char* CALLOUT_PARAMS_LIBRARY = "@abs_builddir@/.libs/libco3.so";
+static const char* CALLOUT_PARAMS_LIBRARY = "@abs_builddir@/@dotlibs@libco3.so";
// Name of a library which is not present.
-static const char* NOT_PRESENT_LIBRARY = "@abs_builddir@/.libs/libnothere.so";
+static const char* NOT_PRESENT_LIBRARY = "@abs_builddir@/@dotlibs@libnothere.so";
} // anonymous namespace
+++ /dev/null
-// Copyright (C) 2013-2025 Internet Systems Consortium, Inc. ("ISC")
-//
-// 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/.
-
-#ifndef TEST_LIBRARIES_H
-#define TEST_LIBRARIES_H
-
-#include <config.h>
-
-namespace {
-
-// Names of the libraries used in these tests. These libraries are built using
-// libtool, so we need to look in the hidden ".libs" directory to locate the
-// .so file. Note that we access the .so file - libtool creates this as a
-// like to the real shared library.
-
-// Basic library with context_create and three "standard" callouts.
-static const char* BASIC_CALLOUT_LIBRARY = "@abs_builddir@/libbcl.so";
-
-// Library with context_create and three "standard" callouts, as well as
-// load() and unload() functions.
-static const char* FULL_CALLOUT_LIBRARY = "@abs_builddir@/libfcl.so";
-
-// Library where the all framework functions throw an exception
-static const char* FRAMEWORK_EXCEPTION_LIBRARY = "@abs_builddir@/libfxl.so";
-
-// Library where the version() function returns an incorrect result.
-static const char* INCORRECT_VERSION_LIBRARY = "@abs_builddir@/libivl.so";
-
-// Library where some of the callout registration is done with the load()
-// function.
-static const char* LOAD_CALLOUT_LIBRARY = "@abs_builddir@/liblcl.so";
-
-// Library where the load() function returns an error.
-static const char* LOAD_ERROR_CALLOUT_LIBRARY =
- "@abs_builddir@/liblecl.so";
-
-// Name of a library which is not present.
-static const char* NOT_PRESENT_LIBRARY = "@abs_builddir@/libnothere.so";
-
-// Library that does not include a version function.
-static const char* NO_VERSION_LIBRARY = "@abs_builddir@/libnvl.so";
-
-// Library where there is an unload() function.
-static const char* UNLOAD_CALLOUT_LIBRARY = "@abs_builddir@/libucl.so";
-
-// Library where parameters are checked.
-static const char* CALLOUT_PARAMS_LIBRARY = "@abs_builddir@/libpcl.so";
-
-// Library which tests objects parking.
-// Used only by hooks_manager_unittest.cc.
-#ifdef TEST_ASYNC_CALLOUT
-static const char* ASYNC_CALLOUT_LIBRARY = "@abs_builddir@/libacl.so";
-#endif
-
-} // anonymous namespace
-
-
-#endif // TEST_LIBRARIES_H
kea_hooks_conf_data = configuration_data()
kea_hooks_conf_data.set('abs_builddir', meson.current_build_dir())
+kea_hooks_conf_data.set('dotlibs', '')
configure_file(
input: 'marker_file.h.in',
output: 'marker_file.h',
configuration: kea_hooks_conf_data,
)
configure_file(
- input: 'meson-test_libraries.h.in',
+ input: 'test_libraries.h.in',
output: 'test_libraries.h',
configuration: kea_hooks_conf_data,
)
-// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2025 Internet Systems Consortium, Inc. ("ISC")
//
// 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
// like to the real shared library.
// Basic library with context_create and three "standard" callouts.
-static const char* BASIC_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libbcl.so";
+static const char* BASIC_CALLOUT_LIBRARY = "@abs_builddir@/@dotlibs@libbcl.so";
// Library with context_create and three "standard" callouts, as well as
// load() and unload() functions.
-static const char* FULL_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libfcl.so";
+static const char* FULL_CALLOUT_LIBRARY = "@abs_builddir@/@dotlibs@libfcl.so";
// Library where the all framework functions throw an exception
-static const char* FRAMEWORK_EXCEPTION_LIBRARY = "@abs_builddir@/.libs/libfxl.so";
+static const char* FRAMEWORK_EXCEPTION_LIBRARY = "@abs_builddir@/@dotlibs@libfxl.so";
// Library where the version() function returns an incorrect result.
-static const char* INCORRECT_VERSION_LIBRARY = "@abs_builddir@/.libs/libivl.so";
+static const char* INCORRECT_VERSION_LIBRARY = "@abs_builddir@/@dotlibs@libivl.so";
// Library where some of the callout registration is done with the load()
// function.
-static const char* LOAD_CALLOUT_LIBRARY = "@abs_builddir@/.libs/liblcl.so";
+static const char* LOAD_CALLOUT_LIBRARY = "@abs_builddir@/@dotlibs@liblcl.so";
// Library where the load() function returns an error.
static const char* LOAD_ERROR_CALLOUT_LIBRARY =
- "@abs_builddir@/.libs/liblecl.so";
+ "@abs_builddir@/@dotlibs@liblecl.so";
// Name of a library which is not present.
-static const char* NOT_PRESENT_LIBRARY = "@abs_builddir@/.libs/libnothere.so";
+static const char* NOT_PRESENT_LIBRARY = "@abs_builddir@/@dotlibs@libnothere.so";
// Library that does not include a version function.
-static const char* NO_VERSION_LIBRARY = "@abs_builddir@/.libs/libnvl.so";
+static const char* NO_VERSION_LIBRARY = "@abs_builddir@/@dotlibs@libnvl.so";
// Library where there is an unload() function.
-static const char* UNLOAD_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libucl.so";
+static const char* UNLOAD_CALLOUT_LIBRARY = "@abs_builddir@/@dotlibs@libucl.so";
// Library where parameters are checked.
-static const char* CALLOUT_PARAMS_LIBRARY = "@abs_builddir@/.libs/libpcl.so";
+static const char* CALLOUT_PARAMS_LIBRARY = "@abs_builddir@/@dotlibs@libpcl.so";
// Library which tests objects parking.
// Used only by hooks_manager_unittest.cc.
#ifdef TEST_ASYNC_CALLOUT
-static const char* ASYNC_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libacl.so";
+static const char* ASYNC_CALLOUT_LIBRARY = "@abs_builddir@/@dotlibs@libacl.so";
#endif
} // anonymous namespace
},
"hooks-libraries": [
{
- "library": "@abs_top_builddir@/src/bin/dhcp%s/tests/.libs/libco1.so",
+ "library": "@abs_top_builddir@/src/bin/dhcp%s/tests/@dotlibs@libco1.so",
"parameters": {
"password": "sensitive",
"user": "keatest",
+++ /dev/null
-#!/bin/sh
-
-# Copyright (C) 2014-2025 Internet Systems Consortium, Inc. ("ISC")
-#
-# 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/.
-
-# shellcheck disable=SC2034
-# SC2034: ... appears unused. Verify use (or export if used externally).
-
-# 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
-
-# Include XML reporting library.
-# shellcheck source=src/lib/testutils/xml_reporting_test_lib.sh.in
-. "@abs_top_builddir@/src/lib/testutils/xml_reporting_test_lib.sh"
-
-prefix="@prefix@"
-
-# Expected version
-EXPECTED_VERSION="@PACKAGE_VERSION@"
-
-# Kea environment variables for shell tests.
-# KEA_LOGGER_DESTINATION is set per test with set_logger.
-export KEA_LFC_EXECUTABLE="@abs_top_builddir@/src/bin/lfc/kea-lfc"
-export KEA_LOCKFILE_DIR="@abs_top_builddir@/test_lockfile_dir"
-export KEA_PIDFILE_DIR="@abs_top_builddir@/test_pidfile_dir"
-KEA_DHCP4_LOAD_MARKER_FILE="@abs_top_builddir@/src/bin/dhcp4/tests/load_marker.txt"
-KEA_DHCP4_UNLOAD_MARKER_FILE="@abs_top_builddir@/src/bin/dhcp4/tests/unload_marker.txt"
-KEA_DHCP4_SRV_CONFIG_MARKER_FILE="@abs_top_builddir@/src/bin/dhcp4/tests/srv_config_marker_file.txt"
-KEA_DHCP6_LOAD_MARKER_FILE="@abs_top_builddir@/src/bin/dhcp6/tests/load_marker.txt"
-KEA_DHCP6_UNLOAD_MARKER_FILE="@abs_top_builddir@/src/bin/dhcp6/tests/unload_marker.txt"
-KEA_DHCP6_SRV_CONFIG_MARKER_FILE="@abs_top_builddir@/src/bin/dhcp6/tests/srv_config_marker_file.txt"
-
-# A list of Kea processes, mainly used by the cleanup functions.
-KEA_PROCS="kea-dhcp4 kea-dhcp6 kea-dhcp-ddns kea-ctrl-agent"
-
-### Colors ###
-
-if test -t 1; then
- green='\033[92m'
- red='\033[91m'
- reset='\033[0m'
-fi
-
-### Logging functions ###
-
-# Prints error message.
-test_lib_error() {
- local s="${1-}" # Error message.
- local no_new_line="${2-}" # If specified, the message is not terminated
- # with new line.
- printf "ERROR/test_lib: %s" "${s}"
- if [ -z "${no_new_line}" ]; then
- printf '\n'
- fi
-}
-
-# Prints info message.
-test_lib_info() {
- 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}"
- if [ -z "${no_new_line}" ]; then
- printf '\n'
- fi
-}
-
-### Assertions ###
-
-# 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".
-assert_eq() {
- val1=${1} # Reference value
- val2=${2} # Tested value
- detailed_err=${3-} # Optional detailed error format string
- # If nothing found, present an error an exit.
- if [ "${val1}" -ne "${val2}" ]; then
- printf 'Assertion failure: %s != %s, expected %s, got %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
- clean_exit 1
- fi
-}
-
-# Assertion that checks that two strings are equal.
-# If strings 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-} # Optional detailed error format string
- # If nothing found, present an error an exit.
- if [ "${val1}" != "${val2}" ]; then
- printf 'Assertion failure: %s != %s, expected "%s", got "%s"\n' \
- "${val1}" "${val2}" "${val1}" "${val2}"
- # shellcheck disable=SC2059
- # 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
- clean_exit 1
- fi
-}
-
-# Assertion that checks that two strings are NOT equal.
-# If strings are equal, the mismatched values are presented and the
-# optional detailed error, if any, is printed.
-assert_str_neq() {
- reference=${1} # Reference value
- tested=${2} # Tested value
- detailed_error=${3-} # Optional detailed error format string
- if test "${reference}" = "${tested}"; then
- printf 'Assertion failure: expected different strings, but '
- printf 'both variables have the value "%s".\n' "${reference}"
- printf '%s\n%s\n' "${detailed_error}" "${OUTPUT}" >&2
- clean_exit 1
- fi
-}
-
-# 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() {
- pattern="${1}" # Substring or awk pattern
- text="${2}" # Text to be searched for substring
- detailed_err="${3}" # Detailed error format string
- # Search for a pattern
- match=$( printf "%s" "${text}" | awk /"${pattern}"/ )
- # If nothing found, present an error and exit.
- if [ -z "${match}" ]; then
- ERROR=$(printf \
-"Assertion failure:
-\"%s\"
-
-does not contain pattern:
-\"%s\"
-
-${detailed_err}
-" "${text}" "${pattern}" "${pattern}")
- printf '%s\n%s\n' "${ERROR}" "${OUTPUT}" >&2
- clean_exit 1
- fi
-}
-
-# 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).
-run_command() {
- if test -n "${DEBUG+x}"; then
- printf '%s\n' "${*}" >&2
- fi
- set +e
- OUTPUT=$("${@}")
- EXIT_CODE=${?}
- set -e
-}
-
-# Enable traps to print FAILED status when a command fails unexpectedly or when
-# the user sends a SIGINT. Used in `test_start`.
-traps_on() {
- 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
-}
-
-# Disable traps so that a double status is not printed. Used in `test_finish`
-# after the status has been printed explicitly.
-traps_off() {
- for t in HUP INT QUIT KILL TERM EXIT; do
- trap - "${t}"
- done
-}
-
-# 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}"
-}
-
-# Begins a test by printing its name.
-test_start() {
- TEST_NAME=${1-}
- if [ -z "${TEST_NAME}" ]; then
- test_lib_error "test_start requires test name as an argument"
- clean_exit 1
- fi
-
- # Set traps first to fail if something goes wrong.
- traps_on
-
- # Announce test start.
- printf "${green-}[ RUN ]${reset-} %s\n" "${TEST_NAME}"
-
- # Remove dangling Kea instances and remove log files.
- cleanup
-
- # Make sure lockfile and pidfile directories exist. They are used in some
- # tests.
- mkdir -p "${KEA_LOCKFILE_DIR}"
- # There are certain tests that intentionally run without a KEA_PIDFILE_DIR
- # e.g. keactrl.status_test. Only create the directory if we test requires
- # one.
- if test -n "${KEA_PIDFILE_DIR+x}"; then
- mkdir -p "${KEA_PIDFILE_DIR}"
- fi
-
- # Start timer in milliseconds.
- START_TIME=$(get_current_time)
-}
-
-# Prints test result an cleans up after the test.
-test_finish() {
- # 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}"
-
- if [ "${exit_code}" -eq 0 ]; then
- printf "${green-}[ OK ]${reset-} %s\n" "${TEST_NAME}"
- else
- # Dump log file for debugging purposes if specified and exists.
- # Otherwise the code below would simply call cat.
- # Use ${var+x} to test if ${var} is defined.
- if test -n "${LOG_FILE+x}" && test -s "${LOG_FILE}"; then
- printf 'Log file dump:\n'
- cat "${LOG_FILE}"
- fi
- printf "${red-}[ FAILED ]${reset-} %s\n" "${TEST_NAME}"
- fi
-
- # Remove dangling Kea instances and log files.
- cleanup
-
- # Reset traps.
- traps_off
-
- # 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}"
-}
-
-# Stores the configuration specified as a parameter in the configuration
-# file which name has been set in the ${CFG_FILE} variable.
-create_config() {
- local cfg="${1-}" # Configuration string.
- if [ -z "${CFG_FILE+x}" ]; then
- 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
- printf 'Creating Kea configuration file: %s.\n' "${CFG_FILE}"
- printf '%b' "${cfg}" > "${CFG_FILE}"
-}
-
-# Stores the DHCP4 configuration specified as a parameter in the
-# configuration file which name has been set in the ${DHCP4_CFG_FILE}
-# variable.
-create_dhcp4_config() {
- local cfg="${1-}" # Configuration string.
- if [ -z "${DHCP4_CFG_FILE+x}" ]; then
- test_lib_error "create_dhcp4_config requires DHCP4_CFG_FILE \
-variable be set"
- clean_exit 1
-
- elif [ -z "${cfg}" ]; then
- test_lib_error "create_dhcp4_config requires argument holding a \
-configuration"
- clean_exit 1
- fi
- printf 'Creating Dhcp4 configuration file: %s.\n' "${DHCP4_CFG_FILE}"
- printf '%b' "${cfg}" > "${DHCP4_CFG_FILE}"
-}
-
-# 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.
- if [ -z "${DHCP6_CFG_FILE+x}" ]; then
- 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
- printf 'Creating Dhcp6 configuration file: %s.\n' "${DHCP6_CFG_FILE}"
- printf '%b' "${cfg}" > "${DHCP6_CFG_FILE}"
-}
-
-# 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.
- if [ -z "${D2_CFG_FILE+x}" ]; then
- 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
- printf 'Creating D2 configuration file: %s.\n' "${D2_CFG_FILE}"
- printf '%b' "${cfg}" > "${D2_CFG_FILE}"
-}
-
-# 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.
- if [ -z "${CA_CFG_FILE+x}" ]; then
- 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
- printf 'Creating Ca configuration file: %s.\n' "${CA_CFG_FILE}"
- printf '%b' "${cfg}" > "${CA_CFG_FILE}"
-}
-
-# 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.
- if [ -z "${NC_CFG_FILE+x}" ]; then
- 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
- printf 'Creating Nc configuration file: %s.\n' "${NC_CFG_FILE}"
- printf '%b' "${cfg}" > "${NC_CFG_FILE}"
-}
-
-# Stores the keactrl configuration specified as a parameter in the
-# configuration file which name has been set in the ${KEACTRL_CFG_FILE}
-# variable.
-create_keactrl_config() {
- local cfg="${1-}" # Configuration string.
- if [ -z "${KEACTRL_CFG_FILE+x}" ]; then
- 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
- printf 'Creating keactrl configuration file: %s.\n' "${KEACTRL_CFG_FILE}"
- printf '%b' "${cfg}" > "${KEACTRL_CFG_FILE}"
-}
-
-# Sets Kea logger to write to the file specified by the global value
-# ${LOG_FILE}.
-set_logger() {
- if [ -z "${LOG_FILE+x}" ]; then
- test_lib_error "set_logger requires LOG_FILE variable be set"
- clean_exit 1
- fi
- printf 'Kea log will be stored in %s.\n' "${LOG_FILE}"
- export KEA_LOGGER_DESTINATION="${LOG_FILE}"
-}
-
-# 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 ${KEA_PIDFILE_DIR},
-# and their names should match the following pattern:
-# <cfg_file_name>.<proc_name>.pid. If the <cfg_file_name> is not
-# specified a 'test_config' is used by default.
-#
-# Return value:
-# _GET_PID: holds a PID if process is running
-# _GET_PIDS_NUM: holds 1 if process is running, 0 otherwise
-get_pid() {
- local proc_name="${1-}" # Process name
- local cfg_file_name="${2-}" # Configuration file name without extension.
-
- # Reset PID results.
- _GET_PID=0
- _GET_PIDS_NUM=0
-
- # PID file name includes process name. The process name is required.
- if [ -z "${proc_name}" ]; then
- test_lib_error "get_pid requires process name"
- clean_exit 1
- fi
-
- # There are certain tests that intentionally run without a KEA_PIDFILE_DIR
- # e.g. keactrl.status_test. We can't get the PID if KEA_PIDFILE_DIR is not
- # defined. In this case, this function is reporting process not running
- # (_GET_PID == 0).
- if test -z "${KEA_PIDFILE_DIR+x}"; then
- return
- 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.
- if [ -z "${cfg_file_name}" ]; then
- cfg_file_name="test_config"
- fi
-
- # Get the absolute location of the PID file for the specified process
- # name.
- abs_pidfile_path="${KEA_PIDFILE_DIR}/${cfg_file_name}.${proc_name}.pid"
-
- # If the PID file exists, get the PID and see if the process is alive.
- pid=$(cat "${abs_pidfile_path}" 2> /dev/null || true)
- if test -n "${pid}"; then
- if kill -0 "${pid}" > /dev/null 2>&1; then
- _GET_PID=${pid}
- _GET_PIDS_NUM=1
- fi
- fi
-}
-
-# Get the name of the process identified by PID.
-get_process_name() {
- local pid="${1-}"
- if test -z "${pid}"; then
- test_lib_error 'expected PID parameter in get_process_name'
- clean_exit 1
- fi
-
- 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-}"
- if test -z "${file}"; then
- test_lib_error 'expected file parameter in wait_for_file'
- clean_exit 1
- fi
-
- local timeout='4' # seconds
- local deadline="$(($(date +%s) + timeout))"
- while ! test -f "${file}"; do
- 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}"
- sleep 1
- done
-}
-
-# Wait for process identified by PID to die.
-wait_for_process_to_stop() {
- local pid="${1-}"
- if test -z "${pid}"; then
- test_lib_error 'expected PID parameter in wait_for_process_to_stop'
- clean_exit 1
- fi
-
- local timeout='4' # seconds
- local deadline="$(($(date +%s) + timeout))"
- while ps "${pid}" >/dev/null; do
- if test "${deadline}" -lt "$(date +%s)"; then
- # Time is up.
- printf 'ERROR: %s is not stopping.\n' "$(get_process_name "${pid}")" >&2
- return 1
- fi
- printf 'Waiting for %s to stop...\n' "$(get_process_name "${pid}")"
- sleep 1
- done
-}
-
-# 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.
-#
-# 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)
-kill_processes_by_name() {
- local proc_name="${1-}" # Process name
- if [ -z "${proc_name}" ]; then
- test_lib_error "kill_processes_by_name requires process name"
- clean_exit 1
- fi
-
- # Obtain PIDs of running processes.
- local pids
- pids=$(pgrep "${proc_name}" || true)
- # For each PID found, send kill signal.
- for pid in ${pids}; do
- printf 'Shutting down Kea process %s with PID %d...\n' "${proc_name}" "${pid}"
- kill -9 "${pid}" || true
- done
-
- # Wait for all processes to stop.
- for pid in ${pids}; do
- printf 'Waiting for Kea process %s with PID %d to stop...\n' "${proc_name}" "${pid}"
- wait_for_process_to_stop "${pid}"
- done
-}
-
-# Returns the number of occurrences of the Kea log message in the log file.
-# Return value:
-# _GET_LOG_MESSAGES: number of log message occurrences.
-get_log_messages() {
- local msg="${1}" # Message id, e.g. DHCP6_SHUTDOWN
- if [ -z "${msg}" ]; then
- test_lib_error "get_log_messages require message identifier"
- clean_exit 1
- fi
- _GET_LOG_MESSAGES=0
- # If log file is not present, the number of occurrences is 0.
- # Use ${var+x} to test if ${var} is defined.
- if test -n "${LOG_FILE+x}" && test -s "${LOG_FILE}"; then
- # Grep log file for the logger message occurrences and remove
- # whitespaces, if any.
- _GET_LOG_MESSAGES=$(grep -Fo "${msg}" "${LOG_FILE}" | wc -w | tr -d " ")
- fi
-}
-
-# Returns the number of server configurations performed so far. Also
-# returns the number of configuration errors.
-# Return values:
-# _GET_RECONFIGS: number of configurations so far.
-# _GET_RECONFIG_ERRORS: number of configuration errors.
-get_reconfigs() {
- # Grep log file for CONFIG_COMPLETE occurrences. There should
- # be one occurrence per (re)configuration.
- _GET_RECONFIGS=$(grep -Fo CONFIG_COMPLETE "${LOG_FILE}" | wc -w)
- # Grep log file for CONFIG_LOAD_FAIL to check for configuration
- # failures.
- _GET_RECONFIG_ERRORS=$(grep -Fo CONFIG_LOAD_FAIL "${LOG_FILE}" | wc -w)
- # Remove whitespaces
- ${_GET_RECONFIGS##*[! ]}
- ${_GET_RECONFIG_ERRORS##*[! ]}
-}
-
-# Remove the given directories or files if they exist.
-remove_if_exists() {
- while test ${#} -gt 0; do
- if test -e "${1}"; then
- rm -rf "${1}"
- fi
- shift
- done
-}
-
-# Performs cleanup after test.
-# It shuts down running Kea processes and removes temporary files.
-# The location of the log file and the configuration files should be set
-# in the ${LOG_FILE}, ${CFG_FILE} and ${KEACTRL_CFG_FILE} variables
-# respectively, prior to calling this function.
-cleanup() {
- # If there is no KEA_PROCS set, just return
- if [ -z "${KEA_PROCS}" ]; then
- return
- fi
-
- # KEA_PROCS holds the name of all Kea processes. Shut down each
- # of them if running.
- for proc_name in ${KEA_PROCS}
- do
- get_pid "${proc_name}"
- # Shut down running Kea process.
- if [ "${_GET_PIDS_NUM}" -ne 0 ]; then
- printf 'Shutting down Kea process having pid %d.\n' "${_GET_PID}"
- kill -9 "${_GET_PID}"
- fi
- done
-
- # 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.
- kill_processes_by_name "kea-lfc"
-
- # Remove temporary files.
- remove_if_exists \
- "${CA_CFG_FILE-}" \
- "${CFG_FILE-}" \
- "${D2_CFG_FILE-}" \
- "${DHCP4_CFG_FILE-}" \
- "${KEA_DHCP4_LOAD_MARKER_FILE-}" \
- "${KEA_DHCP4_UNLOAD_MARKER_FILE-}" \
- "${KEA_DHCP4_SRV_CONFIG_MARKER_FILE-}" \
- "${DHCP6_CFG_FILE-}" \
- "${KEA_DHCP6_LOAD_MARKER_FILE-}" \
- "${KEA_DHCP6_UNLOAD_MARKER_FILE-}" \
- "${KEA_DHCP6_SRV_CONFIG_MARKER_FILE-}" \
- "${KEACTRL_CFG_FILE-}" \
- "${KEA_LOCKFILE_DIR-}" \
- "${KEA_PIDFILE_DIR-}" \
- "${NC_CFG_FILE-}"
-
- # Use ${var+x} to test if ${var} is defined.
- if test -n "${LOG_FILE+x}" && test -n "${LOG_FILE}"; then
- rm -rf "${LOG_FILE}"
- rm -rf "${LOG_FILE}.lock"
- fi
- # 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.
- if test -n "${LEASE_FILE+x}" && test -n "${LEASE_FILE}"; then
- rm -rf "${LEASE_FILE}"*
- fi
-}
-
-# Exists the test in the clean way.
-# It performs the cleanup and prints whether the test has passed or failed.
-# If a test fails, the Kea log is dumped.
-clean_exit() {
- exit_code=${1-} # Exit code to be returned by the exit function.
- case ${exit_code} in
- ''|*[!0-9]*)
- test_lib_error "argument passed to clean_exit must be a number" ;;
- esac
- # Print test result and perform a cleanup
- test_finish "${exit_code}"
- exit "${exit_code}"
-}
-
-# Starts Kea process in background using a configuration file specified
-# in the global variable ${CFG_FILE}.
-start_kea() {
- local bin="${1-}"
- if [ -z "${bin}" ]; then
- test_lib_error "binary name must be specified for start_kea"
- clean_exit 1
- fi
- printf "Running command %s.\n" "\"${bin} -c ${CFG_FILE}\""
- "${bin}" -c "${CFG_FILE}" &
-}
-
-# Waits with timeout for Kea to start.
-# This function repeatedly checks 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.
-# Return value:
-# _WAIT_FOR_KEA: 0 if Kea hasn't started, 1 otherwise
-wait_for_kea() {
- local timeout="${1-}" # Desired timeout in seconds.
- if test -z "${timeout}"; then
- test_lib_error 'expected timeout parameter in wait_for_kea'
- clean_exit 1
- fi
- 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
- _WAIT_FOR_KEA=0
- test_lib_info "wait_for_kea " "skip-new-line"
- while [ ! -s "${LOG_FILE}" ] && [ "${loops}" -le "${timeout}" ]; do
- printf "."
- sleep 1
- loops=$(( 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 number
-# of message occurrences to show up. If the expected number of
-# message doesn't occur, the error status is returned.
-# Return value:
-# _WAIT_FOR_MESSAGE: 0 if the message hasn't occurred, 1 otherwise.
-wait_for_message() {
- local timeout="${1-}" # Expected timeout value in seconds.
- local message="${2-}" # Expected message id.
- 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
- if [ -z "${message}" ]; then
- 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.
- _WAIT_FOR_MESSAGE=0
- test_lib_info "wait_for_message ${message}: " "skip-new-line"
- # Check if log file exists and if we reached timeout.
- while [ "${loops}" -le "${timeout}" ]; do
- printf "."
- # Check if the message has been logged.
- get_log_messages "${message}"
- if [ "${_GET_LOG_MESSAGES}" -ge "${occurrences}" ]; then
- printf '\n'
- _WAIT_FOR_MESSAGE=1
- return
- fi
- # Message not recorded. Keep going.
- sleep 1
- loops=$(( loops + 1 ))
- done
- printf '\n'
- # Timeout.
-}
-
-# Waits for server to be down.
-# Return value:
-# _WAIT_FOR_SERVER_DOWN: 1 if server is down, 0 if timeout occurred and the
-# server is still running.
-wait_for_server_down() {
- local timeout="${1-}" # Timeout specified in seconds.
- local proc_name="${2-}" # Server process name.
- if test -z "${proc_name}"; then
- test_lib_error 'expected process name parameter in wait_for_server_down'
- clean_exit 1
- fi
-
- 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"
- while [ "${loops}" -le "${timeout}" ]; do
- printf "."
- get_pid "${proc_name}"
- if [ "${_GET_PIDS_NUM}" -eq 0 ]; then
- printf '\n'
- _WAIT_FOR_SERVER_DOWN=1
- return
- fi
- sleep 1
- loops=$(( loops + 1 ))
- done
- printf '\n'
-}
-
-# Sends specified signal to the Kea process.
-send_signal() {
- 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 \
-must be a number"
- clean_exit 1 ;;
- esac
- # Validate process name
- if [ -z "${proc_name}" ]; then
- test_lib_error "send_signal requires process name be passed as argument"
- clean_exit 1
- fi
- # Get Kea pid.
- get_pid "${proc_name}"
- 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 %s to Kea process (pid=%s).\n" "${sig}" "${_GET_PID}"
- # Actually send a signal.
- kill "-${sig}" "${_GET_PID}"
-}
-
-# 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
- if [ -z "${bin_name}" ]; then
- test_lib_error "verify_server_pid requires binary name"
- clean_exit 1
- fi
-
- if [ -z "${cfg_file}" ]; then
- test_lib_error "verify_server_pid requires config file name"
- clean_exit 1
- fi
-
- # Only the file name portion of the config file is used, try and
- # extract it. NOTE if this "algorithm" changes this code will need
- # to be updated.
- fname=$(basename "${cfg_file}")
- fname=$(echo "${fname}" | cut -f1 -d'.')
-
- if [ -z "${fname}" ]; then
- 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"
-
- if [ ! -e "${pid_file}" ]; then
- printf "ERROR: PID file:[%s] does not exist\n" "${pid_file}"
- clean_exit 1
- fi
-
- # File exists, does its PID point to a live process?
- pid=$(cat "${pid_file}" 2> /dev/null || true)
- if ! kill -0 "${pid}"; then
- printf "ERROR: PID file:[%s] exists but PID:[%d] does not\n" \
- "${pid_file}" "${pid}"
- clean_exit 1
- fi
-
- # Make the values accessible to the caller
- _SERVER_PID="${pid}"
- _SERVER_PID_FILE="${pid_file}"
-}
-
-# This test verifies that the binary is reporting its version properly.
-version_test() {
- test_name=${1} # Test name
- long_version=${2-} # Test long version?
-
- # Log the start of the test and print test name.
- test_start "${test_name}"
-
- # If set to anything other than empty string, reset it to the long version
- # parameter.
- if test -n "${long_version}"; then
- long_version='--version'
- fi
-
- # 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
- run_command \
- "${bin_path}/${bin}" "${v}"
-
- if test "${OUTPUT}" != "${EXPECTED_VERSION}"; then
- printf 'ERROR: Expected version "%s", got "%s" when calling "%s"\n' \
- "${EXPECTED_VERSION}" "${OUTPUT}" "${bin} ${v}"
- test_finish 1
- fi
- done
-
- test_finish 0
-}
-
-# 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.
- test_start "${test_name}"
-
- # 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.
- start_kea "${bin_path}/${bin}"
-
- # Wait for Kea to process the invalid configuration and die.
- sleep 1
-
- # Check if it is still running. It should have terminated.
- 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}"
-
- # Revert to the old KEA_LOCKFILE_DIR value
- KEA_LOCKFILE_DIR=${KEA_LOCKFILE_DIR_OLD}
- clean_exit 1
- fi
-
- if [ ! -f "./logger_lockfile" ]; then
- printf 'ERROR: Expect %s to create logger_lockfile in the ' "${bin}"
- printf 'current directory, but no such file exists.\n'
-
- # 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.
- start_kea "${bin_path}/${bin}"
-
- # Wait for Kea to process the invalid configuration and die.
- sleep 1
-
- # Check if it is still running. It should have terminated.
- 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}"
-
- # Revert to the old KEA_LOCKFILE_DIR value
- KEA_LOCKFILE_DIR=${KEA_LOCKFILE_DIR_OLD}
-
- clean_exit 1
- fi
-
- if [ -f "./logger_lockfile" ]; then
- printf 'ERROR: Expect %s to NOT create logger_lockfile in the ' "${bin}"
- printf 'current directory, but the file exists.\n'
-
- # 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
- printf 'Reverting KEA_LOCKFILE_DIR to %s\n' "${KEA_LOCKFILE_DIR_OLD}"
- KEA_LOCKFILE_DIR=${KEA_LOCKFILE_DIR_OLD}
-
- test_finish 0
-}
-
-# 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"
- # Create new configuration file.
- create_config "${CONFIG}"
- # Instruct server to log to the specific file.
- set_logger
- # Start server
- start_kea "${bin_path}/${bin}"
- # Wait up to 20s for server to start.
- wait_for_kea 20
- if [ "${_WAIT_FOR_KEA}" -eq 0 ]; then
- printf 'ERROR: timeout waiting for %s to start.\n' "${bin}"
- clean_exit 1
- fi
-
- # Verify server is still running
- verify_server_pid "${bin}" "${CFG_FILE}"
-
- printf 'PID file is [%s], PID is [%d]\n' "${_SERVER_PID_FILE}" "${_SERVER_PID}"
-
- # Now try to start a second one
- start_kea "${bin_path}/${bin}"
-
- wait_for_message 10 "${log_id}" 1
- if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
- printf 'ERROR: Second %s instance started? ' "${bin}"
- printf 'PID conflict not reported.\n'
- clean_exit 1
- fi
-
- # Verify server is still running
- verify_server_pid "${bin}" "${CFG_FILE}"
-
- # All ok. Shut down the server and exit.
- test_finish 0
-}
-
-# This test verifies that passwords are redacted in logs.
-# This function takes 2 parameters:
-# test_name
-# config - string with a content of the config (will be written to a file)
-# expected_code - expected exit code returned by kea (0 - success, 1 - failure)
-password_redact_test() {
- local test_name="${1}"
- local config="${2}"
- local expected_code="${3}"
-
- # Log the start of the test and print test name.
- test_start "${test_name}"
- # Create correct configuration file.
- create_config "${config}"
- # Instruct Control Agent to log to the specific file.
- set_logger
- # Check it
- printf "Running command %s.\n" "\"${bin_path}/${bin} -d -t ${CFG_FILE}\""
- run_command \
- "${bin_path}/${bin}" -d -t "${CFG_FILE}"
- if [ "${EXIT_CODE}" -ne "${expected_code}" ]; then
- printf 'ERROR: expected exit code %s, got %s\n' "${expected_code}" "${EXIT_CODE}"
- clean_exit 1
- fi
- if grep -q 'sensitive' "${LOG_FILE}"; then
- printf "ERROR: sensitive is present in logs\n"
- clean_exit 1
- fi
- if ! grep -q 'superadmin' "${LOG_FILE}"; then
- printf "ERROR: superadmin is not present in logs\n"
- clean_exit 1
- fi
- test_finish 0
-}
-
-# kea-dhcp[46] configuration with a password
-# used for redact tests:
-# - sensitive should be hidden
-# - superadmin should be visible
-kea_dhcp_config() {
- printf '
-{
- "Dhcp%s": {
- "config-control": {
- "config-databases": [
- {
- "password": "sensitive",
- "type": "mysql",
- "user": "keatest"
- }
- ]
- },
- "hooks-libraries": [
- {
- "library": "@abs_top_builddir@/src/bin/dhcp%s/tests/libco1.so",
- "parameters": {
- "password": "sensitive",
- "user": "keatest",
- "nested-map": {
- "password": "sensitive",
- "user": "keatest"
- }
- }
- }
- ],
- "hosts-database": {
- "password": "sensitive",
- "type": "mysql",
- "user": "keatest"
- },
- "lease-database": {
- "password": "sensitive",
- "type": "mysql",
- "user": "keatest"
- },
- "user-context": {
- "password": "superadmin",
- "secret": "superadmin",
- "shared-info": {
- "password": "superadmin",
- "secret": "superadmin"
- }
- }
- }
-}
-' "${1}" "${1}"
-}
dhcp_test_lib_conf_data.set('abs_top_builddir', TOP_BUILD_DIR)
dhcp_test_lib_conf_data.set('prefix', PREFIX)
dhcp_test_lib_conf_data.set('PACKAGE_VERSION', project_version)
+dhcp_test_lib_conf_data.set('dotlibs', '')
configure_file(
- input: 'meson-dhcp_test_lib.sh.in',
+ input: 'dhcp_test_lib.sh.in',
output: 'dhcp_test_lib.sh',
configuration: dhcp_test_lib_conf_data,
)