void
ClientClassDefListParser::commit() {
- // CfgMgr::instance().setClientClassConfig(local_dictionary_);
+ CfgMgr::instance().getStagingCfg()->setClientClassDictionary(local_dictionary_);
}
} // end of namespace isc::dhcp
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) {
}
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) {
}
// 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
// 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
#include <dhcpsrv/cfg_subnets4.h>
#include <dhcpsrv/cfg_subnets6.h>
#include <dhcpsrv/cfg_mac_source.h>
+#include <dhcpsrv/client_class_def.h>
#include <dhcpsrv/logging_info.h>
#include <cc/data.h>
#include <boost/shared_ptr.hpp>
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
/// @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
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_);
}
// 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
/// 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);
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() {
}
/// @brief Fakes interface configuration.
isc::dhcp::test::IfaceMgrTestConfig iface_mgr_test_config_;
+ /// @brief Client class dictionary with fixed content
+ ClientClassDictionaryPtr ref_dictionary_;
};
void
}
+// 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) {
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);
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