]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1418] Checkpoint: finished v4 part, v6 and doc to do
authorFrancis Dupont <fdupont@isc.org>
Thu, 12 Nov 2020 18:26:10 +0000 (19:26 +0100)
committerFrancis Dupont <fdupont@isc.org>
Mon, 11 Jan 2021 15:05:46 +0000 (16:05 +0100)
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
src/bin/dhcp4/tests/hooks_unittest.cc
src/lib/dhcpsrv/alloc_engine.cc
src/lib/dhcpsrv/alloc_engine.h
src/lib/dhcpsrv/tests/alloc_engine4_unittest.cc
src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc
src/lib/dhcpsrv/tests/alloc_engine_utils.h

index 07b55de6bf06a1e800538cccf16de24362e004d7..46d55bf9b44e0511722a323bccf1ef875b5923ea 100644 (file)
@@ -1731,6 +1731,86 @@ TEST_F(Dhcpv4SrvTest, discoverEchoClientId) {
     checkClientId(offer, clientid);
 }
 
+// This test verifies that incoming DISCOVER can reuse an existing lease.
+TEST_F(Dhcpv4SrvTest, DiscoverReuse) {
+    IfaceMgrTestConfig test_config(true);
+    IfaceMgr::instance().openSockets4();
+
+    boost::scoped_ptr<NakedDhcpv4Srv> srv;
+    ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
+
+    // Enable lease reuse.
+    subnet_->setCacheThreshold(.1);
+
+    const IOAddress addr("192.0.2.106");
+    const uint32_t temp_valid = subnet_->getValid();
+    const int delta = 100;
+    const time_t temp_timestamp = time(NULL) - delta;
+
+    // Generate client-id also sets client_id_ member
+    OptionPtr clientid = generateClientId();
+
+    // Check that the address we are about to use is indeed in pool
+    ASSERT_TRUE(subnet_->inPool(Lease::TYPE_V4, addr));
+
+    // let's create a lease and put it in the LeaseMgr
+    uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
+    HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER));
+    Lease4Ptr used(new Lease4(IOAddress("192.0.2.106"), hwaddr2,
+                              &client_id_->getDuid()[0], client_id_->getDuid().size(),
+                              temp_valid, temp_timestamp, subnet_->getID()));
+    ASSERT_TRUE(LeaseMgrFactory::instance().addLease(used));
+
+    // Check that the lease is really in the database
+    Lease4Ptr l = LeaseMgrFactory::instance().getLease4(addr);
+    ASSERT_TRUE(l);
+
+    // Check that preferred, valid and cltt really set.
+    // Constructed lease looks as if it was assigned 10 seconds ago
+    EXPECT_EQ(l->valid_lft_, temp_valid);
+    EXPECT_EQ(l->cltt_, temp_timestamp);
+
+    // Let's create a DISCOVER
+    Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
+    dis->setRemoteAddr(IOAddress(addr));
+    dis->addOption(clientid);
+    dis->setIface("eth0");
+    dis->setIndex(ETH0_INDEX);
+    dis->setHWAddr(hwaddr2);
+
+    // Pass it to the server and get an offer
+    Pkt4Ptr offer = srv->processDiscover(dis);
+
+    // Check if we get response at all
+    checkResponse(offer, DHCPOFFER, 1234);
+
+    // Check valid lifetime (temp_valid - age)
+    OptionUint32Ptr opt = boost::dynamic_pointer_cast<
+        OptionUint32>(offer->getOption(DHO_DHCP_LEASE_TIME));
+    ASSERT_TRUE(opt);
+    EXPECT_GE(subnet_->getValid() - delta, opt->getValue());
+    EXPECT_LE(subnet_->getValid() - delta - 10, opt->getValue());
+
+    // Check address
+    EXPECT_EQ(addr, offer->getYiaddr());
+
+    // Check T1
+    opt = boost::dynamic_pointer_cast<
+        OptionUint32>(offer->getOption(DHO_DHCP_RENEWAL_TIME));
+    ASSERT_TRUE(opt);
+    EXPECT_EQ(opt->getValue(), subnet_->getT1());
+
+    // Check T2
+    opt = boost::dynamic_pointer_cast<
+        OptionUint32>(offer->getOption(DHO_DHCP_REBINDING_TIME));
+    ASSERT_TRUE(opt);
+    EXPECT_EQ(opt->getValue(), subnet_->getT2());
+
+    // Check identifiers
+    checkServerId(offer, srv->getServerID());
+    checkClientId(offer, clientid);
+}
+
 // Check that option 58 and 59 are not included if they are not specified.
 TEST_F(Dhcpv4SrvTest, RequestNoTimers) {
     IfaceMgrTestConfig test_config(true);
@@ -2158,6 +2238,96 @@ TEST_F(Dhcpv4SrvTest, RenewMaxLifetime) {
 
 } // end of Renew*Lifetime
 
+// This test verifies that incoming RENEW can reuse an existing lease.
+TEST_F(Dhcpv4SrvTest, RenewReuse) {
+    IfaceMgrTestConfig test_config(true);
+    IfaceMgr::instance().openSockets4();
+
+    boost::scoped_ptr<NakedDhcpv4Srv> srv;
+    ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
+
+    // Enable lease reuse.
+    subnet_->setCacheThreshold(.1);
+
+    const IOAddress addr("192.0.2.106");
+    const uint32_t temp_valid = subnet_->getValid();
+    const int delta = 100;
+    const time_t temp_timestamp = time(NULL) - delta;
+
+    // Generate client-id also sets client_id_ member
+    OptionPtr clientid = generateClientId();
+
+    // Check that the address we are about to use is indeed in pool
+    ASSERT_TRUE(subnet_->inPool(Lease::TYPE_V4, addr));
+
+    // let's create a lease and put it in the LeaseMgr
+    uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
+    HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER));
+    Lease4Ptr used(new Lease4(IOAddress("192.0.2.106"), hwaddr2,
+                              &client_id_->getDuid()[0], client_id_->getDuid().size(),
+                              temp_valid, temp_timestamp, subnet_->getID()));
+    ASSERT_TRUE(LeaseMgrFactory::instance().addLease(used));
+
+    // Check that the lease is really in the database
+    Lease4Ptr l = LeaseMgrFactory::instance().getLease4(addr);
+    ASSERT_TRUE(l);
+
+    // Check that preferred, valid and cltt really set.
+    // Constructed lease looks as if it was assigned 10 seconds ago
+    EXPECT_EQ(l->valid_lft_, temp_valid);
+    EXPECT_EQ(l->cltt_, temp_timestamp);
+
+    // Let's create a RENEW
+    Pkt4Ptr req = Pkt4Ptr(new Pkt4(DHCPREQUEST, 1234));
+    req->setRemoteAddr(IOAddress(addr));
+    req->setYiaddr(addr);
+    req->setCiaddr(addr); // client's address
+    req->setIface("eth0");
+    req->setIndex(ETH0_INDEX);
+
+    req->addOption(clientid);
+    req->setHWAddr(hwaddr2);
+
+    // Pass it to the server and hope for a REPLY
+    Pkt4Ptr ack = srv->processRequest(req);
+
+    // Check if we get response at all
+    checkResponse(ack, DHCPACK, 1234);
+
+    // Check valid lifetime (temp_valid - age)
+    OptionUint32Ptr opt = boost::dynamic_pointer_cast<
+        OptionUint32>(ack->getOption(DHO_DHCP_LEASE_TIME));
+    ASSERT_TRUE(opt);
+    EXPECT_GE(subnet_->getValid() - delta, opt->getValue());
+    EXPECT_LE(subnet_->getValid() - delta - 10, opt->getValue());
+
+    // Check address
+    EXPECT_EQ(addr, ack->getYiaddr());
+
+    // Check T1
+    opt = boost::dynamic_pointer_cast<
+        OptionUint32>(ack->getOption(DHO_DHCP_RENEWAL_TIME));
+    ASSERT_TRUE(opt);
+    EXPECT_EQ(opt->getValue(), subnet_->getT1());
+
+    // Check T2
+    opt = boost::dynamic_pointer_cast<
+        OptionUint32>(ack->getOption(DHO_DHCP_REBINDING_TIME));
+    ASSERT_TRUE(opt);
+    EXPECT_EQ(opt->getValue(), subnet_->getT2());
+
+    // Check identifiers
+    checkServerId(ack, srv->getServerID());
+    checkClientId(ack, clientid);
+
+    // Check that the lease is really in the database
+    Lease4Ptr lease = checkLease(ack, clientid, req->getHWAddr(), addr);
+    ASSERT_TRUE(lease);
+
+    // Check that the lease was not updated
+    EXPECT_EQ(temp_timestamp, lease->cltt_);
+}
+
 // This test verifies that the logic which matches server identifier in the
 // received message with server identifiers used by a server works correctly:
 // - a message with no server identifier is accepted,
index ed51ae97846dd495e62ad1cac71cd7b1e7b4024a..991cf301ace676b1507e9e1b323610a639ecad3a 100644 (file)
@@ -2039,6 +2039,78 @@ TEST_F(HooksDhcpv4SrvTest, leases4CommittedRequest) {
     checkCalloutHandleReset(client.getContext().query_);
 }
 
+// This test verifies that the callout installed on the leases4_committed hook
+// point is executed as a result of DHCPREQUEST message sent to reuse an
+// an existing lease.
+TEST_F(HooksDhcpv4SrvTest, leases4CommittedReuse) {
+    IfaceMgrTestConfig test_config(true);
+    IfaceMgr::instance().openSockets4();
+
+    ASSERT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+                    "leases4_committed", leases4_committed_callout));
+
+
+    // Modify the subnet to reuse leases.
+    subnet_->setCacheThreshold(.25);
+
+    Dhcp4Client client(Dhcp4Client::SELECTING);
+    client.setIfaceName("eth1");
+    client.setIfaceIndex(ETH1_INDEX);
+    ASSERT_NO_THROW(client.doDORA(boost::shared_ptr<IOAddress>(new IOAddress("192.0.2.100"))));
+
+    // Make sure that we received a response
+    ASSERT_TRUE(client.getContext().response_);
+
+    // Check that the callback called is indeed the one we installed
+    EXPECT_EQ("leases4_committed", callback_name_);
+
+    // Check if all expected parameters were really received
+    vector<string> expected_argument_names;
+    expected_argument_names.push_back("query4");
+    expected_argument_names.push_back("deleted_leases4");
+    expected_argument_names.push_back("leases4");
+
+    sort(expected_argument_names.begin(), expected_argument_names.end());
+    EXPECT_TRUE(callback_argument_names_ == expected_argument_names);
+
+    // Newly allocated lease should be returned.
+    ASSERT_TRUE(callback_lease4_);
+    EXPECT_EQ("192.0.2.100", callback_lease4_->addr_.toText());
+
+    // Deleted lease must not be present, because it is a new allocation.
+    EXPECT_FALSE(callback_deleted_lease4_);
+
+    // Pkt passed to a callout must be configured to copy retrieved options.
+    EXPECT_TRUE(callback_qry_options_copy_);
+
+    // Check if the callout handle state was reset after the callout.
+    checkCalloutHandleReset(client.getContext().query_);
+
+    resetCalloutBuffers();
+
+    // Renew the lease and make sure that the callout has been executed.
+    client.setState(Dhcp4Client::RENEWING);
+    ASSERT_NO_THROW(client.doRequest());
+
+    // Make sure that we received a response
+    ASSERT_TRUE(client.getContext().response_);
+
+    // Check that the callback called is indeed the one we installed
+    EXPECT_EQ("leases4_committed", callback_name_);
+
+    // Renewed lease should not be present because it was renewed.
+    EXPECT_FALSE(callback_lease4_);
+
+    // Deleted lease must not be present, because it renews the same address.
+    EXPECT_FALSE(callback_deleted_lease4_);
+
+    // Pkt passed to a callout must be configured to copy retrieved options.
+    EXPECT_TRUE(callback_qry_options_copy_);
+
+    // Check if the callout handle state was reset after the callout.
+    checkCalloutHandleReset(client.getContext().query_);
+}
+
 // This test verifies that it is possible to park a packet as a result of
 // the leases4_committed callouts.
 TEST_F(HooksDhcpv4SrvTest, leases4CommittedParkRequests) {
index 53b5456047c0af8d6b3bad3364e39992ecb18037..a268e19d7ce662eb1f6c8d046956ed6372b72e15 100644 (file)
@@ -3770,7 +3770,7 @@ AllocEngine::createLease4(const ClientContext4& ctx, const IOAddress& addr,
     lease->hostname_ = ctx.hostname_;
 
     // Add(update) the extended information on the lease.
-    updateLease4ExtendedInfo(lease, ctx);
+    static_cast<void>(updateLease4ExtendedInfo(lease, ctx));
 
     // Let's execute all callouts registered for lease4_select
     if (ctx.callout_handle_ &&
@@ -3869,7 +3869,10 @@ AllocEngine::renewLease4(const Lease4Ptr& lease,
     ctx.old_lease_.reset(new Lease4(*old_values));
 
     // Update the lease with the information from the context.
-    updateLease4Information(lease, ctx);
+    // If there was no significant changes, try reuse.
+    if (!updateLease4Information(lease, ctx)) {
+        setLeaseRemainingLife(lease, ctx);
+    }
 
     if (!ctx.fake_allocation_) {
         // If the lease is expired we have to reclaim it before
@@ -3931,7 +3934,7 @@ AllocEngine::renewLease4(const Lease4Ptr& lease,
         /// DROP status does not make sense here.
     }
 
-    if (!ctx.fake_allocation_ && !skip) {
+    if (!ctx.fake_allocation_ && !skip && (lease->remaining_valid_lft_ == 0)) {
         // for REQUEST we do update the lease
         LeaseMgrFactory::instance().updateLease4(lease);
 
@@ -3978,7 +3981,7 @@ AllocEngine::reuseExpiredLease4(Lease4Ptr& expired,
         expired->state_ = Lease::STATE_DEFAULT;
     }
 
-    updateLease4Information(expired, ctx);
+    static_cast<void>(updateLease4Information(expired, ctx));
 
     LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE_DETAIL_DATA,
               ALLOC_ENGINE_V4_REUSE_EXPIRED_LEASE_DATA)
@@ -4221,12 +4224,29 @@ AllocEngine::allocateUnreservedLease4(ClientContext4& ctx) {
     return (new_lease);
 }
 
-void
+bool
 AllocEngine::updateLease4Information(const Lease4Ptr& lease,
                                      AllocEngine::ClientContext4& ctx) const {
-    lease->subnet_id_ = ctx.subnet_->getID();
-    lease->hwaddr_ = ctx.hwaddr_;
-    lease->client_id_ = ctx.subnet_->getMatchClientId() ? ctx.clientid_ : ClientIdPtr();
+    bool changed = false;
+    if (lease->subnet_id_ != ctx.subnet_->getID()) {
+        changed = true;
+        lease->subnet_id_ = ctx.subnet_->getID();
+    }
+    if ((!ctx.hwaddr_ && lease->hwaddr_) ||
+        (ctx.hwaddr_ &&
+         (!lease->hwaddr_ || (*ctx.hwaddr_ != *lease->hwaddr_)))) {
+            changed = true;
+            lease->hwaddr_ = ctx.hwaddr_;
+    }
+    if (ctx.subnet_->getMatchClientId() && ctx.clientid_) {
+        if (!lease->client_id_ || (*ctx.clientid_ != *lease->client_id_)) {
+            changed = true;
+            lease->client_id_ = ctx.clientid_;
+        }
+    } else if (lease->client_id_) {
+        changed = true;
+        lease->client_id_ = ClientIdPtr();
+    }
     lease->cltt_ = time(NULL);
     if (ctx.query_->inClass("BOOTP")) {
         // BOOTP uses infinite valid lifetime.
@@ -4244,28 +4264,43 @@ AllocEngine::updateLease4Information(const Lease4Ptr& lease,
             lease->valid_lft_ = ctx.subnet_->getValid();
         }
     }
+    // Reduced valid lifetime is a significant change.
+    if (lease->valid_lft_ < lease->current_valid_lft_) {
+        changed = true;
+    }
 
-    lease->fqdn_fwd_ = ctx.fwd_dns_update_;
-    lease->fqdn_rev_ = ctx.rev_dns_update_;
-    lease->hostname_ = ctx.hostname_;
+    if ((lease->fqdn_fwd_ != ctx.fwd_dns_update_) ||
+        (lease->fqdn_rev_ != ctx.rev_dns_update_) ||
+        (lease->hostname_ != ctx.hostname_)) {
+        changed = true;
+        lease->fqdn_fwd_ = ctx.fwd_dns_update_;
+        lease->fqdn_rev_ = ctx.rev_dns_update_;
+        lease->hostname_ = ctx.hostname_;
+    }
 
     // Add(update) the extended information on the lease.
-    updateLease4ExtendedInfo(lease, ctx);
+    if (updateLease4ExtendedInfo(lease, ctx)) {
+        changed = true;
+    }
+
+    return (changed);
 }
 
-void
+bool
 AllocEngine::updateLease4ExtendedInfo(const Lease4Ptr& lease,
                                       const AllocEngine::ClientContext4& ctx) const {
+    bool changed = false;
+
     // If storage is not enabled then punt.
     if (!ctx.subnet_->getStoreExtendedInfo()) {
-        return;
+        return (changed);
     }
 
     // Look for relay agent information option (option 82)
     OptionPtr rai = ctx.query_->getOption(DHO_DHCP_AGENT_OPTIONS);
     if (!rai) {
         // Pkt4 doesn't have it, so nothing to store (or update).
-        return;
+        return (changed);
     }
 
     // Create a StringElement with the hex string for relay-agent-info.
@@ -4284,24 +4319,31 @@ AllocEngine::updateLease4ExtendedInfo(const Lease4Ptr& lease,
     }
 
     // Add/replace the extended info entry.
-    user_context->set("ISC", extended_info);
+    ConstElementPtr old_extended_info = user_context->get("ISC");
+    if (!old_extended_info || (*old_extended_info != *extended_info)) {
+        changed = true;
+        user_context->set("ISC", extended_info);
+    }
 
     // Update the lease's user_context.
     lease->setContext(user_context);
+
+    return (changed);
 }
 
-void
+bool
 AllocEngine::updateLease6ExtendedInfo(const Lease6Ptr& lease,
                                       const AllocEngine::ClientContext6& ctx) const {
+    bool changed = false;
 
     // If storage is not enabled then punt.
     if (!ctx.subnet_->getStoreExtendedInfo()) {
-        return;
+        return (changed);
     }
 
     // If we do not have relay information, then punt.
     if (ctx.query_->relay_info_.empty()) {
-        return;
+        return (changed);
     }
 
     // We need to convert the vector of RelayInfo instances in
@@ -4355,10 +4397,16 @@ AllocEngine::updateLease6ExtendedInfo(const Lease6Ptr& lease,
     }
 
     // Add/replace the extended info entry.
-    user_context->set("ISC", extended_info);
+    ConstElementPtr old_extended_info = user_context->get("ISC");
+    if (!old_extended_info || (*old_extended_info != *extended_info)) {
+        changed = true;
+        user_context->set("ISC", extended_info);
+    }
 
     // Update the lease's user_context.
     lease->setContext(user_context);
+
+    return (changed);
 }
 
 void
@@ -4370,6 +4418,9 @@ AllocEngine::setLeaseRemainingLife(const Lease4Ptr& lease,
     if (!subnet) {
         return;
     }
+    if (lease->state_ != Lease::STATE_DEFAULT) {
+        return;
+    }
 
     // Always reuse infinite lifetime leases.
     if (lease->valid_lft_ == Lease::INFINITY_LFT) {
@@ -4378,11 +4429,11 @@ AllocEngine::setLeaseRemainingLife(const Lease4Ptr& lease,
     }
 
     // Refuse time not going forward.
-    if (lease->cltt_ >= lease->current_cltt_) {
+    if (lease->cltt_ < lease->current_cltt_) {
         return;
     }
 
-    uint32_t age = lease->current_cltt_ - lease->cltt_;
+    uint32_t age = lease->cltt_ - lease->current_cltt_;
     // Already expired.
     if (age >= lease->current_valid_lft_) {
         return;
@@ -4409,6 +4460,11 @@ AllocEngine::setLeaseRemainingLife(const Lease4Ptr& lease,
         }
     }
 
+    // No cache.
+    if (max_age == 0) {
+        return;
+    }
+
     // Seems to be reusable.
     lease->remaining_valid_lft_ = lease->current_valid_lft_ - age;
 }
@@ -4422,13 +4478,16 @@ AllocEngine::setLeaseRemainingLife(const Lease6Ptr& lease,
     if (!subnet) {
         return;
     }
+    if (lease->state_ != Lease::STATE_DEFAULT) {
+        return;
+    }
 
     // Refuse time not going forward.
-    if (lease->cltt_ >= lease->current_cltt_) {
+    if (lease->cltt_ < lease->current_cltt_) {
         return;
     }
 
-    uint32_t age = lease->current_cltt_ - lease->cltt_;
+    uint32_t age = lease->cltt_ - lease->current_cltt_;
     // Already expired.
     if (age >= lease->current_valid_lft_) {
         return;
@@ -4455,6 +4514,11 @@ AllocEngine::setLeaseRemainingLife(const Lease6Ptr& lease,
         }
     }
 
+    // No cache.
+    if (max_age == 0) {
+        return;
+    }
+
     // Seems to be reusable.
     if ((lease->remaining_preferred_lft_ == Lease::INFINITY_LFT) ||
         (lease->remaining_preferred_lft_ == 0)) {
index 6e1cdf903e816ec3fef4b282fa50d49cb43ff332..540a1dabf4d66f7ff80c7d567bf43750646a7d53 100644 (file)
@@ -1806,7 +1806,9 @@ private:
     /// @param [out] lease A pointer to the lease to be updated.
     /// @param ctx A context containing information from the server about the
     /// client and its message.
-    void updateLease4Information(const Lease4Ptr& lease,
+    /// @return True if there was a significant (e.g. other than cltt) change,
+    /// false otherwise.
+    bool updateLease4Information(const Lease4Ptr& lease,
                                  ClientContext4& ctx) const;
 
 protected:
@@ -1824,7 +1826,9 @@ protected:
     /// @param [out] lease A pointer to the lease to be updated.
     /// @param ctx A context containing information from the server about the
     /// client and its message.
-    void updateLease4ExtendedInfo(const Lease4Ptr& lease,
+    /// @return True if there was a significant (e.g. other than cltt) change,
+    /// false otherwise.
+    bool updateLease4ExtendedInfo(const Lease4Ptr& lease,
                                   const ClientContext4& ctx) const;
 
     /// @brief Stores additional client query parameters on a V6 lease
@@ -1842,7 +1846,9 @@ protected:
     /// @param [out] lease A pointer to the lease to be updated.
     /// @param ctx A context containing information from the server about the
     /// client and its message.
-    void updateLease6ExtendedInfo(const Lease6Ptr& lease,
+    /// @return True if there was a significant (e.g. other than cltt) change,
+    /// false otherwise.
+    bool updateLease6ExtendedInfo(const Lease6Ptr& lease,
                                   const ClientContext6& ctx) const;
 
 private:
index ffb2696f626073db55a8cc419c72bfe59b2f3f9a..84b348697fa5dd9fe5ae1a704bf65ad215580071 100644 (file)
@@ -3501,6 +3501,7 @@ TEST_F(AllocEngine4Test, updateExtendedInfo4) {
         std::string orig_context_json_; // user context the lease begins with
         std::string rai_data_;          // RAI option the client packet contains
         std::string exp_context_json_;  // expected user context on the lease
+        bool exp_ret;                   // expected returned value
     };
 
     // Test scenarios.
@@ -3509,37 +3510,43 @@ TEST_F(AllocEngine4Test, updateExtendedInfo4) {
         "no context, no rai",
         "",
         "",
-        ""
+        "",
+        false
     },
     {
         "some original context, no rai",
         "{\"foo\": 123}",
         "",
-        "{\"foo\": 123}"
+        "{\"foo\": 123}",
+        false
     },
     {
         "no original context, rai",
         "",
         "0x52050104aabbccdd",
         "{ \"ISC\": { \"relay-agent-info\": \"0x52050104AABBCCDD\" } }",
+        true
     },
     {
         "some original context, rai",
         "{\"foo\": 123}",
         "0x52050104aabbccdd",
-        "{ \"ISC\": { \"relay-agent-info\": \"0x52050104AABBCCDD\" }, \"foo\": 123 }"
+        "{ \"ISC\": { \"relay-agent-info\": \"0x52050104AABBCCDD\" }, \"foo\": 123 }",
+        true
     },
     {
         "original rai context, no rai",
         "{ \"ISC\": { \"relay-agent-info\": \"0x52050104AABBCCDD\" } }",
         "",
         "{ \"ISC\": { \"relay-agent-info\": \"0x52050104AABBCCDD\" } }",
+        false
     },
     {
         "original rai context, different rai",
         "{ \"ISC\": { \"relay-agent-info\": \"0x52050104AABBCCDD\" } }",
         "0x52050104ddeeffaa",
         "{ \"ISC\": { \"relay-agent-info\": \"0x52050104DDEEFFAA\" } }",
+        true
     }};
 
     // Create the allocation engine, context and lease.
@@ -3609,7 +3616,9 @@ TEST_F(AllocEngine4Test, updateExtendedInfo4) {
         }
 
         // Call AllocEngine::updateLease4ExtendeInfo().
-        ASSERT_NO_THROW_LOG(engine.callUpdateLease4ExtendedInfo(lease, ctx));
+        bool ret = false;
+        ASSERT_NO_THROW_LOG(ret = engine.callUpdateLease4ExtendedInfo(lease, ctx));
+        ASSERT_EQ(scenario.exp_ret, ret);
 
         // Verify the lease has the expected user context content.
         if (!exp_context) {
@@ -3827,6 +3836,435 @@ TEST_F(AllocEngine4Test, storeExtendedInfoDisabled4) {
     }
 }
 
+// This test checks if a lease can be reused in DHCPDISCOVER (fake allocation)
+// using cache threshold.
+TEST_F(AllocEngine4Test, discoverCacheThreshold4) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
+                                                 0, false)));
+    ASSERT_TRUE(engine);
+
+    // Set valid lifetime to 500.
+    subnet_->setValid(500);
+
+    // Set the threshold to 25%.
+    subnet_->setCacheThreshold(.25);
+
+    IOAddress addr("192.0.2.105");
+    time_t now = time(NULL) - 100; // Allocated 100 seconds ago.
+    Lease4Ptr lease(new Lease4(addr, hwaddr_, clientid_,
+                               500, now, subnet_->getID()));
+    ASSERT_FALSE(lease->expired());
+    ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
+
+    // Create a context for fake allocation.
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, addr,
+                                    false, false, "", true);
+
+    ctx.query_.reset(new Pkt4(DHCPDISCOVER, 1234));
+    lease = engine->allocateLease4(ctx);
+    // Check that we got that single lease.
+    ASSERT_TRUE(lease);
+    EXPECT_EQ(addr, lease->addr_);
+
+    // The lease was reused.
+    time_t age = lease->cltt_ - now;
+    EXPECT_GE(age, 100);
+    EXPECT_LE(age, 110);
+    EXPECT_EQ(500 - age, lease->remaining_valid_lft_);
+
+    // Check other lease parameters.
+    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
+    ASSERT_TRUE(lease->client_id_);
+    EXPECT_TRUE(*lease->client_id_ == *clientid_);
+    ASSERT_TRUE(lease->hwaddr_);
+    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
+}    
+
+// This test checks if a lease can be reused in DHCPREQUEST (real allocation)
+// using cache threshold.
+TEST_F(AllocEngine4Test, requestCacheThreshold4) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
+                                                 0, false)));
+    ASSERT_TRUE(engine);
+
+    // Set valid lifetime to 500.
+    subnet_->setValid(500);
+
+    // Set the threshold to 25%.
+    subnet_->setCacheThreshold(.25);
+
+    IOAddress addr("192.0.2.105");
+    time_t now = time(NULL) - 100; // Allocated 100 seconds ago.
+    Lease4Ptr lease(new Lease4(addr, hwaddr_, clientid_,
+                               500, now, subnet_->getID()));
+    ASSERT_FALSE(lease->expired());
+    // Copy the lease, so as it can be compared with.
+    Lease4Ptr original_lease(new Lease4(*lease));
+    ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
+
+    // Create a context for real allocation.
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, addr,
+                                    false, false, "", false);
+
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
+    lease = engine->allocateLease4(ctx);
+    // Check that we got that single lease.
+    ASSERT_TRUE(lease);
+    EXPECT_EQ(addr, lease->addr_);
+
+    // The lease was reused.
+    time_t age = lease->cltt_ - now;
+    EXPECT_GE(age, 100);
+    EXPECT_LE(age, 110);
+    EXPECT_EQ(500 - age, lease->remaining_valid_lft_);
+
+    // Check other lease parameters.
+    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
+    ASSERT_TRUE(lease->client_id_);
+    EXPECT_TRUE(*lease->client_id_ == *clientid_);
+    ASSERT_TRUE(lease->hwaddr_);
+    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
+
+    // Check the lease was not updated in the database.
+    Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(addr);
+    ASSERT_TRUE(from_mgr);
+
+    detailCompareLease(original_lease, from_mgr);
+}    
+
+/// We proved that there is no different from the "cache" feature between
+/// discovers and request at the exception of the lease database update.
+
+// This test checks if a lease can be reused in DHCPDISCOVER (fake allocation)
+// using cache max age.
+TEST_F(AllocEngine4Test, discoverCacheMaxAge4) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
+                                                 0, false)));
+    ASSERT_TRUE(engine);
+
+    // Set valid lifetime to 500.
+    subnet_->setValid(500);
+
+    // Set the max age to 200.
+    subnet_->setCacheMaxAge(200);
+
+    IOAddress addr("192.0.2.105");
+    time_t now = time(NULL) - 100; // Allocated 100 seconds ago.
+    Lease4Ptr lease(new Lease4(addr, hwaddr_, clientid_,
+                               500, now, subnet_->getID()));
+    ASSERT_FALSE(lease->expired());
+    ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
+
+    // Create a context for fake allocation.
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, addr,
+                                    false, false, "", true);
+
+    ctx.query_.reset(new Pkt4(DHCPDISCOVER, 1234));
+    lease = engine->allocateLease4(ctx);
+    // Check that we got that single lease.
+    ASSERT_TRUE(lease);
+    EXPECT_EQ(addr, lease->addr_);
+
+    // The lease was reused.
+    time_t age = lease->cltt_ - now;
+    EXPECT_GE(age, 100);
+    EXPECT_LE(age, 110);
+    EXPECT_EQ(500 - age, lease->remaining_valid_lft_);
+
+    // Check other lease parameters.
+    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
+    ASSERT_TRUE(lease->client_id_);
+    EXPECT_TRUE(*lease->client_id_ == *clientid_);
+    ASSERT_TRUE(lease->hwaddr_);
+    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
+}    
+
+// This test checks if a lease can be reused in DHCPREQUEST (real allocation)
+// using both cache threshold and max age.
+TEST_F(AllocEngine4Test, requestCacheBoth4) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
+                                                 0, false)));
+    ASSERT_TRUE(engine);
+
+    // Set valid lifetime to 500.
+    subnet_->setValid(500);
+
+    // Set the threshold to 25%.
+    subnet_->setCacheThreshold(.25);
+
+    // Set the max age to 200.
+    subnet_->setCacheMaxAge(200);
+
+    IOAddress addr("192.0.2.105");
+    time_t now = time(NULL) - 100; // Allocated 100 seconds ago.
+    Lease4Ptr lease(new Lease4(addr, hwaddr_, clientid_,
+                               500, now, subnet_->getID()));
+    ASSERT_FALSE(lease->expired());
+    // Copy the lease, so as it can be compared with.
+    Lease4Ptr original_lease(new Lease4(*lease));
+    ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
+
+    // Create a context for real allocation.
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, addr,
+                                    false, false, "", false);
+
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
+    lease = engine->allocateLease4(ctx);
+    // Check that we got that single lease.
+    ASSERT_TRUE(lease);
+    EXPECT_EQ(addr, lease->addr_);
+
+    // The lease was reused.
+    time_t age = lease->cltt_ - now;
+    EXPECT_GE(age, 100);
+    EXPECT_LE(age, 110);
+    EXPECT_EQ(500 - age, lease->remaining_valid_lft_);
+
+    // Check other lease parameters.
+    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
+    ASSERT_TRUE(lease->client_id_);
+    EXPECT_TRUE(*lease->client_id_ == *clientid_);
+    ASSERT_TRUE(lease->hwaddr_);
+    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
+
+    // Check the lease was not updated in the database.
+    Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(addr);
+    ASSERT_TRUE(from_mgr);
+
+    detailCompareLease(original_lease, from_mgr);
+}    
+
+// This test checks if a lease can't be reused in DHCPDISCOVER (fake allocation)
+// using too small cache threshold.
+TEST_F(AllocEngine4Test, discoverCacheBadThreshold4) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
+                                                 0, false)));
+    ASSERT_TRUE(engine);
+
+    // Set valid lifetime to 500.
+    subnet_->setValid(500);
+
+    // Set the threshold to 10%.
+    subnet_->setCacheThreshold(.1);
+
+    IOAddress addr("192.0.2.105");
+    time_t now = time(NULL) - 100; // Allocated 100 seconds ago.
+    Lease4Ptr lease(new Lease4(addr, hwaddr_, clientid_,
+                               500, now, subnet_->getID()));
+    ASSERT_FALSE(lease->expired());
+    ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
+
+    // Create a context for fake allocation.
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, addr,
+                                    false, false, "", true);
+
+    ctx.query_.reset(new Pkt4(DHCPDISCOVER, 1234));
+    lease = engine->allocateLease4(ctx);
+    // Check that we got that single lease.
+    ASSERT_TRUE(lease);
+    EXPECT_EQ(addr, lease->addr_);
+
+    // The lease was not reused.
+    EXPECT_EQ(0, lease->remaining_valid_lft_);
+}    
+
+// This test checks if a lease can't be reused in DHCPREQUEST (real allocation)
+// using too small cache max age.
+TEST_F(AllocEngine4Test, requestCacheBadMaxAge4) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
+                                                 0, false)));
+    ASSERT_TRUE(engine);
+
+    // Set valid lifetime to 500.
+    subnet_->setValid(500);
+
+    // Set the max age to 50.
+    subnet_->setCacheMaxAge(50);
+
+    IOAddress addr("192.0.2.105");
+    time_t now = time(NULL) - 100; // Allocated 100 seconds ago.
+    Lease4Ptr lease(new Lease4(addr, hwaddr_, clientid_,
+                               500, now, subnet_->getID()));
+    ASSERT_FALSE(lease->expired());
+
+    // Create a context for real allocation.
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, addr,
+                                    false, false, "", false);
+
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
+    lease = engine->allocateLease4(ctx);
+    // Check that we got that single lease.
+    ASSERT_TRUE(lease);
+    EXPECT_EQ(addr, lease->addr_);
+
+    // The lease was not reused.
+    EXPECT_EQ(0, lease->remaining_valid_lft_);
+
+    // Check the lease was updated in the database.
+    Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(addr);
+    ASSERT_TRUE(from_mgr);
+
+    detailCompareLease(lease, from_mgr);
+}    
+
+// This test checks if a lease can't be reused in DHCPDISCOVER (fake allocation)
+// when the valid lifetime was reduced.
+TEST_F(AllocEngine4Test, discoverCacheReducedValid4) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
+                                                 0, false)));
+    ASSERT_TRUE(engine);
+
+    // Set valid lifetime to 200.
+    subnet_->setValid(200);
+
+    // Set the threshold to 10%.
+    subnet_->setCacheThreshold(.1);
+
+    IOAddress addr("192.0.2.105");
+    time_t now = time(NULL) - 100; // Allocated 100 seconds ago.
+    Lease4Ptr lease(new Lease4(addr, hwaddr_, clientid_,
+                               500, now, subnet_->getID()));
+    ASSERT_FALSE(lease->expired());
+    ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
+
+    // Create a context for fake allocation.
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, addr,
+                                    false, false, "", true);
+
+    ctx.query_.reset(new Pkt4(DHCPDISCOVER, 1234));
+    lease = engine->allocateLease4(ctx);
+    // Check that we got that single lease.
+    ASSERT_TRUE(lease);
+    EXPECT_EQ(addr, lease->addr_);
+
+    // The lease was not reused.
+    EXPECT_EQ(0, lease->remaining_valid_lft_);
+}    
+
+// This test checks if a lease can't be reused in DHCPREQUEST (real allocation)
+// when DDNS parameter changed.
+TEST_F(AllocEngine4Test, requestCacheFwdDDNS4) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
+                                                 0, false)));
+    ASSERT_TRUE(engine);
+
+    // Set valid lifetime to 500.
+    subnet_->setValid(500);
+
+    // Set the max age to 200.
+    subnet_->setCacheMaxAge(200);
+
+    IOAddress addr("192.0.2.105");
+    time_t now = time(NULL) - 100; // Allocated 100 seconds ago.
+    Lease4Ptr lease(new Lease4(addr, hwaddr_, clientid_,
+                               500, now, subnet_->getID()));
+    ASSERT_FALSE(lease->expired());
+
+    // Create a context for real allocation with fwd_dns_update changed.
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, addr,
+                                    true, false, "", false);
+
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
+    lease = engine->allocateLease4(ctx);
+    // Check that we got that single lease.
+    ASSERT_TRUE(lease);
+    EXPECT_EQ(addr, lease->addr_);
+
+    // The lease was not reused.
+    EXPECT_EQ(0, lease->remaining_valid_lft_);
+
+    // Check the lease was updated in the database.
+    Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(addr);
+    ASSERT_TRUE(from_mgr);
+
+    detailCompareLease(lease, from_mgr);
+}    
+
+// This test checks if a lease can't be reused in DHCPDISCOVER (fake allocation)
+// when DDNS parameter changed.
+TEST_F(AllocEngine4Test, discoverCacheRevDDNS4) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
+                                                 0, false)));
+    ASSERT_TRUE(engine);
+
+    // Set valid lifetime to 500.
+    subnet_->setValid(500);
+
+    // Set the threshold to 10%.
+    subnet_->setCacheThreshold(.1);
+
+    IOAddress addr("192.0.2.105");
+    time_t now = time(NULL) - 100; // Allocated 100 seconds ago.
+    Lease4Ptr lease(new Lease4(addr, hwaddr_, clientid_,
+                               500, now, subnet_->getID()));
+    ASSERT_FALSE(lease->expired());
+    ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
+
+    // Create a context for fake allocation with rev_dns_update changed.
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, addr,
+                                    false, true, "", true);
+
+    ctx.query_.reset(new Pkt4(DHCPDISCOVER, 1234));
+    lease = engine->allocateLease4(ctx);
+    // Check that we got that single lease.
+    ASSERT_TRUE(lease);
+    EXPECT_EQ(addr, lease->addr_);
+
+    // The lease was not reused.
+    EXPECT_EQ(0, lease->remaining_valid_lft_);
+}    
+
+// This test checks if a lease can't be reused in DHCPREQUEST (real allocation)
+// when hostname changed.
+TEST_F(AllocEngine4Test, requestCacheHostname4) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
+                                                 0, false)));
+    ASSERT_TRUE(engine);
+
+    // Set valid lifetime to 500.
+    subnet_->setValid(500);
+
+    // Set the max age to 200.
+    subnet_->setCacheMaxAge(200);
+
+    IOAddress addr("192.0.2.105");
+    time_t now = time(NULL) - 100; // Allocated 100 seconds ago.
+    Lease4Ptr lease(new Lease4(addr, hwaddr_, clientid_,
+                               500, now, subnet_->getID(),
+                               false, false, "foo"));
+    ASSERT_FALSE(lease->expired());
+
+    // Create a context for real allocation with fwd_dns_update changed.
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, addr,
+                                    false, false, "bar", false);
+
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
+    lease = engine->allocateLease4(ctx);
+    // Check that we got that single lease.
+    ASSERT_TRUE(lease);
+    EXPECT_EQ(addr, lease->addr_);
+
+    // The lease was not reused.
+    EXPECT_EQ(0, lease->remaining_valid_lft_);
+    EXPECT_EQ("bar", lease->hostname_);
+
+    // Check the lease was updated in the database.
+    Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(addr);
+    ASSERT_TRUE(from_mgr);
+
+    detailCompareLease(lease, from_mgr);
+}    
+
 }  // namespace test
 }  // namespace dhcp
 }  // namespace isc
index b1c9f855afd23fabe6ffb0967eccfb7f7129e60a..cc782eb91485542fe9fdb335572d455cb9501108 100644 (file)
@@ -4050,6 +4050,7 @@ TEST_F(AllocEngine6ExtendedInfoTest, updateExtendedInfo6) {
         std::string orig_context_json_; // user context the lease begins with
         std::vector<Pkt6::RelayInfo> relays_; // vector of relays from pkt
         std::string exp_context_json_;  // expected user context on the lease
+        bool exp_ret;                   // expected returned value
     };
 
     // Test scenarios.
@@ -4058,20 +4059,23 @@ TEST_F(AllocEngine6ExtendedInfoTest, updateExtendedInfo6) {
         "no context, no relay",
         "",
         {},
-        ""
+        "",
+        false
     },
     {
         "some original context, no relay",
         "{\"foo\": 123}",
         {},
-        "{\"foo\": 123}"
+        "{\"foo\": 123}",
+        false
     },
     {
         "no original context, one relay",
         "",
         { relay1_ },
         "{ \"ISC\": { \"relays\": [ { \"hop\": 33, \"link\": \"2001:db8::1\","
-        " \"options\": \"0x00C800080102030405060708\", \"peer\": \"2001:db8::2\" } ] } }"
+        " \"options\": \"0x00C800080102030405060708\", \"peer\": \"2001:db8::2\" } ] } }",
+        true
     },
     {
         "some original context, one relay",
@@ -4079,7 +4083,8 @@ TEST_F(AllocEngine6ExtendedInfoTest, updateExtendedInfo6) {
         { relay1_ },
         "{ \"ISC\": { \"relays\": [ { \"hop\": 33, \"link\": \"2001:db8::1\","
         " \"options\": \"0x00C800080102030405060708\", \"peer\": \"2001:db8::2\" } ] },"
-        " \"foo\": 123 }"
+        " \"foo\": 123 }",
+        true
     },
     {
         "no original context, two relays",
@@ -4087,7 +4092,8 @@ TEST_F(AllocEngine6ExtendedInfoTest, updateExtendedInfo6) {
         { relay1_, relay2_ },
         "{ \"ISC\": { \"relays\": [ { \"hop\": 33, \"link\": \"2001:db8::1\","
         " \"options\": \"0x00C800080102030405060708\", \"peer\": \"2001:db8::2\" },"
-        " {\"hop\": 77, \"link\": \"2001:db8::3\", \"peer\": \"2001:db8::4\" } ] } }"
+        " {\"hop\": 77, \"link\": \"2001:db8::3\", \"peer\": \"2001:db8::4\" } ] } }",
+        true
     },
     {
         "original relay context, no relay",
@@ -4095,7 +4101,8 @@ TEST_F(AllocEngine6ExtendedInfoTest, updateExtendedInfo6) {
         " \"options\": \"0x00C800080102030405060708\", \"peer\": \"2001:db8::2\" } ] } }",
         {},
         "{ \"ISC\": { \"relays\": [ { \"hop\": 33, \"link\": \"2001:db8::1\","
-        " \"options\": \"0x00C800080102030405060708\", \"peer\": \"2001:db8::2\" } ] } }"
+        " \"options\": \"0x00C800080102030405060708\", \"peer\": \"2001:db8::2\" } ] } }",
+        false
     },
     {
         "original relay context, different relay",
@@ -4103,7 +4110,8 @@ TEST_F(AllocEngine6ExtendedInfoTest, updateExtendedInfo6) {
         " \"options\": \"0x00C800080102030405060708\", \"peer\": \"2001:db8::2\" } ] } }",
         { relay2_ },
         "{ \"ISC\": { \"relays\": [ { \"hop\": 77, \"link\": \"2001:db8::3\","
-        " \"peer\": \"2001:db8::4\" } ] } }"
+        " \"peer\": \"2001:db8::4\" } ] } }",
+        true
     }};
 
     // Allocate a lease.
@@ -4156,7 +4164,9 @@ TEST_F(AllocEngine6ExtendedInfoTest, updateExtendedInfo6) {
         ctx.query_->relay_info_ = scenario.relays_;
 
         // Call AllocEngine::updateLease6ExtendeInfo().
-        ASSERT_NO_THROW_LOG(engine_.callUpdateLease6ExtendedInfo(lease, ctx));
+        bool ret;
+        ASSERT_NO_THROW_LOG(ret = engine_.callUpdateLease6ExtendedInfo(lease, ctx));
+        ASSERT_EQ(scenario.exp_ret, ret);
 
         // Verify the lease has the expected user context content.
         if (!exp_context) {
index 28dc70ac0689f9dd7aa71e609bf80c3d44b2c773..fde5a37ad075c133920ca55eabf2229686656646 100644 (file)
@@ -93,17 +93,19 @@ public:
     /// @brief Wrapper method for invoking AllocEngine4::updateLease4ExtendedInfo().
     /// @param lease lease to update
     /// @param ctx current packet processing context
-    void callUpdateLease4ExtendedInfo(const Lease4Ptr& lease,
+    /// @return the changed returned value
+    bool callUpdateLease4ExtendedInfo(const Lease4Ptr& lease,
                                       AllocEngine::ClientContext4& ctx) const {
-        updateLease4ExtendedInfo(lease,ctx);
+        return (updateLease4ExtendedInfo(lease, ctx));
     }
 
     /// @brief Wrapper method for invoking AllocEngine6::updateLease6ExtendedInfo().
     /// @param lease lease to update
     /// @param ctx current packet processing context
-    void callUpdateLease6ExtendedInfo(const Lease6Ptr& lease,
+    /// @return the changed returned value
+    bool callUpdateLease6ExtendedInfo(const Lease6Ptr& lease,
                                       AllocEngine::ClientContext6& ctx) const {
-        updateLease6ExtendedInfo(lease,ctx);
+        return (updateLease6ExtendedInfo(lease, ctx));
     }
 
 };
@@ -559,6 +561,7 @@ public:
             EXPECT_TRUE(*lease->client_id_ == *clientid_);
         }
         EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
+        EXPECT_EQ(0, lease->remaining_valid_lft_);
         /// @todo: check cltt
     }
 
@@ -620,8 +623,8 @@ public:
                                      ///< allocation engine functions.
 };
 
-}; // namespace test
-}; // namespace dhcp
-}; // namespace isc
+} // namespace test
+} // namespace dhcp
+} // namespace isc
 
 #endif