Commit 8047f978 authored by Thomas Markwalder's avatar Thomas Markwalder
Browse files

[4277] Insert and fetch IPv4 Hosts plus tests work (without options)

src/lib/dhcpsrv/host_data_source_factory.cc
    HostDataSourceFactory::create() - now instantiates PgSqlHostDataSource

src/lib/dhcpsrv/pgsql_host_data_source.cc
    Enabled basic IPv4 host statements and methods

src/lib/dhcpsrv/tests
    New file: pgsql_host_data_source_unittest.cc

src/lib/dhcpsrv/tests/Makefile.am
    Added pgsql_host_data_source_unittest.cc
parent 7e11527e
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -14,6 +14,10 @@
#include <dhcpsrv/mysql_host_data_source.h>
#endif
#ifdef HAVE_PGSQL
#include <dhcpsrv/pgsql_host_data_source.h>
#endif
#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <boost/scoped_ptr.hpp>
......@@ -63,8 +67,10 @@ HostDataSourceFactory::create(const std::string& dbaccess) {
#ifdef HAVE_PGSQL
if (db_type == "postgresql") {
isc_throw(NotImplemented, "Sorry, PostgreSQL backend for host reservations "
"is not implemented yet.");
LOG_INFO(dhcpsrv_logger, DHCPSRV_PGSQL_HOST_DB)
.arg(DatabaseConnection::redactedAccessString(parameters));
getHostDataSourcePtr().reset(new PgSqlHostDataSource(parameters));
return;
}
#endif
......
......@@ -165,11 +165,11 @@ public:
/// None of the fields in the host reservation are modified -
/// the host data is only read.
///
/// @return pointer to newly constructed bind_array containing the
/// @return pointer to newly constructed bind_array containing the
/// bound values extracted from host
///
/// @throw DbOperationError if bind_array cannot be populated.
PsqlBindArrayPtr
PsqlBindArrayPtr
createBindForSend(const HostPtr& host) {
if (!host) {
isc_throw(BadValue, "createBindForSend:: host object is NULL");
......@@ -178,7 +178,7 @@ public:
// Store the host to ensure bound values remain in scope
host_ = host;
// Bind the host data to the array
// Bind the host data to the array
PsqlBindArrayPtr bind_array(new PsqlBindArray());
try {
// host_id : is auto_incremented skip it
......@@ -195,9 +195,9 @@ public:
// dhcp6_subnet_id : INT NULL
bind_array->add(host->getIPv6SubnetID());
// ipv4_address : BIGINT NULL
// ipv4_address : BIGINT NULL
bind_array->add(host->getIPv4Reservation());
// hostname : VARCHAR(255) NULL
bind_array->bindString(host->getHostname());
......@@ -230,7 +230,7 @@ public:
// host_id INT NOT NULL
// @todo going to have to deal with uint64_t versus INT etc...
HostID host_id;
getColumnValue(r, row, HOST_ID_COL, host_id);
getColumnValue(r, row, HOST_ID_COL, host_id);
// dhcp_identifier : BYTEA NOT NULL
uint8_t identifier_value[DHCP_IDENTIFIER_MAX_LEN];
......@@ -250,17 +250,17 @@ public:
static_cast<Host::IdentifierType>(type);
// dhcp4_subnet_id : INT NULL
uint32_t subnet_id;
getColumnValue(r, row, DHCP4_SUBNET_ID_COL, subnet_id);
uint32_t subnet_id;
getColumnValue(r, row, DHCP4_SUBNET_ID_COL, subnet_id);
SubnetID dhcp4_subnet_id = static_cast<SubnetID>(subnet_id);
// dhcp6_subnet_id : INT NULL
getColumnValue(r, row, DHCP6_SUBNET_ID_COL, subnet_id);
getColumnValue(r, row, DHCP6_SUBNET_ID_COL, subnet_id);
SubnetID dhcp6_subnet_id = static_cast<SubnetID>(subnet_id);
// ipv4_address : BIGINT NULL
uint32_t addr4;
getColumnValue(r, row, IPV4_ADDRESS_COL, addr4);
uint32_t addr4;
getColumnValue(r, row, IPV4_ADDRESS_COL, addr4);
isc::asiolink::IOAddress ipv4_reservation(addr4);
// hostname : VARCHAR(255) NULL
......@@ -280,13 +280,13 @@ public:
host.reset(new Host(identifier_value, identifier_len,
identifier_type, dhcp4_subnet_id,
dhcp6_subnet_id, ipv4_reservation, hostname,
dhcp4_client_classes, dhcp6_client_classes));
dhcp4_client_classes, dhcp6_client_classes));
host->setHostId(host_id);
} catch (const isc::Exception& ex) {
isc_throw(DbOperationError, "Could not create host: " << ex.what());
}
return(host);
};
......@@ -1348,10 +1348,12 @@ public:
GET_HOST_DHCPID, // Gets hosts by host identifier
#endif
GET_HOST_ADDR, // Gets hosts by IPv4 address
#if 0
GET_HOST_SUBID4_DHCPID, // Gets host by IPv4 SubnetID, HW address/DUID
#if 0
GET_HOST_SUBID6_DHCPID, // Gets host by IPv6 SubnetID, HW address/DUID
#endif
GET_HOST_SUBID_ADDR, // Gets host by IPv4 SubnetID and IPv4 address
#if 0
GET_HOST_PREFIX, // Gets host by IPv6 prefix
#endif
GET_VERSION, // Obtain version number
......@@ -1373,18 +1375,18 @@ public:
/// @param bind Vector of MYSQL_BIND objects to be used when making the
/// query.
/// @param return_last_id flag indicating whether or not the insert
/// returns the primary key of from the row inserted via " RETURNING
/// returns the primary key of from the row inserted via " RETURNING
/// <primary key> as pid" clause on the INSERT statement. The RETURNING
/// clause causes the INSERT to return a result set that should consist
/// of a single row with one column, the value of the primary key.
/// Defaults to false.
///
/// @returns 0 if return_last_id is false, otherwise it returns the
/// the value in the result set in the first col of the first row.
/// the value in the result set in the first col of the first row.
///
/// @throw isc::dhcp::DuplicateEntry Database throws duplicate entry error
uint64_t addStatement(PgSqlHostDataSourceImpl::StatementIndex stindex,
PsqlBindArrayPtr& bind,
PsqlBindArrayPtr& bind,
const bool return_last_id = false);
#if 0
......@@ -1509,14 +1511,14 @@ public:
/// retrieve hosts from the database.
PgSqlTaggedStatement tagged_statements[] = {
// Inserts a host into the 'hosts' table. Returns the inserted host id.
{PgSqlHostDataSourceImpl::INSERT_HOST,
{ OID_INT8, OID_BYTEA, OID_INT2,
{ 8, // PgSqlHostDataSourceImpl::INSERT_HOST,
{ OID_BYTEA, OID_INT2,
OID_INT4, OID_INT4, OID_INT8, OID_VARCHAR,
OID_VARCHAR, OID_VARCHAR },
"INSERT INTO hosts(host_id, dhcp_identifier, dhcp_identifier_type, "
OID_VARCHAR, OID_VARCHAR }, "insert_host",
"INSERT INTO hosts(dhcp_identifier, dhcp_identifier_type, "
"dhcp4_subnet_id, dhcp6_subnet_id, ipv4_address, hostname, "
"dhcp4_client_classes, dhcp6_client_classes) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING host_id"},
"VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING host_id"},
#if 0
// Inserts a single IPv6 reservation into 'reservations' table.
......@@ -1567,8 +1569,8 @@ PgSqlTaggedStatement tagged_statements[] = {
// Retrieves host information along with the DHCPv4 options associated with
// it. Left joining the dhcp4_options table results in multiple rows being
// returned for the same host. The host is retrieved by IPv4 address.
{PgSqlHostDataSourceImpl::GET_HOST_ADDR,
{ OID_INT8 },
{ 1, // PgSqlHostDataSourceImpl::GET_HOST_ADDR,
{ OID_INT8 }, "get_host_addr",
"SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
"h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
"h.dhcp4_client_classes, h.dhcp6_client_classes, "
......@@ -1576,26 +1578,26 @@ PgSqlTaggedStatement tagged_statements[] = {
"o.persistent "
"FROM hosts AS h "
"LEFT JOIN dhcp4_options AS o ON h.host_id = o.host_id "
"WHERE ipv4_address = ? "
"WHERE ipv4_address = $1 "
"ORDER BY h.host_id, o.option_id"},
#if 0
// Retrieves host information and DHCPv4 options using subnet identifier
// and client's identifier. Left joining the dhcp4_options table results in
// multiple rows being returned for the same host.
{PgSqlHostDataSourceImpl::GET_HOST_SUBID4_DHCPID,
"SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
"h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
"h.dhcp4_client_classes, h.dhcp6_client_classes, "
"o.option_id, o.code, o.value, o.formatted_value, o.space, "
"o.persistent "
"FROM hosts AS h "
"LEFT JOIN dhcp4_options AS o "
"ON h.host_id = o.host_id "
"WHERE h.dhcp4_subnet_id = ? AND h.dhcp_identifier_type = ? "
" AND h.dhcp_identifier = ? "
"ORDER BY h.host_id, o.option_id"},
{ 3, //PgSqlHostDataSourceImpl::GET_HOST_SUBID4_DHCPID,
{ OID_INT4, OID_INT2, OID_BYTEA }, "get_host_subid4_dhcpid",
"SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
"h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
"h.dhcp4_client_classes, h.dhcp6_client_classes, "
"o.option_id, o.code, o.value, o.formatted_value, o.space, "
"o.persistent "
"FROM hosts AS h "
"LEFT JOIN dhcp4_options AS o ON h.host_id = o.host_id "
"WHERE h.dhcp4_subnet_id = $1 AND h.dhcp_identifier_type = $2 "
" AND h.dhcp_identifier = $3 "
"ORDER BY h.host_id, o.option_id"},
#if 0
// Retrieves host information, IPv6 reservations and DHCPv6 options
// associated with a host. The number of rows returned is a multiplication
// of number of IPv6 reservations and DHCPv6 options.
......@@ -1616,22 +1618,24 @@ PgSqlTaggedStatement tagged_statements[] = {
"WHERE h.dhcp6_subnet_id = ? AND h.dhcp_identifier_type = ? "
"AND h.dhcp_identifier = ? "
"ORDER BY h.host_id, o.option_id, r.reservation_id"},
#endif
// Retrieves host information and DHCPv4 options for the host using subnet
// identifier and IPv4 reservation. Left joining the dhcp4_options table
// results in multiple rows being returned for the host. The number of
// rows depends on the number of options defined for the host.
{PgSqlHostDataSourceImpl::GET_HOST_SUBID_ADDR,
"SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
"h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
"h.dhcp4_client_classes, h.dhcp6_client_classes, "
"o.option_id, o.code, o.value, o.formatted_value, o.space, "
"o.persistent "
"FROM hosts AS h "
"LEFT JOIN dhcp4_options AS o "
"ON h.host_id = o.host_id "
"WHERE h.dhcp4_subnet_id = ? AND h.ipv4_address = ? "
"ORDER BY h.host_id, o.option_id"},
{ 2, //PgSqlHostDataSourceImpl::GET_HOST_SUBID_ADDR,
{ OID_INT4, OID_INT8 }, "get_host_subid_addr",
"SELECT h.host_id, h.dhcp_identifier, h.dhcp_identifier_type, "
"h.dhcp4_subnet_id, h.dhcp6_subnet_id, h.ipv4_address, h.hostname, "
"h.dhcp4_client_classes, h.dhcp6_client_classes, "
"o.option_id, o.code, o.value, o.formatted_value, o.space, "
"o.persistent "
"FROM hosts AS h "
"LEFT JOIN dhcp4_options AS o ON h.host_id = o.host_id "
"WHERE h.dhcp4_subnet_id = $1 AND h.ipv4_address = $2 "
"ORDER BY h.host_id, o.option_id"},
#if 0
// Retrieves host information, IPv6 reservations and DHCPv6 options
// associated with a host using prefix and prefix length. This query
......@@ -1660,11 +1664,12 @@ PgSqlTaggedStatement tagged_statements[] = {
#endif
// Retrieves MySQL schema version.
{PgSqlHostDataSourceImpl::GET_VERSION, { OID_NONE },
"SELECT version, minor FROM schema_version"},
{ 0, //PgSqlHostDataSourceImpl::GET_VERSION,
{ OID_NONE }, "get_version",
"SELECT version, minor FROM schema_version"},
// Marks the end of the statements table.
{PgSqlHostDataSourceImpl::NUM_STATEMENTS, { 0 }, NULL, NULL}
{0, { 0 }, NULL, NULL}
};
PgSqlHostDataSourceImpl::
......@@ -1836,12 +1841,12 @@ getHost(const SubnetID& subnet_id,
// Add the subnet id.
bind_array->add(subnet_id);
// Add the identifier value.
bind_array->add(identifier_begin, identifier_len);
// Add the Identifier type.
bind_array->add(static_cast<uint8_t>(identifier_type));
// Add the identifier value.
bind_array->add(identifier_begin, identifier_len);
ConstHostCollection collection;
getHostCollection(stindex, bind_array, exchange, collection, true);
......@@ -1858,7 +1863,7 @@ std::pair<uint32_t, uint32_t> PgSqlHostDataSourceImpl::getVersion() const {
DHCPSRV_PGSQL_HOST_DB_GET_VERSION);
PgSqlResult r(PQexecPrepared(conn_, "get_version", 0, NULL, NULL, NULL, 0));
conn_.checkStatementError(r, tagged_statements[GET_VERSION]);
conn_.checkStatementError(r, tagged_statements[GET_VERSION]);
istringstream tmp;
uint32_t version;
......@@ -2023,16 +2028,6 @@ PgSqlHostDataSource::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
return (ConstHostPtr());
}
#if 1
ConstHostPtr
PgSqlHostDataSource::get4(const SubnetID&,
const Host::IdentifierType&,
const uint8_t*,
const size_t) const {
return (HostPtr());
}
#else
ConstHostPtr
PgSqlHostDataSource::get4(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
......@@ -2040,18 +2035,11 @@ PgSqlHostDataSource::get4(const SubnetID& subnet_id,
const size_t identifier_len) const {
return (impl_->getHost(subnet_id, identifier_type, identifier_begin,
identifier_len, PgSqlHostDataSourceImpl::GET_HOST_SUBID4_DHCPID,
impl_->host_exchange_));
identifier_len,
PgSqlHostDataSourceImpl::GET_HOST_SUBID4_DHCPID,
impl_->host_exchange_));
}
#endif
#if 1
ConstHostPtr
PgSqlHostDataSource::get4(const SubnetID&,
const asiolink::IOAddress&) const {
return(HostPtr());
}
#else
ConstHostPtr
PgSqlHostDataSource::get4(const SubnetID& subnet_id,
const asiolink::IOAddress& address) const {
......@@ -2066,7 +2054,8 @@ PgSqlHostDataSource::get4(const SubnetID& subnet_id,
ConstHostCollection collection;
impl_->getHostCollection(PgSqlHostDataSourceImpl::GET_HOST_SUBID_ADDR,
inbind, impl_->host_exchange_, collection, true);
bind_array, impl_->host_exchange_, collection,
true);
// Return single record if present, else clear the host.
ConstHostPtr result;
......@@ -2075,7 +2064,6 @@ PgSqlHostDataSource::get4(const SubnetID& subnet_id,
return (result);
}
#endif
#if 1
ConstHostPtr
......
......@@ -120,6 +120,7 @@ libdhcpsrv_unittests_SOURCES += ncr_generator_unittest.cc
if HAVE_PGSQL
libdhcpsrv_unittests_SOURCES += pgsql_exchange_unittest.cc
libdhcpsrv_unittests_SOURCES += pgsql_host_data_source_unittest.cc
libdhcpsrv_unittests_SOURCES += pgsql_lease_mgr_unittest.cc
endif
libdhcpsrv_unittests_SOURCES += pool_unittest.cc
......
// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
#include <asiolink/io_address.h>
#include <dhcpsrv/tests/test_utils.h>
#include <exceptions/exceptions.h>
#include <dhcpsrv/host.h>
#include <dhcpsrv/pgsql_connection.h>
#include <dhcpsrv/pgsql_host_data_source.h>
#include <dhcpsrv/tests/generic_host_data_source_unittest.h>
#include <dhcpsrv/testutils/pgsql_schema.h>
#include <dhcpsrv/host_data_source_factory.h>
#include <gtest/gtest.h>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <utility>
using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
using namespace std;
namespace {
class PgSqlHostDataSourceTest : public GenericHostDataSourceTest {
public:
/// @brief Constructor
///
/// Deletes everything from the database and opens it.
PgSqlHostDataSourceTest() {
// Ensure schema is the correct one.
destroyPgSQLSchema();
createPgSQLSchema();
// Connect to the database
try {
HostDataSourceFactory::create(validPgSQLConnectionString());
} 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;
}
hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
}
/// @brief Destructor
///
/// Rolls back all pending transactions. The deletion of myhdsptr_ will close
/// the database. Then reopen it and delete everything created by the test.
virtual ~PgSqlHostDataSourceTest() {
hdsptr_->rollback();
HostDataSourceFactory::destroy();
destroyPgSQLSchema();
}
/// @brief Reopen the database
///
/// Closes the database and re-open it. Anything committed should be
/// visible.
///
/// Parameter is ignored for PostgreSQL backend as the v4 and v6 leases share
/// the same database.
void reopen(Universe) {
HostDataSourceFactory::destroy();
HostDataSourceFactory::create(validPgSQLConnectionString());
hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
}
};
/// @brief Check that database can be opened
///
/// This test checks if the PgSqlHostDataSource 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(PgSqlHostDataSource, OpenDatabase) {
// Schema needs to be created for the test to work.
destroyPgSQLSchema();
createPgSQLSchema();
// Check that lease manager open the database opens correctly and tidy up.
// If it fails, print the error message.
try {
HostDataSourceFactory::create(validPgSQLConnectionString());
EXPECT_NO_THROW((void) HostDataSourceFactory::getHostDataSourcePtr());
HostDataSourceFactory::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 lease manager open the database opens correctly with a longer
// timeout. If it fails, print the error message.
try {
string connection_string = validPgSQLConnectionString() + string(" ") +
string(VALID_TIMEOUT);
HostDataSourceFactory::create(connection_string);
EXPECT_NO_THROW((void) HostDataSourceFactory::getHostDataSourcePtr());
HostDataSourceFactory::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_FALSE(HostDataSourceFactory::getHostDataSourcePtr());
// Check that wrong specification of backend throws an exception.
// (This is really a check on LeaseMgrFactory, but is convenient to
// perform here.)
EXPECT_THROW(HostDataSourceFactory::create(connectionString(
NULL, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
InvalidParameter);
EXPECT_THROW(HostDataSourceFactory::create(connectionString(
INVALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)),
InvalidType);
// Check that invalid login data causes an exception.
EXPECT_THROW(HostDataSourceFactory::create(connectionString(
PGSQL_VALID_TYPE, INVALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)),
DbOpenError);
EXPECT_THROW(HostDataSourceFactory::create(connectionString(
PGSQL_VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)),
DbOpenError);
EXPECT_THROW(HostDataSourceFactory::create(connectionString(
PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
DbOpenError);
EXPECT_THROW(HostDataSourceFactory::create(connectionString(
PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_PASSWORD)),
DbOpenError);
EXPECT_THROW(HostDataSourceFactory::create(connectionString(
PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD, INVALID_TIMEOUT_1)),
DbInvalidTimeout);
EXPECT_THROW(HostDataSourceFactory::create(connectionString(
PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD, INVALID_TIMEOUT_2)),
DbInvalidTimeout);
// Check for missing parameters
EXPECT_THROW(HostDataSourceFactory::create(connectionString(
PGSQL_VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
NoDatabaseName);
// Tidy up after the test
destroyPgSQLSchema();
}
// Test verifies if a host reservation can be added and later retrieved by IPv4
// address. Host uses hw address as identifier.
TEST_F(PgSqlHostDataSourceTest, basic4HWAddr) {
testBasic4(Host::IDENT_HWADDR);
}
// Test verifies if a host reservation can be added and later retrieved by IPv4
// address. Host uses client-id (DUID) as identifier.
TEST_F(PgSqlHostDataSourceTest, basic4ClientId) {
testBasic4(Host::IDENT_DUID);
}
// Test verifies that multiple hosts can be added and later retrieved by their
// reserved IPv4 address. This test uses HW addresses as identifiers.
TEST_F(PgSqlHostDataSourceTest, getByIPv4HWaddr) {
testGetByIPv4(Host::IDENT_HWADDR);
}
// Test verifies that multiple hosts can be added and later retrieved by their
// reserved IPv4 address. This test uses client-id (DUID) as identifiers.
TEST_F(PgSqlHostDataSourceTest, getByIPv4ClientId) {
testGetByIPv4(Host::IDENT_DUID);
}
// Test verifies if a host reservation can be added and later retrieved by
// hardware address.
TEST_F(PgSqlHostDataSourceTest, get4ByHWaddr) {
testGet4ByIdentifier(Host::IDENT_HWADDR);
}
// Test verifies if a host reservation can be added and later retrieved by
// DUID.
TEST_F(PgSqlHostDataSourceTest, get4ByDUID) {
testGet4ByIdentifier(Host::IDENT_DUID);
}
// Test verifies if a host reservation can be added and later retrieved by
// circuit id.
TEST_F(PgSqlHostDataSourceTest, get4ByCircuitId) {
testGet4ByIdentifier(Host::IDENT_CIRCUIT_ID);
}
// Test verifies if hardware address and client identifier are not confused.
TEST_F(PgSqlHostDataSourceTest, hwaddrNotClientId1) {
testHWAddrNotClientId();
}
// Test verifies if hardware address and client identifier are not confused.
TEST_F(PgSqlHostDataSourceTest, hwaddrNotClientId2) {
testClientIdNotHWAddr();
}
// Test verifies if a host with FQDN hostname can be stored and later retrieved.
TEST_F(PgSqlHostDataSourceTest, hostnameFQDN) {
testHostname("foo.example.org", 1);
}
// Test verifies if 100 hosts with unique FQDN hostnames can be stored and later
// retrieved.
TEST_F(PgSqlHostDataSourceTest, hostnameFQDN100) {
testHostname("foo.example.org", 100);
}
// Test verifies if a host without any hostname specified can be stored and
// later retrieved.
TEST_F(PgSqlHostDataSourceTest, noHostname) {
testHostname("", 1);
}
// Test verifies if the hardware or client-id query can match hardware address.
TEST_F(PgSqlHostDataSourceTest, DISABLED_hwaddrOrClientId1) {
/// @todo: The logic behind ::get4(subnet_id, hwaddr, duid) call needs to
/// be discussed.
///
/// @todo: Add host reservation with hardware address X, try to retrieve
/// host for hardware address X or client identifier Y, verify that the
/// reservation is returned.
}
// Test verifies if the hardware or client-id query can match client-id.
TEST_F(PgSqlHostDataSourceTest, DISABLED_hwaddrOrClientId2) {
/// @todo: The logic behind ::get4(subnet_id, hwaddr, duid) call needs to
/// be discussed.
///
/// @todo: Add host reservation with client identifier Y, try to retrieve
/// host for hardware address X or client identifier Y, verify that the
/// reservation is returned.
}
#if 0