Browse Source

[3565] Unit-tests written for host reservations by MAC

Tomek Mrugalski 10 years ago
parent
commit
75030024b9

+ 99 - 0
src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc

@@ -1233,6 +1233,105 @@ TEST_F(AllocEngine6Test, reservedAddressRenewReserved) {
 /// - AllocEngine::removeLeases
 /// - AllocEngine::removeNonreservedLeases6
 
+// Checks that a client gets the address reserved (in-pool case)
+// This test checks the behavior of the allocation engine in the following
+// scenario:
+// - Client has no lease in the database.
+// - Client has an in-pool reservation.
+// - Client sends SOLICIT without any hints.
+// - Client is allocated a reserved address.
+//
+// Note that DHCPv6 client can, but don't have to send any hints in its
+// Solicit message.
+TEST_F(AllocEngine6Test, reservedAddressByMacInPoolSolicitNoHint) {
+    // Create reservation for the client. This is in-pool reservation,
+    // as the pool is 2001:db8:1::10 - 2001:db8:1::20.
+    createHost6HWAddr(true, IPv6Resrv::TYPE_NA, hwaddr_,
+                      IOAddress("2001:db8:1::1c"), 128);
+
+    AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
+
+    Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("::"), true);
+    ASSERT_TRUE(lease);
+    EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText());
+}
+
+// Checks that a client gets the address reserved (in-pool case)
+// This test checks the behavior of the allocation engine in the following
+// scenario:
+// - Client has no lease in the database.
+// - Client has an in-pool reservation.
+// - Client sends REQUEST without any hints.
+// - Client is allocated a reserved address.
+//
+// Note that DHCPv6 client must send an address in REQUEST that the server
+// offered in Advertise. Nevertheless, the client may ignore this requirement.
+TEST_F(AllocEngine6Test, reservedAddressByMacInPoolRequestNoHint) {
+    // Create reservation for the client. This is in-pool reservation,
+    // as the pool is 2001:db8:1::10 - 2001:db8:1::20.
+    createHost6HWAddr(true, IPv6Resrv::TYPE_NA, hwaddr_,
+                      IOAddress("2001:db8:1::1c"), 128);
+
+    AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
+
+    Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("::"), false);
+    ASSERT_TRUE(lease);
+    EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText());
+}
+
+
+// Checks that a client gets the address reserved (in-pool case)
+// This test checks the behavior of the allocation engine in the following
+// scenario:
+// - Client has no lease in the database.
+// - Client has an in-pool reservation.
+// - Client sends SOLICIT with a hint that does not match reservation
+// - Client is allocated a reserved address, not the hint.
+//
+// Note that DHCPv6 client can, but don't have to send any hints in its
+// Solicit message.
+TEST_F(AllocEngine6Test, reservedAddressByMacInPoolSolicitValidHint) {
+    // Create reservation for the client. This is in-pool reservation,
+    // as the pool is 2001:db8:1::10 - 2001:db8:1::20.
+    createHost6HWAddr(true, IPv6Resrv::TYPE_NA, hwaddr_,
+                      IOAddress("2001:db8:1::1c"), 128);
+
+    AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
+
+    // Let's pretend the client sends hint 2001:db8:1::10.
+    Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::10"), true);
+    ASSERT_TRUE(lease);
+
+    // The hint should be ignored and the reserved address should be assigned
+    EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText());
+}
+
+// Checks that a client gets the address reserved (in-pool case)
+// This test checks the behavior of the allocation engine in the following
+// scenario:
+// - Client has no lease in the database.
+// - Client has an in-pool reservation.
+// - Client sends REQUEST with a hint that does not match reservation
+// - Client is allocated a reserved address, not the hint.
+//
+// Note that DHCPv6 client must send an address in REQUEST that the server
+// offered in Advertise. Nevertheless, the client may ignore this requirement.
+TEST_F(AllocEngine6Test, reservedAddressByMacInPoolRequestValidHint) {
+    // Create reservation for the client This is in-pool reservation,
+    // as the pool is 2001:db8:1::10 - 2001:db8:1::20.
+    createHost6HWAddr(true, IPv6Resrv::TYPE_NA, hwaddr_,
+                      IOAddress("2001:db8:1::1c"), 128);
+
+    AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
+
+    // Let's pretend the client sends hint 2001:db8:1::10.
+    Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::10"), false);
+    ASSERT_TRUE(lease);
+
+    // The hint should be ignored and the reserved address should be assigned
+    EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText());
+}
+
 }; // namespace test
 }; // namespace dhcp
 }; // namespace isc

+ 23 - 0
src/lib/dhcpsrv/tests/alloc_engine_utils.cc

@@ -49,6 +49,11 @@ AllocEngine6Test::AllocEngine6Test() {
     duid_ = DuidPtr(new DUID(std::vector<uint8_t>(8, 0x42)));
     iaid_ = 42;
 
+    // Let's use odd hardware type to check if there is no Ethernet
+    // hardcoded anywhere.
+    const uint8_t mac[] = { 0, 1, 22, 33, 44, 55};
+    hwaddr_ = HWAddrPtr(new HWAddr(mac, sizeof(mac), HTYPE_FDDI));
+
     // Initialize a subnet and short address pool.
     initSubnet(IOAddress("2001:db8:1::"),
                IOAddress("2001:db8:1::10"),
@@ -77,6 +82,23 @@ AllocEngine6Test::initSubnet(const asiolink::IOAddress& subnet,
     cfg_mgr.commit();
 }
 
+HostPtr
+AllocEngine6Test::createHost6HWAddr(bool add_to_host_mgr, IPv6Resrv::Type type,
+                                    HWAddrPtr& hwaddr, const asiolink::IOAddress& addr,
+                                    uint8_t prefix_len) {
+    HostPtr host(new Host(&hwaddr->hwaddr_[0], hwaddr->hwaddr_.size(),
+                          Host::IDENT_HWADDR, SubnetID(0), subnet_->getID(),
+                          asiolink::IOAddress("0.0.0.0")));
+    IPv6Resrv resv(type, addr, prefix_len);
+    host->addReservation(resv);
+
+    if (add_to_host_mgr) {
+        CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
+        CfgMgr::instance().commit();
+    }
+    return (host);
+}
+
 Lease6Collection
 AllocEngine6Test::allocateTest(AllocEngine& engine, const Pool6Ptr& pool,
                                const asiolink::IOAddress& hint, bool fake,
@@ -142,6 +164,7 @@ AllocEngine6Test::simpleAlloc6Test(const Pool6Ptr& pool, const IOAddress& hint,
     Lease6Ptr lease;
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, hint, type,
                                     false, false, "", fake);
+    ctx.hwaddr_ = hwaddr_;
 
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
 

+ 15 - 1
src/lib/dhcpsrv/tests/alloc_engine_utils.h

@@ -270,7 +270,7 @@ public:
     void allocBogusHint6(Lease::Type type, asiolink::IOAddress hint,
                          uint8_t expected_pd_len);
 
-    /// @brief Utility function that creates a host reservation
+    /// @brief Utility function that creates a host reservation (duid)
     ///
     /// @param add_to_host_mgr true if the reservation should be added
     /// @param type specifies reservation type
@@ -293,11 +293,25 @@ public:
         return (host);
     }
 
+    /// @brief Utility function that creates a host reservation (hwaddr)
+    ///
+    /// @param add_to_host_mgr true if the reservation should be added
+    /// @param type specifies reservation type
+    /// @param hwaddr hardware address to be reserved to
+    /// @param addr specifies reserved address or prefix
+    /// @param prefix_len prefix length (should be 128 for addresses)
+    /// @return created Host object.
+    HostPtr
+    createHost6HWAddr(bool add_to_host_mgr, IPv6Resrv::Type type,
+                      HWAddrPtr& hwaddr, const asiolink::IOAddress& addr,
+                      uint8_t prefix_len);
+
     virtual ~AllocEngine6Test() {
         factory_.destroy();
     }
 
     DuidPtr duid_;            ///< client-identifier (value used in tests)
+    HWAddrPtr hwaddr_;          ///< client's hardware address
     uint32_t iaid_;           ///< IA identifier (value used in tests)
     Subnet6Ptr subnet_;       ///< subnet6 (used in tests)
     Pool6Ptr pool_;           ///< NA pool belonging to subnet_