summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/dhcpsrv/host.cc4
-rw-r--r--src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc95
-rw-r--r--src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h41
-rw-r--r--src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc55
-rw-r--r--src/lib/dhcpsrv/tests/pgsql_host_data_source_unittest.cc54
5 files changed, 245 insertions, 4 deletions
diff --git a/src/lib/dhcpsrv/host.cc b/src/lib/dhcpsrv/host.cc
index 2ceb3d8d93..f342d89a89 100644
--- a/src/lib/dhcpsrv/host.cc
+++ b/src/lib/dhcpsrv/host.cc
@@ -407,8 +407,6 @@ Host::setBootFileName(const std::string& boot_file_name) {
ElementPtr
Host::toElement4() const {
- // Get the subnet ID
- SubnetID subnet_id = getIPv4SubnetID();
// Prepare the map
ElementPtr map = Element::createMap();
// Set the identifier
@@ -466,8 +464,6 @@ Host::toElement4() const {
ElementPtr
Host::toElement6() const {
- // Get the subnet ID
- SubnetID subnet_id = getIPv6SubnetID();
// Prepare the map
ElementPtr map = Element::createMap();
// Set the identifier
diff --git a/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc b/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc
index 85b930a9bf..ce1861d0b7 100644
--- a/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc
+++ b/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc
@@ -1525,6 +1525,53 @@ void GenericHostDataSourceTest::testDeleteById4() {
EXPECT_FALSE(after);
}
+// Test checks when a IPv4 host with options is deleted that the options are
+// deleted as well.
+void GenericHostDataSourceTest::testDeleteById4Options() {
+ // Make sure we have a pointer to the host data source.
+ ASSERT_TRUE(hdsptr_);
+
+ // Let's create a v4 host...
+ HostPtr host1 = initializeHost4("192.0.2.1", Host::IDENT_HWADDR);
+ // Add a bunch of DHCPv4 and DHCPv6 options for the host.
+ ASSERT_NO_THROW(addTestOptions(host1, true, DHCP4_ONLY));
+ // Insert host and the options into respective tables.
+
+ SubnetID subnet1 = host1->getIPv4SubnetID();
+
+ // ... and add it to the data source.
+ ASSERT_NO_THROW(hdsptr_->add(host1));
+
+ // There must be some options
+ EXPECT_NE(0, countDBOptions4());
+
+ // And then try to retrieve it back.
+ ConstHostPtr before = hdsptr_->get4(subnet1,
+ host1->getIdentifierType(),
+ &host1->getIdentifier()[0],
+ host1->getIdentifier().size());
+
+ // Now try to delete it: del4(subnet4-id, identifier-type, identifier)
+ EXPECT_TRUE(hdsptr_->del4(subnet1, host1->getIdentifierType(),
+ &host1->getIdentifier()[0],
+ host1->getIdentifier().size()));
+
+ // Check if it's still there.
+ ConstHostPtr after = hdsptr_->get4(subnet1,
+ host1->getIdentifierType(),
+ &host1->getIdentifier()[0],
+ host1->getIdentifier().size());
+
+ // Make sure the host was there before...
+ EXPECT_TRUE(before);
+
+ // ... and that it's gone after deletion.
+ EXPECT_FALSE(after);
+
+ // Check the options are indeed gone.
+ EXPECT_EQ(0, countDBOptions4());
+}
+
void GenericHostDataSourceTest::testDeleteById6() {
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
@@ -1560,6 +1607,54 @@ void GenericHostDataSourceTest::testDeleteById6() {
EXPECT_FALSE(after);
}
+void GenericHostDataSourceTest::testDeleteById6Options() {
+ // Make sure we have a pointer to the host data source.
+ ASSERT_TRUE(hdsptr_);
+
+ // Let's create a v6 host...
+ HostPtr host1 = initializeHost6("2001:db8::1", Host::IDENT_DUID, false);
+ SubnetID subnet1 = host1->getIPv6SubnetID();
+ ASSERT_NO_THROW(addTestOptions(host1, true, DHCP6_ONLY));
+
+ // ... and add it to the data source.
+ ASSERT_NO_THROW(hdsptr_->add(host1));
+
+ // Check that the options are stored...
+ EXPECT_NE(0, countDBOptions6());
+
+ // ... and so are v6 reservations.
+ EXPECT_NE(0, countDBReservations6());
+
+ // And then try to retrieve it back.
+ ConstHostPtr before = hdsptr_->get6(subnet1,
+ host1->getIdentifierType(),
+ &host1->getIdentifier()[0],
+ host1->getIdentifier().size());
+
+ // Now try to delete it: del4(subnet4-id, identifier-type, identifier)
+ EXPECT_TRUE(hdsptr_->del6(subnet1, host1->getIdentifierType(),
+ &host1->getIdentifier()[0],
+ host1->getIdentifier().size()));
+
+ // Check if it's still there.
+ ConstHostPtr after = hdsptr_->get6(subnet1,
+ host1->getIdentifierType(),
+ &host1->getIdentifier()[0],
+ host1->getIdentifier().size());
+
+ // Make sure the host was there before...
+ EXPECT_TRUE(before);
+
+ // ... and that it's gone after deletion.
+ EXPECT_FALSE(after);
+
+ // Check the options are indeed gone.
+ EXPECT_EQ(0, countDBOptions6());
+
+ // Check the options are indeed gone.
+ EXPECT_EQ(0, countDBReservations6());
+}
+
}; // namespace test
}; // namespace dhcp
}; // namespace isc
diff --git a/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h b/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h
index 9566ee07bc..16c61ecd6d 100644
--- a/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h
+++ b/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h
@@ -292,6 +292,39 @@ public:
return (desc);
}
+ /// @brief Returns number of entries in the v4 options table.
+ ///
+ /// This utility method is expected to be implemented by specific backends.
+ /// The code here is just a boilerplate for backends that do not store
+ /// host options in a table.
+ ///
+ /// @param number of existing entries in options table
+ virtual int countDBOptions4() {
+ return (-1);
+ }
+
+ /// @brief Returns number of entries in the v6 options table.
+ ///
+ /// This utility method is expected to be implemented by specific backends.
+ /// The code here is just a boilerplate for backends that do not store
+ /// host options in a table.
+ ///
+ /// @param number of existing entries in options table
+ virtual int countDBOptions6() {
+ return (-1);
+ }
+
+ /// @brief Returns number of entries in the v6 reservations table.
+ ///
+ /// This utility method is expected to be implemented by specific backends.
+ /// The code here is just a boilerplate for backends that do not store
+ /// v6 reservations in a table.
+ ///
+ /// @param number of existing entries in v6_reservations table
+ virtual int countDBReservations6() {
+ return (-1);
+ }
+
/// @brief Creates an instance of the vendor option.
///
/// @param universe V4 or V6.
@@ -534,11 +567,19 @@ public:
/// Uses gtest macros to report failures.
void testDeleteById4();
+ /// @brief Tests that delete(subnet4-id, id-type, id) also deletes options.
+ void testDeleteById4Options();
+
/// @brief Tests that delete(subnet6-id, identifier-type, identifier) works.
///
/// Uses gtest macros to report failures.
void testDeleteById6();
+ /// @brief Tests that delete(subnet6-id, id-type, id) also deletes options.
+ ///
+ /// Uses gtest macros to report failures.
+ void testDeleteById6Options();
+
/// @brief Returns DUID with identical content as specified HW address
///
/// This method does not have any sense in real life and is only useful
diff --git a/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc b/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc
index 793a211336..2ca2b0f67a 100644
--- a/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc
+++ b/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc
@@ -86,6 +86,49 @@ public:
hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
}
+ /// @brief returns number of rows in a table
+ ///
+ /// Note: This method uses its own connection. It will not work if your test
+ /// uses transactions.
+ ///
+ /// @param name of the table
+ /// @return number of rows currently present in the table
+ int countRowsInTable(const std::string& table) {
+ string query = "SELECT * FROM " + table;
+
+ MySqlConnection::ParameterMap params;
+ params["name"] = "keatest";
+ params["user"] = "keatest";
+ params["password"] = "keatest";
+ MySqlConnection conn(params);
+ conn.openDatabase();
+ int status = mysql_query(conn.mysql_, query.c_str());
+ if (status !=0) {
+ isc_throw(DbOperationError, "Query failed: " << mysql_error(conn.mysql_));
+ }
+
+ MYSQL_RES * res = mysql_store_result(conn.mysql_);
+ int numrows = static_cast<int>(mysql_num_rows(res));
+ mysql_free_result(res);
+
+ return (numrows);
+ }
+
+ /// @brief Returns number of IPv4 options currently stored in DB.
+ virtual int countDBOptions4() {
+ return (countRowsInTable("dhcp4_options"));
+ }
+
+ /// @brief Returns number of IPv4 options currently stored in DB.
+ virtual int countDBOptions6() {
+ return (countRowsInTable("dhcp6_options"));
+ }
+
+ /// @brief Returns number of IPv6 reservations currently stored in DB.
+ virtual int countDBReservations6() {
+ return (countRowsInTable("ipv6_reservations"));
+ }
+
};
/// @brief Check that database can be opened
@@ -545,9 +588,21 @@ TEST_F(MySqlHostDataSourceTest, deleteById4) {
testDeleteById4();
}
+// Check that delete(subnet4-id, identifier-type, identifier) works,
+// even when options are present.
+TEST_F(MySqlHostDataSourceTest, deleteById4Options) {
+ testDeleteById4Options();
+}
+
// Check that delete(subnet6-id, identifier-type, identifier) works.
TEST_F(MySqlHostDataSourceTest, deleteById6) {
testDeleteById6();
}
+// Check that delete(subnet6-id, identifier-type, identifier) works,
+// even when options are present.
+TEST_F(MySqlHostDataSourceTest, deleteById6Options) {
+ testDeleteById6Options();
+}
+
}; // Of anonymous namespace
diff --git a/src/lib/dhcpsrv/tests/pgsql_host_data_source_unittest.cc b/src/lib/dhcpsrv/tests/pgsql_host_data_source_unittest.cc
index ee5b9e0ea7..f9aae9d93d 100644
--- a/src/lib/dhcpsrv/tests/pgsql_host_data_source_unittest.cc
+++ b/src/lib/dhcpsrv/tests/pgsql_host_data_source_unittest.cc
@@ -87,6 +87,48 @@ public:
hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
}
+ /// @brief returns number of rows in a table
+ ///
+ /// Note: This method uses its own connection. It will not work if your test
+ /// uses transactions.
+ ///
+ /// @param name of the table
+ /// @return number of rows currently present in the table
+ int countRowsInTable(const std::string& table) {
+ string query = "SELECT * FROM " + table;
+
+ PgSqlConnection::ParameterMap params;
+ params["name"] = "keatest";
+ params["user"] = "keatest";
+ params["password"] = "keatest";
+
+ PgSqlConnection conn(params);
+ conn.openDatabase();
+
+ PgSqlResult r(PQexec(conn, query.c_str()));
+ if (PQresultStatus(r) != PGRES_TUPLES_OK) {
+ isc_throw(DbOperationError, "Query failed:" << PQerrorMessage(conn));
+ }
+
+ int numrows = PQntuples(r);
+ return (numrows);
+ }
+
+ /// @brief Returns number of IPv4 options in the DB table.
+ virtual int countDBOptions4() {
+ return (countRowsInTable("dhcp4_options"));
+ }
+
+ /// @brief Returns number of IPv4 options in the DB table.
+ virtual int countDBOptions6() {
+ return (countRowsInTable("dhcp6_options"));
+ }
+
+ /// @brief Returns number of IPv6 reservations in the DB table.
+ virtual int countDBReservations6() {
+ return (countRowsInTable("ipv6_reservations"));
+ }
+
};
/// @brief Check that database can be opened
@@ -503,9 +545,21 @@ TEST_F(PgSqlHostDataSourceTest, deleteById4) {
testDeleteById4();
}
+// Check that delete(subnet4-id, identifier-type, identifier) works,
+// even when options are present.
+TEST_F(PgSqlHostDataSourceTest, deleteById4Options) {
+ testDeleteById4Options();
+}
+
// Check that delete(subnet6-id, identifier-type, identifier) works.
TEST_F(PgSqlHostDataSourceTest, deleteById6) {
testDeleteById6();
}
+// Check that delete(subnet6-id, identifier-type, identifier) works,
+// even when options are present.
+TEST_F(PgSqlHostDataSourceTest, deleteById6Options) {
+ testDeleteById6Options();
+}
+
}; // Of anonymous namespace