Browse Source

[2952] MySQL LeaseMgr unit-tests refactored

Tomek Mrugalski 11 years ago
parent
commit
36a281824e

+ 3 - 2
src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc

@@ -18,7 +18,7 @@
 #include <dhcp/duid.h>
 #include <dhcpsrv/lease_mgr.h>
 #include <dhcpsrv/memfile_lease_mgr.h>
-
+#include <dhcpsrv/tests/test_utils.h>
 #include <gtest/gtest.h>
 
 #include <iostream>
@@ -28,10 +28,11 @@ using namespace std;
 using namespace isc;
 using namespace isc::asiolink;
 using namespace isc::dhcp;
+using namespace isc::dhcp::test;
 
 namespace {
 // empty class for now, but may be extended once Addr6 becomes bigger
-class MemfileLeaseMgrTest : public ::testing::Test {
+class MemfileLeaseMgrTest : public GenericLeaseMgrTest {
 public:
     MemfileLeaseMgrTest() {
     }

+ 9 - 352
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc

@@ -20,6 +20,7 @@
 #include <dhcpsrv/tests/test_utils.h>
 #include <exceptions/exceptions.h>
 
+
 #include <gtest/gtest.h>
 
 #include <algorithm>
@@ -39,18 +40,6 @@ namespace {
 // This holds statements to create and destroy the schema.
 #include "schema_copy.h"
 
-// IPv4 and IPv6 addresses used in the tests
-const char* ADDRESS4[] = {
-    "192.0.2.0", "192.0.2.1", "192.0.2.2", "192.0.2.3",
-    "192.0.2.4", "192.0.2.5", "192.0.2.6", "192.0.2.7",
-    NULL
-};
-const char* ADDRESS6[] = {
-    "2001:db8::0", "2001:db8::1", "2001:db8::2", "2001:db8::3",
-    "2001:db8::4", "2001:db8::5", "2001:db8::6", "2001:db8::7",
-    NULL
-};
-
 // Connection strings.
 // Database: keatest
 // Host: localhost
@@ -155,26 +144,12 @@ void createSchema() {
 /// Opens the database prior to each test and closes it afterwards.
 /// All pending transactions are deleted prior to closure.
 
-class MySqlLeaseMgrTest : public ::testing::Test {
+class MySqlLeaseMgrTest : public GenericLeaseMgrTest {
 public:
     /// @brief Constructor
     ///
     /// Deletes everything from the database and opens it.
     MySqlLeaseMgrTest() {
-        // Initialize address strings and IOAddresses
-        for (int i = 0; ADDRESS4[i] != NULL; ++i) {
-            string addr(ADDRESS4[i]);
-            straddress4_.push_back(addr);
-            IOAddress ioaddr(addr);
-            ioaddress4_.push_back(ioaddr);
-        }
-
-        for (int i = 0; ADDRESS6[i] != NULL; ++i) {
-            string addr(ADDRESS6[i]);
-            straddress6_.push_back(addr);
-            IOAddress ioaddr(addr);
-            ioaddress6_.push_back(ioaddr);
-        }
 
         // Ensure schema is the correct one.
         destroySchema();
@@ -214,319 +189,6 @@ public:
         lmptr_ = &(LeaseMgrFactory::instance());
     }
 
-    /// @brief Initialize Lease4 Fields
-    ///
-    /// Returns a pointer to a Lease4 structure.  Different values are put into
-    /// the lease according to the address passed.
-    ///
-    /// This is just a convenience function for the test methods.
-    ///
-    /// @param address Address to use for the initialization
-    ///
-    /// @return Lease4Ptr.  This will not point to anything if the
-    ///         initialization failed (e.g. unknown address).
-    Lease4Ptr initializeLease4(std::string address) {
-        Lease4Ptr lease(new Lease4());
-
-        // Set the address of the lease
-        lease->addr_ = IOAddress(address);
-
-        // Initialize unused fields.
-        lease->ext_ = 0;                            // Not saved
-        lease->t1_ = 0;                             // Not saved
-        lease->t2_ = 0;                             // Not saved
-        lease->fixed_ = false;                      // Unused
-        lease->hostname_ = std::string("");         // Unused
-        lease->fqdn_fwd_ = false;                   // Unused
-        lease->fqdn_rev_ = false;                   // Unused
-        lease->comments_ = std::string("");         // Unused
-
-        // Set other parameters.  For historical reasons, address 0 is not used.
-        if (address == straddress4_[0]) {
-            lease->hwaddr_ = vector<uint8_t>(6, 0x08);
-            lease->client_id_ = ClientIdPtr(
-                new ClientId(vector<uint8_t>(8, 0x42)));
-            lease->valid_lft_ = 8677;
-            lease->cltt_ = 168256;
-            lease->subnet_id_ = 23;
-
-        } else if (address == straddress4_[1]) {
-            lease->hwaddr_ = vector<uint8_t>(6, 0x19);
-            lease->client_id_ = ClientIdPtr(
-                new ClientId(vector<uint8_t>(8, 0x53)));
-            lease->valid_lft_ = 3677;
-            lease->cltt_ = 123456;
-            lease->subnet_id_ = 73;
-
-        } else if (address == straddress4_[2]) {
-            lease->hwaddr_ = vector<uint8_t>(6, 0x2a);
-            lease->client_id_ = ClientIdPtr(
-                new ClientId(vector<uint8_t>(8, 0x64)));
-            lease->valid_lft_ = 5412;
-            lease->cltt_ = 234567;
-            lease->subnet_id_ = 73;                         // Same as lease 1
-
-        } else if (address == straddress4_[3]) {
-            lease->hwaddr_ = vector<uint8_t>(6, 0x19);      // Same as lease 1
-            lease->client_id_ = ClientIdPtr(
-                new ClientId(vector<uint8_t>(8, 0x75)));
-
-            // The times used in the next tests are deliberately restricted - we
-            // should be able to cope with valid lifetimes up to 0xffffffff.
-            //  However, this will lead to overflows.
-            // @TODO: test overflow conditions when code has been fixed
-            lease->valid_lft_ = 7000;
-            lease->cltt_ = 234567;
-            lease->subnet_id_ = 37;
-
-        } else if (address == straddress4_[4]) {
-            lease->hwaddr_ = vector<uint8_t>(6, 0x4c);
-            // Same ClientId as straddr4_[1]
-            lease->client_id_ = ClientIdPtr(
-                new ClientId(vector<uint8_t>(8, 0x53)));    // Same as lease 1
-            lease->valid_lft_ = 7736;
-            lease->cltt_ = 222456;
-            lease->subnet_id_ = 85;
-
-        } else if (address == straddress4_[5]) {
-            lease->hwaddr_ = vector<uint8_t>(6, 0x19);      // Same as lease 1
-            // Same ClientId and IAID as straddress4_1
-            lease->client_id_ = ClientIdPtr(
-                new ClientId(vector<uint8_t>(8, 0x53)));    // Same as lease 1
-            lease->valid_lft_ = 7832;
-            lease->cltt_ = 227476;
-            lease->subnet_id_ = 175;
-
-        } else if (address == straddress4_[6]) {
-            lease->hwaddr_ = vector<uint8_t>(6, 0x6e);
-            // Same ClientId as straddress4_1
-            lease->client_id_ = ClientIdPtr(
-                new ClientId(vector<uint8_t>(8, 0x53)));    // Same as lease 1
-            lease->valid_lft_ = 1832;
-            lease->cltt_ = 627476;
-            lease->subnet_id_ = 112;
-
-        } else if (address == straddress4_[7]) {
-            lease->hwaddr_ = vector<uint8_t>();             // Empty
-            lease->client_id_ = ClientIdPtr();              // Empty
-            lease->valid_lft_ = 7975;
-            lease->cltt_ = 213876;
-            lease->subnet_id_ = 19;
-
-        } else {
-            // Unknown address, return an empty pointer.
-            lease.reset();
-
-        }
-
-        return (lease);
-    }
-
-    /// @brief Initialize Lease6 Fields
-    ///
-    /// Returns a pointer to a Lease6 structure.  Different values are put into
-    /// the lease according to the address passed.
-    ///
-    /// This is just a convenience function for the test methods.
-    ///
-    /// @param address Address to use for the initialization
-    ///
-    /// @return Lease6Ptr.  This will not point to anything if the initialization
-    ///         failed (e.g. unknown address).
-    Lease6Ptr initializeLease6(std::string address) {
-        Lease6Ptr lease(new Lease6());
-
-        // Set the address of the lease
-        lease->addr_ = IOAddress(address);
-
-        // Initialize unused fields.
-        lease->t1_ = 0;                             // Not saved
-        lease->t2_ = 0;                             // Not saved
-        lease->fixed_ = false;                      // Unused
-        lease->hostname_ = std::string("");         // Unused
-        lease->fqdn_fwd_ = false;                   // Unused
-        lease->fqdn_rev_ = false;                   // Unused
-        lease->comments_ = std::string("");         // Unused
-
-        // Set other parameters.  For historical reasons, address 0 is not used.
-        if (address == straddress6_[0]) {
-            lease->type_ = Lease6::LEASE_IA_TA;
-            lease->prefixlen_ = 4;
-            lease->iaid_ = 142;
-            lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x77)));
-            lease->preferred_lft_ = 900;
-            lease->valid_lft_ = 8677;
-            lease->cltt_ = 168256;
-            lease->subnet_id_ = 23;
-
-        } else if (address == straddress6_[1]) {
-            lease->type_ = Lease6::LEASE_IA_TA;
-            lease->prefixlen_ = 0;
-            lease->iaid_ = 42;
-            lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
-            lease->preferred_lft_ = 3600;
-            lease->valid_lft_ = 3677;
-            lease->cltt_ = 123456;
-            lease->subnet_id_ = 73;
-
-        } else if (address == straddress6_[2]) {
-            lease->type_ = Lease6::LEASE_IA_PD;
-            lease->prefixlen_ = 7;
-            lease->iaid_ = 89;
-            lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x3a)));
-            lease->preferred_lft_ = 1800;
-            lease->valid_lft_ = 5412;
-            lease->cltt_ = 234567;
-            lease->subnet_id_ = 73;                     // Same as lease 1
-
-        } else if (address == straddress6_[3]) {
-            lease->type_ = Lease6::LEASE_IA_NA;
-            lease->prefixlen_ = 28;
-            lease->iaid_ = 0xfffffffe;
-            vector<uint8_t> duid;
-            for (uint8_t i = 31; i < 126; ++i) {
-                duid.push_back(i);
-            }
-            lease->duid_ = DuidPtr(new DUID(duid));
-
-            // The times used in the next tests are deliberately restricted - we
-            // should be able to cope with valid lifetimes up to 0xffffffff.
-            //  However, this will lead to overflows.
-            // @TODO: test overflow conditions when code has been fixed
-            lease->preferred_lft_ = 7200;
-            lease->valid_lft_ = 7000;
-            lease->cltt_ = 234567;
-            lease->subnet_id_ = 37;
-
-        } else if (address == straddress6_[4]) {
-            // Same DUID and IAID as straddress6_1
-            lease->type_ = Lease6::LEASE_IA_PD;
-            lease->prefixlen_ = 15;
-            lease->iaid_ = 42;
-            lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
-            lease->preferred_lft_ = 4800;
-            lease->valid_lft_ = 7736;
-            lease->cltt_ = 222456;
-            lease->subnet_id_ = 671;
-
-        } else if (address == straddress6_[5]) {
-            // Same DUID and IAID as straddress6_1
-            lease->type_ = Lease6::LEASE_IA_PD;
-            lease->prefixlen_ = 24;
-            lease->iaid_ = 42;                          // Same as lease 4
-            lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
-                                                        // Same as lease 4
-            lease->preferred_lft_ = 5400;
-            lease->valid_lft_ = 7832;
-            lease->cltt_ = 227476;
-            lease->subnet_id_ = 175;
-
-        } else if (address == straddress6_[6]) {
-            // Same DUID as straddress6_1
-            lease->type_ = Lease6::LEASE_IA_PD;
-            lease->prefixlen_ = 24;
-            lease->iaid_ = 93;
-            lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
-                                                        // Same as lease 4
-            lease->preferred_lft_ = 5400;
-            lease->valid_lft_ = 1832;
-            lease->cltt_ = 627476;
-            lease->subnet_id_ = 112;
-
-        } else if (address == straddress6_[7]) {
-            // Same IAID as straddress6_1
-            lease->type_ = Lease6::LEASE_IA_PD;
-            lease->prefixlen_ = 24;
-            lease->iaid_ = 42;
-            lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0xe5)));
-            lease->preferred_lft_ = 5600;
-            lease->valid_lft_ = 7975;
-            lease->cltt_ = 213876;
-            lease->subnet_id_ = 19;
-
-        } else {
-            // Unknown address, return an empty pointer.
-            lease.reset();
-
-        }
-
-        return (lease);
-    }
-
-    /// @brief Check Leases present and different
-    ///
-    /// Checks a vector of lease pointers and ensures that all the leases
-    /// they point to are present and different.  If not, a GTest assertion
-    /// will fail.
-    ///
-    /// @param leases Vector of pointers to leases
-    template <typename T>
-    void checkLeasesDifferent(const std::vector<T>& leases) const {
-
-        // Check they were created
-        for (int i = 0; i < leases.size(); ++i) {
-            ASSERT_TRUE(leases[i]);
-        }
-
-        // Check they are different
-        for (int i = 0; i < (leases.size() - 1); ++i) {
-            for (int j = (i + 1); j < leases.size(); ++j) {
-                stringstream s;
-                s << "Comparing leases " << i << " & " << j << " for equality";
-                SCOPED_TRACE(s.str());
-                EXPECT_TRUE(*leases[i] != *leases[j]);
-            }
-        }
-    }
-
-    /// @brief Creates leases for the test
-    ///
-    /// Creates all leases for the test and checks that they are different.
-    ///
-    /// @return vector<Lease4Ptr> Vector of pointers to leases
-    vector<Lease4Ptr> createLeases4() {
-
-        // Create leases for each address
-        vector<Lease4Ptr> leases;
-        for (int i = 0; i < straddress4_.size(); ++i) {
-            leases.push_back(initializeLease4(straddress4_[i]));
-        }
-        EXPECT_EQ(8, leases.size());
-
-        // Check all were created and that they are different.
-        checkLeasesDifferent(leases);
-
-        return (leases);
-    }
-
-    /// @brief Creates leases for the test
-    ///
-    /// Creates all leases for the test and checks that they are different.
-    ///
-    /// @return vector<Lease6Ptr> Vector of pointers to leases
-    vector<Lease6Ptr> createLeases6() {
-
-        // Create leases for each address
-        vector<Lease6Ptr> leases;
-        for (int i = 0; i < straddress6_.size(); ++i) {
-            leases.push_back(initializeLease6(straddress6_[i]));
-        }
-        EXPECT_EQ(8, leases.size());
-
-        // Check all were created and that they are different.
-        checkLeasesDifferent(leases);
-
-        return (leases);
-    }
-
-
-    // Member variables
-
-    LeaseMgr*   lmptr_;             ///< Pointer to the lease manager
-    vector<string>  straddress4_;   ///< String forms of IPv4 addresses
-    vector<IOAddress> ioaddress4_;  ///< IOAddress forms of IPv4 addresses
-    vector<string>  straddress6_;   ///< String forms of IPv6 addresses
-    vector<IOAddress> ioaddress6_;  ///< IOAddress forms of IPv6 addresses
 };
 
 /// @brief Check that database can be opened
@@ -888,7 +550,7 @@ TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSize) {
         leases[1]->hwaddr_.resize(i, i);
         EXPECT_TRUE(lmptr_->addLease(leases[1]));
         // @todo: Simply use HWAddr directly once 2589 is implemented
-        Lease4Collection returned = 
+        Lease4Collection returned =
             lmptr_->getLease4(HWAddr(leases[1]->hwaddr_, HTYPE_ETHER));
 
         ASSERT_EQ(1, returned.size());
@@ -917,7 +579,7 @@ TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSubnetId) {
     // Get the leases matching the hardware address of lease 1 and
     // subnet ID of lease 1.  Result should be a single lease - lease 1.
     // @todo: Simply use HWAddr directly once 2589 is implemented
-    Lease4Ptr returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_, 
+    Lease4Ptr returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_,
         HTYPE_ETHER), leases[1]->subnet_id_);
 
     ASSERT_TRUE(returned);
@@ -954,16 +616,11 @@ TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSubnetId) {
     leases[1]->addr_ = leases[2]->addr_;
     EXPECT_TRUE(lmptr_->addLease(leases[1]));
     // @todo: Simply use HWAddr directly once 2589 is implemented
-    EXPECT_THROW(returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_, 
-                                                    HTYPE_ETHER), 
-                                             leases[1]->subnet_id_), 
+    EXPECT_THROW(returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_,
+                                                    HTYPE_ETHER),
+                                             leases[1]->subnet_id_),
                  isc::dhcp::MultipleRecords);
 
-    // Delete all leases in the database
-    for (int i = 0; ADDRESS4[i] != NULL; ++i) {
-        IOAddress addr(ADDRESS4[i]);
-        (void) lmptr_->deleteLease(addr);
-    }
 }
 
 // @brief Get lease4 by hardware address and subnet ID (2)
@@ -981,8 +638,8 @@ TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSubnetIdSize) {
         leases[1]->hwaddr_.resize(i, i);
         EXPECT_TRUE(lmptr_->addLease(leases[1]));
         // @todo: Simply use HWAddr directly once 2589 is implemented
-        Lease4Ptr returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_, 
-                                                      HTYPE_ETHER), 
+        Lease4Ptr returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_,
+                                                      HTYPE_ETHER),
                                                leases[1]->subnet_id_);
         ASSERT_TRUE(returned);
         detailCompareLease(leases[1], returned);

+ 304 - 0
src/lib/dhcpsrv/tests/test_utils.cc

@@ -13,12 +13,29 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include "test_utils.h"
+#include <asiolink/io_address.h>
 #include <gtest/gtest.h>
+#include <sstream>
+
+using namespace std;
+using namespace isc::asiolink;
 
 namespace isc {
 namespace dhcp {
 namespace test {
 
+// IPv4 and IPv6 addresses used in the tests
+const char* ADDRESS4[] = {
+    "192.0.2.0", "192.0.2.1", "192.0.2.2", "192.0.2.3",
+    "192.0.2.4", "192.0.2.5", "192.0.2.6", "192.0.2.7",
+    NULL
+};
+const char* ADDRESS6[] = {
+    "2001:db8::0", "2001:db8::1", "2001:db8::2", "2001:db8::3",
+    "2001:db8::4", "2001:db8::5", "2001:db8::6", "2001:db8::7",
+    NULL
+};
+
 void
 detailCompareLease(const Lease4Ptr& first, const Lease4Ptr& second) {
     // Compare address strings.  Comparison of address objects is not used, as
@@ -69,6 +86,293 @@ detailCompareLease(const Lease6Ptr& first, const Lease6Ptr& second) {
     EXPECT_EQ(first->subnet_id_, second->subnet_id_);
 }
 
+
+GenericLeaseMgrTest::GenericLeaseMgrTest() {
+    // Initialize address strings and IOAddresses
+    for (int i = 0; ADDRESS4[i] != NULL; ++i) {
+        string addr(ADDRESS4[i]);
+        straddress4_.push_back(addr);
+        IOAddress ioaddr(addr);
+        ioaddress4_.push_back(ioaddr);
+    }
+
+    for (int i = 0; ADDRESS6[i] != NULL; ++i) {
+        string addr(ADDRESS6[i]);
+        straddress6_.push_back(addr);
+        IOAddress ioaddr(addr);
+        ioaddress6_.push_back(ioaddr);
+    }
+}
+
+Lease4Ptr
+GenericLeaseMgrTest::initializeLease4(std::string address) {
+    Lease4Ptr lease(new Lease4());
+
+    // Set the address of the lease
+    lease->addr_ = IOAddress(address);
+
+    // Initialize unused fields.
+    lease->ext_ = 0;                            // Not saved
+    lease->t1_ = 0;                             // Not saved
+    lease->t2_ = 0;                             // Not saved
+    lease->fixed_ = false;                      // Unused
+    lease->hostname_ = std::string("");         // Unused
+    lease->fqdn_fwd_ = false;                   // Unused
+    lease->fqdn_rev_ = false;                   // Unused
+    lease->comments_ = std::string("");         // Unused
+
+    // Set other parameters.  For historical reasons, address 0 is not used.
+    if (address == straddress4_[0]) {
+        lease->hwaddr_ = vector<uint8_t>(6, 0x08);
+        lease->client_id_ = ClientIdPtr(
+            new ClientId(vector<uint8_t>(8, 0x42)));
+        lease->valid_lft_ = 8677;
+        lease->cltt_ = 168256;
+        lease->subnet_id_ = 23;
+
+    } else if (address == straddress4_[1]) {
+        lease->hwaddr_ = vector<uint8_t>(6, 0x19);
+        lease->client_id_ = ClientIdPtr(
+            new ClientId(vector<uint8_t>(8, 0x53)));
+        lease->valid_lft_ = 3677;
+        lease->cltt_ = 123456;
+        lease->subnet_id_ = 73;
+
+    } else if (address == straddress4_[2]) {
+        lease->hwaddr_ = vector<uint8_t>(6, 0x2a);
+        lease->client_id_ = ClientIdPtr(
+            new ClientId(vector<uint8_t>(8, 0x64)));
+        lease->valid_lft_ = 5412;
+        lease->cltt_ = 234567;
+        lease->subnet_id_ = 73;                         // Same as lease 1
+
+    } else if (address == straddress4_[3]) {
+        lease->hwaddr_ = vector<uint8_t>(6, 0x19);      // Same as lease 1
+        lease->client_id_ = ClientIdPtr(
+            new ClientId(vector<uint8_t>(8, 0x75)));
+
+        // The times used in the next tests are deliberately restricted - we
+        // should be able to cope with valid lifetimes up to 0xffffffff.
+        //  However, this will lead to overflows.
+        // @TODO: test overflow conditions when code has been fixed
+        lease->valid_lft_ = 7000;
+        lease->cltt_ = 234567;
+        lease->subnet_id_ = 37;
+
+    } else if (address == straddress4_[4]) {
+        lease->hwaddr_ = vector<uint8_t>(6, 0x4c);
+        // Same ClientId as straddr4_[1]
+        lease->client_id_ = ClientIdPtr(
+            new ClientId(vector<uint8_t>(8, 0x53)));    // Same as lease 1
+        lease->valid_lft_ = 7736;
+        lease->cltt_ = 222456;
+        lease->subnet_id_ = 85;
+
+    } else if (address == straddress4_[5]) {
+        lease->hwaddr_ = vector<uint8_t>(6, 0x19);      // Same as lease 1
+        // Same ClientId and IAID as straddress4_1
+        lease->client_id_ = ClientIdPtr(
+            new ClientId(vector<uint8_t>(8, 0x53)));    // Same as lease 1
+        lease->valid_lft_ = 7832;
+        lease->cltt_ = 227476;
+        lease->subnet_id_ = 175;
+
+    } else if (address == straddress4_[6]) {
+        lease->hwaddr_ = vector<uint8_t>(6, 0x6e);
+        // Same ClientId as straddress4_1
+        lease->client_id_ = ClientIdPtr(
+            new ClientId(vector<uint8_t>(8, 0x53)));    // Same as lease 1
+        lease->valid_lft_ = 1832;
+        lease->cltt_ = 627476;
+        lease->subnet_id_ = 112;
+
+    } else if (address == straddress4_[7]) {
+        lease->hwaddr_ = vector<uint8_t>();             // Empty
+        lease->client_id_ = ClientIdPtr();              // Empty
+        lease->valid_lft_ = 7975;
+        lease->cltt_ = 213876;
+        lease->subnet_id_ = 19;
+
+    } else {
+        // Unknown address, return an empty pointer.
+        lease.reset();
+
+    }
+
+    return (lease);
+}
+
+Lease6Ptr
+GenericLeaseMgrTest::initializeLease6(std::string address) {
+    Lease6Ptr lease(new Lease6());
+
+    // Set the address of the lease
+    lease->addr_ = IOAddress(address);
+
+    // Initialize unused fields.
+    lease->t1_ = 0;                             // Not saved
+    lease->t2_ = 0;                             // Not saved
+    lease->fixed_ = false;                      // Unused
+    lease->hostname_ = std::string("");         // Unused
+    lease->fqdn_fwd_ = false;                   // Unused
+    lease->fqdn_rev_ = false;                   // Unused
+    lease->comments_ = std::string("");         // Unused
+
+    // Set other parameters.  For historical reasons, address 0 is not used.
+    if (address == straddress6_[0]) {
+        lease->type_ = Lease6::LEASE_IA_TA;
+        lease->prefixlen_ = 4;
+        lease->iaid_ = 142;
+        lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x77)));
+        lease->preferred_lft_ = 900;
+        lease->valid_lft_ = 8677;
+        lease->cltt_ = 168256;
+        lease->subnet_id_ = 23;
+
+    } else if (address == straddress6_[1]) {
+        lease->type_ = Lease6::LEASE_IA_TA;
+        lease->prefixlen_ = 0;
+        lease->iaid_ = 42;
+        lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
+        lease->preferred_lft_ = 3600;
+        lease->valid_lft_ = 3677;
+        lease->cltt_ = 123456;
+        lease->subnet_id_ = 73;
+
+    } else if (address == straddress6_[2]) {
+        lease->type_ = Lease6::LEASE_IA_PD;
+        lease->prefixlen_ = 7;
+        lease->iaid_ = 89;
+        lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x3a)));
+        lease->preferred_lft_ = 1800;
+        lease->valid_lft_ = 5412;
+        lease->cltt_ = 234567;
+        lease->subnet_id_ = 73;                     // Same as lease 1
+
+    } else if (address == straddress6_[3]) {
+        lease->type_ = Lease6::LEASE_IA_NA;
+        lease->prefixlen_ = 28;
+        lease->iaid_ = 0xfffffffe;
+        vector<uint8_t> duid;
+        for (uint8_t i = 31; i < 126; ++i) {
+            duid.push_back(i);
+        }
+        lease->duid_ = DuidPtr(new DUID(duid));
+
+        // The times used in the next tests are deliberately restricted - we
+        // should be able to cope with valid lifetimes up to 0xffffffff.
+        //  However, this will lead to overflows.
+        // @TODO: test overflow conditions when code has been fixed
+        lease->preferred_lft_ = 7200;
+        lease->valid_lft_ = 7000;
+        lease->cltt_ = 234567;
+        lease->subnet_id_ = 37;
+
+    } else if (address == straddress6_[4]) {
+        // Same DUID and IAID as straddress6_1
+        lease->type_ = Lease6::LEASE_IA_PD;
+        lease->prefixlen_ = 15;
+        lease->iaid_ = 42;
+        lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
+        lease->preferred_lft_ = 4800;
+        lease->valid_lft_ = 7736;
+        lease->cltt_ = 222456;
+        lease->subnet_id_ = 671;
+
+    } else if (address == straddress6_[5]) {
+        // Same DUID and IAID as straddress6_1
+        lease->type_ = Lease6::LEASE_IA_PD;
+        lease->prefixlen_ = 24;
+        lease->iaid_ = 42;                          // Same as lease 4
+        lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
+        // Same as lease 4
+        lease->preferred_lft_ = 5400;
+        lease->valid_lft_ = 7832;
+        lease->cltt_ = 227476;
+        lease->subnet_id_ = 175;
+
+    } else if (address == straddress6_[6]) {
+        // Same DUID as straddress6_1
+        lease->type_ = Lease6::LEASE_IA_PD;
+        lease->prefixlen_ = 24;
+        lease->iaid_ = 93;
+        lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
+        // Same as lease 4
+        lease->preferred_lft_ = 5400;
+        lease->valid_lft_ = 1832;
+        lease->cltt_ = 627476;
+        lease->subnet_id_ = 112;
+
+    } else if (address == straddress6_[7]) {
+        // Same IAID as straddress6_1
+        lease->type_ = Lease6::LEASE_IA_PD;
+        lease->prefixlen_ = 24;
+        lease->iaid_ = 42;
+        lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0xe5)));
+        lease->preferred_lft_ = 5600;
+        lease->valid_lft_ = 7975;
+        lease->cltt_ = 213876;
+        lease->subnet_id_ = 19;
+
+    } else {
+        // Unknown address, return an empty pointer.
+        lease.reset();
+
+    }
+
+    return (lease);
+}
+
+template <typename T>
+void GenericLeaseMgrTest::checkLeasesDifferent(const std::vector<T>& leases) const {
+
+    // Check they were created
+    for (int i = 0; i < leases.size(); ++i) {
+        ASSERT_TRUE(leases[i]);
+    }
+
+    // Check they are different
+    for (int i = 0; i < (leases.size() - 1); ++i) {
+        for (int j = (i + 1); j < leases.size(); ++j) {
+            stringstream s;
+            s << "Comparing leases " << i << " & " << j << " for equality";
+            SCOPED_TRACE(s.str());
+            EXPECT_TRUE(*leases[i] != *leases[j]);
+        }
+    }
+}
+
+vector<Lease4Ptr>
+GenericLeaseMgrTest::createLeases4() {
+
+    // Create leases for each address
+    vector<Lease4Ptr> leases;
+    for (int i = 0; i < straddress4_.size(); ++i) {
+        leases.push_back(initializeLease4(straddress4_[i]));
+    }
+    EXPECT_EQ(8, leases.size());
+
+    // Check all were created and that they are different.
+    checkLeasesDifferent(leases);
+
+    return (leases);
+}
+
+vector<Lease6Ptr> GenericLeaseMgrTest::createLeases6() {
+
+    // Create leases for each address
+    vector<Lease6Ptr> leases;
+    for (int i = 0; i < straddress6_.size(); ++i) {
+        leases.push_back(initializeLease6(straddress6_[i]));
+    }
+    EXPECT_EQ(8, leases.size());
+
+    // Check all were created and that they are different.
+    checkLeasesDifferent(leases);
+
+    return (leases);
+}
+
 };
 };
 };

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

@@ -16,6 +16,8 @@
 #define LIBDHCPSRV_TEST_UTILS_H
 
 #include <dhcpsrv/lease_mgr.h>
+#include <gtest/gtest.h>
+#include <vector>
 
 namespace isc {
 namespace dhcp {
@@ -41,6 +43,72 @@ detailCompareLease(const Lease6Ptr& first, const Lease6Ptr& second);
 void
 detailCompareLease(const Lease4Ptr& first, const Lease4Ptr& second);
 
+/// @brief Test Fixture class with utility functions for LeaseMgr backends
+///
+/// It contains utility functions, like dummy lease creation.
+/// All concrete LeaseMgr test classes should be derived from it.
+class GenericLeaseMgrTest : public ::testing::Test {
+public:
+    GenericLeaseMgrTest();
+
+    /// @brief Initialize Lease4 Fields
+    ///
+    /// Returns a pointer to a Lease4 structure.  Different values are put into
+    /// the lease according to the address passed.
+    ///
+    /// This is just a convenience function for the test methods.
+    ///
+    /// @param address Address to use for the initialization
+    ///
+    /// @return Lease4Ptr.  This will not point to anything if the
+    ///         initialization failed (e.g. unknown address).
+    Lease4Ptr initializeLease4(std::string address);
+
+    /// @brief Initialize Lease6 Fields
+    ///
+    /// Returns a pointer to a Lease6 structure.  Different values are put into
+    /// the lease according to the address passed.
+    ///
+    /// This is just a convenience function for the test methods.
+    ///
+    /// @param address Address to use for the initialization
+    ///
+    /// @return Lease6Ptr.  This will not point to anything if the initialization
+    ///         failed (e.g. unknown address).
+    Lease6Ptr initializeLease6(std::string address);
+
+    /// @brief Check Leases present and different
+    ///
+    /// Checks a vector of lease pointers and ensures that all the leases
+    /// they point to are present and different.  If not, a GTest assertion
+    /// will fail.
+    ///
+    /// @param leases Vector of pointers to leases
+    template <typename T>
+        void checkLeasesDifferent(const std::vector<T>& leases) const;
+
+    /// @brief Creates leases for the test
+    ///
+    /// Creates all leases for the test and checks that they are different.
+    ///
+    /// @return vector<Lease4Ptr> Vector of pointers to leases
+    std::vector<Lease4Ptr> createLeases4();
+
+    /// @brief Creates leases for the test
+    ///
+    /// Creates all leases for the test and checks that they are different.
+    ///
+    /// @return vector<Lease6Ptr> Vector of pointers to leases
+    std::vector<Lease6Ptr> createLeases6();
+
+    // Member variables
+    std::vector<std::string>  straddress4_;   ///< String 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<isc::asiolink::IOAddress> ioaddress6_;  ///< IOAddress forms of IPv6 addresses
+
+    LeaseMgr*   lmptr_;             ///< Pointer to the lease manager
+};
 
 };
 };