Skip to content

Commit 9f6d397

Browse files
author
Michael Fero
committed
test: Fixing and stabilizing integration tests
- DSE server version checking - Value type server version checking - Authentication log message checking - EACH_QUORUM - System schema keyspaces - Ensure reconnect test doesn't restart node after chaotic test - Stabilized external host listener tests - Speculative execution tests required larger function timeout for UDF - Proxy authentication - Invalid YAML string for configuration - Updated server error message validation for unauthorized - Added missing C* versions to CCM bridge - JVM argument usage when starting a node - Ensure restarting nodes are performed once - Ensuring start/stop node operations do not cause test start failures
1 parent 1ff9ddc commit 9f6d397

14 files changed

Lines changed: 213 additions & 72 deletions

File tree

cpp-driver/gtests/src/integration/integration.cpp

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "integration.hpp"
1818
#include "options.hpp"
1919

20+
#include <algorithm>
2021
#include <cstdarg>
2122
#include <iostream>
2223
#include <sys/stat.h>
@@ -60,7 +61,12 @@ Integration::Integration()
6061
, create_keyspace_query_("")
6162
, start_time_(0ull) {
6263
// Determine if the schema keyspaces table should be updated
63-
if (server_version_ >= "3.0.0") {
64+
// TODO: Make cass_version (and dse_version) available for all tests
65+
CCM::CassVersion cass_version = server_version_;
66+
if (Options::is_dse()) {
67+
cass_version = static_cast<CCM::DseVersion>(cass_version).get_cass_version();
68+
}
69+
if (cass_version >= "3.0.0") {
6470
system_schema_keyspaces_ = "system_schema.keyspaces";
6571
}
6672

@@ -391,13 +397,31 @@ bool Integration::force_decommission_node(unsigned int node) {
391397
return decommission_node(node, true);
392398
}
393399

394-
bool Integration::stop_node(unsigned int node) {
400+
bool Integration::start_node(unsigned int node) {
395401
// Stop the requested node
396-
bool status = ccm_->stop_node(node);
397-
if (status) {
398-
stopped_nodes_.push_back(node);
402+
if (ccm_->is_node_down(node, true)) {
403+
bool status = ccm_->start_node(node);
404+
std::vector<unsigned int>::iterator it = std::find(stopped_nodes_.begin(),
405+
stopped_nodes_.end(),
406+
node);
407+
if (it != stopped_nodes_.end()) {
408+
stopped_nodes_.erase(it);
409+
}
410+
return status;
399411
}
400-
return status;
412+
return false;
413+
}
414+
415+
bool Integration::stop_node(unsigned int node, bool is_kill /*= false*/) {
416+
// Stop the requested node
417+
if (ccm_->is_node_up(node, true)) {
418+
bool status = ccm_->stop_node(node, is_kill);
419+
if (status) {
420+
stopped_nodes_.push_back(node);
421+
}
422+
return status;
423+
}
424+
return false;
401425
}
402426

403427
std::string Integration::generate_contact_points(const std::string& ip_prefix,

cpp-driver/gtests/src/integration/integration.hpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,12 @@
9999
}
100100

101101
#define CHECK_VALUE_TYPE_VERSION(type) \
102-
if (this->server_version_ < type::supported_server_version()) { \
103-
SKIP_TEST_VERSION(this->server_version_.to_string(), \
102+
CCM::CassVersion cass_version = this->server_version_; \
103+
if (Options::is_dse()) { \
104+
cass_version = static_cast<CCM::DseVersion>(cass_version).get_cass_version(); \
105+
} \
106+
if (cass_version < type::supported_server_version()) { \
107+
SKIP_TEST_VERSION(cass_version.to_string(), \
104108
type::supported_server_version()) \
105109
}
106110

@@ -423,14 +427,26 @@ class Integration : public testing::Test {
423427
*/
424428
virtual bool force_decommission_node(unsigned int node);
425429

430+
/**
431+
* Start a node that was previously stopped to ensure that it is not restarted
432+
* after test is completed
433+
*
434+
* @param node Node that should be started
435+
* @return True if node was started; false otherwise (the node is invalid or
436+
* was already started)
437+
*/
438+
virtual bool start_node(unsigned int node);
439+
426440
/**
427441
* Stop a node that should be restarted after test is completed
428442
*
429443
* @param node Node that should be stopped
444+
* @param is_kill True if forced termination requested; false otherwise
445+
* (default: false)
430446
* @return True if node was stopped; false otherwise (the node is invalid or
431447
* was already stopped)
432448
*/
433-
virtual bool stop_node(unsigned int node);
449+
virtual bool stop_node(unsigned int node, bool is_kill = false);
434450

435451
/**
436452
* Generate the contact points for the cluster

cpp-driver/gtests/src/integration/tests/test_auth.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,11 @@ CASSANDRA_INTEGRATION_TEST_F(AuthenticationTests, BadCredentials) {
203203
CHECK_FAILURE;
204204

205205
// Add the proper logging criteria (based on server version)
206-
if (server_version_ >= "3.10") {
206+
CCM::CassVersion cass_version = this->server_version_;
207+
if (Options::is_dse()) {
208+
cass_version = static_cast<CCM::DseVersion>(cass_version).get_cass_version();
209+
}
210+
if (cass_version >= "3.10") {
207211
logger_.add_critera("Provided username invalid and/or password are incorrect");
208212
} else {
209213
logger_.add_critera("Username and/or password are incorrect");
@@ -241,7 +245,11 @@ CASSANDRA_INTEGRATION_TEST_F(AuthenticationTests, AuthenticatorSetErrorNull) {
241245
CHECK_FAILURE;
242246

243247
// Add the proper logging criteria (based on server version)
244-
if (server_version_ >= "3.10") {
248+
CCM::CassVersion cass_version = this->server_version_;
249+
if (Options::is_dse()) {
250+
cass_version = static_cast<CCM::DseVersion>(cass_version).get_cass_version();
251+
}
252+
if (cass_version >= "3.10") {
245253
logger_.add_critera("Provided username invalid and/or password are incorrect");
246254
} else {
247255
logger_.add_critera("Username and/or password are incorrect");

cpp-driver/gtests/src/integration/tests/test_consistency.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ CASSANDRA_INTEGRATION_TEST_F(ConsistencyTwoNodeClusterTests, SimpleLocalQuorum)
196196
*/
197197
CASSANDRA_INTEGRATION_TEST_F(ConsistencyTwoNodeClusterTests, SimpleEachQuorum) {
198198
CHECK_FAILURE;
199+
CHECK_VERSION(3.0.0);
199200

200201
// Assign the consistency level for the test
201202
insert_.set_consistency(CASS_CONSISTENCY_EACH_QUORUM);

cpp-driver/gtests/src/integration/tests/test_control_connection.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ CASSANDRA_INTEGRATION_TEST_F(ControlConnectionTests, TopologyChange) {
336336

337337
// Bootstrap a second node and ensure all hosts are actively used
338338
logger_.add_critera("New node " + (ccm_->get_ip_prefix() + "2") + " added");
339-
EXPECT_EQ(2, ccm_->bootstrap_node()); // Triggers a `NEW_NODE` event
339+
EXPECT_EQ(2u, ccm_->bootstrap_node()); // Triggers a `NEW_NODE` event
340340
EXPECT_TRUE(wait_for_logger(1));
341341
std::set<unsigned short> expected_nodes;
342342
expected_nodes.insert(1);
@@ -395,7 +395,7 @@ CASSANDRA_INTEGRATION_TEST_F(ControlConnectionTwoNodeClusterTests,
395395

396396
// Restart the second node and ensure all hosts are actively used
397397
reset_logger_criteria("Node ", logger_nodes, " is up");
398-
ccm_->start_node(2); // Triggers a `UP` event
398+
start_node(2); // Triggers a `UP` event
399399
ASSERT_TRUE(wait_for_logger(logger_nodes.size()));
400400
expected_nodes.insert(2);
401401
check_hosts(session, expected_nodes);

cpp-driver/gtests/src/integration/tests/test_dc_aware_policy.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ CASSANDRA_INTEGRATION_TEST_F(DcAwarePolicyTest, UsedHostsRemoteDc) {
9898
}
9999

100100
// Stop the whole local DC
101-
ccm_->stop_node(1, true);
102-
ccm_->stop_node(2, true);
101+
stop_node(1, true);
102+
stop_node(2, true);
103103

104104
{ // Run queries using the remote DC
105105
std::vector<std::string> attempted_hosts = validate();

cpp-driver/gtests/src/integration/tests/test_session.cpp

Lines changed: 89 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,35 +15,83 @@
1515
*/
1616

1717
#include "integration.hpp"
18+
1819
#include "cassandra.h"
20+
#include "scoped_lock.hpp"
21+
22+
#include <queue>
23+
24+
#define EVENT_MAXIMUM_WAIT_TIME_MS 5000
25+
#define EVENT_WAIT_FOR_NAP_MS 100
1926

2027
class SessionTest : public Integration {
2128
public:
2229
typedef std::pair<CassHostListenerEvent, std::string> Event;
23-
typedef std::vector<Event> Events;
30+
typedef std::queue<Event> Events;
31+
32+
SessionTest() {
33+
uv_mutex_init(&mutex_);
34+
}
35+
~SessionTest() {
36+
uv_mutex_destroy(&mutex_);
37+
}
2438

2539
void SetUp() {
2640
is_session_requested_ = false;
2741
Integration::SetUp();
2842
}
2943

30-
size_t event_count() { return events_.size(); }
31-
const Events& events() const { return events_; }
44+
void check_event(CassHostListenerEvent expected_event, short expected_node) {
45+
cass::ScopedMutex l(&mutex_);
46+
std::stringstream expected_address;
47+
expected_address << ccm_->get_ip_prefix() << expected_node;
48+
Event event = events_.front();
49+
EXPECT_EQ(expected_event, event.first);
50+
EXPECT_EQ(expected_address.str().c_str(), event.second);
51+
events_.pop();
52+
}
53+
bool wait_for_event(size_t expected_count) {
54+
start_timer();
55+
while (elapsed_time() < EVENT_MAXIMUM_WAIT_TIME_MS
56+
&& event_count() < expected_count) {
57+
msleep(EVENT_WAIT_FOR_NAP_MS);
58+
}
59+
return event_count() >= expected_count;
60+
}
3261

3362
protected:
63+
size_t event_count() {
64+
cass::ScopedMutex l(&mutex_);
65+
return events_.size();
66+
}
67+
void add_event(CassHostListenerEvent event, CassInet inet) {
68+
cass::ScopedMutex l(&mutex_);
69+
char address[CASS_INET_STRING_LENGTH];
70+
71+
cass_inet_string(inet, address);
72+
if (event == CASS_HOST_LISTENER_EVENT_ADD) {
73+
TEST_LOG("Host " << address << " has been ADDED");
74+
} else if (event == CASS_HOST_LISTENER_EVENT_REMOVE) {
75+
TEST_LOG("Host " << address << " has been REMOVED");
76+
} else if (event == CASS_HOST_LISTENER_EVENT_UP) {
77+
TEST_LOG("Host " << address << " is UP");
78+
} else if (event == CASS_HOST_LISTENER_EVENT_DOWN) {
79+
TEST_LOG("Host " << address << " is DOWN");
80+
} else {
81+
TEST_LOG_ERROR("Invalid event [" << event << "] for " << address);
82+
}
83+
84+
events_.push(Event(event, address));
85+
}
3486
static void on_host_listener(CassHostListenerEvent event,
3587
CassInet inet,
3688
void* data) {
3789
SessionTest* instance = static_cast<SessionTest*>(data);
38-
39-
char address[CASS_INET_STRING_LENGTH];
40-
uv_inet_ntop(inet.address_length == CASS_INET_V4_LENGTH ? AF_INET : AF_INET6,
41-
inet.address,
42-
address, CASS_INET_STRING_LENGTH);
43-
instance->events_.push_back(Event(event, address));
90+
instance->add_event(event, inet);
4491
}
4592

4693
private:
94+
uv_mutex_t mutex_;
4795
Events events_;
4896
};
4997

@@ -78,26 +126,42 @@ CASSANDRA_INTEGRATION_TEST_F(SessionTest, ExternalHostListener) {
78126
.with_host_listener_callback(on_host_listener, this);
79127
Session session = cluster.connect();
80128

81-
ASSERT_EQ(0u, event_count());
129+
// Initial node 1 events (add and up)
130+
ASSERT_TRUE(wait_for_event(2u));
131+
check_event(CASS_HOST_LISTENER_EVENT_ADD, 1);
132+
check_event(CASS_HOST_LISTENER_EVENT_UP, 1);
133+
134+
// Bootstrap node 2 (add and up events)
135+
EXPECT_EQ(2u, ccm_->bootstrap_node());
136+
ASSERT_TRUE(wait_for_event(2u));
137+
check_event(CASS_HOST_LISTENER_EVENT_ADD, 2);
138+
check_event(CASS_HOST_LISTENER_EVENT_UP, 2);
82139

83-
EXPECT_EQ(2, ccm_->bootstrap_node());
140+
// Stop node 1 (down event)
84141
stop_node(1);
142+
ASSERT_TRUE(wait_for_event(1u));
143+
check_event(CASS_HOST_LISTENER_EVENT_DOWN, 1);
144+
145+
// Restart node 1 (up event)
85146
ccm_->start_node(1);
147+
CCM::CassVersion cass_version = this->server_version_;
148+
if (Options::is_dse()) {
149+
cass_version = static_cast<CCM::DseVersion>(cass_version).get_cass_version();
150+
}
151+
if (cass_version >= "2.2") {
152+
ASSERT_TRUE(wait_for_event(1u));
153+
} else {
154+
ASSERT_TRUE(wait_for_event(3u)); // C* <= 2.1 fires remove and add event on restart
155+
check_event(CASS_HOST_LISTENER_EVENT_REMOVE, 1);
156+
check_event(CASS_HOST_LISTENER_EVENT_ADD, 1);
157+
}
158+
check_event(CASS_HOST_LISTENER_EVENT_UP, 1);
159+
160+
// Decomission node 1 (down and remove events)
86161
force_decommission_node(1);
162+
ASSERT_TRUE(wait_for_event(1u));
163+
check_event(CASS_HOST_LISTENER_EVENT_DOWN, 1);
164+
check_event(CASS_HOST_LISTENER_EVENT_REMOVE, 1);
87165

88166
session.close();
89-
90-
ASSERT_EQ(6u, event_count());
91-
EXPECT_EQ(CASS_HOST_LISTENER_EVENT_ADD, events()[0].first);
92-
EXPECT_EQ(ccm_->get_ip_prefix() + "2", events()[0].second);
93-
EXPECT_EQ(CASS_HOST_LISTENER_EVENT_UP, events()[1].first);
94-
EXPECT_EQ(ccm_->get_ip_prefix() + "2", events()[1].second);
95-
EXPECT_EQ(CASS_HOST_LISTENER_EVENT_DOWN, events()[2].first);
96-
EXPECT_EQ(ccm_->get_ip_prefix() + "1", events()[2].second);
97-
EXPECT_EQ(CASS_HOST_LISTENER_EVENT_UP, events()[3].first);
98-
EXPECT_EQ(ccm_->get_ip_prefix() + "1", events()[3].second);
99-
EXPECT_EQ(CASS_HOST_LISTENER_EVENT_DOWN, events()[4].first);
100-
EXPECT_EQ(ccm_->get_ip_prefix() + "1", events()[4].second);
101-
EXPECT_EQ(CASS_HOST_LISTENER_EVENT_REMOVE, events()[5].first);
102-
EXPECT_EQ(ccm_->get_ip_prefix() + "1", events()[5].second);
103167
}

cpp-driver/gtests/src/integration/tests/test_tracing.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ CASSANDRA_INTEGRATION_TEST_F(TracingTests, Simple) {
3535
Statement statement("SELECT * FROM system_traces.sessions WHERE session_id = ?", 1);
3636
statement.bind(0, tracing_id);
3737
Result result = session_.execute(statement);
38-
ASSERT_GT(result.row_count(), 0);
38+
ASSERT_GT(result.row_count(), 0u);
3939
Uuid session_id = result.first_row().column_by_name<Uuid>("session_id");
4040
ASSERT_FALSE(session_id.is_null());
4141
EXPECT_EQ(tracing_id, session_id);

0 commit comments

Comments
 (0)