]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2448] add NEXT_STEP_DROP test cases to dhcpX_srv_configured unit test
authorAndrei Pavel <andrei@isc.org>
Thu, 7 Jul 2022 07:01:41 +0000 (10:01 +0300)
committerAndrei Pavel <andrei@isc.org>
Thu, 7 Jul 2022 11:48:20 +0000 (11:48 +0000)
src/bin/dhcp4/tests/callout_library_3.cc
src/bin/dhcp4/tests/hooks_unittest.cc
src/bin/dhcp6/tests/callout_library_3.cc
src/bin/dhcp6/tests/hooks_unittest.cc

index 8b6668eac020fee3ccca9ef1c6535dc68d9b292f..31365b37dbf01bad586adf20a53cc512d599f384 100644 (file)
@@ -9,9 +9,12 @@
 /// hook point.
 ///
 static const int LIBRARY_NUMBER = 3;
+
 #include <config.h>
 
 #include <dhcp4/tests/callout_library_common.h>
+#include <dhcpsrv/srv_config.h>
+
 #include <string>
 #include <vector>
 
@@ -30,6 +33,7 @@ extern "C" {
 /// @return 0 on success, 1 otherwise.
 int
 dhcp4_srv_configured(CalloutHandle& handle) {
+
     // Append library number.
     if (appendDigit(SRV_CONFIG_MARKER_FILE)) {
         return (1);
@@ -43,6 +47,24 @@ dhcp4_srv_configured(CalloutHandle& handle) {
         }
     }
 
+    // Determine if this callout is configured to fail.
+    isc::dhcp::SrvConfigPtr config;
+    handle.getArgument("server_config", config);
+    isc::data::ConstElementPtr mode_element(config ? config->toElement() ?
+        config->toElement()->find("Dhcp4/hooks-libraries") ?
+        config->toElement()->find("Dhcp4/hooks-libraries")->get(0) ?
+        config->toElement()->find("Dhcp4/hooks-libraries")->get(0)->get("parameters") ?
+        config->toElement()->find("Dhcp4/hooks-libraries")->get(0)->get("parameters")->get("mode")
+        : 0 : 0 : 0 : 0 : 0);
+    std::string mode(mode_element ? mode_element->stringValue() : "");
+    if (mode == "fail-without-error") {
+        handle.setStatus(CalloutHandle::NEXT_STEP_DROP);
+    } else if (mode == "fail-with-error") {
+        std::string error("user explicitly configured me to fail");
+        handle.setArgument("error", error);
+        handle.setStatus(CalloutHandle::NEXT_STEP_DROP);
+    }
+
     return (0);
 }
 
index 6733e87c504c4fed11873bc79fb139b45820e788..bfbf6927503ae61f2bc3ad5d39748c4d661582a5 100644 (file)
@@ -2910,64 +2910,86 @@ TEST_F(LoadUnloadDhcpv4SrvTest, failLoadIncompatibleLibraries) {
 // Checks if callouts installed on the dhcp4_srv_configured ared indeed called
 // and all the necessary parameters are passed.
 TEST_F(LoadUnloadDhcpv4SrvTest, Dhcpv4SrvConfigured) {
-    boost::shared_ptr<ControlledDhcpv4Srv> srv(new ControlledDhcpv4Srv(0));
+    for (string parameters : {
+        "",
+        R"(, "parameters": { "mode": "fail-without-error" } )",
+        R"(, "parameters": { "mode": "fail-with-error" } )"}) {
 
-    // Ensure no marker files to start with.
-    ASSERT_FALSE(checkMarkerFileExists(LOAD_MARKER_FILE));
-    ASSERT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE));
-    ASSERT_FALSE(checkMarkerFileExists(SRV_CONFIG_MARKER_FILE));
-
-    // Minimal valid configuration for the server. It includes the
-    // section which loads the callout library #3, which implements
-    // dhcp4_srv_configured callout.
-    std::string config_str =
-        "{"
-        "    \"interfaces-config\": {"
-        "        \"interfaces\": [ ]"
-        "    },"
-        "    \"rebind-timer\": 2000,"
-        "    \"renew-timer\": 1000,"
-        "    \"subnet4\": [ ],"
-        "    \"valid-lifetime\": 4000,"
-        "    \"lease-database\": {"
-        "         \"type\": \"memfile\","
-        "         \"persist\": false"
-        "    },"
-        "    \"hooks-libraries\": ["
-        "        {"
-        "            \"library\": \"" + std::string(CALLOUT_LIBRARY_3) + "\""
-        "        }"
-        "    ]"
-        "}";
-
-    ConstElementPtr config = Element::fromJSON(config_str);
-
-    // Configure the server.
-    ConstElementPtr answer;
-    ASSERT_NO_THROW(answer = srv->processConfig(config));
-
-    // Make sure there were no errors.
-    int status_code;
-    parseAnswer(status_code, answer);
-    ASSERT_EQ(0, status_code);
+        reset();
 
-    // The hook library should have been loaded.
-    EXPECT_TRUE(checkMarkerFile(LOAD_MARKER_FILE, "3"));
-    EXPECT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE));
-    // The dhcp4_srv_configured should have been invoked and the provided
-    // parameters should be recorded.
-    EXPECT_TRUE(checkMarkerFile(SRV_CONFIG_MARKER_FILE,
-                                "3io_contextjson_confignetwork_stateserver_config"));
+        boost::shared_ptr<ControlledDhcpv4Srv> srv(new ControlledDhcpv4Srv(0));
+
+        // Ensure no marker files to start with.
+        ASSERT_FALSE(checkMarkerFileExists(LOAD_MARKER_FILE));
+        ASSERT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE));
+        ASSERT_FALSE(checkMarkerFileExists(SRV_CONFIG_MARKER_FILE));
+
+        // Minimal valid configuration for the server. It includes the
+        // section which loads the callout library #3, which implements
+        // dhcp4_srv_configured callout.
+        string config_str =
+            "{"
+            "    \"interfaces-config\": {"
+            "        \"interfaces\": [ ]"
+            "    },"
+            "    \"rebind-timer\": 2000,"
+            "    \"renew-timer\": 1000,"
+            "    \"subnet4\": [ ],"
+            "    \"valid-lifetime\": 4000,"
+            "    \"lease-database\": {"
+            "         \"type\": \"memfile\","
+            "         \"persist\": false"
+            "    },"
+            "    \"hooks-libraries\": ["
+            "        {"
+            "            \"library\": \"" + std::string(CALLOUT_LIBRARY_3) + "\""
+            + parameters +
+            "        }"
+            "    ]"
+            "}";
+
+        ConstElementPtr config = Element::fromJSON(config_str);
+
+        // Configure the server.
+        ConstElementPtr answer;
+        ASSERT_NO_THROW(answer = srv->processConfig(config));
+
+        // Make sure there were no errors.
+        int status_code;
+        parseAnswer(status_code, answer);
+        if (parameters.empty()) {
+            EXPECT_EQ(0, status_code);
+            EXPECT_EQ(answer->str(), R"({ "result": 0, "text": "Configuration successful." })");
+        } else {
+            EXPECT_EQ(1, status_code);
+            if (parameters.find("fail-without-error") != string::npos) {
+                EXPECT_EQ(answer->str(), R"({ "result": 1, "text": "unknown error" })");
+            } else if (parameters.find("fail-with-error") != string::npos) {
+                EXPECT_EQ(answer->str(),
+                          R"({ "result": 1, "text": "user explicitly configured me to fail" })");
+            } else {
+                GTEST_FAIL() << "unchecked test case";
+            }
+        }
 
-    // Destroy the server, instance which should unload the libraries.
-    srv.reset();
-
-    // The server was destroyed, so the unload() function should now
-    // include the library number in its marker file.
-    EXPECT_TRUE(checkMarkerFile(LOAD_MARKER_FILE, "3"));
-    EXPECT_TRUE(checkMarkerFile(UNLOAD_MARKER_FILE, "3"));
-    EXPECT_TRUE(checkMarkerFile(SRV_CONFIG_MARKER_FILE,
-                                "3io_contextjson_confignetwork_stateserver_config"));
+        // The hook library should have been loaded.
+        EXPECT_TRUE(checkMarkerFile(LOAD_MARKER_FILE, "3"));
+        EXPECT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE));
+        // The dhcp4_srv_configured should have been invoked and the provided
+        // parameters should be recorded.
+        EXPECT_TRUE(checkMarkerFile(SRV_CONFIG_MARKER_FILE,
+                                    "3io_contextjson_confignetwork_stateserver_config"));
+
+        // Destroy the server, instance which should unload the libraries.
+        srv.reset();
+
+        // The server was destroyed, so the unload() function should now
+        // include the library number in its marker file.
+        EXPECT_TRUE(checkMarkerFile(LOAD_MARKER_FILE, "3"));
+        EXPECT_TRUE(checkMarkerFile(UNLOAD_MARKER_FILE, "3"));
+        EXPECT_TRUE(checkMarkerFile(SRV_CONFIG_MARKER_FILE,
+                                    "3io_contextjson_confignetwork_stateserver_config"));
+    }
 }
 
 // This test verifies that parked-packet-limit is properly enforced.
index 06a67ff804441998d8a5f0e64545e134f36669b4..daae1c8d19cd0e6d5169b693baeb292bdbf1c19a 100644 (file)
@@ -12,6 +12,8 @@ static const int LIBRARY_NUMBER = 3;
 #include <config.h>
 
 #include <dhcp6/tests/callout_library_common.h>
+#include <dhcpsrv/srv_config.h>
+
 #include <string>
 #include <vector>
 
@@ -43,6 +45,24 @@ dhcp6_srv_configured(CalloutHandle& handle) {
         }
     }
 
+    // Determine if this callout is configured to fail.
+    isc::dhcp::SrvConfigPtr config;
+    handle.getArgument("server_config", config);
+    isc::data::ConstElementPtr mode_element(config ? config->toElement() ?
+        config->toElement()->find("Dhcp6/hooks-libraries") ?
+        config->toElement()->find("Dhcp6/hooks-libraries")->get(0) ?
+        config->toElement()->find("Dhcp6/hooks-libraries")->get(0)->get("parameters") ?
+        config->toElement()->find("Dhcp6/hooks-libraries")->get(0)->get("parameters")->get("mode")
+        : 0 : 0 : 0 : 0 : 0);
+    std::string mode(mode_element ? mode_element->stringValue() : "");
+    if (mode == "fail-without-error") {
+        handle.setStatus(CalloutHandle::NEXT_STEP_DROP);
+    } else if (mode == "fail-with-error") {
+        std::string error("user explicitly configured me to fail");
+        handle.setArgument("error", error);
+        handle.setStatus(CalloutHandle::NEXT_STEP_DROP);
+    }
+
     return (0);
 }
 
index 3f2f0ea683d07b793272740139abbfd5a63d95d7..fac2d438ac813a83e88388eb2818a1b3f55b7cd2 100644 (file)
@@ -38,6 +38,7 @@
 #include <sstream>
 
 using namespace isc;
+using namespace isc::config;
 using namespace isc::data;
 using namespace isc::dhcp::test;
 using namespace isc::asiolink;
@@ -5186,67 +5187,87 @@ TEST_F(LoadUnloadDhcpv6SrvTest, failLoadIncompatibleLibraries) {
 // Checks if callouts installed on the dhcp6_srv_configured ared indeed called
 // and all the necessary parameters are passed.
 TEST_F(LoadUnloadDhcpv6SrvTest, Dhcpv6SrvConfigured) {
-    boost::shared_ptr<ControlledDhcpv6Srv> srv(new ControlledDhcpv6Srv(0));
+    for (string parameters : {
+        "",
+        R"(, "parameters": { "mode": "fail-without-error" } )",
+        R"(, "parameters": { "mode": "fail-with-error" } )"}) {
 
-    // Ensure no marker files to start with.
-    ASSERT_FALSE(checkMarkerFileExists(LOAD_MARKER_FILE));
-    ASSERT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE));
-    ASSERT_FALSE(checkMarkerFileExists(SRV_CONFIG_MARKER_FILE));
-
-    // Minimal valid configuration for the server. It includes the
-    // section which loads the callout library #3, which implements
-    // dhcp6_srv_configured callout.
-    std::string config_str =
-        "{"
-        "    \"interfaces-config\": {"
-        "        \"interfaces\": [ ]"
-        "    },"
-        "    \"preferred-lifetime\": 3000,"
-        "    \"rebind-timer\": 2000,"
-        "    \"renew-timer\": 1000,"
-        "    \"subnet6\": [ ],"
-        "    \"valid-lifetime\": 4000,"
-        "    \"lease-database\": {"
-        "         \"type\": \"memfile\","
-        "         \"persist\": false"
-        "    },"
-        "    \"hooks-libraries\": ["
-        "        {"
-        "            \"library\": \"" + std::string(CALLOUT_LIBRARY_3) + "\""
-        "        }"
-        "    ]"
-        "}";
-
-    ConstElementPtr config = Element::fromJSON(config_str);
-
-    // Configure the server.
-    ConstElementPtr answer;
-    ASSERT_NO_THROW(answer = srv->processConfig(config));
-
-    // Make sure there were no errors.
-    int status_code;
-    isc::config::parseAnswer(status_code, answer);
-    ASSERT_EQ(0, status_code);
-
-    // The hook library should have been loaded.
-    EXPECT_TRUE(checkMarkerFile(LOAD_MARKER_FILE, "3"));
-    EXPECT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE));
-    // The dhcp6_srv_configured should have been invoked and the provided
-    // parameters should be recorded.
-    //// not yet network_state
-    EXPECT_TRUE(checkMarkerFile(SRV_CONFIG_MARKER_FILE,
-                                "3io_contextjson_confignetwork_stateserver_config"));
+        reset();
 
-    // Destroy the server, instance which should unload the libraries.
-    srv.reset();
-
-    // The server was destroyed, so the unload() function should now
-    // include the library number in its marker file.
-    //// not yet network_state
-    EXPECT_TRUE(checkMarkerFile(LOAD_MARKER_FILE, "3"));
-    EXPECT_TRUE(checkMarkerFile(UNLOAD_MARKER_FILE, "3"));
-    EXPECT_TRUE(checkMarkerFile(SRV_CONFIG_MARKER_FILE,
-                                "3io_contextjson_confignetwork_stateserver_config"));
+        boost::shared_ptr<ControlledDhcpv6Srv> srv(new ControlledDhcpv6Srv(0));
+
+        // Ensure no marker files to start with.
+        ASSERT_FALSE(checkMarkerFileExists(LOAD_MARKER_FILE));
+        ASSERT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE));
+        ASSERT_FALSE(checkMarkerFileExists(SRV_CONFIG_MARKER_FILE));
+
+        // Minimal valid configuration for the server. It includes the
+        // section which loads the callout library #3, which implements
+        // dhcp6_srv_configured callout.
+        string config_str =
+            "{"
+            "    \"interfaces-config\": {"
+            "        \"interfaces\": [ ]"
+            "    },"
+            "    \"preferred-lifetime\": 3000,"
+            "    \"rebind-timer\": 2000,"
+            "    \"renew-timer\": 1000,"
+            "    \"subnet6\": [ ],"
+            "    \"valid-lifetime\": 4000,"
+            "    \"lease-database\": {"
+            "         \"type\": \"memfile\","
+            "         \"persist\": false"
+            "    },"
+            "    \"hooks-libraries\": ["
+            "        {"
+            "            \"library\": \"" + std::string(CALLOUT_LIBRARY_3) + "\""
+            + parameters +
+            "        }"
+            "    ]"
+            "}";
+
+        ConstElementPtr config = Element::fromJSON(config_str);
+
+        // Configure the server.
+        ConstElementPtr answer;
+        ASSERT_NO_THROW(answer = srv->processConfig(config));
+
+        // Make sure there were no errors.
+        int status_code;
+        parseAnswer(status_code, answer);
+        if (parameters.empty()) {
+            EXPECT_EQ(0, status_code);
+            EXPECT_EQ(answer->str(), R"({ "result": 0, "text": "Configuration successful." })");
+        } else {
+            EXPECT_EQ(1, status_code);
+            if (parameters.find("fail-without-error") != string::npos) {
+                EXPECT_EQ(answer->str(), R"({ "result": 1, "text": "unknown error" })");
+            } else if (parameters.find("fail-with-error") != string::npos) {
+                EXPECT_EQ(answer->str(),
+                          R"({ "result": 1, "text": "user explicitly configured me to fail" })");
+            } else {
+                GTEST_FAIL() << "unchecked test case";
+            }
+        }
+
+        // The hook library should have been loaded.
+        EXPECT_TRUE(checkMarkerFile(LOAD_MARKER_FILE, "3"));
+        EXPECT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE));
+        // The dhcp6_srv_configured should have been invoked and the provided
+        // parameters should be recorded.
+        EXPECT_TRUE(checkMarkerFile(SRV_CONFIG_MARKER_FILE,
+                                    "3io_contextjson_confignetwork_stateserver_config"));
+
+        // Destroy the server, instance which should unload the libraries.
+        srv.reset();
+
+        // The server was destroyed, so the unload() function should now
+        // include the library number in its marker file.
+        EXPECT_TRUE(checkMarkerFile(LOAD_MARKER_FILE, "3"));
+        EXPECT_TRUE(checkMarkerFile(UNLOAD_MARKER_FILE, "3"));
+        EXPECT_TRUE(checkMarkerFile(SRV_CONFIG_MARKER_FILE,
+                                    "3io_contextjson_confignetwork_stateserver_config"));
+    }
 }
 
 // This test verifies that parked-packet-limit is enforced.