csv_lease_file6_unittest.cc 8.17 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// Copyright (C) 2014 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.

#include <config.h>
#include <asiolink/io_address.h>
17
#include <dhcp/duid.h>
18 19 20 21
#include <dhcpsrv/csv_lease_file6.h>
#include <dhcpsrv/lease.h>
#include <dhcpsrv/tests/lease_file_io.h>
#include <boost/scoped_ptr.hpp>
22
#include <boost/shared_ptr.hpp>
23 24 25 26 27 28 29 30 31 32 33
#include <gtest/gtest.h>
#include <sstream>

using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
using namespace isc::util;

namespace {

34
// DUID values used by unit tests.
35 36 37
const uint8_t DUID0[] = { 0, 1, 2, 3, 4, 5, 6, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf };
const uint8_t DUID1[] = { 1, 1, 1, 1, 0xa, 1, 2, 3, 4, 5 };

38
/// @brief Test fixture class for @c CSVLeaseFile6 validation.
39 40 41
class CSVLeaseFile6Test : public ::testing::Test {
public:

42 43 44
    /// @brief Constructor.
    ///
    /// Initializes IO for lease file used by unit tests.
45 46 47 48 49 50 51 52 53
    CSVLeaseFile6Test();

    /// @brief Prepends the absolute path to the file specified
    /// as an argument.
    ///
    /// @param filename Name of the file.
    /// @return Absolute path to the test file.
    static std::string absolutePath(const std::string& filename);

54 55 56 57 58
    /// @brief Create DUID object from the binary.
    ///
    /// @param duid Binary value representing a DUID.
    /// @param size Size of the DUID.
    /// @return Pointer to the @c DUID object.
59 60 61 62
    DuidPtr makeDUID(const uint8_t* duid, const unsigned int size) const {
        return (DuidPtr(new DUID(duid, size)));
    }

63 64 65
    /// @brief Create lease file that can be parsed by unit tests.
    void writeSampleFile() const;

66
    /// @brief Name of the test lease file.
67
    std::string filename_;
68 69

    /// @brief Object providing access to lease file IO.
70 71 72 73 74 75 76 77 78 79 80
    LeaseFileIO io_;

};

CSVLeaseFile6Test::CSVLeaseFile6Test()
    : filename_(absolutePath("leases6.csv")), io_(filename_) {
}

std::string
CSVLeaseFile6Test::absolutePath(const std::string& filename) {
    std::ostringstream s;
81
    s << DHCP_DATA_DIR << "/" << filename;
82 83 84
    return (s.str());
}

85 86 87 88 89 90 91 92 93 94 95 96 97 98
void
CSVLeaseFile6Test::writeSampleFile() const {
    io_.writeFile("address,duid,valid_lifetime,expire,subnet_id,"
                  "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
                  "fqdn_rev,hostname\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,0,200,8,0,2,"
                  "16,64,0,0,\n");
}

99
// This test checks the capability to read and parse leases from the file.
100
TEST_F(CSVLeaseFile6Test, parse) {
101 102 103
    // Create a file to be parsed.
    writeSampleFile();

104
    // Open the lease file.
105
    boost::scoped_ptr<CSVLeaseFile6> lf(new CSVLeaseFile6(filename_));
106 107 108
    ASSERT_NO_THROW(lf->open());

    Lease6Ptr lease;
109 110
    // Reading first read should be successful.
    EXPECT_TRUE(lf->next(lease));
111
    ASSERT_TRUE(lease);
112 113

    // Verify that the lease attributes are correct.
114 115 116 117 118 119 120 121 122 123 124 125 126 127
    EXPECT_EQ("2001:db8:1::1", lease->addr_.toText());
    ASSERT_TRUE(lease->duid_);
    EXPECT_EQ("00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f", lease->duid_->toText());
    EXPECT_EQ(200, lease->valid_lft_);
    EXPECT_EQ(0, lease->cltt_);
    EXPECT_EQ(8, lease->subnet_id_);
    EXPECT_EQ(100, lease->preferred_lft_);
    EXPECT_EQ(Lease::TYPE_NA, lease->type_);
    EXPECT_EQ(7, lease->iaid_);
    EXPECT_EQ(0, lease->prefixlen_);
    EXPECT_TRUE(lease->fqdn_fwd_);
    EXPECT_TRUE(lease->fqdn_rev_);
    EXPECT_EQ("host.example.com", lease->hostname_);

128 129
    // Second lease is malformed - DUID is empty.
    EXPECT_FALSE(lf->next(lease));
130

131 132 133
    // Even, parsing previous lease failed, reading the next lease should be
    // successful.
    EXPECT_TRUE(lf->next(lease));
134
    ASSERT_TRUE(lease);
135
    // Verify that the third lease is correct.
136 137 138 139 140 141 142 143 144 145 146 147 148 149
    EXPECT_EQ("2001:db8:2::10", lease->addr_.toText());
    ASSERT_TRUE(lease->duid_);
    EXPECT_EQ("01:01:01:01:0a:01:02:03:04:05", lease->duid_->toText());
    EXPECT_EQ(300, lease->valid_lft_);
    EXPECT_EQ(0, lease->cltt_);
    EXPECT_EQ(6, lease->subnet_id_);
    EXPECT_EQ(150, lease->preferred_lft_);
    EXPECT_EQ(Lease::TYPE_NA, lease->type_);
    EXPECT_EQ(8, lease->iaid_);
    EXPECT_EQ(0, lease->prefixlen_);
    EXPECT_FALSE(lease->fqdn_fwd_);
    EXPECT_FALSE(lease->fqdn_rev_);
    EXPECT_TRUE(lease->hostname_.empty());

150
    // Reading the fourth lease should be successful.
151
    EXPECT_TRUE(lf->next(lease));
152
    ASSERT_TRUE(lease);
153
    // Verify that the lease is correct.
154 155 156 157 158 159 160 161 162 163 164 165 166 167
    EXPECT_EQ("3000:1::", lease->addr_.toText());
    ASSERT_TRUE(lease->duid_);
    EXPECT_EQ("00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f", lease->duid_->toText());
    EXPECT_EQ(0, lease->valid_lft_);
    EXPECT_EQ(200, lease->cltt_);
    EXPECT_EQ(8, lease->subnet_id_);
    EXPECT_EQ(0, lease->preferred_lft_);
    EXPECT_EQ(Lease::TYPE_PD, lease->type_);
    EXPECT_EQ(16, lease->iaid_);
    EXPECT_EQ(64, lease->prefixlen_);
    EXPECT_FALSE(lease->fqdn_fwd_);
    EXPECT_FALSE(lease->fqdn_rev_);
    EXPECT_TRUE(lease->hostname_.empty());

168 169 170
    // There are no more leases. Reading should cause no error, but the returned
    // lease pointer should be NULL.
    EXPECT_TRUE(lf->next(lease));
171
    EXPECT_FALSE(lease);
172 173 174 175 176

    // We should be able to do it again.
    EXPECT_TRUE(lf->next(lease));
    EXPECT_FALSE(lease);

177
}
178

179
// This test checks creation of the lease file and writing leases.
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
TEST_F(CSVLeaseFile6Test, recreate) {
    boost::scoped_ptr<CSVLeaseFile6> lf(new CSVLeaseFile6(filename_));
    ASSERT_NO_THROW(lf->recreate());
    ASSERT_TRUE(io_.exists());

    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;
    ASSERT_NO_THROW(lf->append(*lease));

    lease.reset(new Lease6(Lease::TYPE_NA, IOAddress("2001:db8:2::10"),
                           makeDUID(DUID1, sizeof(DUID1)),
                           8, 150, 300, 40, 70, 6, false, false,
                           "", 128));
    lease->cltt_ = 0;
    ASSERT_NO_THROW(lf->append(*lease));

    lease.reset(new Lease6(Lease::TYPE_PD, IOAddress("3000:1:1::"),
                           makeDUID(DUID0, sizeof(DUID0)),
                           7, 150, 300, 40, 70, 10, false, false,
                           "", 64));
    lease->cltt_ = 0;
    ASSERT_NO_THROW(lf->append(*lease));

    EXPECT_EQ("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
              "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname\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,128,0,0,\n"
              "3000:1:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
              "300,300,10,150,2,7,64,0,0,\n",
              io_.readFile());
}

217 218 219 220 221 222
/// @todo Currently we don't check invalid lease attributes, such as invalid
/// lease type, invalid preferred lifetime vs valid lifetime etc. The Lease6
/// should be extended with the function that validates lease attributes. Once
/// this is implemented we should provide more tests for malformed leases
/// in the CSV file. See http://bind10.isc.org/ticket/2405.

223
} // end of anonymous namespace