]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1282] Checkpoint: todo HA new test
authorFrancis Dupont <fdupont@isc.org>
Thu, 25 Jun 2020 13:29:33 +0000 (15:29 +0200)
committerFrancis Dupont <fdupont@isc.org>
Sat, 27 Jun 2020 15:59:10 +0000 (17:59 +0200)
21 files changed:
src/bin/dhcp4/ctrl_dhcp4_srv.cc
src/bin/dhcp4/dhcp4_messages.cc
src/bin/dhcp4/dhcp4_messages.h
src/bin/dhcp4/dhcp4_messages.mes
src/bin/dhcp4/dhcp4_srv.cc
src/bin/dhcp4/json_config_parser.cc
src/bin/dhcp4/tests/dhcp4to6_ipc_unittest.cc
src/bin/dhcp4/tests/hooks_unittest.cc
src/bin/dhcp4/tests/shared_network_unittest.cc
src/bin/dhcp6/ctrl_dhcp6_srv.cc
src/bin/dhcp6/dhcp6_messages.cc
src/bin/dhcp6/dhcp6_messages.h
src/bin/dhcp6/dhcp6_messages.mes
src/bin/dhcp6/dhcp6_srv.cc
src/bin/dhcp6/dhcp6to4_ipc.cc
src/bin/dhcp6/json_config_parser.cc
src/bin/dhcp6/tests/dhcp6to4_ipc_unittest.cc
src/bin/dhcp6/tests/hooks_unittest.cc
src/lib/dhcpsrv/tests/alloc_engine_hooks_unittest.cc
src/lib/hooks/hooks_manager.cc
src/lib/hooks/tests/hooks_manager_unittest.cc

index e18487723e0dd015de83378bd2ace7c6f2402e4d..fa4096f00f5d6b036f76e5f78157dbbf7fd0d646 100644 (file)
@@ -232,14 +232,21 @@ ControlledDhcpv4Srv::commandLibReloadHandler(const string&, ConstElementPtr) {
     // stop thread pool (if running)
     MultiThreadingCriticalSection cs;
 
-    /// @todo delete any stored CalloutHandles referring to the old libraries
-    /// Get list of currently loaded libraries and reload them.
-    HookLibsCollection loaded = HooksManager::getLibraryInfo();
-    bool status = HooksManager::loadLibraries(loaded);
-    if (!status) {
+    // Clear the packet queue.
+    MultiThreadingMgr::instance().getThreadPool().reset();
+
+    try {
+        /// Get list of currently loaded libraries and reload them.
+        HookLibsCollection loaded = HooksManager::getLibraryInfo();
+        HooksManager::prepareUnloadLibraries();
+        static_cast<void>(HooksManager::unloadLibraries());
+        bool status = HooksManager::loadLibraries(loaded);
+        if (!status) {
+            isc_throw(Unexpected, "Failed to reload hooks libraries.");
+        }
+    } catch (const std::exception& ex) {
         LOG_ERROR(dhcp4_logger, DHCP4_HOOKS_LIBS_RELOAD_FAIL);
-        ConstElementPtr answer = isc::config::createAnswer(1,
-                                 "Failed to reload hooks libraries.");
+        ConstElementPtr answer = isc::config::createAnswer(1, ex.what());
         return (answer);
     }
     ConstElementPtr answer = isc::config::createAnswer(0,
index 64395acbde27785e8e59077999c833480d299362..c2ae32a7bf9a34d89f2f4257683f3115f9bea133 100644 (file)
@@ -1,4 +1,4 @@
-// File created from ../../../src/bin/dhcp4/dhcp4_messages.mes on Mon Jun 22 2020 17:28
+// File created from ../../../src/bin/dhcp4/dhcp4_messages.mes on Thu Jun 25 2020 13:36
 
 #include <cstddef>
 #include <log/message_types.h>
@@ -141,6 +141,7 @@ extern const isc::log::MessageID DHCP4_SHUTDOWN_REQUEST = "DHCP4_SHUTDOWN_REQUES
 extern const isc::log::MessageID DHCP4_SRV_CONSTRUCT_ERROR = "DHCP4_SRV_CONSTRUCT_ERROR";
 extern const isc::log::MessageID DHCP4_SRV_D2STOP_ERROR = "DHCP4_SRV_D2STOP_ERROR";
 extern const isc::log::MessageID DHCP4_SRV_DHCP4O6_ERROR = "DHCP4_SRV_DHCP4O6_ERROR";
+extern const isc::log::MessageID DHCP4_SRV_UNLOAD_LIBRARIES_ERROR = "DHCP4_SRV_UNLOAD_LIBRARIES_ERROR";
 extern const isc::log::MessageID DHCP4_STARTED = "DHCP4_STARTED";
 extern const isc::log::MessageID DHCP4_STARTING = "DHCP4_STARTING";
 extern const isc::log::MessageID DHCP4_START_INFO = "DHCP4_START_INFO";
@@ -291,6 +292,7 @@ const char* values[] = {
     "DHCP4_SRV_CONSTRUCT_ERROR", "error creating Dhcpv4Srv object, reason: %1",
     "DHCP4_SRV_D2STOP_ERROR", "error stopping IO with DHCP_DDNS during shutdown: %1",
     "DHCP4_SRV_DHCP4O6_ERROR", "error stopping IO with DHCPv4o6 during shutdown: %1",
+    "DHCP4_SRV_UNLOAD_LIBRARIES_ERROR", "error unloading hooks libraries during shutdown: %1",
     "DHCP4_STARTED", "Kea DHCPv4 server version %1 started",
     "DHCP4_STARTING", "Kea DHCPv4 server version %1 (%2) starting",
     "DHCP4_START_INFO", "pid: %1, server port: %2, client port: %3, verbose: %4",
index 9eb0d014d9401642ce1c5b8e3815f8df72243460..408924a064e94fed19ad781998a445523e2840fd 100644 (file)
@@ -1,4 +1,4 @@
-// File created from ../../../src/bin/dhcp4/dhcp4_messages.mes on Mon Jun 22 2020 17:28
+// File created from ../../../src/bin/dhcp4/dhcp4_messages.mes on Thu Jun 25 2020 13:36
 
 #ifndef DHCP4_MESSAGES_H
 #define DHCP4_MESSAGES_H
@@ -142,6 +142,7 @@ extern const isc::log::MessageID DHCP4_SHUTDOWN_REQUEST;
 extern const isc::log::MessageID DHCP4_SRV_CONSTRUCT_ERROR;
 extern const isc::log::MessageID DHCP4_SRV_D2STOP_ERROR;
 extern const isc::log::MessageID DHCP4_SRV_DHCP4O6_ERROR;
+extern const isc::log::MessageID DHCP4_SRV_UNLOAD_LIBRARIES_ERROR;
 extern const isc::log::MessageID DHCP4_STARTED;
 extern const isc::log::MessageID DHCP4_STARTING;
 extern const isc::log::MessageID DHCP4_START_INFO;
index 52cd29ec6135cc7d7759a11ce870e60bc4507ab4..bfc6c372c9e6a221c89882cdae116ee1630d88ff 100644 (file)
@@ -828,6 +828,13 @@ stopping IO between the DHCPv4 server and the DHCPv6o6 server.  This is
 probably due to a programmatic error is not likely to impact either server
 upon restart.  The reason for the failure is given within the message.
 
+% DHCP4_SRV_UNLOAD_LIBRARIES_ERROR error unloading hooks libraries during shutdown: %1
+This error message indicates that during shutdown, unloading hooks
+libraries failed to close them. If the list of libraries is empty it is
+a programmatic error in the server code. If it is not empty it could be
+a programmatic error in one of the hooks libraries which could lead to
+a crash during finalization.
+
 % DHCP4_STARTED Kea DHCPv4 server version %1 started
 This informational message indicates that the DHCPv4 server has
 processed all configuration information and is ready to process
index db041ee2b0fd3c07a94c31aed3864c417647c318..3b68112b871e1c8310e18a6993fa2cb06918ce6b 100644 (file)
@@ -677,7 +677,18 @@ Dhcpv4Srv::~Dhcpv4Srv() {
     LeaseMgrFactory::destroy();
 
     // Explicitly unload hooks
-    HooksManager::unloadLibraries();
+    HooksManager::prepareUnloadLibraries();
+    if (!HooksManager::unloadLibraries()) {
+        auto names = HooksManager::getLibraryNames();
+        std::string msg;
+        if (!names.empty()) {
+            msg = names[0];
+            for (size_t i = 1; i < names.size(); ++i) {
+                msg += std::string(", ") + names[i];
+            }
+        }
+        LOG_ERROR(dhcp4_logger, DHCP4_SRV_UNLOAD_LIBRARIES_ERROR).arg(msg);
+    }
 }
 
 void
index 8c0bae4c858f1a2d4069df05328c4d0588d1ca29..dd0c9ce7d3a1dc2ea1adb66c1d337c35dea3d243 100644 (file)
@@ -35,6 +35,7 @@
 #include <dhcpsrv/host_data_source_factory.h>
 #include <dhcpsrv/timer_mgr.h>
 #include <process/config_ctl_parser.h>
+#include <hooks/hooks_manager.h>
 #include <hooks/hooks_parser.h>
 #include <config/command_mgr.h>
 #include <util/encode/hex.h>
@@ -708,6 +709,8 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
             // This occurs last as if it succeeds, there is no easy way to
             // revert it.  As a result, the failure to commit a subsequent
             // change causes problems when trying to roll back.
+            HooksManager::prepareUnloadLibraries();
+            static_cast<void>(HooksManager::unloadLibraries());
             const HooksConfig& libraries =
                 CfgMgr::instance().getStagingCfg()->getHooksConfig();
             libraries.loadLibraries();
index 166b53ecb2723975482af32c1520b979896cbbc0..13101d61f2df737a0f75b73b43266cbb1ccbf2da 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2020 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
@@ -71,6 +71,19 @@ public:
         callback_sent_pkt_options_copy_ = std::make_pair(false, false);
     }
 
+    /// @brief Destructor
+    ///
+    /// Various cleanups.
+    virtual ~Dhcp4to6IpcTest() {
+        HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("buffer4_send");
+        callback_recv_pkt_.reset();
+        callback_sent_pkt_.reset();
+        bool status = HooksManager::unloadLibraries();
+        if (!status) {
+            cerr << "(fixture dtor) unloadLibraries failed" << endl;
+        }
+    }
+
     /// @brief Configure DHCP4o6 port.
     ///
     /// @param port New port.
index c59f97897f19138ee90b119842959ada17f7281a..0fc7742aff2b6b4fd37b4d9592dd8c9b0486d069 100644 (file)
@@ -106,6 +106,10 @@ public:
     /// @brief creates Dhcpv4Srv and prepares buffers for callouts
     HooksDhcpv4SrvTest() {
         HooksManager::setTestMode(false);
+        bool status = HooksManager::unloadLibraries();
+        if (!status) {
+            cerr << "(fixture ctor) unloadLibraries failed" << endl;
+        }
 
         // Allocate new DHCPv6 Server
         srv_ = new NakedDhcpv4Srv(0);
@@ -119,6 +123,9 @@ public:
     /// @brief destructor (deletes Dhcpv4Srv)
     virtual ~HooksDhcpv4SrvTest() {
 
+        // clear static buffers
+        resetCalloutBuffers();
+
         HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("dhcp4_srv_configured");
         HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("buffer4_receive");
         HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("buffer4_send");
@@ -132,6 +139,10 @@ public:
 
         delete srv_;
         HooksManager::setTestMode(false);
+        bool status = HooksManager::unloadLibraries();
+        if (!status) {
+            cerr << "(fixture dtor) unloadLibraries failed" << endl;
+        }
     }
 
     /// @brief creates an option with specified option code
index ae7ca5f49eac067c4c89d540e651a223f6d2f7db..5cf868c8fb7b9771940ed908463d43e0ec3a4f55 100644 (file)
@@ -1344,7 +1344,7 @@ TEST_F(Dhcpv4SharedNetworkTest, parse) {
     ASSERT_TRUE(status);
     int rcode;
     ConstElementPtr comment = config::parseAnswer(rcode, status);
-    ASSERT_EQ(0, rcode);
+    ASSERT_EQ(0, rcode) << " comment: " << comment->stringValue();
     ASSERT_NO_THROW( {
         CfgDbAccessPtr cfg_db = CfgMgr::instance().getStagingCfg()->getCfgDbAccess();
         cfg_db->setAppendedParameters("universe=4");
index eeb061797ff6a96a31064f1a5e01cc0993f8893b..282cc9e4b16d1ade348491f6a972bacdd04b0ba2 100644 (file)
@@ -235,14 +235,21 @@ ControlledDhcpv6Srv::commandLibReloadHandler(const string&, ConstElementPtr) {
     // stop thread pool (if running)
     MultiThreadingCriticalSection cs;
 
-    /// @todo delete any stored CalloutHandles referring to the old libraries
-    /// Get list of currently loaded libraries and reload them.
-    HookLibsCollection loaded = HooksManager::getLibraryInfo();
-    bool status = HooksManager::loadLibraries(loaded);
-    if (!status) {
+    // Clear the packet queue.
+    MultiThreadingMgr::instance().getThreadPool().reset();
+
+    try {
+        /// Get list of currently loaded libraries and reload them.
+        HookLibsCollection loaded = HooksManager::getLibraryInfo();
+        HooksManager::prepareUnloadLibraries();
+        static_cast<void>(HooksManager::unloadLibraries());
+        bool status = HooksManager::loadLibraries(loaded);
+        if (!status) {
+            isc_throw(Unexpected, "Failed to reload hooks libraries.");
+        }
+    } catch (const std::exception& ex) {
         LOG_ERROR(dhcp6_logger, DHCP6_HOOKS_LIBS_RELOAD_FAIL);
-        ConstElementPtr answer = isc::config::createAnswer(1,
-                                 "Failed to reload hooks libraries.");
+        ConstElementPtr answer = isc::config::createAnswer(1, ex.what());
         return (answer);
     }
     ConstElementPtr answer = isc::config::createAnswer(0,
index 341c9bdb6e0255400cbcc24f66fa76b238187a45..6a37909c17cb4b1c84a7d6c6ec20c35f8e5debca 100644 (file)
@@ -1,4 +1,4 @@
-// File created from ../../../src/bin/dhcp6/dhcp6_messages.mes on Mon Jun 22 2020 17:30
+// File created from ../../../src/bin/dhcp6/dhcp6_messages.mes on Thu Jun 25 2020 14:35
 
 #include <cstddef>
 #include <log/message_types.h>
@@ -140,6 +140,7 @@ extern const isc::log::MessageID DHCP6_SHUTDOWN_REQUEST = "DHCP6_SHUTDOWN_REQUES
 extern const isc::log::MessageID DHCP6_SOCKET_UNICAST = "DHCP6_SOCKET_UNICAST";
 extern const isc::log::MessageID DHCP6_SRV_CONSTRUCT_ERROR = "DHCP6_SRV_CONSTRUCT_ERROR";
 extern const isc::log::MessageID DHCP6_SRV_D2STOP_ERROR = "DHCP6_SRV_D2STOP_ERROR";
+extern const isc::log::MessageID DHCP6_SRV_UNLOAD_LIBRARIES_ERROR = "DHCP6_SRV_UNLOAD_LIBRARIES_ERROR";
 extern const isc::log::MessageID DHCP6_STANDALONE = "DHCP6_STANDALONE";
 extern const isc::log::MessageID DHCP6_STARTED = "DHCP6_STARTED";
 extern const isc::log::MessageID DHCP6_STARTING = "DHCP6_STARTING";
@@ -290,6 +291,7 @@ const char* values[] = {
     "DHCP6_SOCKET_UNICAST", "server is about to open socket on address %1 on interface %2",
     "DHCP6_SRV_CONSTRUCT_ERROR", "error creating Dhcpv6Srv object, reason: %1",
     "DHCP6_SRV_D2STOP_ERROR", "error stopping IO with DHCP_DDNS during shutdown: %1",
+    "DHCP6_SRV_UNLOAD_LIBRARIES_ERROR", "error unloading hooks libraries during shutdown: %1",
     "DHCP6_STANDALONE", "skipping message queue, running standalone",
     "DHCP6_STARTED", "Kea DHCPv6 server version %1 started",
     "DHCP6_STARTING", "Kea DHCPv6 server version %1 (%2) starting",
index 8294a6e17cc93bbd12834cff6bc6124a6d1205e6..bb9bc10ab5a697e5cd28417ebfbd3ef23e0c30ee 100644 (file)
@@ -1,4 +1,4 @@
-// File created from ../../../src/bin/dhcp6/dhcp6_messages.mes on Mon Jun 22 2020 17:30
+// File created from ../../../src/bin/dhcp6/dhcp6_messages.mes on Thu Jun 25 2020 14:35
 
 #ifndef DHCP6_MESSAGES_H
 #define DHCP6_MESSAGES_H
@@ -141,6 +141,7 @@ extern const isc::log::MessageID DHCP6_SHUTDOWN_REQUEST;
 extern const isc::log::MessageID DHCP6_SOCKET_UNICAST;
 extern const isc::log::MessageID DHCP6_SRV_CONSTRUCT_ERROR;
 extern const isc::log::MessageID DHCP6_SRV_D2STOP_ERROR;
+extern const isc::log::MessageID DHCP6_SRV_UNLOAD_LIBRARIES_ERROR;
 extern const isc::log::MessageID DHCP6_STANDALONE;
 extern const isc::log::MessageID DHCP6_STARTED;
 extern const isc::log::MessageID DHCP6_STARTING;
index c04cebe0e54d603385a37d0f8ae84203cc3517e1..01496c95d673ea85698e01831c56eb6b9d05e37c 100644 (file)
@@ -830,6 +830,13 @@ stopping IO between the DHCPv6 server and the DHCP_DDNS server.  This is
 probably due to a programmatic error is not likely to impact either server
 upon restart.  The reason for the failure is given within the message.
 
+% DHCP6_SRV_UNLOAD_LIBRARIES_ERROR error unloading hooks libraries during shutdown: %1
+This error message indicates that during shutdown, unloading hooks
+libraries failed to close them. If the list of libraries is empty it is
+a programmatic error in the server code. If it is not empty it could be
+a programmatic error in one of the hooks libraries which could lead to
+a crash during finalization.
+
 % DHCP6_STANDALONE skipping message queue, running standalone
 This is a debug message indicating that the IPv6 server is running in
 standalone mode, not connected to the message queue.  Standalone mode
index 0ab2ae93c19ea14f3ab8164169af919a7a464358..306ae95e3628c50e47b23dcd0475f9ddb36aa957 100644 (file)
@@ -282,7 +282,18 @@ Dhcpv6Srv::~Dhcpv6Srv() {
     LeaseMgrFactory::destroy();
 
     // Explicitly unload hooks
-    HooksManager::unloadLibraries();
+    HooksManager::prepareUnloadLibraries();
+    if (!HooksManager::unloadLibraries()) {
+        auto names = HooksManager::getLibraryNames();
+        std::string msg;
+        if (!names.empty()) {
+            msg = names[0];
+            for (size_t i = 1; i < names.size(); ++i) {
+                msg += std::string(", ") + names[i];
+            }
+        }
+        LOG_ERROR(dhcp6_logger, DHCP6_SRV_UNLOAD_LIBRARIES_ERROR).arg(msg);
+    }
 }
 
 void Dhcpv6Srv::shutdown() {
index 0022aced205aec280d452da13bc6fd61c4272f98..68b497023808a399e14444a8caaf71fa44e6511f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2020 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
@@ -115,6 +115,12 @@ void Dhcp6to4Ipc::handler(int /* fd */) {
             // Delete previously set arguments
             callout_handle->deleteAllArguments();
 
+            // Use the RAII wrapper to make sure that the callout handle state is
+            // reset when this object goes out of scope. All hook points must do
+            // it to prevent possible circular dependency between the callout
+            // handle and its arguments.
+            ScopedCalloutHandleState callout_handle_state(callout_handle);
+
             // Enable copying options from the packet within hook library.
             ScopedEnableOptionsCopy<Pkt6> response6_options_copy(pkt);
 
@@ -153,6 +159,7 @@ void Dhcp6to4Ipc::handler(int /* fd */) {
     }
 }
 
-};  // namespace dhcp
+} // namespace dhcp
+
+} // namespace isc
 
-};  // namespace isc
index 9ba6f68f0981738043184da43b0c5b95f1234eae..f8f8285fec1099bf5160eeda039c0beae0a810d0 100644 (file)
@@ -39,6 +39,7 @@
 #include <dhcpsrv/parsers/sanity_checks_parser.h>
 #include <dhcpsrv/host_data_source_factory.h>
 #include <hooks/hooks_parser.h>
+#include <hooks/hooks_manager.h>
 #include <log/logger_support.h>
 #include <process/config_ctl_parser.h>
 
@@ -842,6 +843,8 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
             // change causes problems when trying to roll back.
             const HooksConfig& libraries =
                 CfgMgr::instance().getStagingCfg()->getHooksConfig();
+            HooksManager::prepareUnloadLibraries();
+            static_cast<void>(HooksManager::unloadLibraries());
             libraries.loadLibraries();
         }
         catch (const isc::Exception& ex) {
index 307f56e53721ee68b33b5d065d11bdd65e25e4da..46beca27c8f497b575af59b6d979195080c18522 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2020 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
@@ -60,6 +60,18 @@ public:
         callback_pkt_options_copy_ = false;
     }
 
+    /// @brief Destructor
+    ///
+    /// Various cleanups.
+    virtual ~Dhcp6to4IpcTest() {
+        HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("buffer6_send");
+        callback_pkt_.reset();
+        bool status = HooksManager::unloadLibraries();
+        if (!status) {
+            std::cerr << "(fixture dtor) unloadLibraries failed" << std::endl;
+        }
+    }
+
     /// @brief Configure DHCP4o6 port.
     ///
     /// @param port New port.
index cd11232ae050b24a712cc372e3c6063183ca820e..381f589cbc9cfe4611d9bced9646d535a2e06bb6 100644 (file)
@@ -123,6 +123,10 @@ public:
         : Dhcpv6SrvTest() {
 
         HooksManager::setTestMode(false);
+        bool status = HooksManager::unloadLibraries();
+        if (!status) {
+            cerr << "(fixture ctor) unloadLibraries failed" << endl;
+        }
 
         // Allocate new DHCPv6 Server
         srv_.reset(new NakedDhcpv6Srv(0));
@@ -138,7 +142,26 @@ public:
 
     /// @brief destructor (deletes Dhcpv6Srv)
     ~HooksDhcpv6SrvTest() {
+        // Clear static buffers
+        resetCalloutBuffers();
+
+        HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("buffer6_receive");
+        HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("pkt6_receive");
+        HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("pkt6_send");
+        HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("buffer6_send");
+        HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("subnet6_select");
+        HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("leases6_committed");
+        HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("lease6_renew");
+        HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("lease6_release");
+        HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("lease6_rebind");
+        HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("lease6_decline");
+        HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts("host6_identifier");
+
         HooksManager::setTestMode(false);
+        bool status = HooksManager::unloadLibraries();
+        if (!status) {
+            cerr << "(fixture dtor) unloadLibraries failed" << endl;
+        }
     }
 
     /// @brief creates an option with specified option code
@@ -983,7 +1006,7 @@ public:
     /// that no libraries are loaded and that any marker files are deleted.
     void reset() {
         // Unload any previously-loaded libraries.
-        HooksManager::unloadLibraries();
+        EXPECT_TRUE(HooksManager::unloadLibraries());
 
         // Get rid of any marker files.
         static_cast<void>(remove(LOAD_MARKER_FILE));
index df3948b3fa5322231d902b64088d5c1e1e77d034..682e64aa4c7a6274d3a0f80a8d483f60d09806a7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2020 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
@@ -12,6 +12,8 @@
 #include <hooks/callout_manager.h>
 #include <hooks/hooks_manager.h>
 
+#include <iostream>
+
 using namespace std;
 using namespace isc::hooks;
 using namespace isc::asiolink;
@@ -31,8 +33,13 @@ public:
     }
 
     virtual ~HookAllocEngine6Test() {
+        resetCalloutBuffers();
         HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts(
             "lease6_select");
+        bool status = HooksManager::unloadLibraries();
+        if (!status) {
+            cerr << "(fixture dtor) unloadLibraries failed" << endl;
+        }
     }
 
     /// @brief clears out buffers, so callouts can store received arguments
@@ -181,7 +188,7 @@ TEST_F(HookAllocEngine6Test, lease6_select) {
 
     // Initialize Hooks Manager
     HookLibsCollection libraries; // no libraries at this time
-    HooksManager::loadLibraries(libraries);
+    ASSERT_NO_THROW(HooksManager::loadLibraries(libraries));
 
     // Install lease6_select
     EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
@@ -258,7 +265,7 @@ TEST_F(HookAllocEngine6Test, change_lease6_select) {
 
     // Initialize Hooks Manager
     HookLibsCollection libraries; // no libraries at this time
-    HooksManager::loadLibraries(libraries);
+    ASSERT_NO_THROW(HooksManager::loadLibraries(libraries));
 
     // Install a callout
     EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
@@ -304,7 +311,7 @@ TEST_F(HookAllocEngine6Test, skip_lease6_select) {
 
     // Initialize Hooks Manager
     HookLibsCollection libraries; // no libraries at this time
-    HooksManager::loadLibraries(libraries);
+    ASSERT_NO_THROW(HooksManager::loadLibraries(libraries));
 
     // Install a callout
     EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
@@ -338,12 +345,19 @@ TEST_F(HookAllocEngine6Test, skip_lease6_select) {
 class HookAllocEngine4Test : public AllocEngine4Test {
 public:
     HookAllocEngine4Test() {
+        // The default context is not used in these tests.
+        ctx_.callout_handle_.reset();
         resetCalloutBuffers();
     }
 
     virtual ~HookAllocEngine4Test() {
+        resetCalloutBuffers();
         HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts(
             "lease4_select");
+        bool status = HooksManager::unloadLibraries();
+        if (!status) {
+            cerr << "(fixture dtor) unloadLibraries failed" << endl;
+        }
     }
 
     /// @brief clears out buffers, so callouts can store received arguments
@@ -490,7 +504,7 @@ TEST_F(HookAllocEngine4Test, lease4_select) {
 
     // Initialize Hooks Manager
     HookLibsCollection libraries; // no libraries at this time
-    HooksManager::loadLibraries(libraries);
+    ASSERT_NO_THROW(HooksManager::loadLibraries(libraries));
 
     // Install lease4_select
     EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
@@ -565,7 +579,7 @@ TEST_F(HookAllocEngine4Test, change_lease4_select) {
 
     // Initialize Hooks Manager
     HookLibsCollection libraries; // no libraries at this time
-    HooksManager::loadLibraries(libraries);
+    ASSERT_NO_THROW(HooksManager::loadLibraries(libraries));
 
     // Install a callout
     EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
@@ -615,7 +629,7 @@ TEST_F(HookAllocEngine4Test, skip_lease4_select) {
 
     // Initialize Hooks Manager
     HookLibsCollection libraries; // no libraries at this time
-    HooksManager::loadLibraries(libraries);
+    ASSERT_NO_THROW(HooksManager::loadLibraries(libraries));
 
     // Install a callout
     EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
@@ -641,6 +655,6 @@ TEST_F(HookAllocEngine4Test, skip_lease4_select) {
     checkCalloutHandleReset(ctx.query_);
 }
 
-}; // namespace test
-}; // namespace dhcp
-}; // namespace isc
+} // namespace test
+} // namespace dhcp
+} // namespace isc
index 584a4fdf6fc22b28b3729c9e6110e801718df068..868f48192cece852b406b3281fc927e8064d270f 100644 (file)
@@ -135,6 +135,10 @@ HooksManager::loadLibraries(const HookLibsCollection& libraries) {
 
 bool
 HooksManager::unloadLibrariesInternal() {
+    if (test_mode_) {
+        return (true);
+    }
+
     ServerHooks::getServerHooks().getParkingLotsPtr()->clear();
 
     // Keep a weak pointer on the existing library manager collection.
@@ -167,6 +171,10 @@ bool HooksManager::unloadLibraries() {
 
 void
 HooksManager::prepareUnloadLibrariesInternal() {
+    if (test_mode_) {
+        return;
+    }
+
     static_cast<void>(lm_collection_->prepareUnloadLibraries());
 }
 
index 282f78916dcc4edc85c9586cf6566a5dd4911f8e..6d011093d65c555449f26c7ae2e84990073efbc0 100644 (file)
@@ -470,6 +470,10 @@ TEST_F(HooksManagerTest, PrePostCalloutTest) {
 
     // ... and check that the pre- and post- callout functions don't survive a
     // reload.
+    EXPECT_NO_THROW(HooksManager::prepareUnloadLibraries());
+    bool status = false;
+    EXPECT_NO_THROW(status = HooksManager::unloadLibraries());
+    EXPECT_TRUE(status);
     EXPECT_TRUE(HooksManager::loadLibraries(library_names));
     handle = HooksManager::createCalloutHandle();
 
@@ -519,6 +523,10 @@ TEST_F(HooksManagerTest, TestModeEnabledPrePostSurviveLoad) {
 
     // ... and check that the pre- and post- callout functions survive a
     // reload.
+    EXPECT_NO_THROW(HooksManager::prepareUnloadLibraries());
+    bool status = false;
+    EXPECT_NO_THROW(status = HooksManager::unloadLibraries());
+    EXPECT_TRUE(status);
     EXPECT_TRUE(HooksManager::loadLibraries(library_names));
     handle = HooksManager::createCalloutHandle();
 
@@ -569,6 +577,10 @@ TEST_F(HooksManagerTest, TestModeDisabledPrePostDoNotSurviveLoad) {
 
     // ... and check that the pre- and post- callout functions don't survive a
     // reload.
+    EXPECT_NO_THROW(HooksManager::prepareUnloadLibraries());
+    bool status = false;
+    EXPECT_NO_THROW(status = HooksManager::unloadLibraries());
+    EXPECT_TRUE(status);
     EXPECT_TRUE(HooksManager::loadLibraries(library_names));
     handle = HooksManager::createCalloutHandle();
 
@@ -616,6 +628,10 @@ TEST_F(HooksManagerTest, TestModeEnabledTooLatePrePostDoNotSurvive) {
 
     // ... and check that the pre- and post- callout functions don't survive a
     // reload.
+    EXPECT_NO_THROW(HooksManager::prepareUnloadLibraries());
+    bool status = false;
+    EXPECT_NO_THROW(status = HooksManager::unloadLibraries());
+    EXPECT_TRUE(status);
     EXPECT_TRUE(HooksManager::loadLibraries(library_names));
     handle = HooksManager::createCalloutHandle();