From: Thomas Markwalder Date: Tue, 17 Nov 2015 15:53:05 +0000 (-0500) Subject: [4096] Added client class dictionary to SrvConfig X-Git-Tag: trac4097a_base~1^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=559c0a696a9b48f6601daa713bd39735c5265cf8;p=thirdparty%2Fkea.git [4096] Added client class dictionary to SrvConfig src/lib/dhcpsrv/parsers/client_class_def_parser.cc ClientClassDefListParser::commit() - pushes the newly built local dictionary to CfgMgr staging src/lib/dhcpsrv/srv_config.h src/lib/dhcpsrv/srv_config.cc Added client class dictionary member to SrvConfig src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc TEST_F(ClientClassDefListParserTest, simpleValidList) - now verifies that ClientClassDefListParser::commit() pushes its local dictionary to CfgMgr staging. src/lib/dhcpsrv/tests/srv_config_unittest.cc Added support to test new client class dictionary member --- diff --git a/src/lib/dhcpsrv/parsers/client_class_def_parser.cc b/src/lib/dhcpsrv/parsers/client_class_def_parser.cc index 2c2df8b686..c8f8d5eb50 100644 --- a/src/lib/dhcpsrv/parsers/client_class_def_parser.cc +++ b/src/lib/dhcpsrv/parsers/client_class_def_parser.cc @@ -147,7 +147,7 @@ ClientClassDefListParser::build(ConstElementPtr client_class_def_list) { void ClientClassDefListParser::commit() { - // CfgMgr::instance().setClientClassConfig(local_dictionary_); + CfgMgr::instance().getStagingCfg()->setClientClassDictionary(local_dictionary_); } } // end of namespace isc::dhcp diff --git a/src/lib/dhcpsrv/srv_config.cc b/src/lib/dhcpsrv/srv_config.cc index b614ff5d2d..8f8b793eef 100644 --- a/src/lib/dhcpsrv/srv_config.cc +++ b/src/lib/dhcpsrv/srv_config.cc @@ -32,6 +32,7 @@ SrvConfig::SrvConfig() cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()), cfg_hosts_(new CfgHosts()), cfg_rsoo_(new CfgRSOO()), cfg_expiration_(new CfgExpiration()), + class_dictionary_(new ClientClassDictionary()), decline_timer_(0) { } @@ -41,6 +42,7 @@ SrvConfig::SrvConfig(const uint32_t sequence) cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()), cfg_hosts_(new CfgHosts()), cfg_rsoo_(new CfgRSOO()), cfg_expiration_(new CfgExpiration()), + class_dictionary_(new ClientClassDictionary()), decline_timer_(0) { } @@ -103,6 +105,9 @@ SrvConfig::copy(SrvConfig& new_config) const { // Replace option definitions. cfg_option_def_->copyTo(*new_config.cfg_option_def_); cfg_option_->copyTo(*new_config.cfg_option_); + // Replace the client class dictionary + new_config.class_dictionary_.reset(new ClientClassDictionary(*class_dictionary_)); + } void @@ -146,7 +151,8 @@ SrvConfig::equals(const SrvConfig& other) const { // Logging information is equal between objects, so check other values. return ((*cfg_iface_ == *other.cfg_iface_) && (*cfg_option_def_ == *other.cfg_option_def_) && - (*cfg_option_ == *other.cfg_option_)); + (*cfg_option_ == *other.cfg_option_) && + (*class_dictionary_ == *other.class_dictionary_)); } void diff --git a/src/lib/dhcpsrv/srv_config.h b/src/lib/dhcpsrv/srv_config.h index da387c9a56..20f972497f 100644 --- a/src/lib/dhcpsrv/srv_config.h +++ b/src/lib/dhcpsrv/srv_config.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -302,6 +303,24 @@ public: control_socket_ = control_socket; } + /// @brief Returns pointer to the dictionary of global client + /// class definitions + ClientClassDictionaryPtr getClientClassDictionary() { + return (class_dictionary_); + } + + /// @brief Returns pointer to const dictionary of global client + /// class definitions + const ClientClassDictionaryPtr getClientClassDictionary() const { + return (class_dictionary_); + } + + /// @brief Sets the client class dictionary + /// @param dictionary pointer to the new class dictionary + void setClientClassDictionary(const ClientClassDictionaryPtr& dictionary) { + class_dictionary_ = dictionary; + } + /// @brief Copies the currnet configuration to a new configuration. /// /// This method copies the parameters stored in the configuration to @@ -461,6 +480,9 @@ private: /// @brief Pointer to the control-socket information isc::data::ConstElementPtr control_socket_; + /// @brief Pointer to the dictionary of global client class definitions + ClientClassDictionaryPtr class_dictionary_; + /// @brief Decline Period time /// /// This timer specifies decline probation period, the time after a declined diff --git a/src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc b/src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc index c1e6d6186b..cef5daf780 100644 --- a/src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc +++ b/src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc @@ -101,6 +101,9 @@ protected: ClientClassDefListParser parser("", context); parser.build(config_element); + // Commit should push it to CfgMgr staging + parser.commit(); + // Return the parser's local dicationary return (parser.local_dictionary_); } @@ -417,6 +420,13 @@ TEST_F(ClientClassDefListParserTest, simpleValidList) { // For good measure, make sure we can't find a non-existant class. ASSERT_NO_THROW(cclass = dictionary->findClass("bogus")); EXPECT_FALSE(cclass); + + // Verify that the dictionary was pushed to the CfgMgr's staging config. + SrvConfigPtr staging = CfgMgr::instance().getStagingCfg(); + ASSERT_TRUE(staging); + ClientClassDictionaryPtr staged_dictionary = staging->getClientClassDictionary(); + ASSERT_TRUE(staged_dictionary); + EXPECT_TRUE(*staged_dictionary == *dictionary); } // Verifies that class list containing a duplicate class entries, fails diff --git a/src/lib/dhcpsrv/tests/srv_config_unittest.cc b/src/lib/dhcpsrv/tests/srv_config_unittest.cc index cfd0612a6c..b5108a9b22 100644 --- a/src/lib/dhcpsrv/tests/srv_config_unittest.cc +++ b/src/lib/dhcpsrv/tests/srv_config_unittest.cc @@ -40,7 +40,8 @@ public: /// Creates IPv4 and IPv6 subnets for unit test. The number of subnets /// is @c TEST_SUBNETS_NUM for IPv4 and IPv6 each. SrvConfigTest() - : iface_mgr_test_config_(true) { + : iface_mgr_test_config_(true), + ref_dictionary_(new ClientClassDictionary()) { // Disable DDNS. enableDDNS(false); @@ -69,8 +70,14 @@ public: Subnet6Ptr subnet(new Subnet6(prefix, 64, 1000, 2000, 3000, 4000)); test_subnets6_.push_back(subnet); } + + // Build our reference dictionary of client classes + ref_dictionary_->addClass("cc1", ExpressionPtr(), CfgOptionPtr()); + ref_dictionary_->addClass("cc2", ExpressionPtr(), CfgOptionPtr()); + ref_dictionary_->addClass("cc3", ExpressionPtr(), CfgOptionPtr()); } + /// @brief Destructor. virtual ~SrvConfigTest() { } @@ -118,6 +125,8 @@ public: /// @brief Fakes interface configuration. isc::dhcp::test::IfaceMgrTestConfig iface_mgr_test_config_; + /// @brief Client class dictionary with fixed content + ClientClassDictionaryPtr ref_dictionary_; }; void @@ -239,6 +248,26 @@ TEST_F(SrvConfigTest, summarySubnets) { } +// Verifies that we can get and set the client class dictionary +TEST_F(SrvConfigTest, classDictionaryBasics) { + ClientClassDictionaryPtr d1; + SrvConfig conf(32); + + // Upon construction the dictionary should be empty. + ASSERT_TRUE(d1 = conf.getClientClassDictionary()); + EXPECT_EQ(0, d1->getClasses()->size()); + + // Verify we can replace it with a new dictionary. + ASSERT_NO_THROW(conf.setClientClassDictionary(ref_dictionary_)); + ASSERT_TRUE(d1 = conf.getClientClassDictionary()); + EXPECT_EQ(ref_dictionary_->getClasses()->size(), d1->getClasses()->size()); + + // Verify const fetcher works too. + const ClientClassDictionaryPtr cd = conf.getClientClassDictionary(); + ASSERT_TRUE(cd); + EXPECT_EQ(ref_dictionary_->getClasses()->size(), cd->getClasses()->size()); +} + // This test checks if entire configuration can be copied and that the sequence // number is not affected. TEST_F(SrvConfigTest, copy) { @@ -265,6 +294,9 @@ TEST_F(SrvConfigTest, copy) { OptionPtr option(new Option(Option::V6, 1000, OptionBuffer(10, 0xFF))); conf1.getCfgOption()->add(option, true, "dhcp6"); + // Add a class dictionary + conf1.setClientClassDictionary(ref_dictionary_); + // Make sure both configurations are different. ASSERT_TRUE(conf1 != conf2); @@ -342,6 +374,16 @@ TEST_F(SrvConfigTest, equality) { EXPECT_TRUE(conf1 == conf2); EXPECT_FALSE(conf1 != conf2); + + // Add a class dictionary to conf1 + conf1.setClientClassDictionary(ref_dictionary_); + EXPECT_FALSE(conf1 == conf2); + EXPECT_TRUE(conf1 != conf2); + + // Add same class dictionary to conf2 + conf2.setClientClassDictionary(ref_dictionary_); + EXPECT_TRUE(conf1 == conf2); + EXPECT_FALSE(conf1 != conf2); } } // end of anonymous namespace