using namespace std;
using namespace isc::asiolink;
using namespace isc::util;
+using namespace isc::data;
namespace isc {
namespace dhcp {
EXPECT_EQ(host1->getNextServer(), host2->getNextServer());
EXPECT_EQ(host1->getServerHostname(), host2->getServerHostname());
EXPECT_EQ(host1->getBootFileName(), host2->getBootFileName());
+ ConstElementPtr ctx1 = host1->getContext();
+ ConstElementPtr ctx2 = host2->getContext();
+ if (ctx1) {
+ EXPECT_TRUE(ctx2);
+ if (ctx2) {
+ EXPECT_EQ(*ctx1, *ctx2);
+ }
+ } else {
+ EXPECT_FALSE(ctx2);
+ }
// Compare IPv6 reservations
compareReservations6(host1->getIPv6Reservations(),
// Compare number of reservations for both hosts
if (std::distance(resrv1.first, resrv1.second) !=
std::distance(resrv2.first, resrv2.second)){
- ADD_FAILURE()<< "Reservation comparison failed, "
+ ADD_FAILURE() << "Reservation comparison failed, "
"hosts got different number of reservations.";
return;
}
EXPECT_EQ(desc1.formatted_value_, desc2.formatted_value_)
<< "failed for option " << space << "." << desc1.option_->getType();
+ // Compare user context.
+ ConstElementPtr ctx1 = desc1.getContext();
+ ConstElementPtr ctx2 = desc2.getContext();
+ if (ctx1) {
+ EXPECT_TRUE(ctx2);
+ if (ctx2) {
+ EXPECT_EQ(*ctx1, *ctx2)
+ << "failed for option " << space << "." << desc1.option_->getType();
+ }
+ } else {
+ EXPECT_FALSE(ctx2);
+ }
+
// Retrieve options.
Option* option1 = desc1.option_.get();
Option* option2 = desc2.option_.get();
void
GenericHostDataSourceTest::addTestOptions(const HostPtr& host,
const bool formatted,
- const AddedOptions& added_options) const {
+ const AddedOptions& added_options,
+ ConstElementPtr user_context) const {
OptionDefSpaceContainer defs;
if ((added_options == DHCP4_ONLY) || (added_options == DHCP4_AND_DHCP6)) {
// Add DHCPv4 options.
CfgOptionPtr opts = host->getCfgOption4();
- opts->add(createOption<OptionString>(Option::V4, DHO_BOOT_FILE_NAME,
- true, formatted, "my-boot-file"),
- DHCP4_OPTION_SPACE);
+ OptionDescriptor desc =
+ createOption<OptionString>(Option::V4, DHO_BOOT_FILE_NAME,
+ true, formatted, "my-boot-file");
+ desc.setContext(user_context);
+ opts->add(desc, DHCP4_OPTION_SPACE);
opts->add(createOption<OptionUint8>(Option::V4, DHO_DEFAULT_IP_TTL,
false, formatted, 64),
DHCP4_OPTION_SPACE);
if ((added_options == DHCP6_ONLY) || (added_options == DHCP4_AND_DHCP6)) {
// Add DHCPv6 options.
CfgOptionPtr opts = host->getCfgOption6();
- opts->add(createOption<OptionString>(Option::V6, D6O_BOOTFILE_URL,
- true, formatted, "my-boot-file"),
- DHCP6_OPTION_SPACE);
+ OptionDescriptor desc =
+ createOption<OptionString>(Option::V6, D6O_BOOTFILE_URL,
+ true, formatted, "my-boot-file");
+ desc.setContext(user_context);
+ opts->add(desc, DHCP6_OPTION_SPACE);
opts->add(createOption<OptionUint32>(Option::V6, D6O_INFORMATION_REFRESH_TIME,
false, formatted, 3600),
DHCP6_OPTION_SPACE);
}
}
+void
+GenericHostDataSourceTest::testUserContext(ConstElementPtr user_context) {
+
+ // Make sure we have a pointer to the host data source.
+ ASSERT_TRUE(hdsptr_);
+
+ // Create a host reservation.
+ HostPtr host = initializeHost4("192.0.2.1", Host::IDENT_DUID);
+ ASSERT_TRUE(host); // Make sure the host is generate properly.
+ host->setContext(user_context);
+ SubnetID subnet = host->getIPv4SubnetID();
+
+ // Try to add it to the host data source.
+ ASSERT_NO_THROW(hdsptr_->add(host));
+
+ // Retrieve it.
+ ConstHostPtr from_hds = hdsptr_->get4(subnet, IOAddress("192.0.2.1"));
+ ASSERT_TRUE(from_hds);
+
+ // Finally, let's check if what we got makes any sense.
+ compareHosts(host, from_hds);
+
+ // Retry with IPv6
+ host = initializeHost6("2001:db8::1", Host::IDENT_HWADDR, false);
+ ASSERT_TRUE(host);
+ ASSERT_TRUE(host->getHWAddress());
+ host->setContext(user_context);
+ host->setHostname("foo.example.com");
+ subnet = host->getIPv6SubnetID();
+
+ ASSERT_NO_THROW(hdsptr_->add(host));
+
+ from_hds = hdsptr_->get6(subnet, Host::IDENT_HWADDR,
+ &host->getIdentifier()[0],
+ host->getIdentifier().size());
+ ASSERT_TRUE(from_hds);
+
+ compareHosts(host, from_hds);
+}
+
void
GenericHostDataSourceTest::testMultipleSubnets(int subnets,
const Host::IdentifierType& id) {
}
-void GenericHostDataSourceTest::testOptionsReservations4(const bool formatted) {
+void GenericHostDataSourceTest::testOptionsReservations4(const bool formatted,
+ ConstElementPtr user_context) {
HostPtr host = initializeHost4("192.0.2.5", Host::IDENT_HWADDR);
// Add a bunch of DHCPv4 and DHCPv6 options for the host.
- ASSERT_NO_THROW(addTestOptions(host, formatted, DHCP4_ONLY));
+ ASSERT_NO_THROW(addTestOptions(host, formatted, DHCP4_ONLY, user_context));
// Insert host and the options into respective tables.
ASSERT_NO_THROW(hdsptr_->add(host));
// Subnet id will be used in queries to the database.
ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_addr));
}
-void GenericHostDataSourceTest::testOptionsReservations6(const bool formatted) {
+void GenericHostDataSourceTest::testOptionsReservations6(const bool formatted,
+ ConstElementPtr user_context) {
HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_DUID, false);
// Add a bunch of DHCPv4 and DHCPv6 options for the host.
- ASSERT_NO_THROW(addTestOptions(host, formatted, DHCP6_ONLY));
+ ASSERT_NO_THROW(addTestOptions(host, formatted, DHCP6_ONLY, user_context));
// Insert host, options and IPv6 reservations into respective tables.
ASSERT_NO_THROW(hdsptr_->add(host));
// Subnet id will be used in queries to the database.
/// value should be used (if true), or binary value (if false).
/// @param added_options Controls which options should be inserted into
/// a host: DHCPv4, DHCPv6 options or both.
+ /// @param user_context Optional user context
void addTestOptions(const HostPtr& host, const bool formatted,
- const AddedOptions& added_options) const;
+ const AddedOptions& added_options,
+ isc::data::ConstElementPtr user_context =
+ isc::data::ConstElementPtr()) const;
/// @brief Pointer to the host data source
HostDataSourcePtr hdsptr_;
/// @param num number of hostnames to be added.
void testHostname(std::string name, int num);
+ /// @brief Test insert and retrieve a host with user context.
+ ///
+ /// Uses gtest macros to report failures.
+ ///
+ /// @param user_context The user context.
+ void testUserContext(isc::data::ConstElementPtr user_context);
+
/// @brief Test inserts multiple reservations for the same host for different
/// subnets and check that they can be retrieved properly.
///
/// that the can be retrieved by subnet id and prefix value.
void testGetBySubnetIPv6();
-
/// @brief Test that hosts can be retrieved by hardware address.
///
/// Uses gtest macros to report failures.
///
/// @param formatted Boolean value indicating if the option values
/// should be stored in the textual format in the database.
- void testOptionsReservations4(const bool formatted);
+ /// @param user_context Optional user context.
+ void testOptionsReservations4(const bool formatted,
+ isc::data::ConstElementPtr user_context =
+ isc::data::ConstElementPtr());
/// @brief Test that DHCPv6 options can be inserted and retrieved from
/// the database.
///
/// @param formatted Boolean value indicating if the option values
/// should be stored in the textual format in the database.
- void testOptionsReservations6(const bool formatted);
+ /// @param user_context Optional user context.
+ void testOptionsReservations6(const bool formatted,
+ isc::data::ConstElementPtr user_context =
+ isc::data::ConstElementPtr());
/// @brief Test that DHCPv4 and DHCPv6 options can be inserted and retrieved
/// with a single query to the database.
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
+using namespace isc::data;
using namespace std;
namespace {
testHostname("", 1);
}
+// Test verifies if a host with user context can be stored and later retrieved.
+TEST_F(MySqlHostDataSourceTest, usercontext) {
+ string comment = "{ \"comment\": \"a host reservation\" }";
+ testUserContext(Element::fromJSON(comment));
+}
+
// Test verifies if the hardware or client-id query can match hardware address.
TEST_F(MySqlHostDataSourceTest, DISABLED_hwaddrOrClientId1) {
/// @todo: The logic behind ::get4(subnet_id, hwaddr, duid) call needs to
// This test verifies that DHCPv4 options can be inserted in a binary format
/// and retrieved from the MySQL host database.
TEST_F(MySqlHostDataSourceTest, optionsReservations4) {
- testOptionsReservations4(false);
+ string comment = "{ \"comment\": \"a host reservation\" }";
+ testOptionsReservations4(false, Element::fromJSON(comment));
}
// This test verifies that DHCPv6 options can be inserted in a binary format
/// and retrieved from the MySQL host database.
TEST_F(MySqlHostDataSourceTest, optionsReservations6) {
- testOptionsReservations6(false);
+ string comment = "{ \"comment\": \"a host reservation\" }";
+ testOptionsReservations6(false, Element::fromJSON(comment));
}
// This test verifies that DHCPv4 and DHCPv6 options can be inserted in a
// This test verifies that DHCPv4 options can be inserted in a textual format
/// and retrieved from the MySQL host database.
TEST_F(MySqlHostDataSourceTest, formattedOptionsReservations4) {
- testOptionsReservations4(true);
+ string comment = "{ \"comment\": \"a host reservation\" }";
+ testOptionsReservations4(true, Element::fromJSON(comment));
}
// This test verifies that DHCPv6 options can be inserted in a textual format
/// and retrieved from the MySQL host database.
TEST_F(MySqlHostDataSourceTest, formattedOptionsReservations6) {
- testOptionsReservations6(true);
+ string comment = "{ \"comment\": \"a host reservation\" }";
+ testOptionsReservations6(true, Element::fromJSON(comment));
}
// This test verifies that DHCPv4 and DHCPv6 options can be inserted in a
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
+using namespace isc::data;
using namespace std;
namespace {
testHostname("", 1);
}
+// Test verifies if a host with user context can be stored and later retrieved.
+TEST_F(PgSqlHostDataSourceTest, usercontext) {
+ string comment = "{ \"comment\": \"a host reservation\" }";
+ testUserContext(Element::fromJSON(comment));
+}
+
// 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
// This test verifies that DHCPv4 options can be inserted in a binary format
/// and retrieved from the PostgreSQL host database.
TEST_F(PgSqlHostDataSourceTest, optionsReservations4) {
- testOptionsReservations4(false);
+ string comment = "{ \"comment\": \"a host reservation\" }";
+ testOptionsReservations4(false, Element::fromJSON(comment));
}
// This test verifies that DHCPv6 options can be inserted in a binary format
/// and retrieved from the PostgreSQL host database.
TEST_F(PgSqlHostDataSourceTest, optionsReservations6) {
- testOptionsReservations6(false);
+ string comment = "{ \"comment\": \"a host reservation\" }";
+ testOptionsReservations6(false, Element::fromJSON(comment));
}
// This test verifies that DHCPv4 and DHCPv6 options can be inserted in a
// This test verifies that DHCPv4 options can be inserted in a textual format
/// and retrieved from the PostgreSQL host database.
TEST_F(PgSqlHostDataSourceTest, formattedOptionsReservations4) {
- testOptionsReservations4(true);
+ string comment = "{ \"comment\": \"a host reservation\" }";
+ testOptionsReservations4(true, Element::fromJSON(comment));
}
// This test verifies that DHCPv6 options can be inserted in a textual format
/// and retrieved from the PostgreSQL host database.
TEST_F(PgSqlHostDataSourceTest, formattedOptionsReservations6) {
- testOptionsReservations6(true);
+ string comment = "{ \"comment\": \"a host reservation\" }";
+ testOptionsReservations6(true, Element::fromJSON(comment));
}
// This test verifies that DHCPv4 and DHCPv6 options can be inserted in a