From: Marcin Siodelski Date: Thu, 25 Jan 2018 10:27:48 +0000 (+0100) Subject: [5457] Implemented unit test for dhcp4_srv_configured. X-Git-Tag: ha_checkpoints12~3^2~12 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=14286b9e9b4c55dd6b12e8de28c69669c7e8aa9d;p=thirdparty%2Fkea.git [5457] Implemented unit test for dhcp4_srv_configured. --- diff --git a/src/bin/dhcp4/ctrl_dhcp4_srv.cc b/src/bin/dhcp4/ctrl_dhcp4_srv.cc index fd344d20b2..ae0dc5f9bd 100644 --- a/src/bin/dhcp4/ctrl_dhcp4_srv.cc +++ b/src/bin/dhcp4/ctrl_dhcp4_srv.cc @@ -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); diff --git a/src/bin/dhcp4/tests/Makefile.am b/src/bin/dhcp4/tests/Makefile.am index 251525cccf..f23e046e05 100644 --- a/src/bin/dhcp4/tests/Makefile.am +++ b/src/bin/dhcp4/tests/Makefile.am @@ -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 index 0000000000..4adafb09a6 --- /dev/null +++ b/src/bin/dhcp4/tests/callout_library_3.cc @@ -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 +#include +#include + +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 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); +} + +} diff --git a/src/bin/dhcp4/tests/callout_library_common.h b/src/bin/dhcp4/tests/callout_library_common.h index c3e3436591..568746a0f9 100644 --- a/src/bin/dhcp4/tests/callout_library_common.h +++ b/src/bin/dhcp4/tests/callout_library_common.h @@ -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 @@ -17,6 +17,10 @@ /// 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() { diff --git a/src/bin/dhcp4/tests/hooks_unittest.cc b/src/bin/dhcp4/tests/hooks_unittest.cc index 481aa45092..48d231b8d8 100644 --- a/src/bin/dhcp4/tests/hooks_unittest.cc +++ b/src/bin/dhcp4/tests/hooks_unittest.cc @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -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(remove(LOAD_MARKER_FILE)); static_cast(remove(UNLOAD_MARKER_FILE)); + static_cast(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 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")); +} diff --git a/src/bin/dhcp4/tests/marker_file.h.in b/src/bin/dhcp4/tests/marker_file.h.in index d279aac10c..06f60d85ae 100644 --- a/src/bin/dhcp4/tests/marker_file.h.in +++ b/src/bin/dhcp4/tests/marker_file.h.in @@ -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 {