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);
}
///
/// @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
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.
/// 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.
///
#include <gtest/gtest.h>
#include <iostream>
+#include <fstream>
#include <sstream>
using namespace std;
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
// 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,