From: Francis Dupont Date: Sat, 4 Nov 2017 10:48:52 +0000 (+0100) Subject: [5425] Checkpoint: began tests X-Git-Tag: trac5374_base~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b4e2cf347a0cd7bd71554a483af182a217e74c67;p=thirdparty%2Fkea.git [5425] Checkpoint: began tests --- diff --git a/src/lib/dhcpsrv/tests/alloc_engine_utils.h b/src/lib/dhcpsrv/tests/alloc_engine_utils.h index de3d8a2886..eeed469755 100644 --- a/src/lib/dhcpsrv/tests/alloc_engine_utils.h +++ b/src/lib/dhcpsrv/tests/alloc_engine_utils.h @@ -74,6 +74,7 @@ public: :IterativeAllocator(type) { } + using AllocEngine::IterativeAllocator::increaseAddress; using AllocEngine::IterativeAllocator::increasePrefix; }; }; @@ -221,10 +222,10 @@ public: /// @param input address to be increased /// @param exp_output expected address after increase void - checkAddrIncrease(NakedAllocEngine::NakedIterativeAllocator&, + checkAddrIncrease(NakedAllocEngine::NakedIterativeAllocator& alloc, std::string input, std::string exp_output) { - EXPECT_EQ(exp_output, asiolink::IOAddress::increase( - asiolink::IOAddress(input)).toText()); + EXPECT_EQ(exp_output, alloc.increaseAddress(asiolink::IOAddress(input), + false, 0).toText()); } /// @brief Checks if increasePrefix() works as expected diff --git a/src/lib/dhcpsrv/tests/pool_unittest.cc b/src/lib/dhcpsrv/tests/pool_unittest.cc index b78cf1fbcd..5662f6a5ce 100644 --- a/src/lib/dhcpsrv/tests/pool_unittest.cc +++ b/src/lib/dhcpsrv/tests/pool_unittest.cc @@ -190,6 +190,106 @@ TEST(Pool4Test, userContext) { EXPECT_EQ(ctx->str(), pool->getContext()->str()); } +// This test checks that handling for client-class is valid. +TEST(Pool4Test, clientClass) { + // Create a pool. + Pool4Ptr pool(new Pool4(IOAddress("192.0.2.0"), + IOAddress("192.0.2.255"))); + + // This client does not belong to any class. + isc::dhcp::ClientClasses no_class; + + // This client belongs to foo only. + isc::dhcp::ClientClasses foo_class; + foo_class.insert("foo"); + + // This client belongs to bar only. I like that client. + isc::dhcp::ClientClasses bar_class; + bar_class.insert("bar"); + + // This client belongs to foo, bar and baz classes. + isc::dhcp::ClientClasses three_classes; + three_classes.insert("foo"); + three_classes.insert("bar"); + three_classes.insert("baz"); + + // No class restrictions defined, any client should be supported + EXPECT_EQ(0, pool->getClientClasses().size()); + EXPECT_TRUE(pool->clientSupported(no_class)); + EXPECT_TRUE(pool->clientSupported(foo_class)); + EXPECT_TRUE(pool->clientSupported(bar_class)); + EXPECT_TRUE(pool->clientSupported(three_classes)); + + // Let's allow only clients belonging to "bar" class. + pool->allowClientClass("bar"); + EXPECT_EQ(1, pool->getClientClasses().size()); + + EXPECT_FALSE(pool->clientSupported(no_class)); + EXPECT_FALSE(pool->clientSupported(foo_class)); + EXPECT_TRUE(pool->clientSupported(bar_class)); + EXPECT_TRUE(pool->clientSupported(three_classes)); +} + +// This test checks that handling for multiple client-classes is valid. +TEST(Pool4Test, clientClasses) { + // Create a pool. + Pool4Ptr pool(new Pool4(IOAddress("192.0.2.0"), + IOAddress("192.0.2.255"))); + + // This client does not belong to any class. + isc::dhcp::ClientClasses no_class; + + // This client belongs to foo only. + isc::dhcp::ClientClasses foo_class; + foo_class.insert("foo"); + + // This client belongs to bar only. I like that client. + isc::dhcp::ClientClasses bar_class; + bar_class.insert("bar"); + + // No class restrictions defined, any client should be supported + EXPECT_EQ(0, pool->getClientClasses().size()); + EXPECT_TRUE(pool->clientSupported(no_class)); + EXPECT_TRUE(pool->clientSupported(foo_class)); + EXPECT_TRUE(pool->clientSupported(bar_class)); + + // Let's allow clients belonging to "bar" or "foo" class. + pool->allowClientClass("bar"); + pool->allowClientClass("foo"); + EXPECT_EQ(2, pool->getClientClasses().size()); + + // Class-less clients are to be rejected. + EXPECT_FALSE(pool->clientSupported(no_class)); + + // Clients in foo class should be accepted. + EXPECT_TRUE(pool->clientSupported(foo_class)); + + // Clients in bar class should be accepted as well. + EXPECT_TRUE(pool->clientSupported(bar_class)); +} + +// This test checks that handling for last allocated address/prefix is valid. +TEST(Pool4Test, lastAllocated) { + // Create a pool. + IOAddress first("192.0.2.0"); + Pool4Ptr pool(new Pool4(first, IOAddress("192.0.2.255"))); + + // Initial values are first invalid. + EXPECT_EQ(first.toText(), pool->getLastAllocated().toText()); + EXPECT_FALSE(pool->isLastAllocatedValid()); + + // Now set last allocated + IOAddress addr("192.0.2.100"); + EXPECT_NO_THROW(pool->setLastAllocated(addr)); + EXPECT_EQ(addr.toText(), pool->getLastAllocated().toText()); + EXPECT_TRUE(pool->isLastAllocatedValid()); + + // Reset makes it invalid and does not touch address + pool->resetLastAllocated(); + EXPECT_EQ(addr.toText(), pool->getLastAllocated().toText()); + EXPECT_FALSE(pool->isLastAllocatedValid()); +} + TEST(Pool6Test, constructor_first_last) { // let's construct 2001:db8:1:: - 2001:db8:1::ffff:ffff:ffff:ffff pool @@ -494,4 +594,104 @@ TEST(Pool6Test, userContext) { EXPECT_EQ(ctx->str(), pool.getContext()->str()); } +// This test checks that handling for client-class is valid. +TEST(Pool6Test, clientClass) { + // Create a pool. + Pool6 pool(Lease::TYPE_NA, IOAddress("2001:db8::1"), + IOAddress("2001:db8::2")); + + // This client does not belong to any class. + isc::dhcp::ClientClasses no_class; + + // This client belongs to foo only. + isc::dhcp::ClientClasses foo_class; + foo_class.insert("foo"); + + // This client belongs to bar only. I like that client. + isc::dhcp::ClientClasses bar_class; + bar_class.insert("bar"); + + // This client belongs to foo, bar and baz classes. + isc::dhcp::ClientClasses three_classes; + three_classes.insert("foo"); + three_classes.insert("bar"); + three_classes.insert("baz"); + + // No class restrictions defined, any client should be supported + EXPECT_EQ(0, pool.getClientClasses().size()); + EXPECT_TRUE(pool.clientSupported(no_class)); + EXPECT_TRUE(pool.clientSupported(foo_class)); + EXPECT_TRUE(pool.clientSupported(bar_class)); + EXPECT_TRUE(pool.clientSupported(three_classes)); + + // Let's allow only clients belonging to "bar" class. + pool.allowClientClass("bar"); + EXPECT_EQ(1, pool.getClientClasses().size()); + + EXPECT_FALSE(pool.clientSupported(no_class)); + EXPECT_FALSE(pool.clientSupported(foo_class)); + EXPECT_TRUE(pool.clientSupported(bar_class)); + EXPECT_TRUE(pool.clientSupported(three_classes)); +} + +// This test checks that handling for multiple client-classes is valid. +TEST(Pool6Test, clientClasses) { + // Create a pool. + Pool6 pool(Lease::TYPE_NA, IOAddress("2001:db8::1"), + IOAddress("2001:db8::2")); + + // This client does not belong to any class. + isc::dhcp::ClientClasses no_class; + + // This client belongs to foo only. + isc::dhcp::ClientClasses foo_class; + foo_class.insert("foo"); + + // This client belongs to bar only. I like that client. + isc::dhcp::ClientClasses bar_class; + bar_class.insert("bar"); + + // No class restrictions defined, any client should be supported + EXPECT_EQ(0, pool.getClientClasses().size()); + EXPECT_TRUE(pool.clientSupported(no_class)); + EXPECT_TRUE(pool.clientSupported(foo_class)); + EXPECT_TRUE(pool.clientSupported(bar_class)); + + // Let's allow clients belonging to "bar" or "foo" class. + pool.allowClientClass("bar"); + pool.allowClientClass("foo"); + EXPECT_EQ(2, pool.getClientClasses().size()); + + // Class-less clients are to be rejected. + EXPECT_FALSE(pool.clientSupported(no_class)); + + // Clients in foo class should be accepted. + EXPECT_TRUE(pool.clientSupported(foo_class)); + + // Clients in bar class should be accepted as well. + EXPECT_TRUE(pool.clientSupported(bar_class)); +} + +// This test checks that handling for last allocated address/prefix is valid. +TEST(Pool6Test, lastAllocated) { + // Create a pool. + IOAddress first("2001:db8::1"); + Pool6 pool(Lease::TYPE_NA, first, IOAddress("2001:db8::200")); + + // Initial values are first invalid. + EXPECT_EQ(first.toText(), pool.getLastAllocated().toText()); + EXPECT_FALSE(pool.isLastAllocatedValid()); + + // Now set last allocated + IOAddress addr("2001:db8::100"); + EXPECT_NO_THROW(pool.setLastAllocated(addr)); + EXPECT_EQ(addr.toText(), pool.getLastAllocated().toText()); + EXPECT_TRUE(pool.isLastAllocatedValid()); + + // Reset makes it invalid and does not touch address + pool.resetLastAllocated(); + EXPECT_EQ(addr.toText(), pool.getLastAllocated().toText()); + EXPECT_FALSE(pool.isLastAllocatedValid()); +} + }; // end of anonymous namespace diff --git a/src/lib/dhcpsrv/tests/subnet_unittest.cc b/src/lib/dhcpsrv/tests/subnet_unittest.cc index a969b9ccab..efb4cafe1d 100644 --- a/src/lib/dhcpsrv/tests/subnet_unittest.cc +++ b/src/lib/dhcpsrv/tests/subnet_unittest.cc @@ -168,15 +168,18 @@ TEST(Subnet4Test, pool4InSubnet4) { PoolPtr pool1(new Pool4(IOAddress("192.1.2.0"), 25)); PoolPtr pool2(new Pool4(IOAddress("192.1.2.128"), 26)); PoolPtr pool3(new Pool4(IOAddress("192.1.2.192"), 30)); + pool3->allowClientClass("bar"); + PoolPtr pool4(new Pool4(IOAddress("192.1.2.200"), 30)); // Add pools in reverse order to make sure that they get ordered by // first address. - EXPECT_NO_THROW(subnet->addPool(pool3)); + EXPECT_NO_THROW(subnet->addPool(pool4)); // If there's only one pool, get that pool PoolPtr mypool = subnet->getAnyPool(Lease::TYPE_V4); - EXPECT_EQ(mypool, pool3); + EXPECT_EQ(mypool, pool4); + EXPECT_NO_THROW(subnet->addPool(pool3)); EXPECT_NO_THROW(subnet->addPool(pool2)); EXPECT_NO_THROW(subnet->addPool(pool1)); @@ -188,8 +191,8 @@ TEST(Subnet4Test, pool4InSubnet4) { // If we provide a hint, we should get a pool that this hint belongs to ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, - IOAddress("192.1.2.195"))); - EXPECT_EQ(mypool, pool3); + IOAddress("192.1.2.201"))); + EXPECT_EQ(mypool, pool4); ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, IOAddress("192.1.2.129"))); @@ -203,7 +206,7 @@ TEST(Subnet4Test, pool4InSubnet4) { // third parameter prevents it from returning "any" available // pool if a good match is not found. ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, - IOAddress("192.1.2.200"), + IOAddress("192.1.2.210"), false)); EXPECT_FALSE(mypool); @@ -211,6 +214,57 @@ TEST(Subnet4Test, pool4InSubnet4) { IOAddress("192.1.1.254"), false)); EXPECT_FALSE(mypool); + + // Now play with classes + + // This client does not belong to any class. + isc::dhcp::ClientClasses no_class; + + // This client belongs to foo only. + isc::dhcp::ClientClasses foo_class; + foo_class.insert("foo"); + + // This client belongs to bar only. I like that client. + isc::dhcp::ClientClasses bar_class; + bar_class.insert("bar"); + + // This client belongs to foo, bar and baz classes. + isc::dhcp::ClientClasses three_classes; + three_classes.insert("foo"); + three_classes.insert("bar"); + three_classes.insert("baz"); + + // If we provide a hint, we should get a pool that this hint belongs to + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, + IOAddress("192.1.2.201"))); + EXPECT_EQ(mypool, pool4); + + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, + IOAddress("192.1.2.129"))); + EXPECT_EQ(mypool, pool2); + + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, + IOAddress("192.1.2.64"))); + EXPECT_EQ(mypool, pool1); + + // Specify addresses which don't belong to any existing pools. + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, three_classes, + IOAddress("192.1.2.210"))); + EXPECT_FALSE(mypool); + + // Pool3 requires a member of bar + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, + IOAddress("192.1.2.195"))); + EXPECT_FALSE(mypool); + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, foo_class, + IOAddress("192.1.2.195"))); + EXPECT_FALSE(mypool); + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, bar_class, + IOAddress("192.1.2.195"))); + EXPECT_EQ(mypool, pool3); + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, three_classes, + IOAddress("192.1.2.195"))); + EXPECT_EQ(mypool, pool3); } // Check if it's possible to get specified number of possible leases for @@ -237,6 +291,38 @@ TEST(Subnet4Test, getCapacity) { PoolPtr pool3(new Pool4(IOAddress("192.1.2.192"), 30)); subnet->addPool(pool3); EXPECT_EQ(196, subnet->getPoolCapacity(Lease::TYPE_V4)); + + // Let's add a forth pool /30. This one has 4 addresses. + PoolPtr pool4(new Pool4(IOAddress("192.1.2.200"), 30)); + subnet->addPool(pool4); + EXPECT_EQ(200, subnet->getPoolCapacity(Lease::TYPE_V4)); + + // Now play with classes + + // This client does not belong to any class. + isc::dhcp::ClientClasses no_class; + + // This client belongs to foo only. + isc::dhcp::ClientClasses foo_class; + foo_class.insert("foo"); + + // This client belongs to bar only. I like that client. + isc::dhcp::ClientClasses bar_class; + bar_class.insert("bar"); + + // This client belongs to foo, bar and baz classes. + isc::dhcp::ClientClasses three_classes; + three_classes.insert("foo"); + three_classes.insert("bar"); + three_classes.insert("baz"); + + pool3->allowClientClass("bar"); + + // Pool3 requires a member of bar + EXPECT_EQ(196, subnet->getPoolCapacity(Lease::TYPE_V4, no_class)); + EXPECT_EQ(196, subnet->getPoolCapacity(Lease::TYPE_V4, foo_class)); + EXPECT_EQ(200, subnet->getPoolCapacity(Lease::TYPE_V4, bar_class)); + EXPECT_EQ(200, subnet->getPoolCapacity(Lease::TYPE_V4, three_classes)); } // Checks that it is not allowed to add invalid pools. @@ -647,6 +733,37 @@ TEST(Subnet6Test, Pool6getCapacity) { EXPECT_EQ(uint64_t(4294967296ull + 4294967296ull + 65536), subnet->getPoolCapacity(Lease::TYPE_NA)); + // Now play with classes + + // This client does not belong to any class. + isc::dhcp::ClientClasses no_class; + + // This client belongs to foo only. + isc::dhcp::ClientClasses foo_class; + foo_class.insert("foo"); + + // This client belongs to bar only. I like that client. + isc::dhcp::ClientClasses bar_class; + bar_class.insert("bar"); + + // This client belongs to foo, bar and baz classes. + isc::dhcp::ClientClasses three_classes; + three_classes.insert("foo"); + three_classes.insert("bar"); + three_classes.insert("baz"); + + pool3->allowClientClass("bar"); + + // Pool3 requires a member of bar + EXPECT_EQ(uint64_t(4294967296ull + 65536), + subnet->getPoolCapacity(Lease::TYPE_NA, no_class)); + EXPECT_EQ(uint64_t(4294967296ull + 65536), + subnet->getPoolCapacity(Lease::TYPE_NA, foo_class)); + EXPECT_EQ(uint64_t(4294967296ull + 4294967296ull + 65536), + subnet->getPoolCapacity(Lease::TYPE_NA, bar_class)); + EXPECT_EQ(uint64_t(4294967296ull + 4294967296ull + 65536), + subnet->getPoolCapacity(Lease::TYPE_NA, three_classes)); + // 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); @@ -657,6 +774,7 @@ TEST(Subnet6Test, Pool6getCapacity) { subnet->addPool(pool5); EXPECT_EQ(std::numeric_limits::max(), subnet->getPoolCapacity(Lease::TYPE_NA)); + } // Test checks whether the number of prefixes available in the pools are @@ -725,6 +843,41 @@ TEST(Subnet6Test, Pool6InSubnet6) { mypool = subnet->getPool(Lease::TYPE_NA, IOAddress("2001:db8:1:3::dead:beef")); EXPECT_EQ(mypool, pool3); + + // Now play with classes + + // This client does not belong to any class. + isc::dhcp::ClientClasses no_class; + + // This client belongs to foo only. + isc::dhcp::ClientClasses foo_class; + foo_class.insert("foo"); + + // This client belongs to bar only. I like that client. + isc::dhcp::ClientClasses bar_class; + bar_class.insert("bar"); + + // This client belongs to foo, bar and baz classes. + isc::dhcp::ClientClasses three_classes; + three_classes.insert("foo"); + three_classes.insert("bar"); + three_classes.insert("baz"); + + pool3->allowClientClass("bar"); + + // Pool3 requires a member of bar + mypool = subnet->getPool(Lease::TYPE_NA, no_class, + IOAddress("2001:db8:1:3::dead:beef")); + EXPECT_FALSE(mypool); + mypool = subnet->getPool(Lease::TYPE_NA, foo_class, + IOAddress("2001:db8:1:3::dead:beef")); + EXPECT_FALSE(mypool); + mypool = subnet->getPool(Lease::TYPE_NA, bar_class, + IOAddress("2001:db8:1:3::dead:beef")); + EXPECT_EQ(mypool, pool3); + mypool = subnet->getPool(Lease::TYPE_NA, three_classes, + IOAddress("2001:db8:1:3::dead:beef")); + EXPECT_EQ(mypool, pool3); } // Check if Subnet6 supports different types of pools properly.