]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#103,!277] Extended unit tests for databaseConfigApply in DHCPv4.
authorMarcin Siodelski <marcin@isc.org>
Thu, 21 Mar 2019 10:36:49 +0000 (11:36 +0100)
committerMarcin Siodelski <marcin@isc.org>
Tue, 26 Mar 2019 07:08:56 +0000 (03:08 -0400)
src/bin/dhcp4/tests/config_backend_unittest.cc
src/lib/dhcpsrv/cb_ctl_dhcp4.cc
src/lib/dhcpsrv/cb_ctl_dhcp4.h
src/lib/dhcpsrv/cfg_option.h
src/lib/dhcpsrv/tests/cb_ctl_dhcp_unittest.cc
src/lib/dhcpsrv/testutils/generic_backend_unittest.cc
src/lib/dhcpsrv/testutils/generic_backend_unittest.h
src/lib/process/cb_ctl_base.h
src/lib/process/tests/cb_ctl_base_unittests.cc

index 26d8abbb7493e0681bda39c475ab5d0275601b05..1dc87ad71b6439dec3745093aaa53d5c0fa89fb7 100644 (file)
@@ -149,35 +149,6 @@ public:
         }
     }
 
-    /// @brief Tests that a given global is in the staged configured globals
-    ///
-    /// @param name name of the global parameter
-    /// @param exp_value expected value of the global paramter as an Element
-    void checkConfiguredGlobal(const std::string &name,
-                               ConstElementPtr exp_value) {
-        SrvConfigPtr staging_cfg = CfgMgr::instance().getStagingCfg();
-        ConstElementPtr globals = staging_cfg->getConfiguredGlobals();
-        ConstElementPtr found_global = globals->get(name);
-        ASSERT_TRUE(found_global) << "expected global: "
-                    << name << " not found";
-
-        ASSERT_EQ(exp_value->getType(), found_global->getType())
-                  << "expected global: " << name << " has wrong type";
-
-        ASSERT_EQ(*exp_value, *found_global)
-                  << "expected global: " << name << " has wrong value";
-    }
-
-    /// @brief Tests that a given global is in the staged configured globals
-    ///
-    /// @param exp_global StampedValue representing the global value to verify
-    ///
-    /// @todo At the point in time StampedVlaue carries type, exp_type should be
-    /// replaced with exp_global->getType()
-    void checkConfiguredGlobal(StampedValuePtr& exp_global) {
-        checkConfiguredGlobal(exp_global->getName(), exp_global->getElementValue());
-    }
-
     boost::scoped_ptr<Dhcpv4Srv> srv_;  ///< DHCP4 server under test
     int rcode_;                         ///< Return code from element parsing
     ConstElementPtr comment_;           ///< Reason for parse fail
@@ -247,14 +218,16 @@ TEST_F(Dhcp4CBTest, mergeGlobals) {
     EXPECT_EQ(86400, staging_cfg->getDeclinePeriod());
 
     // Verify that the implicit globals from JSON are there.
-    ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal("valid-lifetime", Element::create(1000)));
-    ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal("rebind-timer", Element::create(800)));
+    ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, "valid-lifetime",
+                                                  Element::create(1000)));
+    ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, "rebind-timer",
+                                                  Element::create(800)));
 
     // Verify that the implicit globals from the backend are there.
-    ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(server_hostname));
-    ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(calc_tee_times));
-    ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(t2_percent));
-    ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(renew_timer));
+    ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, server_hostname));
+    ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, calc_tee_times));
+    ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, t2_percent));
+    ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, renew_timer));
 }
 
 // This test verifies that externally configured option definitions
index f6324fba1382538a59a35c54612fcc78956d94f6..e9e7e83677107934315d497f03508b0f193dc616 100644 (file)
@@ -16,8 +16,7 @@ namespace isc {
 namespace dhcp {
 
 void
-CBControlDHCPv4::databaseConfigApply(const ConfigPtr& srv_cfg,
-                                     const db::BackendSelector& backend_selector,
+CBControlDHCPv4::databaseConfigApply(const db::BackendSelector& backend_selector,
                                      const db::ServerSelector& server_selector,
                                      const boost::posix_time::ptime& lb_modification_time,
                                      const db::AuditEntryCollection& audit_entries) {
index 3768925b3031c56787c621d6491974f9957f0fa3..bc5d9ccf70ebdfbb9d79d41c81aa78c5a499e8a3 100644 (file)
@@ -26,23 +26,17 @@ namespace dhcp {
 class CBControlDHCPv4 : public CBControlDHCP<ConfigBackendDHCPv4Mgr> {
 protected:
 
-    /// @brief Fetches the entire or partial configuration from the database.
+    /// @brief DHCPv4 server specific method to apply fetch configuration
+    /// into the local configuration.
     ///
-    /// This method is called by the starting up server to fetch and merge
-    /// the entire configuration from the database or to fetch configuration
-    /// updates periodically, e.g. as a result of triggering an interval
-    /// timer callback.
-    ///
-    /// @param srv_cfg pointer to the staging configuration that should
-    /// hold the config backends list and other partial configuration read
-    /// from the file in case the method is called upon the server's start
-    /// up. It is a pointer to the current server configuration if the
-    /// method is called to fetch configuration updates.
-    /// @param fetch_updates_only boolean value indicating if the method is
-    /// called upon the server start up (false) or it is called to fetch
-    /// configuration updates (true).
-    virtual void databaseConfigApply(const process::ConfigPtr& srv_cfg,
-                                     const db::BackendSelector& backend_selector,
+    /// @param backend_selector Backend selector.
+    /// @param server_selector Server selector.
+    /// @param lb_modification_time Lower bound modification time for the
+    /// configuration elements to be fetched.
+    /// @param audit_entries Audit entries fetched from the database since
+    /// the last configuration update. This collection is empty if there
+    /// were no updates.
+    virtual void databaseConfigApply(const db::BackendSelector& backend_selector,
                                      const db::ServerSelector& server_selector,
                                      const boost::posix_time::ptime& lb_modification_time,
                                      const db::AuditEntryCollection& audit_entries);
index 060c940ea087ddf5f32164902157b23e242d3aaa..cfe7b5f70351a4edc116a99f98999394eb68dcab 100644 (file)
@@ -98,7 +98,8 @@ public:
     ///
     /// @param desc descriptor
     OptionDescriptor(const OptionDescriptor& desc)
-        : data::StampedElement(), option_(desc.option_),
+        : data::StampedElement(desc),
+          option_(desc.option_),
           persistent_(desc.persistent_),
           formatted_value_(desc.formatted_value_),
           space_name_(desc.space_name_) {
index 83d998a9ec744e096c716079ec5591383b0fa8c6..d64c4b584e0760a5c3a757f53e597ddf2ef92426 100644 (file)
 
 #include <config.h>
 
+#include <asiolink/io_address.h>
+#include <cc/stamped_value.h>
+#include <dhcp/option_string.h>
 #include <dhcpsrv/cb_ctl_dhcp4.h>
+#include <dhcpsrv/cfgmgr.h>
+#include <dhcpsrv/testutils/generic_backend_unittest.h>
+#include <dhcpsrv/testutils/test_config_backend_dhcp4.h>
+#include <boost/date_time/posix_time/posix_time.hpp>
 #include <gtest/gtest.h>
+#include <map>
+#include <string>
 
+using namespace isc::asiolink;
+using namespace isc::db;
+using namespace isc::data;
 using namespace isc::dhcp;
+using namespace isc::dhcp::test;
+using namespace isc::process;
 
 namespace {
 
-/// @brief Test fixture class for @c CBControlDHCPv4 unit tests.
-class TestCBControlDHCPv4 : public CBControlDHCPv4 {
+/// @brief Base class for testing derivations of the CBControlDHCP.
+class CBControlDHCPTest : public GenericBackendTest {
 public:
 
+    /// @brief Constructor.
+    CBControlDHCPTest()
+        : timestamp_(), object_timestamp_(), audit_entries_() {
+        CfgMgr::instance().clear();
+        initTimestamps();
+    }
+
+    /// @brief Destructor.
+    virtual ~CBControlDHCPTest() {
+        // Unregister the factory to be tidy.
+        ConfigBackendDHCPv4Mgr::instance().unregisterBackendFactory("memfile");
+        CfgMgr::instance().clear();
+    }
+
+    /// @brief Creates new CREATE audit entry.
+    ///
+    /// The audit entry is added to the @c audit_entries_ collection.
+    ///
+    /// @param object_type Object type to be associated with the audit
+    /// entry.
+    void addCreateAuditEntry(const std::string& object_type) {
+        AuditEntryPtr entry(new AuditEntry(object_type, 1234,
+                                           AuditEntry::ModificationType::CREATE,
+                                           "some log message"));
+        audit_entries_.insert(entry);
+    }
+
+    /// @brief Creates new DELETE audit entry.
+    ///
+    /// The audit entry is added to the @c audit_entries_ collection.
+    ///
+    /// @param object_type Object type to be associated with the audit
+    /// entry.
+    /// @param object_id Identifier of the object to be associated with
+    /// the audit entry.
+    void addDeleteAuditEntry(const std::string& object_type,
+                             const uint64_t object_id) {
+        AuditEntryPtr entry(new AuditEntry(object_type, object_id,
+                                           AuditEntry::ModificationType::DELETE,
+                                           "some log message"));
+        audit_entries_.insert(entry);
+    }
+
+    /// @brief Initializes timestamps used in tests.
+    void initTimestamps() {
+        // Get the current timestamp and move it 30 seconds backwards.
+        auto now = boost::posix_time::second_clock::local_time() -
+            boost::posix_time::seconds(30);
+
+        // Initialize multiple timestamps from the base timestamp. The
+        // values with indexes [-5, 0] are in the past. The remaining
+        // four are in the future.
+        for (int i = -5; i < 5; ++i) {
+            timestamp_[i] = now + boost::posix_time::minutes(i);
+        }
+    }
+
+    /// @brief Returns timestamp associated with a given index.
+    ///
+    /// @param timestamp_index Index of the timestamp to be returned.
+    boost::posix_time::ptime getTimestamp(const int timestamp_index) {
+        return (timestamp_[timestamp_index]);
+    }
+
+    /// @brief Returns timestamp to be associated with a given object type.
+    ///
+    /// The object types correspond to the names of the SQL tables holding
+    /// them, e.g. dhcp4_global_parameter, dhcp4_subnet etc.
+    ///
+    /// @param object_type Object type.
+    boost::posix_time::ptime getTimestamp(const std::string& object_type) {
+        return (object_timestamp_[object_type]);
+    }
+
+    /// @brief Associates object type with a timestamp.
+    ///
+    /// When adding objects to the database, each one is associated with
+    /// a modification time value. This value is setup by unit tests
+    /// via this method.
+    void setTimestamp(const std::string& object_type, const int timestamp_index) {
+        object_timestamp_[object_type] = timestamp_[timestamp_index];
+    }
+
+    /// @brief Sets timestamps for various object types to the same value.
+    ///
+    /// @param timestamp_index Index of the timestamp to be set.
+    virtual void setAllTimestamps(const int timestamp_index) = 0;
+
+    /// @brief Checks if @c databaseConfigApply should fetch updates for specified
+    /// object types.
+    ///
+    /// @param object_type Object type.
+    bool fetchConfigElement(const std::string& object_type) const {
+        if (!audit_entries_.empty()) {
+            const auto& index = audit_entries_.get<AuditEntryObjectTypeTag>();
+            auto range = index.equal_range(object_type);
+            for (auto it = range.first; it != range.second; ++it) {
+                if (((*it)->getModificationType() != AuditEntry::ModificationType::DELETE)) {
+                    return (true);
+                }
+            }
+            return (false);
+        }
+
+        return (true);
+    }
+
+    /// @brief Holds test timestamps.
+    std::map<int, boost::posix_time::ptime> timestamp_;
+
+    /// @brief Holds mapping of the objects types to their timestamps.
+    std::map<std::string, boost::posix_time::ptime> object_timestamp_;
+
+    /// @brief Collection of audit entries used in the unit tests.
+    AuditEntryCollection audit_entries_;
+};
+
+/// @brief Naked @c CBControlDHCPv4 class exposing protected methods.
+class TestCBControlDHCPv4 : public CBControlDHCPv4 {
+public:
+    using CBControlDHCPv4::getInitialAuditEntryTime;
     using CBControlDHCPv4::databaseConfigApply;
 };
 
+/// @brief Test fixture class for @c CBControlDHCPv4 unit tests.
+class CBControlDHCPv4Test : public CBControlDHCPTest {
+public:
+
+    /// @brief Constructor.
+    CBControlDHCPv4Test()
+        : CBControlDHCPTest(), ctl_() {
+        ConfigBackendDHCPv4Mgr::instance().registerBackendFactory("memfile",
+            [](const DatabaseConnection::ParameterMap& params)
+                -> ConfigBackendDHCPv4Ptr {
+                    return (TestConfigBackendDHCPv4Ptr(new TestConfigBackendDHCPv4(params)));
+             });
+        ConfigBackendDHCPv4Mgr::instance().addBackend("type=memfile");
+
+        // By default, set timestamps for all object types to -4. That leaves
+        // us with the possibility to use index -5 (earlier) to use as lower
+        // bound modification time so as all objects are fetched.
+        setAllTimestamps(-4);
+    }
+
+    /// @brief Sets timestamps of all DHCPv4 specific object types.
+    ///
+    /// @param timestamp_index Index of the timestamp to be set.
+    virtual void setAllTimestamps(const int timestamp_index) {
+        setTimestamp("dhcp4_global_parameter", timestamp_index);
+        setTimestamp("dhcp4_option_def", timestamp_index);
+        setTimestamp("dhcp4_options", timestamp_index);
+        setTimestamp("dhcp4_shared_network", timestamp_index);
+        setTimestamp("dhcp4_subnet", timestamp_index);
+    }
+
+    /// @brief Tests the @c CBControlDHCPv4::databaseConfigApply method.
+    ///
+    /// This test inserts configuration elements of each type into the
+    /// configuration database. Next, it calls the @c databaseConfigApply,
+    /// which should merge each object from the database for which the
+    /// CREATE or UPDATE audit entry is found. The test then verifies
+    /// if the appropriate entries have been merged.
+    ///
+    /// @param lb_modification_time Lower bound modification time to be
+    /// passed to the @c databaseConfigApply.
+    void testDatabaseConfigApply(const boost::posix_time::ptime& lb_modification_time) {
+        auto& mgr = ConfigBackendDHCPv4Mgr::instance();
+
+        // Insert global parameter into a database.
+        StampedValuePtr global_parameter = StampedValue::create("foo", "bar");
+        global_parameter->setModificationTime(getTimestamp("dhcp4_global_parameter"));
+        ASSERT_NO_THROW(mgr.getPool()->createUpdateGlobalParameter4(BackendSelector::UNSPEC(),
+                                                                    ServerSelector::ALL(),
+                                                                    global_parameter));
+
+        // Insert option definition into the database.
+        OptionDefinitionPtr def(new OptionDefinition("one", 101, "uint16"));
+        def->setOptionSpaceName("isc");
+        def->setModificationTime(getTimestamp("dhcp4_option_def"));
+        ASSERT_NO_THROW(mgr.getPool()->createUpdateOptionDef4(BackendSelector::UNSPEC(),
+                                                              ServerSelector::ALL(),
+                                                              def));
+
+        // Insert global option into the database.
+        OptionDescriptorPtr opt(new OptionDescriptor(createOption<OptionString>
+                                                     (Option::V4, DHO_HOST_NAME,
+                                                      true, false, "new.example.com")));
+        opt->space_name_ = DHCP4_OPTION_SPACE;
+        opt->setModificationTime(getTimestamp("dhcp4_options"));
+        mgr.getPool()->createUpdateOption4(BackendSelector::UNSPEC(), ServerSelector::ALL(),
+                                           opt);
+
+        // Insert shared network into the database.
+        SharedNetwork4Ptr network(new SharedNetwork4("one"));
+        network->setModificationTime(getTimestamp("dhcp4_shared_network"));
+
+        mgr.getPool()->createUpdateSharedNetwork4(BackendSelector::UNSPEC(),
+                                                  ServerSelector::ALL(),
+                                                  network);
+
+        // Insert subnet into the database.
+        Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.2.0"), 26, 1, 2, 3, SubnetID(1)));
+        subnet->setModificationTime(getTimestamp("dhcp4_subnet"));
+
+        mgr.getPool()->createUpdateSubnet4(BackendSelector::UNSPEC(), ServerSelector::ALL(),
+                                           subnet);
+
+        ASSERT_FALSE(audit_entries_.empty())
+            << "Require at least one audit entry. The test is broken!";
+
+        ctl_.databaseConfigApply(BackendSelector::UNSPEC(), ServerSelector::ALL(),
+                                 lb_modification_time, audit_entries_);
+
+        // The updates should have been merged into current configuration.
+        auto srv_cfg = CfgMgr::instance().getCurrentCfg();
+
+        // If there is an audit entry for global parameter and the parameter
+        // modification time is later than last audit entry time it should
+        // be merged.
+        if (fetchConfigElement("dhcp4_global_parameter") &&
+            (global_parameter->getModificationTime() > lb_modification_time)) {
+            checkConfiguredGlobal(srv_cfg, "foo", Element::create("bar"));
+
+        } else {
+            // Otherwise it shouldn't exist.
+            EXPECT_FALSE(srv_cfg->getConfiguredGlobals()->get("foo"));
+        }
+
+        // If there is an audit entry for option definition and the definition
+        // modification time is later than last audit entry time it should
+        // be merged.
+        auto found_def = srv_cfg->getCfgOptionDef()->get("isc", "one");
+        if (fetchConfigElement("dhcp4_option_def") &&
+            def->getModificationTime() > lb_modification_time) {
+            ASSERT_TRUE(found_def);
+            EXPECT_EQ(101, found_def->getCode());
+            EXPECT_EQ(OptionDataType::OPT_UINT16_TYPE, found_def->getType());
+
+        } else {
+            EXPECT_FALSE(found_def);
+        }
+
+        // If there is an audit entry for an option and the option
+        // modification time is later than last audit entry time it should
+        // be merged.
+        auto options = srv_cfg->getCfgOption();
+        auto found_opt = options->get("dhcp4", DHO_HOST_NAME);
+        if (fetchConfigElement("dhcp4_options") &&
+            (opt->getModificationTime() > lb_modification_time)) {
+            ASSERT_TRUE(found_opt.option_);
+            EXPECT_EQ("new.example.com", found_opt.option_->toString());
+
+        } else {
+            EXPECT_FALSE(found_opt.option_);
+        }
+
+        // If there is an audit entry for a shared network and the network
+        // modification time is later than last audit entry time it should
+        // be merged.
+        auto networks = srv_cfg->getCfgSharedNetworks4();
+        auto found_network = networks->getByName("one");
+        if (fetchConfigElement("dhcp4_shared_network") &&
+            (network->getModificationTime() > lb_modification_time)) {
+            EXPECT_TRUE(found_network);
+
+        } else {
+            EXPECT_FALSE(found_network);
+        }
+
+        // If there is an audit entry for a subnet and the subnet modification
+        // time is later than last audit entry time it should be merged.
+        auto subnets = srv_cfg->getCfgSubnets4();
+        auto found_subnet = subnets->getSubnet(1);
+        if (fetchConfigElement("dhcp4_subnet") &&
+            (subnet->getModificationTime() > lb_modification_time)) {
+            EXPECT_TRUE(found_subnet);
+
+        } else {
+            EXPECT_FALSE(found_subnet);
+        }
+    }
+
+    TestCBControlDHCPv4 ctl_;
+};
+
+
+// This test verifies that the configuration updates for all object
+// types are merged into the current configuration.
+TEST_F(CBControlDHCPv4Test, databaseConfigApplyAll) {
+
+    addCreateAuditEntry("dhcp4_global_parameter");
+    addCreateAuditEntry("dhcp4_option_def");
+    addCreateAuditEntry("dhcp4_options");
+    addCreateAuditEntry("dhcp4_shared_network");
+    addCreateAuditEntry("dhcp4_subnet");
+
+    testDatabaseConfigApply(getTimestamp(-5));
+}
 
-// This test verifies that the configuration updates are
-// merged into the current configuration.
-TEST(CBControlDHCPv4Test, databaseConfigApplyUpdates) {
-    TestCBControlDHCPv4 ctl;
-    /// @todo implement the actual test.
+// This test verifies that only a global parameter is merged into
+// the current configuration.
+TEST_F(CBControlDHCPv4Test, databaseConfigApplyGlobal) {
+    addCreateAuditEntry("dhcp4_global_parameter");
+    testDatabaseConfigApply(getTimestamp(-5));
 }
 
+// This test verifies that global parameter is not fetched from the
+// database when the modification time is earlier than the last
+// fetched audit entry.
+TEST_F(CBControlDHCPv4Test, databaseConfigApplyGlobalNotFetched) {
+    addCreateAuditEntry("dhcp4_global_parameter");
+    testDatabaseConfigApply(getTimestamp(-3));
+}
+
+// This test verifies that only an option definition is merged into
+// the current configuration.
+TEST_F(CBControlDHCPv4Test, databaseConfigApplyOptionDef) {
+    addCreateAuditEntry("dhcp4_option_def");
+    testDatabaseConfigApply(getTimestamp(-5));
+}
+
+// This test verifies that option definition is not fetched from the
+// database when the modification time is earlier than the last
+// fetched audit entry.
+TEST_F(CBControlDHCPv4Test, databaseConfigApplyOptionDefNotFetched) {
+    addCreateAuditEntry("dhcp4_option_def");
+    testDatabaseConfigApply(getTimestamp(-3));
+}
+
+// This test verifies that only a DHCPv4 option is merged into the
+// current configuration.
+TEST_F(CBControlDHCPv4Test, databaseConfigApplyOption) {
+    addCreateAuditEntry("dhcp4_options");
+    testDatabaseConfigApply(getTimestamp(-5));
+}
+
+// This test verifies that DHCPv4 option is not fetched from the
+// database when the modification time is earlier than the last
+// fetched audit entry.
+TEST_F(CBControlDHCPv4Test, databaseConfigApplyOptionNotFetched) {
+    addCreateAuditEntry("dhcp4_options");
+    testDatabaseConfigApply(getTimestamp(-3));
+}
+
+// This test verifies that only a shared network is merged into the
+// current configuration.
+TEST_F(CBControlDHCPv4Test, databaseConfigApplySharedNetwork) {
+    addCreateAuditEntry("dhcp4_shared_network");
+    testDatabaseConfigApply(getTimestamp(-5));
+}
+
+// This test verifies that shared network is not fetched from the
+// database when the modification time is earlier than the last
+// fetched audit entry.
+TEST_F(CBControlDHCPv4Test, databaseConfigApplySharedNetworkNotFetched) {
+    addCreateAuditEntry("dhcp4_shared_network");
+    testDatabaseConfigApply(getTimestamp(-3));
+}
+
+// This test verifies that only a subnet is merged into the current
+// configuration.
+TEST_F(CBControlDHCPv4Test, databaseConfigApplySubnet) {
+    addCreateAuditEntry("dhcp4_subnet");
+    testDatabaseConfigApply(getTimestamp(-5));
+}
+
+// This test verifies that subnet is not fetched from the database
+// when the modification time is earlier than the last fetched audit
+// entry.
+TEST_F(CBControlDHCPv4Test, databaseConfigApplySubnetNotFetched) {
+    addCreateAuditEntry("dhcp4_subnet");
+    testDatabaseConfigApply(getTimestamp(-3));
+}
 
 }
index baceb72f135128c264e9429273d5c84b07231e7c..da6dc67d0f75c8e2d5e1cee8df9482d89c5d095a 100644 (file)
@@ -12,6 +12,8 @@
 #include <util/buffer.h>
 #include <typeinfo>
 
+using namespace isc::data;
+
 namespace isc {
 namespace dhcp {
 namespace test {
@@ -99,6 +101,28 @@ GenericBackendTest::testOptionsEquivalent(const OptionDescriptor& ref_option,
     EXPECT_EQ(ref_option.space_name_, tested_option.space_name_);
 }
 
+void
+GenericBackendTest::checkConfiguredGlobal(const SrvConfigPtr& srv_cfg,
+                                          const std::string &name,
+                                          ConstElementPtr exp_value) {
+    ConstElementPtr globals = srv_cfg->getConfiguredGlobals();
+    ConstElementPtr found_global = globals->get(name);
+    ASSERT_TRUE(found_global) << "expected global: "
+                              << name << " not found";
+
+    ASSERT_EQ(exp_value->getType(), found_global->getType())
+        << "expected global: " << name << " has wrong type";
+
+    ASSERT_EQ(*exp_value, *found_global)
+        << "expected global: " << name << " has wrong value";
+}
+
+void
+GenericBackendTest::checkConfiguredGlobal(const SrvConfigPtr& srv_cfg,
+                                          StampedValuePtr& exp_global) {
+    checkConfiguredGlobal(srv_cfg, exp_global->getName(), exp_global->getElementValue());
+}
+
 
 } // end of namespace isc::dhcp::test
 } // end of namespace isc::dhcp
index c770d7cd4b447400d9ae0bf8595d5ac8b4b941bc..15b7d5d114b134056f2047647f3d160becf8a178 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2019 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
@@ -8,8 +8,10 @@
 #define GENERIC_BACKEND_UNITTEST_H
 
 #include <asiolink/io_address.h>
+#include <cc/stamped_value.h>
 #include <dhcp/option.h>
 #include <dhcpsrv/cfg_option.h>
+#include <dhcpsrv/srv_config.h>
 #include <boost/shared_ptr.hpp>
 #include <gtest/gtest.h>
 #include <cstdint>
@@ -242,6 +244,26 @@ public:
     /// @param tested_option Option returned by the backend to be tested.
     void testOptionsEquivalent(const OptionDescriptor& ref_option,
                                const OptionDescriptor& tested_option) const;
+
+    /// @brief Tests that a given global is in the configured globals
+    ///
+    /// @param srv_cfg server config where the global should be checked.
+    /// @param name name of the global parameter
+    /// @param exp_value expected value of the global paramter as an Element
+    void checkConfiguredGlobal(const SrvConfigPtr& srv_cfg,
+                               const std::string &name,
+                               data::ConstElementPtr exp_value);
+
+    /// @brief Tests that a given global is in the configured globals
+    ///
+    /// @param srv_cfg server config where the global should be checked.
+    /// @param exp_global StampedValue representing the global value to verify
+    ///
+    /// @todo At the point in time StampedVlaue carries type, exp_type should be
+    /// replaced with exp_global->getType()
+    void checkConfiguredGlobal(const SrvConfigPtr& srv_cfg,
+                               data::StampedValuePtr& exp_global);
+
 };
 
 } // end of namespace isc::dhcp::test
index 288f3e2d0e0e93c4bbcbe5c8e6c49d1af418d157..ad4daec20695b51d65ee2df87a61b6845f2c1785 100644 (file)
@@ -211,7 +211,7 @@ public:
         // into the given configuration.
         if (!fetch_updates_only || !audit_entries.empty()) {
             try {
-                databaseConfigApply(srv_cfg, backend_selector, server_selector,
+                databaseConfigApply(backend_selector, server_selector,
                                     lb_modification_time, audit_entries);
             } catch (...) {
                 // Revert last audit entry time so as we can retry from the
@@ -280,7 +280,6 @@ protected:
     /// - Merge the fetched configuration into the local server's
     ///   configuration.
     ///
-    /// @pararm srv_cfg Pointer to the local server configuration.
     /// @param backend_selector Backend selector.
     /// @param server_selector Server selector.
     /// @param lb_modification_time Lower bound modification time for the
@@ -288,8 +287,7 @@ protected:
     /// @param audit_entries Audit entries fetched from the database since
     /// the last configuration update. This collection is empty if there
     /// were no updates.
-    virtual void databaseConfigApply(const ConfigPtr& srv_cfg,
-                                     const db::BackendSelector& backend_selector,
+    virtual void databaseConfigApply(const db::BackendSelector& backend_selector,
                                      const db::ServerSelector& server_selector,
                                      const boost::posix_time::ptime& lb_modification_time,
                                      const db::AuditEntryCollection& audit_entries) = 0;
index f10c7eecb1dbe60c3311cb0926009d2d8b31c310..f1540537565665f3d95189688c9f5a48e1ccc77f 100644 (file)
@@ -245,8 +245,7 @@ public:
     /// @param backend_selector Backend selector.
     /// @param server_selector Server selector.
     /// @param audit_entries Collection of audit entries.
-    virtual void databaseConfigApply(const ConfigPtr& srv_cfg,
-                                     const BackendSelector& backend_selector,
+    virtual void databaseConfigApply(const BackendSelector& backend_selector,
                                      const ServerSelector& server_selector,
                                      const boost::posix_time::ptime&,
                                      const AuditEntryCollection& audit_entries) {