Skip to content

Adjust and enable some ControlConnection integration tests #255

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 19, 2025
Merged
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ SCYLLA_TEST_FILTER := $(subst ${SPACE},${EMPTY},ClusterTests.*\
:PreparedTests.*\
:NamedParametersTests.*\
:CassandraTypes/CassandraTypesTests/*.Integration_Cassandra_*\
:ControlConnectionTests.*\
:BatchSingleNodeClusterTests*:BatchCounterSingleNodeClusterTests*:BatchCounterThreeNodeClusterTests*\
:ErrorTests.*\
:SslNoClusterTests*:SslNoSslOnClusterTests*\
Expand All @@ -25,6 +26,9 @@ SCYLLA_TEST_FILTER := $(subst ${SPACE},${EMPTY},ClusterTests.*\
:UseKeyspaceCaseSensitiveTests.*\
:-PreparedTests.Integration_Cassandra_PreparedIDUnchangedDuringReprepare\
:HeartbeatTests.Integration_Cassandra_HeartbeatFailed\
:ControlConnectionTests.Integration_Cassandra_TopologyChange\
:ControlConnectionTests.Integration_Cassandra_FullOutage\
:ControlConnectionTests.Integration_Cassandra_TerminatedUsingMultipleIoThreadsWithError\
:ExecutionProfileTest.InvalidName\
:*NoCompactEnabledConnection\
:PreparedMetadataTests.Integration_Cassandra_AlterProperlyUpdatesColumnCount\
Expand All @@ -43,6 +47,7 @@ CASSANDRA_TEST_FILTER := $(subst ${SPACE},${EMPTY},ClusterTests.*\
:PreparedTests.*\
:NamedParametersTests.*\
:CassandraTypes/CassandraTypesTests/*.Integration_Cassandra_*\
:ControlConnectionTests.*\
:ErrorTests.*\
:SslClientAuthenticationTests*:SslNoClusterTests*:SslNoSslOnClusterTests*:SslTests*\
:SchemaMetadataTest.*KeyspaceMetadata:SchemaMetadataTest.*MetadataIterator:SchemaMetadataTest.*View*\
Expand All @@ -55,6 +60,9 @@ CASSANDRA_TEST_FILTER := $(subst ${SPACE},${EMPTY},ClusterTests.*\
:-PreparedTests.Integration_Cassandra_PreparedIDUnchangedDuringReprepare\
:PreparedTests.Integration_Cassandra_FailFastWhenPreparedIDChangesDuringReprepare\
:HeartbeatTests.Integration_Cassandra_HeartbeatFailed\
:ControlConnectionTests.Integration_Cassandra_TopologyChange\
:ControlConnectionTests.Integration_Cassandra_FullOutage\
:ControlConnectionTests.Integration_Cassandra_TerminatedUsingMultipleIoThreadsWithError\
:SslTests.Integration_Cassandra_ReconnectAfterClusterCrashAndRestart\
:ExecutionProfileTest.InvalidName\
:*NoCompactEnabledConnection\
Expand Down
42 changes: 34 additions & 8 deletions scylla-rust-wrapper/src/cass_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl ToCassError for ExecutionError {
ExecutionError::BadQuery(bad_query) => bad_query.to_cass_error(),
ExecutionError::RequestTimeout(_) => CassError::CASS_ERROR_LIB_REQUEST_TIMED_OUT,
ExecutionError::EmptyPlan => CassError::CASS_ERROR_LIB_INVALID_STATE,
ExecutionError::MetadataError(_) => CassError::CASS_ERROR_LIB_INVALID_STATE,
ExecutionError::MetadataError(e) => e.to_cass_error(),
ExecutionError::ConnectionPoolError(e) => e.to_cass_error(),
ExecutionError::PrepareError(e) => e.to_cass_error(),
ExecutionError::LastAttemptError(e) => e.to_cass_error(),
Expand All @@ -47,11 +47,7 @@ impl ToCassError for ExecutionError {

impl ToCassError for ConnectionPoolError {
fn to_cass_error(&self) -> CassError {
// I know that TranslationError (corresponding to CASS_ERROR_LIB_HOST_RESOLUTION)
// is hidden under the ConnectionPoolError.
// However, we still have a lot work to do when it comes to error conversion.
// I will address it, once we start resolving all issues related to error conversion.
CassError::CASS_ERROR_LIB_UNABLE_TO_CONNECT
CassError::CASS_ERROR_LIB_NO_HOSTS_AVAILABLE
}
}

Expand Down Expand Up @@ -79,7 +75,7 @@ impl ToCassError for RequestAttemptError {
}
RequestAttemptError::UnableToAllocStreamId => CassError::CASS_ERROR_LIB_NO_STREAMS,
RequestAttemptError::BrokenConnectionError(_) => {
CassError::CASS_ERROR_LIB_UNABLE_TO_CONNECT
CassError::CASS_ERROR_LIB_NO_HOSTS_AVAILABLE
}
RequestAttemptError::BodyExtensionsParseError(_) => {
CassError::CASS_ERROR_LIB_MESSAGE_ENCODE
Expand Down Expand Up @@ -164,7 +160,7 @@ impl ToCassError for NewSessionError {
CassError::CASS_ERROR_LIB_NO_HOSTS_AVAILABLE
}
NewSessionError::EmptyKnownNodesList => CassError::CASS_ERROR_LIB_NO_HOSTS_AVAILABLE,
NewSessionError::MetadataError(_) => CassError::CASS_ERROR_LIB_INVALID_STATE,
NewSessionError::MetadataError(e) => e.to_cass_error(),
NewSessionError::UseKeyspaceError(_) => {
CassError::CASS_ERROR_LIB_UNABLE_TO_SET_KEYSPACE
}
Expand All @@ -174,6 +170,36 @@ impl ToCassError for NewSessionError {
}
}

impl ToCassError for MetadataError {
fn to_cass_error(&self) -> CassError {
match self {
MetadataError::ConnectionPoolError(e) => e.to_cass_error(),
MetadataError::FetchError(e) => match &e.error {
// Server bug - invalid CQL type in system table.
MetadataFetchErrorKind::InvalidColumnType(_) => {
CassError::CASS_ERROR_LIB_UNEXPECTED_RESPONSE
}
MetadataFetchErrorKind::PrepareError(e) => e.to_cass_error(),
MetadataFetchErrorKind::SerializationError(e) => e.to_cass_error(),
MetadataFetchErrorKind::NextRowError(_) => {
CassError::CASS_ERROR_LIB_UNEXPECTED_RESPONSE
}

// non_exhaustive
_ => CassError::CASS_ERROR_LAST_ENTRY,
},
// Remaining errors indicate a serious server bug - e.g. all peers have empty token lists.
MetadataError::Keyspaces(_)
| MetadataError::Peers(_)
| MetadataError::Tables(_)
| MetadataError::Udts(_) => CassError::CASS_ERROR_LIB_UNEXPECTED_RESPONSE,

// non_exhaustive
_ => CassError::CASS_ERROR_LAST_ENTRY,
}
}
}

impl ToCassError for BadKeyspaceName {
fn to_cass_error(&self) -> CassError {
match self {
Expand Down
17 changes: 10 additions & 7 deletions tests/src/integration/tests/test_control_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ CASSANDRA_INTEGRATION_TEST_F(ControlConnectionTests, ConnectUsingInvalidIpAddres
CHECK_FAILURE;

// Attempt to connect to the server using an invalid IP address
logger_.add_critera("Unable to establish a control connection to host "
"1.1.1.1 because of the following error: Underlying "
"connection error: Connection timeout");
logger_.add_critera("Could not fetch metadata, error: "
"Control connection pool error: The pool is broken; "
"Last connection failed with: Connect timeout elapsed");
Cluster cluster = Cluster::build().with_contact_points("1.1.1.1");
try {
cluster.connect();
Expand Down Expand Up @@ -185,7 +185,7 @@ CASSANDRA_INTEGRATION_TEST_F(ControlConnectionTests, ConnectUsingUnresolvableLoc

// Attempt to connect to the server using an unresolvable local IP address
Cluster cluster = default_cluster();
EXPECT_EQ(CASS_ERROR_LIB_HOST_RESOLUTION,
EXPECT_EQ(CASS_ERROR_LIB_BAD_PARAMS,
cass_cluster_set_local_address(cluster.get(), "unknown.invalid"));
}

Expand All @@ -204,7 +204,9 @@ CASSANDRA_INTEGRATION_TEST_F(ControlConnectionTests, ConnectUsingUnbindableLocal
CHECK_FAILURE;

// Attempt to connect to the server using an unbindable local IP address
logger_.add_critera("Unable to bind local address: address not available");
logger_.add_critera("Could not fetch metadata, error: "
"Control connection pool error: The pool is broken; "
"Last connection failed with: Cannot assign requested address");
Cluster cluster = default_cluster().with_local_address("1.1.1.1");
try {
cluster.connect();
Expand Down Expand Up @@ -234,8 +236,9 @@ CASSANDRA_INTEGRATION_TEST_F(ControlConnectionTests,
// Attempt to connect to the server using an valid local IP address
// but invalid remote address. The specified remote is not routable
// from the specified local.
logger_.add_critera("Unable to establish a control connection to host "
"1.1.1.1 because of the following error:");
logger_.add_critera("Could not fetch metadata, error: "
"Control connection pool error: The pool is broken; "
"Last connection failed with: Invalid argument");
Cluster cluster = Cluster::build().with_contact_points("1.1.1.1").with_local_address("127.0.0.1");
try {
cluster.connect();
Expand Down