Skip to content

Commit 76cd38f

Browse files
author
Michael Fero
committed
test: Ensure control connection is decoupled from request timeout
1 parent 022ce4d commit 76cd38f

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

test/integration_tests/src/test_token_aware_policy.cpp

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,4 +301,99 @@ BOOST_AUTO_TEST_CASE(single_entry_routing_key)
301301
% keyspace));
302302
}
303303

304+
/**
305+
* Ensure the control connection is decoupled from request timeout
306+
*
307+
* This test addresses an issue where the control connection would timeout due
308+
* to the rebuilding of the token map, re-establish the connection, re-build
309+
* the token map and then rinse and repeat causing high CPU load and an
310+
* infinite loop.
311+
*
312+
* @since 2.4.3
313+
* @jira_ticket CPP-388
314+
* @test_category load_balancing:token_aware
315+
* @test_category control_connection
316+
*/
317+
BOOST_AUTO_TEST_CASE(no_timeout_control_connection)
318+
{
319+
int num_of_keyspaces = 50;
320+
int num_of_tables = 10;
321+
std::string keyspace_prefix = "tap_";
322+
std::string table_prefix = "table_";
323+
test_utils::CassLog::reset("Request timed out to host");
324+
325+
// Create four data centers with single nodes
326+
std::vector<unsigned short> data_center_nodes;
327+
for (int i = 0; i < 4; ++i) {
328+
data_center_nodes.push_back(1);
329+
}
330+
331+
boost::shared_ptr<CCM::Bridge> ccm(new CCM::Bridge("config.txt"));
332+
if (ccm->create_cluster(data_center_nodes, true)) {
333+
ccm->start_cluster();
334+
}
335+
336+
// Create a session with a quick request timeout
337+
test_utils::CassClusterPtr cluster(cass_cluster_new());
338+
cass_cluster_set_token_aware_routing(cluster.get(), cass_true);
339+
test_utils::initialize_contact_points(cluster.get(), ccm->get_ip_prefix(), 4);
340+
cass_cluster_set_request_timeout(cluster.get(), 500);
341+
test_utils::CassSessionPtr session(test_utils::create_session(cluster.get()));
342+
343+
// Create keyspaces, tables, and perform selects)
344+
for (int i = 1; i <= num_of_keyspaces; ++i) {
345+
// Randomly create keyspaces with valid and invalid data centers)
346+
bool is_valid_keyspace = true;
347+
std::string nts_dcs = "'dc1': 1, 'dc2': 1, 'dc3': 1, 'dc4': 1";
348+
if ((rand() % 4) == 0) {
349+
// Create the invalid data center network topology
350+
int unknown_dcs = (rand() % 250) + 50; // random number [50 - 250]
351+
for (int j = 5; j <= 4 + unknown_dcs; ++j) {
352+
nts_dcs += ", 'dc" + boost::lexical_cast<std::string>(j) + "': 1";
353+
}
354+
is_valid_keyspace = false;
355+
}
356+
357+
// Create the keyspace (handling errors to avoid test failure))
358+
CassError error_code;
359+
do {
360+
error_code = test_utils::execute_query_with_error(session.get(),
361+
str(boost::format("CREATE KEYSPACE " + keyspace_prefix + "%d "
362+
"WITH replication = { 'class': 'NetworkTopologyStrategy', "
363+
+ nts_dcs + " }") % i));
364+
} while (error_code != CASS_OK && error_code != CASS_ERROR_SERVER_ALREADY_EXISTS);
365+
366+
// Perform table creation and random selects (iff keyspace is valid))
367+
if (is_valid_keyspace) {
368+
// Create the table (handling errors to avoid test failures)
369+
for (int j = 0; j < num_of_tables; ++j) {
370+
std::stringstream full_table_name;
371+
full_table_name << keyspace_prefix << i << "."
372+
<< table_prefix << j;
373+
CassError error_code = CASS_ERROR_SERVER_READ_TIMEOUT;
374+
do {
375+
error_code = test_utils::execute_query_with_error(session.get(),
376+
str(boost::format(test_utils::CREATE_TABLE_SIMPLE) %
377+
full_table_name.str()));
378+
} while (error_code != CASS_OK && error_code != CASS_ERROR_SERVER_ALREADY_EXISTS);
379+
380+
// Randomly perform select statements on the newly created table
381+
if (rand() % 2 == 0) {
382+
std::string query = "SELECT * FROM " + full_table_name.str();
383+
do {
384+
error_code = test_utils::execute_query_with_error(session.get(), query.c_str());
385+
} while (error_code != CASS_OK);
386+
}
387+
}
388+
}
389+
}
390+
391+
/*
392+
* Ensure timeouts occurred
393+
*
394+
* NOTE: This also ensures (if reached) that infinite loop did not occur
395+
*/
396+
BOOST_REQUIRE_GT(test_utils::CassLog::message_count(), 0);
397+
}
398+
304399
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)