From: Marcin Siodelski Date: Fri, 19 Sep 2014 06:28:20 +0000 (+0200) Subject: [3589] Added equals function to the CfgOption class. X-Git-Tag: trac3162a_base~4^2~12 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a96015175c2fc201324176be6049ccd5bba6b3c0;p=thirdparty%2Fkea.git [3589] Added equals function to the CfgOption class. --- diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc index bb328307b0..c24e89de14 100644 --- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc +++ b/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 diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc index 961451a4af..35f0403909 100644 --- a/src/bin/dhcp6/tests/config_parser_unittest.cc +++ b/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())); } diff --git a/src/bin/dhcp6/tests/hooks_unittest.cc b/src/bin/dhcp6/tests/hooks_unittest.cc index b943df82cf..8914661b4d 100644 --- a/src/bin/dhcp6/tests/hooks_unittest.cc +++ b/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 diff --git a/src/lib/dhcp/option.cc b/src/lib/dhcp/option.cc index 24ddc06854..5c2366144a 100644 --- a/src/lib/dhcp/option.cc +++ b/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() { diff --git a/src/lib/dhcp/option.h b/src/lib/dhcp/option.h index 15390a2dfa..ad61d28c6d 100644 --- a/src/lib/dhcp/option.h +++ b/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: diff --git a/src/lib/dhcp/tests/option_unittest.cc b/src/lib/dhcp/tests/option_unittest.cc index a3aea9fa48..430bb09420 100644 --- a/src/lib/dhcp/tests/option_unittest.cc +++ b/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 diff --git a/src/lib/dhcp/tests/pkt6_unittest.cc b/src/lib/dhcp/tests/pkt6_unittest.cc index 17cb629b2b..a18aa5cadc 100644 --- a/src/lib/dhcp/tests/pkt6_unittest.cc +++ b/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); diff --git a/src/lib/dhcpsrv/cfg_option.cc b/src/lib/dhcpsrv/cfg_option.cc index 8273d6b4a1..8b620038b1 100644 --- a/src/lib/dhcpsrv/cfg_option.cc +++ b/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) { diff --git a/src/lib/dhcpsrv/cfg_option.h b/src/lib/dhcpsrv/cfg_option.h index 36733dd694..5aed511463 100644 --- a/src/lib/dhcpsrv/cfg_option.h +++ b/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_; - - }; } diff --git a/src/lib/dhcpsrv/cfgmgr.cc b/src/lib/dhcpsrv/cfgmgr.cc index 9f8199f7ea..80025298dd 100644 --- a/src/lib/dhcpsrv/cfgmgr.cc +++ b/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()); diff --git a/src/lib/dhcpsrv/option_space_container.h b/src/lib/dhcpsrv/option_space_container.h index abab8cae30..7bca7d4801 100644 --- a/src/lib/dhcpsrv/option_space_container.h +++ b/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). diff --git a/src/lib/dhcpsrv/tests/cfg_option_unittest.cc b/src/lib/dhcpsrv/tests/cfg_option_unittest.cc index fa34d77e29..b6f865d59e 100644 --- a/src/lib/dhcpsrv/tests/cfg_option_unittest.cc +++ b/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) {