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,
/// 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
/// @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
}
}
});
+
+ // 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.
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());
}
/// 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.
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.
"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 = ?)
// 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.
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,
/// 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
/// @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
}
}
});
+
+ // 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.
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());
}
/// 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.
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.
"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 = ?)
// 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.
}
}
+ /// @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".
#__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__)
#__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__)
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
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.
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
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.
auto tags = selector.getTags();
EXPECT_EQ(1, tags.size());
EXPECT_EQ(1, tags.count(ServerTag("all")));
+ EXPECT_TRUE(selector.amAll());
EXPECT_FALSE(selector.hasMultipleTags());
}
>
> 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
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