]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[710-cb_cmds-add-support-for-server-tags-in-global-options] Completed CB testutils
authorFrancis Dupont <fdupont@isc.org>
Tue, 2 Jul 2019 22:51:55 +0000 (00:51 +0200)
committerFrancis Dupont <fdupont@isc.org>
Tue, 9 Jul 2019 07:30:45 +0000 (09:30 +0200)
src/lib/dhcpsrv/testutils/test_config_backend.h
src/lib/dhcpsrv/testutils/test_config_backend_dhcp4.cc
src/lib/dhcpsrv/testutils/test_config_backend_dhcp6.cc

index 8cffe006aeec55ba0e2cfd49ba0d17b89e100afe..e29d2cce4ce51f6d9a4ec273c94761af5c980888 100644 (file)
@@ -18,6 +18,9 @@ namespace isc {
 namespace dhcp {
 namespace test {
 
+/// @brief Type of pointers to stamped elements.
+typedef boost::shared_ptr<data::StampedElement> StampedElementPtr;
+
 /// @brief Base class for implementing fake backends
 template<typename ConfigBackendType>
 class TestConfigBackend : public ConfigBackendType {
@@ -86,6 +89,40 @@ public:
         return ("");
     }
 
+    /// @brief Copy server tags between two stamped elements.
+    ///
+    /// @param src Pointer to stamped element to copy tags from.
+    /// @param dst Pointer to stamped element to copy tags to.
+    void copyServerTags(const StampedElementPtr& src,
+                        const StampedElementPtr& dst) const {
+        auto tags = src->getServerTags();
+        for (auto tag : tags) {
+            // Until the stamped element tags are in a set (vs a vector)
+            // we have to avoid duplicates.
+            if (dst->hasServerTag(tag)) {
+                continue;
+            }
+            dst->setServerTag(tag.get());
+        }
+    }
+
+    /// @brief Merge server tags for a stamped element and a server selector.
+    ///
+    /// @param elem Stamped element to update.
+    /// @param server_selector Server selector.
+    void mergeServerTags(const StampedElementPtr& elem,
+                         const db::ServerSelector& server_selector) const {
+        auto tags = server_selector.getTags();
+        for (auto tag : tags) {
+            // Until the stamped element tags are in a set (vs a vector)
+            // we have to avoid duplicates.
+            if (elem->hasServerTag(tag)) {
+                continue;
+            }
+            elem->setServerTag(tag.get());
+        }
+    }
+
     /// @brief Fake database connection
     db::DatabaseConnection connection_;
 
index cb92280a1f057f50d53d7786089b9de95972ae8c..5c161fb3f6978d5f729a6646b145be591b644aaa 100644 (file)
@@ -51,8 +51,26 @@ TestConfigBackendDHCPv4::getSubnet4(const db::ServerSelector& /* server_selector
 }
 
 Subnet4Collection
-TestConfigBackendDHCPv4::getAllSubnets4(const db::ServerSelector& /* server_selector */) const {
-    return (subnets_);
+TestConfigBackendDHCPv4::getAllSubnets4(const db::ServerSelector& server_selector) const {
+    auto tags = server_selector.getTags();
+    Subnet4Collection subnets;
+    for (auto subnet : subnets_) {
+        bool got = false;
+        for (auto tag : tags) {
+            if (subnet->hasServerTag(ServerTag(tag))) {
+                subnets.push_back(subnet);
+                got = true;
+                break;
+            }
+        }
+        if (got) {
+            continue;
+        }
+        if (subnet->hasAllServerTag()) {
+            subnets.push_back(subnet);
+        }
+    }
+    return (subnets);
 }
 
 Subnet4Collection
@@ -101,8 +119,26 @@ TestConfigBackendDHCPv4::getSharedNetwork4(const db::ServerSelector& /* server_s
 }
 
 SharedNetwork4Collection
-TestConfigBackendDHCPv4::getAllSharedNetworks4(const db::ServerSelector& /* server_selector */) const{
-    return (shared_networks_);
+TestConfigBackendDHCPv4::getAllSharedNetworks4(const db::ServerSelector& server_selector) const{
+    auto tags = server_selector.getTags();
+    SharedNetwork4Collection shared_networks;
+    for (auto shared_network : shared_networks_) {
+        bool got = false;
+        for (auto tag : tags) {
+            if (shared_network->hasServerTag(ServerTag(tag))) {
+                shared_networks.push_back(shared_network);
+                got = true;
+                break;
+            }
+        }
+        if (got) {
+            continue;
+        }
+        if (shared_network->hasAllServerTag()) {
+            shared_networks.push_back(shared_network);
+        }
+    }
+    return (shared_networks);
 }
 
 SharedNetwork4Collection
@@ -118,9 +154,11 @@ TestConfigBackendDHCPv4::getModifiedSharedNetworks4(const db::ServerSelector& /*
 }
 
 OptionDefinitionPtr
-TestConfigBackendDHCPv4::getOptionDef4(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv4::getOptionDef4(const db::ServerSelector& server_selector,
                                        const uint16_t code,
                                        const std::string& space) const {
+    auto tags = server_selector.getTags();
+    auto candidate = OptionDefinitionPtr();
     const auto& index = option_defs_.get<1>();
     auto option_def_it_pair = index.equal_range(code);
 
@@ -128,59 +166,139 @@ TestConfigBackendDHCPv4::getOptionDef4(const db::ServerSelector& /* server_selec
          option_def_it != option_def_it_pair.second;
          ++option_def_it) {
         if ((*option_def_it)->getOptionSpaceName() == space) {
-            return (*option_def_it);
+            for (auto tag : tags) {
+                if ((*option_def_it)->hasServerTag(ServerTag(tag))) {
+                    return (*option_def_it);
+                }
+            }
+            if ((*option_def_it)->hasAllServerTag()) {
+                candidate = *option_def_it;
+            }
         }
     }
-    return (OptionDefinitionPtr());
+    return (candidate);
 }
 
 OptionDefContainer
-TestConfigBackendDHCPv4::getAllOptionDefs4(const db::ServerSelector& /* server_selector */) const {
-    return (option_defs_);
+TestConfigBackendDHCPv4::getAllOptionDefs4(const db::ServerSelector& server_selector) const {
+    auto tags = server_selector.getTags();
+    OptionDefContainer option_defs;
+    for (auto option_def : option_defs_) {
+        bool got = false;
+        for (auto tag : tags) {
+            if (option_def->hasServerTag(ServerTag(tag))) {
+                option_defs.push_back(option_def);
+                got = true;
+                break;
+            }
+        }
+        if (got) {
+            continue;
+        }
+        if (option_def->hasAllServerTag()) {
+            option_defs.push_back(option_def);
+        }
+    }
+    return (option_defs);
 }
 
 OptionDefContainer
-TestConfigBackendDHCPv4::getModifiedOptionDefs4(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv4::getModifiedOptionDefs4(const db::ServerSelector& server_selector,
                                                 const boost::posix_time::ptime& modification_time) const {
-    const auto& index = option_defs_.get<3>();
+    auto tags = server_selector.getTags();
     OptionDefContainer option_defs;
+    const auto& index = option_defs_.get<3>();
     auto lb = index.lower_bound(modification_time);
     for (auto option_def = lb; option_def != index.end(); ++option_def) {
-        option_defs.push_back(*option_def);
+        bool got = false;
+        for (auto tag : tags) {
+            if ((*option_def)->hasServerTag(ServerTag(tag))) {
+                option_defs.push_back(*option_def);
+                got = true;
+                break;
+            }
+        }
+        if (got) {
+            continue;
+        }
+        if ((*option_def)->hasAllServerTag()) {
+            option_defs.push_back(*option_def);
+        }
     }
     return (option_defs);
 }
 
 OptionDescriptorPtr
-TestConfigBackendDHCPv4::getOption4(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv4::getOption4(const db::ServerSelector& server_selector,
                                     const uint16_t code,
                                     const std::string& space) const {
+    auto tags = server_selector.getTags();
+    auto candidate = OptionDescriptorPtr();
     const auto& index = options_.get<1>();
     auto option_it_pair = index.equal_range(code);
 
     for (auto option_it = option_it_pair.first; option_it != option_it_pair.second;
          ++option_it) {
         if (option_it->space_name_ == space) {
-            return (OptionDescriptorPtr(new OptionDescriptor(*option_it)));
+            for (auto tag : tags) {
+                if (option_it->hasServerTag(ServerTag(tag))) {
+                    return (OptionDescriptorPtr(new OptionDescriptor(*option_it)));
+                }
+            }
+            if (option_it->hasAllServerTag()) {
+                candidate = OptionDescriptorPtr(new OptionDescriptor(*option_it));
+            }
         }
     }
 
-    return (OptionDescriptorPtr());
+    return (candidate);
 }
 
 OptionContainer
-TestConfigBackendDHCPv4::getAllOptions4(const db::ServerSelector& /* server_selector */) const {
-    return (options_);
+TestConfigBackendDHCPv4::getAllOptions4(const db::ServerSelector& server_selector) const {
+    auto tags = server_selector.getTags();
+    OptionContainer options;
+    for (auto option : options_) {
+        bool got = false;
+        for (auto tag : tags) {
+            if (option.hasServerTag(ServerTag(tag))) {
+                options.push_back(option);
+                got = true;
+                break;
+            }
+        }
+        if (got) {
+            continue;
+        }
+        if (option.hasAllServerTag()) {
+            options.push_back(option);
+        }
+    }
+    return (options);
 }
 
 OptionContainer
-TestConfigBackendDHCPv4::getModifiedOptions4(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv4::getModifiedOptions4(const db::ServerSelector& server_selector,
                                              const boost::posix_time::ptime& modification_time) const {
-    const auto& index = options_.get<3>();
+    auto tags = server_selector.getTags();
     OptionContainer options;
+    const auto& index = options_.get<3>();
     auto lb = index.lower_bound(modification_time);
     for (auto option = lb; option != index.end(); ++option) {
-        options.push_back(*option);
+        bool got = false;
+        for (auto tag : tags) {
+            if (option->hasServerTag(ServerTag(tag))) {
+                options.push_back(*option);
+                got = true;
+                break;
+            }
+        }
+        if (got) {
+            continue;
+        }
+        if (option->hasAllServerTag()) {
+            options.push_back(*option);
+        }
     }
     return (options);
 }
@@ -278,15 +396,16 @@ TestConfigBackendDHCPv4::getServer4(const ServerTag& server_tag) const {
 void
 TestConfigBackendDHCPv4::createUpdateSubnet4(const db::ServerSelector& server_selector,
                                              const Subnet4Ptr& subnet) {
-    subnet->setServerTag(getServerTag(server_selector));
-
     auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
     auto subnet_it = index.find(subnet->getID());
 
     if (subnet_it != index.cend()) {
+        copyServerTags(*subnet_it, subnet);
+        mergeServerTags(subnet, server_selector);
         index.replace(subnet_it, subnet);
 
     } else {
+        mergeServerTags(subnet, server_selector);
         index.insert(subnet);
     }
 }
@@ -294,15 +413,16 @@ TestConfigBackendDHCPv4::createUpdateSubnet4(const db::ServerSelector& server_se
 void
 TestConfigBackendDHCPv4::createUpdateSharedNetwork4(const db::ServerSelector& server_selector,
                                                     const SharedNetwork4Ptr& shared_network) {
-    shared_network->setServerTag(getServerTag(server_selector));
-
     auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
     auto network_it = index.find(shared_network->getName());
 
     if (network_it != index.cend()) {
+        copyServerTags(*network_it, shared_network);
+        mergeServerTags(shared_network, server_selector);
         index.replace(network_it, shared_network);
 
     } else {
+        mergeServerTags(shared_network, server_selector);
         index.insert(shared_network);
     }
 }
@@ -310,94 +430,177 @@ TestConfigBackendDHCPv4::createUpdateSharedNetwork4(const db::ServerSelector& se
 void
 TestConfigBackendDHCPv4::createUpdateOptionDef4(const db::ServerSelector& server_selector,
                                                 const OptionDefinitionPtr& option_def) {
-    option_def->setServerTag(getServerTag(server_selector));
-
-    auto& index = option_defs_.get<1>();
-    auto option_def_it = index.find(option_def->getCode());
-
-    if (option_def_it != index.cend()) {
-        index.replace(option_def_it, option_def);
+    auto tag = getServerTag(server_selector);
+    option_def->setServerTag(tag);
+
+    // Index #1 is by option code.
+    auto& index1 = option_defs_.get<1>();
+    auto option_def_it_pair1 = index1.equal_range(option_def->getCode());
+
+    for (auto option_def_it = option_def_it_pair1.first;
+         option_def_it != option_def_it_pair1.second;
+         option_def_it++) {
+        auto existing_option_def = *option_def_it;
+        if ((existing_option_def->getOptionSpaceName() == option_def->getOptionSpaceName()) &&
+            (existing_option_def->hasServerTag(ServerTag(tag)))) {
+            index1.replace(option_def_it, option_def);
+            return;
+        }
+    }
 
-    } else {
-        index.insert(option_def);
+    // Index #2 is by option name.
+    auto& index2 = option_defs_.get<2>();
+    auto option_def_it_pair2 = index2.equal_range(option_def->getName());
+
+    for (auto option_def_it = option_def_it_pair2.first;
+         option_def_it != option_def_it_pair2.second;
+         option_def_it++) {
+        auto existing_option_def = *option_def_it;
+        if ((existing_option_def->getOptionSpaceName() == option_def->getOptionSpaceName()) &&
+            (existing_option_def->hasServerTag(ServerTag(tag)))) {
+            index2.replace(option_def_it, option_def);
+            return;
+        }
     }
+
+    option_defs_.push_back(option_def);
 }
 
 void
 TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& server_selector,
                                              const OptionDescriptorPtr& option) {
-    option->setServerTag(getServerTag(server_selector));
+    auto tag = getServerTag(server_selector);
+    option->setServerTag(tag);
 
     auto& index = options_.get<1>();
-    auto option_it = index.find(option->option_->getType());
-
-    if (option_it != index.end()) {
-        index.replace(option_it, *option);
+    auto option_it_pair = index.equal_range(option->option_->getType());
 
-    } else {
-        index.insert(*option);
+    for (auto option_it = option_it_pair.first;
+         option_it != option_it_pair.second;
+         ++option_it) {
+        if ((option_it->space_name_ == option->space_name_) &&
+            (option_it->hasServerTag(ServerTag(tag)))) {
+            index.replace(option_it, *option);
+            return;
+        }
     }
+
+    options_.push_back(*option);
 }
 
 void
-TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& server_selector,
                                              const std::string& shared_network_name,
                                              const OptionDescriptorPtr& option) {
     auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
     auto network_it = index.find(shared_network_name);
 
-    if (network_it != index.end()) {
-        auto shared_network = *network_it;
-        shared_network->getCfgOption()->del(option->space_name_, option->option_->getType());
-        shared_network->getCfgOption()->add(*option, option->space_name_);
-
-    } else {
+    if (network_it == index.end()) {
         isc_throw(BadValue, "attempted to create or update option in a non existing "
                   "shared network " << shared_network_name);
     }
+
+    auto shared_network = *network_it;
+    if (!shared_network->hasAllServerTag()) {
+        bool found = false;
+        auto tags = server_selector.getTags();
+        for (auto tag : tags) {
+            if (shared_network->hasServerTag(ServerTag(tag))) {
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            isc_throw(BadValue, "attempted to create or update option in a "
+                      "shared network " << shared_network_name
+                      << " not present in a selected server");
+        }
+    }
+
+    shared_network->getCfgOption()->del(option->space_name_, option->option_->getType());
+    shared_network->getCfgOption()->add(*option, option->space_name_);
 }
 
 void
-TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& server_selector,
                                              const SubnetID& subnet_id,
                                              const OptionDescriptorPtr& option) {
     auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
     auto subnet_it = index.find(subnet_id);
 
-    if (subnet_it != index.cend()) {
-        auto subnet = *subnet_it;
-        subnet->getCfgOption()->del(option->space_name_, option->option_->getType());
-        subnet->getCfgOption()->add(*option, option->space_name_);
-
-    } else {
+    if (subnet_it == index.cend()) {
         isc_throw(BadValue, "attempted to create or update option in a non existing "
                   "subnet ID " << subnet_id);
     }
+
+    auto subnet = *subnet_it;
+    if (!subnet->hasAllServerTag()) {
+        bool found = false;
+        auto tags = server_selector.getTags();
+        for (auto tag : tags) {
+            if (subnet->hasServerTag(ServerTag(tag))) {
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            isc_throw(BadValue, "attempted to create or update option in a "
+                      "subnet ID " << subnet_id
+                      << " not present in a selected server");
+        }
+    }
+
+    subnet->getCfgOption()->del(option->space_name_, option->option_->getType());
+    subnet->getCfgOption()->add(*option, option->space_name_);
 }
 
 void
-TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& server_selector,
                                              const asiolink::IOAddress& pool_start_address,
                                              const asiolink::IOAddress& pool_end_address,
                                              const OptionDescriptorPtr& option) {
-    for (auto subnet = subnets_.begin(); subnet != subnets_.end(); ++subnet) {
-        auto pool = (*subnet)->getPool(Lease::TYPE_V4, pool_start_address);
-        if (pool) {
-            pool->getCfgOption()->del(option->space_name_, option->option_->getType());
-            pool->getCfgOption()->add(*option, option->space_name_);
-
-            return;
+    auto tags = server_selector.getTags();
+    auto not_in_tags = false;
+    for (auto subnet : subnets_) {
+        auto pool = subnet->getPool(Lease::TYPE_V4, pool_start_address);
+        if (!pool) {
+            continue;
+        }
+        if (!subnet->hasAllServerTag()) {
+            for (auto tag : tags) {
+                if (subnet->hasServerTag(ServerTag(tag))) {
+                    not_in_tags = true;
+                    break;
+                }
+            }
+            if (not_in_tags) {
+                continue;
+            }
         }
+
+        pool->getCfgOption()->del(option->space_name_, option->option_->getType());
+        pool->getCfgOption()->add(*option, option->space_name_);
+
+        return;
     }
 
-    isc_throw(BadValue, "attempted to create or update option in a non existing "
-              "pool " << pool_start_address << " - " << pool_end_address);
+    if (!not_in_tags) {
+        isc_throw(BadValue, "attempted to create or update option in "
+                  "a non existing pool " << pool_start_address
+                  << " - " << pool_end_address);
+    } else {
+        isc_throw(BadValue, "attempted to create or update option in "
+                  "a pool " << pool_start_address
+                  << " - " << pool_end_address
+                  << " not present in a selected server");
+    }
 }
 
 void
 TestConfigBackendDHCPv4::createUpdateGlobalParameter4(const db::ServerSelector& server_selector,
                                                       const data::StampedValuePtr& value) {
-    value->setServerTag(getServerTag(server_selector));
+    auto tag = getServerTag(server_selector);
+    value->setServerTag(tag);
 
     auto& index = globals_.get<StampedValueNameIndexTag>();
     auto global_it_pair = index.equal_range(value->getName());
@@ -405,7 +608,7 @@ TestConfigBackendDHCPv4::createUpdateGlobalParameter4(const db::ServerSelector&
     for (auto global_it = global_it_pair.first; global_it != global_it_pair.second;
          ++global_it) {
         auto existing_value = *global_it;
-        if (existing_value->hasServerTag(ServerTag(getServerTag(server_selector)))) {
+        if (existing_value->hasServerTag(ServerTag(tag))) {
             index.replace(global_it, value);
             return;
         }
@@ -453,7 +656,7 @@ TestConfigBackendDHCPv4::deleteSharedNetworkSubnets4(const db::ServerSelector& /
                                                      const std::string& shared_network_name) {
     uint64_t cnt = 0;
     auto& index = subnets_.get<SubnetRandomAccessIndexTag>();
-    for (auto subnet = index.begin(); subnet != index.end(); ++subnet) {
+    for (auto subnet = index.begin(); subnet != index.end(); ) {
         SharedNetwork4Ptr network;
         (*subnet)->getSharedNetwork(network);
         if (network && (network->getName() == shared_network_name)) {
@@ -464,6 +667,8 @@ TestConfigBackendDHCPv4::deleteSharedNetworkSubnets4(const db::ServerSelector& /
             ((*subnet)->getSharedNetworkName() == shared_network_name)) {
             subnet = index.erase(subnet);
             ++cnt;
+        } else {
+            ++subnet;
         }
     }
     return (cnt);
@@ -494,39 +699,53 @@ TestConfigBackendDHCPv4::deleteAllSharedNetworks4(const db::ServerSelector& /* s
 }
 
 uint64_t
-TestConfigBackendDHCPv4::deleteOptionDef4(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv4::deleteOptionDef4(const db::ServerSelector& server_selector,
                                           const uint16_t code,
                                           const std::string& space) {
+    auto tag = getServerTag(server_selector);
     uint64_t erased = 0;
-    for (auto option_def_it = option_defs_.begin(); option_def_it != option_defs_.end();
-         ++option_def_it) {
+    for (auto option_def_it = option_defs_.begin(); option_def_it != option_defs_.end(); ) {
         if (((*option_def_it)->getCode() == code) &&
-            ((*option_def_it)->getOptionSpaceName() == space)) {
+            ((*option_def_it)->getOptionSpaceName() == space) &&
+            ((*option_def_it)->hasServerTag(ServerTag(tag)))) {
             option_def_it = option_defs_.erase(option_def_it);
             ++erased;
+        } else {
+            ++option_def_it;
         }
     }
     return (erased);
 }
 
 uint64_t
-TestConfigBackendDHCPv4::deleteAllOptionDefs4(const db::ServerSelector& /* server_selector */) {
-    auto option_defs_size = option_defs_.size();
-    option_defs_.clear();
-    return (option_defs_size);
+TestConfigBackendDHCPv4::deleteAllOptionDefs4(const db::ServerSelector& server_selector) {
+    auto tag = getServerTag(server_selector);
+    uint64_t erased = 0;
+    for (auto option_def_it = option_defs_.begin(); option_def_it != option_defs_.end(); ) {
+        if ((*option_def_it)->hasServerTag(ServerTag(tag))) {
+            option_def_it = option_defs_.erase(option_def_it);
+            ++erased;
+        } else {
+            ++option_def_it;
+        }
+    }
+    return (erased);
 }
 
 uint64_t
-TestConfigBackendDHCPv4::deleteOption4(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv4::deleteOption4(const db::ServerSelector& server_selector,
                                        const uint16_t code,
                                        const std::string& space) {
+    auto tag = getServerTag(server_selector);
     uint64_t erased = 0;
-    for (auto option_it = options_.begin(); option_it != options_.end();
-         ++option_it) {
+    for (auto option_it = options_.begin(); option_it != options_.end(); ) {
         if ((option_it->option_->getType() == code) &&
-            (option_it->space_name_ == space)) {
+            (option_it->space_name_ == space) &&
+            (option_it->hasServerTag(ServerTag(tag)))) {
             option_it = options_.erase(option_it);
             ++erased;
+        } else {
+            ++option_it;
         }
     }
     return (erased);
@@ -588,13 +807,14 @@ TestConfigBackendDHCPv4::deleteOption4(const db::ServerSelector& /* server_selec
 uint64_t
 TestConfigBackendDHCPv4::deleteGlobalParameter4(const db::ServerSelector& server_selector,
                                                 const std::string& name) {
+    auto tag = getServerTag(server_selector);
     auto& index = globals_.get<StampedValueNameIndexTag>();
     auto global_it_pair = index.equal_range(name);
 
     for (auto global_it = global_it_pair.first; global_it != global_it_pair.second;
          ++global_it) {
         auto value = *global_it;
-        if (value->hasServerTag(ServerTag(getServerTag(server_selector)))) {
+        if (value->hasServerTag(ServerTag(tag))) {
             index.erase(global_it);
             return (1);
         }
@@ -604,10 +824,11 @@ TestConfigBackendDHCPv4::deleteGlobalParameter4(const db::ServerSelector& server
 
 uint64_t
 TestConfigBackendDHCPv4::deleteAllGlobalParameters4(const db::ServerSelector& server_selector) {
+    auto tag = getServerTag(server_selector);
     uint64_t cnt = 0;
     for (auto global_it = globals_.begin(); global_it != globals_.end(); ) {
         auto value = *global_it;
-        if (value->hasServerTag(ServerTag(getServerTag(server_selector)))) {
+        if (value->hasServerTag(ServerTag(tag))) {
             global_it = globals_.erase(global_it);
             cnt++;
         } else {
index 787d31f8ebbfe0fc890888a7320fa9dc29b632ef..f4e5561587d434c14358a33de92339f862ff5154 100644 (file)
@@ -50,8 +50,26 @@ TestConfigBackendDHCPv6::getSubnet6(const db::ServerSelector& /* server_selector
 }
 
 Subnet6Collection
-TestConfigBackendDHCPv6::getAllSubnets6(const db::ServerSelector& /* server_selector */) const {
-    return (subnets_);
+TestConfigBackendDHCPv6::getAllSubnets6(const db::ServerSelector& server_selector) const {
+    auto tags = server_selector.getTags();
+    Subnet6Collection subnets;
+    for (auto subnet : subnets_) {
+        bool got = false;
+        for (auto tag : tags) {
+            if (subnet->hasServerTag(ServerTag(tag))) {
+                subnets.push_back(subnet);
+                got = true;
+                break;
+            }
+        }
+        if (got) {
+            continue;
+        }
+        if (subnet->hasAllServerTag()) {
+            subnets.push_back(subnet);
+        }
+    }
+    return (subnets);
 }
 
 Subnet6Collection
@@ -100,8 +118,26 @@ TestConfigBackendDHCPv6::getSharedNetwork6(const db::ServerSelector& /* server_s
 }
 
 SharedNetwork6Collection
-TestConfigBackendDHCPv6::getAllSharedNetworks6(const db::ServerSelector& /* server_selector */) const{
-    return (shared_networks_);
+TestConfigBackendDHCPv6::getAllSharedNetworks6(const db::ServerSelector& server_selector) const{
+    auto tags = server_selector.getTags();
+    SharedNetwork6Collection shared_networks;
+    for (auto shared_network : shared_networks_) {
+        bool got = false;
+        for (auto tag : tags) {
+            if (shared_network->hasServerTag(ServerTag(tag))) {
+                shared_networks.push_back(shared_network);
+                got = true;
+                break;
+            }
+        }
+        if (got) {
+            continue;
+        }
+        if (shared_network->hasAllServerTag()) {
+            shared_networks.push_back(shared_network);
+        }
+    }
+    return (shared_networks);
 }
 
 SharedNetwork6Collection
@@ -117,9 +153,11 @@ TestConfigBackendDHCPv6::getModifiedSharedNetworks6(const db::ServerSelector& /*
 }
 
 OptionDefinitionPtr
-TestConfigBackendDHCPv6::getOptionDef6(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv6::getOptionDef6(const db::ServerSelector& server_selector,
                                        const uint16_t code,
                                        const std::string& space) const {
+    auto tags = server_selector.getTags();
+    auto candidate = OptionDefinitionPtr();
     const auto& index = option_defs_.get<1>();
     auto option_def_it_pair = index.equal_range(code);
 
@@ -127,59 +165,139 @@ TestConfigBackendDHCPv6::getOptionDef6(const db::ServerSelector& /* server_selec
          option_def_it != option_def_it_pair.second;
          ++option_def_it) {
         if ((*option_def_it)->getOptionSpaceName() == space) {
-            return (*option_def_it);
+            for (auto tag : tags) {
+                if ((*option_def_it)->hasServerTag(ServerTag(tag))) {
+                    return (*option_def_it);
+                }
+            }
+            if ((*option_def_it)->hasAllServerTag()) {
+                candidate = *option_def_it;
+            }
         }
     }
-    return (OptionDefinitionPtr());
+    return (candidate);
 }
 
 OptionDefContainer
-TestConfigBackendDHCPv6::getAllOptionDefs6(const db::ServerSelector& /* server_selector */) const {
-    return (option_defs_);
+TestConfigBackendDHCPv6::getAllOptionDefs6(const db::ServerSelector& server_selector) const {
+    auto tags = server_selector.getTags();
+    OptionDefContainer option_defs;
+    for (auto option_def : option_defs_) {
+        bool got = false;
+        for (auto tag : tags) {
+            if (option_def->hasServerTag(ServerTag(tag))) {
+                option_defs.push_back(option_def);
+                got = true;
+                break;
+            }
+        }
+        if (got) {
+            continue;
+        }
+        if (option_def->hasAllServerTag()) {
+            option_defs.push_back(option_def);
+        }
+    }
+    return (option_defs);
 }
 
 OptionDefContainer
-TestConfigBackendDHCPv6::getModifiedOptionDefs6(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv6::getModifiedOptionDefs6(const db::ServerSelector& server_selector,
                                                 const boost::posix_time::ptime& modification_time) const {
-    const auto& index = option_defs_.get<3>();
+    auto tags = server_selector.getTags();
     OptionDefContainer option_defs;
+    const auto& index = option_defs_.get<3>();
     auto lb = index.lower_bound(modification_time);
     for (auto option_def = lb; option_def != index.end(); ++option_def) {
-        option_defs.push_back(*option_def);
+        bool got = false;
+        for (auto tag : tags) {
+            if ((*option_def)->hasServerTag(ServerTag(tag))) {
+                option_defs.push_back(*option_def);
+                got = true;
+                break;
+            }
+        }
+        if (got) {
+            continue;
+        }
+        if ((*option_def)->hasAllServerTag()) {
+            option_defs.push_back(*option_def);
+        }
     }
     return (option_defs);
 }
 
 OptionDescriptorPtr
-TestConfigBackendDHCPv6::getOption6(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv6::getOption6(const db::ServerSelector& server_selector,
                                     const uint16_t code,
                                     const std::string& space) const {
+    auto tags = server_selector.getTags();
+    auto candidate = OptionDescriptorPtr();
     const auto& index = options_.get<1>();
     auto option_it_pair = index.equal_range(code);
 
     for (auto option_it = option_it_pair.first; option_it != option_it_pair.second;
          ++option_it) {
         if (option_it->space_name_ == space) {
-            return (OptionDescriptorPtr(new OptionDescriptor(*option_it)));
+            for (auto tag : tags) {
+                if (option_it->hasServerTag(ServerTag(tag))) {
+                    return (OptionDescriptorPtr(new OptionDescriptor(*option_it)));
+                }
+            }
+            if (option_it->hasAllServerTag()) {
+                candidate = OptionDescriptorPtr(new OptionDescriptor(*option_it));
+            }
         }
     }
 
-    return (OptionDescriptorPtr());
+    return (candidate);
 }
 
 OptionContainer
-TestConfigBackendDHCPv6::getAllOptions6(const db::ServerSelector& /* server_selector */) const {
-    return (options_);
+TestConfigBackendDHCPv6::getAllOptions6(const db::ServerSelector& server_selector) const {
+    auto tags = server_selector.getTags();
+    OptionContainer options;
+    for (auto option : options_) {
+        bool got = false;
+        for (auto tag : tags) {
+            if (option.hasServerTag(ServerTag(tag))) {
+                options.push_back(option);
+                got = true;
+                break;
+            }
+        }
+        if (got) {
+            continue;
+        }
+        if (option.hasAllServerTag()) {
+            options.push_back(option);
+        }
+    }
+    return (options);
 }
 
 OptionContainer
-TestConfigBackendDHCPv6::getModifiedOptions6(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv6::getModifiedOptions6(const db::ServerSelector& server_selector,
                                              const boost::posix_time::ptime& modification_time) const {
-    const auto& index = options_.get<3>();
+    auto tags = server_selector.getTags();
     OptionContainer options;
+    const auto& index = options_.get<3>();
     auto lb = index.lower_bound(modification_time);
     for (auto option = lb; option != index.end(); ++option) {
-        options.push_back(*option);
+        bool got = false;
+        for (auto tag : tags) {
+            if (option->hasServerTag(ServerTag(tag))) {
+                options.push_back(*option);
+                got = true;
+                break;
+            }
+        }
+        if (got) {
+            continue;
+        }
+        if (option->hasAllServerTag()) {
+            options.push_back(*option);
+        }
     }
     return (options);
 }
@@ -277,15 +395,16 @@ TestConfigBackendDHCPv6::getServer6(const ServerTag& server_tag) const {
 void
 TestConfigBackendDHCPv6::createUpdateSubnet6(const db::ServerSelector& server_selector,
                                              const Subnet6Ptr& subnet) {
-    subnet->setServerTag(getServerTag(server_selector));
-
     auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
     auto subnet_it = index.find(subnet->getID());
 
     if (subnet_it != index.cend()) {
+        copyServerTags(*subnet_it, subnet);
+        mergeServerTags(subnet, server_selector);
         index.replace(subnet_it, subnet);
 
     } else {
+        mergeServerTags(subnet, server_selector);
         index.insert(subnet);
     }
 }
@@ -293,15 +412,16 @@ TestConfigBackendDHCPv6::createUpdateSubnet6(const db::ServerSelector& server_se
 void
 TestConfigBackendDHCPv6::createUpdateSharedNetwork6(const db::ServerSelector& server_selector,
                                                     const SharedNetwork6Ptr& shared_network) {
-
-    shared_network->setServerTag(getServerTag(server_selector));
     auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
     auto network_it = index.find(shared_network->getName());
 
     if (network_it != index.cend()) {
+        copyServerTags(*network_it, shared_network);
+        mergeServerTags(shared_network, server_selector);
         index.replace(network_it, shared_network);
 
     } else {
+        mergeServerTags(shared_network, server_selector);
         index.insert(shared_network);
     }
 }
@@ -309,114 +429,219 @@ TestConfigBackendDHCPv6::createUpdateSharedNetwork6(const db::ServerSelector& se
 void
 TestConfigBackendDHCPv6::createUpdateOptionDef6(const db::ServerSelector& server_selector,
                                                 const OptionDefinitionPtr& option_def) {
-    option_def->setServerTag(getServerTag(server_selector));
-
-    auto& index = option_defs_.get<1>();
-    auto option_def_it = index.find(option_def->getCode());
-
-    if (option_def_it != index.cend()) {
-        index.replace(option_def_it, option_def);
+    auto tag = getServerTag(server_selector);
+    option_def->setServerTag(tag);
+
+    // Index #1 is by option code.
+    auto& index1 = option_defs_.get<1>();
+    auto option_def_it_pair1 = index1.equal_range(option_def->getCode());
+
+    for (auto option_def_it = option_def_it_pair1.first;
+         option_def_it != option_def_it_pair1.second;
+         option_def_it++) {
+        auto existing_option_def = *option_def_it;
+        if ((existing_option_def->getOptionSpaceName() == option_def->getOptionSpaceName()) &&
+            (existing_option_def->hasServerTag(ServerTag(tag)))) {
+            index1.replace(option_def_it, option_def);
+            return;
+        }
+    }
 
-    } else {
-        index.insert(option_def);
+    // Index #2 is by option name.
+    auto& index2 = option_defs_.get<2>();
+    auto option_def_it_pair2 = index2.equal_range(option_def->getName());
+
+    for (auto option_def_it = option_def_it_pair2.first;
+         option_def_it != option_def_it_pair2.second;
+         option_def_it++) {
+        auto existing_option_def = *option_def_it;
+        if ((existing_option_def->getOptionSpaceName() == option_def->getOptionSpaceName()) &&
+            (existing_option_def->hasServerTag(ServerTag(tag)))) {
+            index2.replace(option_def_it, option_def);
+            return;
+        }
     }
+
+    option_defs_.push_back(option_def);
 }
 
 void
 TestConfigBackendDHCPv6::createUpdateOption6(const db::ServerSelector& server_selector,
                                              const OptionDescriptorPtr& option) {
-    option->setServerTag(getServerTag(server_selector));
+    auto tag = getServerTag(server_selector);
+    option->setServerTag(tag);
 
     auto& index = options_.get<1>();
-    auto option_it = index.find(option->option_->getType());
+    auto option_it_pair = index.equal_range(option->option_->getType());
 
-    if (option_it != index.end()) {
-        index.replace(option_it, *option);
-
-    } else {
-        index.insert(*option);
+    for (auto option_it = option_it_pair.first;
+         option_it != option_it_pair.second;
+         ++option_it) {
+        if ((option_it->space_name_ == option->space_name_) &&
+            (option_it->hasServerTag(ServerTag(tag)))) {
+            index.replace(option_it, *option);
+            return;
+        }
     }
+
+    options_.push_back(*option);
 }
 
 void
-TestConfigBackendDHCPv6::createUpdateOption6(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv6::createUpdateOption6(const db::ServerSelector& server_selector,
                                              const std::string& shared_network_name,
                                              const OptionDescriptorPtr& option) {
     auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
     auto network_it = index.find(shared_network_name);
 
-    if (network_it != index.end()) {
-        auto shared_network = *network_it;
-        shared_network->getCfgOption()->del(option->space_name_, option->option_->getType());
-        shared_network->getCfgOption()->add(*option, option->space_name_);
-
-    } else {
+    if (network_it == index.end()) {
         isc_throw(BadValue, "attempted to create or update option in a non existing "
                   "shared network " << shared_network_name);
     }
+
+    auto shared_network = *network_it;
+    if (!shared_network->hasAllServerTag()) {
+        bool found = false;
+        auto tags = server_selector.getTags();
+        for (auto tag : tags) {
+            if (shared_network->hasServerTag(ServerTag(tag))) {
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            isc_throw(BadValue, "attempted to create or update option in a "
+                      "shared network " << shared_network_name
+                      << " not present in a selected server");
+        }
+    }
+
+    shared_network->getCfgOption()->del(option->space_name_, option->option_->getType());
+    shared_network->getCfgOption()->add(*option, option->space_name_);
 }
 
 void
-TestConfigBackendDHCPv6::createUpdateOption6(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv6::createUpdateOption6(const db::ServerSelector& server_selector,
                                              const SubnetID& subnet_id,
                                              const OptionDescriptorPtr& option) {
     auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
     auto subnet_it = index.find(subnet_id);
 
-    if (subnet_it != index.cend()) {
-        auto subnet = *subnet_it;
-        subnet->getCfgOption()->del(option->space_name_, option->option_->getType());
-        subnet->getCfgOption()->add(*option, option->space_name_);
-
-    } else {
+    if (subnet_it == index.cend()) {
         isc_throw(BadValue, "attempted to create or update option in a non existing "
                   "subnet ID " << subnet_id);
     }
+
+    auto subnet = *subnet_it;
+    if (!subnet->hasAllServerTag()) {
+        bool found = false;
+        auto tags = server_selector.getTags();
+        for (auto tag : tags) {
+            if (subnet->hasServerTag(ServerTag(tag))) {
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            isc_throw(BadValue, "attempted to create or update option in a "
+                      "subnet ID " << subnet_id
+                      << " not present in a selected server");
+        }
+    }
+
+    subnet->getCfgOption()->del(option->space_name_, option->option_->getType());
+    subnet->getCfgOption()->add(*option, option->space_name_);
 }
 
 void
-TestConfigBackendDHCPv6::createUpdateOption6(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv6::createUpdateOption6(const db::ServerSelector& server_selector,
                                              const asiolink::IOAddress& pool_start_address,
                                              const asiolink::IOAddress& pool_end_address,
                                              const OptionDescriptorPtr& option) {
-    for (auto subnet = subnets_.begin(); subnet != subnets_.end(); ++subnet) {
-        auto pool = (*subnet)->getPool(Lease::TYPE_NA, pool_start_address);
-        if (pool) {
-            pool->getCfgOption()->del(option->space_name_, option->option_->getType());
-            pool->getCfgOption()->add(*option, option->space_name_);
-
-            return;
+    auto tags = server_selector.getTags();
+    auto not_in_tags = false;
+    for (auto subnet : subnets_) {
+        auto pool = subnet->getPool(Lease::TYPE_NA, pool_start_address);
+        if (!pool) {
+            continue;
         }
+        if (!subnet->hasAllServerTag()) {
+            for (auto tag : tags) {
+                if (subnet->hasServerTag(ServerTag(tag))) {
+                    not_in_tags = true;
+                    break;
+                }
+            }
+            if (not_in_tags) {
+                continue;
+            }
+        }
+
+        pool->getCfgOption()->del(option->space_name_, option->option_->getType());
+        pool->getCfgOption()->add(*option, option->space_name_);
+
+        return;
     }
 
-    isc_throw(BadValue, "attempted to create or update option in a non existing "
-              "pool " << pool_start_address << " - " << pool_end_address);
+    if (!not_in_tags) {
+        isc_throw(BadValue, "attempted to create or update option in "
+                  "a non existing pool " << pool_start_address
+                  << " - " << pool_end_address);
+    } else {
+        isc_throw(BadValue, "attempted to create or update option in "
+                  "a pool " << pool_start_address
+                  << " - " << pool_end_address
+                  << " not present in a selected server");
+    }
 }
 
 void
-TestConfigBackendDHCPv6::createUpdateOption6(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv6::createUpdateOption6(const db::ServerSelector& server_selector,
                                              const asiolink::IOAddress& pd_pool_prefix,
                                              const uint8_t pd_pool_prefix_length,
                                              const OptionDescriptorPtr& option) {
-    for (auto subnet = subnets_.begin(); subnet != subnets_.end(); ++subnet) {
-        auto pdpool = (*subnet)->getPool(Lease::TYPE_PD,pd_pool_prefix);
-        if (pdpool) {
-            pdpool->getCfgOption()->del(option->space_name_, option->option_->getType());
-            pdpool->getCfgOption()->add(*option, option->space_name_);
-
-            return;
+    auto tags = server_selector.getTags();
+    auto not_in_tags = false;
+    for (auto subnet : subnets_) {
+        auto pdpool = subnet->getPool(Lease::TYPE_PD, pd_pool_prefix);
+        if (!pdpool) {
+            continue;
         }
+        if (!subnet->hasAllServerTag()) {
+            for (auto tag : tags) {
+                if (subnet->hasServerTag(ServerTag(tag))) {
+                    not_in_tags = true;
+                    break;
+                }
+            }
+            if (not_in_tags) {
+                continue;
+            }
+        }
+
+        pdpool->getCfgOption()->del(option->space_name_, option->option_->getType());
+        pdpool->getCfgOption()->add(*option, option->space_name_);
+
+        return;
     }
 
-    isc_throw(BadValue, "attempted to create or update option in a non existing "
-              "pd pool " << pd_pool_prefix << "/"
-              << static_cast<unsigned>(pd_pool_prefix_length));
+    if (!not_in_tags) {
+        isc_throw(BadValue, "attempted to create or update option in "
+                  "a non existing prefix pool " << pd_pool_prefix
+                  << "/" << static_cast<unsigned>(pd_pool_prefix_length));
+    } else {
+        isc_throw(BadValue, "attempted to create or update option in "
+                  "a prefix pool " << pd_pool_prefix
+                  << "/" << static_cast<unsigned>(pd_pool_prefix_length)
+                  << " not present in a selected server");
+    }
 }
 
 void
 TestConfigBackendDHCPv6::createUpdateGlobalParameter6(const db::ServerSelector& server_selector,
                                                       const data::StampedValuePtr& value) {
-    value->setServerTag(getServerTag(server_selector));
+    auto tag = getServerTag(server_selector);
+    value->setServerTag(tag);
 
     auto& index = globals_.get<StampedValueNameIndexTag>();
     auto global_it_pair = index.equal_range(value->getName());
@@ -424,7 +649,7 @@ TestConfigBackendDHCPv6::createUpdateGlobalParameter6(const db::ServerSelector&
     for (auto global_it = global_it_pair.first; global_it != global_it_pair.second;
          ++global_it) {
         auto existing_value = *global_it;
-        if (existing_value->hasServerTag(ServerTag(getServerTag(server_selector)))) {
+        if (existing_value->hasServerTag(ServerTag(tag))) {
             index.replace(global_it, value);
             return;
         }
@@ -472,7 +697,7 @@ TestConfigBackendDHCPv6::deleteSharedNetworkSubnets6(const db::ServerSelector& /
                                                      const std::string& shared_network_name) {
     uint64_t cnt = 0;
     auto& index = subnets_.get<SubnetRandomAccessIndexTag>();
-    for (auto subnet = index.begin(); subnet != index.end(); ++subnet) {
+    for (auto subnet = index.begin(); subnet != index.end(); ) {
         SharedNetwork6Ptr network;
         (*subnet)->getSharedNetwork(network);
         if (network && (network->getName() == shared_network_name)) {
@@ -483,6 +708,8 @@ TestConfigBackendDHCPv6::deleteSharedNetworkSubnets6(const db::ServerSelector& /
             ((*subnet)->getSharedNetworkName() == shared_network_name)) {
             subnet = index.erase(subnet);
             ++cnt;
+        } else {
+            ++subnet;
         }
     }
     return (cnt);
@@ -513,39 +740,53 @@ TestConfigBackendDHCPv6::deleteAllSharedNetworks6(const db::ServerSelector& /* s
 }
 
 uint64_t
-TestConfigBackendDHCPv6::deleteOptionDef6(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv6::deleteOptionDef6(const db::ServerSelector& server_selector,
                                           const uint16_t code,
                                           const std::string& space) {
+    auto tag = getServerTag(server_selector);
     uint64_t erased = 0;
-    for (auto option_def_it = option_defs_.begin(); option_def_it != option_defs_.end();
-         ++option_def_it) {
+    for (auto option_def_it = option_defs_.begin(); option_def_it != option_defs_.end(); ) {
         if (((*option_def_it)->getCode() == code) &&
-            ((*option_def_it)->getOptionSpaceName() == space)) {
+            ((*option_def_it)->getOptionSpaceName() == space) &&
+            ((*option_def_it)->hasServerTag(ServerTag(tag)))) {
             option_def_it = option_defs_.erase(option_def_it);
             ++erased;
+        } else {
+            ++option_def_it;
         }
     }
     return (erased);
 }
 
 uint64_t
-TestConfigBackendDHCPv6::deleteAllOptionDefs6(const db::ServerSelector& /* server_selector */) {
-    auto option_defs_size = option_defs_.size();
-    option_defs_.clear();
-    return (option_defs_size);
+TestConfigBackendDHCPv6::deleteAllOptionDefs6(const db::ServerSelector& server_selector) {
+    auto tag = getServerTag(server_selector);
+    uint64_t erased = 0;
+    for (auto option_def_it = option_defs_.begin(); option_def_it != option_defs_.end(); ) {
+        if ((*option_def_it)->hasServerTag(ServerTag(tag))) {
+            option_def_it = option_defs_.erase(option_def_it);
+            ++erased;
+        } else {
+            ++option_def_it;
+        }
+    }
+    return (erased);
 }
 
 uint64_t
-TestConfigBackendDHCPv6::deleteOption6(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv6::deleteOption6(const db::ServerSelector& server_selector,
                                        const uint16_t code,
                                        const std::string& space) {
+    auto tag = getServerTag(server_selector);
     uint64_t erased = 0;
-    for (auto option_it = options_.begin(); option_it != options_.end();
-         ++option_it) {
+    for (auto option_it = options_.begin(); option_it != options_.end(); ) {
         if ((option_it->option_->getType() == code) &&
-            (option_it->space_name_ == space)) {
+            (option_it->space_name_ == space) &&
+            (option_it->hasServerTag(ServerTag(tag)))) {
             option_it = options_.erase(option_it);
             ++erased;
+        } else {
+            ++option_it;
         }
     }
     return (erased);
@@ -625,13 +866,14 @@ TestConfigBackendDHCPv6::deleteOption6(const db::ServerSelector& /* server_selec
 uint64_t
 TestConfigBackendDHCPv6::deleteGlobalParameter6(const db::ServerSelector& server_selector,
                                                 const std::string& name) {
+    auto tag = getServerTag(server_selector);
     auto& index = globals_.get<StampedValueNameIndexTag>();
     auto global_it_pair = index.equal_range(name);
 
     for (auto global_it = global_it_pair.first; global_it != global_it_pair.second;
          ++global_it) {
         auto value = *global_it;
-        if (value->hasServerTag(ServerTag(getServerTag(server_selector)))) {
+        if (value->hasServerTag(ServerTag(tag))) {
             index.erase(global_it);
             return (1);
         }
@@ -641,10 +883,11 @@ TestConfigBackendDHCPv6::deleteGlobalParameter6(const db::ServerSelector& server
 
 uint64_t
 TestConfigBackendDHCPv6::deleteAllGlobalParameters6(const db::ServerSelector& server_selector) {
+    auto tag = getServerTag(server_selector);
     uint64_t cnt = 0;
     for (auto global_it = globals_.begin(); global_it != globals_.end(); ) {
         auto value = *global_it;
-        if (value->hasServerTag(ServerTag(getServerTag(server_selector)))) {
+        if (value->hasServerTag(ServerTag(tag))) {
             global_it = globals_.erase(global_it);
             cnt++;
         } else {