From: Tomek Mrugalski Date: Mon, 19 Oct 2015 00:16:21 +0000 (+0200) Subject: [3682] Unit-test for adding basic v4 host reservation added. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5c4af7ea5445de1b437b71e8b6bafe2ee3bf0bc6;p=thirdparty%2Fkea.git [3682] Unit-test for adding basic v4 host reservation added. --- diff --git a/src/lib/dhcpsrv/mysql_host_data_source.cc b/src/lib/dhcpsrv/mysql_host_data_source.cc index b3958a2a27..03299c5acb 100644 --- a/src/lib/dhcpsrv/mysql_host_data_source.cc +++ b/src/lib/dhcpsrv/mysql_host_data_source.cc @@ -294,21 +294,19 @@ public: // reasons, see memset() above // dhcp4_client_classes : VARCHAR(255) NULL - // TODO this should probably be converted in some way... Don't know how yet, - // also size method might be wrong bind_[7].buffer_type = MYSQL_TYPE_STRING; - //bind_[7].buffer = reinterpret_cast(host_->getClientClasses4()); - bind_[7].buffer_length = sizeof(host_->getClientClasses4()); - // bind_[7].is_null = &MLM_FALSE; // commented out for performance - // reasons, see memset() above + string classes4_txt = classesToString(host_->getClientClasses4()); + strncpy(dhcp4_client_classes_, classes4_txt.c_str(), CLIENT_CLASSES_MAX_LEN - 1); + bind_[7].buffer = dhcp4_client_classes_; + bind_[7].buffer_length = classes4_txt.length(); // dhcp6_client_classes : VARCHAR(255) NULL bind_[8].buffer_type = MYSQL_TYPE_STRING; - //bind_[8].buffer = reinterpret_cast(host_->getClientClasses6()); + string classes6_txt = classesToString(host->getClientClasses6()); + strncpy(dhcp6_client_classes_, classes6_txt.c_str(), CLIENT_CLASSES_MAX_LEN - 1); + bind_[8].buffer = dhcp6_client_classes_; + bind_[8].buffer_length = classes6_txt.length(); bind_[8].buffer_length = sizeof(host_->getClientClasses6()); - // bind_[8].is_null = &MLM_FALSE; // commented out for performance - // reasons, see memset() above - } catch (const std::exception& ex) { isc_throw(DbOperationError, @@ -498,6 +496,22 @@ public: return (getColumnsInError(error_, columns_, HOST_COLUMNS)); } + std::string classesToString(const ClientClasses& classes) { + string txt; + bool first = true; + for (ClientClasses::const_iterator it = classes.begin(); + it != classes.end(); ++it) { + if (!first) { + txt += ","; + } + txt += (*it); + + first = false; + } + + return (txt); + } + private: uint32_t host_id_; /// Host unique identifier std::vector dhcp_identifier_; /// HW address (0) / DUID (1) @@ -587,7 +601,7 @@ MySqlHostDataSource::add(const HostPtr& host) { void MySqlHostDataSource::addHost(StatementIndex stindex, - std::vector& bind) { + std::vector& bind) { // Bind the parameters to the statement int status = mysql_stmt_bind_param(conn_.statements_[stindex], 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 c8b70c7499..61da447a19 100644 --- a/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc +++ b/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc @@ -34,8 +34,116 @@ GenericHostDataSourceTest::GenericHostDataSourceTest() GenericHostDataSourceTest::~GenericHostDataSourceTest() { } +std::string +GenericHostDataSourceTest::generateHWAddr() { + /// @todo: Make this code return different hwaddress every time. + return ("01:02:03:04:05:06"); +} + +std::string +GenericHostDataSourceTest::generateDuid() { + /// @todo: Make this code return different duid every time. + return ("010203040506abcd"); +} + +HostPtr GenericHostDataSourceTest::initializeHost4(std::string address, + bool hwaddr) { + string ident; + string ident_type; + + if (hwaddr) { + ident = generateHWAddr(); + ident_type = "hw-address"; + } else { + ident = generateDuid(); + ident_type = "duid"; + } + + // Let's create ever increasing subnet-ids. Let's keep those different, + // so subnet4 != subnet6. Useful for catching cases if the code confuses + // subnet4 with subnet6. + static SubnetID subnet4 = 0; + static SubnetID subnet6 = 100; + subnet4++; + subnet6++; + + IOAddress addr(address); + HostPtr host(new Host(ident, ident_type, subnet4, subnet6, addr)); + + return (host); +} + +HostPtr GenericHostDataSourceTest::initializeHost6(std::string address, + bool hwaddr, bool prefix) { + string ident; + string ident_type; + + if (hwaddr) { + ident = generateHWAddr(); + ident_type = "hw-address"; + } else { + ident = generateDuid(); + ident_type = "duid"; + } + + // Let's create ever increasing subnet-ids. Let's keep those different, + // so subnet4 != subnet6. Useful for catching cases if the code confuses + // subnet4 with subnet6. + static SubnetID subnet4 = 0; + static SubnetID subnet6 = 100; + subnet4++; + subnet6++; + HostPtr host(new Host(ident, ident_type, subnet4, subnet6, IOAddress("0.0.0.0"))); + if (!prefix) { + // Create IPv6 reservation (for an address) + IPv6Resrv resv(IPv6Resrv::TYPE_NA, IOAddress(address), 128); + host->addReservation(resv); + } else { + // Create IPv6 reservation for a /64 prefix + IPv6Resrv resv(IPv6Resrv::TYPE_PD, IOAddress(address), 64); + host->addReservation(resv); + } + return (host); +} + +void GenericHostDataSourceTest::compareHosts(const ConstHostPtr& host1, + const ConstHostPtr& host2) { + ASSERT_TRUE(host1); + ASSERT_TRUE(host2); + + // Compare if both have or have not HWaddress set. + ASSERT_EQ(host1->getHWAddress(), host2->getHWAddress()); + if (host1->getHWAddress()) { + // Compare the actual address if they match. + EXPECT_EQ(*host1->getHWAddress(), *host2->getHWAddress()); + } + + /// @todo: Compare other fields +} + +void GenericHostDataSourceTest::testBasic4() { + // Make sure we have the pointer to the host data source. + ASSERT_TRUE(hdsptr_); + + // Create a host reservation. + HostPtr host = initializeHost4("192.0.2.1", true); + ASSERT_TRUE(host); // Make sure the host is generate properly. + SubnetID subnet = host->getIPv4SubnetID(); + + // Try to add it to the host data source. + ASSERT_NO_THROW(hdsptr_->add(host)); + + // And then retrive it. + ConstHostPtr from_hds = hdsptr_->get4(subnet, IOAddress("192.0.2.1")); + + // Make sure we got something back. + ASSERT_TRUE(from_hds); + + // Finally, let's check if what we got makes any sense. + compareHosts(host, from_hds); +} }; // namespace test }; // namespace dhcp 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 7e4fa5cc57..ccaaf1588d 100644 --- a/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h +++ b/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h @@ -42,8 +42,48 @@ public: /// @brief Virtual destructor. virtual ~GenericHostDataSourceTest(); + /// @brief Creates a host reservation for specified IPv4 address. + /// + /// @param address IPv4 address to be set + /// @param hwaddr type of identifier (true = hwaddr, false = client-id) + /// + /// @return generated Host object + HostPtr initializeHost4(std::string address, bool hwaddr); + + /// @brief Creates a host reservation for specified IPv4 address. + /// + /// @param address IPv6 address to be reserved + /// @param hwaddr type of identifier (true = hwaddr, false = client-id) + /// @param prefix reservation type (true = prefix, false = address) + /// + /// @return generated Host object + HostPtr initializeHost6(std::string address, bool hwaddr, bool prefix); + + /// @brief Generates a hardware address in text version. + /// + /// @return HW address in textual form acceptable by Host constructor + std::string generateHWAddr(); + + /// @brief Generates a hardware address in text version. + /// @return DUID in textual form acceptable by Host constructor + std::string generateDuid(); + + /// @brief Compares two hosts + /// + /// This method uses gtest macros to signal errors. + /// + /// @param host1 first host to compare + /// @param host2 second host to compare + void compareHosts(const ConstHostPtr& host1, const ConstHostPtr& host2); + /// @brief Pointer to the host data source BaseHostDataSource* hdsptr_; + + /// @brief Test that checks that simple host with IPv4 reservation + /// can be inserted and later retrieved. + /// + /// Uses gtest macros to report failures. + void testBasic4(); }; }; // namespace test 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 113d2d64fe..422bee3248 100644 --- a/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc +++ b/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc @@ -301,8 +301,7 @@ TEST_F(MySqlHostDataSourceTest, checkTimeConversion) { // Test verifies if a host reservation can be added and later retrieved by IPv4 // address. TEST_F(MySqlHostDataSourceTest, basic4) { - /// @todo: basic - add host reserveration, retrieve it by address and - /// confirm that all fields have correct value. + testBasic4(); } // Test verifies if a host reservation can be added and later retrieved by diff --git a/src/lib/dhcpsrv/tests/schema_mysql_copy.h b/src/lib/dhcpsrv/tests/schema_mysql_copy.h index 5e60fe3262..7382465295 100755 --- a/src/lib/dhcpsrv/tests/schema_mysql_copy.h +++ b/src/lib/dhcpsrv/tests/schema_mysql_copy.h @@ -45,6 +45,8 @@ const char* destroy_statement[] = { "DROP TABLE hosts", "DROP TABLE dhcp4_options", "DROP TABLE dhcp6_options", + + "DROP TRIGGER host_BDEL", NULL };