Commit 6b57b6b5 authored by Thomas Markwalder's avatar Thomas Markwalder

[master] kea-dhcp4 now merges shared-networks from config backend

    Merge branch '399-merge-dhcpv4-shared-networks-fetched-from-the-cb-into-the-configuration'
parents 5e35336e c6cd21d2
...@@ -390,8 +390,7 @@ TEST_F(Dhcp4CBTest, DISABLED_mergeOptions) { ...@@ -390,8 +390,7 @@ TEST_F(Dhcp4CBTest, DISABLED_mergeOptions) {
// This test verifies that externally configured shared-networks are // This test verifies that externally configured shared-networks are
// merged correctly into staging configuration. // merged correctly into staging configuration.
// @todo enable test when SrvConfig can merge shared networks. TEST_F(Dhcp4CBTest, mergeSharedNetworks) {
TEST_F(Dhcp4CBTest, DISABLED_mergeSharedNetworks) {
string base_config = string base_config =
"{ \n" "{ \n"
" \"interfaces-config\": { \n" " \"interfaces-config\": { \n"
...@@ -441,8 +440,10 @@ TEST_F(Dhcp4CBTest, DISABLED_mergeSharedNetworks) { ...@@ -441,8 +440,10 @@ TEST_F(Dhcp4CBTest, DISABLED_mergeSharedNetworks) {
staged_network = networks->getByName("two"); staged_network = networks->getByName("two");
ASSERT_TRUE(staged_network); ASSERT_TRUE(staged_network);
// Subnet3, which is in db2 should not have been merged, since it is // Subnet3, which is in db2 should not have been merged.
// first found, first used? // We queried db1 first and the query returned data. In
// other words, we iterate over the backends, asking for
// data. We use the first data, we find.
staged_network = networks->getByName("three"); staged_network = networks->getByName("three");
ASSERT_FALSE(staged_network); ASSERT_FALSE(staged_network);
} }
......
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2017-2019 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this // License, v. 2.0. If a copy of the MPL was not distributed with this
...@@ -19,6 +19,51 @@ CfgSharedNetworks4::hasNetworkWithServerId(const IOAddress& server_id) const { ...@@ -19,6 +19,51 @@ CfgSharedNetworks4::hasNetworkWithServerId(const IOAddress& server_id) const {
return (network_it != index.cend()); return (network_it != index.cend());
} }
void
CfgSharedNetworks4::merge(const CfgSharedNetworks4& other) {
auto& index = networks_.get<SharedNetworkNameIndexTag>();
// Iterate over the subnets to be merged. They will replace the existing
// subnets with the same id. All new subnets will be inserted into this
// configuration.
auto other_networks = other.getAll();
for (auto other_network = other_networks->begin();
other_network != other_networks->end(); ++other_network) {
// In theory we should drop subnet assignments from "other". The
// idea being those that come from the CB should not have subnets_
// populated. We will quietly throw them away, just in case.
(*other_network)->delAll();
// Check if the other network exists in this config.
auto existing_network = index.find((*other_network)->getName());
if (existing_network != index.end()) {
// Somehow the same instance is in both, skip it.
if (*existing_network == *other_network) {
continue;
}
// Network exists, which means we're updating it.
// First we need to move its subnets to the new
// version of the network.
const Subnet4Collection* subnets = (*existing_network)->getAllSubnets();
Subnet4Collection copy_subnets(*subnets);
for (auto subnet = copy_subnets.cbegin(); subnet != copy_subnets.cend(); ++subnet) {
(*existing_network)->del((*subnet)->getID());
(*other_network)->add(*subnet);
}
// Now we discard the existing copy of the network.
index.erase(existing_network);
}
// Add the new/updated nework.
networks_.push_back(*other_network);
}
}
} // end of namespace isc::dhcp } // end of namespace isc::dhcp
} // end of namespace isc } // end of namespace isc
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2017-2019 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this // License, v. 2.0. If a copy of the MPL was not distributed with this
...@@ -124,7 +124,33 @@ public: ...@@ -124,7 +124,33 @@ public:
/// @return true if there is a network with a specified server identifier. /// @return true if there is a network with a specified server identifier.
bool hasNetworkWithServerId(const asiolink::IOAddress& server_id) const; bool hasNetworkWithServerId(const asiolink::IOAddress& server_id) const;
/// @brief Merges specified shared network configuration into this
/// configuration.
///
/// This method merges networks from the @c other configuration into this
/// configuration. The general rule is that existing networks are replaced
/// by the networks from @c other.
///
/// For each network in @c other, do the following:
///
/// - Any associated subnets are removed. Shared networks retrieved from
/// config backends, do not carry their associated subnets (if any) with
/// them. (Subnet assignments are maintained by subnet merges).
/// - If a shared network of the same name already exists in this
/// configuration:
/// - All of its associated subnets are moved to the "other" network.
/// - The existing network is removed from this configuration.
/// - The "other" network is added to this configuration.
///
/// @warning The merge operation may affect the @c other configuration.
/// Therefore, the caller must not rely on the data held in the @c other
/// object after the call to @c merge. Also, the data held in @c other must
/// not be modified after the call to @c merge because it may affect the
/// merged configuration.
///
/// @param other the shared network configuration to be merged into this
/// configuration.
void merge(const CfgSharedNetworks4& other);
}; };
/// @brief Pointer to the configuration of IPv4 shared networks. /// @brief Pointer to the configuration of IPv4 shared networks.
......
...@@ -56,7 +56,8 @@ CfgSubnets4::del(const ConstSubnet4Ptr& subnet) { ...@@ -56,7 +56,8 @@ CfgSubnets4::del(const ConstSubnet4Ptr& subnet) {
} }
void void
CfgSubnets4::merge(const CfgSubnets4& other) { CfgSubnets4::merge(CfgSharedNetworks4Ptr networks,
const CfgSubnets4& other) {
auto& index = subnets_.get<SubnetSubnetIdIndexTag>(); auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
// Iterate over the subnets to be merged. They will replace the existing // Iterate over the subnets to be merged. They will replace the existing
...@@ -72,55 +73,46 @@ CfgSubnets4::merge(const CfgSubnets4& other) { ...@@ -72,55 +73,46 @@ CfgSubnets4::merge(const CfgSubnets4& other) {
if (subnet_it != index.end()) { if (subnet_it != index.end()) {
// Subnet found. // Subnet found.
auto subnet = *subnet_it; auto existing_subnet = *subnet_it;
// Continue if the merged and existing subnets are the same instance. // If the existing subnet and other subnet
if (subnet == *other_subnet) { // are the same instance skip it.
if (existing_subnet == *other_subnet) {
continue; continue;
} }
// If the merged subnet belongs to a shared network we need to // We're going to replace the existing subnet with the other
// discard this shared network so as it is merged into the existing // version. If it belongs to a shared network, we need
// shared network or left not unassigned if the existing subnet // remove it from that network.
// is unassigned.
SharedNetwork4Ptr other_network;
(*other_subnet)->getSharedNetwork(other_network);
if (other_network) {
other_network->del((*other_subnet)->getID());
}
// Check if the subnet belongs to a shared network.
SharedNetwork4Ptr network; SharedNetwork4Ptr network;
subnet->getSharedNetwork(network); existing_subnet->getSharedNetwork(network);
if (network) { if (network) {
// The subnet belongs to a shared network. The shared network network->del(existing_subnet->getID());
// instance holds a pointer to the subnet so we need to remove
// the existing subnet from the shared network it belongs to.
network->del(subnet->getID());
// The new subnet instance must be added to the existing shared
// network.
network->add(*other_subnet);
} }
// The existing subnet may now be removed. // Now we remove the existing subnet.
index.erase(subnet_it); index.erase(subnet_it);
} }
}
// Make another pass over the merged subnets to add them. Any existing // Add the "other" subnet to the our collection of subnets.
// instances with the same IDs have been removed. subnets_.push_back(*other_subnet);
for (auto other_subnet = other_subnets->begin();
other_subnet != other_subnets->end();
++other_subnet) {
// Continue if the merged and existing subnets are the same instance. // If it belongs to a shared network, find the network and
auto subnet_it = index.find((*other_subnet)->getID()); // add the subnet to it
if ((subnet_it != index.end()) && ((*subnet_it) == (*other_subnet))) { std::string network_name = (*other_subnet)->getSharedNetworkName();
continue; if (!network_name.empty()) {
SharedNetwork4Ptr network = networks->getByName(network_name);
if (network) {
network->add(*other_subnet);
} else {
// This implies the shared-network collection we were given
// is out of sync with the subnets we were given.
isc_throw(InvalidOperation, "Cannot assign subnet ID of "
<< (*other_subnet)->getID()
<< " to shared network: " << network_name
<< ", network does not exist");
}
} }
subnets_.push_back(*other_subnet);
} }
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <asiolink/io_address.h> #include <asiolink/io_address.h>
#include <cc/cfg_to_element.h> #include <cc/cfg_to_element.h>
#include <dhcp/pkt4.h> #include <dhcp/pkt4.h>
#include <dhcpsrv/cfg_shared_networks.h>
#include <dhcpsrv/subnet.h> #include <dhcpsrv/subnet.h>
#include <dhcpsrv/subnet_id.h> #include <dhcpsrv/subnet_id.h>
#include <dhcpsrv/subnet_selector.h> #include <dhcpsrv/subnet_selector.h>
...@@ -55,30 +56,23 @@ public: ...@@ -55,30 +56,23 @@ public:
/// this configuration the subnet from @c other configuration is inserted. /// this configuration the subnet from @c other configuration is inserted.
/// ///
/// The complexity of the merge process stems from the associations between /// The complexity of the merge process stems from the associations between
/// the subnets and shared networks. Although, the subnets in this /// the subnets and shared networks. It is assumed that subnets in @c other
/// configuration are replaced by the subnets from @c other, the existing /// are the authority on their shared network assignments. It is also
/// shared networks should not be affected. The new subnets must be /// assumed that @ networks is the list of shared networks that should be
/// inserted into the exsiting shared networks. The @c CfgSharedNetworks4 /// used in making assignments. The general concept is that the overarching
/// is responsible for merging the shared networks and this merge must /// merge process will first merge shared networks and then pass that list
/// be triggered before the merge of the subnets. Therefore, this method /// of networks into this method. Subnets from @c other are then merged
/// assumes that existing shared networks have been already merged. /// into this configuration as follows:
/// ///
/// These are the rules concerning the shared network associations that /// For each subnet in @c other:
/// this method follows: ///
/// - If there is a subnet in this configuration and it is associated with /// - If a subnet of the same ID already exists in this configuration:
/// a shared network, the shared network is preserved and the new subnet /// -# If it belongs to a shared network, remove it from that network
/// instance (replacing existing one) is associated with it. The old /// -# Remove the subnet from this configuration and discard it
/// subnet instance is removed from the shared network. ///
/// - If there is a subnet in this configuration and it is not associated /// - Add the subnet from @c other to this configuration.
/// with any shared network, the new subnet instance replaces the existing /// - If that subnet is associated to shared network, find that network
/// subnet instance and its association with a shared network is discarded. /// in @ networks and add that subnet to it.
/// As a result, the configuration will contain new subnet instance but
/// not associated with any shared network.
/// - If there is no subnet with the given ID, the new subnet instance is
/// inserted into the configuration and the association with a shared
/// network (if present) will be preserved. As a result, the configuration
/// will hold the instance of the new subnet with the shared network
/// it originally belonged to.
/// ///
/// @warning The merge operation affects the @c other configuration. /// @warning The merge operation affects the @c other configuration.
/// Therefore, the caller must not rely on the data held in the @c other /// Therefore, the caller must not rely on the data held in the @c other
...@@ -86,9 +80,12 @@ public: ...@@ -86,9 +80,12 @@ public:
/// not be modified after the call to @c merge because it may affect the /// not be modified after the call to @c merge because it may affect the
/// merged configuration. /// merged configuration.
/// ///
/// @param networks collection of shared networks that to which assignments
/// should be added. In other words, the list of shared networks that belong
/// to the same SrvConfig instance we are merging into.
/// @param other the subnet configuration to be merged into this /// @param other the subnet configuration to be merged into this
/// configuration. /// configuration.
void merge(const CfgSubnets4& other); void merge(CfgSharedNetworks4Ptr networks, const CfgSubnets4& other);
/// @brief Returns pointer to the collection of all IPv4 subnets. /// @brief Returns pointer to the collection of all IPv4 subnets.
/// ///
......
// Copyright (C) 2017-2018 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2017-2019 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this // License, v. 2.0. If a copy of the MPL was not distributed with this
...@@ -254,18 +254,21 @@ SharedNetwork4::add(const Subnet4Ptr& subnet) { ...@@ -254,18 +254,21 @@ SharedNetwork4::add(const Subnet4Ptr& subnet) {
Impl::add(subnets_, subnet); Impl::add(subnets_, subnet);
// Associate the subnet with this network. // Associate the subnet with this network.
setSharedNetwork(subnet); setSharedNetwork(subnet);
subnet->setSharedNetworkName(name_);
} }
void void
SharedNetwork4::del(const SubnetID& subnet_id) { SharedNetwork4::del(const SubnetID& subnet_id) {
Subnet4Ptr subnet = Impl::del<Subnet4Ptr>(subnets_, subnet_id); Subnet4Ptr subnet = Impl::del<Subnet4Ptr>(subnets_, subnet_id);
clearSharedNetwork(subnet); clearSharedNetwork(subnet);
subnet->setSharedNetworkName("");
} }
void void
SharedNetwork4::delAll() { SharedNetwork4::delAll() {
for (auto subnet = subnets_.cbegin(); subnet != subnets_.cend(); ++subnet) { for (auto subnet = subnets_.cbegin(); subnet != subnets_.cend(); ++subnet) {
clearSharedNetwork(*subnet); clearSharedNetwork(*subnet);
(*subnet)->setSharedNetworkName("");
} }
subnets_.clear(); subnets_.clear();
} }
...@@ -316,12 +319,14 @@ SharedNetwork6::add(const Subnet6Ptr& subnet) { ...@@ -316,12 +319,14 @@ SharedNetwork6::add(const Subnet6Ptr& subnet) {
Impl::add(subnets_, subnet); Impl::add(subnets_, subnet);
// Associate the subnet with this network. // Associate the subnet with this network.
setSharedNetwork(subnet); setSharedNetwork(subnet);
subnet->setSharedNetworkName(name_);
} }
void void
SharedNetwork6::del(const SubnetID& subnet_id) { SharedNetwork6::del(const SubnetID& subnet_id) {
Subnet6Ptr subnet = Impl::del<Subnet6Ptr>(subnets_, subnet_id); Subnet6Ptr subnet = Impl::del<Subnet6Ptr>(subnets_, subnet_id);
clearSharedNetwork(subnet); clearSharedNetwork(subnet);
subnet->setSharedNetworkName("");
} }
void void
......
...@@ -39,7 +39,7 @@ SrvConfig::SrvConfig() ...@@ -39,7 +39,7 @@ SrvConfig::SrvConfig()
decline_timer_(0), echo_v4_client_id_(true), dhcp4o6_port_(0), decline_timer_(0), echo_v4_client_id_(true), dhcp4o6_port_(0),
d2_client_config_(new D2ClientConfig()), d2_client_config_(new D2ClientConfig()),
configured_globals_(Element::createMap()), configured_globals_(Element::createMap()),
cfg_consist_(new CfgConsistency()), cfg_consist_(new CfgConsistency()),
server_tag_("") { server_tag_("") {
} }
...@@ -162,10 +162,18 @@ SrvConfig::merge(const ConfigBase& other) { ...@@ -162,10 +162,18 @@ SrvConfig::merge(const ConfigBase& other) {
ConfigBase::merge(other); ConfigBase::merge(other);
try { try {
/// @todo merge other parts of the configuration here.
const SrvConfig& other_srv_config = dynamic_cast<const SrvConfig&>(other); const SrvConfig& other_srv_config = dynamic_cast<const SrvConfig&>(other);
cfg_subnets4_->merge(*other_srv_config.getCfgSubnets4());
/// We merge objects in order of dependency (real or theoretical).
/// @todo merge globals
/// @todo merge option defs
/// @todo merge options
// Merge shared networks.
cfg_shared_networks4_->merge(*(other_srv_config.getCfgSharedNetworks4()));
/// Merge subnets.
cfg_subnets4_->merge(getCfgSharedNetworks4(), *(other_srv_config.getCfgSubnets4()));
/// @todo merge other parts of the configuration here. /// @todo merge other parts of the configuration here.
......
...@@ -17,6 +17,20 @@ using namespace asiolink; ...@@ -17,6 +17,20 @@ using namespace asiolink;
namespace { namespace {
void checkMergedNetwork(const CfgSharedNetworks4& networks, const std::string& name,
const Triplet<uint32_t>& exp_valid,
const std::vector<SubnetID>& exp_subnets) {
auto network = networks.getByName(name);
ASSERT_TRUE(network) << "expected network: " << name << " not found";
ASSERT_EQ(exp_valid, network->getValid()) << " network valid lifetime wrong";
const Subnet4Collection* subnets = network->getAllSubnets();
ASSERT_EQ(exp_subnets.size(), subnets->size()) << " wrong number of subnets";
for (auto exp_id : exp_subnets) {
ASSERT_TRUE(network->getSubnet(exp_id))
<< " did not find expected subnet: " << exp_id;
}
}
// This test verifies that shared networks can be added to the configruation // This test verifies that shared networks can be added to the configruation
// and retrieved by name. // and retrieved by name.
TEST(CfgSharedNetworks4Test, getByName) { TEST(CfgSharedNetworks4Test, getByName) {
...@@ -158,4 +172,88 @@ TEST(CfgSharedNetworks4Test, unparse) { ...@@ -158,4 +172,88 @@ TEST(CfgSharedNetworks4Test, unparse) {
test::runToElementTest<CfgSharedNetworks4>(expected, cfg); test::runToElementTest<CfgSharedNetworks4>(expected, cfg);
} }
// This test verifies that shared-network configurations are properly merged.
TEST(CfgSharedNetworks4Test, mergeNetworks) {
Subnet4Ptr subnet1(new Subnet4(IOAddress("192.0.1.0"),
26, 1, 2, 100, SubnetID(1)));
Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.0"),
26, 1, 2, 100, SubnetID(2)));
Subnet4Ptr subnet3(new Subnet4(IOAddress("192.0.3.0"),
26, 1, 2, 100, SubnetID(3)));
Subnet4Ptr subnet4(new Subnet4(IOAddress("192.0.4.0"),
26, 1, 2, 100, SubnetID(4)));
// Create network1 and add two subnets to it
SharedNetwork4Ptr network1(new SharedNetwork4("network1"));
network1->setValid(Triplet<uint32_t>(100));
ASSERT_NO_THROW(network1->add(subnet1));
ASSERT_NO_THROW(network1->add(subnet2));
// Create network2 with no subnets.
SharedNetwork4Ptr network2(new SharedNetwork4("network2"));
network2->setValid(Triplet<uint32_t>(200));
// Create network3 with one subnet.
SharedNetwork4Ptr network3(new SharedNetwork4("network3"));
network3->setValid(Triplet<uint32_t>(300));
ASSERT_NO_THROW(network3->add(subnet3));
// Create our "existing" configured networks.
// Add all three networks to the existing config.
CfgSharedNetworks4 cfg_to;
ASSERT_NO_THROW(cfg_to.add(network1));
ASSERT_NO_THROW(cfg_to.add(network2));
ASSERT_NO_THROW(cfg_to.add(network3));
// Merge in an "empty" config. Should have the original config, still intact.
CfgSharedNetworks4 cfg_from;
ASSERT_NO_THROW(cfg_to.merge(cfg_from));
ASSERT_EQ(3, cfg_to.getAll()->size());
ASSERT_NO_FATAL_FAILURE(checkMergedNetwork(cfg_to, "network1", Triplet<uint32_t>(100),
std::vector<SubnetID>{SubnetID(1), SubnetID(2)}));
ASSERT_NO_FATAL_FAILURE(checkMergedNetwork(cfg_to, "network2", Triplet<uint32_t>(200),
std::vector<SubnetID>()));
ASSERT_NO_FATAL_FAILURE(checkMergedNetwork(cfg_to, "network3", Triplet<uint32_t>(300),
std::vector<SubnetID>{SubnetID(3)}));
// Create network1b, this is an "update" of network1
// We'll double the valid time and add subnet4 to it
SharedNetwork4Ptr network1b(new SharedNetwork4("network1"));
network1b->setValid(Triplet<uint32_t>(200));
ASSERT_NO_THROW(network1b->add(subnet4));
// Network2 we will not touch.
// Create network3b, this is an "update" of network3.
// We'll double it's valid time, but leave off the subnet.
SharedNetwork4Ptr network3b(new SharedNetwork4("network3"));
network3b->setValid(Triplet<uint32_t>(600));
// Create our "existing" configured networks.
ASSERT_NO_THROW(cfg_from.add(network1b));
ASSERT_NO_THROW(cfg_from.add(network3b));
ASSERT_NO_THROW(cfg_to.merge(cfg_from));
// Should still have 3 networks.
// Network1 should have doubled its valid lifetime but still only have
// the orignal two subnets. Merge should discard assocations on CB
// subnets and preserve the associations from existing config.
ASSERT_EQ(3, cfg_to.getAll()->size());
ASSERT_NO_FATAL_FAILURE(checkMergedNetwork(cfg_to, "network1", Triplet<uint32_t>(200),
std::vector<SubnetID>{SubnetID(1), SubnetID(2)}));
// No changes to network2.
ASSERT_NO_FATAL_FAILURE(checkMergedNetwork(cfg_to, "network2", Triplet<uint32_t>(200),
std::vector<SubnetID>()));
// Network1 should have doubled its valid lifetime and still subnet3.
ASSERT_NO_FATAL_FAILURE(checkMergedNetwork(cfg_to, "network3", Triplet<uint32_t>(600),
std::vector<SubnetID>{SubnetID(3)}));
}
} // end of anonymous namespace } // end of anonymous namespace
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <dhcp/tests/iface_mgr_test_config.h> #include <dhcp/tests/iface_mgr_test_config.h>
#include <dhcpsrv/parsers/dhcp_parsers.h> #include <dhcpsrv/parsers/dhcp_parsers.h>
#include <dhcpsrv/shared_network.h> #include <dhcpsrv/shared_network.h>
#include <dhcpsrv/cfg_shared_networks.h>
#include <dhcpsrv/cfg_subnets4.h> #include <dhcpsrv/cfg_subnets4.h>
#include <dhcpsrv/shared_network.h> #include <dhcpsrv/shared_network.h>
#include <dhcpsrv/subnet.h> #include <dhcpsrv/subnet.h>
...@@ -32,6 +33,31 @@ using namespace isc::test; ...@@ -32,6 +33,31 @@ using namespace isc::test;
namespace { namespace {
void checkMergedSubnet(CfgSubnets4& cfg_subnets,
const SubnetID exp_subnet_id,
const std::string& prefix,
int exp_valid,
SharedNetwork4Ptr exp_network) {
// The subnet1 should be replaced by subnet4 but the shared network
// should not be affected.
auto subnet = cfg_subnets.getByPrefix(prefix);
ASSERT_TRUE(subnet) << "subnet: " << prefix << " not found";
ASSERT_EQ(exp_subnet_id, subnet->getID()) << "subnet ID is wrong";
ASSERT_EQ(exp_valid, subnet->getValid()) << "subnet valid time is wrong";
SharedNetwork4Ptr shared_network;
subnet->getSharedNetwork(shared_network);
if (exp_network) {
ASSERT_TRUE(shared_network)
<< " expected network: " << exp_network->getName() << " not found";
ASSERT_TRUE(shared_network == exp_network) << " networks do no match";
} else {
ASSERT_FALSE(shared_network) << " unexpected network assignment: "
<< shared_network->getName();
}
}
// This test verifies that specific subnet can be retrieved by specifying // This test verifies that specific subnet can be retrieved by specifying
// subnet identifier or subnet prefix. // subnet identifier or subnet prefix.
TEST(CfgSubnets4Test, getSpecificSubnet) { TEST(CfgSubnets4Test, getSpecificSubnet) {
...@@ -111,110 +137,109 @@ TEST(CfgSubnets4Test, deleteSubnet) { ...@@ -111,110 +137,109 @@ TEST(CfgSubnets4Test, deleteSubnet) {
EXPECT_FALSE(cfg.getByPrefix("192.0.3.0/26")); EXPECT_FALSE(cfg.getByPrefix("192.0.3.0/26"));
} }
// This test verifies that the subnets configuration is properly merged. // This test verifies that subnets configuration is properly merged.
TEST(CfgSubnets4Test, mergeSubnets) { TEST(CfgSubnets4Test, mergeSubnets) {
Subnet4Ptr subnet1(new Subnet4(IOAddress("192.0.1.0"),
26, 1, 2, 100, SubnetID(1)));
Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.0"),
26, 1, 2, 100, SubnetID(2)));
Subnet4Ptr subnet3(new Subnet4(IOAddress("192.0.3.0"),
26, 1, 2, 100, SubnetID(3)));
Subnet4Ptr subnet4(new Subnet4(IOAddress("192.0.4.0"),
26, 1, 2, 100, SubnetID(4)));
// Create the "existing" list of shared networks
CfgSharedNetworks4Ptr networks(new CfgSharedNetworks4());
SharedNetwork4Ptr shared_network1(new SharedNetwork4("shared-network1"));
networks->add(shared_network1);
SharedNetwork4Ptr shared_network2(new SharedNetwork4("shared-network2"));
networks->