diff options
-rw-r--r-- | src/lib/dhcpsrv/host.cc | 4 | ||||
-rw-r--r-- | src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc | 95 | ||||
-rw-r--r-- | src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h | 41 | ||||
-rw-r--r-- | src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc | 55 | ||||
-rw-r--r-- | src/lib/dhcpsrv/tests/pgsql_host_data_source_unittest.cc | 54 |
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 |