From: Thomas Markwalder Date: Thu, 12 Apr 2018 13:57:44 +0000 (-0400) Subject: [5585] v6 Memfile support complete X-Git-Tag: trac5488_base^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c2897f7747dc75c3f7a5c53362e900e88a83a44;p=thirdparty%2Fkea.git [5585] v6 Memfile support complete 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) --- diff --git a/src/lib/dhcpsrv/memfile_lease_mgr.cc b/src/lib/dhcpsrv/memfile_lease_mgr.cc index 5c2de6e5fb..6e9421d048 100644 --- a/src/lib/dhcpsrv/memfile_lease_mgr.cc +++ b/src/lib/dhcpsrv/memfile_lease_mgr.cc @@ -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(); + // 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) diff --git a/src/lib/dhcpsrv/memfile_lease_mgr.h b/src/lib/dhcpsrv/memfile_lease_mgr.h index 98d9395e58..3a352beb5d 100644 --- a/src/lib/dhcpsrv/memfile_lease_mgr.h +++ b/src/lib/dhcpsrv/memfile_lease_mgr.h @@ -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 diff --git a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc index a9f3f6253a..5ce6c485c2 100644 --- a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc @@ -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 diff --git a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h index 2d78dd8440..d0a69ff6d3 100644 --- a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h +++ b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h @@ -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 diff --git a/src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc index 09f8032197..84735a9e11 100644 --- a/src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc @@ -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