Commit ec014713 authored by Marcin Siodelski's avatar Marcin Siodelski

[#99,!176] Added unit test for deleting an option from option space.

parent 81140d6b
......@@ -189,6 +189,43 @@ CfgOption::getAll(const uint32_t vendor_id) const {
return (vendor_options_.getItems(vendor_id));
}
size_t
CfgOption::del(const std::string& option_space, const uint16_t option_code) {
// Check for presence of options.
OptionContainerPtr options = getAll(option_space);
if (!options || options->empty()) {
// There are no options, so there is nothing to do.
return (0);
}
// If this is not top level option we may also need to delete the
// option instance from options encapsulating the particular option
// space.
if ((option_space != DHCP4_OPTION_SPACE) &&
(option_space != DHCP6_OPTION_SPACE)) {
// For each option space name iterate over the existing options.
auto option_space_names = getOptionSpaceNames();
for (auto option_space_from_list : option_space_names) {
// Get all options within the particular option space.
auto options_in_space = getAll(option_space_from_list);
for (auto option_it = options_in_space->begin();
option_it != options_in_space->end();
++option_it) {
// Check if the option encapsulates our option space and
// it does, try to delete our option.
if (option_it->option_ &&
(option_it->option_->getEncapsulatedSpace() == option_space)) {
option_it->option_->delOption(option_code);
}
}
}
}
auto& idx = options->get<1>();
return (idx.erase(option_code));
}
ElementPtr
CfgOption::toElement() const {
// option-data value is a list of maps
......
......@@ -414,30 +414,17 @@ public:
return (*od_itr);
}
/// @brief Deletes option for the specified key and option code.
/// @brief Deletes option for the specified option space and option code.
///
/// The key should be a string, in which case it specifies an option space
/// name, or an uint32_t value, in which case it specifies a vendor
/// identifier.
/// If the option is encapsulated within some non top level option space,
/// it is also deleted from all option instances encapsulating this
/// option space.
///
/// @param key Option space name or vendor identifier.
/// @param option_code Code of the option to be returned.
/// @tparam Selector one of: @c std::string or @c uint32_t
///
/// @return Number of deleted options.
template<typename Selector>
size_t del(const Selector& key, const uint16_t option_code) {
// Check for presence of options.
OptionContainerPtr options = getAll(key);
if (!options || options->empty()) {
// There are no options, so there is nothing to do.
return (0);
}
// Some options present, locate the one we are interested in.
auto& idx = options->get<1>();
return (idx.erase(option_code));
}
size_t del(const std::string& key, const uint16_t option_code);
/// @brief Returns a list of configured option space names.
///
......
......@@ -399,6 +399,48 @@ TEST_F(CfgOptionTest, encapsulate) {
}
}
// This test verifies that an option can be deleted from the configuration.
TEST_F(CfgOptionTest, del) {
CfgOption cfg;
generateEncapsulatedOptions(cfg);
// Append options from "foo" and "bar" space as sub-options and options
// from "foo-subs" and "bar-subs" as sub-options of "foo" and "bar"
// options.
ASSERT_NO_THROW(cfg.encapsulate());
// The option with the code 5 should exist in the option space "foo".
ASSERT_TRUE(cfg.get("foo", 5).option_);
// Because we called "encapsulate", this option should have been
// propagated to the options encapsulating option space "foo".
for (uint16_t code = 1000; code < 1020; ++code) {
OptionDescriptor top_level_option(false);
ASSERT_NO_THROW(top_level_option = cfg.get(DHCP6_OPTION_SPACE, code));
// Make sure that the option with code 5 is there.
ASSERT_TRUE(top_level_option.option_);
ASSERT_TRUE(top_level_option.option_->getOption(5));
}
// Delete option with the code 5 and belonging to option space "foo".
uint64_t deleted_num;
ASSERT_NO_THROW(deleted_num = cfg.del("foo", 5));
EXPECT_EQ(1, deleted_num);
// The option should now be gone from options config.
EXPECT_FALSE(cfg.get("foo", 5).option_);
// Iterate over the options encapsulating "foo" option space. Make sure
// that the option with code 5 is no longer encapsulated by these options.
for (uint16_t code = 1000; code < 1020; ++code) {
OptionDescriptor top_level_option(false);
ASSERT_NO_THROW(top_level_option = cfg.get(DHCP6_OPTION_SPACE, code));
ASSERT_TRUE(top_level_option.option_);
EXPECT_FALSE(top_level_option.option_->getOption(5));
}
}
// This test verifies that single option can be retrieved from the configuration
// using option code and option space.
TEST_F(CfgOptionTest, get) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment