From: Andrei Pavel Date: Thu, 17 Aug 2017 17:52:41 +0000 (+0300) Subject: Merge branch 'cassandra-host-data-source' into cassandra-host-data-source-stress... X-Git-Tag: trac5502_base~5^2~7^2~14^2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d552aa37f9a7aa7b9932940f6ce943fb2936dc0e;p=thirdparty%2Fkea.git Merge branch 'cassandra-host-data-source' into cassandra-host-data-source-stress-test --- d552aa37f9a7aa7b9932940f6ce943fb2936dc0e diff --cc src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc index ec361708d0,bc431ed938..1136c0a4fd --- a/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc +++ b/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc @@@ -1510,76 -1499,198 +1510,268 @@@ GenericHostDataSourceTest::testMessageF ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds)); } +void +GenericHostDataSourceTest::stressTest(unsigned int nOfHosts /* = 0xfffdU */) { + // Make sure we have a pointer to the host data source. + ASSERT_TRUE(hdsptr_); + + // Make sure the variable part of the generated address fits in a 16-bit + // field. + ASSERT_LE(nOfHosts, 0xfffdU); + + // Create hosts. + std::vector hosts; + hosts.reserve(nOfHosts); + for (unsigned int i = 0x0001U; i < 0x0001U + nOfHosts; ++i) { + /// @todo: Check if this is written in hexadecimal format. + std::stringstream ss; + std::string n_host; + ss << std::hex << i; + ss >> n_host; + + const std::string prefix = std::string("2001:db8::") + n_host; + hosts.push_back(initializeHost6(prefix, Host::IDENT_HWADDR, false)); + IPv6ResrvRange range = hosts.back()->getIPv6Reservations(); + ASSERT_EQ(1, std::distance(range.first, range.second)); + EXPECT_TRUE(reservationExists( + IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress(prefix)), range)); + } + const size_t hosts_size = hosts.size(); + + std::cout << "Starting to add hosts..." << std::endl; + struct timespec start, end; + start = (struct timespec){0, 0}; + end = (struct timespec){0, 0}; + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (std::vector::const_iterator it = hosts.begin(); + it != hosts.end(); it++) { + ASSERT_NO_THROW(hdsptr_->add(*it)); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + double s = static_cast(end.tv_sec - start.tv_sec) + + static_cast(end.tv_nsec - start.tv_nsec) / 1e9; + std::cout << "Adding " << hosts_size + << (hosts_size == 1 ? " host" : " hosts") << " took " + << std::fixed << std::setprecision(2) << s << " seconds." + << std::endl; + + // And then try to retrieve them back. + std::cout << "Starting to retrieve hosts..." << std::endl; + start = (struct timespec){0, 0}; + end = (struct timespec){0, 0}; + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (std::vector::const_iterator it = hosts.begin(); + it != hosts.end(); it++) { + IPv6ResrvRange range = (*it)->getIPv6Reservations(); + // This get6() call is particularly useful to test because it involves a + // subquery for MySQL and PostgreSQL and two separate queries for + // Cassandra. + ConstHostPtr from_hds = + hdsptr_->get6(range.first->second.getPrefix(), 128); + ASSERT_TRUE(from_hds); + compareHosts(*it, from_hds); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + s = static_cast(end.tv_sec - start.tv_sec) + + static_cast(end.tv_nsec - start.tv_nsec) / 1e9; + std::cout << "Retrieving " << hosts_size + << (hosts_size == 1 ? " host" : " hosts") << " took " + << std::fixed << std::setprecision(2) << s << " seconds." + << std::endl; +} + + void GenericHostDataSourceTest::testDeleteByAddr4() { + // 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); + SubnetID subnet1 = host1->getIPv4SubnetID(); + + // ... and add it to the data source. + ASSERT_NO_THROW(hdsptr_->add(host1)); + + // And then try to retrieve it back. + ConstHostPtr before = hdsptr_->get4(subnet1, IOAddress("192.0.2.1")); + + // Now try to delete it: del(subnet-id, addr4) + EXPECT_TRUE(hdsptr_->del(subnet1, IOAddress("192.0.2.1"))); + + // Check if it's still there. + ConstHostPtr after = hdsptr_->get4(subnet1, IOAddress("192.0.2.1")); + + // Make sure the host was there before... + EXPECT_TRUE(before); + + // ... and that it's gone after deletion. + EXPECT_FALSE(after); + } + + void GenericHostDataSourceTest::testDeleteById4() { + // 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); + SubnetID subnet1 = host1->getIPv4SubnetID(); + + // ... and add it to the data source. + ASSERT_NO_THROW(hdsptr_->add(host1)); + + // 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); + } + + // 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_); + + // Let's create a v6 host... + HostPtr host1 = initializeHost6("2001:db8::1", Host::IDENT_DUID, false); + SubnetID subnet1 = host1->getIPv6SubnetID(); + + // ... and add it to the data source. + ASSERT_NO_THROW(hdsptr_->add(host1)); + + // 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); + } + + 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 --cc src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h index fda5191ae7,3ce890956d..413943abdd --- a/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h +++ b/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h @@@ -86,16 -86,9 +86,16 @@@ public /// @return Identifier in textual form acceptable by Host constructor std::vector generateIdentifier(const bool new_identifier = true); + /// @brief Checks if the reservation is in the range of reservations. + /// + /// @param resrv Reservation to be searched for. + /// @param range Range of reservations returned by the @c Host object + /// in which the reservation will be searched + bool reservationExists(const IPv6Resrv& resrv, const IPv6ResrvRange& range); + /// @brief Compares hardware addresses of the two hosts. /// - /// This method compares two hwardware address and uses gtest + /// This method compares two hardware address and uses gtest /// macros to signal unexpected (mismatch if expect_match is true; /// match if expect_match is false) values. /// @@@ -537,17 -563,30 +570,38 @@@ /// from a database for a host. /// /// Uses gtest macros to report failures. - /// void testMessageFields4(); + /// @brief Stress test on adding and retrieving hosts + /// + /// Rather than checking for correctness, this test gives interpretable + /// performance results. + /// + /// @param n_of_hosts number of hosts to insert into and retrieve from the + /// database; defaults to the maximum number of allowed hosts. + void stressTest(uint32_t n_of_hosts /* = 0xfffdU */); + /// @brief Tests that delete(subnet-id, addr4) call works. + /// + /// Uses gtest macros to report failures. + void testDeleteByAddr4(); + + /// @brief Tests that delete(subnet4-id, identifier-type, identifier) works. + /// + /// 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 ///