class CqlHostDataSourceTest : public GenericHostDataSourceTest {
public:
- /// @brief Constructor
- ///
- /// Deletes everything from the database and opens it.
- CqlHostDataSourceTest() {
+ /// @brief Clears the database and opens connection to it.
+ void initializeTest() {
// Ensure schema is the correct one.
destroyCqlSchema(false, true);
createCqlSchema(false, true);
hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
}
+ /// @brief Destroys the HDS and the schema.
+ void destroyTest() {
+ hdsptr_->rollback();
+ HostDataSourceFactory::destroy();
+ destroyCqlSchema(false, true);
+ }
+
+ /// @brief Constructor
+ ///
+ /// Deletes everything from the database and opens it.
+ CqlHostDataSourceTest(){
+ initializeTest();
+ }
+
/// @brief Destructor
///
/// Rolls back all pending transactions. The deletion of myhdsptr_ will
/// close the database. Then reopen it and delete everything created by the
/// test.
virtual ~CqlHostDataSourceTest() {
- hdsptr_->rollback();
- HostDataSourceFactory::destroy();
- destroyCqlSchema(false, true);
+ destroyTest();
}
/// @brief Reopen the database
CqlConnection connection(params);
ASSERT_NO_THROW(connection.openDatabase());
- // Drop every table so we make sure host_ipv6_reservation_options doesn't
- // exist anymore
+ // Drop every table so we make sure host_reservations doesn't exist anymore.
destroyCqlSchema(false, true);
// Create a host with a reservation.
DbOperationError);
}
-}; // anonymous namespace
+TEST_F(CqlHostDataSourceTest, DISABLED_stressTest) {
+ // Run with 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4092, 8192,
+ // 16384 & 32768 hosts.
+ for (unsigned int i = 0X0001U; i < 0xfffdU; i <<= 1) {
+ initializeTest();
+ stressTest(i);
+ destroyTest();
+ }
+}
+
+} // namespace
return (host);
}
+bool
+GenericHostDataSourceTest::reservationExists(const IPv6Resrv& resrv,
+ const IPv6ResrvRange& range) {
+ for (IPv6ResrvIterator it = range.first; it != range.second; ++it) {
+ if (resrv == it->second) {
+ return true;
+ }
+ }
+ return false;
+}
+
void
GenericHostDataSourceTest::compareHwaddrs(const ConstHostPtr& host1,
const ConstHostPtr& host2,
ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
}
-}; // namespace test
-}; // namespace dhcp
-}; // namespace isc
+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<HostPtr> 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<HostPtr>::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<double>(end.tv_sec - start.tv_sec) +
+ static_cast<double>(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<HostPtr>::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<double>(end.tv_sec - start.tv_sec) +
+ static_cast<double>(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;
+}
+
+} // namespace test
+} // namespace dhcp
+} // namespace isc
/// @return Identifier in textual form acceptable by Host constructor
std::vector<uint8_t> 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
///
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 Returns DUID with identical content as specified HW address
///
/// This method does not have any sense in real life and is only useful
};
-}; // namespace test
-}; // namespace dhcp
-}; // namespace isc
+} // namespace test
+} // namespace dhcp
+} // namespace isc
#endif