]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#717] Added tests for fetching all subnets with server tags.
authorMarcin Siodelski <marcin@isc.org>
Mon, 8 Jul 2019 20:47:35 +0000 (22:47 +0200)
committerMarcin Siodelski <marcin@isc.org>
Fri, 12 Jul 2019 15:58:16 +0000 (11:58 -0400)
src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc
src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp6_unittest.cc
src/lib/dhcpsrv/subnet.h
src/lib/dhcpsrv/tests/subnet_unittest.cc

index 4f793a26a9d339024fc2f7d90fabaa7a647966fb..ac99fe277f01a26eeabb81f7c0c71345ed8a14fa 100644 (file)
@@ -1356,6 +1356,78 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getAllSubnets4) {
     }
 }
 
+// Test that subnets with different server associations are returned.
+TEST_F(MySqlConfigBackendDHCPv4Test, getAllSubnets4WithServerTags) {
+    auto subnet1 = test_subnets_[0];
+    auto subnet2 = test_subnets_[2];
+    auto subnet3 = test_subnets_[3];
+
+    EXPECT_NO_THROW(cbptr_->createUpdateServer4(test_servers_[0]));
+    EXPECT_NO_THROW(cbptr_->createUpdateServer4(test_servers_[2]));
+
+    EXPECT_NO_THROW(cbptr_->createUpdateSubnet4(ServerSelector::ALL(),
+                                                subnet1));
+    EXPECT_NO_THROW(cbptr_->createUpdateSubnet4(ServerSelector::ONE("server1"),
+                                                subnet2));
+    EXPECT_NO_THROW(cbptr_->createUpdateSubnet4(ServerSelector::MULTIPLE({ "server1", "server2" }),
+                                                subnet3));
+
+    Subnet4Collection subnets;
+
+    // All three subnets are associated with the server1.
+    EXPECT_NO_THROW(subnets = cbptr_->getAllSubnets4(ServerSelector::ONE("server1")));
+    EXPECT_EQ(3, subnets.size());
+
+    // First network is associated with all servers.
+    auto returned_subnet = SubnetFetcher4::get(subnets, SubnetID(1024));
+    ASSERT_TRUE(returned_subnet);
+    EXPECT_TRUE(returned_subnet->hasAllServerTag());
+    EXPECT_FALSE(returned_subnet->hasServerTag(ServerTag("server1")));
+    EXPECT_FALSE(returned_subnet->hasServerTag(ServerTag("server2")));
+
+    // Second network is only associated with the server1.
+    returned_subnet = SubnetFetcher4::get(subnets, SubnetID(2048));
+    ASSERT_TRUE(returned_subnet);
+    EXPECT_FALSE(returned_subnet->hasAllServerTag());
+    EXPECT_TRUE(returned_subnet->hasServerTag(ServerTag("server1")));
+    EXPECT_FALSE(returned_subnet->hasServerTag(ServerTag("server2")));
+
+    // Third network is associated with both server1 and server2.
+    returned_subnet = SubnetFetcher4::get(subnets, SubnetID(4096));
+    ASSERT_TRUE(returned_subnet);
+    EXPECT_FALSE(returned_subnet->hasAllServerTag());
+    EXPECT_TRUE(returned_subnet->hasServerTag(ServerTag("server1")));
+    EXPECT_TRUE(returned_subnet->hasServerTag(ServerTag("server2")));
+
+    // For server2 we should only get two shared subnets, i.e. first and last.
+    EXPECT_NO_THROW(subnets = cbptr_->getAllSubnets4(ServerSelector::ONE("server2")));
+    EXPECT_EQ(2, subnets.size());
+
+    // First shared network is associated with all servers.
+    returned_subnet = SubnetFetcher4::get(subnets, SubnetID(1024));
+    ASSERT_TRUE(returned_subnet);
+    EXPECT_TRUE(returned_subnet->hasAllServerTag());
+    EXPECT_FALSE(returned_subnet->hasServerTag(ServerTag("server1")));
+    EXPECT_FALSE(returned_subnet->hasServerTag(ServerTag("server2")));
+
+    // Last shared network is associated with server1 and server2.
+    returned_subnet = SubnetFetcher4::get(subnets, SubnetID(4096));
+    ASSERT_TRUE(returned_subnet);
+    EXPECT_FALSE(returned_subnet->hasAllServerTag());
+    EXPECT_TRUE(returned_subnet->hasServerTag(ServerTag("server1")));
+    EXPECT_TRUE(returned_subnet->hasServerTag(ServerTag("server2")));
+
+    // Only the first shared network is associated with all servers.
+    EXPECT_NO_THROW(subnets = cbptr_->getAllSubnets4(ServerSelector::ALL()));
+    EXPECT_EQ(1, subnets.size());
+
+    returned_subnet = SubnetFetcher4::get(subnets, SubnetID(1024));
+    ASSERT_TRUE(returned_subnet);
+    EXPECT_TRUE(returned_subnet->hasAllServerTag());
+    EXPECT_FALSE(returned_subnet->hasServerTag(ServerTag("server1")));
+    EXPECT_FALSE(returned_subnet->hasServerTag(ServerTag("server2")));
+}
+
 // Test that subnets modified after given time can be fetched.
 TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedSubnets4) {
     // Explicitly set timestamps of subnets. First subnet has a timestamp
index fbd186e31d3c1f4dbff89641ad71491ade254157..0d2999a4c4383cc3b40e2743a9a96bf68cc18d17 100644 (file)
@@ -1374,6 +1374,78 @@ TEST_F(MySqlConfigBackendDHCPv6Test, getAllSubnets6) {
     }
 }
 
+// Test that subnets with different server associations are returned.
+TEST_F(MySqlConfigBackendDHCPv6Test, getAllSubnets6WithServerTags) {
+    auto subnet1 = test_subnets_[0];
+    auto subnet2 = test_subnets_[2];
+    auto subnet3 = test_subnets_[3];
+
+    EXPECT_NO_THROW(cbptr_->createUpdateServer6(test_servers_[0]));
+    EXPECT_NO_THROW(cbptr_->createUpdateServer6(test_servers_[2]));
+
+    EXPECT_NO_THROW(cbptr_->createUpdateSubnet6(ServerSelector::ALL(),
+                                                subnet1));
+    EXPECT_NO_THROW(cbptr_->createUpdateSubnet6(ServerSelector::ONE("server1"),
+                                                subnet2));
+    EXPECT_NO_THROW(cbptr_->createUpdateSubnet6(ServerSelector::MULTIPLE({ "server1", "server2" }),
+                                                subnet3));
+
+    Subnet6Collection subnets;
+
+    // All three subnets are associated with the server1.
+    EXPECT_NO_THROW(subnets = cbptr_->getAllSubnets6(ServerSelector::ONE("server1")));
+    EXPECT_EQ(3, subnets.size());
+
+    // First network is associated with all servers.
+    auto returned_subnet = SubnetFetcher6::get(subnets, SubnetID(1024));
+    ASSERT_TRUE(returned_subnet);
+    EXPECT_TRUE(returned_subnet->hasAllServerTag());
+    EXPECT_FALSE(returned_subnet->hasServerTag(ServerTag("server1")));
+    EXPECT_FALSE(returned_subnet->hasServerTag(ServerTag("server2")));
+
+    // Second network is only associated with the server1.
+    returned_subnet = SubnetFetcher6::get(subnets, SubnetID(2048));
+    ASSERT_TRUE(returned_subnet);
+    EXPECT_FALSE(returned_subnet->hasAllServerTag());
+    EXPECT_TRUE(returned_subnet->hasServerTag(ServerTag("server1")));
+    EXPECT_FALSE(returned_subnet->hasServerTag(ServerTag("server2")));
+
+    // Third network is associated with both server1 and server2.
+    returned_subnet = SubnetFetcher6::get(subnets, SubnetID(4096));
+    ASSERT_TRUE(returned_subnet);
+    EXPECT_FALSE(returned_subnet->hasAllServerTag());
+    EXPECT_TRUE(returned_subnet->hasServerTag(ServerTag("server1")));
+    EXPECT_TRUE(returned_subnet->hasServerTag(ServerTag("server2")));
+
+    // For server2 we should only get two shared subnets, i.e. first and last.
+    EXPECT_NO_THROW(subnets = cbptr_->getAllSubnets6(ServerSelector::ONE("server2")));
+    EXPECT_EQ(2, subnets.size());
+
+    // First shared network is associated with all servers.
+    returned_subnet = SubnetFetcher6::get(subnets, SubnetID(1024));
+    ASSERT_TRUE(returned_subnet);
+    EXPECT_TRUE(returned_subnet->hasAllServerTag());
+    EXPECT_FALSE(returned_subnet->hasServerTag(ServerTag("server1")));
+    EXPECT_FALSE(returned_subnet->hasServerTag(ServerTag("server2")));
+
+    // Last shared network is associated with server1 and server2.
+    returned_subnet = SubnetFetcher6::get(subnets, SubnetID(4096));
+    ASSERT_TRUE(returned_subnet);
+    EXPECT_FALSE(returned_subnet->hasAllServerTag());
+    EXPECT_TRUE(returned_subnet->hasServerTag(ServerTag("server1")));
+    EXPECT_TRUE(returned_subnet->hasServerTag(ServerTag("server2")));
+
+    // Only the first shared network is associated with all servers.
+    EXPECT_NO_THROW(subnets = cbptr_->getAllSubnets6(ServerSelector::ALL()));
+    EXPECT_EQ(1, subnets.size());
+
+    returned_subnet = SubnetFetcher6::get(subnets, SubnetID(1024));
+    ASSERT_TRUE(returned_subnet);
+    EXPECT_TRUE(returned_subnet->hasAllServerTag());
+    EXPECT_FALSE(returned_subnet->hasServerTag(ServerTag("server1")));
+    EXPECT_FALSE(returned_subnet->hasServerTag(ServerTag("server2")));
+}
+
 // Test that subnets modified after given time can be fetched.
 TEST_F(MySqlConfigBackendDHCPv6Test, getModifiedSubnets6) {
     // Explicitly set timestamps of subnets. First subnet has a timestamp
index 9eb720292dc1666eacfb690b00fcb5eb1af66aae..da1284d4de67b1c967d08aeef10d92ba88094740 100644 (file)
@@ -855,6 +855,42 @@ typedef boost::multi_index_container<
     >
 > Subnet6Collection;
 
+/// @brief A class containing static convenience methods to fetch the subnets
+/// from the containers.
+///
+/// @tparam ReturnPtrType Type of the returned object, i.e. @c Subnet4Ptr
+/// or @c Subnet6Ptr.
+/// @tparam CollectionType One of the @c Subnet4Collection or @c Subnet6Collection.
+template<typename ReturnPtrType, typename CollectionType>
+class SubnetFetcher {
+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 SubnetID& subnet_id) {
+        auto& index = collection.template get<SubnetSubnetIdIndexTag>();
+        auto s = index.find(subnet_id);
+        if (s != index.end()) {
+            return (*s);
+        }
+        // No subnet found. Return null pointer.
+        return (ReturnPtrType());
+    }
+};
+
+/// @brief Type of the @c SubnetFetcher used for IPv4.
+using SubnetFetcher4 = SubnetFetcher<Subnet4Ptr, Subnet4Collection>;
+
+/// @brief Type of the @c SubnetFetcher used for IPv6.
+using SubnetFetcher6 = SubnetFetcher<Subnet6Ptr, Subnet6Collection>;
+
+
 //@}
 
 } // end of isc::dhcp namespace
index 65cced7fd9291f0932de89cb1140eadd13db87b3..3f808ddedc93ab87c75243b0694f5c5720d0977a 100644 (file)
@@ -1684,4 +1684,56 @@ TEST(Subnet6Test, lastAllocated) {
     EXPECT_THROW(subnet->setLastAllocated(Lease::TYPE_V4, ia), BadValue);
 }
 
+// This test verifies that the IPv4 subnet can be fetched by id.
+TEST(SubnetFetcherTest, getSubnet4ById) {
+    Subnet4Collection collection;
+
+    // Shared network hasn't been added to the collection. A null pointer should
+    // be returned.
+    auto subnet = SubnetFetcher4::get(collection, SubnetID(1024));
+    EXPECT_FALSE(subnet);
+
+    subnet.reset(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3, 1024));
+    EXPECT_NO_THROW(collection.push_back(subnet));
+
+    subnet.reset(new Subnet4(IOAddress("192.0.3.0"), 24, 1, 2, 3, 2048));
+    EXPECT_NO_THROW(collection.push_back(subnet));
+
+    subnet = SubnetFetcher4::get(collection, SubnetID(1024));
+    ASSERT_TRUE(subnet);
+    EXPECT_EQ(1024, subnet->getID());
+    EXPECT_EQ("192.0.2.0/24", subnet->toText());
+
+    subnet = SubnetFetcher4::get(collection, SubnetID(2048));
+    ASSERT_TRUE(subnet);
+    EXPECT_EQ(2048, subnet->getID());
+    EXPECT_EQ("192.0.3.0/24", subnet->toText());
+}
+
+// This test verifies that the IPv6 subnet can be fetched by id.
+TEST(SubnetFetcherTest, getSubnet6ById) {
+    Subnet6Collection collection;
+
+    // Shared network hasn't been added to the collection. A null pointer should
+    // be returned.
+    auto subnet = SubnetFetcher6::get(collection, SubnetID(1026));
+    EXPECT_FALSE(subnet);
+
+    subnet.reset(new Subnet6(IOAddress("2001:db8:1::"), 64, 1, 2, 3, 4, 1024));
+    EXPECT_NO_THROW(collection.push_back(subnet));
+
+    subnet.reset(new Subnet6(IOAddress("2001:db8:2::"), 64, 1, 2, 3, 4, 2048));
+    EXPECT_NO_THROW(collection.push_back(subnet));
+
+    subnet = SubnetFetcher6::get(collection, SubnetID(1024));
+    ASSERT_TRUE(subnet);
+    EXPECT_EQ(1024, subnet->getID());
+    EXPECT_EQ("2001:db8:1::", subnet->toText());
+
+    subnet = SubnetFetcher6::get(collection, SubnetID(2048));
+    ASSERT_TRUE(subnet);
+    EXPECT_EQ(2048, subnet->getID());
+    EXPECT_EQ("2001:db8:2::", subnet->toText());
+}
+
 };