Browse Source

[2342] Added MySQL lease manager and null implementation

Also includes first unit test, which fails.
Stephen Morris 12 years ago
parent
commit
6b45e5c026

+ 12 - 11
src/lib/dhcp/Makefile.am

@@ -15,22 +15,23 @@ CLEANFILES = *.gcno *.gcda
 
 lib_LTLIBRARIES = libb10-dhcp++.la libb10-dhcpsrv.la
 libb10_dhcp___la_SOURCES  =
-libb10_dhcp___la_SOURCES += libdhcp++.cc libdhcp++.h
-libb10_dhcp___la_SOURCES += lease_mgr.cc lease_mgr.h
-libb10_dhcp___la_SOURCES += lease_mgr_factory.cc lease_mgr_factory.h
+libb10_dhcp___la_SOURCES += dhcp6.h dhcp4.h
+libb10_dhcp___la_SOURCES += duid.cc duid.h
+libb10_dhcp___la_SOURCES += iface_mgr_bsd.cc
 libb10_dhcp___la_SOURCES += iface_mgr.cc iface_mgr.h
 libb10_dhcp___la_SOURCES += iface_mgr_linux.cc
-libb10_dhcp___la_SOURCES += iface_mgr_bsd.cc
 libb10_dhcp___la_SOURCES += iface_mgr_sun.cc
-libb10_dhcp___la_SOURCES += option.cc option.h
-libb10_dhcp___la_SOURCES += option6_ia.cc option6_ia.h
-libb10_dhcp___la_SOURCES += option6_iaaddr.cc option6_iaaddr.h
-libb10_dhcp___la_SOURCES += option6_addrlst.cc option6_addrlst.h
+libb10_dhcp___la_SOURCES += lease_mgr.cc lease_mgr.h
+libb10_dhcp___la_SOURCES += lease_mgr_factory.cc lease_mgr_factory.h
+libb10_dhcp___la_SOURCES += libdhcp++.cc libdhcp++.h
+libb10_dhcp___la_SOURCES += mysql_lease_mgr.cc mysql_lease_mgr.h
 libb10_dhcp___la_SOURCES += option4_addrlst.cc option4_addrlst.h
-libb10_dhcp___la_SOURCES += dhcp6.h dhcp4.h
-libb10_dhcp___la_SOURCES += pkt6.cc pkt6.h
+libb10_dhcp___la_SOURCES += option6_addrlst.cc option6_addrlst.h
+libb10_dhcp___la_SOURCES += option6_iaaddr.cc option6_iaaddr.h
+libb10_dhcp___la_SOURCES += option6_ia.cc option6_ia.h
+libb10_dhcp___la_SOURCES += option.cc option.h
 libb10_dhcp___la_SOURCES += pkt4.cc pkt4.h
-libb10_dhcp___la_SOURCES += duid.cc duid.h
+libb10_dhcp___la_SOURCES += pkt6.cc pkt6.h
 
 libb10_dhcpsrv_la_SOURCES  = cfgmgr.cc cfgmgr.h
 libb10_dhcpsrv_la_SOURCES += pool.cc pool.h

+ 21 - 5
src/lib/dhcp/lease_mgr.h

@@ -12,14 +12,20 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-#include <string>
+#ifndef __LEASE_MGR_H
+#define __LEASE_MGR_H
+
 #include <fstream>
-#include <vector>
 #include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
 #include <asiolink/io_address.h>
 #include <boost/shared_ptr.hpp>
-#include <dhcp/option.h>
 #include <dhcp/duid.h>
+#include <dhcp/option.h>
+#include <exceptions/exceptions.h>
 
 /// @file dhcp/lease_mgr.h
 /// @brief An abstract API for lease database
@@ -55,6 +61,12 @@
 namespace isc {
 namespace dhcp {
 
+/// @brief Exception thrown on failure to open database
+class DbOpenError : public Exception {
+    DbOpenError(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
 /// @brief specifies unique subnet identifier
 /// @todo: Move this to subnet.h once ticket #2237 is merged
 typedef uint32_t SubnetID;
@@ -448,6 +460,9 @@ public:
 
     /// @brief Returns backend version.
     ///
+    /// @return Version number as a pair of unsigned integers.  "first" is the
+    ///         major version number, "second" the minor number.
+    ///
     /// @todo: We will need to implement 3 version functions eventually:
     /// A. abstract API version
     /// B. backend version
@@ -457,7 +472,7 @@ public:
     /// B>=A and B=C (it is ok to have newer backend, as it should be backward
     /// compatible)
     /// Also if B>C, some database upgrade procedure may be triggered
-    virtual std::string getVersion() const = 0;
+    virtual std::pair<uint32_t, uint32_t> getVersion() const = 0;
 
     /// @todo: Add host management here
     /// As host reservation is outside of scope for 2012, support for hosts
@@ -479,5 +494,6 @@ protected:
 typedef boost::shared_ptr<LeaseMgr> LeaseMgrPtr;
 
 }; // end of isc::dhcp namespace
-
 }; // end of isc namespace
+
+#endif // __LEASE_MGR_H

+ 3 - 2
src/lib/dhcp/lease_mgr_factory.cc

@@ -26,6 +26,7 @@
 #include <boost/algorithm/string.hpp>
 #include <exceptions/exceptions.h>
 #include <dhcp/lease_mgr_factory.h>
+#include <dhcp/mysql_lease_mgr.h>
 
 using namespace std;
 
@@ -48,7 +49,7 @@ LeaseMgrFactory::parse(const std::string& dbconfig) {
             size_t pos = token.find("=");
             if (pos != string::npos) {
                 string name = token.substr(0, pos);
-                string value = token.substr(pos + 1, -1);
+                string value = token.substr(pos + 1);
                 mapped_tokens.insert(make_pair(name, value));
             } else {
                 isc_throw(InvalidParameter, "Cannot parse " << token
@@ -74,7 +75,7 @@ LeaseMgrFactory::create(const std::string& dbconfig) {
     // Yes, check what it is.
 #ifdef HAVE_MYSQL
     if (parameters[type] == string("mysql")) {
-        return LeaseMgrPtr(new LeaseMgr(parameters));
+        return LeaseMgrPtr(new MySqlLeaseMgr(parameters));
     }
 #endif
 

+ 14 - 2
src/lib/dhcp/lease_mgr_factory.h

@@ -12,13 +12,24 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#ifndef __LEASE_MGR_FACTORY_H
+#define __LEASE_MGR_FACTORY_H
+
 #include <string>
 #include <dhcp/lease_mgr.h>
-
+#include <exceptions/exceptions.h>
 
 namespace isc {
 namespace dhcp {
 
+/// @brief Invalid Type Exception
+///
+/// Thrown when the factory doesn't recognise the type of the backend.
+class InvalidType : public Exception {
+    InvalidType(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
 /// @brief Lease Manager Factory
 ///
 /// This class comprises nothing but static methods used to create a lease
@@ -61,5 +72,6 @@ public:
 };
 
 }; // end of isc::dhcp namespace
-
 }; // end of isc namespace
+
+#endif // __LEASE_MGR_FACTORY_H

+ 122 - 0
src/lib/dhcp/mysql_lease_mgr.cc

@@ -0,0 +1,122 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+
+#include <dhcp/mysql_lease_mgr.h>
+
+namespace isc {
+namespace dhcp {
+
+MySqlLeaseMgr::MySqlLeaseMgr(const LeaseMgr::ParameterMap& parameters) 
+    : LeaseMgr(parameters), major_(0), minor_(0) {
+}
+
+MySqlLeaseMgr::~MySqlLeaseMgr() {
+}
+
+bool
+MySqlLeaseMgr::addLease(Lease4Ptr /* lease */) {
+    return (false);
+}
+
+bool
+MySqlLeaseMgr::addLease(Lease6Ptr /* lease */) {
+    return (false);
+}
+
+Lease4Ptr
+MySqlLeaseMgr::getLease4(isc::asiolink::IOAddress /* addr */,
+                         SubnetID /* subnet_id */) const {
+    return (Lease4Ptr());
+}
+
+Lease4Ptr
+MySqlLeaseMgr::getLease4(isc::asiolink::IOAddress /* addr */) const {
+    return (Lease4Ptr());
+}
+
+Lease4Collection
+MySqlLeaseMgr::getLease4(const HWAddr& /* hwaddr */) const {
+    return (Lease4Collection());
+}
+
+Lease4Ptr
+MySqlLeaseMgr::getLease4(const HWAddr& /* hwaddr */,
+                         SubnetID /* subnet_id */) const {
+    return (Lease4Ptr());
+}
+
+Lease4Collection
+MySqlLeaseMgr::getLease4(const ClientId& /* clientid */) const {
+    return (Lease4Collection());
+}
+
+Lease4Ptr
+MySqlLeaseMgr::getLease4(const ClientId& /* clientid */,
+                         SubnetID /* subnet_id */) const {
+    return (Lease4Ptr());
+}
+
+Lease6Ptr
+MySqlLeaseMgr::getLease6(isc::asiolink::IOAddress /* addr */) const {
+    return (Lease6Ptr());
+}
+
+Lease6Collection
+MySqlLeaseMgr::getLease6(const DUID& /* duid */, uint32_t /* iaid */) const {
+    return (Lease6Collection());
+}
+
+Lease6Ptr
+MySqlLeaseMgr::getLease6(const DUID& /* duid */, uint32_t /* iaid */,
+                         SubnetID /* subnet_id */) const {
+    return (Lease6Ptr());
+}
+
+void
+MySqlLeaseMgr::updateLease4(Lease4Ptr /* lease4 */) {
+}
+
+void
+MySqlLeaseMgr::updateLease6(Lease6Ptr /* lease6 */) {
+}
+
+bool
+MySqlLeaseMgr::deleteLease4(uint32_t /* addr */) {
+    return (false);
+}
+
+bool
+MySqlLeaseMgr::deleteLease6(isc::asiolink::IOAddress /* addr */) {
+    return (false);
+}
+
+std::string
+MySqlLeaseMgr::getName() const {
+    return (std::string(""));
+}
+
+std::string
+MySqlLeaseMgr::getDescription() const {
+    return (std::string(""));
+}
+
+std::pair<uint32_t, uint32_t>
+MySqlLeaseMgr::getVersion() const {
+    return (std::make_pair(major_, minor_));
+}
+
+}; // end of isc::dhcp namespace
+}; // end of isc namespace

+ 234 - 0
src/lib/dhcp/mysql_lease_mgr.h

@@ -0,0 +1,234 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __MYSQL_LEASE_MGR_H
+#define __MYSQL_LEASE_MGR_H
+
+#include <dhcp/lease_mgr.h>
+
+namespace isc {
+namespace dhcp {
+
+/// @brief Abstract Lease Manager
+///
+/// This is a concrete API for the backend for the MySQL database.
+class MySqlLeaseMgr : public LeaseMgr {
+public:
+    /// @brief Constructor
+    ///
+    /// Uses the following keywords in the parameters passed to it to
+    /// connect to the database:
+    /// - name - Name of the database to which to connect
+    /// - host - Host name to which to connect
+    /// - user - Username under which to connect.
+    /// - password - Password for "user" on the database.
+    ///
+    /// If the database is successfully opened, the version number in the
+    /// schema_version table will be checked against hard-coded value in
+    /// the implementation file.
+    ///
+    /// Finally, all the SQL commands are pre-compiled.
+    ///
+    /// @param parameters A data structure relating keywords and values
+    ///        concerned with the database.
+    MySqlLeaseMgr(const ParameterMap& parameters);
+
+    /// @brief Destructor (closes database)
+    virtual ~MySqlLeaseMgr();
+
+    /// @brief Adds an IPv4 lease.
+    ///
+    /// @param lease lease to be added
+    virtual bool addLease(Lease4Ptr lease) = 0;
+
+    /// @brief Adds an IPv6 lease.
+    ///
+    /// @param lease lease to be added
+    virtual bool addLease(Lease6Ptr lease) = 0;
+
+    /// @brief Returns existing IPv4 lease for specified IPv4 address and subnet_id
+    ///
+    /// This method is used to get a lease for specific subnet_id. There can be
+    /// at most one lease for any given subnet, so this method returns a single
+    /// pointer.
+    ///
+    /// @param addr address of the searched lease
+    /// @param subnet_id ID of the subnet the lease must belong to
+    ///
+    /// @return smart pointer to the lease (or NULL if a lease is not found)
+    virtual Lease4Ptr getLease4(isc::asiolink::IOAddress addr,
+                                SubnetID subnet_id) const = 0;
+
+    /// @brief Returns an IPv4 lease for specified IPv4 address
+    ///
+    /// This method return a lease that is associated with a given address.
+    /// For other query types (by hardware addr, by client-id) there can be
+    /// several leases in different subnets (e.g. for mobile clients that
+    /// got address in different subnets). However, for a single address
+    /// there can be only one lease, so this method returns a pointer to
+    /// a single lease, not a container of leases.
+    ///
+    /// @param addr address of the searched lease
+    /// @param subnet_id ID of the subnet the lease must belong to
+    ///
+    /// @return smart pointer to the lease (or NULL if a lease is not found)
+    virtual Lease4Ptr getLease4(isc::asiolink::IOAddress addr) const = 0;
+
+    /// @brief Returns existing IPv4 leases for specified hardware address.
+    ///
+    /// Although in the usual case there will be only one lease, for mobile
+    /// clients or clients with multiple static/fixed/reserved leases there
+    /// can be more than one. Thus return type is a container, not a single
+    /// pointer.
+    ///
+    /// @param hwaddr hardware address of the client
+    ///
+    /// @return lease collection
+    virtual Lease4Collection getLease4(const HWAddr& hwaddr) const = 0;
+
+    /// @brief Returns existing IPv4 leases for specified hardware address
+    ///        and a subnet
+    ///
+    /// There can be at most one lease for a given HW address in a single
+    /// pool, so this method with either return a single lease or NULL.
+    ///
+    /// @param hwaddr hardware address of the client
+    /// @param subnet_id identifier of the subnet that lease must belong to
+    ///
+    /// @return a pointer to the lease (or NULL if a lease is not found)
+    virtual Lease4Ptr getLease4(const HWAddr& hwaddr,
+                                SubnetID subnet_id) const = 0;
+
+    /// @brief Returns existing IPv4 lease for specified client-id
+    ///
+    /// Although in the usual case there will be only one lease, for mobile
+    /// clients or clients with multiple static/fixed/reserved leases there
+    /// can be more than one. Thus return type is a container, not a single
+    /// pointer.
+    ///
+    /// @param clientid client identifier
+    ///
+    /// @return lease collection
+    virtual Lease4Collection getLease4(const ClientId& clientid) const = 0;
+
+    /// @brief Returns existing IPv4 lease for specified client-id
+    ///
+    /// There can be at most one lease for a given HW address in a single
+    /// pool, so this method with either return a single lease or NULL.
+    ///
+    /// @param clientid client identifier
+    /// @param subnet_id identifier of the subnet that lease must belong to
+    ///
+    /// @return a pointer to the lease (or NULL if a lease is not found)
+    virtual Lease4Ptr getLease4(const ClientId& clientid,
+                                SubnetID subnet_id) const = 0;
+
+    /// @brief Returns existing IPv6 lease for a given IPv6 address.
+    ///
+    /// For a given address, we assume that there will be only one lease.
+    /// The assumtion here is that there will not be site or link-local
+    /// addresses used, so there is no way of having address duplication.
+    ///
+    /// @param addr address of the searched lease
+    ///
+    /// @return smart pointer to the lease (or NULL if a lease is not found)
+    virtual Lease6Ptr getLease6(isc::asiolink::IOAddress addr) const = 0;
+
+    /// @brief Returns existing IPv6 leases for a given DUID+IA combination
+    ///
+    /// Although in the usual case there will be only one lease, for mobile
+    /// clients or clients with multiple static/fixed/reserved leases there
+    /// can be more than one. Thus return type is a container, not a single
+    /// pointer.
+    ///
+    /// @param duid client DUID
+    /// @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;
+
+    /// @brief Returns existing IPv6 lease for a given DUID+IA combination
+    ///
+    /// @param duid client DUID
+    /// @param iaid IA identifier
+    /// @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;
+
+    /// @brief Updates IPv4 lease.
+    ///
+    /// @param lease4 The lease to be updated.
+    ///
+    /// If no such lease is present, an exception will be thrown.
+    virtual void updateLease4(Lease4Ptr lease4) = 0;
+
+    /// @brief Updates IPv4 lease.
+    ///
+    /// @param lease4 The lease to be updated.
+    ///
+    /// If no such lease is present, an exception will be thrown.
+    virtual void updateLease6(Lease6Ptr lease6) = 0;
+
+    /// @brief Deletes a lease.
+    ///
+    /// @param addr IPv4 address of the lease to be deleted.
+    ///
+    /// @return true if deletion was successful, false if no such lease exists
+    virtual bool deleteLease4(uint32_t addr) = 0;
+
+    /// @brief Deletes a lease.
+    ///
+    /// @param addr IPv4 address of the lease to be deleted.
+    ///
+    /// @return true if deletion was successful, false if no such lease exists
+    virtual bool deleteLease6(isc::asiolink::IOAddress addr) = 0;
+
+    /// @brief Returns backend name.
+    ///
+    /// Each backend have specific name, e.g. "mysql" or "sqlite".
+    virtual std::string getName() const = 0;
+
+    /// @brief Returns description of the backend.
+    ///
+    /// This description may be multiline text that describes the backend.
+    virtual std::string getDescription() const = 0;
+
+    /// @brief Returns backend version.
+    ///
+    /// @return Version number as a pair of unsigned integers.  "first" is the
+    ///         major version number, "second" the minor number.
+    ///
+    /// @todo: We will need to implement 3 version functions eventually:
+    /// A. abstract API version
+    /// B. backend version
+    /// C. database version (stored in the database scheme)
+    ///
+    /// and then check that:
+    /// B>=A and B=C (it is ok to have newer backend, as it should be backward
+    /// compatible)
+    /// Also if B>C, some database upgrade procedure may be triggered
+    virtual std::pair<uint32_t, uint32_t> getVersion() const;
+
+private:
+    uint32_t    major_;     ///< Major version number
+    uint32_t    minor_;     ///< Minor version number
+};
+
+}; // end of isc::dhcp namespace
+}; // end of isc namespace
+
+#endif // __MYSQL_LEASE_MGR_H

+ 11 - 8
src/lib/dhcp/tests/Makefile.am

@@ -26,27 +26,30 @@ TESTS =
 if HAVE_GTEST
 TESTS += libdhcp++_unittests libdhcpsrv_unittests
 libdhcp___unittests_SOURCES  = run_unittests.cc
-libdhcp___unittests_SOURCES += libdhcp++_unittest.cc
+libdhcp___unittests_SOURCES += duid_unittest.cc
 libdhcp___unittests_SOURCES += iface_mgr_unittest.cc
-libdhcp___unittests_SOURCES += lease_mgr_unittest.cc
 libdhcp___unittests_SOURCES += lease_mgr_factory_unittest.cc
+libdhcp___unittests_SOURCES += lease_mgr_unittest.cc
+libdhcp___unittests_SOURCES += mysql_lease_mgr_unittest.cc
+libdhcp___unittests_SOURCES += libdhcp++_unittest.cc
+libdhcp___unittests_SOURCES += option4_addrlst_unittest.cc
+libdhcp___unittests_SOURCES += option6_addrlst_unittest.cc
 libdhcp___unittests_SOURCES += option6_iaaddr_unittest.cc
 libdhcp___unittests_SOURCES += option6_ia_unittest.cc
-libdhcp___unittests_SOURCES += option6_addrlst_unittest.cc
-libdhcp___unittests_SOURCES += option4_addrlst_unittest.cc
 libdhcp___unittests_SOURCES += option_unittest.cc
-libdhcp___unittests_SOURCES += pkt6_unittest.cc
 libdhcp___unittests_SOURCES += pkt4_unittest.cc
-libdhcp___unittests_SOURCES += duid_unittest.cc
+libdhcp___unittests_SOURCES += pkt6_unittest.cc
 
 libdhcp___unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
 libdhcp___unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
 libdhcp___unittests_CXXFLAGS = $(AM_CXXFLAGS)
 
 libdhcpsrv_unittests_SOURCES  = run_unittests.cc
-libdhcpsrv_unittests_SOURCES += cfgmgr_unittest.cc triplet_unittest.cc
-libdhcpsrv_unittests_SOURCES += pool_unittest.cc subnet_unittest.cc
 libdhcpsrv_unittests_SOURCES += addr_utilities_unittest.cc
+libdhcpsrv_unittests_SOURCES += cfgmgr_unittest.cc
+libdhcpsrv_unittests_SOURCES += pool_unittest.cc
+libdhcpsrv_unittests_SOURCES += subnet_unittest.cc
+libdhcpsrv_unittests_SOURCES += triplet_unittest.cc
 
 libdhcpsrv_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
 libdhcpsrv_unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)

+ 3 - 1
src/lib/dhcp/tests/lease_mgr_unittest.cc

@@ -176,7 +176,9 @@ public:
     std::string getDescription() const;
 
     /// @brief Returns backend version.
-    std::string getVersion() const { return "test-version"; }
+    std::pair<uint32_t, uint32_t> getVersion() const {
+        return (make_pair(uint32_t(0), uint32_t(0)));
+    }
 
     using LeaseMgr::getParameter;
 

+ 100 - 0
src/lib/dhcp/tests/mysql_lease_mgr_unittest.cc

@@ -0,0 +1,100 @@
+// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <iostream>
+#include <sstream>
+#include <utility>
+#include <gtest/gtest.h>
+
+#include <asiolink/io_address.h>
+#include <dhcp/lease_mgr_factory.h>
+#include <dhcp/mysql_lease_mgr.h>
+
+using namespace isc;
+using namespace isc::asiolink;
+using namespace isc::dhcp;
+using namespace std;
+
+namespace {
+// empty class for now, but may be extended later.
+class MySqlLeaseMgrTest : public ::testing::Test {
+public:
+    MySqlLeaseMgrTest() {
+    }
+};
+
+// Connection strings
+const char* VALID_TYPE = "type=mysql";
+const char* INVALID_TYPE = "type=unknown";
+const char* VALID_NAME = "name=keattest";
+const char* INVALID_NAME = "name=invalidname";
+const char* VALID_HOST = "host=localhost";
+const char* INVALID_HOST = "host=invalidhost";
+const char* VALID_USER = "user=keatest";
+const char* INVALID_USER = "user=invaliduser";
+const char* VALID_PASSWORD = "password=keatest";
+const char* INVALID_PASSWORD = "password=invalid";
+
+// Given a combination of strings above, produce a connection string.
+string connectionString(const char* type, const char* name, const char* host,
+                        const char* user, const char* password) {
+    const string space = " ";
+    return (string(type) + space + string(name) + space + string(host) + space +
+            string(user) + space + string(password));
+}
+
+// Return valid connection string
+string validConnectionString() {
+    return (connectionString(VALID_TYPE, VALID_NAME, VALID_HOST,
+                             VALID_USER, VALID_PASSWORD));
+}
+
+
+// This test checks if the MySqlLeaseMgr can be instantiated.  This happens
+// only if:
+// a) The database can be opened
+// b) It finds the schema_version table
+// c) The schema version matches that in the Lease Manager code
+TEST_F(MySqlLeaseMgrTest, OpenDatabase) {
+    LeaseMgrPtr lmptr;
+
+    // Check that failure to open the database generates an exception
+    EXPECT_THROW(lmptr = LeaseMgrFactory::create(connectionString(
+        INVALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)),
+        InvalidType);
+    EXPECT_THROW(lmptr = LeaseMgrFactory::create(connectionString(
+        VALID_TYPE, INVALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)),
+        DbOpenError);
+    EXPECT_THROW(lmptr = LeaseMgrFactory::create(connectionString(
+        VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)),
+        DbOpenError);
+    EXPECT_THROW(lmptr = LeaseMgrFactory::create(connectionString(
+        VALID_TYPE, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
+        DbOpenError);
+    EXPECT_THROW(lmptr = LeaseMgrFactory::create(connectionString(
+        VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_PASSWORD)),
+        DbOpenError);
+
+    // Check that database opens correctly and that version is as expected
+    ASSERT_NO_THROW(lmptr = LeaseMgrFactory::create(connectionString(
+        VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)));
+    ASSERT_TRUE(lmptr);
+
+    pair<uint32_t, uint32_t> version = lmptr->getVersion();
+    EXPECT_EQ(0, version.first);
+    EXPECT_EQ(1, version.second);
+}
+
+}; // end of anonymous namespace