Commit 0aa706ea authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[3711] Subnet::getLeasesCount() implemented.

parent 303c0d3e
......@@ -133,6 +133,40 @@ Subnet::toText() const {
return (tmp.str());
}
uint64_t
Subnet::getLeasesCount(Lease::Type type) const {
switch (type) {
case Lease::TYPE_V4:
case Lease::TYPE_NA:
return sumLeasesCount(pools_);
case Lease::TYPE_TA:
return sumLeasesCount(pools_ta_);
case Lease::TYPE_PD:
return sumLeasesCount(pools_pd_);
default:
isc_throw(BadValue, "Unsupported pool type: "
<< static_cast<int>(type));
}
}
uint64_t
Subnet::sumLeasesCount(const PoolCollection& pools) const {
uint64_t sum = 0;
for (PoolCollection::const_iterator p = pools.begin(); p != pools.end(); ++p) {
uint64_t x = (*p)->getLeasesCount();
// Check if we can add it. If sum + x > uint64::max, then we would have
// overflown if we tried to add it.
if (x > std::numeric_limits<uint64_t>::max() - sum) {
return (std::numeric_limits<uint64_t>::max());
}
sum += x;
}
return (sum);
}
void Subnet4::checkType(Lease::Type type) const {
if (type != Lease::TYPE_V4) {
isc_throw(BadValue, "Only TYPE_V4 is allowed for Subnet4");
......
......@@ -233,6 +233,11 @@ public:
/// @return a collection of all pools
const PoolCollection& getPools(Lease::Type type) const;
/// @brief Returns the number of possible leases for specified lease type
///
/// @param type type of the lease
uint64_t getLeasesCount(Lease::Type type) const;
/// @brief Sets name of the network interface for directly attached networks
///
/// @param iface_name name of the interface
......@@ -403,6 +408,12 @@ protected:
/// @throw BadValue if invalid value is used
virtual void checkType(Lease::Type type) const = 0;
/// @brief returns a sum of possible leases in all pools
/// @param pools list of pools
/// @return sum of possible leases
uint64_t sumLeasesCount(const PoolCollection& pools) const;
/// @brief subnet-id
///
/// Subnet-id is a unique value that can be used to find or identify
......
......@@ -289,5 +289,4 @@ TEST(Pool6Test, leasesCount) {
}
}; // end of anonymous namespace
......@@ -22,6 +22,7 @@
#include <boost/scoped_ptr.hpp>
#include <gtest/gtest.h>
#include <limits>
// don't import the entire boost namespace. It will unexpectedly hide uint8_t
// for some systems.
......@@ -147,6 +148,32 @@ TEST(Subnet4Test, Pool4InSubnet4) {
}
// Check if it's possible to get specified number of possible leases for
// an IPv4 subnet.
TEST(Subnet4Test, getLeasesCount) {
// There's one /24 pool.
Subnet4Ptr subnet(new Subnet4(IOAddress("192.1.2.0"), 24, 1, 2, 3));
// There are no pools defined, so the total number of available addrs is 0.
EXPECT_EQ(0, subnet->getLeasesCount(Lease::TYPE_V4));
// Let's add a /25 pool. That's 128 addresses.
PoolPtr pool1(new Pool4(IOAddress("192.1.2.0"), 25));
subnet->addPool(pool1);
EXPECT_EQ(128, subnet->getLeasesCount(Lease::TYPE_V4));
// Let's add another /26 pool. That's extra 64 addresses.
PoolPtr pool2(new Pool4(IOAddress("192.1.2.128"), 26));
subnet->addPool(pool2);
EXPECT_EQ(192, subnet->getLeasesCount(Lease::TYPE_V4));
// Let's add a third pool /30. This one has 4 addresses.
PoolPtr pool3(new Pool4(IOAddress("192.1.2.192"), 30));
subnet->addPool(pool3);
EXPECT_EQ(196, subnet->getLeasesCount(Lease::TYPE_V4));
}
TEST(Subnet4Test, Subnet4_Pool4_checks) {
Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.2.0"), 8, 1, 2, 3));
......@@ -434,6 +461,84 @@ TEST(Subnet6Test, relay) {
EXPECT_EQ("2001:ffff::1", subnet.getRelayInfo().addr_.toText());
}
// Test checks whether the number of addresses available in the pools are
// calculated properly.
TEST(Subnet6Test, Pool6LeasesCount) {
Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
// There's 2^16 = 65536 addresses in this one.
PoolPtr pool1(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:1::"), 112));
// There's 2^32 = 4294967296 addresses in each of those.
PoolPtr pool2(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:2::"), 96));
PoolPtr pool3(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:3::"), 96));
EXPECT_EQ(0, subnet->getLeasesCount(Lease::TYPE_NA));
EXPECT_EQ(0, subnet->getLeasesCount(Lease::TYPE_TA));
EXPECT_EQ(0, subnet->getLeasesCount(Lease::TYPE_PD));
subnet->addPool(pool1);
EXPECT_EQ(65536, subnet->getLeasesCount(Lease::TYPE_NA));
subnet->addPool(pool2);
EXPECT_EQ(uint64_t(4294967296 + 65536), subnet->getLeasesCount(Lease::TYPE_NA));
subnet->addPool(pool3);
EXPECT_EQ(uint64_t(4294967296 + 4294967296 + 65536),
subnet->getLeasesCount(Lease::TYPE_NA));
// This is 2^64 prefixes. We're overflown uint64_t.
PoolPtr pool4(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:4::"), 64));
subnet->addPool(pool4);
EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
subnet->getLeasesCount(Lease::TYPE_NA));
PoolPtr pool5(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:5::"), 64));
subnet->addPool(pool5);
EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
subnet->getLeasesCount(Lease::TYPE_NA));
}
// Test checks whether the number of prefixes available in the pools are
// calculated properly.
TEST(Subnet6Test, Pool6PdLeasesCount) {
Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8::"), 32, 1, 2, 3, 4));
// There's 2^16 = 65536 addresses in this one.
PoolPtr pool1(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:1::"), 48, 64));
// There's 2^32 = 4294967296 addresses in each of those.
PoolPtr pool2(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:2::"), 48, 80));
PoolPtr pool3(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:3::"), 48, 80));
EXPECT_EQ(0, subnet->getLeasesCount(Lease::TYPE_NA));
EXPECT_EQ(0, subnet->getLeasesCount(Lease::TYPE_TA));
EXPECT_EQ(0, subnet->getLeasesCount(Lease::TYPE_PD));
subnet->addPool(pool1);
EXPECT_EQ(65536, subnet->getLeasesCount(Lease::TYPE_PD));
subnet->addPool(pool2);
EXPECT_EQ(uint64_t(4294967296 + 65536), subnet->getLeasesCount(Lease::TYPE_PD));
subnet->addPool(pool3);
EXPECT_EQ(uint64_t(4294967296 + 4294967296 + 65536),
subnet->getLeasesCount(Lease::TYPE_PD));
// This is 2^64.
PoolPtr pool4(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:4::"), 48, 112));
subnet->addPool(pool4);
EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
subnet->getLeasesCount(Lease::TYPE_PD));
PoolPtr pool5(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:5::"), 48, 112));
subnet->addPool(pool5);
EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
subnet->getLeasesCount(Lease::TYPE_PD));
}
TEST(Subnet6Test, Pool6InSubnet6) {
Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment