From: Marcin Siodelski Date: Thu, 3 Apr 2014 12:01:03 +0000 (+0200) Subject: [master] Merge branch 'trac3360' X-Git-Tag: bind10-1.2.0rc1-release~14 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=09e6e71abf8bc693e389ebd262fd149b43c1f1d4;p=thirdparty%2Fkea.git [master] Merge branch 'trac3360' Conflicts: doc/guide/bind10-guide.xml --- 09e6e71abf8bc693e389ebd262fd149b43c1f1d4 diff --cc doc/guide/bind10-guide.xml index d73dda320e,aef7fbc2d0..c59ac29bd5 --- a/doc/guide/bind10-guide.xml +++ b/doc/guide/bind10-guide.xml @@@ -3836,18 -3711,44 +3836,52 @@@ Dhcp4/dhcp-ddns/qualifying-suffix "exam
+ Default storage for leases + + The server is able to store lease data in different repositories. Larger deployments + may elect to store leases in a database. + describes one way to do it. + By default, the server will use a CSV file rather than a database to store + lease information. One of the advantages of using a file is that it eliminates + dependency on third party database software. + + + The configuration of the file backend (Memfile) + is controlled through the Dhcp4/lease-database parameters. When default + parameters are used, the Memfile backend will write leases to a disk in the + [bind10-install-dir]/var/bind10/kea-leases4.csv. + + + It is possible to alter the default location of the lease file. The following + configuration: + + > config set Dhcp4/lease-database/type "memfile" + > config set Dhcp4/lease-database/persist true + > config set Dhcp4/lease-database/name "/tmp/kea-leases4.csv" + > config commit + + will change the default location of the lease file to /tmp/kea-leases4.csv. + + + The "persist" parameter controls whether the leases are written to disk. + It is strongly recommended that this parameter is set to "true" at all times + during the normal operation of the server + +
+ +
Database Configuration - All leases issued by the server are stored in the lease database. Currently, - the only supported database is MySQL and so the server must be configured to + All leases issued by the server are stored in the lease database. Currently - there are 3 database backends available: MySQL, PostgreSQL and experimental memfile. ++ there are 3 database backends available: MySQL, PostgreSQL and memfile. + + + The server comes with an in-memory database ("memfile") configured as the default + database. This is used for internal testing and is not supported. In addition, + it does not store lease information on disk: lease information will be lost if the + server is restarted. + + , and so the server must be configured to access the correct database with the appropriate credentials. @@@ -5313,18 -4902,44 +5347,52 @@@ Dhcp6/dhcp-ddns/qualifying-suffix "ex
+ Default storage for leases + + The server is able to store lease data in different repositories. Larger deployments + may elect to store leases in a database. - describes one way to do it. ++ describes one way to do it. + By default, the server will use a CSV file rather than a database to store + lease information. One of the advantages of using a file is that it eliminates + dependency on third party database software. + + + The configuration of the file backend (Memfile) + is controlled through the Dhcp6/lease-database parameters. When default + parameters are left, the Memfile backend will write leases to a disk in the + [bind10-install-dir]/var/bind10/kea-leases6.csv. + + + It is possible to alter the default location of the lease file. The following + configuration: + + > config set Dhcp4/lease-database/type "memfile" + > config set Dhcp4/lease-database/persist true + > config set Dhcp4/lease-database/leasefile "/tmp/kea-leases6.csv" + > config commit + + will change the default location of the lease file to /tmp/kea-leases6.csv. + + + The "persist" parameter controls whether the leases are written to disk. + It is strongly recommended that this parameter is set to "true" at all times + during the normal operation of the server. + +
+ +
Database Configuration - All leases issued by the server are stored in the lease database. Currently, - the only supported database is MySQL, and so the server must be configured to + All leases issued by the server are stored in the lease database. Currently - there are 3 database backends available: MySQL, PostgreSQL and experimental memfile. ++ there are 3 database backends available: MySQL, PostgreSQL and memfile. + + + The server comes with an in-memory database ("memfile") configured as the default + database. This is used for internal testing and is not supported. In addition, + it does not store lease information on disk: lease information will be lost if the + server is restarted. + + , and so the server must be configured to access the correct database with the appropriate credentials. diff --cc src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc index 653b8437b2,0000000000..1744bd2255 mode 100644,000000..100644 --- a/src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc @@@ -1,456 -1,0 +1,459 @@@ +// 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 + +#include +#include +#include +#include +#include +#include + + +#include + +#include +#include +#include +#include +#include + +using namespace isc; +using namespace isc::asiolink; +using namespace isc::dhcp; +using namespace isc::dhcp::test; +using namespace std; + +namespace { + +// This holds statements to create and destroy the schema. +#include "schema_pgsql_copy.h" + +// Connection strings. +// Database: keatest +// Host: localhost +// Username: keatest +// Password: keatest +const char* VALID_TYPE = "type=postgresql"; +const char* INVALID_TYPE = "type=unknown"; +const char* VALID_NAME = "name=keatest"; +const char* INVALID_NAME = "name=invalidname"; +const char* VALID_HOST = "host=localhost"; +const char* INVALID_HOST = "host=invalidhost"; +const char* VALID_USER = "user=keatest"; +const char* INVALID_USER = "user=invaliduser"; +const char* VALID_PASSWORD = "password=keatest"; +const char* INVALID_PASSWORD = "password=invalid"; + +// Given a combination of strings above, produce a connection string. +string connectionString(const char* type, const char* name, const char* host, + const char* user, const char* password) { + const string space = " "; + string result = ""; + + if (type != NULL) { + result += string(type); + } + if (name != NULL) { + if (! result.empty()) { + result += space; + } + result += string(name); + } + + if (host != NULL) { + if (! result.empty()) { + result += space; + } + result += string(host); + } + + if (user != NULL) { + if (! result.empty()) { + result += space; + } + result += string(user); + } + + if (password != NULL) { + if (! result.empty()) { + result += space; + } + result += string(password); + } + + return (result); +} + +// Return valid connection string +string +validConnectionString() { + return (connectionString(VALID_TYPE, VALID_NAME, VALID_HOST, + VALID_USER, VALID_PASSWORD)); +} + +// @brief Clear everything from the database +// +// There is no error checking in this code: if something fails, one of the +// tests will (should) fall over. +void destroySchema() { + // Open database + PGconn * conn = 0; + conn = PQconnectdb("host = 'localhost' user = 'keatest'" + " password = 'keatest' dbname = 'keatest'"); + + PGresult * r; + // Get rid of everything in it. + for (int i = 0; destroy_statement[i] != NULL; ++i) { + r = PQexec(conn, destroy_statement[i]); + PQclear(r); + } + + PQfinish(conn); +} + +// @brief Create the Schema +// +// Creates all the tables in what is assumed to be an empty database. +// +// There is no error checking in this code: if it fails, one of the tests +// will fall over. +void createSchema() { + // Open database + PGconn * conn = 0; + conn = PQconnectdb("host = 'localhost' user = 'keatest'" + " password = 'keatest' dbname = 'keatest'"); + + PGresult * r; + // Get rid of everything in it. + for (int i = 0; create_statement[i] != NULL; ++i) { + r = PQexec(conn, create_statement[i]); + PQclear(r); + } + + PQfinish(conn); +} + +/// @brief Test fixture class for testing PostgreSQL Lease Manager +/// +/// Opens the database prior to each test and closes it afterwards. +/// All pending transactions are deleted prior to closure. + +class PgSqlLeaseMgrTest : public GenericLeaseMgrTest { +public: + /// @brief Constructor + /// + /// Deletes everything from the database and opens it. + PgSqlLeaseMgrTest() { + + // Ensure schema is the correct one. + destroySchema(); + createSchema(); + + // Connect to the database + try { + LeaseMgrFactory::create(validConnectionString()); + } catch (...) { + std::cerr << "*** ERROR: unable to open database. The test\n" + "*** environment is broken and must be fixed before\n" + "*** the PostgreSQL tests will run correctly.\n" + "*** The reason for the problem is described in the\n" + "*** accompanying exception output.\n"; + throw; + } + lmptr_ = &(LeaseMgrFactory::instance()); + } + + /// @brief Destructor + /// + /// Rolls back all pending transactions. The deletion of lmptr_ will close + /// the database. Then reopen it and delete everything created by the test. + virtual ~PgSqlLeaseMgrTest() { + lmptr_->rollback(); + LeaseMgrFactory::destroy(); + destroySchema(); + } + + /// @brief Reopen the database + /// + /// Closes the database and re-open it. Anything committed should be + /// visible. - void reopen() { ++ /// ++ /// Parameter is ignored for Postgres abckend as the v4 and v6 leases share ++ /// the same database. ++ void reopen(Universe) { + LeaseMgrFactory::destroy(); + LeaseMgrFactory::create(validConnectionString()); + lmptr_ = &(LeaseMgrFactory::instance()); + } + +}; + +/// @brief Check that database can be opened +/// +/// This test checks if the PgSqlLeaseMgr can be instantiated. This happens +/// only if the database can be opened. Note that this is not part of the +/// PgSqlLeaseMgr test fixure set. This test checks that the database can be +/// opened: the fixtures assume that and check basic operations. + +TEST(PgSqlOpenTest, OpenDatabase) { + + // Schema needs to be created for the test to work. + destroySchema(); + createSchema(); + + // Check that lease manager open the database opens correctly and tidy up. + // If it fails, print the error message. + try { + LeaseMgrFactory::create(validConnectionString()); + EXPECT_NO_THROW((void) LeaseMgrFactory::instance()); + LeaseMgrFactory::destroy(); + } catch (const isc::Exception& ex) { + FAIL() << "*** ERROR: unable to open database, reason:\n" + << " " << ex.what() << "\n" + << "*** The test environment is broken and must be fixed\n" + << "*** before the PostgreSQL tests will run correctly.\n"; + } + // Check that attempting to get an instance of the lease manager when + // none is set throws an exception. + EXPECT_THROW(LeaseMgrFactory::instance(), NoLeaseManager); + + // Check that wrong specification of backend throws an exception. + // (This is really a check on LeaseMgrFactory, but is convenient to + // perform here.) + EXPECT_THROW(LeaseMgrFactory::create(connectionString( + NULL, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)), + InvalidParameter); + + EXPECT_THROW(LeaseMgrFactory::create(connectionString( + INVALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)), + InvalidType); + + // Check that invalid login data causes an exception. + EXPECT_THROW(LeaseMgrFactory::create(connectionString( + VALID_TYPE, INVALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)), + DbOpenError); + + EXPECT_THROW(LeaseMgrFactory::create(connectionString( + VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)), + DbOpenError); + + EXPECT_THROW(LeaseMgrFactory::create(connectionString( + VALID_TYPE, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)), + DbOpenError); + + EXPECT_THROW(LeaseMgrFactory::create(connectionString( + VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_PASSWORD)), + DbOpenError); + + // Check for missing parameters + EXPECT_THROW(LeaseMgrFactory::create(connectionString( + VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)), + NoDatabaseName); + + // Tidy up after the test + destroySchema(); +} + +/// @brief Check the getType() method +/// +/// getType() returns a string giving the type of the backend, which should +/// always be "postgresql". +TEST_F(PgSqlLeaseMgrTest, getType) { + EXPECT_EQ(std::string("postgresql"), lmptr_->getType()); +} + +/// @brief Check getName() returns correct database name +TEST_F(PgSqlLeaseMgrTest, getName) { + EXPECT_EQ(std::string("keatest"), lmptr_->getName()); +} + +/// @brief Check that getVersion() returns the expected version +TEST_F(PgSqlLeaseMgrTest, checkVersion) { + // Check version + pair version; + ASSERT_NO_THROW(version = lmptr_->getVersion()); + EXPECT_EQ(PG_CURRENT_VERSION, version.first); + EXPECT_EQ(PG_CURRENT_MINOR, version.second); +} + +//////////////////////////////////////////////////////////////////////////////// +/// LEASE4 ///////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +/// @brief Basic Lease4 Checks +/// +/// Checks that the addLease, getLease4 (by address) and deleteLease (with an +/// IPv4 address) works. +TEST_F(PgSqlLeaseMgrTest, basicLease4) { + testBasicLease4(); +} + +/// @brief Lease4 update tests +/// +/// Checks that we are able to update a lease in the database. +TEST_F(PgSqlLeaseMgrTest, updateLease4) { + testUpdateLease4(); +} + +/// @brief Check GetLease4 methods - access by Hardware Address +TEST_F(PgSqlLeaseMgrTest, getLease4HWAddr1) { + testGetLease4HWAddr1(); +} + +/// @brief Check GetLease4 methods - access by Hardware Address +TEST_F(PgSqlLeaseMgrTest, getLease4HWAddr2) { + testGetLease4HWAddr2(); +} + +// @brief Get lease4 by hardware address (2) +// +// Check that the system can cope with getting a hardware address of +// any size. +TEST_F(PgSqlLeaseMgrTest, getLease4HWAddrSize) { + testGetLease4HWAddrSize(); +} + +/// @brief Check GetLease4 methods - access by Hardware Address & Subnet ID +/// +/// Adds leases to the database and checks that they can be accessed via +/// a combination of hardware address and subnet ID +TEST_F(PgSqlLeaseMgrTest, getLease4HwaddrSubnetId) { + testGetLease4HWAddrSubnetId(); +} + +// @brief Get lease4 by hardware address and subnet ID (2) +// +// Check that the system can cope with getting a hardware address of +// any size. +TEST_F(PgSqlLeaseMgrTest, getLease4HWAddrSubnetIdSize) { + testGetLease4HWAddrSubnetIdSize(); +} + +// This test was derived from memfile. +TEST_F(PgSqlLeaseMgrTest, getLease4ClientId) { + testGetLease4ClientId(); +} + +/// @brief Check GetLease4 methods - access by Client ID +/// +/// Adds leases to the database and checks that they can be accessed via +/// the Client ID. +TEST_F(PgSqlLeaseMgrTest, getLease4ClientId2) { + testGetLease4ClientId2(); +} + +// @brief Get Lease4 by client ID (2) +// +// Check that the system can cope with a client ID of any size. +TEST_F(PgSqlLeaseMgrTest, getLease4ClientIdSize) { + testGetLease4ClientIdSize(); +} + +/// @brief Check GetLease4 methods - access by Client ID & Subnet ID +/// +/// Adds leases to the database and checks that they can be accessed via +/// a combination of client and subnet IDs. +TEST_F(PgSqlLeaseMgrTest, getLease4ClientIdSubnetId) { + testGetLease4ClientIdSubnetId(); +} + +/// @brief Basic Lease4 Checks +/// +/// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id), +/// updateLease4() and deleteLease (IPv4 address) can handle NULL client-id. +/// (client-id is optional and may not be present) +TEST_F(PgSqlLeaseMgrTest, lease4NullClientId) { + testLease4NullClientId(); +} + +/// @brief Verify that too long hostname for Lease4 is not accepted. +/// +/// Checks that the it is not possible to create a lease when the hostname +/// length exceeds 255 characters. +TEST_F(PgSqlLeaseMgrTest, lease4InvalidHostname) { + testLease4InvalidHostname(); +} + +//////////////////////////////////////////////////////////////////////////////// +/// LEASE6 ///////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +// Test checks whether simple add, get and delete operations are possible +// on Lease6 +TEST_F(PgSqlLeaseMgrTest, testAddGetDelete6) { + testAddGetDelete6(false); +} + +/// @brief Basic Lease6 Checks +/// +/// Checks that the addLease, getLease6 (by address) and deleteLease (with an +/// IPv6 address) works. +TEST_F(PgSqlLeaseMgrTest, basicLease6) { + testBasicLease6(); +} + +/// @brief Verify that too long hostname for Lease6 is not accepted. +/// +/// Checks that the it is not possible to create a lease when the hostname +/// length exceeds 255 characters. +TEST_F(PgSqlLeaseMgrTest, lease6InvalidHostname) { + testLease6InvalidHostname(); +} + +/// @brief Check GetLease6 methods - access by DUID/IAID +/// +/// Adds leases to the database and checks that they can be accessed via +/// a combination of DUID and IAID. +TEST_F(PgSqlLeaseMgrTest, getLeases6DuidIaid) { + testGetLeases6DuidIaid(); +} + +// Check that the system can cope with a DUID of allowed size. +TEST_F(PgSqlLeaseMgrTest, getLeases6DuidSize) { + testGetLeases6DuidSize(); +} + +/// @brief Check that getLease6 methods discriminate by lease type. +/// +/// Adds six leases, two per lease type all with the same duid and iad but +/// with alternating subnet_ids. +/// It then verifies that all of getLeases6() method variants correctly +/// discriminate between the leases based on lease type alone. +TEST_F(PgSqlLeaseMgrTest, lease6LeaseTypeCheck) { + testLease6LeaseTypeCheck(); +} + +/// @brief Check GetLease6 methods - access by DUID/IAID/SubnetID +/// +/// Adds leases to the database and checks that they can be accessed via +/// a combination of DIUID and IAID. +TEST_F(PgSqlLeaseMgrTest, getLease6DuidIaidSubnetId) { + testGetLease6DuidIaidSubnetId(); +} + +// Test checks that getLease6() works with different DUID sizes +TEST_F(PgSqlLeaseMgrTest, getLease6DuidIaidSubnetIdSize) { + testGetLease6DuidIaidSubnetIdSize(); +} + +/// @brief Lease6 update tests +/// +/// Checks that we are able to update a lease in the database. +TEST_F(PgSqlLeaseMgrTest, updateLease6) { + testUpdateLease6(); +} + +};