]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5457] Implemented unit test for dhcp4_srv_configured.
authorMarcin Siodelski <marcin@isc.org>
Thu, 25 Jan 2018 10:27:48 +0000 (11:27 +0100)
committerMarcin Siodelski <marcin@isc.org>
Thu, 25 Jan 2018 10:27:48 +0000 (11:27 +0100)
src/bin/dhcp4/ctrl_dhcp4_srv.cc
src/bin/dhcp4/tests/Makefile.am
src/bin/dhcp4/tests/callout_library_3.cc [new file with mode: 0644]
src/bin/dhcp4/tests/callout_library_common.h
src/bin/dhcp4/tests/hooks_unittest.cc
src/bin/dhcp4/tests/marker_file.h.in

index fd344d20b23f87b266ac1ff52db6a894b2c52c84..ae0dc5f9bdc2bbef43ec10389f53e638b013f8b2 100644 (file)
@@ -32,11 +32,11 @@ using namespace std;
 namespace {
 
 /// Structure that holds registered hook indexes.
-struct Dhcp4Hooks {
+struct CtrlDhcp4Hooks {
     int hooks_index_dhcp4_srv_configured_;
 
     /// Constructor that registers hook points for the DHCPv4 server.
-    Dhcp4Hooks() {
+    CtrlDhcp4Hooks() {
         hooks_index_dhcp4_srv_configured_ = HooksManager::registerHook("dhcp4_srv_configured");
     }
 };
@@ -45,7 +45,7 @@ struct Dhcp4Hooks {
 // will be instantiated (and the constructor run) when the module is loaded.
 // As a result, the hook indexes will be defined before any method in this
 // module is called.
-Dhcp4Hooks Hooks;
+CtrlDhcp4Hooks Hooks;
 
 /// @brief Signals handler for DHCPv4 server.
 ///
@@ -646,16 +646,22 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
     }
 
     // This hook point notifies hooks libraries that the configuration of the
-    // DHCPv4 server has completed. Currently it only provides hooks libraries
-    // with the pointer to the common IO service. In the future, additional
-    // information can be provided.
+    // DHCPv4 server has completed. It provides the hook library with the pointer
+    // to the common IO service object, new server configuration in the JSON
+    // format and with the pointer to the configuration storage where the
+    // parsed configuration is stored.
     if (HooksManager::calloutsPresent(Hooks.hooks_index_dhcp4_srv_configured_)) {
         CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
 
         callout_handle->setArgument("io_service", srv->getIOService());
+        callout_handle->setArgument("json_config", config);
+        callout_handle->setArgument("server_config", CfgMgr::instance().getStagingCfg());
 
         HooksManager::callCallouts(Hooks.hooks_index_dhcp4_srv_configured_,
                                    *callout_handle);
+
+        // Ignore status code as none of them would have an effect on further
+        // operation.
     }
 
     return (answer);
index 251525cccf1588894f475c4754481016dc6b7e75..f23e046e05f3f7ef4b48838fcea329cbc5cd5130 100644 (file)
@@ -56,7 +56,7 @@ if HAVE_GTEST
 # to unexpected errors. For this reason, the --enable-static-link option is
 # ignored for unit tests built here.
 
-noinst_LTLIBRARIES = libco1.la libco2.la
+noinst_LTLIBRARIES = libco1.la libco2.la libco3.la
 
 # -rpath /nowhere is a hack to trigger libtool to not create a
 # convenience archive, resulting in shared modules
@@ -71,6 +71,11 @@ libco2_la_CXXFLAGS = $(AM_CXXFLAGS)
 libco2_la_CPPFLAGS = $(AM_CPPFLAGS)
 libco2_la_LDFLAGS = -avoid-version -export-dynamic -module -rpath /nowhere
 
+libco3_la_SOURCES  = callout_library_3.cc callout_library_common.h
+libco3_la_CXXFLAGS = $(AM_CXXFLAGS)
+libco3_la_CPPFLAGS = $(AM_CPPFLAGS)
+libco3_la_LDFLAGS = -avoid-version -export-dynamic -module -rpath /nowhere
+
 TESTS += dhcp4_unittests
 
 dhcp4_unittests_SOURCES  = d2_unittest.h d2_unittest.cc
diff --git a/src/bin/dhcp4/tests/callout_library_3.cc b/src/bin/dhcp4/tests/callout_library_3.cc
new file mode 100644 (file)
index 0000000..4adafb0
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (C) 2018 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/.
+
+/// @file
+/// @brief Callout library for tesing execution of the dhcp4_srv_configured
+/// hook point.
+///
+static const int LIBRARY_NUMBER = 3;
+#include <dhcp4/tests/callout_library_common.h>
+#include <string>
+#include <vector>
+
+using namespace isc::hooks;
+
+extern "C" {
+
+/// @brief Callout which appends library number and provided arguments to
+/// the marker file for dhcp4_srv_configured callout.
+///
+/// @param handle callout handle passed to the callout.
+///
+/// @return 0 on success, 1 otherwise.
+int
+dhcp4_srv_configured(CalloutHandle& handle) {
+    // Append library number.
+    if (appendDigit(SRV_CONFIG_MARKER_FILE)) {
+        return (1);
+    }
+
+    // Append argument names.
+    std::vector<std::string> args = handle.getArgumentNames();
+    for (auto arg = args.begin(); arg != args.end(); ++arg) {
+        if (appendArgument(SRV_CONFIG_MARKER_FILE, arg->c_str()) != 0) {
+            return (1);
+        }
+    }
+
+    return (0);
+}
+
+}
index c3e3436591619eac980a0b7da7cf0b783472c8d6..568746a0f9bb02df951de8e2723429701594a005 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2018 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
 /// can determine whether the load/unload functions have been run and, if so,
 /// in what order.
 ///
+/// The additional marker file is created for the dhcp4_srv_configured hook
+/// point. It records the library number and the names of the parameters
+/// provided to the callout.
+///
 /// This file is the common library file for the tests.  It will not compile
 /// by itself - it is included into each callout library which specifies the
 /// missing constant LIBRARY_NUMBER before the inclusion.
@@ -53,6 +57,26 @@ appendDigit(const char* name) {
     return (0);
 }
 
+/// @brief Append argument name passed to the callout to a marker file.
+///
+/// @param file_name Name of the file to open.
+/// @param parameter Parameter name.
+///
+/// @return 0 on success, non-zero on error.
+int appendArgument(const char* file_name, const char* argument) {
+    // Open the file and check if successful.
+    std::fstream file(file_name, std::fstream::out | std::fstream::app);
+    if (!file.good()) {
+        return (1);
+    }
+
+    // Add the library number to it and close.
+    file << argument;
+    file.close();
+
+    return (0);
+}
+
 // Framework functions
 int
 version() {
index 481aa4509272b8b42d2eb5cb8754ecc0e4f9064a..48d231b8d8aeedb9146060cebf0500387657ec7a 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <dhcp4/tests/dhcp4_test_utils.h>
 #include <dhcp4/tests/dhcp4_client.h>
+#include <dhcp4/ctrl_dhcp4_srv.h>
 #include <dhcp4/json_config_parser.h>
 #include <asiolink/io_service.h>
 #include <cc/command_interpreter.h>
@@ -115,6 +116,7 @@ public:
     /// @brief destructor (deletes Dhcpv4Srv)
     virtual ~HooksDhcpv4SrvTest() {
 
+        HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("dhcp4_srv_configured");
         HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("buffer4_receive");
         HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("buffer4_send");
         HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("pkt4_receive");
@@ -862,10 +864,12 @@ public:
         // Get rid of any marker files.
         static_cast<void>(remove(LOAD_MARKER_FILE));
         static_cast<void>(remove(UNLOAD_MARKER_FILE));
+        static_cast<void>(remove(SRV_CONFIG_MARKER_FILE));
         CfgMgr::instance().clear();
     }
 };
 
+
 // Checks if callouts installed on pkt4_receive are indeed called and the
 // all necessary parameters are passed.
 //
@@ -2633,3 +2637,66 @@ TEST_F(LoadUnloadDhcpv4SrvTest, unloadLibraries) {
     EXPECT_TRUE(checkMarkerFile(UNLOAD_MARKER_FILE, "21"));
     EXPECT_TRUE(checkMarkerFile(LOAD_MARKER_FILE, "12"));
 }
+
+// Checks if callouts installed on the dhcp4_srv_configured ared indeed called
+// and all the necessary parameters are pased.
+TEST_F(LoadUnloadDhcpv4SrvTest, Dhcpv4SrvConfigured) {
+    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.
+    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);
+
+    // 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_servicejson_configserver_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_servicejson_configserver_config"));
+}
index d279aac10c2627873eb71349d706258435077694..06f60d85ae802829e13f081304c79eee49bf6149 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2018 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
@@ -14,6 +14,7 @@
 namespace {
 const char* const LOAD_MARKER_FILE = "@abs_builddir@/load_marker.txt";
 const char* const UNLOAD_MARKER_FILE = "@abs_builddir@/unload_marker.txt";
+const char* const SRV_CONFIG_MARKER_FILE = "@abs_builddir@/srv_config_marker_file.txt";
 }
 
 namespace isc {