]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#4444] Checkpoint2
authorFrancis Dupont <fdupont@isc.org>
Tue, 19 May 2026 12:44:08 +0000 (14:44 +0200)
committerFrancis Dupont <fdupont@isc.org>
Tue, 19 May 2026 12:44:08 +0000 (14:44 +0200)
src/lib/dhcpsrv/tests/flq_allocator_unittest.cc
src/lib/dhcpsrv/tests/random_allocator_unittest.cc

index daade94f39e0128c2a9a65fecb37514ec456c268..e259182fbed29934d753d1bbf55bfb91837c1626 100644 (file)
@@ -304,6 +304,34 @@ TEST_F(FreeLeaseQueueAllocatorTest4, noPools) {
     EXPECT_EQ(0., r);
 }
 
+// Test that the allocator still works with a single pool of a single address.
+TEST_F(FreeLeaseQueueAllocatorTest4, singlePoolSingleAddress) {
+    FreeLeaseQueueAllocator alloc(Lease::TYPE_V4, subnet_);
+
+    subnet_->delPools(Lease::TYPE_V4);
+    auto addr = IOAddress("192.0.2.10");
+    auto pool = boost::make_shared<Pool4>(addr, addr);
+    subnet_->addPool(pool);
+
+    ASSERT_NO_THROW(alloc.initAfterConfigure());
+
+    // The unique address is returned.
+    EXPECT_EQ(addr, alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")));
+    // Forever...
+    EXPECT_EQ(addr, alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")));
+
+    // Create and add the lease for the address.
+    auto lease = createLease4(addr, 0);
+    EXPECT_TRUE(LeaseMgrFactory::instance().addLease(lease));
+
+    // Now the address is busy,
+    auto candidate = alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0"));
+    EXPECT_TRUE(candidate.isV4Zero());
+
+    double r = alloc.getOccupancyRate(addr, cc_);
+    EXPECT_EQ(1., r);
+}
+
 // Test that the allocator respects client class guards.
 TEST_F(FreeLeaseQueueAllocatorTest4, clientClasses) {
    FreeLeaseQueueAllocator alloc(Lease::TYPE_V4, subnet_);
@@ -649,6 +677,31 @@ TEST_F(FreeLeaseQueueAllocatorTest6, noPools) {
    EXPECT_TRUE(candidate.isV6Zero());
 }
 
+// Test that the allocator still works with a single pool of a single address.
+TEST_F(FreeLeaseQueueAllocatorTest6, singlePoolSingleAddress) {
+    FreeLeaseQueueAllocator alloc(Lease::TYPE_NA, subnet_);
+
+    subnet_->delPools(Lease::TYPE_NA);
+    auto addr = IOAddress("2001:db8:1::1");
+    auto pool = boost::make_shared<Pool6>(Lease::TYPE_NA, addr, addr);
+    subnet_->addPool(pool);
+
+    ASSERT_NO_THROW(alloc.initAfterConfigure());
+
+    // The unique address is returned.
+    EXPECT_EQ(addr, alloc.pickAddress(cc_, duid_, IOAddress("::")));
+    // Forever...
+    EXPECT_EQ(addr, alloc.pickAddress(cc_, duid_, IOAddress("::")));
+
+    // Create and add the lease for the address.
+    auto lease = createLease6(Lease::TYPE_NA, addr, 0);
+    EXPECT_TRUE(LeaseMgrFactory::instance().addLease(lease));
+
+    // Now the address is busy,
+    auto candidate = alloc.pickAddress(cc_, duid_, IOAddress("::"));
+    EXPECT_TRUE(candidate.isV6Zero());
+}
+
 // Test that the allocator respects client class guards.
 TEST_F(FreeLeaseQueueAllocatorTest6, clientClasses) {
    FreeLeaseQueueAllocator alloc(Lease::TYPE_NA, subnet_);
@@ -1061,6 +1114,40 @@ TEST_F(FreeLeaseQueueAllocatorTest6, manyPdPoolsPreferHigher) {
     EXPECT_EQ((assigned ? 2560. : 2561.) / 68096., r);
 }
 
+// Test that the allocator still works with a single pd pool of a single prefix.
+TEST_F(FreeLeaseQueueAllocatorTest6, singlePdPoolSinglePrefix) {
+    FreeLeaseQueueAllocator alloc(Lease::TYPE_PD, subnet_);
+
+    subnet_->delPools(Lease::TYPE_PD);
+    auto addr = IOAddress("3000::");
+    auto pool = boost::make_shared<Pool6>(Lease::TYPE_PD, addr, 120, 120);
+    subnet_->addPool(pool);
+
+    ASSERT_NO_THROW(alloc.initAfterConfigure());
+
+    // The unique prefix is returned.
+    EXPECT_EQ(addr, alloc.pickPrefix(cc_, pool, duid_,
+                                     Allocator::PREFIX_LEN_HIGHER,
+                                     IOAddress("::"), 0));
+    // Forever...
+    EXPECT_EQ(addr, alloc.pickPrefix(cc_, pool, duid_,
+                                     Allocator::PREFIX_LEN_HIGHER,
+                                     IOAddress("::"), 0));
+
+    // Create and add the lease for the prefix.
+    auto lease = createLease6(Lease::TYPE_PD, addr, 0);
+    EXPECT_TRUE(LeaseMgrFactory::instance().addLease(lease));
+
+    // Now the prefix is busy,
+    auto candidate = alloc.pickPrefix(cc_, pool, duid_,
+                                     Allocator::PREFIX_LEN_HIGHER,
+                                     IOAddress("::"), 0);
+    EXPECT_TRUE(candidate.isV6Zero());
+
+    double r = alloc.getOccupancyRate(addr, 128, cc_);
+    EXPECT_EQ(1., r);
+}
+
 // Test that the allocator respects client class guards.
 TEST_F(FreeLeaseQueueAllocatorTest6, pdPoolsClientClasses) {
     FreeLeaseQueueAllocator alloc(Lease::TYPE_PD, subnet_);
index b6997ffa9f8f08ccb8cec2db352fbb1c4d917456..f2c876e80f133863aa4dddac0241d7f4520caf95 100644 (file)
@@ -123,6 +123,21 @@ TEST_F(RandomAllocatorTest4, noPools) {
    EXPECT_TRUE(candidate.isV4Zero());
 }
 
+// Test that the allocator still works with a single pool of a single address.
+TEST_F(RandomAllocatorTest4, singlePoolSingleAddress) {
+    RandomAllocator alloc(Lease::TYPE_V4, subnet_);
+
+    subnet_->delPools(Lease::TYPE_V4);
+    auto addr = IOAddress("192.0.2.10");
+    auto pool = boost::make_shared<Pool4>(addr, addr);
+    subnet_->addPool(pool);
+
+    // The unique address is returned.
+    EXPECT_EQ(addr, alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")));
+    // Forever...
+    EXPECT_EQ(addr, alloc.pickAddress(cc_, clientid_, IOAddress("0.0.0.0")));
+}
+
 // Test that the allocator respects client classes while it picks
 // pools and addresses.
 TEST_F(RandomAllocatorTest4, clientClasses) {
@@ -275,6 +290,21 @@ TEST_F(RandomAllocatorTest6, manyPools) {
     }
 }
 
+// Test that the allocator still works with a single pool of a single address.
+TEST_F(RandomAllocatorTest6, singlePoolSingleAddress) {
+    RandomAllocator alloc(Lease::TYPE_NA, subnet_);
+
+    subnet_->delPools(Lease::TYPE_NA);
+    auto addr = IOAddress("2001:db8:1::1");
+    auto pool = boost::make_shared<Pool6>(Lease::TYPE_NA, addr, addr);
+    subnet_->addPool(pool);
+
+    // The unique address is returned.
+    EXPECT_EQ(addr, alloc.pickAddress(cc_, duid_, IOAddress("::")));
+    // Forever...
+    EXPECT_EQ(addr, alloc.pickAddress(cc_, duid_, IOAddress("::")));
+}
+
 // Test that the allocator respects client classes while it picks
 // pools and addresses.
 TEST_F(RandomAllocatorTest6, clientClasses) {
@@ -356,6 +386,25 @@ TEST_F(RandomAllocatorTest6, singlePdPool) {
     EXPECT_EQ(65536, prefixes.size());
 }
 
+// Test that the allocator still works with a single pd pool of a single prefix.
+TEST_F(RandomAllocatorTest6, singlePdPoolSinglePrefix) {
+    RandomAllocator alloc(Lease::TYPE_PD, subnet_);
+
+    subnet_->delPools(Lease::TYPE_PD);
+    auto addr = IOAddress("3000::");
+    auto pool = boost::make_shared<Pool6>(Lease::TYPE_PD, addr, 120, 120);
+    subnet_->addPool(pool);
+
+    // The unique prefix is returned.
+    EXPECT_EQ(addr, alloc.pickPrefix(cc_, pool, duid_,
+                                     Allocator::PREFIX_LEN_HIGHER,
+                                     IOAddress("::"), 0));
+    // Forever...
+    EXPECT_EQ(addr, alloc.pickPrefix(cc_, pool, duid_,
+                                     Allocator::PREFIX_LEN_HIGHER,
+                                     IOAddress("::"), 0));
+}
+
 // Test allocating delegated prefixes from multiple pools.
 TEST_F(RandomAllocatorTest6, manyPdPools) {
     RandomAllocator alloc(Lease::TYPE_PD, subnet_);