Browse Source

[3589] Added equals function to the CfgOption class.

Marcin Siodelski 10 years ago
parent
commit
a96015175c

+ 3 - 3
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc

@@ -1163,7 +1163,7 @@ TEST_F(Dhcpv4SrvTest, relayAgentInfoEcho) {
     OptionPtr rai_response = offer->getOption(DHO_DHCP_AGENT_OPTIONS);
     ASSERT_TRUE(rai_response);
 
-    EXPECT_TRUE(rai_response->equal(rai_query));
+    EXPECT_TRUE(rai_response->equals(rai_query));
 }
 
 /// @todo move vendor options tests to a separate file.
@@ -2166,7 +2166,7 @@ TEST_F(HooksDhcpv4SrvTest, valueChange_pkt4_receive) {
 
     // ... and check if it is the modified value
     OptionPtr expected = createOption(DHO_DHCP_CLIENT_IDENTIFIER);
-    EXPECT_TRUE(clientid->equal(expected));
+    EXPECT_TRUE(clientid->equals(expected));
 }
 
 // Checks if callouts installed on pkt4_received is able to delete
@@ -2295,7 +2295,7 @@ TEST_F(HooksDhcpv4SrvTest, pkt4SendValueChange) {
 
     // ... and check if it is the modified value
     OptionPtr expected = createOption(DHO_DHCP_SERVER_IDENTIFIER);
-    EXPECT_TRUE(clientid->equal(expected));
+    EXPECT_TRUE(clientid->equals(expected));
 }
 
 // Checks if callouts installed on pkt4_send is able to delete

+ 1 - 1
src/bin/dhcp6/tests/config_parser_unittest.cc

@@ -1002,7 +1002,7 @@ TEST_F(Dhcp6ParserTest, subnetInterfaceId) {
     ifaceid.reset(new Option(Option::V6, D6O_INTERFACE_ID, tmp));
     subnet = CfgMgr::instance().getSubnet6(ifaceid, classify_);
     ASSERT_TRUE(subnet);
-    EXPECT_TRUE(ifaceid->equal(subnet->getInterfaceId()));
+    EXPECT_TRUE(ifaceid->equals(subnet->getInterfaceId()));
 }
 
 

+ 3 - 3
src/bin/dhcp6/tests/hooks_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -701,7 +701,7 @@ TEST_F(HooksDhcpv6SrvTest, valueChange_pkt6_receive) {
 
     // ... and check if it is the modified value
     OptionPtr expected = createOption(D6O_CLIENTID);
-    EXPECT_TRUE(clientid->equal(expected));
+    EXPECT_TRUE(clientid->equals(expected));
 }
 
 // Checks if callouts installed on pkt6_received is able to delete
@@ -822,7 +822,7 @@ TEST_F(HooksDhcpv6SrvTest, valueChange_pkt6_send) {
 
     // ... and check if it is the modified value
     OptionPtr expected = createOption(D6O_SERVERID);
-    EXPECT_TRUE(clientid->equal(expected));
+    EXPECT_TRUE(clientid->equals(expected));
 }
 
 // Checks if callouts installed on pkt6_send is able to delete

+ 7 - 3
src/lib/dhcp/option.cc

@@ -274,9 +274,13 @@ void Option::setUint32(uint32_t value) {
     writeUint32(value, &data_[0], data_.size());
 }
 
-bool Option::equal(const OptionPtr& other) const {
-    return ( (getType() == other->getType()) &&
-             (getData() == other->getData()) );
+bool Option::equals(const OptionPtr& other) const {
+    return (equals(*other));
+}
+
+bool Option::equals(const Option& other) const {
+    return ( (getType() == other.getType()) &&
+             (getData() == other.getData()) );
 }
 
 Option::~Option() {

+ 4 - 2
src/lib/dhcp/option.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -363,7 +363,9 @@ public:
     ///
     /// @param other the other option
     /// @return true if both options are equal
-    virtual bool equal(const OptionPtr& other) const;
+    bool equals(const OptionPtr& other) const;
+
+    virtual bool equals(const Option& other) const;
 
 protected:
 

+ 7 - 7
src/lib/dhcp/tests/option_unittest.cc

@@ -547,8 +547,8 @@ TEST_F(OptionTest, setData) {
                             buf_.size()));
 }
 
-// This test verifies that options can be compared using equal() method.
-TEST_F(OptionTest, equal) {
+// This test verifies that options can be compared using equals() method.
+TEST_F(OptionTest, equals) {
 
     // Five options with varying lengths
     OptionPtr opt1(new Option(Option::V6, 258, buf_.begin(), buf_.begin() + 1));
@@ -561,13 +561,13 @@ TEST_F(OptionTest, equal) {
     // Another instance with the same type and content as opt2
     OptionPtr opt5(new Option(Option::V6, 258, buf_.begin(), buf_.begin() + 2));
 
-    EXPECT_TRUE(opt1->equal(opt1));
+    EXPECT_TRUE(opt1->equals(opt1));
 
-    EXPECT_FALSE(opt1->equal(opt2));
-    EXPECT_FALSE(opt1->equal(opt3));
-    EXPECT_FALSE(opt1->equal(opt4));
+    EXPECT_FALSE(opt1->equals(opt2));
+    EXPECT_FALSE(opt1->equals(opt3));
+    EXPECT_FALSE(opt1->equals(opt4));
 
-    EXPECT_TRUE(opt2->equal(opt5));
+    EXPECT_TRUE(opt2->equals(opt5));
 }
 
 // This test verifies that the name of the option space being encapsulated by

+ 7 - 7
src/lib/dhcp/tests/pkt6_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -732,33 +732,33 @@ TEST_F(Pkt6Test, getAnyRelayOption) {
     // closest to the client.
     opt = msg->getAnyRelayOption(200, Pkt6::RELAY_SEARCH_FROM_CLIENT);
     ASSERT_TRUE(opt);
-    EXPECT_TRUE(opt->equal(relay3_opt1));
+    EXPECT_TRUE(opt->equals(relay3_opt1));
 
     // We want to ge that one inserted by relay1 (first match, starting from
     // closest to the server.
     opt = msg->getAnyRelayOption(200, Pkt6::RELAY_SEARCH_FROM_SERVER);
     ASSERT_TRUE(opt);
-    EXPECT_TRUE(opt->equal(relay1_opt1));
+    EXPECT_TRUE(opt->equals(relay1_opt1));
 
     // We just want option from the first relay (closest to the client)
     opt = msg->getAnyRelayOption(200, Pkt6::RELAY_GET_FIRST);
     ASSERT_TRUE(opt);
-    EXPECT_TRUE(opt->equal(relay3_opt1));
+    EXPECT_TRUE(opt->equals(relay3_opt1));
 
     // We just want option from the last relay (closest to the server)
     opt = msg->getAnyRelayOption(200, Pkt6::RELAY_GET_LAST);
     ASSERT_TRUE(opt);
-    EXPECT_TRUE(opt->equal(relay1_opt1));
+    EXPECT_TRUE(opt->equals(relay1_opt1));
 
     // Let's try to ask for something that is inserted by the middle relay
     // only.
     opt = msg->getAnyRelayOption(100, Pkt6::RELAY_SEARCH_FROM_SERVER);
     ASSERT_TRUE(opt);
-    EXPECT_TRUE(opt->equal(relay2_opt1));
+    EXPECT_TRUE(opt->equals(relay2_opt1));
 
     opt = msg->getAnyRelayOption(100, Pkt6::RELAY_SEARCH_FROM_CLIENT);
     ASSERT_TRUE(opt);
-    EXPECT_TRUE(opt->equal(relay2_opt1));
+    EXPECT_TRUE(opt->equals(relay2_opt1));
 
     opt = msg->getAnyRelayOption(100, Pkt6::RELAY_GET_FIRST);
     EXPECT_FALSE(opt);

+ 12 - 0
src/lib/dhcpsrv/cfg_option.cc

@@ -64,6 +64,18 @@ optionSpaceToVendorId(const std::string& option_space) {
 namespace isc {
 namespace dhcp {
 
+bool
+OptionDescriptor::equals(const OptionDescriptor& other) const {
+    return (persistent == other.persistent &&
+            option->equals(other.option));
+}
+
+bool
+CfgOption::equals(const CfgOption& other) const {
+    return (options_.equals(other.options_) &&
+            vendor_options_.equals(other.vendor_options_));
+}
+
 void
 CfgOption::add(const OptionPtr& option, const bool persistent,
                const std::string& option_space) {

+ 55 - 2
src/lib/dhcpsrv/cfg_option.h

@@ -54,6 +54,31 @@ struct OptionDescriptor {
     /// @param persist if true option is always sent.
     OptionDescriptor(bool persist)
         : option(OptionPtr()), persistent(persist) {};
+
+    /// @brief Checks if the one descriptor is equal to another.
+    ///
+    /// @param other Other option descriptor to compare to.
+    ///
+    /// @return true if descriptors equal, false otherwise.
+    bool equals(const OptionDescriptor& other) const;
+
+    /// @brief Equality operator.
+    ///
+    /// @param other Other option descriptor to compare to.
+    ///
+    /// @return true if descriptors equal, false otherwise.
+    bool operator==(const OptionDescriptor& other) const {
+        return (equals(other));
+    }
+
+    /// @brief Inequality operator.
+    ///
+    /// @param other Other option descriptor to compare to.
+    ///
+    /// @return true if descriptors unequal, false otherwise.
+    bool operator!=(const OptionDescriptor& other) const {
+        return (!equals(other));
+    }
 };
 
 /// A pointer to option descriptor.
@@ -171,6 +196,36 @@ typedef OptionContainer::nth_index<2>::type OptionContainerPersistIndex;
 class CfgOption {
 public:
 
+    /// @name Methods and operators used for comparing objects.
+    ///
+    //@{
+    /// @brief Check if configuration is equal to other configuration.
+    ///
+    /// @param other An object holding configuration to compare to.
+    ///
+    /// @return true if configurations are equal, false otherwise.
+    bool equals(const CfgOption& other) const;
+
+    /// @brief Equality operator.
+    ///
+    /// @param other An object holding configuration to compare to.
+    ///
+    /// @return true if configurations are equal, false otherwise.
+    bool operator==(const CfgOption& other) const {
+        return (equals(other));
+    }
+
+    /// @brief Inequality operator.
+    ///
+    /// @param other An object holding configuration to compare to.
+    ///
+    /// @return true if configurations are unequal, false otherwise.
+    bool operator!=(const CfgOption& other) const {
+        return (!equals(other));
+    }
+
+    //@}
+
     /// @brief Adds instance of the option to the configuration.
     ///
     /// There are two types of options which may be passed to this method:
@@ -257,8 +312,6 @@ private:
     /// @brief Container holding options grouped by vendor id.
     VendorOptionSpaceCollection vendor_options_;
 
-
-
 };
 
 }

+ 1 - 1
src/lib/dhcpsrv/cfgmgr.cc

@@ -141,7 +141,7 @@ Subnet6Ptr CfgMgr::getSubnet6(OptionPtr iface_id_option,
         }
 
         if ( (*subnet)->getInterfaceId() &&
-             ((*subnet)->getInterfaceId()->equal(iface_id_option))) {
+             ((*subnet)->getInterfaceId()->equals(iface_id_option))) {
             LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
                       DHCPSRV_CFGMGR_SUBNET6_IFACE_ID)
                 .arg((*subnet)->toText());

+ 48 - 1
src/lib/dhcpsrv/option_space_container.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -89,6 +89,53 @@ public:
         option_space_map_.clear();
     }
 
+    /// @brief Check if two containers are equal.
+    ///
+    /// This method checks if option space container contains exactly
+    /// the same selectors and that there are exactly the same items
+    /// added for each selector. The order of items doesn't matter.
+    ///
+    /// @param other Other container to compare to.
+    ///
+    /// @return true if containers are equal, false otherwise.
+    bool equals(const OptionSpaceContainer& other) const {
+        for (typename OptionSpaceMap::const_iterator it =
+                 option_space_map_.begin(); it != option_space_map_.end();
+             ++it) {
+
+            typename OptionSpaceMap::const_iterator other_it =
+                other.option_space_map_.find(it->first);
+            if (other_it == option_space_map_.end()) {
+                return (false);
+            }
+
+            for (typename ContainerType::const_iterator items_it =
+                     it->second->begin();
+                 items_it != it->second->end(); ++items_it) {
+
+                if (it->second->size() != other_it->second->size()) {
+                    return (false);
+                }
+
+                bool match_found = false;
+                for (typename ContainerType::const_iterator other_items_it =
+                         other_it->second->begin();
+                     other_items_it != other_it->second->end();
+                     ++other_items_it) {
+                    if (items_it->equals(*other_items_it)) {
+                        match_found = true;
+                        break;
+                    }
+                }
+
+                if (!match_found) {
+                    return (false);
+                }
+            }
+        }
+        return (true);
+    }
+
 private:
 
     /// A map holding container (option space name or vendor-id is the key).

+ 52 - 0
src/lib/dhcpsrv/tests/cfg_option_unittest.cc

@@ -22,6 +22,58 @@ using namespace isc::dhcp;
 
 namespace {
 
+// This test verifies that the option configurations can be compared.
+TEST(CfgOptionTest, equals) {
+    CfgOption cfg1;
+    CfgOption cfg2;
+
+    // Initially the configurations should be equal.
+    ASSERT_TRUE(cfg1 == cfg2);
+    ASSERT_FALSE(cfg1 != cfg2);
+
+    // Add 9 options to two different option spaces. Each option have different
+    // option code and content.
+    for (uint16_t code = 1; code < 10; ++code) {
+        OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, code)));
+        ASSERT_NO_THROW(cfg1.add(option, false, "isc"));
+        ASSERT_NO_THROW(cfg1.add(option, true, "vendor-123"));
+    }
+
+    // Configurations should now be different.
+    ASSERT_FALSE(cfg1 == cfg2);
+    ASSERT_TRUE(cfg1 != cfg2);
+
+    // Add 8 options (excluding the option with code 1) to the same option
+    // spaces.
+    for (uint16_t code = 2; code < 10; ++code) {
+        OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, code)));
+        ASSERT_NO_THROW(cfg2.add(option, false, "isc"));
+        ASSERT_NO_THROW(cfg2.add(option, true, "vendor-123"));
+    }
+
+    // Configurations should still be unequal.
+    ASSERT_FALSE(cfg1 == cfg2);
+    ASSERT_TRUE(cfg1 != cfg2);
+
+    // Add missing option to the option space isc.
+    ASSERT_NO_THROW(cfg2.add(OptionPtr(new Option(Option::V6, 1,
+                                                  OptionBuffer(10, 0x01))),
+                             false, "isc"));
+    // Configurations should still be unequal because option with code 1
+    // is missing in the option space vendor-123.
+    ASSERT_FALSE(cfg1 == cfg2);
+    ASSERT_TRUE(cfg1 != cfg2);
+
+    // Add missing option.
+    ASSERT_NO_THROW(cfg2.add(OptionPtr(new Option(Option::V6, 1,
+                                                  OptionBuffer(10, 0x01))),
+                             true, "vendor-123"));
+    // Configurations should now be equal.
+    ASSERT_TRUE(cfg1 == cfg2);
+    ASSERT_FALSE(cfg1 != cfg2);
+
+}
+
 // This test verifies that multiple options can be added to the configuration
 // and that they can be retrieved using the option space name.
 TEST(CfgOptionTest, add) {