Skip to content

Add integration tests for query parameters #1235

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

Open
wants to merge 8 commits into
base: branch-hackathon
Choose a base branch
from
28 changes: 0 additions & 28 deletions scylla/src/client/session_test.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use super::session_builder::SessionBuilder;
use crate as scylla;
use crate::cluster::metadata::{ColumnType, NativeType};
use crate::query::Query;
Expand All @@ -7,35 +6,8 @@ use crate::routing::Token;
use crate::utils::test_utils::{
create_new_session_builder, setup_tracing, unique_keyspace_name, PerformDDL,
};
use futures::FutureExt;
use scylla_cql::frame::request::query::{PagingState, PagingStateResponse};
use scylla_cql::serialize::row::SerializedValues;
use tokio::net::TcpListener;

#[tokio::test]
async fn test_connection_failure() {
setup_tracing();
// Make sure that Session::create fails when the control connection
// fails to connect.

// Create a dummy server which immediately closes the connection.
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
let addr = listener.local_addr().unwrap();

let (fut, _handle) = async move {
loop {
let _ = listener.accept().await;
}
}
.remote_handle();
tokio::spawn(fut);

let res = SessionBuilder::new().known_node_addr(addr).build().await;
match res {
Ok(_) => panic!("Unexpected success"),
Err(err) => println!("Connection error (it was expected): {:?}", err),
}
}

#[tokio::test]
async fn test_prepared_statement() {
Expand Down
65 changes: 65 additions & 0 deletions scylla/tests/integration/cql_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use scylla::serialize::value::SerializeValue;
use scylla::value::{Counter, CqlDate, CqlTime, CqlTimestamp, CqlTimeuuid, CqlValue, CqlVarint};
use scylla::{DeserializeValue, SerializeValue};
use std::cmp::PartialEq;
use std::collections::{HashMap, HashSet};
use std::fmt::Debug;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
Expand Down Expand Up @@ -1863,3 +1864,67 @@ async fn test_udt_with_missing_field() {
)
.await;
}

/// ScyllaDB does not distinguish empty collections from nulls. That is, INSERTing an empty collection
/// is equivalent to nullifying the corresponding column.
/// As pointed out in [#1001](https://github.com/scylladb/scylla-rust-driver/issues/1001), it's a nice
/// QOL feature to be able to deserialize empty CQL collections to empty Rust collections instead of
/// `None::<RustCollection>`. This test checks that.
#[tokio::test]
async fn test_deserialize_empty_collections() {
// Setup session.
let ks = unique_keyspace_name();
let session = create_new_session_builder().build().await.unwrap();
session.ddl(format!("CREATE KEYSPACE IF NOT EXISTS {} WITH REPLICATION = {{'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}}", ks)).await.unwrap();
session.use_keyspace(&ks, true).await.unwrap();

async fn deserialize_empty_collection<
Collection: Default + DeserializeOwnedValue + SerializeValue,
>(
session: &Session,
collection_name: &str,
collection_type_params: &str,
) -> Collection {
// Create a table for the given collection type.
let table_name = "test_empty_".to_owned() + collection_name;
let query = format!(
"CREATE TABLE {} (n int primary key, c {}<{}>)",
table_name, collection_name, collection_type_params
);
session.ddl(query).await.unwrap();

// Populate the table with an empty collection, effectively inserting null as the collection.
session
.query_unpaged(
format!("INSERT INTO {} (n, c) VALUES (?, ?)", table_name,),
(0, Collection::default()),
)
.await
.unwrap();

let query_rows_result = session
.query_unpaged(format!("SELECT c FROM {}", table_name), ())
.await
.unwrap()
.into_rows_result()
.unwrap();
let (collection,) = query_rows_result.first_row::<(Collection,)>().unwrap();

// Drop the table
collection
}

let list = deserialize_empty_collection::<Vec<i32>>(&session, "list", "int").await;
assert!(list.is_empty());

let set = deserialize_empty_collection::<HashSet<i64>>(&session, "set", "bigint").await;
assert!(set.is_empty());

let map = deserialize_empty_collection::<HashMap<bool, CqlVarint>>(
&session,
"map",
"boolean, varint",
)
.await;
assert!(map.is_empty());
}
1 change: 1 addition & 0 deletions scylla/tests/integration/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod shards;
mod silent_prepare_batch;
mod silent_prepare_query;
mod skip_metadata_optimization;
mod statement;
mod tablets;
#[path = "../common/utils.rs"]
mod utils;
Loading
Loading