Browse Source

[3555] Extra unit-tests implemented, memfile version bumped to 2.0

Tomek Mrugalski 10 years ago
parent
commit
fd96a35764

+ 1 - 1
src/lib/dhcpsrv/csv_lease_file6.cc

@@ -44,7 +44,7 @@ CSVLeaseFile6::append(const Lease6& lease) const {
     row.writeAt(getColumnIndex("hostname"), lease.hostname_);
     if (lease.hwaddr_) {
         // We may not have hardware information
-        row.writeAt(getColumnIndex("hwaddr"), lease.hwaddr_);
+        row.writeAt(getColumnIndex("hwaddr"), lease.hwaddr_->toText(false));
     }
     CSVFile::append(row);
 }

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

@@ -274,8 +274,12 @@ public:
     ///
     /// @return Version number as a pair of unsigned integers.  "first" is the
     ///         major version number, "second" the minor number.
+    ///
+    /// Numbering history:
+    /// 1.0 - initial version (released as 0.9)
+    /// 2.0 - hwaddr (hardware address/MAC) column added
     virtual std::pair<uint32_t, uint32_t> getVersion() const {
-        return (std::make_pair(1, 0));
+        return (std::make_pair(2, 0));
     }
 
     /// @brief Commit Transactions

+ 42 - 0
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc

@@ -874,6 +874,48 @@ GenericLeaseMgrTest::testMaxDate6() {
     detailCompareLease(leases[1], l_returned);
 }
 
+// Checks whether a MAC address can be stored and retrieved together with
+// a lease.
+void
+GenericLeaseMgrTest::testLease6MAC() {
+    // Get the leases to be used for the test.
+    vector<Lease6Ptr> leases = createLeases6();
+
+    HWAddrPtr hwaddr1(new HWAddr(vector<uint8_t>(6, 11), HTYPE_ETHER));
+    HWAddrPtr hwaddr2(new HWAddr(vector<uint8_t>(6, 22), HTYPE_ETHER));
+
+    leases[1]->hwaddr_ = hwaddr1;     // Add hardware address to leases 1 and 2
+    leases[2]->hwaddr_ = hwaddr2;
+    leases[3]->hwaddr_ = HWAddrPtr(); // No hardware address for the third one
+
+    // Start the tests.  Add three leases to the database, read them back and
+    // check they are what we think they are.
+    EXPECT_TRUE(lmptr_->addLease(leases[1]));
+    EXPECT_TRUE(lmptr_->addLease(leases[2]));
+    EXPECT_TRUE(lmptr_->addLease(leases[3]));
+    lmptr_->commit();
+
+    // Reopen the database to ensure that they actually got stored.
+    reopen(V6);
+
+    // First lease should have a hardware address in it
+    Lease6Ptr stored1 = lmptr_->getLease6(leasetype6_[1], ioaddress6_[1]);
+    ASSERT_TRUE(stored1);
+    ASSERT_TRUE(stored1->hwaddr_);
+    EXPECT_TRUE(*hwaddr1 == *stored1->hwaddr_);
+
+    // Second lease should have a hardware address in it
+    Lease6Ptr stored2 = lmptr_->getLease6(leasetype6_[2], ioaddress6_[2]);
+    ASSERT_TRUE(stored2);
+    ASSERT_TRUE(stored2->hwaddr_);
+    EXPECT_TRUE(*hwaddr2 == *stored2->hwaddr_);
+
+    // Third lease should NOT have any hardware address.
+    Lease6Ptr stored3 = lmptr_->getLease6(leasetype6_[3], ioaddress6_[3]);
+    ASSERT_TRUE(stored3);
+    EXPECT_FALSE(stored3->hwaddr_);
+}
+
 void
 GenericLeaseMgrTest::testLease4InvalidHostname() {
     // Get the leases to be used for the test.

+ 3 - 1
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h

@@ -183,9 +183,11 @@ public:
     /// IPv6 address) works.
     void testBasicLease6();
 
-    /// @brief checks that invalid dates are safely handled.
+    /// @brief Checks that invalid dates are safely handled.
     void testMaxDate6();
 
+    /// @brief Checks that Lease6 can be stored with and without a hardware address.
+    void testLease6MAC();
 
     /// @brief Test that IPv6 lease can be added, retrieved and deleted.
     ///

+ 44 - 0
src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc

@@ -26,6 +26,7 @@
 #include <gtest/gtest.h>
 
 #include <iostream>
+#include <fstream>
 #include <sstream>
 
 using namespace std;
@@ -421,4 +422,47 @@ TEST_F(MemfileLeaseMgrTest, DISABLED_nullDuid) {
     ASSERT_THROW(lmptr_->addLease(leases[1]), DbOperationError);
 }
 
+/// @brief Tests whether memfile can store and retrieve hardware addresses
+TEST_F(MemfileLeaseMgrTest, testLease6Mac) {
+    startBackend(V6);
+    testLease6MAC();
+}
+
+/// @brief Tests whether memfile is able to work with old CSV file (without mac)
+///
+/// Ticket #3555 introduced MAC address support in Lease6. Instead of developing
+/// an upgrade script, the code is written in a way that allows reading old CSV
+/// (i.e. format that was used in Kea 0.9), hence no upgrade is necessary.
+TEST_F(MemfileLeaseMgrTest, testUpgrade0_9_0_to_0_9_1) {
+
+    // Let's write a CSV file without hwaddr column. Sorry about the long
+    // lines, but nobody was around to whine about 80 columns limit when CSV
+    // format was invented :).
+    string csv_nohwaddr =
+        "address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname\n"
+        "2001:db8::1,42:42:42:42:42:42:42:42,3677,127133,73,3600,1,42,0,0,1,myhost.example.com.\n"
+        "2001:db8::2,3a:3a:3a:3a:3a:3a:3a:3a,5412,239979,73,1800,2,89,7,0,0,myhost.example.com.\n"
+        "2001:db8::3,1f:20:21:22:23:24:25:26,7000,241567,37,7200,0,4294967294,28,1,0,myhost.example.com.\n";
+
+    ofstream csv(getLeaseFilePath("leasefile6_0.csv").c_str(), ios::out | ios::trunc);
+    ASSERT_TRUE(csv.is_open());
+    csv << csv_nohwaddr;
+    csv.close();
+
+    startBackend(V6);
+
+    // None of the leases should have any hardware addresses assigned.
+    Lease6Ptr stored1 = lmptr_->getLease6(leasetype6_[1], ioaddress6_[1]);
+    ASSERT_TRUE(stored1);
+    EXPECT_FALSE(stored1->hwaddr_);
+
+    Lease6Ptr stored2 = lmptr_->getLease6(leasetype6_[2], ioaddress6_[2]);
+    ASSERT_TRUE(stored2);
+    EXPECT_FALSE(stored2->hwaddr_);
+
+    Lease6Ptr stored3 = lmptr_->getLease6(leasetype6_[3], ioaddress6_[3]);
+    ASSERT_TRUE(stored3);
+    EXPECT_FALSE(stored3->hwaddr_);
+}
+
 }; // end of anonymous namespace

+ 10 - 2
src/lib/util/csv_file.cc

@@ -288,8 +288,16 @@ CSVFile::open() {
 
             // Check the header against the columns specified for the CSV file.
             if (!validateHeader(header)) {
-                isc_throw(CSVFileError, "invalid header '" << header
-                          << "' in CSV file '" << filename_ << "'");
+
+                // One possible validation failure is that we're reading Kea 0.9
+                // lease file that didn't have hwaddr column. Let's add it and
+                // try to revalidate.
+                header.append("hwaddr");
+
+                if (!validateHeader(header)) {
+                    isc_throw(CSVFileError, "invalid header '" << header
+                              << "' in CSV file '" << filename_ << "'");
+                }
             }
 
             // Everything is good, so if we haven't added any columns yet,