Browse Source

[master] Merge branch 'trac3146' (Abstract LeaseMgr support for PD)

Conflicts:
	ChangeLog
Tomek Mrugalski 11 years ago
parent
commit
733a15db38

+ 5 - 0
ChangeLog

@@ -1,3 +1,8 @@
+674.	[func]		tomek
+	Preparatory work for prefix delegation in LeaseMgr. getLease6()
+	renamed to getLeases6(). It now can return more than one lease.
+	(Trac #3146, git 05a05d810be754e7a4d8ca181550867febf6dcc6)
+
 673.	[func]		tomek
 673.	[func]		tomek
 	libdhcp: Added support for IA_PD and IAPREFIX options. New class
 	libdhcp: Added support for IA_PD and IAPREFIX options. New class
 	for IAPREFIX (Option6_IAPrefix) has been added.
 	for IAPREFIX (Option6_IAPrefix) has been added.

+ 16 - 9
src/bin/dhcp6/dhcp6_srv.cc

@@ -1223,13 +1223,18 @@ Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
     // will try to honour the hint, but it is just a hint - some other address
     // will try to honour the hint, but it is just a hint - some other address
     // may be used instead. If fake_allocation is set to false, the lease will
     // may be used instead. If fake_allocation is set to false, the lease will
     // be inserted into the LeaseMgr as well.
     // be inserted into the LeaseMgr as well.
-    Lease6Ptr lease = alloc_engine_->allocateAddress6(subnet, duid,
-                                                      ia->getIAID(),
-                                                      hint,
-                                                      do_fwd, do_rev,
-                                                      hostname,
-                                                      fake_allocation,
-                                                      callout_handle);
+    Lease6Collection leases = alloc_engine_->allocateAddress6(subnet, duid,
+                                                              ia->getIAID(),
+                                                              hint,
+                                                              do_fwd, do_rev,
+                                                              hostname,
+                                                              fake_allocation,
+                                                              callout_handle);
+    /// @todo: Handle more than one lease
+    Lease6Ptr lease;
+    if (!leases.empty()) {
+        lease = *leases.begin();
+    }
 
 
     // Create IA_NA that we will put in the response.
     // Create IA_NA that we will put in the response.
     // Do not use OptionDefinition to create option's instance so
     // Do not use OptionDefinition to create option's instance so
@@ -1316,7 +1321,8 @@ Dhcpv6Srv::renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
         return (ia_rsp);
         return (ia_rsp);
     }
     }
 
 
-    Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(*duid, ia->getIAID(),
+    Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
+                                                            *duid, ia->getIAID(),
                                                             subnet->getID());
                                                             subnet->getID());
 
 
     if (!lease) {
     if (!lease) {
@@ -1579,7 +1585,8 @@ Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query,
         return (ia_rsp);
         return (ia_rsp);
     }
     }
 
 
-    Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(release_addr->getAddress());
+    Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
+                                                            release_addr->getAddress());
 
 
     if (!lease) {
     if (!lease) {
         // client releasing a lease that we don't know about.
         // client releasing a lease that we don't know about.

+ 16 - 11
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc

@@ -1024,7 +1024,8 @@ TEST_F(Dhcpv6SrvTest, RenewBasic) {
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
 
 
     // Check that the lease is really in the database
     // Check that the lease is really in the database
-    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
+    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
+                                                        addr);
     ASSERT_TRUE(l);
     ASSERT_TRUE(l);
 
 
     // Check that T1, T2, preferred, valid and cltt really set and not using
     // Check that T1, T2, preferred, valid and cltt really set and not using
@@ -1116,7 +1117,8 @@ TEST_F(Dhcpv6SrvTest, RenewReject) {
     OptionPtr clientid = generateClientId();
     OptionPtr clientid = generateClientId();
 
 
     // Check that the lease is NOT in the database
     // Check that the lease is NOT in the database
-    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
+    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
+                                                        addr);
     ASSERT_FALSE(l);
     ASSERT_FALSE(l);
 
 
     // Let's create a RENEW
     // Let's create a RENEW
@@ -1147,7 +1149,7 @@ TEST_F(Dhcpv6SrvTest, RenewReject) {
     checkIA_NAStatusCode(ia, STATUS_NoBinding);
     checkIA_NAStatusCode(ia, STATUS_NoBinding);
 
 
     // Check that there is no lease added
     // Check that there is no lease added
-    l = LeaseMgrFactory::instance().getLease6(addr);
+    l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
     ASSERT_FALSE(l);
     ASSERT_FALSE(l);
 
 
     // CASE 2: Lease is known and belongs to this client, but to a different IAID
     // CASE 2: Lease is known and belongs to this client, but to a different IAID
@@ -1189,7 +1191,7 @@ TEST_F(Dhcpv6SrvTest, RenewReject) {
     ASSERT_TRUE(ia);
     ASSERT_TRUE(ia);
     checkIA_NAStatusCode(ia, STATUS_NoBinding);
     checkIA_NAStatusCode(ia, STATUS_NoBinding);
 
 
-    lease = LeaseMgrFactory::instance().getLease6(addr);
+    lease = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
     // Verify that the lease was not updated.
     // Verify that the lease was not updated.
     EXPECT_EQ(123, lease->cltt_);
     EXPECT_EQ(123, lease->cltt_);
@@ -1226,7 +1228,8 @@ TEST_F(Dhcpv6SrvTest, ReleaseBasic) {
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
 
 
     // Check that the lease is really in the database
     // Check that the lease is really in the database
-    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
+    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
+                                                        addr);
     ASSERT_TRUE(l);
     ASSERT_TRUE(l);
 
 
     // Let's create a RELEASE
     // Let's create a RELEASE
@@ -1265,11 +1268,12 @@ TEST_F(Dhcpv6SrvTest, ReleaseBasic) {
 
 
     // Check that the lease is really gone in the database
     // Check that the lease is really gone in the database
     // get lease by address
     // get lease by address
-    l = LeaseMgrFactory::instance().getLease6(addr);
+    l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
     ASSERT_FALSE(l);
     ASSERT_FALSE(l);
 
 
     // get lease by subnetid/duid/iaid combination
     // get lease by subnetid/duid/iaid combination
-    l = LeaseMgrFactory::instance().getLease6(*duid_, iaid, subnet_->getID());
+    l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, *duid_, iaid,
+                                              subnet_->getID());
     ASSERT_FALSE(l);
     ASSERT_FALSE(l);
 }
 }
 
 
@@ -1301,7 +1305,8 @@ TEST_F(Dhcpv6SrvTest, ReleaseReject) {
     OptionPtr clientid = generateClientId();
     OptionPtr clientid = generateClientId();
 
 
     // Check that the lease is NOT in the database
     // Check that the lease is NOT in the database
-    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
+    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
+                                                        addr);
     ASSERT_FALSE(l);
     ASSERT_FALSE(l);
 
 
     // Let's create a RELEASE
     // Let's create a RELEASE
@@ -1334,7 +1339,7 @@ TEST_F(Dhcpv6SrvTest, ReleaseReject) {
     checkMsgStatusCode(reply, STATUS_NoBinding);
     checkMsgStatusCode(reply, STATUS_NoBinding);
 
 
     // Check that the lease is not there
     // Check that the lease is not there
-    l = LeaseMgrFactory::instance().getLease6(addr);
+    l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
     ASSERT_FALSE(l);
     ASSERT_FALSE(l);
 
 
     // CASE 2: Lease is known and belongs to this client, but to a different IAID
     // CASE 2: Lease is known and belongs to this client, but to a different IAID
@@ -1356,7 +1361,7 @@ TEST_F(Dhcpv6SrvTest, ReleaseReject) {
     checkMsgStatusCode(reply, STATUS_NoBinding);
     checkMsgStatusCode(reply, STATUS_NoBinding);
 
 
     // Check that the lease is still there
     // Check that the lease is still there
-    l = LeaseMgrFactory::instance().getLease6(addr);
+    l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
     ASSERT_TRUE(l);
     ASSERT_TRUE(l);
 
 
     // CASE 3: Lease belongs to a client with different client-id
     // CASE 3: Lease belongs to a client with different client-id
@@ -1379,7 +1384,7 @@ TEST_F(Dhcpv6SrvTest, ReleaseReject) {
     checkMsgStatusCode(reply, STATUS_NoBinding);
     checkMsgStatusCode(reply, STATUS_NoBinding);
 
 
     // Check that the lease is still there
     // Check that the lease is still there
-    l = LeaseMgrFactory::instance().getLease6(addr);
+    l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
     ASSERT_TRUE(l);
     ASSERT_TRUE(l);
 
 
     // Finally, let's cleanup the database
     // Finally, let's cleanup the database

+ 2 - 1
src/bin/dhcp6/tests/dhcp6_test_utils.h

@@ -377,7 +377,8 @@ public:
                          boost::shared_ptr<Option6IAAddr> addr) {
                          boost::shared_ptr<Option6IAAddr> addr) {
         boost::shared_ptr<Option6IA> ia = boost::dynamic_pointer_cast<Option6IA>(ia_na);
         boost::shared_ptr<Option6IA> ia = boost::dynamic_pointer_cast<Option6IA>(ia_na);
 
 
-        Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(addr->getAddress());
+        Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
+                                                                addr->getAddress());
         if (!lease) {
         if (!lease) {
             std::cout << "Lease for " << addr->getAddress().toText()
             std::cout << "Lease for " << addr->getAddress().toText()
                       << " not found in the database backend.";
                       << " not found in the database backend.";

+ 18 - 10
src/bin/dhcp6/tests/hooks_unittest.cc

@@ -1076,7 +1076,8 @@ TEST_F(HooksDhcpv6SrvTest, basic_lease6_renew) {
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
 
 
     // Check that the lease is really in the database
     // Check that the lease is really in the database
-    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
+    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
+                                                        addr);
     ASSERT_TRUE(l);
     ASSERT_TRUE(l);
 
 
     // Check that T1, T2, preferred, valid and cltt really set and not using
     // Check that T1, T2, preferred, valid and cltt really set and not using
@@ -1172,7 +1173,8 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdate_lease6_renew) {
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
 
 
     // Check that the lease is really in the database
     // Check that the lease is really in the database
-    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
+    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
+                                                        addr);
     ASSERT_TRUE(l);
     ASSERT_TRUE(l);
 
 
     // Check that T1, T2, preferred, valid and cltt really set and not using
     // Check that T1, T2, preferred, valid and cltt really set and not using
@@ -1262,7 +1264,8 @@ TEST_F(HooksDhcpv6SrvTest, skip_lease6_renew) {
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
 
 
     // Check that the lease is really in the database
     // Check that the lease is really in the database
-    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
+    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
+                                                        addr);
     ASSERT_TRUE(l);
     ASSERT_TRUE(l);
 
 
     // Check that T1, T2, preferred, valid and cltt really set and not using
     // Check that T1, T2, preferred, valid and cltt really set and not using
@@ -1293,7 +1296,7 @@ TEST_F(HooksDhcpv6SrvTest, skip_lease6_renew) {
     // Check that our callback was called
     // Check that our callback was called
     EXPECT_EQ("lease6_renew", callback_name_);
     EXPECT_EQ("lease6_renew", callback_name_);
 
 
-    l = LeaseMgrFactory::instance().getLease6(addr);
+    l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
 
 
     // Check that the old values are still there and they were not
     // Check that the old values are still there and they were not
     // updated by the renewal
     // updated by the renewal
@@ -1337,7 +1340,8 @@ TEST_F(HooksDhcpv6SrvTest, basic_lease6_release) {
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
 
 
     // Check that the lease is really in the database
     // Check that the lease is really in the database
-    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
+    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
+                                                        addr);
     ASSERT_TRUE(l);
     ASSERT_TRUE(l);
 
 
     // Let's create a RELEASE
     // Let's create a RELEASE
@@ -1375,11 +1379,12 @@ TEST_F(HooksDhcpv6SrvTest, basic_lease6_release) {
 
 
     // Check that the lease is really gone in the database
     // Check that the lease is really gone in the database
     // get lease by address
     // get lease by address
-    l = LeaseMgrFactory::instance().getLease6(addr);
+    l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
     ASSERT_FALSE(l);
     ASSERT_FALSE(l);
 
 
     // Get lease by subnetid/duid/iaid combination
     // Get lease by subnetid/duid/iaid combination
-    l = LeaseMgrFactory::instance().getLease6(*duid_, iaid, subnet_->getID());
+    l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, *duid_, iaid,
+                                              subnet_->getID());
     ASSERT_FALSE(l);
     ASSERT_FALSE(l);
 }
 }
 
 
@@ -1416,7 +1421,8 @@ TEST_F(HooksDhcpv6SrvTest, skip_lease6_release) {
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
 
 
     // Check that the lease is really in the database
     // Check that the lease is really in the database
-    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
+    Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
+                                                        addr);
     ASSERT_TRUE(l);
     ASSERT_TRUE(l);
 
 
     // Let's create a RELEASE
     // Let's create a RELEASE
@@ -1442,11 +1448,13 @@ TEST_F(HooksDhcpv6SrvTest, skip_lease6_release) {
 
 
     // Check that the lease is still there
     // Check that the lease is still there
     // get lease by address
     // get lease by address
-    l = LeaseMgrFactory::instance().getLease6(addr);
+    l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
+                                              addr);
     ASSERT_TRUE(l);
     ASSERT_TRUE(l);
 
 
     // Get lease by subnetid/duid/iaid combination
     // Get lease by subnetid/duid/iaid combination
-    l = LeaseMgrFactory::instance().getLease6(*duid_, iaid, subnet_->getID());
+    l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, *duid_, iaid,
+                                              subnet_->getID());
     ASSERT_TRUE(l);
     ASSERT_TRUE(l);
 }
 }
 
 

+ 44 - 25
src/lib/dhcpsrv/alloc_engine.cc

@@ -195,7 +195,7 @@ AllocEngine::AllocEngine(AllocType engine_type, unsigned int attempts)
     hook_index_lease6_select_ = Hooks.hook_index_lease6_select_;
     hook_index_lease6_select_ = Hooks.hook_index_lease6_select_;
 }
 }
 
 
-Lease6Ptr
+Lease6Collection
 AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
 AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
                               const DuidPtr& duid,
                               const DuidPtr& duid,
                               uint32_t iaid,
                               uint32_t iaid,
@@ -222,40 +222,52 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
         }
         }
 
 
         // check if there's existing lease for that subnet/duid/iaid combination.
         // check if there's existing lease for that subnet/duid/iaid combination.
-        Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(*duid, iaid, subnet->getID());
-        if (existing) {
-            // we have a lease already. This is a returning client, probably after
-            // his reboot.
+        /// @todo: Make this generic (cover temp. addrs and prefixes)
+        Lease6Collection existing = LeaseMgrFactory::instance().getLeases6(
+            Lease6::LEASE_IA_NA, *duid, iaid, subnet->getID());
+
+        if (!existing.empty()) {
+            // we have at least one lease already. This is a returning client,
+            // probably after his reboot.
             return (existing);
             return (existing);
         }
         }
 
 
         // check if the hint is in pool and is available
         // check if the hint is in pool and is available
         if (subnet->inPool(hint)) {
         if (subnet->inPool(hint)) {
-            existing = LeaseMgrFactory::instance().getLease6(hint);
-            if (!existing) {
+
+            /// @todo: We support only one hint for now
+            Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(
+                Lease6::LEASE_IA_NA, hint);
+            if (!lease) {
                 /// @todo: check if the hint is reserved once we have host support
                 /// @todo: check if the hint is reserved once we have host support
                 /// implemented
                 /// implemented
 
 
                 // the hint is valid and not currently used, let's create a lease for it
                 // the hint is valid and not currently used, let's create a lease for it
-                Lease6Ptr lease = createLease6(subnet, duid, iaid,
-                                               hint,
-                                               fwd_dns_update,
-                                               rev_dns_update, hostname,
-                                               callout_handle,
-                                               fake_allocation);
+                /// @todo: We support only one lease per ia for now
+                lease = createLease6(subnet, duid, iaid, hint, fwd_dns_update,
+                                     rev_dns_update, hostname, callout_handle,
+                                     fake_allocation);
 
 
                 // It can happen that the lease allocation failed (we could have lost
                 // It can happen that the lease allocation failed (we could have lost
                 // the race condition. That means that the hint is lo longer usable and
                 // the race condition. That means that the hint is lo longer usable and
                 // we need to continue the regular allocation path.
                 // we need to continue the regular allocation path.
                 if (lease) {
                 if (lease) {
-                    return (lease);
+                    /// @todo: We support only one lease per ia for now
+                    Lease6Collection collection;
+                    collection.push_back(lease);
+                    return (collection);
                 }
                 }
             } else {
             } else {
-                if (existing->expired()) {
-                    return (reuseExpiredLease(existing, subnet, duid, iaid,
+                if (lease->expired()) {
+                    /// We found a lease and it is expired, so we can reuse it
+                    /// @todo: We support only one lease per ia for now
+                    lease = reuseExpiredLease(lease, subnet, duid, iaid,
                                               fwd_dns_update, rev_dns_update,
                                               fwd_dns_update, rev_dns_update,
                                               hostname, callout_handle,
                                               hostname, callout_handle,
-                                              fake_allocation));
+                                              fake_allocation);
+                    Lease6Collection collection;
+                    collection.push_back(lease);
+                    return (collection);
                 }
                 }
 
 
             }
             }
@@ -284,7 +296,8 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
             /// @todo: check if the address is reserved once we have host support
             /// @todo: check if the address is reserved once we have host support
             /// implemented
             /// implemented
 
 
-            Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(candidate);
+            Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(
+                                 Lease6::LEASE_IA_NA, candidate);
             if (!existing) {
             if (!existing) {
                 // there's no existing lease for selected candidate, so it is
                 // there's no existing lease for selected candidate, so it is
                 // free. Let's allocate it.
                 // free. Let's allocate it.
@@ -293,7 +306,9 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
                                                hostname,
                                                hostname,
                                                callout_handle, fake_allocation);
                                                callout_handle, fake_allocation);
                 if (lease) {
                 if (lease) {
-                    return (lease);
+                    Lease6Collection collection;
+                    collection.push_back(lease);
+                    return (collection);
                 }
                 }
 
 
                 // Although the address was free just microseconds ago, it may have
                 // Although the address was free just microseconds ago, it may have
@@ -301,10 +316,13 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
                 // allocation attempts.
                 // allocation attempts.
             } else {
             } else {
                 if (existing->expired()) {
                 if (existing->expired()) {
-                    return (reuseExpiredLease(existing, subnet, duid, iaid,
-                                              fwd_dns_update, rev_dns_update,
-                                              hostname, callout_handle,
-                                              fake_allocation));
+                    existing = reuseExpiredLease(existing, subnet, duid, iaid,
+                                                 fwd_dns_update, rev_dns_update,
+                                                 hostname, callout_handle,
+                                                 fake_allocation);
+                    Lease6Collection collection;
+                    collection.push_back(existing);
+                    return (collection);
                 }
                 }
             }
             }
 
 
@@ -322,7 +340,7 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
         LOG_ERROR(dhcpsrv_logger, DHCPSRV_ADDRESS6_ALLOC_ERROR).arg(e.what());
         LOG_ERROR(dhcpsrv_logger, DHCPSRV_ADDRESS6_ALLOC_ERROR).arg(e.what());
     }
     }
 
 
-    return (Lease6Ptr());
+    return (Lease6Collection());
 }
 }
 
 
 Lease4Ptr
 Lease4Ptr
@@ -795,7 +813,8 @@ Lease6Ptr AllocEngine::createLease6(const Subnet6Ptr& subnet,
 
 
         // It is for advertise only. We should not insert the lease into LeaseMgr,
         // It is for advertise only. We should not insert the lease into LeaseMgr,
         // but rather check that we could have inserted it.
         // but rather check that we could have inserted it.
-        Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(addr);
+        Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(
+                             Lease6::LEASE_IA_NA, addr);
         if (!existing) {
         if (!existing) {
             return (lease);
             return (lease);
         } else {
         } else {

+ 2 - 2
src/lib/dhcpsrv/alloc_engine.h

@@ -295,8 +295,8 @@ protected:
     /// @param callout_handle a callout handle (used in hooks). A lease callouts
     /// @param callout_handle a callout handle (used in hooks). A lease callouts
     ///        will be executed if this parameter is passed.
     ///        will be executed if this parameter is passed.
     ///
     ///
-    /// @return Allocated IPv6 lease (or NULL if allocation failed)
-    Lease6Ptr
+    /// @return Allocated IPv6 leases (may be empty if allocation failed)
+    Lease6Collection
     allocateAddress6(const Subnet6Ptr& subnet,
     allocateAddress6(const Subnet6Ptr& subnet,
                      const DuidPtr& duid,
                      const DuidPtr& duid,
                      uint32_t iaid,
                      uint32_t iaid,

+ 3 - 1
src/lib/dhcpsrv/dhcpdb_create.mysql

@@ -76,7 +76,9 @@ CREATE INDEX lease6_by_iaid_subnet_id_duid ON lease6 (iaid, subnet_id, duid);
 
 
 # ... and a definition of lease6 types.  This table is a convenience for
 # ... and a definition of lease6 types.  This table is a convenience for
 # users of the database - if they want to view the lease table and use the
 # users of the database - if they want to view the lease table and use the
-# type names, they can join this table with the lease6 table
+# type names, they can join this table with the lease6 table.
+# Make sure those values match Lease6::LeaseType enum (see src/bin/dhcpsrv/
+# lease_mgr.h)
 CREATE TABLE lease6_types (
 CREATE TABLE lease6_types (
     lease_type TINYINT PRIMARY KEY NOT NULL,    # Lease type code.
     lease_type TINYINT PRIMARY KEY NOT NULL,    # Lease type code.
     name VARCHAR(5)                             # Name of the lease type
     name VARCHAR(5)                             # Name of the lease type

+ 17 - 0
src/lib/dhcpsrv/lease_mgr.cc

@@ -130,6 +130,23 @@ std::string LeaseMgr::getParameter(const std::string& name) const {
     return (param->second);
     return (param->second);
 }
 }
 
 
+Lease6Ptr
+LeaseMgr::getLease6(Lease6::LeaseType type, const DUID& duid,
+                    uint32_t iaid, SubnetID subnet_id) const {
+    Lease6Collection col = getLeases6(type, duid, iaid, subnet_id);
+
+    if (col.size() > 1) {
+        isc_throw(MultipleRecords, "More than one lease found for type "
+                  << static_cast<int>(type) << ", duid "
+                  << duid.toText() << ", iaid " << iaid
+                  << " and subnet-id " << subnet_id);
+    }
+    if (col.empty()) {
+        return (Lease6Ptr());
+    }
+    return (*col.begin());
+}
+
 std::string
 std::string
 Lease6::toText() const {
 Lease6::toText() const {
     ostringstream stream;
     ostringstream stream;

+ 44 - 10
src/lib/dhcpsrv/lease_mgr.h

@@ -318,9 +318,9 @@ struct Lease6 : public Lease {
 
 
     /// @brief Type of lease contents
     /// @brief Type of lease contents
     typedef enum {
     typedef enum {
-        LEASE_IA_NA, /// the lease contains non-temporary IPv6 address
-        LEASE_IA_TA, /// the lease contains temporary IPv6 address
-        LEASE_IA_PD  /// the lease contains IPv6 prefix (for prefix delegation)
+        LEASE_IA_NA = 0, /// the lease contains non-temporary IPv6 address
+        LEASE_IA_TA = 1, /// the lease contains temporary IPv6 address
+        LEASE_IA_PD = 2  /// the lease contains IPv6 prefix (for prefix delegation)
     } LeaseType;
     } LeaseType;
 
 
     /// @brief Lease type
     /// @brief Lease type
@@ -533,10 +533,12 @@ public:
     /// The assumption here is that there will not be site or link-local
     /// The assumption here is that there will not be site or link-local
     /// addresses used, so there is no way of having address duplication.
     /// addresses used, so there is no way of having address duplication.
     ///
     ///
+    /// @param type specifies lease type: (NA, TA or PD)
     /// @param addr address of the searched lease
     /// @param addr address of the searched lease
     ///
     ///
     /// @return smart pointer to the lease (or NULL if a lease is not found)
     /// @return smart pointer to the lease (or NULL if a lease is not found)
-    virtual Lease6Ptr getLease6(const isc::asiolink::IOAddress& addr) const = 0;
+    virtual Lease6Ptr getLease6(Lease6::LeaseType type,
+                                const isc::asiolink::IOAddress& addr) const = 0;
 
 
     /// @brief Returns existing IPv6 leases for a given DUID+IA combination
     /// @brief Returns existing IPv6 leases for a given DUID+IA combination
     ///
     ///
@@ -545,22 +547,54 @@ public:
     /// can be more than one. Thus return type is a container, not a single
     /// can be more than one. Thus return type is a container, not a single
     /// pointer.
     /// pointer.
     ///
     ///
+    /// @param type specifies lease type: (NA, TA or PD)
     /// @param duid client DUID
     /// @param duid client DUID
     /// @param iaid IA identifier
     /// @param iaid IA identifier
     ///
     ///
-    /// @return smart pointer to the lease (or NULL if a lease is not found)
-    virtual Lease6Collection getLease6(const DUID& duid,
-                                       uint32_t iaid) const = 0;
+    /// @return Lease collection (may be empty if no lease is found)
+    virtual Lease6Collection getLeases6(Lease6::LeaseType type, const DUID& duid,
+                                        uint32_t iaid) const = 0;
 
 
     /// @brief Returns existing IPv6 lease for a given DUID+IA combination
     /// @brief Returns existing IPv6 lease for a given DUID+IA combination
     ///
     ///
+    /// There may be more than one address, temp. address or prefix
+    /// for specified duid/iaid/subnet-id tuple.
+    ///
+    /// @param type specifies lease type: (NA, TA or PD)
     /// @param duid client DUID
     /// @param duid client DUID
     /// @param iaid IA identifier
     /// @param iaid IA identifier
     /// @param subnet_id subnet id of the subnet the lease belongs to
     /// @param subnet_id subnet id of the subnet the lease belongs to
     ///
     ///
-    /// @return smart pointer to the lease (or NULL if a lease is not found)
-    virtual Lease6Ptr getLease6(const DUID& duid, uint32_t iaid,
-                                SubnetID subnet_id) const = 0;
+    /// @return Lease collection (may be empty if no lease is found)
+    virtual Lease6Collection getLeases6(Lease6::LeaseType type, const DUID& duid,
+                                        uint32_t iaid, SubnetID subnet_id) const = 0;
+
+
+    /// @brief returns zero or one IPv6 lease for a given duid+iaid+subnet_id
+    ///
+    /// This function is mostly intended to be used in unit-tests during the
+    /// transition from single to multi address per IA. It may also be used
+    /// in other cases where at most one lease is expected in the database.
+    ///
+    /// It is a wrapper around getLease6(), which returns a collection of
+    /// leases. That collection can be converted into a single pointer if
+    /// there are no leases (NULL pointer) or one lease (use that single lease).
+    /// If there are more leases in the collection, the function will
+    /// throw MultipleRecords exception.
+    ///
+    /// Note: This method is not virtual on purpose. It is common for all
+    /// backends.
+    ///
+    /// @param type specifies lease type: (NA, TA or PD)
+    /// @param duid client DUID
+    /// @param iaid IA identifier
+    /// @param subnet_id subnet id of the subnet the lease belongs to
+    ///
+    /// @throw MultipleRecords if there is more than one lease matching
+    ///
+    /// @return Lease pointer (or NULL if none is found)
+    Lease6Ptr getLease6(Lease6::LeaseType type, const DUID& duid,
+                        uint32_t iaid, SubnetID subnet_id) const;
 
 
     /// @brief Updates IPv4 lease.
     /// @brief Updates IPv4 lease.
     ///
     ///

+ 17 - 8
src/lib/dhcpsrv/memfile_lease_mgr.cc

@@ -46,7 +46,7 @@ Memfile_LeaseMgr::addLease(const Lease6Ptr& lease) {
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_MEMFILE_ADD_ADDR6).arg(lease->addr_.toText());
               DHCPSRV_MEMFILE_ADD_ADDR6).arg(lease->addr_.toText());
 
 
-    if (getLease6(lease->addr_)) {
+    if (getLease6(lease->type_, lease->addr_)) {
         // there is a lease with specified address already
         // there is a lease with specified address already
         return (false);
         return (false);
     }
     }
@@ -186,7 +186,8 @@ Memfile_LeaseMgr::getLease4(const ClientId& client_id,
 }
 }
 
 
 Lease6Ptr
 Lease6Ptr
-Memfile_LeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
+Memfile_LeaseMgr::getLease6(Lease6::LeaseType /* not used yet */,
+                            const isc::asiolink::IOAddress& addr) const {
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_MEMFILE_GET_ADDR6).arg(addr.toText());
               DHCPSRV_MEMFILE_GET_ADDR6).arg(addr.toText());
 
 
@@ -199,16 +200,20 @@ Memfile_LeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
 }
 }
 
 
 Lease6Collection
 Lease6Collection
-Memfile_LeaseMgr::getLease6(const DUID& duid, uint32_t iaid) const {
+Memfile_LeaseMgr::getLeases6(Lease6::LeaseType /* not used yet */,
+                            const DUID& duid, uint32_t iaid) const {
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_MEMFILE_GET_IAID_DUID).arg(iaid).arg(duid.toText());
               DHCPSRV_MEMFILE_GET_IAID_DUID).arg(iaid).arg(duid.toText());
 
 
+    /// @todo Not implemented.
+
     return (Lease6Collection());
     return (Lease6Collection());
 }
 }
 
 
-Lease6Ptr
-Memfile_LeaseMgr::getLease6(const DUID& duid, uint32_t iaid,
-                            SubnetID subnet_id) const {
+Lease6Collection
+Memfile_LeaseMgr::getLeases6(Lease6::LeaseType /* not used yet */,
+                             const DUID& duid, uint32_t iaid,
+                             SubnetID subnet_id) const {
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_MEMFILE_GET_IAID_SUBID_DUID)
               DHCPSRV_MEMFILE_GET_IAID_SUBID_DUID)
               .arg(iaid).arg(subnet_id).arg(duid.toText());
               .arg(iaid).arg(subnet_id).arg(duid.toText());
@@ -224,10 +229,14 @@ Memfile_LeaseMgr::getLease6(const DUID& duid, uint32_t iaid,
         idx.find(boost::make_tuple(duid.getDuid(), iaid, subnet_id));
         idx.find(boost::make_tuple(duid.getDuid(), iaid, subnet_id));
     // Lease was not found. Return empty pointer.
     // Lease was not found. Return empty pointer.
     if (lease == idx.end()) {
     if (lease == idx.end()) {
-        return (Lease6Ptr());
+        return (Lease6Collection());
     }
     }
+
     // Lease was found, return it to the caller.
     // Lease was found, return it to the caller.
-    return (Lease6Ptr(new Lease6(**lease)));
+    /// @todo: allow multiple leases for a single duid+iaid+subnet_id tuple
+    Lease6Collection collection;
+    collection.push_back(Lease6Ptr(new Lease6(**lease)));
+    return (collection);
 }
 }
 
 
 void
 void

+ 10 - 5
src/lib/dhcpsrv/memfile_lease_mgr.h

@@ -140,33 +140,38 @@ public:
     /// This function returns a copy of the lease. The modification in the
     /// This function returns a copy of the lease. The modification in the
     /// return lease does not affect the instance held in the lease storage.
     /// return lease does not affect the instance held in the lease storage.
     ///
     ///
+    /// @param type specifies lease type: (NA, TA or PD)
     /// @param addr An address of the searched lease.
     /// @param addr An address of the searched lease.
     ///
     ///
     /// @return smart pointer to the lease (or NULL if a lease is not found)
     /// @return smart pointer to the lease (or NULL if a lease is not found)
-    virtual Lease6Ptr getLease6(const isc::asiolink::IOAddress& addr) const;
+    virtual Lease6Ptr getLease6(Lease6::LeaseType type,
+                                const isc::asiolink::IOAddress& addr) const;
 
 
     /// @brief Returns existing IPv6 lease for a given DUID+IA combination
     /// @brief Returns existing IPv6 lease for a given DUID+IA combination
     ///
     ///
     /// @todo Not implemented yet
     /// @todo Not implemented yet
     ///
     ///
+    /// @param type specifies lease type: (NA, TA or PD)
     /// @param duid client DUID
     /// @param duid client DUID
     /// @param iaid IA identifier
     /// @param iaid IA identifier
     ///
     ///
     /// @return collection of IPv6 leases
     /// @return collection of IPv6 leases
-    virtual Lease6Collection getLease6(const DUID& duid, uint32_t iaid) const;
+    virtual Lease6Collection getLeases6(Lease6::LeaseType type,
+                                        const DUID& duid, uint32_t iaid) const;
 
 
     /// @brief Returns existing IPv6 lease for a given DUID/IA/subnet-id tuple
     /// @brief Returns existing IPv6 lease for a given DUID/IA/subnet-id tuple
     ///
     ///
     /// This function returns a copy of the lease. The modification in the
     /// This function returns a copy of the lease. The modification in the
     /// return lease does not affect the instance held in the lease storage.
     /// return lease does not affect the instance held in the lease storage.
     ///
     ///
+    /// @param type specifies lease type: (NA, TA or PD)
     /// @param duid client DUID
     /// @param duid client DUID
     /// @param iaid IA identifier
     /// @param iaid IA identifier
     /// @param subnet_id identifier of the subnet the lease must belong to
     /// @param subnet_id identifier of the subnet the lease must belong to
     ///
     ///
-    /// @return smart pointer to the lease (or NULL if a lease is not found)
-    virtual Lease6Ptr getLease6(const DUID& duid, uint32_t iaid,
-                                SubnetID subnet_id) const;
+    /// @return lease collection (may be empty if no lease is found)
+    virtual Lease6Collection getLeases6(Lease6::LeaseType type, const DUID& duid,
+                                        uint32_t iaid, SubnetID subnet_id) const;
 
 
     /// @brief Updates IPv4 lease.
     /// @brief Updates IPv4 lease.
     ///
     ///

+ 16 - 9
src/lib/dhcpsrv/mysql_lease_mgr.cc

@@ -984,8 +984,9 @@ public:
 
 
             default:
             default:
                 isc_throw(BadValue, "invalid lease type returned (" <<
                 isc_throw(BadValue, "invalid lease type returned (" <<
-                          lease_type_ << ") for lease with address " <<
-                          address << ". Only 0, 1, or 2 are allowed.");
+                          static_cast<int>(lease_type_) << ") for lease with "
+                          << "address " << address << ". Only 0, 1, or 2 are "
+                          << "allowed.");
         }
         }
 
 
         // Set up DUID,
         // Set up DUID,
@@ -1650,7 +1651,8 @@ MySqlLeaseMgr::getLease4(const ClientId& clientid, SubnetID subnet_id) const {
 
 
 
 
 Lease6Ptr
 Lease6Ptr
-MySqlLeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
+MySqlLeaseMgr::getLease6(Lease6::LeaseType /* type - not used yet */,
+                         const isc::asiolink::IOAddress& addr) const {
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_MYSQL_GET_ADDR6).arg(addr.toText());
               DHCPSRV_MYSQL_GET_ADDR6).arg(addr.toText());
 
 
@@ -1676,7 +1678,8 @@ MySqlLeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
 
 
 
 
 Lease6Collection
 Lease6Collection
-MySqlLeaseMgr::getLease6(const DUID& duid, uint32_t iaid) const {
+MySqlLeaseMgr::getLeases6(Lease6::LeaseType /* type - not used yet */,
+                          const DUID& duid, uint32_t iaid) const {
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_MYSQL_GET_IAID_DUID).arg(iaid).arg(duid.toText());
               DHCPSRV_MYSQL_GET_IAID_DUID).arg(iaid).arg(duid.toText());
 
 
@@ -1716,10 +1719,10 @@ MySqlLeaseMgr::getLease6(const DUID& duid, uint32_t iaid) const {
     return (result);
     return (result);
 }
 }
 
 
-
-Lease6Ptr
-MySqlLeaseMgr::getLease6(const DUID& duid, uint32_t iaid,
-                         SubnetID subnet_id) const {
+Lease6Collection
+MySqlLeaseMgr::getLeases6(Lease6::LeaseType /* type - not used yet */,
+                          const DUID& duid, uint32_t iaid,
+                          SubnetID subnet_id) const {
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_MYSQL_GET_IAID_SUBID_DUID)
               DHCPSRV_MYSQL_GET_IAID_SUBID_DUID)
               .arg(iaid).arg(subnet_id).arg(duid.toText());
               .arg(iaid).arg(subnet_id).arg(duid.toText());
@@ -1751,7 +1754,11 @@ MySqlLeaseMgr::getLease6(const DUID& duid, uint32_t iaid,
     Lease6Ptr result;
     Lease6Ptr result;
     getLease(GET_LEASE6_DUID_IAID_SUBID, inbind, result);
     getLease(GET_LEASE6_DUID_IAID_SUBID, inbind, result);
 
 
-    return (result);
+    /// @todo: Implement getting one than more lease at the time
+    Lease6Collection collection;
+    collection.push_back(result);
+
+    return (collection);
 }
 }
 
 
 // Update lease methods.  These comprise common code that handles the actual
 // Update lease methods.  These comprise common code that handles the actual

+ 10 - 6
src/lib/dhcpsrv/mysql_lease_mgr.h

@@ -244,6 +244,7 @@ public:
     /// The assumption here is that there will not be site or link-local
     /// The assumption here is that there will not be site or link-local
     /// addresses used, so there is no way of having address duplication.
     /// addresses used, so there is no way of having address duplication.
     ///
     ///
+    /// @param type specifies lease type: (NA, TA or PD)
     /// @param addr address of the searched lease
     /// @param addr address of the searched lease
     ///
     ///
     /// @return smart pointer to the lease (or NULL if a lease is not found)
     /// @return smart pointer to the lease (or NULL if a lease is not found)
@@ -255,7 +256,8 @@ public:
     ///        programming error.
     ///        programming error.
     /// @throw isc::dhcp::DbOperationError An operation on the open database has
     /// @throw isc::dhcp::DbOperationError An operation on the open database has
     ///        failed.
     ///        failed.
-    virtual Lease6Ptr getLease6(const isc::asiolink::IOAddress& addr) const;
+    virtual Lease6Ptr getLease6(Lease6::LeaseType type,
+                                const isc::asiolink::IOAddress& addr) const;
 
 
     /// @brief Returns existing IPv6 leases for a given DUID+IA combination
     /// @brief Returns existing IPv6 leases for a given DUID+IA combination
     ///
     ///
@@ -264,6 +266,7 @@ public:
     /// can be more than one. Thus return type is a container, not a single
     /// can be more than one. Thus return type is a container, not a single
     /// pointer.
     /// pointer.
     ///
     ///
+    /// @param type specifies lease type: (NA, TA or PD)
     /// @param duid client DUID
     /// @param duid client DUID
     /// @param iaid IA identifier
     /// @param iaid IA identifier
     ///
     ///
@@ -276,16 +279,17 @@ public:
     ///        programming error.
     ///        programming error.
     /// @throw isc::dhcp::DbOperationError An operation on the open database has
     /// @throw isc::dhcp::DbOperationError An operation on the open database has
     ///        failed.
     ///        failed.
-    virtual Lease6Collection getLease6(const DUID& duid,
-                                       uint32_t iaid) const;
+    virtual Lease6Collection getLeases6(Lease6::LeaseType type, const DUID& duid,
+                                        uint32_t iaid) const;
 
 
     /// @brief Returns existing IPv6 lease for a given DUID+IA combination
     /// @brief Returns existing IPv6 lease for a given DUID+IA combination
     ///
     ///
+    /// @param type specifies lease type: (NA, TA or PD)
     /// @param duid client DUID
     /// @param duid client DUID
     /// @param iaid IA identifier
     /// @param iaid IA identifier
     /// @param subnet_id subnet id of the subnet the lease belongs to
     /// @param subnet_id subnet id of the subnet the lease belongs to
     ///
     ///
-    /// @return smart pointer to the lease (or NULL if a lease is not found)
+    /// @return lease collection (may be empty if no lease is found)
     ///
     ///
     /// @throw isc::BadValue record retrieved from database had an invalid
     /// @throw isc::BadValue record retrieved from database had an invalid
     ///        lease type field.
     ///        lease type field.
@@ -294,8 +298,8 @@ public:
     ///        programming error.
     ///        programming error.
     /// @throw isc::dhcp::DbOperationError An operation on the open database has
     /// @throw isc::dhcp::DbOperationError An operation on the open database has
     ///        failed.
     ///        failed.
-    virtual Lease6Ptr getLease6(const DUID& duid, uint32_t iaid,
-                                SubnetID subnet_id) const;
+    virtual Lease6Collection getLeases6(Lease6::LeaseType type, const DUID& duid,
+                                        uint32_t iaid, SubnetID subnet_id) const;
 
 
     /// @brief Updates IPv4 lease.
     /// @brief Updates IPv4 lease.
     ///
     ///

+ 92 - 65
src/lib/dhcpsrv/tests/alloc_engine_unittest.cc

@@ -89,6 +89,24 @@ public:
         factory_.create("type=memfile");
         factory_.create("type=memfile");
     }
     }
 
 
+    /// @brief attempts to convert leases collection to a single lease
+    ///
+    /// This operation makes sense if there is at most one lease in the
+    /// collection. Otherwise it will throw.
+    ///
+    /// @param col collection of leases (zero or one leases allowed)
+    /// @throw MultipleRecords if there is more than one lease
+    /// @return Lease6 pointer (or NULL if collection was empty)
+    Lease6Ptr expectOneLease(const Lease6Collection& col) {
+        if (col.size() > 1) {
+            isc_throw(MultipleRecords, "More than one lease found in collection");
+        }
+        if (col.empty()) {
+            return (Lease6Ptr());
+        }
+        return (*col.begin());
+    }
+
     /// @brief checks if Lease6 matches expected configuration
     /// @brief checks if Lease6 matches expected configuration
     ///
     ///
     /// @param lease lease to be checked
     /// @param lease lease to be checked
@@ -207,10 +225,10 @@ TEST_F(AllocEngine6Test, simpleAlloc6) {
     ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
     ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
     ASSERT_TRUE(engine);
     ASSERT_TRUE(engine);
 
 
-    Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
-                                               IOAddress("::"), false,
-                                               false, "",
-                                               false, CalloutHandlePtr());
+    Lease6Ptr lease;
+    EXPECT_NO_THROW(lease = expectOneLease(engine->allocateAddress6(subnet_,
+                    duid_, iaid_, IOAddress("::"), false, false, "", false,
+                    CalloutHandlePtr())));
 
 
     // Check that we got a lease
     // Check that we got a lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
@@ -219,7 +237,8 @@ TEST_F(AllocEngine6Test, simpleAlloc6) {
     checkLease6(lease);
     checkLease6(lease);
 
 
     // Check that the lease is indeed in LeaseMgr
     // Check that the lease is indeed in LeaseMgr
-    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->addr_);
+    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
+                                                               lease->addr_);
     ASSERT_TRUE(from_mgr);
     ASSERT_TRUE(from_mgr);
 
 
     // Now check that the lease in LeaseMgr has the same parameters
     // Now check that the lease in LeaseMgr has the same parameters
@@ -232,10 +251,10 @@ TEST_F(AllocEngine6Test, fakeAlloc6) {
     ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
     ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
     ASSERT_TRUE(engine);
     ASSERT_TRUE(engine);
 
 
-    Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
-                                               IOAddress("::"), false,
-                                               false, "", true,
-                                               CalloutHandlePtr());
+    Lease6Ptr lease;
+    EXPECT_NO_THROW(lease = expectOneLease(engine->allocateAddress6(subnet_,
+                    duid_, iaid_, IOAddress("::"), false, false, "", true,
+                    CalloutHandlePtr())));
 
 
     // Check that we got a lease
     // Check that we got a lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
@@ -244,7 +263,8 @@ TEST_F(AllocEngine6Test, fakeAlloc6) {
     checkLease6(lease);
     checkLease6(lease);
 
 
     // Check that the lease is NOT in LeaseMgr
     // Check that the lease is NOT in LeaseMgr
-    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->addr_);
+    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
+                                                               lease->addr_);
     ASSERT_FALSE(from_mgr);
     ASSERT_FALSE(from_mgr);
 }
 }
 
 
@@ -255,10 +275,10 @@ TEST_F(AllocEngine6Test, allocWithValidHint6) {
     ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
     ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
     ASSERT_TRUE(engine);
     ASSERT_TRUE(engine);
 
 
-    Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
-                                               IOAddress("2001:db8:1::15"),
-                                               false, false, "",
-                                               false, CalloutHandlePtr());
+    Lease6Ptr lease;
+    EXPECT_NO_THROW(lease = expectOneLease(engine->allocateAddress6(subnet_,
+                            duid_, iaid_, IOAddress("2001:db8:1::15"), false,
+                            false, "", false, CalloutHandlePtr())));
 
 
     // Check that we got a lease
     // Check that we got a lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
@@ -270,7 +290,8 @@ TEST_F(AllocEngine6Test, allocWithValidHint6) {
     checkLease6(lease);
     checkLease6(lease);
 
 
     // Check that the lease is indeed in LeaseMgr
     // Check that the lease is indeed in LeaseMgr
-    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->addr_);
+    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
+                                                               lease->addr_);
     ASSERT_TRUE(from_mgr);
     ASSERT_TRUE(from_mgr);
 
 
     // Now check that the lease in LeaseMgr has the same parameters
     // Now check that the lease in LeaseMgr has the same parameters
@@ -294,10 +315,11 @@ TEST_F(AllocEngine6Test, allocWithUsedHint6) {
     // Another client comes in and request an address that is in pool, but
     // Another client comes in and request an address that is in pool, but
     // unfortunately it is used already. The same address must not be allocated
     // unfortunately it is used already. The same address must not be allocated
     // twice.
     // twice.
-    Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
-                                               IOAddress("2001:db8:1::1f"),
-                                               false, false, "",
-                                               false, CalloutHandlePtr());
+    Lease6Ptr lease;
+    EXPECT_NO_THROW(lease = expectOneLease(engine->allocateAddress6(subnet_,
+                    duid_, iaid_, IOAddress("2001:db8:1::1f"), false, false, "",
+                    false, CalloutHandlePtr())));
+
     // Check that we got a lease
     // Check that we got a lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
 
 
@@ -311,7 +333,8 @@ TEST_F(AllocEngine6Test, allocWithUsedHint6) {
     checkLease6(lease);
     checkLease6(lease);
 
 
     // Check that the lease is indeed in LeaseMgr
     // Check that the lease is indeed in LeaseMgr
-    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->addr_);
+    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
+                                                               lease->addr_);
     ASSERT_TRUE(from_mgr);
     ASSERT_TRUE(from_mgr);
 
 
     // Now check that the lease in LeaseMgr has the same parameters
     // Now check that the lease in LeaseMgr has the same parameters
@@ -328,10 +351,11 @@ TEST_F(AllocEngine6Test, allocBogusHint6) {
     // Client would like to get a 3000::abc lease, which does not belong to any
     // Client would like to get a 3000::abc lease, which does not belong to any
     // supported lease. Allocation engine should ignore it and carry on
     // supported lease. Allocation engine should ignore it and carry on
     // with the normal allocation
     // with the normal allocation
-    Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
-                                               IOAddress("3000::abc"),
-                                               false, false, "",
-                                               false, CalloutHandlePtr());
+    Lease6Ptr lease;
+    EXPECT_NO_THROW(lease = expectOneLease(engine->allocateAddress6(subnet_,
+                    duid_, iaid_, IOAddress("3000::abc"), false, false, "",
+                    false, CalloutHandlePtr())));
+
     // Check that we got a lease
     // Check that we got a lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
 
 
@@ -342,7 +366,8 @@ TEST_F(AllocEngine6Test, allocBogusHint6) {
     checkLease6(lease);
     checkLease6(lease);
 
 
     // Check that the lease is indeed in LeaseMgr
     // Check that the lease is indeed in LeaseMgr
-    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->addr_);
+    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
+                                                               lease->addr_);
     ASSERT_TRUE(from_mgr);
     ASSERT_TRUE(from_mgr);
 
 
     // Now check that the lease in LeaseMgr has the same parameters
     // Now check that the lease in LeaseMgr has the same parameters
@@ -356,17 +381,16 @@ TEST_F(AllocEngine6Test, allocateAddress6Nulls) {
     ASSERT_TRUE(engine);
     ASSERT_TRUE(engine);
 
 
     // Allocations without subnet are not allowed
     // Allocations without subnet are not allowed
-    Lease6Ptr lease = engine->allocateAddress6(Subnet6Ptr(), duid_, iaid_,
-                                               IOAddress("::"),
-                                               false, false, "", false,
-                                               CalloutHandlePtr());
+    Lease6Ptr lease;
+    EXPECT_NO_THROW(lease = expectOneLease(engine->allocateAddress6(
+                    Subnet6Ptr(), duid_, iaid_, IOAddress("::"), false, false,
+                    "", false, CalloutHandlePtr())));
     ASSERT_FALSE(lease);
     ASSERT_FALSE(lease);
 
 
     // Allocations without DUID are not allowed either
     // Allocations without DUID are not allowed either
-    lease = engine->allocateAddress6(subnet_, DuidPtr(), iaid_,
-                                     IOAddress("::"),
-                                     false, false, "", false,
-                                     CalloutHandlePtr());
+    EXPECT_NO_THROW(lease = expectOneLease(engine->allocateAddress6(subnet_,
+                    DuidPtr(), iaid_, IOAddress("::"), false, false, "", false,
+                    CalloutHandlePtr())));
     ASSERT_FALSE(lease);
     ASSERT_FALSE(lease);
 }
 }
 
 
@@ -454,10 +478,10 @@ TEST_F(AllocEngine6Test, smallPool6) {
     subnet_->addPool(pool_);
     subnet_->addPool(pool_);
     cfg_mgr.addSubnet6(subnet_);
     cfg_mgr.addSubnet6(subnet_);
 
 
-    Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
-                                               IOAddress("::"),
-                                               false, false, "",
-                                               false, CalloutHandlePtr());
+    Lease6Ptr lease;
+    EXPECT_NO_THROW(lease = expectOneLease(engine->allocateAddress6(subnet_,
+                    duid_, iaid_, IOAddress("::"), false, false, "", false,
+                    CalloutHandlePtr())));
 
 
     // Check that we got that single lease
     // Check that we got that single lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
@@ -468,7 +492,8 @@ TEST_F(AllocEngine6Test, smallPool6) {
     checkLease6(lease);
     checkLease6(lease);
 
 
     // Check that the lease is indeed in LeaseMgr
     // Check that the lease is indeed in LeaseMgr
-    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->addr_);
+    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
+                                                               lease->addr_);
     ASSERT_TRUE(from_mgr);
     ASSERT_TRUE(from_mgr);
 
 
     // Now check that the lease in LeaseMgr has the same parameters
     // Now check that the lease in LeaseMgr has the same parameters
@@ -502,10 +527,10 @@ TEST_F(AllocEngine6Test, outOfAddresses6) {
 
 
     // There is just a single address in the pool and allocated it to someone
     // There is just a single address in the pool and allocated it to someone
     // else, so the allocation should fail
     // else, so the allocation should fail
-    Lease6Ptr lease2 = engine->allocateAddress6(subnet_, duid_, iaid_,
-                                                IOAddress("::"),
-                                                false, false, "", false,
-                                                CalloutHandlePtr());
+    Lease6Ptr lease2;
+    EXPECT_NO_THROW(lease2 = expectOneLease(engine->allocateAddress6(subnet_,
+                    duid_, iaid_, IOAddress("::"), false, false, "", false,
+                    CalloutHandlePtr())));
     EXPECT_FALSE(lease2);
     EXPECT_FALSE(lease2);
 }
 }
 
 
@@ -538,9 +563,9 @@ TEST_F(AllocEngine6Test, solicitReuseExpiredLease6) {
     ASSERT_TRUE(lease->expired());
     ASSERT_TRUE(lease->expired());
 
 
     // CASE 1: Asking for any address
     // CASE 1: Asking for any address
-    lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
-                                     false, false, "",
-                                     true, CalloutHandlePtr());
+    EXPECT_NO_THROW(lease = expectOneLease(engine->allocateAddress6(subnet_,
+                    duid_, iaid_, IOAddress("::"), false, false, "", true,
+                    CalloutHandlePtr())));
     // Check that we got that single lease
     // Check that we got that single lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
     EXPECT_EQ(addr.toText(), lease->addr_.toText());
     EXPECT_EQ(addr.toText(), lease->addr_.toText());
@@ -549,10 +574,10 @@ TEST_F(AllocEngine6Test, solicitReuseExpiredLease6) {
     checkLease6(lease);
     checkLease6(lease);
 
 
     // CASE 2: Asking specifically for this address
     // CASE 2: Asking specifically for this address
-    lease = engine->allocateAddress6(subnet_, duid_, iaid_,
-                                     IOAddress(addr.toText()),
-                                     false, false, "",
-                                     true, CalloutHandlePtr());
+    EXPECT_NO_THROW(lease = expectOneLease(engine->allocateAddress6(subnet_,
+                    duid_, iaid_, IOAddress(addr.toText()), false, false, "",
+                    true, CalloutHandlePtr())));
+
     // Check that we got that single lease
     // Check that we got that single lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
     EXPECT_EQ(addr.toText(), lease->addr_.toText());
     EXPECT_EQ(addr.toText(), lease->addr_.toText());
@@ -585,17 +610,17 @@ TEST_F(AllocEngine6Test, requestReuseExpiredLease6) {
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
     ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
 
 
     // A client comes along, asking specifically for this address
     // A client comes along, asking specifically for this address
-    lease = engine->allocateAddress6(subnet_, duid_, iaid_,
-                                     IOAddress(addr.toText()),
-                                     false, false, "", false,
-                                     CalloutHandlePtr());
+    EXPECT_NO_THROW(lease = expectOneLease(engine->allocateAddress6(subnet_,
+                    duid_, iaid_, IOAddress(addr.toText()), false, false, "",
+                    false, CalloutHandlePtr())));
 
 
     // Check that he got that single lease
     // Check that he got that single lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
     EXPECT_EQ(addr.toText(), lease->addr_.toText());
     EXPECT_EQ(addr.toText(), lease->addr_.toText());
 
 
     // Check that the lease is indeed updated in LeaseMgr
     // Check that the lease is indeed updated in LeaseMgr
-    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(addr);
+    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
+                                                               addr);
     ASSERT_TRUE(from_mgr);
     ASSERT_TRUE(from_mgr);
 
 
     // Now check that the lease in LeaseMgr has the same parameters
     // Now check that the lease in LeaseMgr has the same parameters
@@ -1119,7 +1144,7 @@ TEST_F(AllocEngine4Test, renewLease4) {
     // renew it.
     // renew it.
     ASSERT_FALSE(lease->expired());
     ASSERT_FALSE(lease->expired());
     lease = engine->renewLease4(subnet_, clientid_, hwaddr_, true,
     lease = engine->renewLease4(subnet_, clientid_, hwaddr_, true,
-                                true, "host.example.com.", lease, 
+                                true, "host.example.com.", lease,
                                 callout_handle, false);
                                 callout_handle, false);
     // Check that he got that single lease
     // Check that he got that single lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
@@ -1262,9 +1287,10 @@ TEST_F(HookAllocEngine6Test, lease6_select) {
 
 
     CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
     CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
 
 
-    Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
-                                               false, false, "",
-                                               false, callout_handle);
+    Lease6Ptr lease;
+    EXPECT_NO_THROW(lease = expectOneLease(engine->allocateAddress6(subnet_,
+                    duid_, iaid_, IOAddress("::"), false, false, "", false,
+                    callout_handle)));
     // Check that we got a lease
     // Check that we got a lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
 
 
@@ -1272,7 +1298,8 @@ TEST_F(HookAllocEngine6Test, lease6_select) {
     checkLease6(lease);
     checkLease6(lease);
 
 
     // Check that the lease is indeed in LeaseMgr
     // Check that the lease is indeed in LeaseMgr
-    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->addr_);
+    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
+                                                               lease->addr_);
     ASSERT_TRUE(from_mgr);
     ASSERT_TRUE(from_mgr);
 
 
     // Check that callouts were indeed called
     // Check that callouts were indeed called
@@ -1331,9 +1358,10 @@ TEST_F(HookAllocEngine6Test, change_lease6_select) {
     CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
     CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
 
 
     // Call allocateAddress6. Callouts should be triggered here.
     // Call allocateAddress6. Callouts should be triggered here.
-    Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
-                                               false, false, "",
-                                               false, callout_handle);
+    Lease6Ptr lease;
+    EXPECT_NO_THROW(lease = expectOneLease(engine->allocateAddress6(subnet_,
+                    duid_, iaid_, IOAddress("::"), false, false, "", false,
+                    callout_handle)));
     // Check that we got a lease
     // Check that we got a lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
 
 
@@ -1345,7 +1373,8 @@ TEST_F(HookAllocEngine6Test, change_lease6_select) {
     EXPECT_EQ(valid_override_, lease->valid_lft_);
     EXPECT_EQ(valid_override_, lease->valid_lft_);
 
 
     // Now check if the lease is in the database
     // Now check if the lease is in the database
-    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->addr_);
+    Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
+                                                               lease->addr_);
     ASSERT_TRUE(from_mgr);
     ASSERT_TRUE(from_mgr);
 
 
     // Check if values in the database are overridden
     // Check if values in the database are overridden
@@ -1575,6 +1604,4 @@ TEST_F(HookAllocEngine4Test, change_lease4_select) {
     EXPECT_EQ(valid_override_, from_mgr->valid_lft_);
     EXPECT_EQ(valid_override_, from_mgr->valid_lft_);
 }
 }
 
 
-
-
 }; // End of anonymous namespace
 }; // End of anonymous namespace

+ 69 - 14
src/lib/dhcpsrv/tests/lease_mgr_unittest.cc

@@ -16,6 +16,8 @@
 
 
 #include <asiolink/io_address.h>
 #include <asiolink/io_address.h>
 #include <dhcpsrv/lease_mgr.h>
 #include <dhcpsrv/lease_mgr.h>
+#include <dhcpsrv/memfile_lease_mgr.h>
+#include <dhcpsrv/tests/test_utils.h>
 
 
 #include <gtest/gtest.h>
 #include <gtest/gtest.h>
 
 
@@ -28,6 +30,7 @@ using namespace std;
 using namespace isc;
 using namespace isc;
 using namespace isc::asiolink;
 using namespace isc::asiolink;
 using namespace isc::dhcp;
 using namespace isc::dhcp;
+using namespace isc::dhcp::test;
 
 
 // This is a concrete implementation of a Lease database.  It does not do
 // This is a concrete implementation of a Lease database.  It does not do
 // anything useful and is used for abstract LeaseMgr class testing.
 // anything useful and is used for abstract LeaseMgr class testing.
@@ -128,29 +131,32 @@ public:
     /// @param addr address of the searched lease
     /// @param addr address of the searched lease
     ///
     ///
     /// @return smart pointer to the lease (or NULL if a lease is not found)
     /// @return smart pointer to the lease (or NULL if a lease is not found)
-    virtual Lease6Ptr getLease6(const isc::asiolink::IOAddress&) const {
+    virtual Lease6Ptr getLease6(Lease6::LeaseType /* not used yet */,
+                                const isc::asiolink::IOAddress&) const {
         return (Lease6Ptr());
         return (Lease6Ptr());
     }
     }
 
 
     /// @brief Returns existing IPv6 lease for a given DUID+IA combination
     /// @brief Returns existing IPv6 lease for a given DUID+IA combination
     ///
     ///
-    /// @param duid client DUID
-    /// @param iaid IA identifier
+    /// @param duid ignored
+    /// @param iaid ignored
     ///
     ///
-    /// @return collection of IPv6 leases
-    virtual Lease6Collection getLease6(const DUID&, uint32_t) const {
-        return (Lease6Collection());
+    /// @return whatever is set in leases6_ field
+    virtual Lease6Collection getLeases6(Lease6::LeaseType /* not used yet */,
+                                        const DUID&, uint32_t) const {
+        return (leases6_);
     }
     }
 
 
-    /// @brief Returns existing IPv6 lease for a given DUID+IA combination
+    /// @brief Returns existing IPv6 lease for a given DUID+IA+subnet-id combination
     ///
     ///
-    /// @param duid client DUID
-    /// @param iaid IA identifier
-    /// @param subnet_id identifier of the subnet the lease must belong to
+    /// @param duid ignored
+    /// @param iaid ignored
+    /// @param subnet_id ignored
     ///
     ///
-    /// @return smart pointer to the lease (or NULL if a lease is not found)
-    virtual Lease6Ptr getLease6(const DUID&, uint32_t, SubnetID) const {
-        return (Lease6Ptr());
+    /// @return whatever is set in leases6_ field
+    virtual Lease6Collection getLeases6(Lease6::LeaseType /* not used yet */,
+                                        const DUID&, uint32_t, SubnetID) const {
+        return (leases6_);
     }
     }
 
 
     /// @brief Updates IPv4 lease.
     /// @brief Updates IPv4 lease.
@@ -217,6 +223,17 @@ public:
     /// @brief Rollback transactions
     /// @brief Rollback transactions
     virtual void rollback() {
     virtual void rollback() {
     }
     }
+
+    // We need to use it in ConcreteLeaseMgr
+    using LeaseMgr::getLease6;
+
+    Lease6Collection leases6_; ///< getLease6 methods return this as is
+};
+
+class LeaseMgrTest : public GenericLeaseMgrTest {
+public:
+    LeaseMgrTest() {
+    }
 };
 };
 
 
 namespace {
 namespace {
@@ -225,7 +242,7 @@ namespace {
 ///
 ///
 /// This test checks if the LeaseMgr can be instantiated and that it
 /// This test checks if the LeaseMgr can be instantiated and that it
 /// parses parameters string properly.
 /// parses parameters string properly.
-TEST(LeaseMgr, getParameter) {
+TEST_F(LeaseMgrTest, getParameter) {
 
 
     LeaseMgr::ParameterMap pmap;
     LeaseMgr::ParameterMap pmap;
     pmap[std::string("param1")] = std::string("value1");
     pmap[std::string("param1")] = std::string("value1");
@@ -237,6 +254,44 @@ TEST(LeaseMgr, getParameter) {
     EXPECT_THROW(leasemgr.getParameter("param3"), BadValue);
     EXPECT_THROW(leasemgr.getParameter("param3"), BadValue);
 }
 }
 
 
+// This test checks if getLease6() method is working properly for 0 (NULL),
+// 1 (return the lease) and more than 1 leases (throw).
+TEST_F(LeaseMgrTest, getLease6) {
+
+    LeaseMgr::ParameterMap pmap;
+    boost::scoped_ptr<ConcreteLeaseMgr> mgr(new ConcreteLeaseMgr(pmap));
+
+    vector<Lease6Ptr> leases = createLeases6();
+
+    mgr->leases6_.clear();
+    // For no leases, the function should return NULL pointer
+    Lease6Ptr lease;
+
+    // the getLease6() is calling getLeases6(), which is a dummy. It returns
+    // whatever is there in leases6_ field.
+    EXPECT_NO_THROW(lease = mgr->getLease6(leasetype6_[1], *leases[1]->duid_,
+                                           leases[1]->iaid_,
+                                           leases[1]->subnet_id_));
+    EXPECT_TRUE(Lease6Ptr() == lease);
+
+    // For a single lease, the function should return that lease
+    mgr->leases6_.push_back(leases[1]);
+    EXPECT_NO_THROW(lease = mgr->getLease6(leasetype6_[1], *leases[1]->duid_,
+                                           leases[1]->iaid_,
+                                           leases[1]->subnet_id_));
+    EXPECT_TRUE(lease);
+
+    EXPECT_NO_THROW(detailCompareLease(lease, leases[1]));
+
+    // Add one more lease. There are 2 now. It should throw
+    mgr->leases6_.push_back(leases[2]);
+
+    EXPECT_THROW(lease = mgr->getLease6(leasetype6_[1], *leases[1]->duid_,
+                                        leases[1]->iaid_,
+                                        leases[1]->subnet_id_),
+                 MultipleRecords);
+}
+
 // There's no point in calling any other methods in LeaseMgr, as they
 // There's no point in calling any other methods in LeaseMgr, as they
 // are purely virtual, so we would only call ConcreteLeaseMgr methods.
 // are purely virtual, so we would only call ConcreteLeaseMgr methods.
 // Those methods are just stubs that do not return anything.
 // Those methods are just stubs that do not return anything.

+ 14 - 8
src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc

@@ -60,7 +60,7 @@ TEST_F(MemfileLeaseMgrTest, getTypeAndName) {
 // Checks that adding/getting/deleting a Lease6 object works.
 // Checks that adding/getting/deleting a Lease6 object works.
 TEST_F(MemfileLeaseMgrTest, addGetDelete6) {
 TEST_F(MemfileLeaseMgrTest, addGetDelete6) {
     const LeaseMgr::ParameterMap pmap;  // Empty parameter map
     const LeaseMgr::ParameterMap pmap;  // Empty parameter map
-    boost::scoped_ptr<Memfile_LeaseMgr> lease_mgr(new Memfile_LeaseMgr(pmap));
+    boost::scoped_ptr<LeaseMgr> lease_mgr(new Memfile_LeaseMgr(pmap));
 
 
     IOAddress addr("2001:db8:1::456");
     IOAddress addr("2001:db8:1::456");
 
 
@@ -80,10 +80,12 @@ TEST_F(MemfileLeaseMgrTest, addGetDelete6) {
     // should not be allowed to add a second lease with the same address
     // should not be allowed to add a second lease with the same address
     EXPECT_FALSE(lease_mgr->addLease(lease));
     EXPECT_FALSE(lease_mgr->addLease(lease));
 
 
-    Lease6Ptr x = lease_mgr->getLease6(IOAddress("2001:db8:1::234"));
+    Lease6Ptr x = lease_mgr->getLease6(Lease6::LEASE_IA_NA,
+                                       IOAddress("2001:db8:1::234"));
     EXPECT_EQ(Lease6Ptr(), x);
     EXPECT_EQ(Lease6Ptr(), x);
 
 
-    x = lease_mgr->getLease6(IOAddress("2001:db8:1::456"));
+    x = lease_mgr->getLease6(Lease6::LEASE_IA_NA,
+                             IOAddress("2001:db8:1::456"));
     ASSERT_TRUE(x);
     ASSERT_TRUE(x);
 
 
     EXPECT_EQ(x->addr_.toText(), addr.toText());
     EXPECT_EQ(x->addr_.toText(), addr.toText());
@@ -100,7 +102,8 @@ TEST_F(MemfileLeaseMgrTest, addGetDelete6) {
     EXPECT_EQ(x->t2_, 80);
     EXPECT_EQ(x->t2_, 80);
 
 
     // Test getLease6(duid, iaid, subnet_id) - positive case
     // Test getLease6(duid, iaid, subnet_id) - positive case
-    Lease6Ptr y = lease_mgr->getLease6(*duid, iaid, subnet_id);
+    Lease6Ptr y = lease_mgr->getLease6(Lease6::LEASE_IA_NA, *duid, iaid,
+                                       subnet_id);
     ASSERT_TRUE(y);
     ASSERT_TRUE(y);
     EXPECT_TRUE(*y->duid_ == *duid);
     EXPECT_TRUE(*y->duid_ == *duid);
     EXPECT_EQ(y->iaid_, iaid);
     EXPECT_EQ(y->iaid_, iaid);
@@ -108,16 +111,19 @@ TEST_F(MemfileLeaseMgrTest, addGetDelete6) {
 
 
     // Test getLease6(duid, iaid, subnet_id) - wrong iaid
     // Test getLease6(duid, iaid, subnet_id) - wrong iaid
     uint32_t invalid_iaid = 9; // no such iaid
     uint32_t invalid_iaid = 9; // no such iaid
-    y = lease_mgr->getLease6(*duid, invalid_iaid, subnet_id);
+    y = lease_mgr->getLease6(Lease6::LEASE_IA_NA, *duid, invalid_iaid,
+                             subnet_id);
     EXPECT_FALSE(y);
     EXPECT_FALSE(y);
 
 
     uint32_t invalid_subnet_id = 999;
     uint32_t invalid_subnet_id = 999;
-    y = lease_mgr->getLease6(*duid, iaid, invalid_subnet_id);
+    y = lease_mgr->getLease6(Lease6::LEASE_IA_NA, *duid, iaid,
+                             invalid_subnet_id);
     EXPECT_FALSE(y);
     EXPECT_FALSE(y);
 
 
     // truncated duid
     // truncated duid
     DuidPtr invalid_duid(new DUID(llt, sizeof(llt) - 1));
     DuidPtr invalid_duid(new DUID(llt, sizeof(llt) - 1));
-    y = lease_mgr->getLease6(*invalid_duid, iaid, subnet_id);
+    y = lease_mgr->getLease6(Lease6::LEASE_IA_NA, *invalid_duid, iaid,
+                             subnet_id);
     EXPECT_FALSE(y);
     EXPECT_FALSE(y);
 
 
     // should return false - there's no such address
     // should return false - there's no such address
@@ -127,7 +133,7 @@ TEST_F(MemfileLeaseMgrTest, addGetDelete6) {
     EXPECT_TRUE(lease_mgr->deleteLease(IOAddress("2001:db8:1::456")));
     EXPECT_TRUE(lease_mgr->deleteLease(IOAddress("2001:db8:1::456")));
 
 
     // after the lease is deleted, it should really be gone
     // after the lease is deleted, it should really be gone
-    x = lease_mgr->getLease6(IOAddress("2001:db8:1::456"));
+    x = lease_mgr->getLease6(Lease6::LEASE_IA_NA, IOAddress("2001:db8:1::456"));
     EXPECT_EQ(Lease6Ptr(), x);
     EXPECT_EQ(Lease6Ptr(), x);
 }
 }
 
 

+ 28 - 23
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc

@@ -484,15 +484,15 @@ TEST_F(MySqlLeaseMgrTest, basicLease6) {
     // Reopen the database to ensure that they actually got stored.
     // Reopen the database to ensure that they actually got stored.
     reopen();
     reopen();
 
 
-    Lease6Ptr l_returned = lmptr_->getLease6(ioaddress6_[1]);
+    Lease6Ptr l_returned = lmptr_->getLease6(leasetype6_[1], ioaddress6_[1]);
     ASSERT_TRUE(l_returned);
     ASSERT_TRUE(l_returned);
     detailCompareLease(leases[1], l_returned);
     detailCompareLease(leases[1], l_returned);
 
 
-    l_returned = lmptr_->getLease6(ioaddress6_[2]);
+    l_returned = lmptr_->getLease6(leasetype6_[2], ioaddress6_[2]);
     ASSERT_TRUE(l_returned);
     ASSERT_TRUE(l_returned);
     detailCompareLease(leases[2], l_returned);
     detailCompareLease(leases[2], l_returned);
 
 
-    l_returned = lmptr_->getLease6(ioaddress6_[3]);
+    l_returned = lmptr_->getLease6(leasetype6_[3], ioaddress6_[3]);
     ASSERT_TRUE(l_returned);
     ASSERT_TRUE(l_returned);
     detailCompareLease(leases[3], l_returned);
     detailCompareLease(leases[3], l_returned);
 
 
@@ -502,12 +502,12 @@ TEST_F(MySqlLeaseMgrTest, basicLease6) {
     // Delete a lease, check that it's gone, and that we can't delete it
     // Delete a lease, check that it's gone, and that we can't delete it
     // a second time.
     // a second time.
     EXPECT_TRUE(lmptr_->deleteLease(ioaddress6_[1]));
     EXPECT_TRUE(lmptr_->deleteLease(ioaddress6_[1]));
-    l_returned = lmptr_->getLease6(ioaddress6_[1]);
+    l_returned = lmptr_->getLease6(leasetype6_[1], ioaddress6_[1]);
     EXPECT_FALSE(l_returned);
     EXPECT_FALSE(l_returned);
     EXPECT_FALSE(lmptr_->deleteLease(ioaddress6_[1]));
     EXPECT_FALSE(lmptr_->deleteLease(ioaddress6_[1]));
 
 
     // Check that the second address is still there.
     // Check that the second address is still there.
-    l_returned = lmptr_->getLease6(ioaddress6_[2]);
+    l_returned = lmptr_->getLease6(leasetype6_[2], ioaddress6_[2]);
     ASSERT_TRUE(l_returned);
     ASSERT_TRUE(l_returned);
     detailCompareLease(leases[2], l_returned);
     detailCompareLease(leases[2], l_returned);
 }
 }
@@ -525,7 +525,7 @@ TEST_F(MySqlLeaseMgrTest, lease6InvalidHostname) {
     ASSERT_TRUE(lmptr_->addLease(leases[1]));
     ASSERT_TRUE(lmptr_->addLease(leases[1]));
 
 
     // The new lease must be in the database.
     // The new lease must be in the database.
-    Lease6Ptr l_returned = lmptr_->getLease6(ioaddress6_[1]);
+    Lease6Ptr l_returned = lmptr_->getLease6(leasetype6_[1], ioaddress6_[1]);
     detailCompareLease(leases[1], l_returned);
     detailCompareLease(leases[1], l_returned);
 
 
     // Let's delete the lease, so as we can try to add it again with
     // Let's delete the lease, so as we can try to add it again with
@@ -824,6 +824,7 @@ TEST_F(MySqlLeaseMgrTest, getLease4ClientIdSubnetId) {
 ///
 ///
 /// Adds leases to the database and checks that they can be accessed via
 /// Adds leases to the database and checks that they can be accessed via
 /// a combination of DIUID and IAID.
 /// a combination of DIUID and IAID.
+/// @todo: update this test once type checking/filtering is implemented
 TEST_F(MySqlLeaseMgrTest, getLease6DuidIaid) {
 TEST_F(MySqlLeaseMgrTest, getLease6DuidIaid) {
     // Get the leases to be used for the test.
     // Get the leases to be used for the test.
     vector<Lease6Ptr> leases = createLeases6();
     vector<Lease6Ptr> leases = createLeases6();
@@ -835,8 +836,9 @@ TEST_F(MySqlLeaseMgrTest, getLease6DuidIaid) {
     }
     }
 
 
     // Get the leases matching the DUID and IAID of lease[1].
     // Get the leases matching the DUID and IAID of lease[1].
-    Lease6Collection returned = lmptr_->getLease6(*leases[1]->duid_,
-                                                  leases[1]->iaid_);
+    Lease6Collection returned = lmptr_->getLeases6(leasetype6_[1],
+                                                   *leases[1]->duid_,
+                                                   leases[1]->iaid_);
 
 
     // Should be three leases, matching leases[1], [4] and [5].
     // Should be three leases, matching leases[1], [4] and [5].
     ASSERT_EQ(3, returned.size());
     ASSERT_EQ(3, returned.size());
@@ -854,20 +856,22 @@ TEST_F(MySqlLeaseMgrTest, getLease6DuidIaid) {
 
 
     // Check that nothing is returned when either the IAID or DUID match
     // Check that nothing is returned when either the IAID or DUID match
     // nothing.
     // nothing.
-    returned = lmptr_->getLease6(*leases[1]->duid_, leases[1]->iaid_ + 1);
+    returned = lmptr_->getLeases6(leasetype6_[1], *leases[1]->duid_,
+                                  leases[1]->iaid_ + 1);
     EXPECT_EQ(0, returned.size());
     EXPECT_EQ(0, returned.size());
 
 
     // Alter the leases[1] DUID to match nothing in the database.
     // Alter the leases[1] DUID to match nothing in the database.
     vector<uint8_t> duid_vector = leases[1]->duid_->getDuid();
     vector<uint8_t> duid_vector = leases[1]->duid_->getDuid();
     ++duid_vector[0];
     ++duid_vector[0];
     DUID new_duid(duid_vector);
     DUID new_duid(duid_vector);
-    returned = lmptr_->getLease6(new_duid, leases[1]->iaid_);
+    returned = lmptr_->getLeases6(leasetype6_[1], new_duid, leases[1]->iaid_);
     EXPECT_EQ(0, returned.size());
     EXPECT_EQ(0, returned.size());
 }
 }
 
 
 // @brief Get Lease4 by DUID and IAID (2)
 // @brief Get Lease4 by DUID and IAID (2)
 //
 //
 // Check that the system can cope with a DUID of any size.
 // Check that the system can cope with a DUID of any size.
+/// @todo: update this test once type checking/filtering is implemented
 TEST_F(MySqlLeaseMgrTest, getLease6DuidIaidSize) {
 TEST_F(MySqlLeaseMgrTest, getLease6DuidIaidSize) {
 
 
     // Create leases, although we need only one.
     // Create leases, although we need only one.
@@ -885,8 +889,9 @@ TEST_F(MySqlLeaseMgrTest, getLease6DuidIaidSize) {
         vector<uint8_t> duid_vec(i, i);
         vector<uint8_t> duid_vec(i, i);
         leases[1]->duid_.reset(new DUID(duid_vec));
         leases[1]->duid_.reset(new DUID(duid_vec));
         EXPECT_TRUE(lmptr_->addLease(leases[1]));
         EXPECT_TRUE(lmptr_->addLease(leases[1]));
-        Lease6Collection returned = lmptr_->getLease6(*leases[1]->duid_,
-                                                      leases[1]->iaid_);
+        Lease6Collection returned = lmptr_->getLeases6(leasetype6_[1],
+                                                       *leases[1]->duid_,
+                                                       leases[1]->iaid_);
         ASSERT_EQ(1, returned.size());
         ASSERT_EQ(1, returned.size());
         detailCompareLease(leases[1], *returned.begin());
         detailCompareLease(leases[1], *returned.begin());
         (void) lmptr_->deleteLease(leases[1]->addr_);
         (void) lmptr_->deleteLease(leases[1]->addr_);
@@ -909,7 +914,7 @@ TEST_F(MySqlLeaseMgrTest, getLease6DuidIaidSubnetId) {
     }
     }
 
 
     // Get the leases matching the DUID and IAID of lease[1].
     // Get the leases matching the DUID and IAID of lease[1].
-    Lease6Ptr returned = lmptr_->getLease6(*leases[1]->duid_,
+    Lease6Ptr returned = lmptr_->getLease6(leasetype6_[1], *leases[1]->duid_,
                                            leases[1]->iaid_,
                                            leases[1]->iaid_,
                                            leases[1]->subnet_id_);
                                            leases[1]->subnet_id_);
     ASSERT_TRUE(returned);
     ASSERT_TRUE(returned);
@@ -917,19 +922,19 @@ TEST_F(MySqlLeaseMgrTest, getLease6DuidIaidSubnetId) {
 
 
     // Modify each of the three parameters (DUID, IAID, Subnet ID) and
     // Modify each of the three parameters (DUID, IAID, Subnet ID) and
     // check that nothing is returned.
     // check that nothing is returned.
-    returned = lmptr_->getLease6(*leases[1]->duid_, leases[1]->iaid_ + 1,
-                                 leases[1]->subnet_id_);
+    returned = lmptr_->getLease6(leasetype6_[1], *leases[1]->duid_,
+                                 leases[1]->iaid_ + 1, leases[1]->subnet_id_);
     EXPECT_FALSE(returned);
     EXPECT_FALSE(returned);
 
 
-    returned = lmptr_->getLease6(*leases[1]->duid_, leases[1]->iaid_,
-                                 leases[1]->subnet_id_ + 1);
+    returned = lmptr_->getLease6(leasetype6_[1], *leases[1]->duid_,
+                                 leases[1]->iaid_, leases[1]->subnet_id_ + 1);
     EXPECT_FALSE(returned);
     EXPECT_FALSE(returned);
 
 
     // Alter the leases[1] DUID to match nothing in the database.
     // Alter the leases[1] DUID to match nothing in the database.
     vector<uint8_t> duid_vector = leases[1]->duid_->getDuid();
     vector<uint8_t> duid_vector = leases[1]->duid_->getDuid();
     ++duid_vector[0];
     ++duid_vector[0];
     DUID new_duid(duid_vector);
     DUID new_duid(duid_vector);
-    returned = lmptr_->getLease6(new_duid, leases[1]->iaid_,
+    returned = lmptr_->getLease6(leasetype6_[1], new_duid, leases[1]->iaid_,
                                  leases[1]->subnet_id_);
                                  leases[1]->subnet_id_);
     EXPECT_FALSE(returned);
     EXPECT_FALSE(returned);
 }
 }
@@ -954,7 +959,7 @@ TEST_F(MySqlLeaseMgrTest, getLease6DuidIaidSubnetIdSize) {
         vector<uint8_t> duid_vec(i, i);
         vector<uint8_t> duid_vec(i, i);
         leases[1]->duid_.reset(new DUID(duid_vec));
         leases[1]->duid_.reset(new DUID(duid_vec));
         EXPECT_TRUE(lmptr_->addLease(leases[1]));
         EXPECT_TRUE(lmptr_->addLease(leases[1]));
-        Lease6Ptr returned = lmptr_->getLease6(*leases[1]->duid_,
+        Lease6Ptr returned = lmptr_->getLease6(leasetype6_[1], *leases[1]->duid_,
                                                leases[1]->iaid_,
                                                leases[1]->iaid_,
                                                leases[1]->subnet_id_);
                                                leases[1]->subnet_id_);
         ASSERT_TRUE(returned);
         ASSERT_TRUE(returned);
@@ -1030,7 +1035,7 @@ TEST_F(MySqlLeaseMgrTest, updateLease6) {
     EXPECT_TRUE(lmptr_->addLease(leases[1]));
     EXPECT_TRUE(lmptr_->addLease(leases[1]));
     lmptr_->commit();
     lmptr_->commit();
 
 
-    Lease6Ptr l_returned = lmptr_->getLease6(ioaddress6_[1]);
+    Lease6Ptr l_returned = lmptr_->getLease6(leasetype6_[1], ioaddress6_[1]);
     ASSERT_TRUE(l_returned);
     ASSERT_TRUE(l_returned);
     detailCompareLease(leases[1], l_returned);
     detailCompareLease(leases[1], l_returned);
 
 
@@ -1046,7 +1051,7 @@ TEST_F(MySqlLeaseMgrTest, updateLease6) {
 
 
     // ... and check what is returned is what is expected.
     // ... and check what is returned is what is expected.
     l_returned.reset();
     l_returned.reset();
-    l_returned = lmptr_->getLease6(ioaddress6_[1]);
+    l_returned = lmptr_->getLease6(leasetype6_[1], ioaddress6_[1]);
     ASSERT_TRUE(l_returned);
     ASSERT_TRUE(l_returned);
     detailCompareLease(leases[1], l_returned);
     detailCompareLease(leases[1], l_returned);
 
 
@@ -1058,14 +1063,14 @@ TEST_F(MySqlLeaseMgrTest, updateLease6) {
     lmptr_->updateLease6(leases[1]);
     lmptr_->updateLease6(leases[1]);
 
 
     l_returned.reset();
     l_returned.reset();
-    l_returned = lmptr_->getLease6(ioaddress6_[1]);
+    l_returned = lmptr_->getLease6(leasetype6_[1], ioaddress6_[1]);
     ASSERT_TRUE(l_returned);
     ASSERT_TRUE(l_returned);
     detailCompareLease(leases[1], l_returned);
     detailCompareLease(leases[1], l_returned);
 
 
     // Check we can do an update without changing data.
     // Check we can do an update without changing data.
     lmptr_->updateLease6(leases[1]);
     lmptr_->updateLease6(leases[1]);
     l_returned.reset();
     l_returned.reset();
-    l_returned = lmptr_->getLease6(ioaddress6_[1]);
+    l_returned = lmptr_->getLease6(leasetype6_[1], ioaddress6_[1]);
     ASSERT_TRUE(l_returned);
     ASSERT_TRUE(l_returned);
     detailCompareLease(leases[1], l_returned);
     detailCompareLease(leases[1], l_returned);
 
 

+ 19 - 8
src/lib/dhcpsrv/tests/test_utils.cc

@@ -36,6 +36,13 @@ const char* ADDRESS6[] = {
     NULL
     NULL
 };
 };
 
 
+// Lease types that correspond to ADDRESS6 leases
+static const Lease6::LeaseType LEASETYPE6[] = {
+    Lease6::LEASE_IA_NA, Lease6::LEASE_IA_TA, Lease6::LEASE_IA_PD,
+    Lease6::LEASE_IA_NA, Lease6::LEASE_IA_TA, Lease6::LEASE_IA_PD,
+    Lease6::LEASE_IA_NA, Lease6::LEASE_IA_TA
+};
+
 void
 void
 detailCompareLease(const Lease4Ptr& first, const Lease4Ptr& second) {
 detailCompareLease(const Lease4Ptr& first, const Lease4Ptr& second) {
     // Compare address strings.  Comparison of address objects is not used, as
     // Compare address strings.  Comparison of address objects is not used, as
@@ -108,6 +115,10 @@ GenericLeaseMgrTest::GenericLeaseMgrTest()
         straddress6_.push_back(addr);
         straddress6_.push_back(addr);
         IOAddress ioaddr(addr);
         IOAddress ioaddr(addr);
         ioaddress6_.push_back(ioaddr);
         ioaddress6_.push_back(ioaddr);
+
+        /// Let's create different lease types. We use LEASETYPE6 values as
+        /// a template
+        leasetype6_.push_back(LEASETYPE6[i]);
     }
     }
 }
 }
 
 
@@ -264,7 +275,7 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
 
 
     // Set other parameters.  For historical reasons, address 0 is not used.
     // Set other parameters.  For historical reasons, address 0 is not used.
     if (address == straddress6_[0]) {
     if (address == straddress6_[0]) {
-        lease->type_ = Lease6::LEASE_IA_TA;
+        lease->type_ = leasetype6_[0];
         lease->prefixlen_ = 4;
         lease->prefixlen_ = 4;
         lease->iaid_ = 142;
         lease->iaid_ = 142;
         lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x77)));
         lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x77)));
@@ -277,7 +288,7 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
         lease->hostname_ = "myhost.example.com.";
         lease->hostname_ = "myhost.example.com.";
 
 
     } else if (address == straddress6_[1]) {
     } else if (address == straddress6_[1]) {
-        lease->type_ = Lease6::LEASE_IA_TA;
+        lease->type_ = leasetype6_[1];
         lease->prefixlen_ = 0;
         lease->prefixlen_ = 0;
         lease->iaid_ = 42;
         lease->iaid_ = 42;
         lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
         lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
@@ -290,7 +301,7 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
         lease->hostname_ = "myhost.example.com.";
         lease->hostname_ = "myhost.example.com.";
 
 
     } else if (address == straddress6_[2]) {
     } else if (address == straddress6_[2]) {
-        lease->type_ = Lease6::LEASE_IA_PD;
+        lease->type_ = leasetype6_[2];
         lease->prefixlen_ = 7;
         lease->prefixlen_ = 7;
         lease->iaid_ = 89;
         lease->iaid_ = 89;
         lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x3a)));
         lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x3a)));
@@ -303,7 +314,7 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
         lease->hostname_ = "myhost.example.com.";
         lease->hostname_ = "myhost.example.com.";
 
 
     } else if (address == straddress6_[3]) {
     } else if (address == straddress6_[3]) {
-        lease->type_ = Lease6::LEASE_IA_NA;
+        lease->type_ = leasetype6_[3];
         lease->prefixlen_ = 28;
         lease->prefixlen_ = 28;
         lease->iaid_ = 0xfffffffe;
         lease->iaid_ = 0xfffffffe;
         vector<uint8_t> duid;
         vector<uint8_t> duid;
@@ -326,7 +337,7 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
 
 
     } else if (address == straddress6_[4]) {
     } else if (address == straddress6_[4]) {
         // Same DUID and IAID as straddress6_1
         // Same DUID and IAID as straddress6_1
-        lease->type_ = Lease6::LEASE_IA_PD;
+        lease->type_ = leasetype6_[4];
         lease->prefixlen_ = 15;
         lease->prefixlen_ = 15;
         lease->iaid_ = 42;
         lease->iaid_ = 42;
         lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
         lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
@@ -340,7 +351,7 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
 
 
     } else if (address == straddress6_[5]) {
     } else if (address == straddress6_[5]) {
         // Same DUID and IAID as straddress6_1
         // Same DUID and IAID as straddress6_1
-        lease->type_ = Lease6::LEASE_IA_PD;
+        lease->type_ = leasetype6_[5];
         lease->prefixlen_ = 24;
         lease->prefixlen_ = 24;
         lease->iaid_ = 42;                          // Same as lease 4
         lease->iaid_ = 42;                          // Same as lease 4
         lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
         lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
@@ -355,7 +366,7 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
 
 
     } else if (address == straddress6_[6]) {
     } else if (address == straddress6_[6]) {
         // Same DUID as straddress6_1
         // Same DUID as straddress6_1
-        lease->type_ = Lease6::LEASE_IA_PD;
+        lease->type_ = leasetype6_[6];
         lease->prefixlen_ = 24;
         lease->prefixlen_ = 24;
         lease->iaid_ = 93;
         lease->iaid_ = 93;
         lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
         lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
@@ -370,7 +381,7 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
 
 
     } else if (address == straddress6_[7]) {
     } else if (address == straddress6_[7]) {
         // Same IAID as straddress6_1
         // Same IAID as straddress6_1
-        lease->type_ = Lease6::LEASE_IA_PD;
+        lease->type_ = leasetype6_[7];
         lease->prefixlen_ = 24;
         lease->prefixlen_ = 24;
         lease->iaid_ = 42;
         lease->iaid_ = 42;
         lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0xe5)));
         lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0xe5)));

+ 1 - 0
src/lib/dhcpsrv/tests/test_utils.h

@@ -105,6 +105,7 @@ public:
     std::vector<std::string>  straddress4_;   ///< String forms of IPv4 addresses
     std::vector<std::string>  straddress4_;   ///< String forms of IPv4 addresses
     std::vector<isc::asiolink::IOAddress> ioaddress4_;  ///< IOAddress forms of IPv4 addresses
     std::vector<isc::asiolink::IOAddress> ioaddress4_;  ///< IOAddress forms of IPv4 addresses
     std::vector<std::string>  straddress6_;   ///< String forms of IPv6 addresses
     std::vector<std::string>  straddress6_;   ///< String forms of IPv6 addresses
+    std::vector<Lease6::LeaseType> leasetype6_; ///< Lease types
     std::vector<isc::asiolink::IOAddress> ioaddress6_;  ///< IOAddress forms of IPv6 addresses
     std::vector<isc::asiolink::IOAddress> ioaddress6_;  ///< IOAddress forms of IPv6 addresses
 
 
     LeaseMgr*   lmptr_;             ///< Pointer to the lease manager
     LeaseMgr*   lmptr_;             ///< Pointer to the lease manager