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");
}
};
// 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.
///
}
// 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);
# 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
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
--- /dev/null
+// 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);
+}
+
+}
-// 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.
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() {
#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>
/// @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");
// 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.
//
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"));
+}
-// 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
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 {