Parcourir la source

[2404] Tidying up and refactoring the code

Stephen Morris il y a 12 ans
Parent
commit
5b1850bbc2

+ 7 - 7
src/lib/dhcpsrv/lease_mgr.cc

@@ -31,13 +31,13 @@ using namespace std;
 
 using namespace isc::dhcp;
 
-Lease6::Lease6(LeaseType type, const isc::asiolink::IOAddress& addr, DuidPtr duid,
-               uint32_t iaid, uint32_t preferred, uint32_t valid, uint32_t t1,
-               uint32_t t2, SubnetID subnet_id, uint8_t prefixlen)
-    :type_(type), addr_(addr), prefixlen_(prefixlen), iaid_(iaid), duid_(duid),
-     preferred_lft_(preferred), valid_lft_(valid), t1_(t1), t2_(t2),
-     subnet_id_(subnet_id), fixed_(false), fqdn_fwd_(false),
-     fqdn_rev_(false) {
+Lease6::Lease6(LeaseType type, const isc::asiolink::IOAddress& addr,
+               DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid,
+               uint32_t t1, uint32_t t2, SubnetID subnet_id, uint8_t prefixlen)
+    : addr_(addr), type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid),
+      preferred_lft_(preferred), valid_lft_(valid), t1_(t1), t2_(t2),
+      subnet_id_(subnet_id), fixed_(false), fqdn_fwd_(false),
+      fqdn_rev_(false) {
     if (!duid) {
         isc_throw(InvalidOperation, "DUID must be specified for a lease");
     }

+ 97 - 67
src/lib/dhcpsrv/lease_mgr.h

@@ -87,6 +87,13 @@ public:
         isc::Exception(file, line, what) {}
 };
 
+/// @brief Multiple lease records found where one expected
+class MultipleRecords : public Exception {
+public:
+    MultipleRecords(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
 /// @brief Attempt to update lease that was not there
 class NoSuchLease : public Exception {
 public:
@@ -101,6 +108,7 @@ public:
 /// would be required. As this is a critical part of the code that will be used
 /// extensively, direct access is warranted.
 struct Lease4 {
+
     /// @brief Constructor
     ///
     /// @param addr IPv4 address as unsigned 32-bit integer in network byte
@@ -133,69 +141,78 @@ struct Lease4 {
 
     /// @brief Address extension
     ///
-    /// It is envisaged that in some cases IPv4 address will be accompanied with some
-    /// additional data. One example of such use are Address + Port solutions (or
-    /// Port-restricted Addresses), where several clients may get the same address, but
-    /// different port ranges. This feature is not expected to be widely used.
-    /// Under normal circumstances, the value should be 0.
+    /// It is envisaged that in some cases IPv4 address will be accompanied
+    /// with some additional data. One example of such use are Address + Port
+    /// solutions (or Port-restricted Addresses), where several clients may get
+    /// the same address, but different port ranges. This feature is not
+    /// expected to be widely used.  Under normal circumstances, the value
+    /// should be 0.
     uint32_t ext_;
 
-    /// @brief hardware address
+    /// @brief Hardware address
     std::vector<uint8_t> hwaddr_;
 
-    /// @brief client identifier
+    /// @brief Client identifier
+    ///
+    /// @todo Should this be a pointer to a client ID or the ID itself?
+    ///       Compare with the DUID in the Lease6 structure.
     boost::shared_ptr<ClientId> client_id_;
 
-    /// @brief renewal timer
+    /// @brief Renewal timer
     ///
-    /// Specifies renewal time. Although technically it is a property of IA container,
-    /// not the address itself, since our data model does not define separate IA
-    /// entity, we are keeping it in the lease. In case of multiple addresses/prefixes
-    /// for the same IA, each must have consistent T1 and T2 values. Specified in
-    /// seconds since cltt.
+    /// Specifies renewal time. Although technically it is a property of the
+    /// IA container and not the address itself, since our data model does not
+    /// define a separate IA entity, we are keeping it in the lease. In the
+    /// case of multiple addresses/prefixes for the same IA, each must have
+    /// consistent T1 and T2 values. This is specified in seconds since cltt.
     uint32_t t1_;
 
-    /// @brief rebinding timer
+    /// @brief Rebinding timer
     ///
-    /// Specifies rebinding time. Although technically it is a property of IA container,
-    /// not the address itself, since our data model does not define separate IA
-    /// entity, we are keeping it in the lease. In case of multiple addresses/prefixes
-    /// for the same IA, each must have consistent T1 and T2 values. Specified in
-    /// seconds since cltt.
+    /// Specifies rebinding time. Although technically it is a property of the
+    /// IA container and not the address itself, since our data model does not
+    /// define a separate IA entity, we are keeping it in the lease. In the
+    /// case of multiple addresses/prefixes for the same IA, each must have
+    /// consistent T1 and T2 values. This is pecified in seconds since cltt.
     uint32_t t2_;
 
-    /// @brief valid lifetime
+    /// @brief Ralid lifetime
     ///
-    /// Expressed as number of seconds since cltt
+    /// Expressed as number of seconds since cltt.
     uint32_t valid_lft_;
 
-    /// @brief client last transmission time
+    /// @brief Client last transmission time
     ///
-    /// Specifies a timestamp, when last transmission from a client was received.
+    /// Specifies a timestamp giving the time when the last transmission from a
+    /// client was received.
     time_t cltt_;
 
     /// @brief Subnet identifier
     ///
-    /// Specifies subnet-id of the subnet that the lease belongs to
+    /// Specifies the identification of the subnet to which the lease belongs.
     SubnetID subnet_id_;
 
-    /// @brief Is this a fixed lease?
+    /// @brief Fixed lease?
     ///
     /// Fixed leases are kept after they are released/expired.
     bool fixed_;
 
-    /// @brief client hostname
+    /// @brief Client hostname
     ///
     /// This field may be empty
     std::string hostname_;
 
-    /// @brief did we update AAAA record for this lease?
+    /// @brief Forward zone updated?
+    ///
+    /// Set true if the DNS AAAA record for this lease has been updated.
     bool fqdn_fwd_;
 
-    /// @brief did we update PTR record for this lease?
+    /// @brief Reverse zone updated?
+    ///
+    /// Set true if the DNS PTR record for this lease has been updated.
     bool fqdn_rev_;
 
-    /// @brief Lease comments.
+    /// @brief Lease comments
     ///
     /// Currently not used. It may be used for keeping comments made by the
     /// system administrator.
@@ -210,13 +227,16 @@ typedef boost::shared_ptr<Lease4> Lease4Ptr;
 /// @brief A collection of IPv4 leases.
 typedef std::vector<Lease4Ptr> Lease4Collection;
 
+
+
 /// @brief Structure that holds a lease for IPv6 address and/or prefix
 ///
-/// For performance reasons it is a simple structure, not a class. Had we chose to
-/// make it a class, all fields would have to be made private and getters/setters
+/// For performance reasons it is a simple structure, not a class. If we chose
+/// make it a class, all fields would have to made private and getters/setters
 /// would be required. As this is a critical part of the code that will be used
-/// extensively, direct access rather than through getters/setters is warranted.
 struct Lease6 {
+
+    /// @brief Type of lease contents
     typedef enum {
         LEASE_IA_NA, /// the lease contains non-temporary IPv6 address
         LEASE_IA_TA, /// the lease contains temporary IPv6 address
@@ -228,86 +248,96 @@ struct Lease6 {
            uint32_t iaid, uint32_t preferred, uint32_t valid, uint32_t t1,
            uint32_t t2, SubnetID subnet_id, uint8_t prefixlen_ = 0);
 
-    /// @brief specifies lease type (normal addr, temporary addr, prefix)
-    LeaseType type_;
-
-    /// IPv6 address
+    /// @brief IPv6 address
     isc::asiolink::IOAddress addr_;
 
-    /// IPv6 prefix length (used only for PD)
+    /// @brief Lease type
+    ///
+    /// One of normal address, temporary address, or prefix.
+    LeaseType type_;
+
+    /// @brief IPv6 prefix length
+    ///
+    /// This is used only for prefix delegations and is ignored otherwise.
     uint8_t prefixlen_;
 
-    /// @brief IAID
+    /// @brief Identity Association Identifier (IAID)
     ///
-    /// Identity Association IDentifier. DHCPv6 stores all addresses and prefixes
-    /// in IA containers (IA_NA, IA_TA, IA_PD). Most containers may appear more
-    /// than once in a message. To differentiate between them, IAID field is present
+    /// DHCPv6 stores all addresses and prefixes in IA containers (IA_NA,
+    /// IA_TA, IA_PD). Most containers may appear more than once in a message.
+    /// To differentiate between them, the IAID field is present
     uint32_t iaid_;
 
-    /// @brief client identifier
+    /// @brief Client identifier
     boost::shared_ptr<DUID> duid_;
 
     /// @brief preferred lifetime
     ///
-    /// This parameter specifies preferred lifetime since the lease was assigned/renewed
-    /// (cltt), expressed in seconds.
+    /// This parameter specifies the preferred lifetime since the lease was
+    /// assigned or renewed (cltt), expressed in seconds.
     uint32_t preferred_lft_;
 
     /// @brief valid lifetime
     ///
-    /// This parameter specified valid lifetime since the lease was assigned/renewed
-    /// (cltt), expressed in seconds.
+    /// This parameter specifies the valid lifetime since the lease waa
+    /// assigned/renewed (cltt), expressed in seconds.
     uint32_t valid_lft_;
 
     /// @brief T1 timer
     ///
-    /// Specifies renewal time. Although technically it is a property of IA container,
-    /// not the address itself, since our data model does not define separate IA
-    /// entity, we are keeping it in the lease. In case of multiple addresses/prefixes
-    /// for the same IA, each must have consistent T1 and T2 values. Specified in
-    /// seconds since cltt.
-    /// This value will also be useful for failover to calculate the next expected
-    /// client transmission time.
+    /// Specifies renewal time. Although technically it is a property of the
+    /// IA container and not the address itself, since our data model does not
+    /// define a separate IA entity, we are keeping it in the lease. In the
+    /// case of multiple addresses/prefixes for the same IA, each must have
+    /// consistent T1 and T2 values. This is specified in seconds since cltt.
+    /// The value will also be useful for failover to calculate the next
+    /// expected client transmission time.
     uint32_t t1_;
 
     /// @brief T2 timer
     ///
-    /// Specifies rebinding time. Although technically it is a property of IA container,
-    /// not the address itself, since our data model does not define separate IA
-    /// entity, we are keeping it in the lease. In case of multiple addresses/prefixes
-    /// for the same IA, each must have consistent T1 and T2 values. Specified in
-    /// seconds since cltt.
+    /// Specifies rebinding time. Although technically it is a property of the
+    /// IA container and not the address itself, since our data model does not
+    /// define a separate IA entity, we are keeping it in the lease. In the
+    /// case of multiple addresses/prefixes for the same IA, each must have
+    /// consistent T1 and T2 values. This is specified in seconds since cltt.
     uint32_t t2_;
 
-    /// @brief client last transmission time
+    /// @brief Client last transmission time
     ///
-    /// Specifies a timestamp, when last transmission from a client was received.
+    /// Specifies a timestamp giving the time when the last transmission from a
+    /// client was received.
     time_t cltt_;
 
     /// @brief Subnet identifier
     ///
-    /// Specifies subnet-id of the subnet that the lease belongs to
+    /// Specifies the identification of the subnet to which the lease belongs.
     SubnetID subnet_id_;
 
-    /// @brief Is this a fixed lease?
+    /// @brief Fixed lease?
     ///
     /// Fixed leases are kept after they are released/expired.
     bool fixed_;
 
-    /// @brief client hostname
+    /// @brief Client hostname
     ///
     /// This field may be empty
     std::string hostname_;
 
-    /// @brief did we update AAAA record for this lease?
+    /// @brief Forward zone updated?
+    ///
+    /// Set true if the DNS AAAA record for this lease has been updated.
     bool fqdn_fwd_;
 
-    /// @brief did we update PTR record for this lease?
+    /// @brief Reverse zone updated?
+    ///
+    /// Set true if the DNS PTR record for this lease has been updated.
     bool fqdn_rev_;
 
     /// @brief Lease comments
     ///
-    /// This field is currently not used.
+    /// Currently not used. It may be used for keeping comments made by the
+    /// system administrator.
     std::string comments_;
 
     /// @todo: Add DHCPv6 failover related fields here
@@ -357,7 +387,7 @@ typedef std::vector<Lease6Ptr> Lease6Collection;
 /// see the documentation of those classes for details.
 class LeaseMgr {
 public:
-    /// Client Hardware address
+    /// Client hardware address
     typedef std::vector<uint8_t> HWAddr;
 
     /// Database configuration parameter map

Fichier diff supprimé car celui-ci est trop grand
+ 266 - 257
src/lib/dhcpsrv/mysql_lease_mgr.cc


+ 147 - 35
src/lib/dhcpsrv/mysql_lease_mgr.h

@@ -28,7 +28,7 @@ namespace dhcp {
 // Define the current database schema values
 
 const uint32_t CURRENT_VERSION_VERSION = 0;
-const uint32_t CURRENT_VERSION_MINOR = 1;
+const uint32_t CURRENT_VERSION_MINOR = 2;
 
 
 // Forward declaration of the Lease exchange objects.  This class is defined
@@ -69,7 +69,7 @@ public:
     /// @brief Destructor (closes database)
     virtual ~MySqlLeaseMgr();
 
-    /// @brief Adds an IPv4 lease.
+    /// @brief Adds an IPv4 lease
     ///
     /// @param lease lease to be added
     ///
@@ -80,7 +80,7 @@ public:
     ///        failed.
     virtual bool addLease(const Lease4Ptr& lease);
 
-    /// @brief Adds an IPv6 lease.
+    /// @brief Adds an IPv6 lease
     ///
     /// @param lease lease to be added
     ///
@@ -210,13 +210,22 @@ public:
 
     /// @brief Updates IPv4 lease.
     ///
+    /// Updates the record of the lease in the database (as identified by the
+    /// address) with the data in the passed lease object.
+    ///
     /// @param lease4 The lease to be updated.
     ///
-    /// If no such lease is present, an exception will be thrown.
+    /// @throw isc::dhcp::NoSuchLease Attempt to update a lease that did not
+    ///        exist.
+    /// @throw isc::dhcp::DbOperationError An operation on the open database has
+    ///        failed.
     virtual void updateLease4(const Lease4Ptr& lease4);
 
     /// @brief Updates IPv6 lease.
     ///
+    /// Updates the record of the lease in the database (as identified by the
+    /// address) with the data in the passed lease object.
+    ///
     /// @param lease6 The lease to be updated.
     ///
     /// @throw isc::dhcp::NoSuchLease Attempt to update a lease that did not
@@ -234,6 +243,9 @@ public:
     /// @param addr IPv4 address of the lease to be deleted.
     ///
     /// @return true if deletion was successful, false if no such lease exists
+    ///
+    /// @throw isc::dhcp::DbOperationError An operation on the open database has
+    ///        failed.
     virtual bool deleteLease4(const isc::asiolink::IOAddress& addr);
 
     /// @brief Deletes an IPv6 lease.
@@ -409,7 +421,8 @@ private:
     /// @brief Add Lease Common Code
     ///
     /// This method performs the common actions for both flavours of the
-    /// addLease method.
+    /// addLease method.  It binds the contents of the lease object to
+    /// the prepated statement and adds it to the database.
     ///
     /// @param stindex Index of statemnent being executed
     /// @param bind MYSQL_BIND array that has been created for the type
@@ -422,18 +435,28 @@ private:
     ///        failed.
     bool addLease(StatementIndex stindex, std::vector<MYSQL_BIND>& bind);
 
-    /// @brief Get Lease Common Code
+    /// @brief Binds Parameters and Executes
     ///
-    /// This method performs the common actions for obtaining a single lease
-    /// from the database.
+    /// This method abstracts a lot of common processing from the getXxxx()
+    /// methods.  It binds the parameters passed to it to the appropriate
+    /// prepared statement, and binds the variables in the exchange6 object to
+    /// the output parameters of the statement.  It then executes the prepared
+    /// statement.
     ///
-    /// @param stindex Index of statement being executed
-    /// @param inbind MYSQL_BIND array for input parameters
+    /// The data can be retrieved using mysql_stmt_fetch and the getLeaseData()
+    /// method on the appropriate exchange object.
+    ///
+    /// @param stindex Index of prepared statement to be executed
     /// @param exchange Exchange object to use
-    /// @param lease Lease object returned
-    template <typename Exchange, typename LeasePtr>
-    void getLease(StatementIndex stindex, MYSQL_BIND* inbind,
-                  Exchange& exchange, LeasePtr& result) const;
+    /// @param inbind Array of MYSQL_BIND objects representing the parameters.
+    ///        (Note that the number is determined by the number of parameters
+    ///        in the statement.)
+    ///
+    /// @throw isc::dhcp::DbOperationError An operation on the open database has
+    ///        failed.
+    template <typename Exchange>
+    void bindAndExecute(StatementIndex stindex, Exchange& exchange,
+                         MYSQL_BIND* inbind) const;
 
     /// @brief Get Lease Collection Common Code
     ///
@@ -445,32 +468,121 @@ private:
     /// @param exchange Exchange object to use
     /// @param lease LeaseCollection object returned.  Note that any data in
     ///        the collection is cleared before new data is added.
+    /// @param single If true, only a single data item is to be retrieved.
+    ///        If more than one is present, a MultipleRecords exception will
+    ///        be thrown.
+    ///
+    /// @throw isc::dhcp::BadValue Data retrieved from the database was invalid.
+    /// @throw isc::dhcp::DbOperationError An operation on the open database has
+    ///        failed.
+    /// @throw isc::dhcp::MultipleRecords Multiple records were retrieved
+    ///        from the database where only one was expected.
     template <typename Exchange, typename LeaseCollection>
     void getLeaseCollection(StatementIndex stindex, MYSQL_BIND* inbind,
-                            Exchange& exchange, LeaseCollection& result) const;
+                            Exchange& exchange, LeaseCollection& result,
+                            bool single = false) const;
 
-    /// @brief Binds Parameters and Executes
+    /// @brief Get Lease Collection
     ///
-    /// This method abstracts a lot of common processing from the getXxxx()
-    /// methods.  It binds the parameters passed to it to the appropriate
-    /// prepared statement, and binds the variables in the exchange6 object to
-    /// the output parameters of the statement.  It then executes the prepared
-    /// statement.
+    /// Gets a collection of Lease4 objects.  This is just an interface to
+    /// the get lease collection common code.
     ///
-    /// The data can be retrieved using mysql_stmt_fetch and the getLeaseData()
-    /// method on the appropriate exchange object.
+    /// @param stindex Index of statement being executed
+    /// @param inbind MYSQL_BIND array for input parameters
+    /// @param lease LeaseCollection object returned.  Note that any data in
+    ///        the collection is cleared before new data is added.
+    ///
+    /// @throw isc::dhcp::BadValue Data retrieved from the database was invalid.
+    /// @throw isc::dhcp::DbOperationError An operation on the open database has
+    ///        failed.
+    /// @throw isc::dhcp::MultipleRecords Multiple records were retrieved
+    ///        from the database where only one was expected.
+    void getLeaseCollection(StatementIndex stindex, MYSQL_BIND* inbind,
+                            Lease4Collection& result) const {
+        getLeaseCollection(stindex, inbind, exchange4_, result);
+    }
+
+    /// @brief Get Lease Collection
+    ///
+    /// Gets a collection of Lease6 objects.  This is just an interface to
+    /// the get lease collection common code.
+    ///
+    /// @param stindex Index of statement being executed
+    /// @param inbind MYSQL_BIND array for input parameters
+    /// @param lease LeaseCollection object returned.  Note that any data in
+    ///        the collection is cleared before new data is added.
+    ///
+    /// @throw isc::dhcp::BadValue Data retrieved from the database was invalid.
+    /// @throw isc::dhcp::DbOperationError An operation on the open database has
+    ///        failed.
+    /// @throw isc::dhcp::MultipleRecords Multiple records were retrieved
+    ///        from the database where only one was expected.
+    void getLeaseCollection(StatementIndex stindex, MYSQL_BIND* inbind,
+                            Lease6Collection& result) const {
+        getLeaseCollection(stindex, inbind, exchange6_, result);
+    }
+
+    /// @brief Get Lease6 Common Code
+    ///
+    /// This method performs the common actions for the various getLease4()
+    /// methods.  It acts as an interface to the getLeaseCollection() method,
+    /// but retrieveing only a single lease.
+    ///
+    /// @param stindex Index of statement being executed
+    /// @param inbind MYSQL_BIND array for input parameters
+    /// @param lease Lease4 object returned
+    void getLease(StatementIndex stindex, MYSQL_BIND* inbind,
+                  Lease4Ptr& result) const;
+
+    /// @brief Get Lease4 Common Code
+    ///
+    /// This method performs the common actions for the various getLease4()
+    /// methods.  It acts as an interface to the getLeaseCollection() method,
+    /// but retrieveing only a single lease.
+    ///
+    /// @param stindex Index of statement being executed
+    /// @param inbind MYSQL_BIND array for input parameters
+    /// @param lease Lease6 object returned
+    void getLease(StatementIndex stindex, MYSQL_BIND* inbind,
+                   Lease6Ptr& result) const;
+
+    /// @brief Update lease common code
+    ///
+    /// Holds the common code for updating a lease.  It binds the parameters
+    /// to the prepared statement, executes it, then checks how many rows
+    /// were affected.
     ///
     /// @param stindex Index of prepared statement to be executed
-    /// @param exchange Exchange object to use
-    /// @param inbind Array of MYSQL_BIND objects representing the parameters.
+    /// @param bind Array of MYSQL_BIND objects representing the parameters.
     ///        (Note that the number is determined by the number of parameters
     ///        in the statement.)
+    /// @param lease Pointer to the lease object whose record is being updated.
     ///
+    /// @throw NoSuchLease Could not update a lease because no lease matches
+    ///        the address given.
     /// @throw isc::dhcp::DbOperationError An operation on the open database has
     ///        failed.
-    template <typename Exchange>
-    void bindAndExecute(StatementIndex stindex, Exchange& exchange,
-                         MYSQL_BIND* inbind) const;
+    template <typename LeasePtr>
+    void updateLease(StatementIndex stindex, MYSQL_BIND* bind,
+                     const LeasePtr& lease);
+
+    /// @brief Delete lease common code
+    ///
+    /// Holds the common code for deleting a lease.  It binds the parameters
+    /// to the prepared statement, executes the statement and checks to
+    /// see how many rows were deleted.
+    ///
+    /// @param stindex Index of prepared statement to be executed
+    /// @param bind Array of MYSQL_BIND objects representing the parameters.
+    ///        (Note that the number is determined by the number of parameters
+    ///        in the statement.)
+    ///
+    /// @return true if one or more rows were deleted, false if none were
+    ///         deleted.
+    ///
+    /// @throw isc::dhcp::DbOperationError An operation on the open database has
+    ///        failed.
+    bool deleteLease(StatementIndex stindex, MYSQL_BIND* bind);
 
     /// @brief Check Error and Throw Exception
     ///
@@ -496,15 +608,15 @@ private:
 
     // Members
 
-    /// Used for transfer of data to/from the database. This is a pointed-to
-    /// object as its contents may change in "const" calls, while the rest
-    /// of this object does not.  (At alternative would be to declare it as
-    /// "mutable".)
-    MYSQL*              mysql_;                 ///< MySQL context object
-    std::vector<std::string> text_statements_;  ///< Raw text of statements
-    std::vector<MYSQL_STMT*> statements_;       ///< Prepared statements
+    /// The exchange objects are used for transfer of data to/from the database.
+    /// They are pointed-to objects as the contents may change in "const" calls,
+    /// while the rest of this object does not.  (At alternative would be to
+    /// declare them as "mutable".)
     boost::scoped_ptr<MySqlLease4Exchange> exchange4_; ///< Exchange object
     boost::scoped_ptr<MySqlLease6Exchange> exchange6_; ///< Exchange object
+    MYSQL*              mysql_;                 ///< MySQL context object
+    std::vector<MYSQL_STMT*> statements_;       ///< Prepared statements
+    std::vector<std::string> text_statements_;  ///< Raw text of statements
 };
 
 }; // end of isc::dhcp namespace

+ 205 - 195
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -32,10 +32,10 @@ using namespace std;
 
 namespace {
 
-// Creation of the schema
+// This holds statements to create and destroy the schema.
 #include "schema_copy.h"
 
-// IPv4 and IPv6 addresseses
+// 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",
@@ -47,8 +47,9 @@ const char* ADDRESS6[] = {
     NULL
 };
 
-// Connection strings.  Assume:
+// Connection strings.
 // Database: keatest
+// Host: localhost
 // Username: keatest
 // Password: keatest
 const char* VALID_TYPE = "type=mysql";
@@ -71,8 +72,7 @@ string connectionString(const char* type, const char* name, const char* host,
     if (type != NULL) {
         result += string(type);
     }
-
-    if (name != NULL) {
+if (name != NULL) {
         if (! result.empty()) {
             result += space;
         }
@@ -113,7 +113,7 @@ validConnectionString() {
 // @brief Clear everything from the database
 //
 // There is no error checking in this code: if something fails, one of the
-// tests will fall over.
+// tests will (should) fall over.
 void destroySchema() {
     // Initialise
     MYSQL handle;
@@ -147,7 +147,7 @@ void createSchema() {
     (void) mysql_real_connect(&handle, "localhost", "keatest",
                               "keatest", "keatest", 0, NULL, 0);
 
-    // Get rid of everything in it.
+    // Execute creation statements.
     for (int i = 0; create_statement[i] != NULL; ++i) {
         (void) mysql_query(&handle, create_statement[i]);
     }
@@ -156,20 +156,16 @@ void createSchema() {
     (void) mysql_close(&handle);
 }
 
-// Note: Doxygen "///" not used - even though Doxygen is used to
-// document class and methods - to avoid the comments appearing
-// in the programming manual.
-
-// @brief Test Fixture Class
-//
-// Opens the database prior to each test and closes it afterwards.
-// All pending transactions are deleted prior to closure.
+/// @brief Test fixture class for testing MySQL Lease Manager
+///
+/// Opens the database prior to each test and closes it afterwards.
+/// All pending transactions are deleted prior to closure.
 
 class MySqlLeaseMgrTest : public ::testing::Test {
 public:
-    // @brief Constructor
-    //
-    // Deletes everything from the database and opens it.
+    /// @brief Constructor
+    ///
+    /// Deletes everything from the database and opens it.
     MySqlLeaseMgrTest() {
         // Initialize address strings and IOAddresses
         for (int i = 0; ADDRESS4[i] != NULL; ++i) {
@@ -202,38 +198,38 @@ public:
         lmptr_ = &(LeaseMgrFactory::instance());
     }
 
-    // @brief Destructor
-    //
-    // Rolls back all pending transactions.  The deletion of the
-    // lmptr_ member variable will close the database.  Then
-    // reopen it and delete everything created by the test.
+    /// @brief Destructor
+    ///
+    /// Rolls back all pending transactions.  The deletion of the
+    /// lmptr_ member variable will close the database.  Then
+    /// reopen it and delete everything created by the test.
     virtual ~MySqlLeaseMgrTest() {
         lmptr_->rollback();
         LeaseMgrFactory::destroy();
         destroySchema();
     }
 
-    // @brief Reopen the database
-    //
-    // Closes the database and re-open it.  Anything committed should be
-    // visible.
+    /// @brief Reopen the database
+    ///
+    /// Closes the database and re-open it.  Anything committed should be
+    /// visible.
     void reopen() {
         LeaseMgrFactory::destroy();
         LeaseMgrFactory::create(validConnectionString());
         lmptr_ = &(LeaseMgrFactory::instance());
     }
 
-    // @brief Initialize Lease4 Fields
-    //
-    // Returns a pointer to a Lease4 structure.  Different values are put
-    // in 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).
+    /// @brief Initialize Lease4 Fields
+    ///
+    /// Returns a pointer to a Lease4 structure.  Different values are put
+    /// in 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());
 
@@ -332,17 +328,17 @@ public:
         return (lease);
     }
 
-    // @brief Initialize Lease6 Fields
-    //
-    // Returns a pointer to a Lease6 structure.  Different values are put
-    // in 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).
+    /// @brief Initialize Lease6 Fields
+    ///
+    /// Returns a pointer to a Lease6 structure.  Different values are put
+    /// in 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());
 
@@ -363,31 +359,34 @@ public:
             lease->type_ = Lease6::LEASE_IA_TA;
             lease->prefixlen_ = 4;
             lease->iaid_ = 142;
-            lease->duid_ = boost::shared_ptr<DUID>(new DUID(vector<uint8_t>(8, 0x77)));
-            lease->preferred_lft_ = 900;   // Preferred lifetime
-            lease->valid_lft_ = 8677;      // Actual lifetime
-            lease->cltt_ = 168256;         // Current time of day
-            lease->subnet_id_ = 23;        // Arbitrary number
+            lease->duid_ = boost::shared_ptr<DUID>(
+                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_ = boost::shared_ptr<DUID>(new DUID(vector<uint8_t>(8, 0x42)));
-            lease->preferred_lft_ = 3600;  // Preferred lifetime
-            lease->valid_lft_ = 3677;      // Actual lifetime
-            lease->cltt_ = 123456;         // Current time of day
-            lease->subnet_id_ = 73;        // Arbitrary number
+            lease->duid_ = boost::shared_ptr<DUID>(
+                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_ = boost::shared_ptr<DUID>(new DUID(vector<uint8_t>(8, 0x3a)));
-            lease->preferred_lft_ = 1800;  // Preferred lifetime
-            lease->valid_lft_ = 5412;      // Actual lifetime
-            lease->cltt_ = 234567;         // Current time of day
-            lease->subnet_id_ = 73;        // Same as for straddress6_1
+            lease->duid_ = boost::shared_ptr<DUID>(
+                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;
@@ -403,54 +402,58 @@ public:
             // 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;  // Preferred lifetime
-            lease->valid_lft_ = 7000;      // Actual lifetime
-            lease->cltt_ = 234567;         // Current time of day
-            lease->subnet_id_ = 37;        // Different from L1 and L2
+            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_ = boost::shared_ptr<DUID>(new DUID(vector<uint8_t>(8, 0x42)));
-            lease->preferred_lft_ = 4800;  // Preferred lifetime
-            lease->valid_lft_ = 7736;      // Actual lifetime
-            lease->cltt_ = 222456;         // Current time of day
-            lease->subnet_id_ = 75;        // Arbitrary number
+            lease->duid_ = boost::shared_ptr<DUID>(
+                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;
-            lease->duid_ = boost::shared_ptr<DUID>(new DUID(vector<uint8_t>(8, 0x42)));
-            lease->preferred_lft_ = 5400;  // Preferred lifetime
-            lease->valid_lft_ = 7832;      // Actual lifetime
-            lease->cltt_ = 227476;         // Current time of day
-            lease->subnet_id_ = 175;       // Arbitrary number
+            lease->iaid_ = 42;                          // Same as lease 4
+            lease->duid_ = boost::shared_ptr<DUID>(
+                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_ = boost::shared_ptr<DUID>(new DUID(vector<uint8_t>(8, 0x42)));
-            lease->preferred_lft_ = 5400;  // Preferred lifetime
-            lease->valid_lft_ = 1832;      // Actual lifetime
-            lease->cltt_ = 627476;         // Current time of day
-            lease->subnet_id_ = 112;       // Arbitrary number
+            lease->duid_ = boost::shared_ptr<DUID>(
+                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_ = boost::shared_ptr<DUID>(new DUID(vector<uint8_t>(8, 0xe5)));
-            lease->preferred_lft_ = 5600;  // Preferred lifetime
-            lease->valid_lft_ = 7975;      // Actual lifetime
-            lease->cltt_ = 213876;         // Current time of day
-            lease->subnet_id_ = 19;        // Arbitrary number
+            lease->duid_ = boost::shared_ptr<DUID>(
+                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.
@@ -461,13 +464,13 @@ public:
         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
+    /// @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 {
 
@@ -484,11 +487,11 @@ public:
         }
     }
 
-    // @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
+    /// @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
@@ -504,11 +507,11 @@ public:
         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
+    /// @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
@@ -527,21 +530,20 @@ public:
 
     // 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
+    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
-//
-// This test checks if the MySqlLeaseMgr can be instantiated.  This happens
-// only if the database can be opened.  Note that this is not part of the
-// MySqlLeaseMgr test fixure set.  This test checks that the database can be
-// opened: the fixtures assume that and check basic operations.
+/// @brief Check that database can be opened
+///
+/// This test checks if the MySqlLeaseMgr can be instantiated.  This happens
+/// only if the database can be opened.  Note that this is not part of the
+/// MySqlLeaseMgr test fixure set.  This test checks that the database can be
+/// opened: the fixtures assume that and check basic operations.
 
 TEST(MySqlOpenTest, OpenDatabase) {
 
@@ -599,25 +601,25 @@ TEST(MySqlOpenTest, OpenDatabase) {
     destroySchema();
 }
 
-// @brief Check the getType() method
-//
-// getType() returns a string giving the type of the backend, which should
-// always be "mysql".
+/// @brief Check the getType() method
+///
+/// getType() returns a string giving the type of the backend, which should
+/// always be "mysql".
 TEST_F(MySqlLeaseMgrTest, getType) {
     EXPECT_EQ(std::string("mysql"), lmptr_->getType());
 }
 
-// @brief Check conversion functions
-//
-// The server works using cltt and valid_filetime.  In the database, the
-// information is stored as expire_time and valid-lifetime, which are
-// related by
-//
-// expire_time = cltt + valid_lifetime
-//
-// This test checks that the conversion is correct.  It does not check that the
-// data is entered into the database correctly, only that the MYSQL_TIME
-// structure used for the entry is correctly set up.
+/// @brief Check conversion functions
+///
+/// The server works using cltt and valid_filetime.  In the database, the
+/// information is stored as expire_time and valid-lifetime, which are
+/// related by
+///
+/// expire_time = cltt + valid_lifetime
+///
+/// This test checks that the conversion is correct.  It does not check that the
+/// data is entered into the database correctly, only that the MYSQL_TIME
+/// structure used for the entry is correctly set up.
 TEST_F(MySqlLeaseMgrTest, checkTimeConversion) {
     const time_t cltt = time(NULL);
     const uint32_t valid_lft = 86400;       // 1 day
@@ -649,14 +651,14 @@ TEST_F(MySqlLeaseMgrTest, checkTimeConversion) {
 }
 
 
-// @brief Check getName() returns correct database name
+/// @brief Check getName() returns correct database name
 TEST_F(MySqlLeaseMgrTest, getName) {
     EXPECT_EQ(std::string("keatest"), lmptr_->getName());
 
     // @TODO: check for the negative
 }
 
-// @brief Check that getVersion() returns the expected version
+/// @brief Check that getVersion() returns the expected version
 TEST_F(MySqlLeaseMgrTest, checkVersion) {
     // Check version
     pair<uint32_t, uint32_t> version;
@@ -665,7 +667,7 @@ TEST_F(MySqlLeaseMgrTest, checkVersion) {
     EXPECT_EQ(CURRENT_VERSION_MINOR, version.second);
 }
 
-// @brief Compare two Lease4 structures for equality
+/// @brief Compare two Lease4 structures for equality
 void
 detailCompareLease(const Lease4Ptr& first, const Lease4Ptr& second) {
     // Compare address strings.  Comparison of address objects is not used, as
@@ -680,7 +682,7 @@ detailCompareLease(const Lease4Ptr& first, const Lease4Ptr& second) {
     EXPECT_EQ(first->subnet_id_, second->subnet_id_);
 }
 
-// @brief Compare two Lease6 structures for equality
+/// @brief Compare two Lease6 structures for equality
 void
 detailCompareLease(const Lease6Ptr& first, const Lease6Ptr& second) {
     EXPECT_EQ(first->type_, second->type_);
@@ -700,17 +702,17 @@ detailCompareLease(const Lease6Ptr& first, const Lease6Ptr& second) {
 }
 
 
-// @brief Basic Lease Checks
-//
-// Checks that the add/get/delete works.  All are done within one
-// test so that "rollback" can be used to remove trace of the tests
-// from the database.
-//
-// Tests where a collection of leases can be returned are in the test
-// Lease4Collection.
-//
-// @param leases Vector of leases used in the tests
-// @param ioaddress Vector of IOAddresses used in the tests
+/// @brief Basic Lease Checks
+///
+/// Checks that the add/get/delete works.  All are done within one
+/// test so that "rollback" can be used to remove trace of the tests
+/// from the database.
+///
+/// Tests where a collection of leases can be returned are in the test
+/// Lease4Collection.
+///
+/// @param leases Vector of leases used in the tests
+/// @param ioaddress Vector of IOAddresses used in the tests
 
 TEST_F(MySqlLeaseMgrTest, basicLease4) {
     // Get the leases to be used for the test.
@@ -755,14 +757,14 @@ TEST_F(MySqlLeaseMgrTest, basicLease4) {
 }
 
 
-// @brief Check individual Lease6 methods
-//
-// Checks that the add/get/delete works.  All are done within one
-// test so that "rollback" can be used to remove trace of the tests
-// from the database.
-//
-// Tests where a collection of leases can be returned are in the test
-// Lease6Collection.
+/// @brief Check individual Lease6 methods
+///
+/// Checks that the add/get/delete works.  All are done within one
+/// test so that "rollback" can be used to remove trace of the tests
+/// from the database.
+///
+/// Tests where a collection of leases can be returned are in the test
+/// Lease6Collection.
 TEST_F(MySqlLeaseMgrTest, basicLease6) {
     // Get the leases to be used for the test.
     vector<Lease6Ptr> leases = createLeases6();
@@ -805,10 +807,10 @@ TEST_F(MySqlLeaseMgrTest, basicLease6) {
     detailCompareLease(leases[2], l_returned);
 }
 
-// @brief Check GetLease4 methods - Access by Address and SubnetID
-//
-// Adds leases to the database and checks that they can be accessed via
-// a the hardware address
+/// @brief Check GetLease4 methods - access by Address and SubnetID
+///
+/// Adds leases to the database and checks that they can be accessed via
+/// a the hardware address
 TEST_F(MySqlLeaseMgrTest, getLease4AddressSubnetId) {
     // Get the leases to be used for the test.
     vector<Lease4Ptr> leases = createLeases4();
@@ -835,10 +837,10 @@ TEST_F(MySqlLeaseMgrTest, getLease4AddressSubnetId) {
 }
 
 
-// @brief Check GetLease4 methods - Access by Hardware Address
-//
-// Adds leases to the database and checks that they can be accessed via
-// a combination of DIUID and IAID.
+/// @brief Check GetLease4 methods - access by Hardware Address
+///
+/// Adds leases to the database and checks that they can be accessed via
+/// a combination of DIUID and IAID.
 TEST_F(MySqlLeaseMgrTest, getLease4Hwaddr) {
     // Get the leases to be used for the test and add to the database
     vector<Lease4Ptr> leases = createLeases4();
@@ -888,11 +890,10 @@ TEST_F(MySqlLeaseMgrTest, getLease4Hwaddr) {
 
 
 
-// @brief Check GetLease4 methods - Access by Hardware Address & Subnet ID
-//
-// Adds leases to the database and checks that they can be accessed via
-// a combination of hardware address and subnet ID
-
+/// @brief Check GetLease4 methods - access by Hardware Address & Subnet ID
+///
+/// Adds leases to the database and checks that they can be accessed via
+/// a combination of hardware address and subnet ID
 TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSubnetId) {
     // Get the leases to be used for the test and add to the database
     vector<Lease4Ptr> leases = createLeases4();
@@ -925,13 +926,25 @@ TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSubnetId) {
     returned = lmptr_->getLease4(invalid_hwaddr,
                                  leases[1]->subnet_id_ + 1);
     EXPECT_FALSE(returned);
+
+    // Add a second lease with the same values as the first and check that
+    // an attempt to access the database by these parameters throws a
+    // "multiple records" exception. (We expect there to be only one record
+    // with that combination, so getting them via getLeaseX() (as opposed
+    // to getLeaseXCollection() should throw an exception.)
+    EXPECT_TRUE(lmptr_->deleteLease4(leases[2]->addr_));
+    leases[1]->addr_ = leases[2]->addr_;
+    EXPECT_TRUE(lmptr_->addLease(leases[1]));
+    EXPECT_THROW(returned = lmptr_->getLease4(leases[1]->hwaddr_,
+                                              leases[1]->subnet_id_),
+                 isc::dhcp::MultipleRecords);
 }
 
 
-// @brief Check GetLease4 methods - Access by Client ID
-//
-// Adds leases to the database and checks that they can be accessed via
-// the Client ID
+/// @brief Check GetLease4 methods - access by Client ID
+///
+/// Adds leases to the database and checks that they can be accessed via
+/// the Client ID.
 TEST_F(MySqlLeaseMgrTest, getLease4ClientId) {
     // Get the leases to be used for the test and add to the database
     vector<Lease4Ptr> leases = createLeases4();
@@ -976,11 +989,10 @@ TEST_F(MySqlLeaseMgrTest, getLease4ClientId) {
 }
 
 
-// @brief Check GetLease4 methods - Access by Client ID & Subnet ID
-//
-// Adds leases to the database and checks that they can be accessed via
-// a combination of client and subnet IDs.
-
+/// @brief Check GetLease4 methods - access by Client ID & Subnet ID
+///
+/// Adds leases to the database and checks that they can be accessed via
+/// a combination of client and subnet IDs.
 TEST_F(MySqlLeaseMgrTest, getLease4ClientIdSubnetId) {
     // Get the leases to be used for the test and add to the database
     vector<Lease4Ptr> leases = createLeases4();
@@ -1015,10 +1027,10 @@ TEST_F(MySqlLeaseMgrTest, getLease4ClientIdSubnetId) {
 }
 
 
-// @brief Check GetLease6 methods - Access by DUID/IAID
-//
-// Adds leases to the database and checks that they can be accessed via
-// a combination of DIUID and IAID.
+/// @brief Check GetLease6 methods - access by DUID/IAID
+///
+/// Adds leases to the database and checks that they can be accessed via
+/// a combination of DIUID and IAID.
 TEST_F(MySqlLeaseMgrTest, getLease6DuidIaid) {
     // Get the leases to be used for the test.
     vector<Lease6Ptr> leases = createLeases6();
@@ -1062,10 +1074,10 @@ TEST_F(MySqlLeaseMgrTest, getLease6DuidIaid) {
 
 
 
-// @brief Check GetLease6 methods - Access by DUID/IAID/SubnetID
-//
-// Adds leases to the database and checks that they can be accessed via
-// a combination of DIUID and IAID.
+/// @brief Check GetLease6 methods - access by DUID/IAID/SubnetID
+///
+/// Adds leases to the database and checks that they can be accessed via
+/// a combination of DIUID and IAID.
 TEST_F(MySqlLeaseMgrTest, getLease6DuidIaidSubnetId) {
     // Get the leases to be used for the test and add them to the database.
     vector<Lease6Ptr> leases = createLeases6();
@@ -1100,8 +1112,9 @@ TEST_F(MySqlLeaseMgrTest, getLease6DuidIaidSubnetId) {
 }
 
 
-// Update lease4 tests
-
+/// @brief Lease4 update tests
+///
+/// Checks that we are able to update a lease in the database.
 TEST_F(MySqlLeaseMgrTest, updateLease4) {
     // Get the leases to be used for the test and add them to the database.
     vector<Lease4Ptr> leases = createLeases4();
@@ -1144,10 +1157,9 @@ TEST_F(MySqlLeaseMgrTest, updateLease4) {
 }
 
 
-
-// @brief Lease6 Update Tests
-//
-// Checks that we are able to update a lease in the database.
+/// @brief Lease6 update tests
+///
+/// Checks that we are able to update a lease in the database.
 TEST_F(MySqlLeaseMgrTest, updateLease6) {
     // Get the leases to be used for the test.
     vector<Lease6Ptr> leases = createLeases6();
@@ -1157,7 +1169,6 @@ TEST_F(MySqlLeaseMgrTest, updateLease6) {
     EXPECT_TRUE(lmptr_->addLease(leases[1]));
     lmptr_->commit();
 
-    reopen();
     Lease6Ptr l_returned = lmptr_->getLease6(ioaddress6_[1]);
     ASSERT_TRUE(l_returned);
     detailCompareLease(leases[1], l_returned);
@@ -1168,7 +1179,6 @@ TEST_F(MySqlLeaseMgrTest, updateLease6) {
     leases[1]->valid_lft_ *= 2;
     lmptr_->updateLease6(leases[1]);
     lmptr_->commit();
-    reopen();
 
     // ... and check what is returned is what is expected.
     l_returned.reset();

+ 1 - 1
src/lib/dhcpsrv/tests/schema_copy.h

@@ -75,7 +75,7 @@ const char* create_statement[] = {
         "minor INT"
         ")",
 
-    "INSERT INTO schema_version VALUES (0, 1)",
+    "INSERT INTO schema_version VALUES (0, 2)",
 
     NULL
 };