: first_subnet_id_(0), last_subnet_id_(0), select_mode_(ALL_SUBNETS) {
}
-LeaseStatsQuery::LeaseStatsQuery(SubnetID subnet_id)
+LeaseStatsQuery::LeaseStatsQuery(const SubnetID& subnet_id)
: first_subnet_id_(subnet_id), last_subnet_id_(0),
select_mode_(SINGLE_SUBNET) {
- if (first_subnet_id_ == 0) {
- isc_throw(BadValue, "LeaseStatsQuery: subnet_id_ must be > 0");
- }
+
+ if (first_subnet_id_ == 0) {
+ isc_throw(BadValue, "LeaseStatsQuery: subnet_id_ must be > 0");
+ }
}
-LeaseStatsQuery::LeaseStatsQuery(SubnetID first, SubnetID last)
- : first_subnet_id_(first), last_subnet_id_(last),
+LeaseStatsQuery::LeaseStatsQuery(const SubnetID& first_subnet_id,
+ const SubnetID& last_subnet_id)
+ : first_subnet_id_(first_subnet_id), last_subnet_id_(last_subnet_id),
select_mode_(SUBNET_RANGE) {
if (first_subnet_id_ == 0) {
}
LeaseStatsQueryPtr
-LeaseMgr::startSubnetLeaseStatsQuery4(SubnetID /* subnet_id */) {
+LeaseMgr::startSubnetLeaseStatsQuery4(const SubnetID& /* subnet_id */) {
return(LeaseStatsQueryPtr());
}
LeaseStatsQueryPtr
-LeaseMgr::startSubnetRangeLeaseStatsQuery4(SubnetID /* first */,
- SubnetID /* last */) {
+LeaseMgr::startSubnetRangeLeaseStatsQuery4(const SubnetID& /* first_subnet_id */,
+ const SubnetID& /* last_subnet_id */) {
return(LeaseStatsQueryPtr());
}
}
LeaseStatsQueryPtr
-LeaseMgr::startSubnetLeaseStatsQuery6(SubnetID /* subnet_id */) {
+LeaseMgr::startSubnetLeaseStatsQuery6(const SubnetID& /* subnet_id */) {
return(LeaseStatsQueryPtr());
}
LeaseStatsQueryPtr
-LeaseMgr::startSubnetRangeLeaseStatsQuery6(SubnetID /* first */,
- SubnetID /* last */) {
+LeaseMgr::startSubnetRangeLeaseStatsQuery6(const SubnetID& /* first_subnet_id */,
+ const SubnetID& /* last_subnet_id */) {
return(LeaseStatsQueryPtr());
}
///
/// @param subnet_id id of the subnet for which stats are desired
/// @throw BadValue if sunbet_id given is 0.
- LeaseStatsQuery(SubnetID subnet_id);
+ LeaseStatsQuery(const SubnetID& subnet_id);
/// @brief Constructor to query for the stats for a range of subnets
///
/// The query created will return statistics for the inclusive range of
/// subnets described by first and last sunbet IDs.
///
- /// @param first first subnet in the range of subnets
- /// @param last last subnet in the range of subnets
+ /// @param first_subnet_id first subnet in the range of subnets
+ /// @param last_subnet_id last subnet in the range of subnets
/// @throw BadValue if either value given is 0 or if last <= first.
- LeaseStatsQuery(SubnetID first, SubnetID last);
+ LeaseStatsQuery(const SubnetID& first_subnet_id, const SubnetID& last_subnet_id);
/// @brief virtual destructor
virtual ~LeaseStatsQuery() {};
///
/// @param subnet_id id of the subnet for which stats are desired
/// @return A populated LeaseStatsQuery
- virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(SubnetID subnet_id);
+ virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID& subnet_id);
/// @brief Creates and runs the IPv4 lease stats query for a single subnet
///
/// range of subnets. Each row of the result set is an LeaseStatRow which
/// ordered ascending by subnet ID.
///
- /// @param first first subnet in the range of subnets
- /// @param last last subnet in the range of subnets
+ /// @param first_subnet_id first subnet in the range of subnets
+ /// @param last_subnet_id last subnet in the range of subnets
/// @return A populated LeaseStatsQuery
- virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery4(SubnetID first,
- SubnetID last);
+ virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery4(const SubnetID& first_subnet_id,
+ const SubnetID& last_subnet_id);
/// @brief Recalculates per-subnet and global stats for IPv6 leases
///
///
/// @param subnet_id id of the subnet for which stats are desired
/// @return A populated LeaseStatsQuery
- virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(SubnetID subnet_id);
+ virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID& subnet_id);
/// @brief Creates and runs the IPv6 lease stats query for a single subnet
///
/// range of subnets. Each row of the result set is an LeaseStatRow which
/// ordered ascending by subnet ID.
///
- /// @param first first subnet in the range of subnets
- /// @param last last subnet in the range of subnets
+ /// @param first_subnet_id first subnet in the range of subnets
+ /// @param last last_subnet_id subnet in the range of subnets
/// @return A populated LeaseStatsQuery
- virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery6(SubnetID first,
- SubnetID last);
+ virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery6(const SubnetID& first_subnet_id,
+ const SubnetID& last_subnet_id);
/// @brief Virtual method which removes specified leases.
///
///
class MemfileLeaseStatsQuery : public LeaseStatsQuery {
public:
- /// @brief Constructor
+ /// @brief Constructor for all subnets query
///
MemfileLeaseStatsQuery()
- : rows_(0), next_pos_(rows_.end()) {
+ : rows_(0), next_pos_(rows_.end()) {
+ };
+
+ /// @brief Constructor for single subnet query
+ ///
+ /// @param subnet_id ID of the desired subnet
+ MemfileLeaseStatsQuery(const SubnetID& subnet_id)
+ : LeaseStatsQuery(subnet_id), rows_(0), next_pos_(rows_.end()) {
+ };
+
+ /// @brief Constructor for subnet range query
+ ///
+ /// @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
+ MemfileLeaseStatsQuery(const SubnetID& first_subnet_id, const SubnetID& last_subnet_id)
+ : LeaseStatsQuery(first_subnet_id, last_subnet_id), rows_(0), next_pos_(rows_.end()) {
};
/// @brief Destructor
///
class MemfileLeaseStatsQuery4 : public MemfileLeaseStatsQuery {
public:
- /// @brief Constructor
+ /// @brief Constructor for an all subnets query
///
/// @param storage4 A pointer to the v4 lease storage to be counted
MemfileLeaseStatsQuery4(Lease4Storage& storage4)
- : MemfileLeaseStatsQuery(), storage4_(storage4) {
+ : MemfileLeaseStatsQuery(), storage4_(storage4) {
+ };
+
+ /// @brief Constructor for a single subnet query
+ ///
+ /// @param storage4 A pointer to the v4 lease storage to be counted
+ /// @param subnet_id ID of the desired subnet
+ MemfileLeaseStatsQuery4(Lease4Storage& storage4, const SubnetID& subnet_id)
+ : MemfileLeaseStatsQuery(subnet_id), storage4_(storage4) {
+ };
+
+ /// @brief Constructor for a subnet range query
+ ///
+ /// @param storage4 A pointer to the v4 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
+ MemfileLeaseStatsQuery4(Lease4Storage& storage4, const SubnetID& first_subnet_id,
+ const SubnetID& last_subnet_id)
+ : MemfileLeaseStatsQuery(first_subnet_id, last_subnet_id), storage4_(storage4) {
};
/// @brief Destructor
const Lease4StorageSubnetIdIndex& idx
= storage4_.get<SubnetIdIndexTag>();
+ // Set lower and upper bounds based on select mode
+ Lease4StorageSubnetIdIndex::const_iterator lower;
+ Lease4StorageSubnetIdIndex::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.
SubnetID cur_id = 0;
int64_t assigned = 0;
int64_t declined = 0;
- for(Lease4StorageSubnetIdIndex::const_iterator lease = idx.begin();
- lease != idx.end(); ++lease) {
+ for(Lease4StorageSubnetIdIndex::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) {
}
}
- // Make the rows for last subnet, unless there were no rows
- if (idx.begin() != idx.end()) {
- rows_.push_back(LeaseStatsRow(cur_id, Lease::STATE_DEFAULT,
- assigned));
- rows_.push_back(LeaseStatsRow(cur_id, Lease::STATE_DECLINED,
- declined));
- }
+ // Make the rows for last subnet
+ rows_.push_back(LeaseStatsRow(cur_id, Lease::STATE_DEFAULT, assigned));
+ rows_.push_back(LeaseStatsRow(cur_id, Lease::STATE_DECLINED, declined));
- // Set the next row position to the beginning of the rows.
+ // Reset the next row position back to the beginning of the rows.
next_pos_ = rows_.begin();
}
return(query);
}
+LeaseStatsQueryPtr
+Memfile_LeaseMgr::startSubnetLeaseStatsQuery4(const SubnetID& subnet_id) {
+ LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery4(storage4_, subnet_id));
+ query->start();
+ return(query);
+}
+
+LeaseStatsQueryPtr
+Memfile_LeaseMgr::startSubnetRangeLeaseStatsQuery4(const SubnetID& first_subnet_id,
+ const SubnetID& last_subnet_id) {
+ LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery4(storage4_, first_subnet_id,
+ last_subnet_id));
+ query->start();
+ return(query);
+}
+
LeaseStatsQueryPtr
Memfile_LeaseMgr::startLeaseStatsQuery6() {
LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery6(storage6_));
return(query);
}
+#if 0
+LeaseStatsQueryPtr
+Memfile_LeaseMgr::startSubnetLeaseStatsQuery6(const SubnetID& subnet_id) {
+ LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery6(storage6_, subnet_id));
+ query->start();
+ return(query);
+}
+
+LeaseStatsQueryPtr
+Memfile_LeaseMgr::startSubnetRangeLeaseStatsQuery6(const SubnetID& first_subnet_id,
+ const SubnetID& last_subnet_id) {
+ LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery4(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)
.arg(subnet_id);
/// @brief Creates and runs the IPv4 lease stats query
///
- /// It creates an instance of a MemfileLeaseStatsQuery4 and then
- /// invokes its start method in which the query constructs its
+ /// It creates an instance of a MemfileLeaseStatsQuery4 for an all subnets
+ /// query and then invokes its start method in which the query constructs its
/// statistical data result set. The query object is then returned.
///
/// @return The populated query as a pointer to an LeaseStatsQuery
virtual LeaseStatsQueryPtr startLeaseStatsQuery4();
+ /// @brief Creates and runs the IPv4 lease stats query for a single subnet
+ ///
+ /// It creates an instance of a MemfileLeaseStatsQuery4 for a single subnet
+ /// query and then invokes its start method in which the query constructs its
+ /// statistical data result set. The query object is then returned.
+ ///
+ /// @param subnet_id id of the subnet for which stats are desired
+ /// @return A populated LeaseStatsQuery
+ virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID& subnet_id);
+
+ /// @brief Creates and runs the IPv4 lease stats query for a single subnet
+ ///
+ /// It creates an instance of a MemfileLeaseStatsQuery4 for a subnet range
+ /// query and then invokes its start method in which the query constructs its
+ /// statistical data result set. The query object is then returned.
+ ///
+ /// @param first_subnet_id first subnet in the range of subnets
+ /// @param last_subnet_id last subnet in the range of subnets
+ /// @return A populated LeaseStatsQuery
+ virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery4(const SubnetID& first_subnet_id,
+ const SubnetID& last_subnet_id);
+
/// @brief Creates and runs the IPv6 lease stats query
///
/// It creates an instance of a MemfileLeaseStatsQuery6 and then
/// @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
+ /// query and then invokes its start method in which the query constructs its
+ /// statistical data result set. The query object is then returned.
+ ///
+ /// @param subnet_id id of the subnet for which stats are desired
+ /// @return A populated LeaseStatsQuery
+ virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID& subnet_id);
+
+ /// @brief Creates and runs the IPv6 lease stats query for a single subnet
+ ///
+ /// It creates an instance of a MemfileLeaseStatsQuery4 for a subnet range
+ /// query and then invokes its start method in which the query constructs its
+ /// statistical data result set. The query object is then returned.
+ ///
+ /// @param first_subnet_id first subnet in the range of subnets
+ /// @param last_subnet_id last subnet in the range of subnets
+ /// @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
/// tested by unit tests.
ASSERT_NO_THROW(CfgMgr::instance().commit());
+ // Make sure invalid values throw.
+ LeaseStatsQueryPtr query;
+ ASSERT_THROW(query = lmptr_->startSubnetLeaseStatsQuery4(0), BadValue);
+ ASSERT_THROW(query = lmptr_->startSubnetRangeLeaseStatsQuery4(0,1), BadValue);
+ ASSERT_THROW(query = lmptr_->startSubnetRangeLeaseStatsQuery4(1,0), BadValue);
+ ASSERT_THROW(query = lmptr_->startSubnetRangeLeaseStatsQuery4(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_->startLeaseStatsQuery4());
+ checkQueryAgainstRowSet(query, expected_rows);
+ }
+
// Now let's insert some leases into subnet 1.
// Two leases in the default state, i.e. assigned.
// One lease in declined state.
makeLease4("192.0.3.2", subnet_id);
makeLease4("192.0.3.3", subnet_id, Lease::STATE_DECLINED);
- LeaseStatsQueryPtr query;
- RowSet expected_rows;
+ // Test single subnet for non-matching subnet
+ {
+ SCOPED_TRACE("NO MATCHING SUBNET");
+ ASSERT_NO_THROW(query = lmptr_->startSubnetLeaseStatsQuery4(777));
+ checkQueryAgainstRowSet(query, expected_rows);
+ }
- // Test a non-matching single subnet
- ASSERT_NO_THROW(query = lmptr_->startSubnetLeaseStatsQuery4(777));
- checkQueryAgainstRowSet(query, expected_rows);
+ // Test an empty range
+ {
+ SCOPED_TRACE("EMPTY SUBNET RANGE");
+ ASSERT_NO_THROW(query = lmptr_->startSubnetRangeLeaseStatsQuery4(777, 900));
+ checkQueryAgainstRowSet(query, expected_rows);
+ }
// Test a single subnet
- // Add expected row for Subnet 2
- expected_rows.insert(LeaseStatsRow(2, Lease::STATE_DEFAULT, 0));
- expected_rows.insert(LeaseStatsRow(2, Lease::STATE_DECLINED, 1));
- // Start the query
- ASSERT_NO_THROW(query = lmptr_->startSubnetLeaseStatsQuery4(2));
- // Verify contents
- checkQueryAgainstRowSet(query, expected_rows);
+ {
+ SCOPED_TRACE("SINGLE SUBNET");
+ // Add expected row for Subnet 2
+ expected_rows.insert(LeaseStatsRow(2, Lease::STATE_DEFAULT, 0));
+ expected_rows.insert(LeaseStatsRow(2, Lease::STATE_DECLINED, 1));
+ // Start the query
+ ASSERT_NO_THROW(query = lmptr_->startSubnetLeaseStatsQuery4(2));
+ // Verify contents
+ checkQueryAgainstRowSet(query, expected_rows);
+ }
// Test a range of subnets
- // Add expected rows for Subnet 3
- expected_rows.insert(LeaseStatsRow(3, Lease::STATE_DEFAULT, 2));
- expected_rows.insert(LeaseStatsRow(3, Lease::STATE_DECLINED, 1));
- // Start the query
- ASSERT_NO_THROW(query = lmptr_->startSubnetRangeLeaseStatsQuery4(2,3));
- // Verify contents
- checkQueryAgainstRowSet(query, expected_rows);
+ {
+ SCOPED_TRACE("SUBNET RANGE");
+ // Add expected rows for Subnet 3
+ expected_rows.insert(LeaseStatsRow(3, Lease::STATE_DEFAULT, 2));
+ expected_rows.insert(LeaseStatsRow(3, Lease::STATE_DECLINED, 1));
+ // Start the query
+ ASSERT_NO_THROW(query = lmptr_->startSubnetRangeLeaseStatsQuery4(2,3));
+ // Verify contents
+ checkQueryAgainstRowSet(query, expected_rows);
+ }
// Test all subnets
- // Add expected rows for Subnet 1
- expected_rows.insert(LeaseStatsRow(1, Lease::STATE_DEFAULT, 2));
- expected_rows.insert(LeaseStatsRow(1, Lease::STATE_DECLINED, 1));
- // Start the query
- ASSERT_NO_THROW(query = lmptr_->startLeaseStatsQuery4());
- // Verify contents
- checkQueryAgainstRowSet(query, expected_rows);
+ {
+ SCOPED_TRACE("ALL SUBNETS");
+ // Add expected rows for Subnet 1
+ expected_rows.insert(LeaseStatsRow(1, Lease::STATE_DEFAULT, 2));
+ expected_rows.insert(LeaseStatsRow(1, Lease::STATE_DECLINED, 1));
+ // Start the query
+ ASSERT_NO_THROW(query = lmptr_->startLeaseStatsQuery4());
+ // Verify contents
+ checkQueryAgainstRowSet(query, expected_rows);
+ }
}
}; // namespace test
TEST (LeaseStatsQueryTest, defaultCtor) {
LeaseStatsQueryPtr qry;
+ // Valid construction, verifiy member values.
ASSERT_NO_THROW(qry.reset(new LeaseStatsQuery()));
ASSERT_EQ(0, qry->getFirstSubnetID());
ASSERT_EQ(0, qry->getLastSubnetID());
TEST (LeaseStatsQueryTest, singleSubnetCtor) {
LeaseStatsQueryPtr qry;
+ // Invalid values for subnet_id
ASSERT_THROW(qry.reset(new LeaseStatsQuery(0)), BadValue);
+
+ // Valid values should work and set mode accordingly.
ASSERT_NO_THROW(qry.reset(new LeaseStatsQuery(77)));
ASSERT_EQ(77, qry->getFirstSubnetID());
ASSERT_EQ(0, qry->getLastSubnetID());