Skip to content

Commit a8c5a51

Browse files
committed
IT: test allow_remote_dcs_for_local_cl
DCAwarePolicy integration test was missing a test case for the `allow_remote_dcs_for_local_cl` parameter. This commit adds a test case that verifies the behavior of the DCAwarePolicy when this parameter is set to either logical value.
1 parent 3f6927f commit a8c5a51

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

tests/src/integration/tests/test_dc_aware_policy.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616

1717
#include "cassandra.h"
1818
#include "integration.hpp"
19+
#include "objects/error_result.hpp"
20+
#include "objects/execution_profile.hpp"
21+
#include "objects/statement.hpp"
1922

23+
#include "gtest/gtest.h"
2024
#include <algorithm>
2125
#include <iterator>
2226

@@ -56,6 +60,45 @@ class DcAwarePolicyTest : public Integration {
5660
return attempted_hosts;
5761
}
5862

63+
void validate_with_statement(Statement const& statement, bool const expect_no_hosts_available_error, bool const expect_remotes_used) {
64+
std::vector<std::string> attempted_hosts, temp;
65+
Result result;
66+
67+
result = session_.execute(statement, !expect_no_hosts_available_error);
68+
temp = result.attempted_hosts();
69+
std::copy(temp.begin(), temp.end(), std::back_inserter(attempted_hosts));
70+
71+
if (expect_no_hosts_available_error) {
72+
EXPECT_EQ(result.error_result().error_code(), CASS_ERROR_LIB_NO_HOSTS_AVAILABLE);
73+
return; // No hosts available, so nothing more to check.
74+
} else {
75+
// The query should succeed, so we can check the result.
76+
EXPECT_EQ(result.first_row().next().as<Varchar>(), Varchar("one"));
77+
}
78+
79+
if (expect_remotes_used) {
80+
// Verify that remote DC hosts were used.
81+
EXPECT_TRUE(contains(ccm_->get_ip_prefix() + "3", attempted_hosts) ||
82+
contains(ccm_->get_ip_prefix() + "4", attempted_hosts));
83+
84+
// Verify that no local DC hosts where used.
85+
//
86+
// Commented out, because I'm not sure if this is guaranteed:
87+
// the driver may have already noticed that the local DC hosts
88+
// are down and removed them from the host list.
89+
// EXPECT_TRUE(!contains(ccm_->get_ip_prefix() + "1", attempted_hosts) &&
90+
// !contains(ccm_->get_ip_prefix() + "2", attempted_hosts));
91+
} else {
92+
// Verify that local DC hosts were used.
93+
EXPECT_TRUE(contains(ccm_->get_ip_prefix() + "1", attempted_hosts) ||
94+
contains(ccm_->get_ip_prefix() + "2", attempted_hosts));
95+
96+
// Verify that no remote DC hosts were used.
97+
EXPECT_TRUE(!contains(ccm_->get_ip_prefix() + "3", attempted_hosts) &&
98+
!contains(ccm_->get_ip_prefix() + "4", attempted_hosts));
99+
}
100+
}
101+
59102
Statement select_statement(const std::string& key) {
60103
Statement statement(
61104
format_string(CASSANDRA_SELECT_VALUE_FORMAT, table_name_.c_str(), key.c_str()));
@@ -119,3 +162,73 @@ CASSANDRA_INTEGRATION_TEST_F(DcAwarePolicyTest, UsedHostsRemoteDc) {
119162
!contains(ccm_->get_ip_prefix() + "2", attempted_hosts));
120163
}
121164
}
165+
166+
/**
167+
* Verify that the "allow remote DCs for local CL" setting allows requests that are using
168+
* a local consistency level to be routed to remote DC nodes when the local DC nodes
169+
* are unavailable.
170+
* Also, verify that requests using a local consistency level are not routed to remote DC nodes
171+
* when the local DC nodes are unavailable if the "allow remote DCs for local CL" setting is false.
172+
*
173+
* @test_category load_balancing_policy:dc_aware
174+
*/
175+
CASSANDRA_INTEGRATION_TEST_F(DcAwarePolicyTest, AllowRemoteDcsForLocalCl) {
176+
CHECK_FAILURE
177+
178+
cluster_ = default_cluster();
179+
char const *const local_dc = "dc1";
180+
cluster_.with_load_balance_dc_aware(local_dc, 42, false);
181+
182+
ExecutionProfile profile_allowing_remote_dcs_for_local_cl = ExecutionProfile::build().with_load_balance_dc_aware(local_dc, 42, true);
183+
char const *const profile_name = "allow_remote_dcs_for_local_cl";
184+
cluster_.with_execution_profile(profile_name, profile_allowing_remote_dcs_for_local_cl);
185+
186+
connect(cluster_);
187+
188+
// Create a test table and add test data to it
189+
initialize();
190+
191+
Statement statement_with_nonlocal_consistency = select_statement("1");
192+
statement_with_nonlocal_consistency.set_consistency(CASS_CONSISTENCY_TWO);
193+
194+
Statement statement_with_local_consistency = select_statement("1");
195+
statement_with_local_consistency.set_consistency(CASS_CONSISTENCY_LOCAL_ONE);
196+
197+
std::cerr << "Testing with `allow_remote_dcs_for_local_cl`=`false`" << std::endl;
198+
{
199+
std::cerr << "Running nonlocal statement with local DC available" << std::endl;
200+
// With local DC available, everything should succeed and only local DC hosts should be used.
201+
validate_with_statement(statement_with_nonlocal_consistency, false, false);
202+
203+
std::cerr << "Running local statement with local DC available" << std::endl;
204+
// With local DC available, everything should succeed and only local DC hosts should be used.
205+
validate_with_statement(statement_with_local_consistency, false, false);
206+
207+
// Stop the whole local DC.
208+
stop_node(1, true);
209+
stop_node(2, true);
210+
211+
std::cerr << "Running nonlocal statement with local DC unavailable" << std::endl;
212+
// With local DC unavailable, remote DC available and nonlocal consistency used, remote hosts should be used and the request should succeed.
213+
validate_with_statement(statement_with_nonlocal_consistency, false, true);
214+
215+
std::cerr << "Running local statement with local DC unavailable" << std::endl;
216+
// With local DC unavailable, remote DC available and local consistency used, remote hosts should be forbidden and the request should fail.
217+
validate_with_statement(statement_with_local_consistency, true, false);
218+
}
219+
220+
statement_with_local_consistency.set_execution_profile(profile_name);
221+
statement_with_nonlocal_consistency.set_execution_profile(profile_name);
222+
std::cerr << "Testing with `allow_remote_dcs_for_local_cl`=`true`" << std::endl;
223+
{
224+
// The local DC nodes are still dead.
225+
226+
std::cerr << "Running nonlocal statement with local DC unavailable" << std::endl;
227+
// With local DC unavailable, remote DC available and nonlocal consistency used, remote hosts should be used and the request should succeed.
228+
validate_with_statement(statement_with_nonlocal_consistency, false, true);
229+
230+
std::cerr << "Running local statement with local DC unavailable" << std::endl;
231+
// With local DC unavailable, remote DC available and local consistency used, remote hosts should be used and the request should succeed.
232+
validate_with_statement(statement_with_local_consistency, false, true);
233+
}
234+
}

0 commit comments

Comments
 (0)