Browse Source

[master] Merge branch 'trac3465'

Marcin Siodelski 10 years ago
parent
commit
6bc61470c9

+ 1 - 0
src/bin/d2/tests/.gitignore

@@ -1,2 +1,3 @@
 /d2_unittests
 /test_data_files_config.h
+/d2_process_tests.sh

+ 4 - 7
src/bin/d2/tests/d2_process_tests.sh.in

@@ -211,13 +211,10 @@ shutdown_test() {
         clean_exit 1
     fi
 
-    # Server should have shut down.
-    get_pids ${bin}
-    if [ ${_GET_PIDS_NUM} -ne 0 ]; then
-        printf "ERROR: D2 did not shut down after receiving signal.\n"\
- ${_GET_PIDS_NUM}
-        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"
 
     test_finish 0
 }

+ 4 - 7
src/bin/dhcp4/tests/dhcp4_process_tests.sh.in

@@ -215,13 +215,10 @@ shutdown_test() {
         clean_exit 1
     fi
 
-    # Server should have shut down.
-    get_pids ${bin}
-    if [ ${_GET_PIDS_NUM} -ne 0 ]; then
-        printf "ERROR: Kea did not shut down after receiving signal.\n"\
- ${_GET_PIDS_NUM}
-        clean_exit 1
-    fi
+    # 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"
 
     test_finish 0
 }

+ 4 - 7
src/bin/dhcp6/tests/dhcp6_process_tests.sh.in

@@ -218,13 +218,10 @@ shutdown_test() {
         clean_exit 1
     fi
 
-    # Server should have shut down.
-    get_pids ${bin}
-    if [ ${_GET_PIDS_NUM} -ne 0 ]; then
-        printf "ERROR: Kea did not shut down after receiving signal.\n"\
- ${_GET_PIDS_NUM}
-        clean_exit 1
-    fi
+    # 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"
 
     test_finish 0
 }

+ 10 - 0
src/bin/keactrl/kea.conf.in

@@ -55,6 +55,16 @@
 #  {    "subnet": "2001:db8:4::/64",
 #       "pool": [ "2001:db8:4::/80" ] }
    ]
+},
+
+# DHCP DDNS configuration starts here.
+"DhcpDdns":
+{
+  "ip_address": "127.0.0.1",
+  "port": 53001,
+  "tsig_keys": [],
+  "forward_ddns" : {},
+  "reverse_ddns" : {}
 }
 
 }

+ 4 - 1
src/bin/keactrl/keactrl.conf.in

@@ -12,7 +12,7 @@ kea_config_file=@sysconfdir@/@PACKAGE@/kea.conf
 exec_prefix=@exec_prefix@
 dhcp4_srv=@libexecdir@/@PACKAGE@/b10-dhcp4
 dhcp6_srv=@libexecdir@/@PACKAGE@/b10-dhcp6
-dhcp_ddns=@libexecdir@/@PACKAGE@/b10-dhcp-ddns
+dhcp_ddns_srv=@libexecdir@/@PACKAGE@/b10-dhcp-ddns
 
 # Start DHCPv4 server?
 dhcp4=yes
@@ -20,5 +20,8 @@ dhcp4=yes
 # Start DHCPv6 server?
 dhcp6=yes
 
+# Start DHCP DDNS server?
+dhcp_ddns=yes
+
 # Be verbose?
 kea_verbose=no

+ 13 - 2
src/bin/keactrl/keactrl.in

@@ -212,12 +212,12 @@ do
         -s|--server)
             shift
             servers=$( printf "%s" ${1} | tr "," "\n" )
-            if [ -z ${servers} ]; then
+            if [ -z "${servers}" ]; then
                 log_error "servers not specified"
                 usage
                 exit 1
             fi
-            # Validate that the specifief server names are correct.
+            # Validate that the specified server names are correct.
             for s in ${servers}
             do
                 is_in_list "${s}" "all dhcp4 dhcp6 dhcp_ddns"
@@ -276,6 +276,7 @@ fi
 # respectively.
 dhcp4=$( printf "%s" ${dhcp4} | tr [:upper:] [:lower:] )
 dhcp6=$( printf "%s" ${dhcp6} | tr [:upper:] [:lower:] )
+dhcp_ddns=$( printf "%s" ${dhcp_ddns} | tr [:upper:] [:lower:] )
 
 case ${command} in
     # Start the servers.
@@ -290,6 +291,7 @@ case ${command} in
         # and if they are enabled in the keactrl configuration file.
         run_conditional "dhcp4" "start_server ${dhcp4_srv} \"${args}\"" 1
         run_conditional "dhcp6" "start_server ${dhcp6_srv} \"${args}\"" 1
+        run_conditional "dhcp_ddns" "start_server ${dhcp_ddns_srv} \"${args}\"" 1
 
         exit 0 ;;
 
@@ -298,6 +300,7 @@ case ${command} in
         # Stop all servers or servers specified from the command line.
         run_conditional "dhcp4" "send_signal 15 $(basename ${dhcp4_srv})" 0
         run_conditional "dhcp6" "send_signal 15 $(basename ${dhcp6_srv})" 0
+        run_conditional "dhcp_ddns" "send_signal 15 $(basename ${dhcp_ddns_srv})" 0
 
         exit 0 ;;
 
@@ -306,6 +309,7 @@ case ${command} in
         # Reconfigure all servers or servers specified from the command line.
         run_conditional "dhcp4" "send_signal 1 $(basename ${dhcp4_srv})" 0
         run_conditional "dhcp6" "send_signal 1 $(basename ${dhcp6_srv})" 0
+        run_conditional "dhcp_ddns" "send_signal 1 $(basename ${dhcp_ddns_srv})" 0
 
         exit 0 ;;
 
@@ -323,6 +327,13 @@ case ${command} in
             kea6_status="active"
         fi
         printf "DHCPv6 server: %s\n" ${kea6_status}
+
+        d2_status="inactive"
+        check_running $(basename ${dhcp_ddns_srv})
+        if [ ${_running} -eq 1 ]; then
+            d2_status="active"
+        fi
+        printf "DHCP DDNS: %s\n" ${d2_status}
         printf "Kea configuration file: %s\n" ${kea_config_file}
         printf "keactrl configuration file: %s\n" ${keactrl_conf}
 

+ 238 - 103
src/bin/keactrl/tests/keactrl_tests.sh.in

@@ -27,8 +27,10 @@ KEACTRL_CFG_FILE=@abs_top_builddir@/src/bin/keactrl/tests/keactrl_test.conf
 # Path to the Kea log file.
 LOG_FILE=@abs_top_builddir@/src/bin/keactrl/tests/test.log
 # Binaries' names
-kea4_name="b10-dhcp4"
-kea6_name="b10-dhcp6"
+wildcard_name="b10-dhcp"
+kea4_name="${wildcard_name}4"
+kea6_name="${wildcard_name}6"
+d2_name="${wildcard_name}-ddns"
 # Kea configuration
 config="{
     \"Dhcp4\":
@@ -65,23 +67,31 @@ config="{
             \"subnet\": \"2001:db8:1::/64\",
             \"pool\": [ \"2001:db8:1::10-2001:db8:1::100\" ]
         } ]
+    },
+    \"DhcpDdns\":
+    {
+        \"ip_address\": \"127.0.0.1\",
+        \"port\": 53001,
+        \"tsig_keys\": [],
+        \"forward_ddns\" : {},
+        \"reverse_ddns\" : {}
     }
 }"
 
 # Fixed part of the keactrl configuration file.
 keactrl_fixed_config="dhcp4_srv=${KEACTRL_BUILD_DIR}/src/bin/dhcp4/b10-dhcp4\n\
 dhcp6_srv=${KEACTRL_BUILD_DIR}/src/bin/dhcp6/b10-dhcp6\n\
-dhcp_ddns=${KEACTRL_BUILD_DIR}/src/bin/d2/b10-dhcp-ddns\n"
+dhcp_ddns_srv=${KEACTRL_BUILD_DIR}/src/bin/d2/b10-dhcp-ddns\n"
 
-# This test checks that both DHCPv4 and DHCPv6 server can be started and
+# This test checks that DHCPv4, DHCPv6 and D2 server can be started and
 # shut down.
-start_both_servers_no_verbose_test() {
+start_all_servers_no_verbose_test() {
     # Create configuration file for keactrl. This configuration enables
-    # both DHCPv4 and DHCPv6 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\nkea_verbose=no\n\
-${keactrl_fixed_config}"
+    # DHCPv4, DHCPv6 and D2 server.
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\n\
+dhcp_ddns=yes\nkea_verbose=no\n${keactrl_fixed_config}"
 
-    test_start "keactrl.start_both_servers_no_verbose_test"
+    test_start "keactrl.start_all_servers_no_verbose_test"
 
     # Create configuration file for Kea and for keactrl.
     create_config "${config}"
@@ -111,21 +121,30 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to start. \
 Expected wait_for_message return %d, returned %d."
 
-    # Make sure that debug messages are not logged (non-verbose mode).
+    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${d2_name} to start. \
+Expected wait_for_message return %d, returned %d."
+
+    # Make sure that debug messages are logged for neither
+    # server (non-verbose mode).
     get_log_messages "DHCP6_START_INFO"
     assert_eq 0 ${_GET_LOG_MESSAGES} \
         "Expected get_log_messages return %d, returned %d."
 
-    # Make sure that debug messages are not logged (non-verbose mode).
     get_log_messages "DHCP4_START_INFO"
     assert_eq 0 ${_GET_LOG_MESSAGES} \
         "Expected get_log_messages return %d, returned %d."
 
+    get_log_messages "DCTL_STARTING"
+    assert_eq 0 ${_GET_LOG_MESSAGES} \
+        "Expected get_log_messages return %d, returned %d."
+
     # Server may shut down imediatelly after configuration has competed.
     # Give it some time to shutdown.
     sleep 3
 
-    # Make sure that both servers are running.
+    # Make sure that all servers are running.
     get_pids ${kea4_name}
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${kea4_name} process running, found %d processes running"
@@ -134,6 +153,10 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${kea6_name} process running, found %d processes running"
 
+    get_pids ${d2_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${d2_name} process running, found %d processes running"
+
     # Use keactrl stop to shutdown the servers.
     printf "Stopping Kea: ${keactrl} stop  -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} stop -c ${KEACTRL_CFG_FILE}
@@ -152,27 +175,29 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
 
-    # Make sure that the servers are down.
-    get_pids ${kea4_name}
-    assert_eq 0 ${_GET_PIDS_NUM} \
-        "Expected %d ${kea4_name} processes running, found %d processes running"
+    # Wait up to 10s for the D2 server to stop.
+    wait_for_message 10 "DCTL_STOPPING" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${d2_name} to shutdown. \
+Expected wait_for_message return %d, returned %d."
 
-    get_pids ${kea6_name}
-    assert_eq 0 ${_GET_PIDS_NUM} \
-        "Expected %d ${kea6_name} processes running, found %d processes running"
+    # Make sure that all servers are down.
+    wait_for_server_down 5 ${wildcard_name}
+    assert_eq 1 ${_WAIT_FOR_SERVER_DOWN} \
+        "Expected wait_for_server_down return %d, returned %d"
 
     test_finish 0
 }
 
 # This test checks that both DHCPv4 and DHCPv6 server can be started in
 # a verbose mode.
-start_both_servers_verbose_test() {
+start_all_servers_verbose_test() {
     # Create configuration file for keactrl. This configuration enables
-    # both DHCPv4 and DHCPv6 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\nkea_verbose=yes\n\
-${keactrl_fixed_config}"
+    # all servers.
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\n\
+dhcp_ddns=yes\nkea_verbose=yes\n${keactrl_fixed_config}"
 
-    test_start "keactrl.start_both_servers_verbose_test"
+    test_start "keactrl.start_all_servers_verbose_test"
 
     # Create configuration file for Kea and for keactrl.
     create_config "${config}"
@@ -199,23 +224,31 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to start. \
 Expected wait_for_message return %d, returned %d."
 
-    # Check if the debug message is present, which should only be the case if
-    # the verbose mode is on.
+    # Wait up to 20s for the D2 server to configure.
+    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${d2_name} to start. \
+Expected wait_for_message return %d, returned %d."
+
+    # Check if the debug messages are present, which should only be
+    # the case if the verbose mode is on.
     get_log_messages "DHCP6_START_INFO" 1
     assert_eq 1 ${_GET_LOG_MESSAGES} \
         "Expected get_log_messages for DHCP6_START_INFO return %d, returned %d."
 
-    # Check if the debug message is present, which should only be the case if
-    # the verbose mode is on.
     get_log_messages "DHCP4_START_INFO" 1
     assert_eq 1 ${_GET_LOG_MESSAGES} \
         "Expected get_log_messages for DHCP4_START_INFO return %d, returned %d."
 
+    get_log_messages "DCTL_STARTING" 1
+    assert_eq 1 ${_GET_LOG_MESSAGES} \
+        "Expected get_log_messages for DCTL_STARTING return %d, returned %d."
+
     # Server may shut down imediatelly after configuration has competed.
     # Give it some time to shutdown.
     sleep 3
 
-    # Make sure that both servers are running.
+    # Make sure that all servers are running.
     get_pids ${kea4_name}
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${kea4_name} process running, found %d processes running"
@@ -224,6 +257,10 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${kea6_name} process running, found %d processes running"
 
+    get_pids ${d2_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${d2_name} process running, found %d processes running"
+
     # Use keactrl stop to shutdown the servers.
     printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} stop -c ${KEACTRL_CFG_FILE}
@@ -242,27 +279,28 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
 
-    # Make sure that the servers are down.
-    get_pids ${kea4_name}
-    assert_eq 0 ${_GET_PIDS_NUM} \
-        "Expected %d ${kea4_name} processes running, found %d processes running"
-
-    get_pids ${kea6_name}
-    assert_eq 0 ${_GET_PIDS_NUM} \
-        "Expected %d ${kea6_name} processes running, found %d processes running"
+    # Wait up to 10s for the D2 server to stop.
+    wait_for_message 10 "DCTL_STOPPING" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${d2_name} to shutdown. \
+Expected wait_for_message return %d, returned %d."
 
+    # Make sure that all servers are down.
+    wait_for_server_down 5 ${wildcard_name}
+    assert_eq 1 ${_WAIT_FOR_SERVER_DOWN} \
+        "Expected wait_for_server_down return %d, returned %d"
 
     test_finish 0
 }
 
 
-# This test checks that only DHCPv4 server can be started and that the DHCPv6
-# server is not started.
+# This test checks that only DHCPv4 server can be started and that other
+# servers are not started.
 start_v4_server_test() {
     # Create configuration file for keactrl. This configuration enables
-    # DHCPv4 server but disables DHCPv6 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=no\nkea_verbose=no\n\
-${keactrl_fixed_config}"
+    # DHCPv4 server but disables other servers.
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=no\n\
+dhcp_ddns=no\nkea_verbose=no\n${keactrl_fixed_config}"
 
     test_start "keactrl.start_v4_server_test"
 
@@ -299,6 +337,11 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 0 ${_GET_PIDS_NUM} \
         "Expected %d ${kea6_name} process running, found %d processes running"
 
+    # Make sure that D2 server is not running.
+    get_pids ${d2_name}
+    assert_eq 0 ${_GET_PIDS_NUM} \
+        "Expected %d ${d2_name} process running, found %d processes running"
+
     # Make sure that the status command returns appropriate status.
     printf "Getting status of Kea modules: %s\n" "${keactrl} status \
 -c ${KEACTRL_CFG_FILE}"
@@ -309,6 +352,8 @@ Expected wait_for_message return %d, returned %d."
         "Expected keactrl status command return %s"
     assert_string_contains "DHCPv6 server: inactive" "${output}" \
         "Expected keactrl status command return %s"
+    assert_string_contains "DHCP DDNS: inactive" "${output}" \
+        "Expected keactrl status command return %s"
 
     # Use keactrl stop to shutdown the servers.
     printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
@@ -322,25 +367,21 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
 
-    # Make sure that the servers are down.
-    get_pids ${kea4_name}
-    assert_eq 0 ${_GET_PIDS_NUM} \
-        "Expected %d ${kea4_name} processes running, found %d processes running"
-
-    get_pids ${kea6_name}
-    assert_eq 0 ${_GET_PIDS_NUM} \
-        "Expected %d ${kea6_name} processes running, found %d processes running"
+    # Make sure that all servers are down.
+    wait_for_server_down 5 ${wildcard_name}
+    assert_eq 1 ${_WAIT_FOR_SERVER_DOWN} \
+        "Expected wait_for_server_down return %d, returned %d"
 
     test_finish 0
 }
 
-# This test checks that only DHCPv6 server can be started and that the DHCPv4
-# server is not started.
+# This test checks that only DHCPv6 server can be started and that other
+# servers are not started.
 start_v6_server_test() {
     # Create configuration file for keactrl. This configuration enables
-    # DHCPv6 server but disables DHCPv4 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=no\ndhcp6=yes\nkea_verbose=no\n\
-${keactrl_fixed_config}"
+    # DHCPv6 server but disables other servers..
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=no\ndhcp6=yes\n\
+dhcp_ddns=no\nkea_verbose=no\n${keactrl_fixed_config}"
 
     test_start "keactrl.start_v6_server_test"
 
@@ -377,6 +418,11 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 0 ${_GET_PIDS_NUM} \
         "Expected %d ${kea4_name} process running, found %d processes running"
 
+    # Make sure that D2 server is not running.
+    get_pids ${d2_name}
+    assert_eq 0 ${_GET_PIDS_NUM} \
+        "Expected %d ${d2_name} process running, found %d processes running"
+
     # Make sure that the status command returns appropriate status.
     printf "Getting status of Kea modules: %s\n" "${keactrl} status -c ${KEACTRL_CFG_FILE}"
     output=$( ${keactrl} status -c ${KEACTRL_CFG_FILE} )
@@ -386,6 +432,9 @@ Expected wait_for_message return %d, returned %d."
         "Expected keactrl status command return %s"
     assert_string_contains "DHCPv6 server: active" "${output}" \
         "Expected keactrl status command return %s"
+    assert_string_contains "DHCP DDNS: inactive" "${output}" \
+        "Expected keactrl status command return %s"
+
 
     # Use keactrl stop to shutdown the servers.
     printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
@@ -399,26 +448,22 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea6_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
 
-    # Make sure that the servers are down.
-    get_pids ${kea4_name}
-    assert_eq 0 ${_GET_PIDS_NUM} \
-        "Expected %d ${kea4_name} processes running, found %d processes running"
-
-    get_pids ${kea6_name}
-    assert_eq 0 ${_GET_PIDS_NUM} \
-        "Expected %d ${kea6_name} processes running, found %d processes running"
+    # Make sure that all servers are down.
+    wait_for_server_down 5 ${wildcard_name}
+    assert_eq 1 ${_WAIT_FOR_SERVER_DOWN} \
+        "Expected wait_for_server_down return %d, returned %d"
 
     test_finish 0
 }
 
-# This test checks that the DHCPv6 server can be started first, and then the
-# DHCPv4 server can be started while DHCPv6 server is already running.
+# This test checks that the DHCPv4 server can be started first, and then the
+# other servers can be started while DHCPv4 server is already running.
 # Also check that both servers can be reconfigured.
 late_start_v4_server_test() {
     # Create configuration file for keactrl. This configuration enables
-    # DHCPv6 server but disables DHCPv4 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=no\ndhcp6=yes\nkea_verbose=no\n\
-${keactrl_fixed_config}"
+    # DHCPv6 server but disables other servers.
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=no\ndhcp6=yes\n\
+dhcp_ddns=no\nkea_verbose=no\n${keactrl_fixed_config}"
 
     test_start "keactrl.late_start_v4_server_test"
 
@@ -466,12 +511,12 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_WAIT_FOR_MESSAGE} "Timeout waiting for ${kea6_name} to reconfigure. \
 Expected wait_for_message to return %d, returned %d."
 
-    # Update keactrl config to enable v4 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\nkea_verbose=yes\n\
-${keactrl_fixed_config}"
+    # Update keactrl config to enable other servers.
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\n\
+dhcp_ddns=yes\nkea_verbose=yes\n${keactrl_fixed_config}"
     create_keactrl_config "${keactrl_config}"
 
-    # Start DHCPv4 server using keactrl script.
+    # Start other servers using keactrl script.
     printf "Starting Kea: ${keactrl} start -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} start -c ${KEACTRL_CFG_FILE}
     ret=${?}
@@ -483,6 +528,13 @@ ${keactrl_fixed_config}"
         "Timeout waiting for ${kea4_name} to start. \
 Expected wait_for_message return %d, returned %d."
 
+    # Wait up to 20s for the D2 server to configure.
+    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${kea4_name} to start. \
+Expected wait_for_message return %d, returned %d."
+
+
     # Make sure that DHCPv6 server is running.
     get_pids ${kea6_name}
     assert_eq 1 ${_GET_PIDS_NUM} \
@@ -493,8 +545,14 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${kea4_name} process running, found %d processes running"
 
+    # Make sure that D2 server is running.
+    get_pids ${d2_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${d2_name} process running, found %d processes running"
+
+
     # Trigger reconfiguration, make sure that servers are reconfigured.
-    printf "Reconfiguring DHCPv6 and DHCPv4 servers: ${keactrl} reload \
+    printf "Reconfiguring all servers: ${keactrl} reload \
 -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} reload -c ${KEACTRL_CFG_FILE}
     ret=${?}
@@ -510,6 +568,11 @@ Expected wait_for_message to return %d, returned %d."
     assert_eq 1 ${_WAIT_FOR_MESSAGE} "Timeout waiting for ${kea4_name} to reconfigure. \
 Expected wait_for_message to return %d, returned %d."
 
+    # There should be two completed configurations of D2 server.
+    wait_for_message 10 "DCTL_CONFIG_COMPLETE" 2
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} "Timeout waiting for ${d2_name} to reconfigure. \
+Expected wait_for_message to return %d, returned %d."
+
     # Use keactrl stop to shutdown the servers.
     printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} stop -c ${KEACTRL_CFG_FILE}
@@ -528,26 +591,28 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
 
-    # Make sure that the servers are down.
-    get_pids ${kea4_name}
-    assert_eq 0 ${_GET_PIDS_NUM} \
-        "Expected %d ${kea4_name} processes running, found %d processes running"
+    # Wait up to 10s for the D2 server to stop.
+    wait_for_message 10 "DCTL_STOPPING" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${d2_name} to shutdown. \
+Expected wait_for_message return %d, returned %d."
 
-    get_pids ${kea6_name}
-    assert_eq 0 ${_GET_PIDS_NUM} \
-        "Expected %d ${kea6_name} processes running, found %d processes running"
+    # Make sure that all servers are down.
+    wait_for_server_down 5 ${wildcard_name}
+    assert_eq 1 ${_WAIT_FOR_SERVER_DOWN} \
+        "Expected wait_for_server_down return %d, returned %d"
 
     test_finish 0
 }
 
 # This test checks that the DHCPv4 server can be started first, and then the
-# DHCPv6 server can be started while DHCPv4 server is already running.
+# other servers can be started while DHCPv4 server is already running.
 # Also check that both servers can be reconfigured.
 late_start_v6_server_test() {
     # Create configuration file for keactrl. This configuration enables
     # DHCPv4 server but disables DHCPv6 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=no\nkea_verbose=yes\n\
-${keactrl_fixed_config}"
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=no\n\
+dhcp_ddns=no\nkea_verbose=yes\n${keactrl_fixed_config}"
 
     test_start "keactrl.late_start_v6_server_test"
 
@@ -584,6 +649,11 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 0 ${_GET_PIDS_NUM} \
         "Expected %d ${kea6_name} process running, found %d processes running"
 
+    # Make sure that D2 server is not running.
+    get_pids ${d2_name}
+    assert_eq 0 ${_GET_PIDS_NUM} \
+        "Expected %d ${d2_name} process running, found %d processes running"
+
     # Trigger reconfiguration, make sure that the DHCPv4 server is reconfigured.
     printf "Reconfiguring the DHCPv4 server: ${keactrl} reload -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} reload -c ${KEACTRL_CFG_FILE}
@@ -595,12 +665,12 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_WAIT_FOR_MESSAGE} "Timeout waiting for ${kea4_name} to reconfigure. \
 Expected wait_for_message to return %d, returned %d."
 
-    # Update keactrl config to enable v6 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\nkea_verbose=no\n\
-${keactrl_fixed_config}"
+    # Update keactrl config to enable other servers.
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\n\
+dhcp_ddns=yes\nkea_verbose=no\n${keactrl_fixed_config}"
     create_keactrl_config "${keactrl_config}"
 
-    # Start DHCPv6 server using keactrl script.
+    # Start other servers using keactrl script.
     printf "Starting Kea: ${keactrl} start -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} start -c ${KEACTRL_CFG_FILE}
     ret=${?}
@@ -612,6 +682,13 @@ ${keactrl_fixed_config}"
         "Timeout waiting for ${kea4_name} to start. \
 Expected wait_for_message return %d, returned %d."
 
+    # Wait up to 20s for the D2 server to configure.
+    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${d2_name} to start. \
+Expected wait_for_message return %d, returned %d."
+
+
     # Make sure that DHCPv6 server is running.
     get_pids ${kea6_name}
     assert_eq 1 ${_GET_PIDS_NUM} \
@@ -622,6 +699,11 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${kea4_name} process running, found %d processes running"
 
+    # Make sure that D2 server is running.
+    get_pids ${d2_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${d2_name} process running, found %d processes running"
+
     # Trigger reconfiguration, make sure that servers are reconfigured.
     printf "Reconfiguring DHCPv6 and DHCPv4 servers: ${keactrl} reload \
 -c ${KEACTRL_CFG_FILE}\n"
@@ -639,6 +721,12 @@ Expected wait_for_message to return %d, returned %d."
     assert_eq 1 ${_WAIT_FOR_MESSAGE} "Timeout waiting for ${kea6_name} to reconfigure. \
 Expected wait_for_message to return %d, returned %d."
 
+    # There should be two completed configurations of Dd2 server.
+    wait_for_message 10 "DCTL_CONFIG_COMPLETE" 2
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} "Timeout waiting for ${d2_name} to reconfigure. \
+Expected wait_for_message to return %d, returned %d."
+
+
     # Use keactrl stop to shutdown the servers.
     printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} stop -c ${KEACTRL_CFG_FILE}
@@ -657,14 +745,16 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
 
-    # Make sure that the servers are down.
-    get_pids ${kea4_name}
-    assert_eq 0 ${_GET_PIDS_NUM} \
-        "Expected %d ${kea4_name} processes running, found %d processes running"
+    # Wait up to 10s for the d2 server to stop.
+    wait_for_message 10 "DCTL_STOPPING" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${d2_name} to shutdown. \
+Expected wait_for_message return %d, returned %d."
 
-    get_pids ${kea6_name}
-    assert_eq 0 ${_GET_PIDS_NUM} \
-        "Expected %d ${kea6_name} processes running, found %d processes running"
+    # Make sure that all servers are down.
+    wait_for_server_down 5 ${wildcard_name}
+    assert_eq 1 ${_WAIT_FOR_SERVER_DOWN} \
+        "Expected wait_for_server_down return %d, returned %d"
 
     test_finish 0
 }
@@ -672,9 +762,9 @@ Expected wait_for_message return %d, returned %d."
 # This test checks that the servers can be shutdown selectively.
 stop_selected_server_test() {
     # Create configuration file for keactrl. This configuration enables
-    # both DHCPv4 and DHCPv6 server.
-    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\nkea_verbose=no\n\
-${keactrl_fixed_config}"
+    # all servers.
+    keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\n\
+dhcp_ddns=yes\nkea_verbose=no\n${keactrl_fixed_config}"
 
     test_start "keactrl.stop_selected_server_test"
 
@@ -703,16 +793,25 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to start. \
 Expected wait_for_message return %d, returned %d."
 
+    # Wait up to 20s for the D2 server to configure.
+    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${d2_name} to start. \
+Expected wait_for_message return %d, returned %d."
+
     # Make sure that debug messages are not logged (non-verbose mode).
     get_log_messages "DHCP6_START_INFO"
     assert_eq 0 ${_GET_LOG_MESSAGES} \
         "Expected get_log_messages return %d, returned %d."
 
-    # Make sure that debug messages are not logged (non-verbose mode).
     get_log_messages "DHCP4_START_INFO"
     assert_eq 0 ${_GET_LOG_MESSAGES} \
         "Expected get_log_messages return %d, returned %d."
 
+    get_log_messages "DCTL_STARTING"
+    assert_eq 0 ${_GET_LOG_MESSAGES} \
+        "Expected get_log_messages return %d, returned %d."
+
     # Server may shut down imediatelly after configuration has competed.
     # Give it some time to shutdown.
     sleep 3
@@ -726,6 +825,10 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${kea6_name} process running, found %d processes running"
 
+    get_pids ${d2_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${d2_name} process running, found %d processes running"
+
     # Use keactrl stop to shutdown DHCPv4 server.
     printf "Stopping DHCPv4 server: ${keactrl} stop -s dhcp4 -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} stop -s dhcp4 -c ${KEACTRL_CFG_FILE}
@@ -738,11 +841,21 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
 
+    # Make sure that the DHCPv4 server is down.
+    wait_for_server_down 5 ${kea4_name}
+    assert_eq 1 ${_WAIT_FOR_SERVER_DOWN} \
+        "Expected wait_for_server_down return %d, returned %d"
+
     # Make sure DHCPv6 server is still running
     get_pids ${kea6_name}
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${kea6_name} process running, found %d processes running"
 
+    # Make sure D2 server is still running
+    get_pids ${kea6_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${d2_name} process running, found %d processes running"
+
     # Use keactrl stop to shutdown DHCPv6 server.
     printf "Stopping DHCPv6 server: ${keactrl} stop -s dhcp6 -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} stop -s dhcp6 -c ${KEACTRL_CFG_FILE}
@@ -756,16 +869,38 @@ Expected wait_for_message return %d, returned %d."
 Expected wait_for_message return %d, returned %d."
 
     # Make sure that the DHCPv6 server is down.
-    get_pids ${kea6_name}
-    assert_eq 0 ${_GET_PIDS_NUM} \
-        "Expected %d ${kea6_name} processes running, found %d processes running"
+    wait_for_server_down 5 ${kea6_name}
+    assert_eq 1 ${_WAIT_FOR_SERVER_DOWN} \
+        "Expected wait_for_server_down return %d, returned %d"
+
+    # Make sure D2 server is still running
+    get_pids ${d2_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${d2_name} process running, found %d processes running"
+
+    # Use keactrl stop to shutdown D2 server.
+    printf "Stopping DHCP DDNS server: ${keactrl} stop -s dhcp_ddns -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} stop -s dhcp_ddns -c ${KEACTRL_CFG_FILE}
+    ret=${?}
+    assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d."
+
+    # Wait up to 10s for the D2 server to stop.
+    wait_for_message 10 "DCTL_STOPPING" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${d2_name} to shutdown. \
+Expected wait_for_message return %d, returned %d."
+
+    # Make sure that the D2 server is down.
+    wait_for_server_down 5 ${d2_name}
+    assert_eq 1 ${_WAIT_FOR_SERVER_DOWN} \
+        "Expected wait_for_server_down return %d, returned %d"
 
     test_finish 0
 }
 
 
-start_both_servers_no_verbose_test
-start_both_servers_verbose_test
+start_all_servers_no_verbose_test
+start_all_servers_verbose_test
 start_v4_server_test
 start_v6_server_test
 late_start_v4_server_test

+ 54 - 9
src/lib/testutils/dhcp_test_lib.sh.in

@@ -19,12 +19,25 @@ KEA_PROCS="b10-dhcp4 b10-dhcp6 b10-dhcp-ddns"
 
 # Prints error message.
 test_lib_error() {
-    printf "ERROR/test_lib: %s\n" "${1}"
+    local s=${1}            # Error message.
+    local no_new_line=${2}  # If specified, the message not terminated with
+                            # new line.
+    printf "ERROR/test_lib: %s" "${s}"
+    if [ -z ${no_new_line} ]; then
+        printf "%s" "\n"
+    fi
+
 }
 
 # Prints info message.
 test_lib_info() {
-    printf "INFO/test_lib: %s\n" "${1}"
+    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 "%s" "\n"
+    fi
 }
 
 ### Assertions ###
@@ -52,9 +65,9 @@ assert_eq() {
 # 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
+    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.
@@ -96,7 +109,7 @@ test_finish() {
 # 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.
+    local cfg="${1}"  # Configuration string.
     if [ -z ${CFG_FILE} ]; then
         test_lib_error "create_config requires CFG_FILE variable be set"
         clean_exit 1
@@ -113,7 +126,7 @@ create_config() {
 # configuration file which name has been set in the ${KEACTRL_CFG_FILE}
 # variable.
 create_keactrl_config() {
-    local cfg=${1} # Configuration string.
+    local cfg="${1}" # Configuration string.
     if [ -z ${KEACTRL_CFG_FILE} ]; then
         test_lib_error "create_keactrl_config requires KEACTRL_CFG_FILE \
 variable be set"
@@ -158,7 +171,7 @@ get_pids() {
 # Return value:
 #   _GET_LOG_MESSAGES: number of log message occurrences.
 get_log_messages() {
-    local msg=${1}  # Message id, e.g. DHCP6_SHUTDOWN
+    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
@@ -259,6 +272,7 @@ wait_for_kea() {
     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
@@ -283,7 +297,7 @@ wait_for_kea() {
 #    _WAIT_FOR_MESSAGE: 0 if the message hasn't occured, 1 otherwise.
 wait_for_message() {
     local timeout=${1}     # Expected timeout value in seconds.
-    local message=${2}     # Expected message id.
+    local message="${2}"   # Expected message id.
     local occurrences=${3} # Number of expected occurrences.
 
     # Validate timeout
@@ -310,6 +324,7 @@ must be a number"
 
     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 "."
@@ -328,6 +343,36 @@ must be a number"
     # Timeout.
 }
 
+# Waits for server to be down.
+# Return value:
+#    _WAIT_FOR_SERVER_DOWN: 1 if server is down, 0 if timeout occured and the
+#                             server is still running.
+wait_for_server_down() {
+    local timeout=${1}    # Timeout specified in seconds.
+    local proc_name=${2}  # Server process name.
+
+    case ${timeout} in
+        ''|*[!0-9]*)
+            test_lib_error "argument passed to wait_for_server_down must be a number"
+            clean_exit 1 ;;
+    esac
+    local loops=0 # Loops counter
+    _WAIT_FOR_SERVER_DOWN=0
+    test_lib_info "wait_for_server_down ${proc_name}: " "skip-new-line"
+    while [ ${loops} -le ${timeout} ]; do
+        printf "."
+        get_pids ${proc_name}
+        if [ ${_GET_PIDS_NUM} -eq 0 ]; then
+            printf "\n"
+            _WAIT_FOR_SERVER_DOWN=1
+            return
+        fi
+        sleep 1
+        loops=$( expr $loops + 1 )
+    done
+    printf "\n"
+}
+
 # Sends specified signal to the Kea process.
 send_signal() {
     local sig=${1}       # Signal number.