diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/dhcpsrv/Makefile.am | 1 | ||||
-rw-r--r-- | src/lib/dhcpsrv/csv_lease_file4.cc | 41 | ||||
-rw-r--r-- | src/lib/dhcpsrv/csv_lease_file4.h | 16 | ||||
-rw-r--r-- | src/lib/dhcpsrv/csv_lease_file6.cc | 37 | ||||
-rw-r--r-- | src/lib/dhcpsrv/csv_lease_file6.h | 16 | ||||
-rw-r--r-- | src/lib/dhcpsrv/lease_file_loader.h | 4 | ||||
-rw-r--r-- | src/lib/dhcpsrv/lease_file_stats.h | 102 | ||||
-rw-r--r-- | src/lib/dhcpsrv/tests/csv_lease_file4_unittest.cc | 68 | ||||
-rw-r--r-- | src/lib/dhcpsrv/tests/csv_lease_file6_unittest.cc | 77 | ||||
-rw-r--r-- | src/lib/dhcpsrv/tests/lease_file_loader_unittest.cc | 320 | ||||
-rw-r--r-- | src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc | 44 | ||||
-rw-r--r-- | src/lib/util/csv_file.h | 3 |
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. /// |