Commit ed777dbd authored by Marcin Siodelski's avatar Marcin Siodelski

[#716,!412] Multiple tags are returned with shared networks.

parent 9447f7b6
......@@ -66,7 +66,6 @@ public:
GET_MODIFIED_SUBNETS4,
GET_SHARED_NETWORK_SUBNETS4,
GET_POOL4_RANGE,
GET_SHARED_NETWORK4_NAME_WITH_TAG,
GET_SHARED_NETWORK4_NAME_NO_TAG,
GET_ALL_SHARED_NETWORKS4,
GET_MODIFIED_SHARED_NETWORKS4,
......@@ -995,6 +994,7 @@ public:
/// Query should order shared networks by id.
///
/// @param index Index of the query to be used.
/// @param server_selector Server selector.
/// @param in_bindings Input bindings specifying selection criteria. The
/// size of the bindings collection must match the number of placeholders
/// in the prepared statement. The input bindings collection must be empty
......@@ -1002,6 +1002,7 @@ public:
/// @param [out] shared_networks Reference to the container where fetched
/// shared networks will be inserted.
void getSharedNetworks4(const StatementIndex& index,
const ServerSelector& server_selector,
const MySqlBindingCollection& in_bindings,
SharedNetwork4Collection& shared_networks) {
// Create output bindings. The order must match that in the prepared
......@@ -1218,6 +1219,13 @@ public:
}
}
});
// Now that we're done fetching the whole network, we have to
// check if it has matching server tags and toss it if it
// doesn't. We skip matching the server tags if we're asking
// for ANY shared network.
auto& sn_index = shared_networks.get<SharedNetworkRandomAccessIndexTag>();
tossNonMatchingElements(server_selector, sn_index);
}
/// @brief Sends query to retrieve single shared network by name.
......@@ -1233,22 +1241,19 @@ public:
if (server_selector.amUnassigned()) {
isc_throw(NotImplemented, "managing configuration for no particular server"
" (unassigned) is unsupported at the moment");
}
MySqlBindingCollection in_bindings;
auto index = GET_SHARED_NETWORK4_NAME_NO_TAG;
if (!server_selector.amAny()) {
auto tag = getServerTag(server_selector, "fetching shared network");
in_bindings.push_back(MySqlBinding::createString(tag));
index = GET_SHARED_NETWORK4_NAME_WITH_TAG;
} else if (server_selector.hasMultipleTags()) {
isc_throw(InvalidOperation, "expected one server tag to be specified"
" while fetching a shared network. Got: "
<< getServerTagsAsText(server_selector));
}
in_bindings.push_back(MySqlBinding::createString(name));
MySqlBindingCollection in_bindings = { MySqlBinding::createString(name) };
auto index = GET_SHARED_NETWORK4_NAME_NO_TAG;
SharedNetwork4Collection shared_networks;
getSharedNetworks4(index, in_bindings, shared_networks);
getSharedNetworks4(GET_SHARED_NETWORK4_NAME_NO_TAG, server_selector, in_bindings,
shared_networks);
return (shared_networks.empty() ? SharedNetwork4Ptr() : *shared_networks.begin());
}
......@@ -1260,15 +1265,9 @@ public:
/// structure where shared networks should be inserted.
void getAllSharedNetworks4(const ServerSelector& server_selector,
SharedNetwork4Collection& shared_networks) {
auto tags = server_selector.getTags();
for (auto tag : tags) {
MySqlBindingCollection in_bindings = {
MySqlBinding::createString(tag.get())
};
getSharedNetworks4(GET_ALL_SHARED_NETWORKS4, in_bindings, shared_networks);
}
MySqlBindingCollection in_bindings;
getSharedNetworks4(GET_ALL_SHARED_NETWORKS4, server_selector, in_bindings,
shared_networks);
}
/// @brief Sends query to retrieve modified shared networks.
......@@ -1280,17 +1279,12 @@ public:
void getModifiedSharedNetworks4(const ServerSelector& server_selector,
const boost::posix_time::ptime& modification_ts,
SharedNetwork4Collection& shared_networks) {
auto tags = server_selector.getTags();
for (auto tag : tags) {
MySqlBindingCollection in_bindings = {
MySqlBinding::createString(tag.get()),
MySqlBinding::createTimestamp(modification_ts)
};
MySqlBindingCollection in_bindings = {
MySqlBinding::createTimestamp(modification_ts)
};
getSharedNetworks4(GET_MODIFIED_SHARED_NETWORKS4, in_bindings,
shared_networks);
}
getSharedNetworks4(GET_MODIFIED_SHARED_NETWORKS4, server_selector, in_bindings,
shared_networks);
}
/// @brief Sends query to insert or update shared network.
......@@ -2030,11 +2024,6 @@ TaggedStatementArray tagged_statements = { {
"ORDER BY p.id, x.option_id"
},
// Select shared network by name and filter by server tag.
{ MySqlConfigBackendDHCPv4Impl::GET_SHARED_NETWORK4_NAME_WITH_TAG,
MYSQL_GET_SHARED_NETWORK4_WITH_TAG(AND n.name = ?)
},
// Select shared network by name without filtering by server tag.
{ MySqlConfigBackendDHCPv4Impl::GET_SHARED_NETWORK4_NAME_NO_TAG,
MYSQL_GET_SHARED_NETWORK4_NO_TAG(WHERE n.name = ?)
......@@ -2042,12 +2031,12 @@ TaggedStatementArray tagged_statements = { {
// Select all shared networks.
{ MySqlConfigBackendDHCPv4Impl::GET_ALL_SHARED_NETWORKS4,
MYSQL_GET_SHARED_NETWORK4_WITH_TAG()
MYSQL_GET_SHARED_NETWORK4_NO_TAG()
},
// Select modified shared networks.
{ MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_SHARED_NETWORKS4,
MYSQL_GET_SHARED_NETWORK4_WITH_TAG(AND n.modification_ts > ?)
MYSQL_GET_SHARED_NETWORK4_NO_TAG(WHERE n.modification_ts > ?)
},
// Retrieves option definition by code and space.
......
......@@ -68,7 +68,6 @@ public:
GET_SHARED_NETWORK_SUBNETS6,
GET_POOL6_RANGE,
GET_PD_POOL,
GET_SHARED_NETWORK6_NAME_WITH_TAG,
GET_SHARED_NETWORK6_NAME_NO_TAG,
GET_ALL_SHARED_NETWORKS6,
GET_MODIFIED_SHARED_NETWORKS6,
......@@ -1197,6 +1196,7 @@ public:
/// Query should order shared networks by id.
///
/// @param index Index of the query to be used.
/// @param server_selector Server selector.
/// @param in_bindings Input bindings specifying selection criteria. The
/// size of the bindings collection must match the number of placeholders
/// in the prepared statement. The input bindings collection must be empty
......@@ -1204,6 +1204,7 @@ public:
/// @param [out] shared_networks Reference to the container where fetched
/// shared networks will be inserted.
void getSharedNetworks6(const StatementIndex& index,
const ServerSelector& server_selector,
const MySqlBindingCollection& in_bindings,
SharedNetwork6Collection& shared_networks) {
// Create output bindings. The order must match that in the prepared
......@@ -1420,6 +1421,13 @@ public:
}
}
});
// Now that we're done fetching the whole network, we have to
// check if it has matching server tags and toss it if it
// doesn't. We skip matching the server tags if we're asking
// for ANY shared network.
auto& sn_index = shared_networks.get<SharedNetworkRandomAccessIndexTag>();
tossNonMatchingElements(server_selector, sn_index);
}
/// @brief Sends query to retrieve single shared network by name.
......@@ -1435,22 +1443,18 @@ public:
if (server_selector.amUnassigned()) {
isc_throw(NotImplemented, "managing configuration for no particular server"
" (unassigned) is unsupported at the moment");
}
MySqlBindingCollection in_bindings;
auto index = GET_SHARED_NETWORK6_NAME_NO_TAG;
if (!server_selector.amAny()) {
auto tag = getServerTag(server_selector, "fetching shared network");
in_bindings.push_back(MySqlBinding::createString(tag));
index = GET_SHARED_NETWORK6_NAME_WITH_TAG;
} else if (server_selector.hasMultipleTags()) {
isc_throw(InvalidOperation, "expected one server tag to be specified"
" while fetching a shared network. Got: "
<< getServerTagsAsText(server_selector));
}
in_bindings.push_back(MySqlBinding::createString(name));
MySqlBindingCollection in_bindings = { MySqlBinding::createString(name) };
auto index = GET_SHARED_NETWORK6_NAME_NO_TAG;
SharedNetwork6Collection shared_networks;
getSharedNetworks6(index, in_bindings, shared_networks);
getSharedNetworks6(index, server_selector, in_bindings, shared_networks);
return (shared_networks.empty() ? SharedNetwork6Ptr() : *shared_networks.begin());
}
......@@ -1462,15 +1466,9 @@ public:
/// structure where shared networks should be inserted.
void getAllSharedNetworks6(const ServerSelector& server_selector,
SharedNetwork6Collection& shared_networks) {
auto tags = server_selector.getTags();
for (auto tag : tags) {
MySqlBindingCollection in_bindings = {
MySqlBinding::createString(tag.get())
};
getSharedNetworks6(GET_ALL_SHARED_NETWORKS6, in_bindings, shared_networks);
}
MySqlBindingCollection in_bindings;
getSharedNetworks6(GET_ALL_SHARED_NETWORKS6, server_selector, in_bindings,
shared_networks);
}
/// @brief Sends query to retrieve modified shared networks.
......@@ -1482,17 +1480,12 @@ public:
void getModifiedSharedNetworks6(const ServerSelector& server_selector,
const boost::posix_time::ptime& modification_ts,
SharedNetwork6Collection& shared_networks) {
auto tags = server_selector.getTags();
for (auto tag : tags) {
MySqlBindingCollection in_bindings = {
MySqlBinding::createString(tag.get()),
MySqlBinding::createTimestamp(modification_ts)
};
MySqlBindingCollection in_bindings = {
MySqlBinding::createTimestamp(modification_ts)
};
getSharedNetworks6(GET_MODIFIED_SHARED_NETWORKS6, in_bindings,
shared_networks);
}
getSharedNetworks6(GET_MODIFIED_SHARED_NETWORKS6, server_selector, in_bindings,
shared_networks);
}
/// @brief Sends query to insert or update shared network.
......@@ -2382,11 +2375,6 @@ TaggedStatementArray tagged_statements = { {
"ORDER BY p.id, x.option_id"
},
// Select shared network by name.
{ MySqlConfigBackendDHCPv6Impl::GET_SHARED_NETWORK6_NAME_WITH_TAG,
MYSQL_GET_SHARED_NETWORK6_WITH_TAG(AND n.name = ?)
},
// Select shared network by name without filtering by server tag.
{ MySqlConfigBackendDHCPv6Impl::GET_SHARED_NETWORK6_NAME_NO_TAG,
MYSQL_GET_SHARED_NETWORK6_NO_TAG(WHERE n.name = ?)
......@@ -2394,12 +2382,12 @@ TaggedStatementArray tagged_statements = { {
// Select all shared networks.
{ MySqlConfigBackendDHCPv6Impl::GET_ALL_SHARED_NETWORKS6,
MYSQL_GET_SHARED_NETWORK6_WITH_TAG()
MYSQL_GET_SHARED_NETWORK6_NO_TAG()
},
// Select modified shared networks.
{ MySqlConfigBackendDHCPv6Impl::GET_MODIFIED_SHARED_NETWORKS6,
MYSQL_GET_SHARED_NETWORK6_WITH_TAG(AND n.modification_ts > ?)
MYSQL_GET_SHARED_NETWORK6_NO_TAG(WHERE n.modification_ts > ?)
},
// Retrieves option definition by code and space.
......
......@@ -669,6 +669,71 @@ public:
}
}
/// @brief Removes configuration elements from the index which don't match
/// the specified server selector.
///
/// This is a generic function which removes configuration elements which
/// don't match the specified selector. In order to fetch all server tags
/// for the returned configuration element, the query must not limit the
/// results to the given server tag. Instead, it must post process the
/// result to eliminate those configuration elements for which the desired
/// server tag wasn't found.
///
/// If the server selector is set to ANY, this method is no-op.
///
/// @tparam CollectionIndex Type of the collection to be processed.
/// @param server_selector Server selector.
/// @param index Reference to the index holding the returned configuration
/// elements to be processed.
template<typename CollectionIndex>
void tossNonMatchingElements(const db::ServerSelector& server_selector,
CollectionIndex& index) {
// Don't filter the matching server tags if the server selector is
// set to ANY.
if (server_selector.amAny()) {
return;
}
// Go over the collection of elements.
for (auto elem = index.begin(); elem != index.end(); ) {
// If we're asking for shared networks matching all servers,
// we have to make sure that the fetched element has "all"
// server tag.
if (server_selector.amAll()) {
if (!(*elem)->hasAllServerTag()) {
// It doesn't so let's remove it.
elem = index.erase(elem);
continue;
}
} else {
// Server selector contains explicit server tags, so
// let's see if the returned elements includes any of
// them.
auto tags = server_selector.getTags();
bool tag_found = false;
for (auto tag : tags) {
if ((*elem)->hasServerTag(tag) ||
(*elem)->hasAllServerTag()) {
tag_found = true;
break;
}
}
if (!tag_found) {
// Tag not matching, so toss the element.
elem = index.erase(elem);
continue;
}
}
// Go to the next element if we didn't toss the current one.
// Otherwise, the erase() function should have already taken
// us to the next one.
++elem;
}
}
/// @brief Returns backend type in the textual format.
///
/// @return "mysql".
......
......@@ -257,9 +257,6 @@ namespace {
#__VA_ARGS__ \
" ORDER BY n.id, s.id, o.option_id"
#define MYSQL_GET_SHARED_NETWORK4_WITH_TAG(...) \
MYSQL_GET_SHARED_NETWORK4_COMMON(WHERE (s.tag = ? OR s.id = 1) __VA_ARGS__)
#define MYSQL_GET_SHARED_NETWORK4_NO_TAG(...) \
MYSQL_GET_SHARED_NETWORK4_COMMON(__VA_ARGS__)
......@@ -313,9 +310,6 @@ namespace {
#__VA_ARGS__ \
" ORDER BY n.id, s.id, o.option_id"
#define MYSQL_GET_SHARED_NETWORK6_WITH_TAG(...) \
MYSQL_GET_SHARED_NETWORK6_COMMON(WHERE (s.tag = ? OR s.id = 1) __VA_ARGS__)
#define MYSQL_GET_SHARED_NETWORK6_NO_TAG(...) \
MYSQL_GET_SHARED_NETWORK6_COMMON(__VA_ARGS__)
......
......@@ -1764,6 +1764,78 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getAllSharedNetworks4) {
EXPECT_TRUE(subnet->getSharedNetworkName().empty());
}
// Test that shared networks with different server associations are returned.
TEST_F(MySqlConfigBackendDHCPv4Test, getAllSharedNetworks4WithServerTags) {
auto shared_network1 = test_networks_[0];
auto shared_network2 = test_networks_[2];
auto shared_network3 = test_networks_[3];
EXPECT_NO_THROW(cbptr_->createUpdateServer4(test_servers_[0]));
EXPECT_NO_THROW(cbptr_->createUpdateServer4(test_servers_[2]));
EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork4(ServerSelector::ALL(),
shared_network1));
EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork4(ServerSelector::ONE("server1"),
shared_network2));
EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork4(ServerSelector::MULTIPLE({ "server1", "server2" }),
shared_network3));
SharedNetwork4Collection networks;
// All three networks are associated with the server1.
EXPECT_NO_THROW(networks = cbptr_->getAllSharedNetworks4(ServerSelector::ONE("server1")));
EXPECT_EQ(3, networks.size());
// First network is associated with all servers.
auto returned_network = SharedNetworkFetcher4::get(networks, "level1");
ASSERT_TRUE(returned_network);
EXPECT_TRUE(returned_network->hasAllServerTag());
EXPECT_FALSE(returned_network->hasServerTag(ServerTag("server1")));
EXPECT_FALSE(returned_network->hasServerTag(ServerTag("server2")));
// Second network is only associated with the server1.
returned_network = SharedNetworkFetcher4::get(networks, "level2");
ASSERT_TRUE(returned_network);
EXPECT_FALSE(returned_network->hasAllServerTag());
EXPECT_TRUE(returned_network->hasServerTag(ServerTag("server1")));
EXPECT_FALSE(returned_network->hasServerTag(ServerTag("server2")));
// Third network is associated with both server1 and server2.
returned_network = SharedNetworkFetcher4::get(networks, "level3");
ASSERT_TRUE(returned_network);
EXPECT_FALSE(returned_network->hasAllServerTag());
EXPECT_TRUE(returned_network->hasServerTag(ServerTag("server1")));
EXPECT_TRUE(returned_network->hasServerTag(ServerTag("server2")));
// For server2 we should only get two shared networks, i.e. first and last.
EXPECT_NO_THROW(networks = cbptr_->getAllSharedNetworks4(ServerSelector::ONE("server2")));
EXPECT_EQ(2, networks.size());
// First shared network is associated with all servers.
returned_network = SharedNetworkFetcher4::get(networks, "level1");
ASSERT_TRUE(returned_network);
EXPECT_TRUE(returned_network->hasAllServerTag());
EXPECT_FALSE(returned_network->hasServerTag(ServerTag("server1")));
EXPECT_FALSE(returned_network->hasServerTag(ServerTag("server2")));
// Last shared network is associated with server1 and server2.
returned_network = SharedNetworkFetcher4::get(networks, "level3");
ASSERT_TRUE(returned_network);
EXPECT_FALSE(returned_network->hasAllServerTag());
EXPECT_TRUE(returned_network->hasServerTag(ServerTag("server1")));
EXPECT_TRUE(returned_network->hasServerTag(ServerTag("server2")));
// Only the first shared network is associated with all servers.
EXPECT_NO_THROW(networks = cbptr_->getAllSharedNetworks4(ServerSelector::ALL()));
EXPECT_EQ(1, networks.size());
returned_network = SharedNetworkFetcher4::get(networks, "level1");
ASSERT_TRUE(returned_network);
EXPECT_TRUE(returned_network->hasAllServerTag());
EXPECT_FALSE(returned_network->hasServerTag(ServerTag("server1")));
EXPECT_FALSE(returned_network->hasServerTag(ServerTag("server2")));
}
// Test that shared networks modified after given time can be fetched.
TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedSharedNetworks4) {
// Explicitly set timestamps of shared networks. First shared
......@@ -1882,13 +1954,12 @@ TEST_F(MySqlConfigBackendDHCPv4Test, deleteSharedNetwork4) {
EXPECT_EQ(1, deleted_count);
EXPECT_FALSE(cbptr_->getSharedNetwork4(server_selector,
shared_network->getName()));
shared_network->getName()));
};
test_delete("all servers", ServerSelector::ALL(), shared_network1);
test_delete("any server", ServerSelector::ANY(), shared_network2);
test_delete("one server", ServerSelector::ONE("server1"), shared_network3);
}
// Test that lifetimes in shared networks are handled as expected.
......
......@@ -1779,6 +1779,78 @@ TEST_F(MySqlConfigBackendDHCPv6Test, getAllSharedNetworks6) {
EXPECT_TRUE(subnet->getSharedNetworkName().empty());
}
// Test that shared networks with different server associations are returned.
TEST_F(MySqlConfigBackendDHCPv6Test, getAllSharedNetworks6WithServerTags) {
auto shared_network1 = test_networks_[0];
auto shared_network2 = test_networks_[2];
auto shared_network3 = test_networks_[3];
EXPECT_NO_THROW(cbptr_->createUpdateServer6(test_servers_[0]));
EXPECT_NO_THROW(cbptr_->createUpdateServer6(test_servers_[2]));
EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork6(ServerSelector::ALL(),
shared_network1));
EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork6(ServerSelector::ONE("server1"),
shared_network2));
EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork6(ServerSelector::MULTIPLE({ "server1", "server2" }),
shared_network3));
SharedNetwork6Collection networks;
// All three networks are associated with the server1.
EXPECT_NO_THROW(networks = cbptr_->getAllSharedNetworks6(ServerSelector::ONE("server1")));
EXPECT_EQ(3, networks.size());
// First network is associated with all servers.
auto returned_network = SharedNetworkFetcher6::get(networks, "level1");
ASSERT_TRUE(returned_network);
EXPECT_TRUE(returned_network->hasAllServerTag());
EXPECT_FALSE(returned_network->hasServerTag(ServerTag("server1")));
EXPECT_FALSE(returned_network->hasServerTag(ServerTag("server2")));
// Second network is only associated with the server1.
returned_network = SharedNetworkFetcher6::get(networks, "level2");
ASSERT_TRUE(returned_network);
EXPECT_FALSE(returned_network->hasAllServerTag());
EXPECT_TRUE(returned_network->hasServerTag(ServerTag("server1")));
EXPECT_FALSE(returned_network->hasServerTag(ServerTag("server2")));
// Third network is associated with both server1 and server2.
returned_network = SharedNetworkFetcher6::get(networks, "level3");
ASSERT_TRUE(returned_network);
EXPECT_FALSE(returned_network->hasAllServerTag());
EXPECT_TRUE(returned_network->hasServerTag(ServerTag("server1")));
EXPECT_TRUE(returned_network->hasServerTag(ServerTag("server2")));
// For server2 we should only get two shared networks, i.e. first and last.
EXPECT_NO_THROW(networks = cbptr_->getAllSharedNetworks6(ServerSelector::ONE("server2")));
EXPECT_EQ(2, networks.size());
// First shared network is associated with all servers.
returned_network = SharedNetworkFetcher6::get(networks, "level1");
ASSERT_TRUE(returned_network);
EXPECT_TRUE(returned_network->hasAllServerTag());
EXPECT_FALSE(returned_network->hasServerTag(ServerTag("server1")));
EXPECT_FALSE(returned_network->hasServerTag(ServerTag("server2")));
// Last shared network is associated with server1 and server2.
returned_network = SharedNetworkFetcher6::get(networks, "level3");
ASSERT_TRUE(returned_network);
EXPECT_FALSE(returned_network->hasAllServerTag());
EXPECT_TRUE(returned_network->hasServerTag(ServerTag("server1")));
EXPECT_TRUE(returned_network->hasServerTag(ServerTag("server2")));
// Only the first shared network is associated with all servers.
EXPECT_NO_THROW(networks = cbptr_->getAllSharedNetworks6(ServerSelector::ALL()));
EXPECT_EQ(1, networks.size());
returned_network = SharedNetworkFetcher6::get(networks, "level1");
ASSERT_TRUE(returned_network);
EXPECT_TRUE(returned_network->hasAllServerTag());
EXPECT_FALSE(returned_network->hasServerTag(ServerTag("server1")));
EXPECT_FALSE(returned_network->hasServerTag(ServerTag("server2")));
}
// Test that shared networks modified after given time can be fetched.
TEST_F(MySqlConfigBackendDHCPv6Test, getModifiedSharedNetworks6) {
// Explicitly set timestamps of shared networks. First shared
......
......@@ -106,6 +106,13 @@ public:
return (getType() == Type::UNASSIGNED);
}
/// @brief Convenience method checking if the server selector is "all".
///
/// @return true if the selector is "all", false otherwise.
bool amAll() const {
return (getType() == Type::ALL);
}
/// @brief Convenience method checking if the server selector is "any".
///
/// @return true if the selector is "any", false otherwise.
......
......@@ -32,6 +32,7 @@ TEST(ServerSelectorTest, all) {
auto tags = selector.getTags();
EXPECT_EQ(1, tags.size());
EXPECT_EQ(1, tags.count(ServerTag("all")));
EXPECT_TRUE(selector.amAll());
EXPECT_FALSE(selector.hasMultipleTags());
}
......
......@@ -455,6 +455,41 @@ typedef boost::multi_index_container<
>
> SharedNetwork6Collection;
/// @brief A class containing static convenience methods to fetch the shared
/// networks from the containers.
///
/// @tparam ReturnPtrType Type of the returned object, i.e. @c SharedNetwork4Ptr
/// or @c SharedNetwork6Ptr.
/// @tparam CollectionType One of the @c SharedNetwork4Collection or
/// @c SharedNetwork6Collection.
template<typename ReturnPtrType, typename CollectionType>
class SharedNetworkFetcher {
public:
/// @brief Fetches shared network by name.
///
/// @param collection Const reference to the collection from which the shared
/// network is to be fetched.
/// @param name Name of the shared network to be fetched.
/// @return Pointer to the fetched shared network or null if no such shared
/// network could be found.
static ReturnPtrType get(const CollectionType& collection, const std::string& name) {
auto& index = collection.template get<SharedNetworkNameIndexTag>();
auto sn = index.find(name);
if (sn != index.end()) {
return (*sn);
}
// No network found. Return null pointer.
return (ReturnPtrType());
}
};
/// @brief Type of the @c SharedNetworkFetcher used for IPv4.
using SharedNetworkFetcher4 = SharedNetworkFetcher<SharedNetwork4Ptr, SharedNetwork4Collection>;
/// @brief Type of the @c SharedNetworkFetcher used for IPv6.
using SharedNetworkFetcher6 = SharedNetworkFetcher<SharedNetwork6Ptr, SharedNetwork6Collection>;
} // end of namespace isc::dhcp
} // end of namespace isc
......
......@@ -1225,5 +1225,53 @@ TEST(SharedNetwork6Test, delAll) {
ASSERT_EQ(0, network->getAllSubnets()->size());
}
// This test verifies that the IPv4 shared network can be fetched by name.
TEST(SharedNetworkFetcherTest, getSharedNetwork4ByName) {
SharedNetwork4Collection collection;
// Shared network hasn't been added to the collection. A null pointer should
// be returned.
auto network = SharedNetworkFetcher4::get(collection, "network1");
EXPECT_FALSE(network);
network.reset(new SharedNetwork4("network1"));
EXPECT_NO_THROW(collection.push_back(network));
network.reset(new SharedNetwork4("network2"));
EXPECT_NO_THROW(collection.push_back(network));
network = SharedNetworkFetcher4::get(collection, "network1");
ASSERT_TRUE(network);
EXPECT_EQ("network1", network->getName());
network = SharedNetworkFetcher4::get(collection, "network2");
ASSERT_TRUE(network);
EXPECT_EQ("network2", network->getName());
}
// This test verifies that the IPv6 shared network can be fetched by name.
TEST(SharedNetworkFetcherTest, getSharedNetwork6ByName) {
SharedNetwork6Collection collection;
// Shared network hasn't been added to the collection. A null pointer should
// be returned.
auto network = SharedNetworkFetcher6::get(collection, "network1");
EXPECT_FALSE(network);
network.reset(new SharedNetwork6("network1"));
EXPECT_NO_THROW(collection.push_back(network));
network.reset(new SharedNetwork6("network2"));
EXPECT_NO_THROW(collection.push_back(network));
network = SharedNetworkFetcher6::get(collection, "network1");
ASSERT_TRUE(network);
EXPECT_EQ("network1", network->getName());
network = SharedNetworkFetcher6::get(collection, "network2");
ASSERT_TRUE(network);
EXPECT_EQ("network2", network->getName());
}
} // end of anonymous namespace
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