]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3477] Added missing shell tests
authorFrancis Dupont <fdupont@isc.org>
Fri, 23 Aug 2024 15:44:20 +0000 (17:44 +0200)
committerFrancis Dupont <fdupont@isc.org>
Fri, 20 Sep 2024 11:46:27 +0000 (13:46 +0200)
15 files changed:
configure.ac
src/bin/shell/tests/.gitignore
src/bin/shell/tests/Makefile.am
src/bin/shell/tests/ca_basic_auth_tests.sh.in
src/bin/shell/tests/d2_basic_auth_tests.sh.in
src/bin/shell/tests/dhcp4_basic_auth_tests.sh.in [new file with mode: 0644]
src/bin/shell/tests/dhcp6_basic_auth_tests.sh.in [new file with mode: 0644]
src/bin/shell/tests/shell_ca_process_tests.sh.in
src/bin/shell/tests/shell_d2_process_tests.sh.in
src/bin/shell/tests/shell_dhcp4_process_tests.sh.in [new file with mode: 0644]
src/bin/shell/tests/shell_dhcp6_process_tests.sh.in [new file with mode: 0644]
src/bin/shell/tests/tls_ca_process_tests.sh.in
src/bin/shell/tests/tls_d2_process_tests.sh.in
src/bin/shell/tests/tls_dhcp4_process_tests.sh.in [new file with mode: 0644]
src/bin/shell/tests/tls_dhcp6_process_tests.sh.in [new file with mode: 0644]

index e184e3aa21888233317e4953236b8037b1152577..eb3bfe3ce1185c070abfa0bd1b9aca63a76d971e 100644 (file)
@@ -1564,16 +1564,28 @@ AC_CONFIG_FILES([src/bin/shell/tests/ca_basic_auth_tests.sh],
                 [chmod +x src/bin/shell/tests/ca_basic_auth_tests.sh])
 AC_CONFIG_FILES([src/bin/shell/tests/d2_basic_auth_tests.sh],
                 [chmod +x src/bin/shell/tests/d2_basic_auth_tests.sh])
+AC_CONFIG_FILES([src/bin/shell/tests/dhcp4_basic_auth_tests.sh],
+                [chmod +x src/bin/shell/tests/dhcp4_basic_auth_tests.sh])
+AC_CONFIG_FILES([src/bin/shell/tests/dhcp6_basic_auth_tests.sh],
+                [chmod +x src/bin/shell/tests/dhcp6_basic_auth_tests.sh])
 AC_CONFIG_FILES([src/bin/shell/tests/shell_ca_process_tests.sh],
                 [chmod +x src/bin/shell/tests/shell_ca_process_tests.sh])
 AC_CONFIG_FILES([src/bin/shell/tests/shell_d2_process_tests.sh],
                 [chmod +x src/bin/shell/tests/shell_d2_process_tests.sh])
+AC_CONFIG_FILES([src/bin/shell/tests/shell_dhcp4_process_tests.sh],
+                [chmod +x src/bin/shell/tests/shell_dhcp4_process_tests.sh])
+AC_CONFIG_FILES([src/bin/shell/tests/shell_dhcp6_process_tests.sh],
+                [chmod +x src/bin/shell/tests/shell_dhcp6_process_tests.sh])
 AC_CONFIG_FILES([src/bin/shell/tests/shell_unittest.py],
                 [chmod +x src/bin/shell/tests/shell_unittest.py])
 AC_CONFIG_FILES([src/bin/shell/tests/tls_ca_process_tests.sh],
                 [chmod +x src/bin/shell/tests/tls_ca_process_tests.sh])
 AC_CONFIG_FILES([src/bin/shell/tests/tls_d2_process_tests.sh],
                 [chmod +x src/bin/shell/tests/tls_d2_process_tests.sh])
+AC_CONFIG_FILES([src/bin/shell/tests/tls_dhcp4_process_tests.sh],
+                [chmod +x src/bin/shell/tests/tls_dhcp4_process_tests.sh])
+AC_CONFIG_FILES([src/bin/shell/tests/tls_dhcp6_process_tests.sh],
+                [chmod +x src/bin/shell/tests/tls_dhcp6_process_tests.sh])
 AC_CONFIG_FILES([src/hooks/Makefile])
 AC_CONFIG_FILES([src/hooks/dhcp/Makefile])
 AC_CONFIG_FILES([src/hooks/dhcp/bootp/Makefile])
index 483de5dea6ec7a130835ef6063f6f836a95a66e6..42a803815d86b568dbcf9dc829200bf4cddb82de 100644 (file)
@@ -1,7 +1,13 @@
 /ca_basic_auth_tests.sh
 /d2_basic_auth_tests.sh
+/dhcp4_basic_auth_tests.sh
+/dhcp6_basic_auth_tests.sh
 /shell_ca_process_tests.sh
 /shell_d2_process_tests.sh
+/shell_dhcp4_process_tests.sh
+/shell_dhcp6_process_tests.sh
 /shell_unittest.py
 /tls_ca_process_tests.sh
 /tls_d2_process_tests.sh
+/tls_dhcp4_process_tests.sh
+/tls_dhcp6_process_tests.sh
index 9b341ee62bf4368658b0df498255f14dca4da4e0..95dfe2661ff5084038dc626650ef42889b208b94 100644 (file)
@@ -10,11 +10,17 @@ PYTESTS = shell_unittest.py
 SHTESTS  =
 SHTESTS += ca_basic_auth_tests.sh
 SHTESTS += d2_basic_auth_tests.sh
+SHTESTS += dhcp4_basic_auth_tests.sh
+SHTESTS += dhcp6_basic_auth_tests.sh
 SHTESTS += shell_ca_process_tests.sh
 SHTESTS += shell_d2_process_tests.sh
+SHTESTS += shell_dhcp4_process_tests.sh
+SHTESTS += shell_dhcp6_process_tests.sh
 if CA_TLS_TEST
 SHTESTS += tls_ca_process_tests.sh
 SHTESTS += tls_d2_process_tests.sh
+SHTESTS += tls_dhcp4_process_tests.sh
+SHTESTS += tls_dhcp6_process_tests.sh
 endif
 
 # As with every file generated by ./configure, clean them up when running
index f25a2cc86243e40978e8c548e4fde9feadb115b8..1ff69608825076c0dfe856f3ec6935a5b518c84c 100644 (file)
@@ -10,6 +10,9 @@
 # used.
 set -eu
 
+# Test suite for CA
+test_suite="ca"
+
 # Path to the temporary configuration file.
 # shellcheck disable=SC2034
 # SC2034: ... appears unused. Verify use (or export if used externally).
@@ -88,7 +91,7 @@ shell_command_test() {
     # Setup phase: start CA.
 
     # Log the start of the test and print test name.
-    test_start "${test_name}"
+    test_start "${test_suite}-${test_name}"
 
     # Create new configuration file.
     create_config "${CONFIG}"
index 5b4687883d9ad57d7a8005313acdc3ca87d44a45..b6e9b84636524b05aaa7b9582fdb67eaabb6ea1a 100644 (file)
@@ -10,6 +10,9 @@
 # used.
 set -eu
 
+# Test suite for D2
+test_suite="d2"
+
 # Path to the temporary configuration file.
 # shellcheck disable=SC2034
 # SC2034: ... appears unused. Verify use (or export if used externally).
@@ -93,7 +96,7 @@ shell_command_test() {
     # Setup phase: start D2.
 
     # Log the start of the test and print test name.
-    test_start "${test_name}"
+    test_start "${test_suite}-${test_name}"
 
     # Create new configuration file.
     create_config "${CONFIG}"
diff --git a/src/bin/shell/tests/dhcp4_basic_auth_tests.sh.in b/src/bin/shell/tests/dhcp4_basic_auth_tests.sh.in
new file mode 100644 (file)
index 0000000..ff5d632
--- /dev/null
@@ -0,0 +1,228 @@
+#!/bin/sh
+
+# Copyright (C) 2020-2024 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
+
+# Test suite for Dhcp4
+test_suite="dhcp4"
+
+# Path to the temporary configuration file.
+# shellcheck disable=SC2034
+# SC2034: ... appears unused. Verify use (or export if used externally).
+# reason: used in dhcp_test_lib.sh.in
+CFG_FILE="@abs_top_builddir@/src/bin/shell/tests/test_config.json"
+
+# Path to the Kea lease file.
+LEASE_FILE="@abs_top_builddir@/src/bin/shell/tests/test_leases.csv"
+
+# Path to the Dhcp4 Server log file.
+LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log"
+
+# Dhcp4 Server configuration to be stored in the configuration file.
+# todo: use actual configuration once we support it.
+CONFIG="{
+    \"Dhcp4\":
+    {
+        \"control-sockets\": [
+        {
+            \"socket-type\": \"http\",
+            \"socket-address\": \"127.0.0.1\",
+            \"socket-port\": 8081,
+            \"authentication\":
+            {
+                \"type\": \"basic\",
+                \"realm\": \"ISC.ORG\",
+                \"clients\": [
+                {
+                    \"user\": \"pet\",
+                    \"password\": \"meow\"
+                }
+                ]
+            }
+        }
+        ],
+        \"interfaces-config\": {
+           \"interfaces\": [ ]
+        },
+        \"valid-lifetime\": 4000,
+        \"renew-timer\": 1000,
+        \"rebind-timer\": 2000,
+        \"lease-database\":
+        {
+            \"type\": \"memfile\",
+            \"name\": \"$LEASE_FILE\",
+            \"persist\": true,
+            \"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\": \"DEBUG\"
+        }
+        ]
+    }
+}"
+
+# In these tests we need to use two binaries: Dhcp4 Server and Kea shell.
+# Using bin and bin_path would be confusing, so we omit defining bin
+# and bin_path on purpose.
+dhcp4_bin="kea-dhcp4"
+dhcp4_bin_path="@abs_top_builddir@/src/bin/dhcp4"
+
+shell_bin="kea-shell"
+shell_bin_path="@abs_top_builddir@/src/bin/shell"
+
+tmpfile_path="@abs_top_builddir@/src/bin/shell/tests"
+
+# Import common test library.
+# shellcheck source=src/lib/testutils/dhcp_test_lib.sh.in
+. "@abs_top_builddir@/src/lib/testutils/dhcp_test_lib.sh"
+
+run_kea_shell() {
+    # shellcheck disable=SC2086
+    # SC2086: Double quote to prevent globbing and word splitting.
+    # reason: ${auth} can be empty here, if we quote, it will be interpreted as
+    # an empty string which is not desired as it will result in unrecognized
+    # argument from kea-shell.
+    echo | "${shell_bin_path}/${shell_bin}" --host 127.0.0.1 --port 8081 \
+        ${auth} "${cmd}" > "${tmpfile_path}/shell-stdout.txt"
+}
+
+# This test verifies that Dhcp4 Server is shut down gracefully when it
+# receives a SIGINT or SIGTERM signal.
+shell_command_test() {
+    test_name=${1}  # Test name
+    auth=${2}       # Authentication
+    cmd=${3}        # Command to be sent
+    exp_result=${4} # Expected result
+    exp_rsp=${5}    # Expected response
+
+    # Setup phase: start Dhcp4.
+
+    # Log the start of the test and print test name.
+    test_start "${test_suite}-${test_name}"
+
+    # Create new configuration file.
+    create_config "${CONFIG}"
+
+    # Instruct Dhcp4 Server to log to the specific file.
+    set_logger
+    # Start Dhcp4 Server.
+    start_kea ${dhcp4_bin_path}/${dhcp4_bin}
+    # Wait up to 20s for Dhcp4 Server to start.
+    wait_for_kea 20
+    if [ "${_WAIT_FOR_KEA}" -eq 0 ]; then
+        printf "ERROR: timeout waiting for Dhcp4 Server 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 ${dhcp4_bin}
+    if [ "${_GET_PIDS_NUM}" -ne 1 ]; then
+        printf "ERROR: expected one Dhcp4 Server 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 been configured %s time(s),\
+ but exactly 1 was expected.\n" "${_GET_RECONFIGS}"
+        clean_exit 1
+    else
+        printf "Server successfully configured.\n"
+    fi
+
+    # Main test phase: send command, check response.
+    tmp="echo | ${shell_bin_path}/${shell_bin} --host \
+ 127.0.0.1 --port 8081 ${auth} ${cmd} > ${tmpfile_path}/shell-stdout.txt"
+    echo "Executing kea-shell ($tmp)"
+
+    run_command \
+        run_kea_shell
+
+    # Check the exit code
+    if [ "${exp_result}" = "fail" ]; then
+        if [ "${EXIT_CODE}" -eq 0 ]; then
+            echo "ERROR:" \
+            "kea-shell returned ${EXIT_CODE} exit code, expected 1."
+        else
+            echo "kea-shell returned ${EXIT_CODE} exit code as expected."
+        fi
+    elif [ "${EXIT_CODE}" -ne 0 ]; then
+        echo "ERROR:" \
+        "kea-shell returned ${EXIT_CODE} exit code, expected 0."
+    else
+        echo "kea-shell returned ${EXIT_CODE} exit code as expected."
+    fi
+
+    # Now check the response
+    rm -f ${tmpfile_path}/shell-expected.txt
+    printf '%s\n' "${exp_rsp}" > ${tmpfile_path}/shell-expected.txt
+    if diff "${tmpfile_path}/shell-stdout.txt" "${tmpfile_path}/shell-expected.txt"; then
+        echo "Content returned by kea-shell meets expectation."
+        rm ${tmpfile_path}/shell-*.txt
+    else
+        echo "ERROR:" \
+        "content returned is different than expected." \
+        "See ${tmpfile_path}/shell-*.txt"
+        echo "EXPECTED:"
+        cat ${tmpfile_path}/shell-expected.txt
+        echo "ACTUAL RESULT:"
+        cat ${tmpfile_path}/shell-stdout.txt
+        clean_exit 1
+    fi
+    # Main test phase ends.
+
+    # Cleanup phase: shutdown Dhcp4
+    # Send SIGTERM signal to Dhcp4 Server
+    send_signal 15 ${dhcp4_bin}
+
+    # Now wait for process to log that it is exiting.
+    wait_for_message 10 "DHCP4_SHUTDOWN" 1
+    if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
+        printf "ERROR: Dhcp4 Server did not log shutdown.\n"
+        clean_exit 1
+    fi
+
+    # Make sure the server is down.
+    wait_for_server_down 5 ${dhcp4_bin}
+    assert_eq 1 "${_WAIT_FOR_SERVER_DOWN}" \
+        "Expected wait_for_server_down return %d, returned %d"
+
+    test_finish 0
+}
+
+shell_command_test "shell.no-auth" "" "list-commands" "fail" \
+    "Failed to run: HTTP Error 401: Unauthorized"
+shell_command_test "shell.bad-auth" \
+    "--auth-user foo --auth-password bar" "list-commands" "fail" \
+    "Failed to run: HTTP Error 401: Unauthorized"
+shell_command_test "shell.authorized" \
+    "--auth-user pet --auth-password meow" "list-commands" "" \
+    "[ { \"arguments\": [ \"build-report\", \"config-backend-pull\", \"config-get\", \"config-hash-get\", \"config-reload\", \"config-set\", \"config-test\", \"config-write\", \"dhcp-disable\", \"dhcp-enable\", \"leases-reclaim\", \"list-commands\", \"server-tag-get\", \"shutdown\", \"statistic-get\", \"statistic-get-all\", \"statistic-remove\", \"statistic-remove-all\", \"statistic-reset\", \"statistic-reset-all\", \"statistic-sample-age-set\", \"statistic-sample-age-set-all\", \"statistic-sample-count-set\", \"statistic-sample-count-set-all\", \"status-get\", \"version-get\" ], \"result\": 0 } ]"
diff --git a/src/bin/shell/tests/dhcp6_basic_auth_tests.sh.in b/src/bin/shell/tests/dhcp6_basic_auth_tests.sh.in
new file mode 100644 (file)
index 0000000..2d16590
--- /dev/null
@@ -0,0 +1,233 @@
+#!/bin/sh
+
+# Copyright (C) 2020-2024 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
+
+# Test suite for Dhcp6
+test_suite="dhcp6"
+
+# Path to the temporary configuration file.
+# shellcheck disable=SC2034
+# SC2034: ... appears unused. Verify use (or export if used externally).
+# reason: used in dhcp_test_lib.sh.in
+CFG_FILE="@abs_top_builddir@/src/bin/shell/tests/test_config.json"
+
+# Path to the Kea lease file.
+LEASE_FILE="@abs_top_builddir@/src/bin/shell/tests/test_leases.csv"
+
+# Path to the Dhcp6 Server log file.
+LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log"
+
+# Dhcp6 Server configuration to be stored in the configuration file.
+# todo: use actual configuration once we support it.
+CONFIG="{
+    \"Dhcp6\":
+    {
+        \"control-sockets\": [
+        {
+            \"socket-type\": \"http\",
+            \"socket-address\": \"127.0.0.1\",
+            \"socket-port\": 8081,
+            \"authentication\":
+            {
+                \"type\": \"basic\",
+                \"realm\": \"ISC.ORG\",
+                \"clients\": [
+                {
+                    \"user\": \"pet\",
+                    \"password\": \"meow\"
+                }
+                ]
+            }
+        }
+        ],
+        \"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\": true,
+            \"lfc-interval\": 0
+        },
+        \"subnet6\": [
+        {
+            \"id\": 1,
+            \"subnet\": \"2001:db8:1::/64\",
+            \"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\": \"DEBUG\"
+        }
+        ]
+    }
+}"
+
+# In these tests we need to use two binaries: Dhcp6 Server and Kea shell.
+# Using bin and bin_path would be confusing, so we omit defining bin
+# and bin_path on purpose.
+dhcp6_bin="kea-dhcp6"
+dhcp6_bin_path="@abs_top_builddir@/src/bin/dhcp6"
+
+shell_bin="kea-shell"
+shell_bin_path="@abs_top_builddir@/src/bin/shell"
+
+tmpfile_path="@abs_top_builddir@/src/bin/shell/tests"
+
+# Import common test library.
+# shellcheck source=src/lib/testutils/dhcp_test_lib.sh.in
+. "@abs_top_builddir@/src/lib/testutils/dhcp_test_lib.sh"
+
+run_kea_shell() {
+    # shellcheck disable=SC2086
+    # SC2086: Double quote to prevent globbing and word splitting.
+    # reason: ${auth} can be empty here, if we quote, it will be interpreted as
+    # an empty string which is not desired as it will result in unrecognized
+    # argument from kea-shell.
+    echo | "${shell_bin_path}/${shell_bin}" --host 127.0.0.1 --port 8081 \
+        ${auth} "${cmd}" > "${tmpfile_path}/shell-stdout.txt"
+}
+
+# This test verifies that Dhcp6 Server is shut down gracefully when it
+# receives a SIGINT or SIGTERM signal.
+shell_command_test() {
+    test_name=${1}  # Test name
+    auth=${2}       # Authentication
+    cmd=${3}        # Command to be sent
+    exp_result=${4} # Expected result
+    exp_rsp=${5}    # Expected response
+
+    # Setup phase: start Dhcp6.
+
+    # Log the start of the test and print test name.
+    test_start "${test_suite}-${test_name}"
+
+    # Create new configuration file.
+    create_config "${CONFIG}"
+
+    # Instruct Dhcp6 Server to log to the specific file.
+    set_logger
+    # Start Dhcp6 Server.
+    start_kea ${dhcp6_bin_path}/${dhcp6_bin}
+    # Wait up to 20s for Dhcp6 Server to start.
+    wait_for_kea 20
+    if [ "${_WAIT_FOR_KEA}" -eq 0 ]; then
+        printf "ERROR: timeout waiting for Dhcp6 Server 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 ${dhcp6_bin}
+    if [ "${_GET_PIDS_NUM}" -ne 1 ]; then
+        printf "ERROR: expected one Dhcp6 Server 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 been configured %s time(s),\
+ but exactly 1 was expected.\n" "${_GET_RECONFIGS}"
+        clean_exit 1
+    else
+        printf "Server successfully configured.\n"
+    fi
+
+    # Main test phase: send command, check response.
+    tmp="echo | ${shell_bin_path}/${shell_bin} --host \
+ 127.0.0.1 --port 8081 ${auth} ${cmd} > ${tmpfile_path}/shell-stdout.txt"
+    echo "Executing kea-shell ($tmp)"
+
+    run_command \
+        run_kea_shell
+
+    # Check the exit code
+    if [ "${exp_result}" = "fail" ]; then
+        if [ "${EXIT_CODE}" -eq 0 ]; then
+            echo "ERROR:" \
+            "kea-shell returned ${EXIT_CODE} exit code, expected 1."
+        else
+            echo "kea-shell returned ${EXIT_CODE} exit code as expected."
+        fi
+    elif [ "${EXIT_CODE}" -ne 0 ]; then
+        echo "ERROR:" \
+        "kea-shell returned ${EXIT_CODE} exit code, expected 0."
+    else
+        echo "kea-shell returned ${EXIT_CODE} exit code as expected."
+    fi
+
+    # Now check the response
+    rm -f ${tmpfile_path}/shell-expected.txt
+    printf '%s\n' "${exp_rsp}" > ${tmpfile_path}/shell-expected.txt
+    if diff "${tmpfile_path}/shell-stdout.txt" "${tmpfile_path}/shell-expected.txt"; then
+        echo "Content returned by kea-shell meets expectation."
+        rm ${tmpfile_path}/shell-*.txt
+    else
+        echo "ERROR:" \
+        "content returned is different than expected." \
+        "See ${tmpfile_path}/shell-*.txt"
+        echo "EXPECTED:"
+        cat ${tmpfile_path}/shell-expected.txt
+        echo "ACTUAL RESULT:"
+        cat ${tmpfile_path}/shell-stdout.txt
+        clean_exit 1
+    fi
+    # Main test phase ends.
+
+    # Cleanup phase: shutdown Dhcp6
+    # Send SIGTERM signal to Dhcp6 Server
+    send_signal 15 ${dhcp6_bin}
+
+    # Now wait for process to log that it is exiting.
+    wait_for_message 10 "DHCP6_SHUTDOWN" 1
+    if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
+        printf "ERROR: Dhcp6 Server did not log shutdown.\n"
+        clean_exit 1
+    fi
+
+    # Make sure the server is down.
+    wait_for_server_down 5 ${dhcp6_bin}
+    assert_eq 1 "${_WAIT_FOR_SERVER_DOWN}" \
+        "Expected wait_for_server_down return %d, returned %d"
+
+    test_finish 0
+}
+
+shell_command_test "shell.no-auth" "" "list-commands" "fail" \
+    "Failed to run: HTTP Error 401: Unauthorized"
+shell_command_test "shell.bad-auth" \
+    "--auth-user foo --auth-password bar" "list-commands" "fail" \
+    "Failed to run: HTTP Error 401: Unauthorized"
+shell_command_test "shell.authorized" \
+    "--auth-user pet --auth-password meow" "list-commands" "" \
+    "[ { \"arguments\": [ \"build-report\", \"config-backend-pull\", \"config-get\", \"config-hash-get\", \"config-reload\", \"config-set\", \"config-test\", \"config-write\", \"dhcp-disable\", \"dhcp-enable\", \"leases-reclaim\", \"list-commands\", \"server-tag-get\", \"shutdown\", \"statistic-get\", \"statistic-get-all\", \"statistic-remove\", \"statistic-remove-all\", \"statistic-reset\", \"statistic-reset-all\", \"statistic-sample-age-set\", \"statistic-sample-age-set-all\", \"statistic-sample-count-set\", \"statistic-sample-count-set-all\", \"status-get\", \"version-get\" ], \"result\": 0 } ]"
index 3ed4071fb1b7f8a86b714fab3fb7ce8d09076885..f141c6685d596d31d6c7e4b0f0537ef435b8a020 100644 (file)
@@ -10,6 +10,9 @@
 # used.
 set -eu
 
+# Test suite for CA
+test_suite="ca"
+
 # Path to the temporary configuration file.
 # shellcheck disable=SC2034
 # SC2034: ... appears unused. Verify use (or export if used externally).
@@ -66,7 +69,7 @@ shell_command_test() {
     # Setup phase: start CA.
 
     # Log the start of the test and print test name.
-    test_start "${test_name}"
+    test_start "${test_suite}-${test_name}"
 
     # Create new configuration file.
     create_config "${CONFIG}"
@@ -163,7 +166,7 @@ version_test() {
     test_name=${1}  # Test name
 
     # Log the start of the test and print test name.
-    test_start "${test_name}"
+    test_start "${test_suite}-${test_name}"
 
     REPORTED_VERSION=$(${shell_bin_path}/${shell_bin} -v)
 
index 03a6f85d83909870786f7ce5ed32f2ac3549db3b..c9a48d960d63214108b433ca42a7ec846d581718 100644 (file)
@@ -10,6 +10,9 @@
 # used.
 set -eu
 
+# Test suite for D2
+test_suite="d2"
+
 # Path to the temporary configuration file.
 # shellcheck disable=SC2034
 # SC2034: ... appears unused. Verify use (or export if used externally).
@@ -68,10 +71,10 @@ shell_command_test() {
     exp_rsp=${3}    # Expected response
     params=${4}     # Any extra parameters
 
-    # Setup phase: start CA.
+    # Setup phase: start D2.
 
     # Log the start of the test and print test name.
-    test_start "${test_name}"
+    test_start "${test_suite}-${test_name}"
 
     # Create new configuration file.
     create_config "${CONFIG}"
@@ -168,7 +171,7 @@ version_test() {
     test_name=${1}  # Test name
 
     # Log the start of the test and print test name.
-    test_start "${test_name}"
+    test_start "${test_suite}-${test_name}"
 
     REPORTED_VERSION=$(${shell_bin_path}/${shell_bin} -v)
 
diff --git a/src/bin/shell/tests/shell_dhcp4_process_tests.sh.in b/src/bin/shell/tests/shell_dhcp4_process_tests.sh.in
new file mode 100644 (file)
index 0000000..6c6be50
--- /dev/null
@@ -0,0 +1,228 @@
+#!/bin/sh
+
+# Copyright (C) 2017-2024 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
+
+# Test suite for Dhcp4
+test_suite="dhcp4"
+
+# Path to the temporary configuration file.
+# shellcheck disable=SC2034
+# SC2034: ... appears unused. Verify use (or export if used externally).
+# reason: used in dhcp_test_lib.sh.in
+CFG_FILE="@abs_top_builddir@/src/bin/shell/tests/test_config.json"
+
+# Path to the Kea lease file.
+LEASE_FILE="@abs_top_builddir@/src/bin/shell/tests/test_leases.csv"
+
+# Path to the Dhcp4 Server log file.
+LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log"
+
+# Dhcp4 Server configuration to be stored in the configuration file.
+# todo: use actual configuration once we support it.
+CONFIG="{
+    \"Dhcp4\":
+    {
+        \"control-sockets\": [
+        {
+            \"socket-type\": \"http\",
+            \"socket-address\": \"127.0.0.1\",
+            \"socket-port\": 8081
+        }
+        ],
+        \"interfaces-config\": {
+           \"interfaces\": [ ]
+        },
+        \"valid-lifetime\": 4000,
+        \"renew-timer\": 1000,
+        \"rebind-timer\": 2000,
+        \"lease-database\":
+        {
+            \"type\": \"memfile\",
+            \"name\": \"$LEASE_FILE\",
+            \"persist\": true,
+            \"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\": \"DEBUG\"
+        }
+        ]
+    }
+}"
+
+# In these tests we need to use two binaries: Dhcp4 Server and Kea shell.
+# Using bin and bin_path would be confusing, so we omit defining bin
+# and bin_path on purpose.
+dhcp4_bin="kea-dhcp4"
+dhcp4_bin_path="@abs_top_builddir@/src/bin/dhcp4"
+
+shell_bin="kea-shell"
+shell_bin_path="@abs_top_builddir@/src/bin/shell"
+
+tmpfile_path="@abs_top_builddir@/src/bin/shell/tests"
+
+# 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 Dhcp4 Server is shut down gracefully when it
+# receives a SIGINT or SIGTERM signal.
+shell_command_test() {
+    test_name=${1}  # Test name
+    cmd=${2}        # Command to be sent
+    exp_rsp=${3}    # Expected response
+    params=${4}     # Any extra parameters
+
+    # Setup phase: start Dhcp4.
+
+    # Log the start of the test and print test name.
+    test_start "${test_suite}-${test_name}"
+
+    # Create new configuration file.
+    create_config "${CONFIG}"
+
+    # Instruct Dhcp4 Server to log to the specific file.
+    set_logger
+    # Start Dhcp4 Server.
+    start_kea ${dhcp4_bin_path}/${dhcp4_bin}
+    # Wait up to 20s for Dhcp4 Server to start.
+    wait_for_kea 20
+    if [ "${_WAIT_FOR_KEA}" -eq 0 ]; then
+        printf "ERROR: timeout waiting for Dhcp4 Server 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 "${dhcp4_bin}"
+    if [ "${_GET_PIDS_NUM}" -ne 1 ]; then
+        printf "ERROR: expected one Dhcp4 Server 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 been configured %s time(s),\
+ but exactly 1 was expected.\n" "${_GET_RECONFIGS}"
+        clean_exit 1
+    else
+        printf "Server successfully configured.\n"
+    fi
+
+    # Main test phase: send command, check response.
+    tmp="echo \"${params}\" | ${shell_bin_path}/${shell_bin} --host \
+ 127.0.0.1 --port 8081 ${cmd} > ${tmpfile_path}/shell-stdout.txt"
+    echo "Executing kea-shell ($tmp)"
+
+    echo "${params}" | ${shell_bin_path}/${shell_bin} --host 127.0.0.1 \
+ --port 8081 "${cmd}" > ${tmpfile_path}/shell-stdout.txt
+    shell_exit_code=$?
+
+    # Check the exit code
+    if [ "${shell_exit_code}" -ne 0 ]; then
+        echo "ERROR:" \
+        "kea-shell returned ${shell_exit_code} exit code, expected 0."
+    else
+        echo "kea-shell returned ${shell_exit_code} exit code as expected."
+    fi
+
+    # Now check the response
+    rm -f ${tmpfile_path}/shell-expected.txt
+    printf '%s\n' "${exp_rsp}" > ${tmpfile_path}/shell-expected.txt
+    diff ${tmpfile_path}/shell-stdout.txt ${tmpfile_path}/shell-expected.txt
+    diff_code=$?
+    if [ "${diff_code}" -ne 0 ]; then
+        echo "ERROR:" \
+        "content returned is different than expected." \
+        "See ${tmpfile_path}/shell-*.txt"
+        echo "EXPECTED:"
+        cat ${tmpfile_path}/shell-expected.txt
+        echo "ACTUAL RESULT:"
+        cat ${tmpfile_path}/shell-stdout.txt
+        clean_exit 1
+    else
+        echo "Content returned by kea-shell meets expectation."
+        rm ${tmpfile_path}/shell-*.txt
+    fi
+    # Main test phase ends.
+
+    # Cleanup phase: shutdown Dhcp4
+    # Send SIGTERM signal to Dhcp4 Server
+    send_signal 15 ${dhcp4_bin}
+
+    # Now wait for process to log that it is exiting.
+    wait_for_message 10 "DHCP4_SHUTDOWN" 1
+    if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
+        printf "ERROR: Dhcp4 Server did not log shutdown.\n"
+        clean_exit 1
+    fi
+
+    # Make sure the server is down.
+    wait_for_server_down 5 ${dhcp4_bin}
+    assert_eq 1 "${_WAIT_FOR_SERVER_DOWN}" \
+        "Expected wait_for_server_down return %d, returned %d"
+
+    test_finish 0
+}
+
+# This test verifies that the binary is reporting its version properly.
+version_test() {
+    test_name=${1}  # Test name
+
+    # Log the start of the test and print test name.
+    test_start "${test_suite}-${test_name}"
+
+    REPORTED_VERSION=$(${shell_bin_path}/${shell_bin} -v)
+
+    if test "${REPORTED_VERSION}" = "${EXPECTED_VERSION}"; then
+        test_finish 0
+    else
+        echo "ERROR:" \
+        "Expected version ${EXPECTED_VERSION}, got ${REPORTED_VERSION}"
+        test_finish 1
+    fi
+}
+
+version_test "shell.version"
+shell_command_test "shell.list-commands" "list-commands" \
+    "[ { \"arguments\": [ \"build-report\", \"config-backend-pull\", \"config-get\", \"config-hash-get\", \"config-reload\", \"config-set\", \"config-test\", \"config-write\", \"dhcp-disable\", \"dhcp-enable\", \"leases-reclaim\", \"list-commands\", \"server-tag-get\", \"shutdown\", \"statistic-get\", \"statistic-get-all\", \"statistic-remove\", \"statistic-remove-all\", \"statistic-reset\", \"statistic-reset-all\", \"statistic-sample-age-set\", \"statistic-sample-age-set-all\", \"statistic-sample-count-set\", \"statistic-sample-count-set-all\", \"status-get\", \"version-get\" ], \"result\": 0 } ]" ""
+shell_command_test "shell.bogus" "give-me-a-beer" \
+"[ { \"result\": 2, \"text\": \"'give-me-a-beer' command not supported.\" } ]" ""
+shell_command_test "shell.empty-config-test" "config-test" \
+    "[ { \"result\": 1, \"text\": \"Missing mandatory 'arguments' parameter.\" } ]" ""
+shell_command_test "shell.no-app-config-test" "config-test" \
+    "[ { \"result\": 1, \"text\": \"Missing mandatory 'Dhcp4' parameter.\" } ]" \
+    "\"FooBar\": { }"
+shell_command_test "shell.no-map-config-test" "config-test" \
+    "[ { \"result\": 1, \"text\": \"'Dhcp4' parameter expected to be a map.\" } ]" \
+    "\"Dhcp4\": [ ]"
+shell_command_test "shell.bad-value-config-test" "config-test" \
+    "[ { \"result\": 1, \"text\": \"out of range value 80000 specified for parameter 'socket-port' (<string>:1:116)\" } ]" \
+    "\"Dhcp4\": { \"control-sockets\": [ { \"socket-type\": \"http\", \"socket-port\": 80000 } ] }"
diff --git a/src/bin/shell/tests/shell_dhcp6_process_tests.sh.in b/src/bin/shell/tests/shell_dhcp6_process_tests.sh.in
new file mode 100644 (file)
index 0000000..0913729
--- /dev/null
@@ -0,0 +1,233 @@
+#!/bin/sh
+
+# Copyright (C) 2017-2024 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
+
+# Test suite for Dhcp6
+test_suite="dhcp6"
+
+# Path to the temporary configuration file.
+# shellcheck disable=SC2034
+# SC2034: ... appears unused. Verify use (or export if used externally).
+# reason: used in dhcp_test_lib.sh.in
+CFG_FILE="@abs_top_builddir@/src/bin/shell/tests/test_config.json"
+
+# Path to the Kea lease file.
+LEASE_FILE="@abs_top_builddir@/src/bin/shell/tests/test_leases.csv"
+
+# Path to the Dhcp6 Server log file.
+LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log"
+
+# Dhcp6 Server configuration to be stored in the configuration file.
+# todo: use actual configuration once we support it.
+CONFIG="{
+    \"Dhcp6\":
+    {
+        \"control-sockets\": [
+        {
+            \"socket-type\": \"http\",
+            \"socket-address\": \"127.0.0.1\",
+            \"socket-port\": 8081
+        }
+        ],
+        \"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\": true,
+            \"lfc-interval\": 0
+        },
+        \"subnet6\": [
+        {
+            \"id\": 1,
+            \"subnet\": \"2001:db8:1::/64\",
+            \"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\": \"DEBUG\"
+        }
+        ]
+    }
+}"
+
+# In these tests we need to use two binaries: Dhcp6 Server and Kea shell.
+# Using bin and bin_path would be confusing, so we omit defining bin
+# and bin_path on purpose.
+dhcp6_bin="kea-dhcp6"
+dhcp6_bin_path="@abs_top_builddir@/src/bin/dhcp6"
+
+shell_bin="kea-shell"
+shell_bin_path="@abs_top_builddir@/src/bin/shell"
+
+tmpfile_path="@abs_top_builddir@/src/bin/shell/tests"
+
+# 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 Dhcp6 Server is shut down gracefully when it
+# receives a SIGINT or SIGTERM signal.
+shell_command_test() {
+    test_name=${1}  # Test name
+    cmd=${2}        # Command to be sent
+    exp_rsp=${3}    # Expected response
+    params=${4}     # Any extra parameters
+
+    # Setup phase: start Dhcp6.
+
+    # Log the start of the test and print test name.
+    test_start "${test_suite}-${test_name}"
+
+    # Create new configuration file.
+    create_config "${CONFIG}"
+
+    # Instruct Dhcp6 Server to log to the specific file.
+    set_logger
+    # Start Dhcp6 Server.
+    start_kea ${dhcp6_bin_path}/${dhcp6_bin}
+    # Wait up to 20s for Dhcp6 Server to start.
+    wait_for_kea 20
+    if [ "${_WAIT_FOR_KEA}" -eq 0 ]; then
+        printf "ERROR: timeout waiting for Dhcp6 Server 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 "${dhcp6_bin}"
+    if [ "${_GET_PIDS_NUM}" -ne 1 ]; then
+        printf "ERROR: expected one Dhcp6 Server 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 been configured %s time(s),\
+ but exactly 1 was expected.\n" "${_GET_RECONFIGS}"
+        clean_exit 1
+    else
+        printf "Server successfully configured.\n"
+    fi
+
+    # Main test phase: send command, check response.
+    tmp="echo \"${params}\" | ${shell_bin_path}/${shell_bin} --host \
+ 127.0.0.1 --port 8081 ${cmd} > ${tmpfile_path}/shell-stdout.txt"
+    echo "Executing kea-shell ($tmp)"
+
+    echo "${params}" | ${shell_bin_path}/${shell_bin} --host 127.0.0.1 \
+ --port 8081 "${cmd}" > ${tmpfile_path}/shell-stdout.txt
+    shell_exit_code=$?
+
+    # Check the exit code
+    if [ "${shell_exit_code}" -ne 0 ]; then
+        echo "ERROR:" \
+        "kea-shell returned ${shell_exit_code} exit code, expected 0."
+    else
+        echo "kea-shell returned ${shell_exit_code} exit code as expected."
+    fi
+
+    # Now check the response
+    rm -f ${tmpfile_path}/shell-expected.txt
+    printf '%s\n' "${exp_rsp}" > ${tmpfile_path}/shell-expected.txt
+    diff ${tmpfile_path}/shell-stdout.txt ${tmpfile_path}/shell-expected.txt
+    diff_code=$?
+    if [ "${diff_code}" -ne 0 ]; then
+        echo "ERROR:" \
+        "content returned is different than expected." \
+        "See ${tmpfile_path}/shell-*.txt"
+        echo "EXPECTED:"
+        cat ${tmpfile_path}/shell-expected.txt
+        echo "ACTUAL RESULT:"
+        cat ${tmpfile_path}/shell-stdout.txt
+        clean_exit 1
+    else
+        echo "Content returned by kea-shell meets expectation."
+        rm ${tmpfile_path}/shell-*.txt
+    fi
+    # Main test phase ends.
+
+    # Cleanup phase: shutdown Dhcp6
+    # Send SIGTERM signal to Dhcp6 Server
+    send_signal 15 ${dhcp6_bin}
+
+    # Now wait for process to log that it is exiting.
+    wait_for_message 10 "DHCP6_SHUTDOWN" 1
+    if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
+        printf "ERROR: Dhcp6 Server did not log shutdown.\n"
+        clean_exit 1
+    fi
+
+    # Make sure the server is down.
+    wait_for_server_down 5 ${dhcp6_bin}
+    assert_eq 1 "${_WAIT_FOR_SERVER_DOWN}" \
+        "Expected wait_for_server_down return %d, returned %d"
+
+    test_finish 0
+}
+
+# This test verifies that the binary is reporting its version properly.
+version_test() {
+    test_name=${1}  # Test name
+
+    # Log the start of the test and print test name.
+    test_start "${test_suite}-${test_name}"
+
+    REPORTED_VERSION=$(${shell_bin_path}/${shell_bin} -v)
+
+    if test "${REPORTED_VERSION}" = "${EXPECTED_VERSION}"; then
+        test_finish 0
+    else
+        echo "ERROR:" \
+        "Expected version ${EXPECTED_VERSION}, got ${REPORTED_VERSION}"
+        test_finish 1
+    fi
+}
+
+version_test "shell.version"
+shell_command_test "shell.list-commands" "list-commands" \
+    "[ { \"arguments\": [ \"build-report\", \"config-backend-pull\", \"config-get\", \"config-hash-get\", \"config-reload\", \"config-set\", \"config-test\", \"config-write\", \"dhcp-disable\", \"dhcp-enable\", \"leases-reclaim\", \"list-commands\", \"server-tag-get\", \"shutdown\", \"statistic-get\", \"statistic-get-all\", \"statistic-remove\", \"statistic-remove-all\", \"statistic-reset\", \"statistic-reset-all\", \"statistic-sample-age-set\", \"statistic-sample-age-set-all\", \"statistic-sample-count-set\", \"statistic-sample-count-set-all\", \"status-get\", \"version-get\" ], \"result\": 0 } ]" ""
+shell_command_test "shell.bogus" "give-me-a-beer" \
+"[ { \"result\": 2, \"text\": \"'give-me-a-beer' command not supported.\" } ]" ""
+shell_command_test "shell.empty-config-test" "config-test" \
+    "[ { \"result\": 1, \"text\": \"Missing mandatory 'arguments' parameter.\" } ]" ""
+shell_command_test "shell.no-app-config-test" "config-test" \
+    "[ { \"result\": 1, \"text\": \"Missing mandatory 'Dhcp6' parameter.\" } ]" \
+    "\"FooBar\": { }"
+shell_command_test "shell.no-map-config-test" "config-test" \
+    "[ { \"result\": 1, \"text\": \"'Dhcp6' parameter expected to be a map.\" } ]" \
+    "\"Dhcp6\": [ ]"
+shell_command_test "shell.bad-value-config-test" "config-test" \
+    "[ { \"result\": 1, \"text\": \"out of range value 80000 specified for parameter 'socket-port' (<string>:1:116)\" } ]" \
+    "\"Dhcp6\": { \"control-sockets\": [ { \"socket-type\": \"http\", \"socket-port\": 80000 } ] }"
index 9ccb9fea85d5e3deead2306406da30ca4ad6b739..0414b859d1163b6b6f5ccfa74481d8d77b7e7924 100644 (file)
@@ -10,6 +10,9 @@
 # used.
 set -eu
 
+# Test suite for CA
+test_suite="ca"
+
 # Include common test library.
 # shellcheck source=src/lib/testutils/dhcp_test_lib.sh.in
 . "@abs_top_builddir@/src/lib/testutils/dhcp_test_lib.sh"
@@ -111,7 +114,7 @@ list_commands_test() {
     # Setup phase: start CA.
 
     # Log the start of the test and print test name.
-    test_start "${test_name}"
+    test_start "${test_suite}-${test_name}"
 
     # Create correct configuration file.
     create_config "${config}"
index 2ea8aba0f3e544e03f73218bee91cf957d5572f7..8d629e3b8349dcbc3ae4147cef36a836ed7855ca 100644 (file)
@@ -10,6 +10,9 @@
 # used.
 set -eu
 
+# Test suite for D2
+test_suite="d2"
+
 # Include common test library.
 # shellcheck source=src/lib/testutils/dhcp_test_lib.sh.in
 . "@abs_top_builddir@/src/lib/testutils/dhcp_test_lib.sh"
@@ -126,7 +129,7 @@ list_commands_test() {
     # Setup phase: start D2.
 
     # Log the start of the test and print test name.
-    test_start "${test_name}"
+    test_start "${test_suite}-${test_name}"
 
     # Create correct configuration file.
     create_config "${config}"
diff --git a/src/bin/shell/tests/tls_dhcp4_process_tests.sh.in b/src/bin/shell/tests/tls_dhcp4_process_tests.sh.in
new file mode 100644 (file)
index 0000000..beb31fa
--- /dev/null
@@ -0,0 +1,311 @@
+#!/bin/sh
+
+# Copyright (C) 2016-2024 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
+
+# Test suite for Dhcp4
+test_suite="dhcp4"
+
+# Include common test library.
+# shellcheck source=src/lib/testutils/dhcp_test_lib.sh.in
+. "@abs_top_builddir@/src/lib/testutils/dhcp_test_lib.sh"
+
+# Path to the temporary configuration file.
+CFG_FILE="@abs_top_builddir@/src/bin/shell/tests/test_config.json"
+
+# Path to the Kea lease file.
+LEASE_FILE="@abs_top_builddir@/src/bin/shell/tests/test_leases.csv"
+
+# Path to the Dhcp4 Server log file.
+LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log"
+
+# Path to the test certificate authority directory.
+TEST_CA_DIR="@abs_top_srcdir@/src/lib/asiolink/testutils/ca"
+
+# Configuration without TLS.
+CONFIG_NONE="{
+    \"Dhcp4\":
+    {
+        \"control-sockets\": [
+        {
+            \"socket-type\": \"http\",
+            \"socket-address\": \"127.0.0.1\",
+            \"socket-port\": 8443
+        }
+        ],
+        \"interfaces-config\": {
+           \"interfaces\": [ ]
+        },
+        \"valid-lifetime\": 4000,
+        \"renew-timer\": 1000,
+        \"rebind-timer\": 2000,
+        \"lease-database\":
+        {
+            \"type\": \"memfile\",
+            \"name\": \"$LEASE_FILE\",
+            \"persist\": true,
+            \"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\": \"DEBUG\"
+        }
+        ]
+    }
+}"
+
+# Configuration without mutual authentication i.e. only channel protection.
+CONFIG_NOCR="{
+    \"Dhcp4\":
+    {
+        \"control-sockets\": [
+        {
+            \"socket-type\": \"http\",
+            \"socket-address\": \"127.0.0.1\",
+            \"socket-port\": 8443,
+            \"trust-anchor\": \"${TEST_CA_DIR}/kea-ca.crt\",
+            \"cert-file\": \"${TEST_CA_DIR}/kea-server-addr.crt\",
+            \"key-file\": \"${TEST_CA_DIR}/kea-server.key\",
+            \"cert-required\": false
+        }
+        ],
+        \"interfaces-config\": {
+           \"interfaces\": [ ]
+        },
+        \"valid-lifetime\": 4000,
+        \"renew-timer\": 1000,
+        \"rebind-timer\": 2000,
+        \"lease-database\":
+        {
+            \"type\": \"memfile\",
+            \"name\": \"$LEASE_FILE\",
+            \"persist\": true,
+            \"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\": \"DEBUG\"
+        }
+        ]
+    }
+}"
+
+# Configuration with mutual authentication.
+CONFIG="{
+    \"Dhcp4\":
+    {
+        \"control-sockets\": [
+        {
+            \"socket-type\": \"http\",
+            \"socket-address\": \"127.0.0.1\",
+            \"socket-port\": 8443,
+            \"trust-anchor\": \"${TEST_CA_DIR}/kea-ca.crt\",
+            \"cert-file\": \"${TEST_CA_DIR}/kea-server-addr.crt\",
+            \"key-file\": \"${TEST_CA_DIR}/kea-server.key\",
+            \"cert-required\": true
+        }
+        ],
+        \"interfaces-config\": {
+           \"interfaces\": [ ]
+        },
+        \"valid-lifetime\": 4000,
+        \"renew-timer\": 1000,
+        \"rebind-timer\": 2000,
+        \"lease-database\":
+        {
+            \"type\": \"memfile\",
+            \"name\": \"$LEASE_FILE\",
+            \"persist\": true,
+            \"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\": \"DEBUG\"
+        }
+        ]
+    }
+}"
+
+# In these tests we need to use two binaries: Dhcp4 Server and Kea shell.
+# Using bin and bin_path would be confusing, so we omit defining bin
+# and bin_path on purpose.
+dhcp4_bin="kea-dhcp4"
+dhcp4_bin_path="@abs_top_builddir@/src/bin/dhcp4"
+
+shell_bin="kea-shell"
+shell_bin_path="@abs_top_builddir@/src/bin/shell"
+
+tmpfile_path="@abs_top_builddir@/src/bin/shell/tests"
+
+list_commands_test() {
+    local test_name="${1}"
+    local config="${2}"
+    local arguments="${3}"
+    local expected_response="${4}"
+
+    # Setup phase: start Dhcp4.
+
+    # Log the start of the test and print test name.
+    test_start "${test_suite}-${test_name}"
+
+    # Create correct configuration file.
+    create_config "${config}"
+
+    # Instruct Dhcp4 Server to log to the specific file.
+    set_logger
+
+    # Start Dhcp4 Server
+    start_kea ${dhcp4_bin_path}/${dhcp4_bin}
+
+    # Wait up to 20s for Dhcp4 Server to start.
+    wait_for_kea 20
+    if [ "${_WAIT_FOR_KEA}" -eq 0 ]; then
+        printf "ERROR: timeout waiting for Dhcp4 Server 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 ${dhcp4_bin}
+    if [ "${_GET_PIDS_NUM}" -ne 1 ]; then
+        printf "ERROR: expected one Dhcp4 Server 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 been configured %s time(s), but exactly 1 was expected.\n' "${_GET_RECONFIGS}"
+        clean_exit 1
+    else
+        printf "Server successfully configured.\n"
+    fi
+
+    # Main test phase: send command, check response.
+
+    # shellcheck disable=SC2086
+    # SC2086: Double quote to prevent globbing and word splitting.
+    # Reason: we specifically want ${arguments} to split because there may be multiple words in it.
+    tmp="echo | ${shell_bin_path}/${shell_bin} --port 8443 \
+    ${arguments} > ${tmpfile_path}/shell-stdout.txt"
+    echo "Executing kea-shell ($tmp)"
+
+    # shellcheck disable=SC2086
+    # SC2086: Double quote to prevent globbing and word splitting.
+    # Reason: we specifically want ${arguments} to split because there may be multiple words in it.
+    echo | ${shell_bin_path}/${shell_bin} --port 8443 \
+    ${arguments} > ${tmpfile_path}/shell-stdout.txt
+    EXIT_CODE=$?
+
+    # Check the exit code
+    if [ "${EXIT_CODE}" -ne 0 ]; then
+        echo "ERROR: kea-shell returned ${EXIT_CODE} exit code, expected 0."
+    else
+        echo "kea-shell returned ${EXIT_CODE} exit code as expected."
+    fi
+
+    # Now check the response
+    rm -f ${tmpfile_path}/shell-expected.txt
+    printf '%s\n' "${expected_response}" > ${tmpfile_path}/shell-expected.txt
+    diff ${tmpfile_path}/shell-stdout.txt ${tmpfile_path}/shell-expected.txt
+    diff_code=$?
+    if [ "${diff_code}" -ne 0 ]; then
+        echo "ERROR:" \
+        "content returned is different than expected." \
+        "See ${tmpfile_path}/shell-*.txt"
+        echo "EXPECTED:"
+        cat ${tmpfile_path}/shell-expected.txt
+        echo "ACTUAL RESULT:"
+        cat ${tmpfile_path}/shell-stdout.txt
+        clean_exit 1
+    else
+        echo "Content returned by kea-shell meets expectation."
+        rm ${tmpfile_path}/shell-*.txt
+    fi
+    # Main test phase ends.
+
+    # Cleanup phase: shutdown Dhcp4 Server
+
+    # Send SIGTERM signal to Dhcp4 Server
+    send_signal 15 ${dhcp4_bin}
+
+    # Now wait for process to log that it is exiting.
+    wait_for_message 10 "DHCP4_SHUTDOWN" 1
+    if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
+        printf "ERROR: Dhcp4 Server did not log shutdown.\n"
+        clean_exit 1
+    fi
+
+    # Make sure the server is down.
+    wait_for_server_down 5 ${dhcp4_bin}
+    assert_eq 1 "${_WAIT_FOR_SERVER_DOWN}" \
+        "Expected wait_for_server_down return %d, returned %d"
+
+    test_finish 0
+}
+
+list_commands_test "NoTLS" "${CONFIG_NONE}" "" \
+"[ { \"arguments\": [ \"build-report\", \"config-backend-pull\", \"config-get\", \"config-hash-get\", \"config-reload\", \"config-set\", \"config-test\", \"config-write\", \"dhcp-disable\", \"dhcp-enable\", \"leases-reclaim\", \"list-commands\", \"server-tag-get\", \"shutdown\", \"statistic-get\", \"statistic-get-all\", \"statistic-remove\", \"statistic-remove-all\", \"statistic-reset\", \"statistic-reset-all\", \"statistic-sample-age-set\", \"statistic-sample-age-set-all\", \"statistic-sample-count-set\", \"statistic-sample-count-set-all\", \"status-get\", \"version-get\" ], \"result\": 0 } ]"
+list_commands_test "Encrypted" "${CONFIG_NOCR}" \
+"--ca ${TEST_CA_DIR}/kea-ca.crt" \
+"[ { \"arguments\": [ \"build-report\", \"config-backend-pull\", \"config-get\", \"config-hash-get\", \"config-reload\", \"config-set\", \"config-test\", \"config-write\", \"dhcp-disable\", \"dhcp-enable\", \"leases-reclaim\", \"list-commands\", \"server-tag-get\", \"shutdown\", \"statistic-get\", \"statistic-get-all\", \"statistic-remove\", \"statistic-remove-all\", \"statistic-reset\", \"statistic-reset-all\", \"statistic-sample-age-set\", \"statistic-sample-age-set-all\", \"statistic-sample-count-set\", \"statistic-sample-count-set-all\", \"status-get\", \"version-get\" ], \"result\": 0 } ]"
+list_commands_test "Authenticated" "${CONFIG}" \
+"--ca ${TEST_CA_DIR}/kea-ca.crt --cert ${TEST_CA_DIR}/kea-client.crt --key ${TEST_CA_DIR}/kea-client.key" \
+"[ { \"arguments\": [ \"build-report\", \"config-backend-pull\", \"config-get\", \"config-hash-get\", \"config-reload\", \"config-set\", \"config-test\", \"config-write\", \"dhcp-disable\", \"dhcp-enable\", \"leases-reclaim\", \"list-commands\", \"server-tag-get\", \"shutdown\", \"statistic-get\", \"statistic-get-all\", \"statistic-remove\", \"statistic-remove-all\", \"statistic-reset\", \"statistic-reset-all\", \"statistic-sample-age-set\", \"statistic-sample-age-set-all\", \"statistic-sample-count-set\", \"statistic-sample-count-set-all\", \"status-get\", \"version-get\" ], \"result\": 0 } ]"
diff --git a/src/bin/shell/tests/tls_dhcp6_process_tests.sh.in b/src/bin/shell/tests/tls_dhcp6_process_tests.sh.in
new file mode 100644 (file)
index 0000000..2f9dd25
--- /dev/null
@@ -0,0 +1,326 @@
+#!/bin/sh
+
+# Copyright (C) 2016-2024 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
+
+# Test suite for Dhcp6
+test_suite="dhcp6"
+
+# Include common test library.
+# shellcheck source=src/lib/testutils/dhcp_test_lib.sh.in
+. "@abs_top_builddir@/src/lib/testutils/dhcp_test_lib.sh"
+
+# Path to the temporary configuration file.
+CFG_FILE="@abs_top_builddir@/src/bin/shell/tests/test_config.json"
+
+# Path to the Kea lease file.
+LEASE_FILE="@abs_top_builddir@/src/bin/shell/tests/test_leases.csv"
+
+# Path to the Dhcp6 Server log file.
+LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log"
+
+# Path to the test certificate authority directory.
+TEST_CA_DIR="@abs_top_srcdir@/src/lib/asiolink/testutils/ca"
+
+# Configuration without TLS.
+CONFIG_NONE="{
+    \"Dhcp6\":
+    {
+        \"control-sockets\": [
+        {
+            \"socket-type\": \"http\",
+            \"socket-address\": \"127.0.0.1\",
+            \"socket-port\": 8443
+        }
+        ],
+        \"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\": true,
+            \"lfc-interval\": 0
+        },
+        \"subnet6\": [
+        {
+            \"id\": 1,
+            \"subnet\": \"2001:db8:1::/64\",
+            \"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\": \"DEBUG\"
+        }
+        ]
+    }
+}"
+
+# Configuration without mutual authentication i.e. only channel protection.
+CONFIG_NOCR="{
+    \"Dhcp6\":
+    {
+        \"control-sockets\": [
+        {
+            \"socket-type\": \"http\",
+            \"socket-address\": \"127.0.0.1\",
+            \"socket-port\": 8443,
+            \"trust-anchor\": \"${TEST_CA_DIR}/kea-ca.crt\",
+            \"cert-file\": \"${TEST_CA_DIR}/kea-server-addr.crt\",
+            \"key-file\": \"${TEST_CA_DIR}/kea-server.key\",
+            \"cert-required\": false
+        }
+        ],
+        \"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\": true,
+            \"lfc-interval\": 0
+        },
+        \"subnet6\": [
+        {
+            \"id\": 1,
+            \"subnet\": \"2001:db8:1::/64\",
+            \"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\": \"DEBUG\"
+        }
+        ]
+    }
+}"
+
+# Configuration with mutual authentication.
+CONFIG="{
+    \"Dhcp6\":
+    {
+        \"control-sockets\": [
+        {
+            \"socket-type\": \"http\",
+            \"socket-address\": \"127.0.0.1\",
+            \"socket-port\": 8443,
+            \"trust-anchor\": \"${TEST_CA_DIR}/kea-ca.crt\",
+            \"cert-file\": \"${TEST_CA_DIR}/kea-server-addr.crt\",
+            \"key-file\": \"${TEST_CA_DIR}/kea-server.key\",
+            \"cert-required\": true
+        }
+        ],
+        \"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\": true,
+            \"lfc-interval\": 0
+        },
+        \"subnet6\": [
+        {
+            \"id\": 1,
+            \"subnet\": \"2001:db8:1::/64\",
+            \"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\": \"DEBUG\"
+        }
+        ]
+    }
+}"
+
+# In these tests we need to use two binaries: Dhcp6 Server and Kea shell.
+# Using bin and bin_path would be confusing, so we omit defining bin
+# and bin_path on purpose.
+dhcp6_bin="kea-dhcp6"
+dhcp6_bin_path="@abs_top_builddir@/src/bin/dhcp6"
+
+shell_bin="kea-shell"
+shell_bin_path="@abs_top_builddir@/src/bin/shell"
+
+tmpfile_path="@abs_top_builddir@/src/bin/shell/tests"
+
+list_commands_test() {
+    local test_name="${1}"
+    local config="${2}"
+    local arguments="${3}"
+    local expected_response="${4}"
+
+    # Setup phase: start Dhcp6.
+
+    # Log the start of the test and print test name.
+    test_start "${test_suite}-${test_name}"
+
+    # Create correct configuration file.
+    create_config "${config}"
+
+    # Instruct Dhcp6 Server to log to the specific file.
+    set_logger
+
+    # Start Dhcp6 Server
+    start_kea ${dhcp6_bin_path}/${dhcp6_bin}
+
+    # Wait up to 20s for Dhcp6 Server to start.
+    wait_for_kea 20
+    if [ "${_WAIT_FOR_KEA}" -eq 0 ]; then
+        printf "ERROR: timeout waiting for Dhcp6 Server 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 ${dhcp6_bin}
+    if [ "${_GET_PIDS_NUM}" -ne 1 ]; then
+        printf "ERROR: expected one Dhcp6 Server 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 been configured %s time(s), but exactly 1 was expected.\n' "${_GET_RECONFIGS}"
+        clean_exit 1
+    else
+        printf "Server successfully configured.\n"
+    fi
+
+    # Main test phase: send command, check response.
+
+    # shellcheck disable=SC2086
+    # SC2086: Double quote to prevent globbing and word splitting.
+    # Reason: we specifically want ${arguments} to split because there may be multiple words in it.
+    tmp="echo | ${shell_bin_path}/${shell_bin} --port 8443 \
+    ${arguments} > ${tmpfile_path}/shell-stdout.txt"
+    echo "Executing kea-shell ($tmp)"
+
+    # shellcheck disable=SC2086
+    # SC2086: Double quote to prevent globbing and word splitting.
+    # Reason: we specifically want ${arguments} to split because there may be multiple words in it.
+    echo | ${shell_bin_path}/${shell_bin} --port 8443 \
+    ${arguments} > ${tmpfile_path}/shell-stdout.txt
+    EXIT_CODE=$?
+
+    # Check the exit code
+    if [ "${EXIT_CODE}" -ne 0 ]; then
+        echo "ERROR: kea-shell returned ${EXIT_CODE} exit code, expected 0."
+    else
+        echo "kea-shell returned ${EXIT_CODE} exit code as expected."
+    fi
+
+    # Now check the response
+    rm -f ${tmpfile_path}/shell-expected.txt
+    printf '%s\n' "${expected_response}" > ${tmpfile_path}/shell-expected.txt
+    diff ${tmpfile_path}/shell-stdout.txt ${tmpfile_path}/shell-expected.txt
+    diff_code=$?
+    if [ "${diff_code}" -ne 0 ]; then
+        echo "ERROR:" \
+        "content returned is different than expected." \
+        "See ${tmpfile_path}/shell-*.txt"
+        echo "EXPECTED:"
+        cat ${tmpfile_path}/shell-expected.txt
+        echo "ACTUAL RESULT:"
+        cat ${tmpfile_path}/shell-stdout.txt
+        clean_exit 1
+    else
+        echo "Content returned by kea-shell meets expectation."
+        rm ${tmpfile_path}/shell-*.txt
+    fi
+    # Main test phase ends.
+
+    # Cleanup phase: shutdown Dhcp6 Server
+
+    # Send SIGTERM signal to Dhcp6 Server
+    send_signal 15 ${dhcp6_bin}
+
+    # Now wait for process to log that it is exiting.
+    wait_for_message 10 "DHCP6_SHUTDOWN" 1
+    if [ "${_WAIT_FOR_MESSAGE}" -eq 0 ]; then
+        printf "ERROR: Dhcp6 Server did not log shutdown.\n"
+        clean_exit 1
+    fi
+
+    # Make sure the server is down.
+    wait_for_server_down 5 ${dhcp6_bin}
+    assert_eq 1 "${_WAIT_FOR_SERVER_DOWN}" \
+        "Expected wait_for_server_down return %d, returned %d"
+
+    test_finish 0
+}
+
+list_commands_test "NoTLS" "${CONFIG_NONE}" "" \
+"[ { \"arguments\": [ \"build-report\", \"config-backend-pull\", \"config-get\", \"config-hash-get\", \"config-reload\", \"config-set\", \"config-test\", \"config-write\", \"dhcp-disable\", \"dhcp-enable\", \"leases-reclaim\", \"list-commands\", \"server-tag-get\", \"shutdown\", \"statistic-get\", \"statistic-get-all\", \"statistic-remove\", \"statistic-remove-all\", \"statistic-reset\", \"statistic-reset-all\", \"statistic-sample-age-set\", \"statistic-sample-age-set-all\", \"statistic-sample-count-set\", \"statistic-sample-count-set-all\", \"status-get\", \"version-get\" ], \"result\": 0 } ]"
+list_commands_test "Encrypted" "${CONFIG_NOCR}" \
+"--ca ${TEST_CA_DIR}/kea-ca.crt" \
+"[ { \"arguments\": [ \"build-report\", \"config-backend-pull\", \"config-get\", \"config-hash-get\", \"config-reload\", \"config-set\", \"config-test\", \"config-write\", \"dhcp-disable\", \"dhcp-enable\", \"leases-reclaim\", \"list-commands\", \"server-tag-get\", \"shutdown\", \"statistic-get\", \"statistic-get-all\", \"statistic-remove\", \"statistic-remove-all\", \"statistic-reset\", \"statistic-reset-all\", \"statistic-sample-age-set\", \"statistic-sample-age-set-all\", \"statistic-sample-count-set\", \"statistic-sample-count-set-all\", \"status-get\", \"version-get\" ], \"result\": 0 } ]"
+list_commands_test "Authenticated" "${CONFIG}" \
+"--ca ${TEST_CA_DIR}/kea-ca.crt --cert ${TEST_CA_DIR}/kea-client.crt --key ${TEST_CA_DIR}/kea-client.key" \
+"[ { \"arguments\": [ \"build-report\", \"config-backend-pull\", \"config-get\", \"config-hash-get\", \"config-reload\", \"config-set\", \"config-test\", \"config-write\", \"dhcp-disable\", \"dhcp-enable\", \"leases-reclaim\", \"list-commands\", \"server-tag-get\", \"shutdown\", \"statistic-get\", \"statistic-get-all\", \"statistic-remove\", \"statistic-remove-all\", \"statistic-reset\", \"statistic-reset-all\", \"statistic-sample-age-set\", \"statistic-sample-age-set-all\", \"statistic-sample-count-set\", \"statistic-sample-count-set-all\", \"status-get\", \"version-get\" ], \"result\": 0 } ]"