summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/dhcpsrv/Makefile.am1
-rw-r--r--src/lib/dhcpsrv/csv_lease_file4.cc41
-rw-r--r--src/lib/dhcpsrv/csv_lease_file4.h16
-rw-r--r--src/lib/dhcpsrv/csv_lease_file6.cc37
-rw-r--r--src/lib/dhcpsrv/csv_lease_file6.h16
-rw-r--r--src/lib/dhcpsrv/lease_file_loader.h4
-rw-r--r--src/lib/dhcpsrv/lease_file_stats.h102
-rw-r--r--src/lib/dhcpsrv/tests/csv_lease_file4_unittest.cc68
-rw-r--r--src/lib/dhcpsrv/tests/csv_lease_file6_unittest.cc77
-rw-r--r--src/lib/dhcpsrv/tests/lease_file_loader_unittest.cc320
-rw-r--r--src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc44
-rw-r--r--src/lib/util/csv_file.h3
12 files changed, 587 insertions, 142 deletions
diff --git a/src/lib/dhcpsrv/Makefile.am b/src/lib/dhcpsrv/Makefile.am
index 818414a008..d82601d6b9 100644
--- a/src/lib/dhcpsrv/Makefile.am
+++ b/src/lib/dhcpsrv/Makefile.am
@@ -86,6 +86,7 @@ libkea_dhcpsrv_la_SOURCES += host_mgr.cc host_mgr.h
libkea_dhcpsrv_la_SOURCES += key_from_key.h
libkea_dhcpsrv_la_SOURCES += lease.cc lease.h
libkea_dhcpsrv_la_SOURCES += lease_file_loader.h
+libkea_dhcpsrv_la_SOURCES += lease_file_stats.h
libkea_dhcpsrv_la_SOURCES += lease_mgr.cc lease_mgr.h
libkea_dhcpsrv_la_SOURCES += lease_mgr_factory.cc lease_mgr_factory.h
libkea_dhcpsrv_la_SOURCES += logging.cc logging.h
diff --git a/src/lib/dhcpsrv/csv_lease_file4.cc b/src/lib/dhcpsrv/csv_lease_file4.cc
index e48d47e0b4..d4d60fff69 100644
--- a/src/lib/dhcpsrv/csv_lease_file4.cc
+++ b/src/lib/dhcpsrv/csv_lease_file4.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2015 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
@@ -26,10 +26,25 @@ CSVLeaseFile4::CSVLeaseFile4(const std::string& filename)
}
void
-CSVLeaseFile4::append(const Lease4& lease) const {
+CSVLeaseFile4::open(const bool seek_to_end) {
+ // Call the base class to open the file
+ CSVFile::open(seek_to_end);
+
+ // and clear any statistics we may have
+ clearStatistics();
+}
+
+void
+CSVLeaseFile4::append(const Lease4& lease) {
+ // Bump the number of write attempts
+ ++writes_;
+
CSVRow row(getColumnCount());
row.writeAt(getColumnIndex("address"), lease.addr_.toText());
if (!lease.hwaddr_) {
+ // Bump the error counter
+ ++write_errs_;
+
isc_throw(BadValue, "Lease4 must have hardware address specified.");
}
row.writeAt(getColumnIndex("hwaddr"), lease.hwaddr_->toText(false));
@@ -43,11 +58,24 @@ CSVLeaseFile4::append(const Lease4& lease) const {
row.writeAt(getColumnIndex("fqdn_fwd"), lease.fqdn_fwd_);
row.writeAt(getColumnIndex("fqdn_rev"), lease.fqdn_rev_);
row.writeAt(getColumnIndex("hostname"), lease.hostname_);
- CSVFile::append(row);
+
+ try {
+ CSVFile::append(row);
+ } catch (const std::exception& ex) {
+ // Catch any errors so we can bump the error counter than rethrow it
+ ++write_errs_;
+ throw;
+ }
+
+ // Bump the number of leases written
+ ++write_leases_;
}
bool
CSVLeaseFile4::next(Lease4Ptr& lease) {
+ // Bump the number of read attempts
+ ++reads_;
+
// Read the CSV row and try to create a lease from the values read.
// This may easily result in exception. We don't want this function
// to throw exceptions, so we catch them all and rather return the
@@ -88,12 +116,19 @@ CSVLeaseFile4::next(Lease4Ptr& lease) {
readHostname(row)));
} catch (std::exception& ex) {
+ // bump the read error count
+ ++read_errs_;
+
// The lease might have been created, so let's set it back to NULL to
// signal that lease hasn't been parsed.
lease.reset();
setReadMsg(ex.what());
return (false);
}
+
+ // bump the number of leases read
+ ++read_leases_;
+
return (true);
}
diff --git a/src/lib/dhcpsrv/csv_lease_file4.h b/src/lib/dhcpsrv/csv_lease_file4.h
index 57862f659d..736316209d 100644
--- a/src/lib/dhcpsrv/csv_lease_file4.h
+++ b/src/lib/dhcpsrv/csv_lease_file4.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2015 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
@@ -19,6 +19,7 @@
#include <dhcp/duid.h>
#include <dhcpsrv/lease.h>
#include <dhcpsrv/subnet.h>
+#include <dhcpsrv/lease_file_stats.h>
#include <util/csv_file.h>
#include <stdint.h>
#include <string>
@@ -38,7 +39,7 @@ namespace dhcp {
/// validation (see http://kea.isc.org/ticket/2405). However, when #2405
/// is implemented, the @c next function may need to be updated to use the
/// validation capablity of @c Lease4.
-class CSVLeaseFile4 : public isc::util::CSVFile {
+class CSVLeaseFile4 : public isc::util::CSVFile, public LeaseFileStats {
public:
/// @brief Constructor.
@@ -48,6 +49,15 @@ public:
/// @param filename Name of the lease file.
CSVLeaseFile4(const std::string& filename);
+ /// @brief Opens a lease file.
+ ///
+ /// This function calls the base class open to do the
+ /// work of opening a file. It is used to clear any
+ /// statistics associated with any previous use of the file
+ /// While it doesn't throw any exceptions of its own
+ /// the base class may do so.
+ virtual void open(const bool seek_to_end = false);
+
/// @brief Appends the lease record to the CSV file.
///
/// This function doesn't throw exceptions itself. In theory, exceptions
@@ -56,7 +66,7 @@ public:
/// error.
///
/// @param lease Structure representing a DHCPv4 lease.
- void append(const Lease4& lease) const;
+ void append(const Lease4& lease);
/// @brief Reads next lease from the CSV file.
///
diff --git a/src/lib/dhcpsrv/csv_lease_file6.cc b/src/lib/dhcpsrv/csv_lease_file6.cc
index 7157e2e79c..2b1cfd887a 100644
--- a/src/lib/dhcpsrv/csv_lease_file6.cc
+++ b/src/lib/dhcpsrv/csv_lease_file6.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2015 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
@@ -27,7 +27,19 @@ CSVLeaseFile6::CSVLeaseFile6(const std::string& filename)
}
void
-CSVLeaseFile6::append(const Lease6& lease) const {
+CSVLeaseFile6::open(const bool seek_to_end) {
+ // Call the base class to open the file
+ CSVFile::open(seek_to_end);
+
+ // and clear any statistics we may have
+ clearStatistics();
+}
+
+void
+CSVLeaseFile6::append(const Lease6& lease) {
+ // Bump the number of write attempts
+ ++writes_;
+
CSVRow row(getColumnCount());
row.writeAt(getColumnIndex("address"), lease.addr_.toText());
row.writeAt(getColumnIndex("duid"), lease.duid_->toText());
@@ -46,11 +58,23 @@ CSVLeaseFile6::append(const Lease6& lease) const {
// We may not have hardware information
row.writeAt(getColumnIndex("hwaddr"), lease.hwaddr_->toText(false));
}
- CSVFile::append(row);
+ try {
+ CSVFile::append(row);
+ } catch (const std::exception& ex) {
+ // Catch any errors so we can bump the error counter than rethrow it
+ ++write_errs_;
+ throw;
+ }
+
+ // Bump the number of leases written
+ ++write_leases_;
}
bool
CSVLeaseFile6::next(Lease6Ptr& lease) {
+ // Bump the number of read attempts
+ ++reads_;
+
// Read the CSV row and try to create a lease from the values read.
// This may easily result in exception. We don't want this function
// to throw exceptions, so we catch them all and rather return the
@@ -77,12 +101,19 @@ CSVLeaseFile6::next(Lease6Ptr& lease) {
lease->hostname_ = readHostname(row);
} catch (std::exception& ex) {
+ // bump the read error count
+ ++read_errs_;
+
// The lease might have been created, so let's set it back to NULL to
// signal that lease hasn't been parsed.
lease.reset();
setReadMsg(ex.what());
return (false);
}
+
+ // bump the number of leases read
+ ++read_leases_;
+
return (true);
}
diff --git a/src/lib/dhcpsrv/csv_lease_file6.h b/src/lib/dhcpsrv/csv_lease_file6.h
index 105b4e505c..2c2a0f6f86 100644
--- a/src/lib/dhcpsrv/csv_lease_file6.h
+++ b/src/lib/dhcpsrv/csv_lease_file6.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2015 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
@@ -19,6 +19,7 @@
#include <dhcp/duid.h>
#include <dhcpsrv/lease.h>
#include <dhcpsrv/subnet.h>
+#include <dhcpsrv/lease_file_stats.h>
#include <util/csv_file.h>
#include <stdint.h>
#include <string>
@@ -37,7 +38,7 @@ namespace dhcp {
/// validation (see http://kea.isc.org/ticket/2405). However, when #2405
/// is implemented, the @c next function may need to be updated to use the
/// validation capablity of @c Lease6.
-class CSVLeaseFile6 : public isc::util::CSVFile {
+class CSVLeaseFile6 : public isc::util::CSVFile, public LeaseFileStats {
public:
/// @brief Constructor.
@@ -47,6 +48,15 @@ public:
/// @param filename Name of the lease file.
CSVLeaseFile6(const std::string& filename);
+ /// @brief Opens a lease file.
+ ///
+ /// This function calls the base class open to do the
+ /// work of opening a file. It is used to clear any
+ /// statistics associated with any previous use of the file
+ /// While it doesn't throw any exceptions of its own
+ /// the base class may do so.
+ virtual void open(const bool seek_to_end = false);
+
/// @brief Appends the lease record to the CSV file.
///
/// This function doesn't throw exceptions itself. In theory, exceptions
@@ -55,7 +65,7 @@ public:
/// error.
///
/// @param lease Structure representing a DHCPv6 lease.
- void append(const Lease6& lease) const;
+ void append(const Lease6& lease);
/// @brief Reads next lease from the CSV file.
///
diff --git a/src/lib/dhcpsrv/lease_file_loader.h b/src/lib/dhcpsrv/lease_file_loader.h
index d2fc637b8f..f41bf4bfcb 100644
--- a/src/lib/dhcpsrv/lease_file_loader.h
+++ b/src/lib/dhcpsrv/lease_file_loader.h
@@ -43,8 +43,6 @@ namespace dhcp {
/// with the @c Lease4Storage and @c Lease6Storage to process the DHCPv4
/// and DHCPv6 leases respectively.
///
-/// @todo Add a method which dumps all leases from the storage to a
-/// specified lease file.
class LeaseFileLoader {
public:
@@ -184,7 +182,7 @@ public:
/// @param storage A reference to the container from which leases
/// should be written.
///
- /// @tparam LeasePtrType A @c Lease4 or @c Lease6.
+ /// @tparam LeaseObjectType A @c Lease4 or @c Lease6.
/// @tparam LeaseFileType A @c CSVLeaseFile4 or @c CSVLeaseFile6.
/// @tparam StorageType A @c Lease4Storage or @c Lease6Storage.
template<typename LeaseObjectType, typename LeaseFileType,
diff --git a/src/lib/dhcpsrv/lease_file_stats.h b/src/lib/dhcpsrv/lease_file_stats.h
new file mode 100644
index 0000000000..6c6b15752b
--- /dev/null
+++ b/src/lib/dhcpsrv/lease_file_stats.h
@@ -0,0 +1,102 @@
+// Copyright (C) 2015 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 LEASE_FILE_STATS_H
+#define LEASE_FILE_STATS_H
+
+namespace isc {
+namespace dhcp {
+
+/// @brief Provides statistics for leases.
+///
+/// This class provides a common space for statistics that we wish
+/// to keep about leases. Currently this is for use with lease files
+/// but it may be expanded in the future.
+class LeaseFileStats {
+public:
+ /// @brief Constructor
+ ///
+ /// Initializes the stats variables to zeros
+ LeaseFileStats() {
+ clearStatistics();
+ }
+
+ /// @brief Destructor
+ ~LeaseFileStats() {
+ }
+
+ /// @brief Gets the number of attempts to read a lease
+ uint32_t getReads() const {
+ return (reads_);
+ }
+
+ /// @brief Gets the number of leases read
+ uint32_t getReadLeases() const {
+ return (read_leases_);
+ }
+
+ /// @brief Gets the number of errors when reading leases
+ uint32_t getReadErrs() const {
+ return (read_errs_);
+ }
+
+ /// @brief Gets the number of attempts to write a lease
+ uint32_t getWrites() const {
+ return (writes_);
+ }
+
+ /// @brief Gets the number of leases written
+ uint32_t getWriteLeases() const {
+ return (write_leases_);
+ }
+
+ /// @brief Gets the number of errors when writting leases
+ uint32_t getWriteErrs() const {
+ return (write_errs_);
+ }
+
+ /// @brief Clears the statistics
+ void clearStatistics() {
+ reads_ = 0;
+ read_leases_ = 0;
+ read_errs_ = 0;
+ writes_ = 0;
+ write_leases_ = 0;
+ write_errs_ = 0;
+ }
+
+protected:
+ /// @brief Number of attempts to read a lease
+ uint32_t reads_;
+
+ /// @brief Number of leases read
+ uint32_t read_leases_;
+
+ /// @brief Number of errors when reading
+ uint32_t read_errs_;
+
+ /// @brief Number of attempts to write a lease
+ uint32_t writes_;
+
+ /// @brief Number of lease written
+ uint32_t write_leases_;
+
+ /// @brief Number of errors when writing
+ uint32_t write_errs_;
+};
+
+} // namespace isc::dhcp
+} // namesapce isc
+
+#endif // LEASE_FILE_STATS_H
diff --git a/src/lib/dhcpsrv/tests/csv_lease_file4_unittest.cc b/src/lib/dhcpsrv/tests/csv_lease_file4_unittest.cc
index b2ecdc20b9..d0d16604b9 100644
--- a/src/lib/dhcpsrv/tests/csv_lease_file4_unittest.cc
+++ b/src/lib/dhcpsrv/tests/csv_lease_file4_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2015 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
@@ -57,6 +57,30 @@ public:
/// @brief Creates the lease file to be parsed by unit tests.
void writeSampleFile() const;
+ /// @brief Checks the stats for the file
+ ///
+ /// This method is passed a leasefile and the values for the statistics it
+ /// should have for comparison.
+ ///
+ /// @param lease_file A reference to the file we are using
+ /// @param reads the number of attempted reads
+ /// @param read_leases the number of valid leases read
+ /// @param read_errs the number of errors while reading leases
+ /// @param writes the number of attempted writes
+ /// @param write_leases the number of leases successfully written
+ /// @param write_errs the number of errors while writing
+ void checkStats(CSVLeaseFile4& lease_file,
+ uint32_t reads, uint32_t read_leases,
+ uint32_t read_errs, uint32_t writes,
+ uint32_t write_leases, uint32_t write_errs) const {
+ EXPECT_EQ(reads, lease_file.getReads());
+ EXPECT_EQ(read_leases, lease_file.getReadLeases());
+ EXPECT_EQ(read_errs, lease_file.getReadErrs());
+ EXPECT_EQ(writes, lease_file.getWrites());
+ EXPECT_EQ(write_leases, lease_file.getWriteLeases());
+ EXPECT_EQ(write_errs, lease_file.getWriteErrs());
+ }
+
/// @brief Name of the test lease file.
std::string filename_;
@@ -104,10 +128,19 @@ TEST_F(CSVLeaseFile4Test, parse) {
boost::scoped_ptr<CSVLeaseFile4> lf(new CSVLeaseFile4(filename_));
ASSERT_NO_THROW(lf->open());
+ // Verify the counters are cleared
+ {
+ SCOPED_TRACE("Check stats are empty");
+ checkStats(*lf, 0, 0, 0, 0, 0, 0);
+ }
+
Lease4Ptr lease;
// Reading first read should be successful.
+ {
+ SCOPED_TRACE("First lease valid");
EXPECT_TRUE(lf->next(lease));
ASSERT_TRUE(lease);
+ checkStats(*lf, 1, 1, 0, 0, 0, 0);
// Verify that the lease attributes are correct.
EXPECT_EQ("192.0.2.1", lease->addr_.toText());
@@ -120,14 +153,23 @@ TEST_F(CSVLeaseFile4Test, parse) {
EXPECT_TRUE(lease->fqdn_fwd_);
EXPECT_TRUE(lease->fqdn_rev_);
EXPECT_EQ("host.example.com", lease->hostname_);
+ }
// Second lease is malformed - HW address is empty.
+ {
+ SCOPED_TRACE("Second lease malformed");
EXPECT_FALSE(lf->next(lease));
+ checkStats(*lf, 2, 1, 1, 0, 0, 0);
+ }
// Even though parsing previous lease failed, reading the next lease should be
// successful.
+ {
+ SCOPED_TRACE("Third lease valid");
EXPECT_TRUE(lf->next(lease));
ASSERT_TRUE(lease);
+ checkStats(*lf, 3, 2, 1, 0, 0, 0);
+
// Verify that the third lease is correct.
EXPECT_EQ("192.0.3.15", lease->addr_.toText());
HWAddr hwaddr3(*lease->hwaddr_);
@@ -140,16 +182,24 @@ TEST_F(CSVLeaseFile4Test, parse) {
EXPECT_FALSE(lease->fqdn_fwd_);
EXPECT_FALSE(lease->fqdn_rev_);
EXPECT_TRUE(lease->hostname_.empty());
+ }
// There are no more leases. Reading should cause no error, but the returned
// lease pointer should be NULL.
+ {
+ SCOPED_TRACE("Fifth read empty");
EXPECT_TRUE(lf->next(lease));
EXPECT_FALSE(lease);
+ checkStats(*lf, 4, 2, 1, 0, 0, 0);
+ }
// We should be able to do it again.
+ {
+ SCOPED_TRACE("Sixth read empty");
EXPECT_TRUE(lf->next(lease));
EXPECT_FALSE(lease);
-
+ checkStats(*lf, 5, 2, 1, 0, 0, 0);
+ }
}
// This test checks creation of the lease file and writing leases.
@@ -157,19 +207,33 @@ TEST_F(CSVLeaseFile4Test, recreate) {
boost::scoped_ptr<CSVLeaseFile4> lf(new CSVLeaseFile4(filename_));
ASSERT_NO_THROW(lf->recreate());
ASSERT_TRUE(io_.exists());
+
+ // Verify the counters are cleared
+ checkStats(*lf, 0, 0, 0, 0, 0, 0);
+
// Create first lease, with NULL client id.
Lease4Ptr lease(new Lease4(IOAddress("192.0.3.2"),
hwaddr0_,
NULL, 0,
200, 50, 80, 0, 8, true, true,
"host.example.com"));
+ {
+ SCOPED_TRACE("First write");
ASSERT_NO_THROW(lf->append(*lease));
+ checkStats(*lf, 0, 0, 0, 1, 1, 0);
+ }
+
// Create second lease, with non-NULL client id.
lease.reset(new Lease4(IOAddress("192.0.3.10"),
hwaddr1_,
CLIENTID0, sizeof(CLIENTID0),
100, 60, 90, 0, 7));
+ {
+ SCOPED_TRACE("Second write");
ASSERT_NO_THROW(lf->append(*lease));
+ checkStats(*lf, 0, 0, 0, 2, 2, 0);
+ }
+
// Close the lease file.
lf->close();
// Check that the contents of the csv file are correct.
diff --git a/src/lib/dhcpsrv/tests/csv_lease_file6_unittest.cc b/src/lib/dhcpsrv/tests/csv_lease_file6_unittest.cc
index 31f40e4d05..7735f1a15f 100644
--- a/src/lib/dhcpsrv/tests/csv_lease_file6_unittest.cc
+++ b/src/lib/dhcpsrv/tests/csv_lease_file6_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2015 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
@@ -63,6 +63,30 @@ public:
/// @brief Create lease file that can be parsed by unit tests.
void writeSampleFile() const;
+ /// @brief Checks the stats for the file
+ ///
+ /// This method is passed a leasefile and the values for the statistics it
+ /// should have for comparison.
+ ///
+ /// @param lease_file A reference to the file we are using
+ /// @param reads the number of attempted reads
+ /// @param read_leases the number of valid leases read
+ /// @param read_errs the number of errors while reading leases
+ /// @param writes the number of attempted writes
+ /// @param write_leases the number of leases successfully written
+ /// @param write_errs the number of errors while writing
+ void checkStats(CSVLeaseFile6& lease_file,
+ uint32_t reads, uint32_t read_leases,
+ uint32_t read_errs, uint32_t writes,
+ uint32_t write_leases, uint32_t write_errs) const {
+ EXPECT_EQ(reads, lease_file.getReads());
+ EXPECT_EQ(read_leases, lease_file.getReadLeases());
+ EXPECT_EQ(read_errs, lease_file.getReadErrs());
+ EXPECT_EQ(writes, lease_file.getWrites());
+ EXPECT_EQ(write_leases, lease_file.getWriteLeases());
+ EXPECT_EQ(write_errs, lease_file.getWriteErrs());
+ }
+
/// @brief Name of the test lease file.
std::string filename_;
@@ -105,10 +129,19 @@ TEST_F(CSVLeaseFile6Test, parse) {
boost::scoped_ptr<CSVLeaseFile6> lf(new CSVLeaseFile6(filename_));
ASSERT_NO_THROW(lf->open());
+ // Verify the counters are cleared
+ {
+ SCOPED_TRACE("Check stats are empty");
+ checkStats(*lf, 0, 0, 0, 0, 0, 0);
+ }
+
Lease6Ptr lease;
// Reading first read should be successful.
+ {
+ SCOPED_TRACE("First lease valid");
EXPECT_TRUE(lf->next(lease));
ASSERT_TRUE(lease);
+ checkStats(*lf, 1, 1, 0, 0, 0, 0);
// Verify that the lease attributes are correct.
EXPECT_EQ("2001:db8:1::1", lease->addr_.toText());
@@ -124,14 +157,23 @@ TEST_F(CSVLeaseFile6Test, parse) {
EXPECT_TRUE(lease->fqdn_fwd_);
EXPECT_TRUE(lease->fqdn_rev_);
EXPECT_EQ("host.example.com", lease->hostname_);
+ }
// Second lease is malformed - DUID is empty.
+ {
+ SCOPED_TRACE("Second lease malformed");
EXPECT_FALSE(lf->next(lease));
+ checkStats(*lf, 2, 1, 1, 0, 0, 0);
+ }
// Even, parsing previous lease failed, reading the next lease should be
// successful.
+ {
+ SCOPED_TRACE("Third lease valid");
EXPECT_TRUE(lf->next(lease));
ASSERT_TRUE(lease);
+ checkStats(*lf, 3, 2, 1, 0, 0, 0);
+
// Verify that the third lease is correct.
EXPECT_EQ("2001:db8:2::10", lease->addr_.toText());
ASSERT_TRUE(lease->duid_);
@@ -146,10 +188,15 @@ TEST_F(CSVLeaseFile6Test, parse) {
EXPECT_FALSE(lease->fqdn_fwd_);
EXPECT_FALSE(lease->fqdn_rev_);
EXPECT_TRUE(lease->hostname_.empty());
+ }
// Reading the fourth lease should be successful.
+ {
+ SCOPED_TRACE("Fourth lease valid");
EXPECT_TRUE(lf->next(lease));
ASSERT_TRUE(lease);
+ checkStats(*lf, 4, 3, 1, 0, 0, 0);
+
// Verify that the lease is correct.
EXPECT_EQ("3000:1::", lease->addr_.toText());
ASSERT_TRUE(lease->duid_);
@@ -164,16 +211,24 @@ TEST_F(CSVLeaseFile6Test, parse) {
EXPECT_FALSE(lease->fqdn_fwd_);
EXPECT_FALSE(lease->fqdn_rev_);
EXPECT_TRUE(lease->hostname_.empty());
+ }
// There are no more leases. Reading should cause no error, but the returned
// lease pointer should be NULL.
+ {
+ SCOPED_TRACE("Fifth read empty");
EXPECT_TRUE(lf->next(lease));
EXPECT_FALSE(lease);
+ checkStats(*lf, 5, 3, 1, 0, 0, 0);
+ }
// We should be able to do it again.
+ {
+ SCOPED_TRACE("Sixth read empty");
EXPECT_TRUE(lf->next(lease));
EXPECT_FALSE(lease);
-
+ checkStats(*lf, 6, 3, 1, 0, 0, 0);
+ }
}
// This test checks creation of the lease file and writing leases.
@@ -182,26 +237,44 @@ TEST_F(CSVLeaseFile6Test, recreate) {
ASSERT_NO_THROW(lf->recreate());
ASSERT_TRUE(io_.exists());
+ // Verify the counters are cleared
+ {
+ SCOPED_TRACE("Check stats are empty");
+ checkStats(*lf, 0, 0, 0, 0, 0, 0);
+ }
+
Lease6Ptr lease(new Lease6(Lease::TYPE_NA, IOAddress("2001:db8:1::1"),
makeDUID(DUID0, sizeof(DUID0)),
7, 100, 200, 50, 80, 8, true, true,
"host.example.com"));
lease->cltt_ = 0;
+ {
+ SCOPED_TRACE("First write");
ASSERT_NO_THROW(lf->append(*lease));
+ checkStats(*lf, 0, 0, 0, 1, 1, 0);
+ }
lease.reset(new Lease6(Lease::TYPE_NA, IOAddress("2001:db8:2::10"),
makeDUID(DUID1, sizeof(DUID1)),
8, 150, 300, 40, 70, 6, false, false,
"", HWAddrPtr(), 128));
lease->cltt_ = 0;
+ {
+ SCOPED_TRACE("Second write");
ASSERT_NO_THROW(lf->append(*lease));
+ checkStats(*lf, 0, 0, 0, 2, 2, 0);
+ }
lease.reset(new Lease6(Lease::TYPE_PD, IOAddress("3000:1:1::"),
makeDUID(DUID0, sizeof(DUID0)),
7, 150, 300, 40, 70, 10, false, false,
"", HWAddrPtr(), 64));
lease->cltt_ = 0;
+ {
+ SCOPED_TRACE("Third write");
ASSERT_NO_THROW(lf->append(*lease));
+ checkStats(*lf, 0, 0, 0, 3, 3, 0);
+ }
EXPECT_EQ("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
"lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr\n"
diff --git a/src/lib/dhcpsrv/tests/lease_file_loader_unittest.cc b/src/lib/dhcpsrv/tests/lease_file_loader_unittest.cc
index 4287fe53ed..14ce913fa2 100644
--- a/src/lib/dhcpsrv/tests/lease_file_loader_unittest.cc
+++ b/src/lib/dhcpsrv/tests/lease_file_loader_unittest.cc
@@ -86,11 +86,13 @@ public:
/// the write was correct. The order of the leases in the output will depend
/// on the order in which the container provides the leases.
///
+ /// @param lease_file A reference to the file to write to
/// @param storage A reference to the container to be written to the file
/// @param compare The string to compare to what was read from the file
///
- /// @tparam LeaseStorage Type of the container: @c Lease4Container
- /// @c Lease6Container.
+ /// @tparam LeaseObjectType A @c Lease4 or @c Lease6.
+ /// @tparam LeaseFileType A @c CSVLeaseFile4 or @c CSVLeaseFile6.
+ /// @tparam StorageType A @c Lease4Storage or @c Lease6Storage.
///
template<typename LeaseObjectType, typename LeaseFileType,
typename StorageType>
@@ -109,12 +111,52 @@ public:
EXPECT_EQ(compare, io_.readFile());
}
+ /// @brief Checks the stats for the file
+ ///
+ /// This method is passed a leasefile and the values for the statistics it
+ /// should have for comparison.
+ ///
+ /// @param lease_file A reference to the file we are using
+ /// @param reads the number of attempted reads
+ /// @param read_leases the number of valid leases read
+ /// @param read_errs the number of errors while reading leases
+ /// @param writes the number of attempted writes
+ /// @param write_leases the number of leases successfully written
+ /// @param write_errs the number of errors while writing
+ ///
+ /// @tparam LeaseFileType A @c CSVLeaseFile4 or @c CSVLeaseFile6.
+ template<typename LeaseFileType>
+ void checkStats(LeaseFileType& lease_file,
+ uint32_t reads, uint32_t read_leases,
+ uint32_t read_errs, uint32_t writes,
+ uint32_t write_leases, uint32_t write_errs) const {
+ EXPECT_EQ(reads, lease_file.getReads());
+ EXPECT_EQ(read_leases, lease_file.getReadLeases());
+ EXPECT_EQ(read_errs, lease_file.getReadErrs());
+ EXPECT_EQ(writes, lease_file.getWrites());
+ EXPECT_EQ(write_leases, lease_file.getWriteLeases());
+ EXPECT_EQ(write_errs, lease_file.getWriteErrs());
+ }
/// @brief Name of the test lease file.
std::string filename_;
/// @brief Object providing access to lease file IO.
LeaseFileIO io_;
+
+ std::string v4_hdr_; ///< String for the header of the v4 csv test file
+ std::string v6_hdr_; ///< String for the header of the v6 csv test file
+
+protected:
+ /// @brief Sets up the header strings
+ virtual void SetUp() {
+ v4_hdr_ = "address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
+ "fqdn_fwd,fqdn_rev,hostname\n";
+
+ v6_hdr_ = "address,duid,valid_lifetime,expire,subnet_id,"
+ "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
+ "fqdn_rev,hostname,hwaddr\n";
+ }
};
LeaseFileLoaderTest::LeaseFileLoaderTest()
@@ -135,20 +177,25 @@ LeaseFileLoaderTest::absolutePath(const std::string& filename) {
// It also tests the write function by writing the storage to a file
// and comparing that with the expected value.
TEST_F(LeaseFileLoaderTest, loadWrite4) {
+ std::string test_str;
+ std::string a_1 = "192.0.2.1,06:07:08:09:0a:bc,,"
+ "200,200,8,1,1,host.example.com\n";
+ std::string a_2 = "192.0.2.1,06:07:08:09:0a:bc,,"
+ "200,500,8,1,1,host.example.com\n";
+
+ std::string b_1 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
+ "100,100,7,0,0,\n";
+ std::string b_2 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
+ "100,135,7,0,0,\n";
+
+ std::string c_1 = "192.0.2.3,,a:11:01:04,"
+ "200,200,8,1,1,host.example.com\n";
+
// Create lease file with leases for 192.0.2.1, 192.0.3.15. The lease
// entry for the 192.0.2.3 is invalid (lacks HW address) and should
// be discarded.
- io_.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
- "fqdn_fwd,fqdn_rev,hostname\n"
- "192.0.2.1,06:07:08:09:0a:bc,,200,200,8,1,1,"
- "host.example.com\n"
- "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,100,100,7,"
- "0,0,\n"
- "192.0.2.3,,a:11:01:04,200,200,8,1,1,host.example.com\n"
- "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,100,135,7,"
- "0,0,\n"
- "192.0.2.1,06:07:08:09:0a:bc,,200,500,8,1,1,"
- "host.example.com\n");
+ test_str = v4_hdr_ + a_1 + b_1 + c_1 + b_2 + a_2;
+ io_.writeFile(test_str);
boost::scoped_ptr<CSVLeaseFile4> lf(new CSVLeaseFile4(filename_));
ASSERT_NO_THROW(lf->open());
@@ -157,6 +204,12 @@ TEST_F(LeaseFileLoaderTest, loadWrite4) {
Lease4Storage storage;
ASSERT_NO_THROW(LeaseFileLoader::load<Lease4>(*lf, storage, 10));
+ // We should have made 6 attempts to read, with 4 leases read and 1 error
+ {
+ SCOPED_TRACE("Read leases");
+ checkStats(*lf, 6, 4, 1, 0, 0, 0);
+ }
+
// There are two unique leases.
ASSERT_EQ(2, storage.size());
@@ -178,14 +231,14 @@ TEST_F(LeaseFileLoaderTest, loadWrite4) {
ASSERT_TRUE(lease);
EXPECT_EQ(35, lease->cltt_);
- writeLeases<Lease4, CSVLeaseFile4, Lease4Storage>
- (*lf, storage,
- "address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
- "fqdn_fwd,fqdn_rev,hostname\n"
- "192.0.2.1,06:07:08:09:0a:bc,,200,500,8,1,1,"
- "host.example.com\n"
- "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,100,135,7,"
- "0,0,\n");
+ test_str = v4_hdr_ + a_2 + b_2;
+ writeLeases<Lease4, CSVLeaseFile4, Lease4Storage>(*lf, storage, test_str);
+
+ // We should have made 2 attempts to write, with 2 leases written and 0 errors
+ {
+ SCOPED_TRACE("Write leases");
+ checkStats(*lf, 0, 0, 0, 2, 2, 0);
+ }
}
// This test verifies that the lease with a valid lifetime of 0
@@ -195,19 +248,23 @@ TEST_F(LeaseFileLoaderTest, loadWrite4) {
// It also tests the write function by writing the storage to a file
// and comparing that with the expected value.
TEST_F(LeaseFileLoaderTest, loadWrite4LeaseRemove) {
+ std::string test_str;
+ std::string a_1 = "192.0.2.1,06:07:08:09:0a:bc,,"
+ "200,200,8,1,1,host.example.com\n";
+ std::string a_2 = "192.0.2.1,06:07:08:09:0a:bc,,"
+ "0,500,8,1,1,host.example.com\n";
+
+ std::string b_1 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
+ "100,100,7,0,0,\n";
+ std::string b_2 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
+ "100,135,7,0,0,\n";
+
+
// Create lease file in which one of the entries for 192.0.2.1
// has a valid_lifetime of 0 and results in the deletion of the
// lease.
- io_.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
- "fqdn_fwd,fqdn_rev,hostname\n"
- "192.0.2.1,06:07:08:09:0a:bc,,200,200,8,1,1,"
- "host.example.com\n"
- "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,100,100,7,"
- "0,0,\n"
- "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,100,135,7,"
- "0,0,\n"
- "192.0.2.1,06:07:08:09:0a:bc,,0,500,8,1,1,"
- "host.example.com\n");
+ test_str = v4_hdr_ + a_1 + b_1 + b_2 + a_2;
+ io_.writeFile(test_str);
boost::scoped_ptr<CSVLeaseFile4> lf(new CSVLeaseFile4(filename_));
ASSERT_NO_THROW(lf->open());
@@ -215,6 +272,12 @@ TEST_F(LeaseFileLoaderTest, loadWrite4LeaseRemove) {
Lease4Storage storage;
ASSERT_NO_THROW(LeaseFileLoader::load<Lease4>(*lf, storage, 10));
+ // We should have made 5 attempts to read, with 4 leases read and 0 error
+ {
+ SCOPED_TRACE("Read leases");
+ checkStats(*lf, 5, 4, 0, 0, 0, 0);
+ }
+
// There should only be one lease. The one with the valid_lifetime
// of 0 should be removed.
ASSERT_EQ(1, storage.size());
@@ -223,12 +286,14 @@ TEST_F(LeaseFileLoaderTest, loadWrite4LeaseRemove) {
ASSERT_TRUE(lease);
EXPECT_EQ(35, lease->cltt_);
- writeLeases<Lease4, CSVLeaseFile4, Lease4Storage>
- (*lf, storage,
- "address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
- "fqdn_fwd,fqdn_rev,hostname\n"
- "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,100,135,7,"
- "0,0,\n");
+ test_str = v4_hdr_ + b_2;
+ writeLeases<Lease4, CSVLeaseFile4, Lease4Storage>(*lf, storage, test_str);
+
+ // We should have made 1 attempts to write, with 1 leases written and 0 errors
+ {
+ SCOPED_TRACE("Write leases");
+ checkStats(*lf, 0, 0, 0, 1, 1, 0);
+ }
}
// This test verifies that the DHCPv6 leases can be loaded from the lease
@@ -238,22 +303,28 @@ TEST_F(LeaseFileLoaderTest, loadWrite4LeaseRemove) {
// It also tests the write function by writing the storage to a file
// and comparing that with the expected value.
TEST_F(LeaseFileLoaderTest, loadWrite6) {
+ std::string test_str;
+ std::string a_1 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
+ "200,200,8,100,0,7,0,1,1,host.example.com,\n";
+ std::string a_2 = "2001:db8:1::1,,"
+ "200,200,8,100,0,7,0,1,1,host.example.com,\n";
+ std::string a_3 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
+ "200,400,8,100,0,7,0,1,1,host.example.com,\n";
+
+ std::string b_1 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
+ "300,300,6,150,0,8,0,0,0,,\n";
+ std::string b_2 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
+ "300,800,6,150,0,8,0,0,0,,\n";
+
+ std::string c_1 = "3000:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
+ "100,200,8,0,2,16,64,0,0,,\n";
+
+
+
// Create a lease file with three valid leases: 2001:db8:1::1,
// 3000:1:: and 2001:db8:2::10.
- io_.writeFile("address,duid,valid_lifetime,expire,subnet_id,"
- "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
- "fqdn_rev,hostname,hwaddr\n"
- "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
- "200,200,8,100,0,7,0,1,1,host.example.com,\n"
- "2001:db8:1::1,,200,200,8,100,0,7,0,1,1,host.example.com,\n"
- "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,300,300,6,150,"
- "0,8,0,0,0,,\n"
- "3000:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,100,200,8,0,2,"
- "16,64,0,0,,\n"
- "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,300,800,6,150,"
- "0,8,0,0,0,,\n"
- "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
- "200,400,8,100,0,7,0,1,1,host.example.com,\n");
+ test_str = v6_hdr_ + a_1 + a_2 + b_1 + c_1 + b_2 + a_3;
+ io_.writeFile(test_str);
boost::scoped_ptr<CSVLeaseFile6> lf(new CSVLeaseFile6(filename_));
ASSERT_NO_THROW(lf->open());
@@ -262,6 +333,12 @@ TEST_F(LeaseFileLoaderTest, loadWrite6) {
Lease6Storage storage;
ASSERT_NO_THROW(LeaseFileLoader::load<Lease6>(*lf, storage, 10));
+ // We should have made 7 attempts to read, with 5 leases read and 1 error
+ {
+ SCOPED_TRACE("Read leases");
+ checkStats(*lf, 7, 5, 1, 0, 0, 0);
+ }
+
// There should be 3 unique leases.
ASSERT_EQ(3, storage.size());
@@ -283,17 +360,14 @@ TEST_F(LeaseFileLoaderTest, loadWrite6) {
ASSERT_TRUE(lease);
EXPECT_EQ(500, lease->cltt_);
- writeLeases<Lease6, CSVLeaseFile6, Lease6Storage>
- (*lf, storage,
- "address,duid,valid_lifetime,expire,subnet_id,"
- "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
- "fqdn_rev,hostname,hwaddr\n"
- "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
- "200,400,8,100,0,7,0,1,1,host.example.com,\n"
- "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,300,800,6,150,"
- "0,8,0,0,0,,\n"
- "3000:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,100,200,8,0,2,"
- "16,64,0,0,,\n");
+ test_str = v6_hdr_ + a_3 + b_2 + c_1;
+ writeLeases<Lease6, CSVLeaseFile6, Lease6Storage>(*lf, storage, test_str);
+
+ // We should have made 3 attempts to write, with 3 leases written and 0 errors
+ {
+ SCOPED_TRACE("Write leases");
+ checkStats(*lf, 0, 0, 0, 3, 3, 0);
+ }
}
// This test verifies that the lease with a valid lifetime of 0
@@ -303,20 +377,22 @@ TEST_F(LeaseFileLoaderTest, loadWrite6) {
// It also tests the write function by writing the storage to a file
// and comparing that with the expected value.
TEST_F(LeaseFileLoaderTest, loadWrite6LeaseRemove) {
+ std::string test_str;
+ std::string a_1 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
+ "200,200,8,100,0,7,0,1,1,host.example.com,\n";
+ std::string a_2 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
+ "0,400,8,100,0,7,0,1,1,host.example.com,\n";
+
+ std::string b_1 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
+ "300,300,6,150,0,8,0,0,0,,\n";
+ std::string b_2 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
+ "300,800,6,150,0,8,0,0,0,,\n";
+
// Create lease file in which one of the entries for the 2001:db8:1::1
// has valid lifetime set to 0, in which case the lease should be
// deleted.
- io_.writeFile("address,duid,valid_lifetime,expire,subnet_id,"
- "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
- "fqdn_rev,hostname,hwaddr\n"
- "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
- "200,200,8,100,0,7,0,1,1,host.example.com,\n"
- "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,300,300,6,150,"
- "0,8,0,0,0,,\n"
- "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,300,800,6,150,"
- "0,8,0,0,0,,\n"
- "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
- "0,400,8,100,0,7,0,1,1,host.example.com,\n");
+ test_str = v6_hdr_ + a_1 + b_1 + b_2 + a_2;
+ io_.writeFile(test_str);
boost::scoped_ptr<CSVLeaseFile6> lf(new CSVLeaseFile6(filename_));
ASSERT_NO_THROW(lf->open());
@@ -325,6 +401,12 @@ TEST_F(LeaseFileLoaderTest, loadWrite6LeaseRemove) {
Lease6Storage storage;
ASSERT_NO_THROW(LeaseFileLoader::load<Lease6>(*lf, storage, 10));
+ // We should have made 5 attempts to read, with 4 leases read and 0 error
+ {
+ SCOPED_TRACE("Read leases");
+ checkStats(*lf, 5, 4, 0, 0, 0, 0);
+ }
+
// There should be only one lease for 2001:db8:2::10. The other one
// should have been deleted (or rather not loaded).
ASSERT_EQ(1, storage.size());
@@ -333,32 +415,34 @@ TEST_F(LeaseFileLoaderTest, loadWrite6LeaseRemove) {
ASSERT_TRUE(lease);
EXPECT_EQ(500, lease->cltt_);
- writeLeases<Lease6, CSVLeaseFile6, Lease6Storage>
- (*lf, storage,
- "address,duid,valid_lifetime,expire,subnet_id,"
- "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
- "fqdn_rev,hostname,hwaddr\n"
- "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,300,800,6,150,"
- "0,8,0,0,0,,\n");
+ test_str = v6_hdr_ + b_2;
+ writeLeases<Lease6, CSVLeaseFile6, Lease6Storage>(*lf, storage, test_str);
+
+ // We should have made 1 attempts to write, with 1 leases written and 0 errors
+ {
+ SCOPED_TRACE("Write leases");
+ checkStats(*lf, 0, 0, 0, 1, 1, 0);
+ }
}
// This test verifies that the exception is thrown when the specific
// number of errors in the test data occur during reading of the lease
// file.
TEST_F(LeaseFileLoaderTest, loadMaxErrors) {
+ std::string test_str;
+ std::string a_1 = "192.0.2.1,06:07:08:09:0a:bc,,"
+ "200,200,8,1,1,host.example.com\n";
+ std::string a_2 = "192.0.2.1,06:07:08:09:0a:bc,,"
+ "200,500,8,1,1,host.example.com\n";
+
+ std::string b_1 = "192.0.2.3,,a:11:01:04,200,200,8,1,1,host.example.com\n";
+
+ std::string c_1 = "192.0.2.10,01:02:03:04:05:06,,200,300,8,1,1,\n";
+
// Create a lease file for which there is a number of invalid
- // entries.
- io_.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
- "fqdn_fwd,fqdn_rev,hostname\n"
- "192.0.2.1,06:07:08:09:0a:bc,,200,200,8,1,1,"
- "host.example.com\n"
- "192.0.2.3,,a:11:01:04,200,200,8,1,1,host.example.com\n"
- "192.0.2.3,,a:11:01:04,200,200,8,1,1,host.example.com\n"
- "192.0.2.10,01:02:03:04:05:06,,200,300,8,1,1,,\n"
- "192.0.2.3,,a:11:01:04,200,200,8,1,1,host.example.com\n"
- "192.0.2.3,,a:11:01:04,200,200,8,1,1,host.example.com\n"
- "192.0.2.1,06:07:08:09:0a:bc,,200,500,8,1,1,"
- "host.example.com\n");
+ // entries. b_1 is invalid and gets used multiple times.
+ test_str = v4_hdr_ + a_1 + b_1 + b_1 + c_1 + b_1 + b_1 + a_2;
+ io_.writeFile(test_str);
boost::scoped_ptr<CSVLeaseFile4> lf(new CSVLeaseFile4(filename_));
ASSERT_NO_THROW(lf->open());
@@ -369,6 +453,12 @@ TEST_F(LeaseFileLoaderTest, loadMaxErrors) {
ASSERT_THROW(LeaseFileLoader::load<Lease4>(*lf, storage, 3),
util::CSVFileError);
+ // We should have made 6 attempts to read, with 2 leases read and 4 error
+ {
+ SCOPED_TRACE("Read leases 1");
+ checkStats(*lf, 6, 2, 4, 0, 0, 0);
+ }
+
lf->close();
ASSERT_NO_THROW(lf->open());
@@ -377,6 +467,12 @@ TEST_F(LeaseFileLoaderTest, loadMaxErrors) {
storage.clear();
ASSERT_NO_THROW(LeaseFileLoader::load<Lease4>(*lf, storage, 4));
+ // We should have made 8 attempts to read, with 3 leases read and 4 error
+ {
+ SCOPED_TRACE("Read leases 2");
+ checkStats(*lf, 8, 3, 4, 0, 0, 0);
+ }
+
ASSERT_EQ(2, storage.size());
Lease4Ptr lease = getLease<Lease4Ptr>("192.0.2.1", storage);
@@ -386,6 +482,15 @@ TEST_F(LeaseFileLoaderTest, loadMaxErrors) {
lease = getLease<Lease4Ptr>("192.0.2.10", storage);
ASSERT_TRUE(lease);
EXPECT_EQ(100, lease->cltt_);
+
+ test_str = v4_hdr_ + a_2 + c_1;
+ writeLeases<Lease4, CSVLeaseFile4, Lease4Storage>(*lf, storage, test_str);
+
+ // We should have made 1 attempts to write, with 1 leases written and 0 errors
+ {
+ SCOPED_TRACE("Write leases");
+ checkStats(*lf, 0, 0, 0, 2, 2, 0);
+ }
}
// This test verifies that the lease with a valid lifetime set to 0 is
@@ -395,11 +500,13 @@ TEST_F(LeaseFileLoaderTest, loadMaxErrors) {
// It also tests the write function by writing the storage to a file
// and comparing that with the expected value.
TEST_F(LeaseFileLoaderTest, loadWriteLeaseWithZeroLifetime) {
+ std::string test_str;
+ std::string a_1 = "192.0.2.1,06:07:08:09:0a:bc,,200,200,8,1,1,\n";
+ std::string b_2 = "192.0.2.3,06:07:08:09:0a:bd,,0,200,8,1,1,\n";
+
// Create lease file. The second lease has a valid lifetime of 0.
- io_.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
- "fqdn_fwd,fqdn_rev,hostname\n"
- "192.0.2.1,06:07:08:09:0a:bc,,200,200,8,1,1,,\n"
- "192.0.2.3,06:07:08:09:0a:bd,,0,200,8,1,1,,\n");
+ test_str = v4_hdr_ + a_1 + b_2;
+ io_.writeFile(test_str);
boost::scoped_ptr<CSVLeaseFile4> lf(new CSVLeaseFile4(filename_));
ASSERT_NO_THROW(lf->open());
@@ -409,6 +516,12 @@ TEST_F(LeaseFileLoaderTest, loadWriteLeaseWithZeroLifetime) {
Lease4Storage storage;
ASSERT_NO_THROW(LeaseFileLoader::load<Lease4>(*lf, storage, 0));
+ // We should have made 3 attempts to read, with 2 leases read and 0 error
+ {
+ SCOPED_TRACE("Read leases");
+ checkStats(*lf, 3, 2, 0, 0, 0, 0);
+ }
+
// The first lease should be present.
Lease4Ptr lease = getLease<Lease4Ptr>("192.0.2.1", storage);
ASSERT_TRUE(lease);
@@ -417,12 +530,13 @@ TEST_F(LeaseFileLoaderTest, loadWriteLeaseWithZeroLifetime) {
// The lease with a valid lifetime of 0 should not be loaded.
EXPECT_FALSE(getLease<Lease4Ptr>("192.0.2.3", storage));
- writeLeases<Lease4, CSVLeaseFile4, Lease4Storage>
- (*lf, storage,
- "address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
- "fqdn_fwd,fqdn_rev,hostname\n"
- "192.0.2.1,06:07:08:09:0a:bc,,200,200,8,1,1,\n");
-}
-
+ test_str = v4_hdr_ + a_1;
+ writeLeases<Lease4, CSVLeaseFile4, Lease4Storage>(*lf, storage, test_str);
+ // We should have made 1 attempts to write, with 1 leases written and 0 errors
+ {
+ SCOPED_TRACE("Write leases");
+ checkStats(*lf, 0, 0, 0, 1, 1, 0);
+ }
+}
} // end of anonymous namespace
diff --git a/src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc
index ad4b34994c..13b015caf4 100644
--- a/src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc
+++ b/src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc
@@ -456,17 +456,19 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCleanup4) {
"192.0.2.45,00:00:00:00:00:00,,100,100,1,0,0,\n";
EXPECT_EQ(updated_file_contents, current_file.readFile());
- /// @todo Replace the following with the checks that the LFC has
- /// completed successfully, i.e. the leasefile4_0.csv.2 exists
- /// and it holds the cleaned up lease information.
-
- // Until the kea-lfc is implemented and performs the cleanup, we can
- // only check that the backend has moved the lease file to a lease
- // file with suffix ".1".
- LeaseFileIO input_file(getLeaseFilePath("leasefile4_0.csv.1"), false);
+ // This string contains the contents of the lease file we
+ // expect after the LFC run. It has two leases with one
+ // entry each.
+ std::string result_file_contents = new_file_contents +
+ "192.0.2.2,02:02:02:02:02:02,,200,800,8,1,1,\n"
+ "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,\n";
+
+ // The LFC should have created a file with the two leases and moved it
+ // to leasefile4_0.csv.2
+ LeaseFileIO input_file(getLeaseFilePath("leasefile4_0.csv.2"), false);
ASSERT_TRUE(input_file.exists());
- // And this file should contain the contents of the original file.
- EXPECT_EQ(current_file_contents, input_file.readFile());
+ // And this file should contain the contents of the result file.
+ EXPECT_EQ(result_file_contents, input_file.readFile());
}
// This test that the callback function executing the cleanup of the
@@ -537,17 +539,21 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCleanup6) {
"400,2,300,0,123,128,0,0,,\n";
EXPECT_EQ(update_file_contents, current_file.readFile());
- /// @todo Replace the following with the checks that the LFC has
- /// completed successfully, i.e. the leasefile6_0.csv.2 exists
- /// and it holds the cleaned up lease information.
+ // This string contains the contents of the lease file we
+ // expect after the LFC run. It has two leases with one
+ // entry each.
+ std::string result_file_contents = new_file_contents +
+ "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
+ "8,100,0,7,0,1,1,,\n"
+ "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
+ "8,100,0,7,0,1,1,,\n";
- // Until the kea-lfc is implemented and performs the cleanup, we can
- // only check that the backend has moved the lease file to a lease
- // file with suffix ".1".
- LeaseFileIO input_file(getLeaseFilePath("leasefile6_0.csv.1"), false);
+ // The LFC should have created a file with the two leases and moved it
+ // to leasefile6_0.csv.2
+ LeaseFileIO input_file(getLeaseFilePath("leasefile6_0.csv.2"), false);
ASSERT_TRUE(input_file.exists());
- // And this file should contain the contents of the original file.
- EXPECT_EQ(current_file_contents, input_file.readFile());
+ // And this file should contain the contents of the result file.
+ EXPECT_EQ(result_file_contents, input_file.readFile());
}
// This test verifies that EXIT_FAILURE status code is returned when
diff --git a/src/lib/util/csv_file.h b/src/lib/util/csv_file.h
index 3296349d84..d2474cb7fd 100644
--- a/src/lib/util/csv_file.h
+++ b/src/lib/util/csv_file.h
@@ -395,7 +395,8 @@ public:
/// output file pointer should be set at the end of file.
///
/// @throw CSVFileError when IO operation fails.
- void open(const bool seek_to_end = false);
+
+ virtual void open(const bool seek_to_end = false);
/// @brief Creates a new CSV file.
///