]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5585] v6 Memfile support complete
authorThomas Markwalder <tmark@isc.org>
Thu, 12 Apr 2018 13:57:44 +0000 (09:57 -0400)
committerThomas Markwalder <tmark@isc.org>
Thu, 12 Apr 2018 13:57:44 +0000 (09:57 -0400)
src/lib/dhcpsrv/memfile_lease_mgr.*
    Added:
    - MemfileLeaseStatsQuery6(Lease6Storage& storage6, const SubnetID& subnet_id)
    - MemfileLeaseStatsQuery6(Lease6Storage& storage6, const SubnetID& first_subnet_id,
                            const SubnetID& last_subnet_id)
    - Memfile_LeaseMgr::startSubnetLeaseStatsQuery6()
    - Memfile_LeaseMgr::startSubnetRangeLeaseStatsQuery6()

    MemfileLeaseStatsQuery6()::start() - modified to set lower/upper bounds based
    on select mode

src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.*
    GenericLeaseMgrTest::testLeaseStatsQuery6() - new test to check v6 variants

src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc
    TEST_F(MemfileLeaseMgrTest, leaseStatsQuery6)

src/lib/dhcpsrv/memfile_lease_mgr.cc
src/lib/dhcpsrv/memfile_lease_mgr.h
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h
src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc

index 5c2de6e5fb442275051a49b661ae0649468c6a86..6e9421d04896f2ecb559f0dc1fc7c32f5cdca36d 100644 (file)
@@ -461,6 +461,24 @@ public:
         : MemfileLeaseStatsQuery(), storage6_(storage6) {
     };
 
+    /// @brief Constructor for a single subnet query
+    ///
+    /// @param storage6 A pointer to the v6 lease storage to be counted
+    /// @param subnet_id ID of the desired subnet
+    MemfileLeaseStatsQuery6(Lease6Storage& storage6, const SubnetID& subnet_id)
+        : MemfileLeaseStatsQuery(subnet_id), storage6_(storage6) {
+    };
+
+    /// @brief Constructor for a subnet range query
+    ///
+    /// @param storage6 A pointer to the v6 lease storage to be counted
+    /// @param first_subnet_id ID of the first subnet in the desired range
+    /// @param last_subnet_id ID of the last subnet in the desired range
+    MemfileLeaseStatsQuery6(Lease6Storage& storage6, const SubnetID& first_subnet_id,
+                            const SubnetID& last_subnet_id)
+        : MemfileLeaseStatsQuery(first_subnet_id, last_subnet_id), storage6_(storage6) {
+    };
+
     /// @brief Destructor
     virtual ~MemfileLeaseStatsQuery6() {};
 
@@ -482,6 +500,31 @@ public:
         const Lease6StorageSubnetIdIndex& idx
             = storage6_.get<SubnetIdIndexTag>();
 
+        // Set lower and upper bounds based on select mode
+        Lease6StorageSubnetIdIndex::const_iterator lower;
+        Lease6StorageSubnetIdIndex::const_iterator upper;
+        switch (getSelectMode()) {
+        case ALL_SUBNETS:
+            lower = idx.begin();
+            upper = idx.end();
+            break;
+
+        case SINGLE_SUBNET:
+            lower = idx.lower_bound(getFirstSubnetID());
+            upper = idx.upper_bound(getFirstSubnetID());
+            break;
+
+        case SUBNET_RANGE:
+            lower = idx.lower_bound(getFirstSubnetID());
+            upper = idx.upper_bound(getLastSubnetID());
+            break;
+        }
+
+        // Return an empty set if there are no rows.
+        if (lower == upper) {
+            return;
+        }
+
         // Iterate over the leases in order by subnet, accumulating per
         // subnet counts for each state of interest.  As we finish each
         // subnet, add the appropriate rows to our result set.
@@ -489,10 +532,8 @@ public:
         int64_t assigned = 0;
         int64_t declined = 0;
         int64_t assigned_pds = 0;
-
-        for(Lease6StorageSubnetIdIndex::const_iterator lease = idx.begin();
-            lease != idx.end(); ++lease) {
-
+        for(Lease6StorageSubnetIdIndex::const_iterator lease = lower;
+            lease != upper; ++lease) {
             // If we've hit the next subnet, add rows for the current subnet
             // and wipe the accumulators
             if ((*lease)->subnet_id_ != cur_id) {
@@ -536,17 +577,12 @@ public:
         }
 
         // Make the rows for last subnet, unless there were no rows
-        if (idx.begin() != idx.end()) {
-            rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_NA,
-                                          Lease::STATE_DEFAULT,
-                                          assigned));
-            rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_NA,
-                                          Lease::STATE_DECLINED,
-                                          declined));
-            rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_PD,
-                                          Lease::STATE_DEFAULT,
-                                          assigned_pds));
-        }
+        rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_NA,
+                                      Lease::STATE_DEFAULT, assigned));
+        rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_NA,
+                                      Lease::STATE_DECLINED, declined));
+        rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_PD,
+                                      Lease::STATE_DEFAULT, assigned_pds));
 
         // Set the next row position to the beginning of the rows.
         next_pos_ = rows_.begin();
@@ -1444,7 +1480,6 @@ Memfile_LeaseMgr::startLeaseStatsQuery6() {
     return(query);
 }
 
-#if 0
 LeaseStatsQueryPtr
 Memfile_LeaseMgr::startSubnetLeaseStatsQuery6(const SubnetID& subnet_id) {
     LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery6(storage6_, subnet_id));
@@ -1455,12 +1490,11 @@ Memfile_LeaseMgr::startSubnetLeaseStatsQuery6(const SubnetID& subnet_id) {
 LeaseStatsQueryPtr
 Memfile_LeaseMgr::startSubnetRangeLeaseStatsQuery6(const SubnetID& first_subnet_id,
                                                    const SubnetID& last_subnet_id) {
-    LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery4(storage6_, first_subnet_id,
+    LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery6(storage6_, first_subnet_id,
                                                          last_subnet_id));
     query->start();
     return(query);
 }
-#endif
 
 size_t Memfile_LeaseMgr::wipeLeases4(const SubnetID& subnet_id) {
     LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_WIPE_LEASES4)
index 98d9395e58a855b499df8294119d1d49cfac2b63..3a352beb5de734945c9370aafa6e0e6b80500ebd 100644 (file)
@@ -676,7 +676,6 @@ public:
     /// @return The populated query as a pointer to an LeaseStatsQuery.
     virtual LeaseStatsQueryPtr startLeaseStatsQuery6();
 
-#if 0
     /// @brief Creates and runs the IPv6 lease stats query for a single subnet
     ///
     /// It creates an instance of a MemfileLeaseStatsQuery6 for a single subnet
@@ -698,7 +697,6 @@ public:
     /// @return A populated LeaseStatsQuery
     virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery6(const SubnetID& first_subnet_id,
                                                                 const SubnetID& last_subnet_id);
-#endif
 
     /// @name Protected methods used for %Lease File Cleanup.
     /// The following methods are protected so as they can be accessed and
index a9f3f6253ab7bc136ddedb96192346c8141fbf07..5ce6c485c27d18d32d1facb0ec2ff1d92a7444bf 100644 (file)
@@ -2996,6 +2996,155 @@ GenericLeaseMgrTest::testLeaseStatsQuery4() {
     }
 }
 
+void
+GenericLeaseMgrTest::testLeaseStatsQuery6() {
+    // Create three subnets.
+    int num_subnets = 3;
+
+    CfgSubnets6Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets6();
+    Subnet6Ptr subnet;
+    Pool6Ptr pool;
+
+    int subnet_id = 1;
+    subnet.reset(new Subnet6(IOAddress("3001:1::"), 64, 1, 2, 3, 4, subnet_id));
+    pool.reset(new Pool6(Lease::TYPE_NA, IOAddress("3001:1::"),
+                         IOAddress("3001:1::FF")));
+    subnet->addPool(pool);
+
+    pool.reset(new Pool6(Lease::TYPE_PD, IOAddress("3001:1:2::"),96,112));
+    subnet->addPool(pool);
+    cfg->add(subnet);
+
+    ++subnet_id;
+    subnet.reset(new Subnet6(IOAddress("2001:db8:1::"), 64, 1, 2, 3, 4,
+                             subnet_id));
+    pool.reset(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1::"), 120));
+    subnet->addPool(pool);
+    cfg->add(subnet);
+
+    ++subnet_id;
+    subnet.reset(new Subnet6(IOAddress("2002:db8:1::"), 64, 1, 2, 3, 4,
+                             subnet_id));
+    pool.reset(new Pool6(Lease::TYPE_NA, IOAddress("2002:db8:1::"), 120));
+    subnet->addPool(pool);
+    cfg->add(subnet);
+
+    ASSERT_NO_THROW(CfgMgr::instance().commit());
+
+    // Make sure invalid values throw.
+    LeaseStatsQueryPtr query;
+    ASSERT_THROW(query = lmptr_->startSubnetLeaseStatsQuery6(0), BadValue);
+    ASSERT_THROW(query = lmptr_->startSubnetRangeLeaseStatsQuery6(0,1), BadValue);
+    ASSERT_THROW(query = lmptr_->startSubnetRangeLeaseStatsQuery6(1,0), BadValue);
+    ASSERT_THROW(query = lmptr_->startSubnetRangeLeaseStatsQuery6(10,1), BadValue);
+
+    // Start tests with an empty expected row set.
+    RowSet expected_rows;
+
+    // Before we add leases, test an empty return for get all subnets
+    {
+        SCOPED_TRACE("GET ALL WITH NO LEASES");
+        ASSERT_NO_THROW(query = lmptr_->startLeaseStatsQuery6());
+        checkQueryAgainstRowSet(query, expected_rows);
+    }
+
+
+    // Now let's insert some leases into subnet 1.
+    // Three assigned NAs.
+    // Two declined NAs.
+    // One expired NA.
+    // Two assigned PDs.
+    // Two expired PDs.
+    subnet_id = 1;
+    makeLease6(Lease::TYPE_NA, "3001:1::1", 0, subnet_id);
+    makeLease6(Lease::TYPE_NA, "3001:1::2", 0, subnet_id);
+    makeLease6(Lease::TYPE_NA, "3001:1::3", 0, subnet_id);
+    makeLease6(Lease::TYPE_NA, "3001:1::4", 0, subnet_id,
+               Lease::STATE_DECLINED);
+    makeLease6(Lease::TYPE_NA, "3001:1::5", 0, subnet_id,
+               Lease::STATE_DECLINED);
+    makeLease6(Lease::TYPE_NA, "3001:1::6", 0, subnet_id,
+               Lease::STATE_EXPIRED_RECLAIMED);
+    makeLease6(Lease::TYPE_PD, "3001:1:2:0100::", 112, subnet_id);
+    makeLease6(Lease::TYPE_PD, "3001:1:2:0200::", 112, subnet_id);
+    makeLease6(Lease::TYPE_PD, "3001:1:2:0300::", 112, subnet_id,
+               Lease::STATE_EXPIRED_RECLAIMED);
+    makeLease6(Lease::TYPE_PD, "3001:1:2:0400::", 112, subnet_id,
+               Lease::STATE_EXPIRED_RECLAIMED);
+
+    // Now let's add leases to subnet 2.
+    // Two assigned NAs
+    // One declined NAs
+    subnet_id = 2;
+    makeLease6(Lease::TYPE_NA, "2001:db81::1", 0, subnet_id);
+    makeLease6(Lease::TYPE_NA, "2001:db81::2", 0, subnet_id);
+    makeLease6(Lease::TYPE_NA, "2001:db81::3", 0, subnet_id,
+               Lease::STATE_DECLINED);
+
+    // Now let's add leases to subnet 3.
+    // Two assigned NAs
+    // One declined NAs
+    subnet_id = 3;
+    makeLease6(Lease::TYPE_NA, "2002:db81::1", 0, subnet_id);
+    makeLease6(Lease::TYPE_NA, "2002:db81::2", 0, subnet_id);
+    makeLease6(Lease::TYPE_NA, "2002:db81::3", 0, subnet_id,
+               Lease::STATE_DECLINED);
+
+    // Test single subnet for non-matching subnet
+    {
+        SCOPED_TRACE("NO MATCHING SUBNET");
+        ASSERT_NO_THROW(query = lmptr_->startSubnetLeaseStatsQuery6(777));
+        checkQueryAgainstRowSet(query, expected_rows);
+    }
+
+    // Test an empty range
+    {
+        SCOPED_TRACE("EMPTY SUBNET RANGE");
+        ASSERT_NO_THROW(query = lmptr_->startSubnetRangeLeaseStatsQuery6(777, 900));
+        checkQueryAgainstRowSet(query, expected_rows);
+    }
+
+    // Test a single subnet
+    {
+        SCOPED_TRACE("SINGLE SUBNET");
+        // Add expected row for Subnet 2
+        expected_rows.insert(LeaseStatsRow(2, Lease::TYPE_NA, Lease::STATE_DEFAULT, 2));
+        expected_rows.insert(LeaseStatsRow(2, Lease::TYPE_NA, Lease::STATE_DECLINED, 1));
+        expected_rows.insert(LeaseStatsRow(2, Lease::TYPE_PD, Lease::STATE_DEFAULT, 0));
+        // Start the query
+        ASSERT_NO_THROW(query = lmptr_->startSubnetLeaseStatsQuery6(2));
+        // Verify contents
+        checkQueryAgainstRowSet(query, expected_rows);
+    }
+
+    // Test a range of subnets
+    {
+        SCOPED_TRACE("SUBNET RANGE");
+        // Add expected rows for Subnet 3
+        expected_rows.insert(LeaseStatsRow(3, Lease::TYPE_NA, Lease::STATE_DEFAULT, 2));
+        expected_rows.insert(LeaseStatsRow(3, Lease::TYPE_NA, Lease::STATE_DECLINED, 1));
+        expected_rows.insert(LeaseStatsRow(3, Lease::TYPE_PD, Lease::STATE_DEFAULT, 0));
+        // Start the query
+        ASSERT_NO_THROW(query = lmptr_->startSubnetRangeLeaseStatsQuery6(2,3));
+        // Verify contents
+        checkQueryAgainstRowSet(query, expected_rows);
+    }
+
+    // Test all subnets
+    {
+        SCOPED_TRACE("ALL SUBNETS");
+        // Add expected rows for Subnet 1
+        expected_rows.insert(LeaseStatsRow(1, Lease::TYPE_NA, Lease::STATE_DEFAULT, 3));
+        expected_rows.insert(LeaseStatsRow(1, Lease::TYPE_NA, Lease::STATE_DECLINED, 2));
+        expected_rows.insert(LeaseStatsRow(1, Lease::TYPE_PD, Lease::STATE_DEFAULT, 2));
+        // Start the query
+        ASSERT_NO_THROW(query = lmptr_->startLeaseStatsQuery6());
+
+        // Verify contents
+        checkQueryAgainstRowSet(query, expected_rows);
+    }
+}
+
 }; // namespace test
 }; // namespace dhcp
 }; // namespace isc
index 2d78dd8440710a7c023d13848455802edfdf81d5..d0a69ff6d35368918eddaf18abe2537119b5c571 100644 (file)
@@ -408,6 +408,18 @@ public:
     ///
     void testLeaseStatsQuery4();
 
+    /// @brief Checks operation of v6 LeaseStatsQuery variants
+    ///
+    /// It creates three subnets with leasese in various states in
+    /// each.  It runs and verifies the returned query contents for
+    /// each of the v6 startLeaseQuery variants:
+    ///
+    /// - startSubnetLeaseQuery()
+    /// - startSubneRangetLeaseQuery()
+    /// - startLeaseQuery()
+    ///
+    void testLeaseStatsQuery6();
+
     /// @brief Compares LeaseQueryStats content to expected set of rows
     ///
     /// @param qry - a started LeaseStatsQuery
index 09f803219715b4b59c380647a737c65748fe61c2..84735a9e116a9c7a9d84dad2afe2b906d82bdf5f 100644 (file)
@@ -1935,10 +1935,17 @@ TEST_F(MemfileLeaseMgrTest, wipeLeases6) {
     testWipeLeases6();
 }
 
+// Tests v4 lease stats query variants.
 TEST_F(MemfileLeaseMgrTest, leaseStatsQuery4) {
     startBackend(V4);
     testLeaseStatsQuery4();
 }
 
+// Tests v6 lease stats query variants.
+TEST_F(MemfileLeaseMgrTest, leaseStatsQuery6) {
+    startBackend(V6);
+    testLeaseStatsQuery6();
+}
+
 
 }  // namespace