Skip to content

Commit

Permalink
result: implement tests for cass_result basic api.
Browse files Browse the repository at this point in the history
Implemented tests for two cases:
- Rows result - i.e. result of SELECT query.
- non-Rows result - e.g. result of INSERT query
  • Loading branch information
muzarski committed Oct 7, 2024
1 parent 8296d5e commit 69eb3bf
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 4 deletions.
6 changes: 3 additions & 3 deletions scylla-rust-wrapper/src/cass_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ include!(concat!(env!("OUT_DIR"), "/cppdriver_data_types.rs"));
include!(concat!(env!("OUT_DIR"), "/cppdriver_data_query_error.rs"));
include!(concat!(env!("OUT_DIR"), "/cppdriver_batch_types.rs"));

#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UDTDataType {
// Vec to preserve the order of types
pub field_types: Vec<(String, Arc<CassDataType>)>,
Expand Down Expand Up @@ -131,14 +131,14 @@ impl Default for UDTDataType {
}
}

#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum MapDataType {
Untyped,
Key(Arc<CassDataType>),
KeyAndValue(Arc<CassDataType>, Arc<CassDataType>),
}

#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum CassDataType {
Value(CassValueType),
UDT(UDTDataType),
Expand Down
191 changes: 191 additions & 0 deletions scylla-rust-wrapper/src/query_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1377,6 +1377,197 @@ pub unsafe extern "C" fn cass_result_paging_state_token(
CassError::CASS_OK
}

#[cfg(test)]
mod tests {
use std::{ffi::c_char, ptr::addr_of_mut, sync::Arc};

use scylla::{
frame::response::result::{ColumnSpec, ColumnType, CqlValue, Row, TableSpec},
transport::PagingStateResponse,
};

use crate::{
cass_error::CassError,
cass_types::{CassDataType, CassValueType},
query_result::{
cass_result_column_data_type, cass_result_column_name, cass_result_first_row,
ptr_to_cstr_n, ptr_to_ref, size_t,
},
session::create_cass_rows_from_rows,
};

use super::{cass_result_column_count, cass_result_column_type, CassResult, CassResultData};

fn col_spec(name: &str, typ: ColumnType) -> ColumnSpec {
ColumnSpec {
table_spec: TableSpec::borrowed("ks", "tbl"),
name: name.to_string(),
typ,
}
}

const FIRST_COLUMN_NAME: &str = "bigint_col";
const SECOND_COLUMN_NAME: &str = "varint_col";
const THIRD_COLUMN_NAME: &str = "list_double_col";
fn create_cass_rows_result() -> CassResult {
let metadata = Arc::new(CassResultData::from_result_payload(
PagingStateResponse::NoMorePages,
vec![
col_spec(FIRST_COLUMN_NAME, ColumnType::BigInt),
col_spec(SECOND_COLUMN_NAME, ColumnType::Varint),
col_spec(
THIRD_COLUMN_NAME,
ColumnType::List(Box::new(ColumnType::Double)),
),
],
None,
None,
));

let rows = create_cass_rows_from_rows(
Some(vec![Row {
columns: vec![
Some(CqlValue::BigInt(42)),
None,
Some(CqlValue::List(vec![
CqlValue::Float(0.5),
CqlValue::Float(42.42),
CqlValue::Float(9999.9999),
])),
],
}]),
&metadata,
);

CassResult { rows, metadata }
}

unsafe fn cass_result_column_name_rust_str(
result_ptr: *const CassResult,
column_index: u64,
) -> Option<&'static str> {
let mut name_ptr: *const c_char = std::ptr::null();
let mut name_length: size_t = 0;
let cass_err = cass_result_column_name(
result_ptr,
column_index,
addr_of_mut!(name_ptr),
addr_of_mut!(name_length),
);
assert_eq!(CassError::CASS_OK, cass_err);
ptr_to_cstr_n(name_ptr, name_length)
}

#[test]
fn rows_cass_result_api_test() {
let result = create_cass_rows_result();

unsafe {
let result_ptr = std::ptr::addr_of!(result);

// cass_result_column_count test
{
let column_count = cass_result_column_count(result_ptr);
assert_eq!(3, column_count);
}

// cass_result_column_name test
{
let first_column_name = cass_result_column_name_rust_str(result_ptr, 0).unwrap();
assert_eq!(FIRST_COLUMN_NAME, first_column_name);
let second_column_name = cass_result_column_name_rust_str(result_ptr, 1).unwrap();
assert_eq!(SECOND_COLUMN_NAME, second_column_name);
let third_column_name = cass_result_column_name_rust_str(result_ptr, 2).unwrap();
assert_eq!(THIRD_COLUMN_NAME, third_column_name);
}

// cass_result_column_type test
{
let first_col_type = cass_result_column_type(result_ptr, 0);
assert_eq!(CassValueType::CASS_VALUE_TYPE_BIGINT, first_col_type);
let second_col_type = cass_result_column_type(result_ptr, 1);
assert_eq!(CassValueType::CASS_VALUE_TYPE_VARINT, second_col_type);
let third_col_type = cass_result_column_type(result_ptr, 2);
assert_eq!(CassValueType::CASS_VALUE_TYPE_LIST, third_col_type);
let out_of_bound_col_type = cass_result_column_type(result_ptr, 555);
assert_eq!(
CassValueType::CASS_VALUE_TYPE_UNKNOWN,
out_of_bound_col_type
);
}

// cass_result_column_data_type test
{
let first_col_data_type = ptr_to_ref(cass_result_column_data_type(result_ptr, 0));
assert_eq!(
&CassDataType::Value(CassValueType::CASS_VALUE_TYPE_BIGINT),
first_col_data_type
);
let second_col_data_type = ptr_to_ref(cass_result_column_data_type(result_ptr, 1));
assert_eq!(
&CassDataType::Value(CassValueType::CASS_VALUE_TYPE_VARINT),
second_col_data_type
);
let third_col_data_type = ptr_to_ref(cass_result_column_data_type(result_ptr, 2));
assert_eq!(
&CassDataType::List {
typ: Some(Arc::new(CassDataType::Value(
CassValueType::CASS_VALUE_TYPE_DOUBLE
))),
frozen: false
},
third_col_data_type
);
let out_of_bound_col_data_type = cass_result_column_data_type(result_ptr, 555);
assert!(out_of_bound_col_data_type.is_null());
}
}
}

fn create_non_rows_cass_result() -> CassResult {
let metadata = Arc::new(CassResultData::from_result_payload(
PagingStateResponse::NoMorePages,
vec![],
None,
None,
));
CassResult {
rows: None,
metadata,
}
}

#[test]
fn non_rows_cass_result_api_test() {
let result = create_non_rows_cass_result();

// Check that API functions do not panic when rows are empty - e.g. for INSERT queries.
unsafe {
let result_ptr = std::ptr::addr_of!(result);

assert_eq!(0, cass_result_column_count(result_ptr));
assert_eq!(
CassValueType::CASS_VALUE_TYPE_UNKNOWN,
cass_result_column_type(result_ptr, 0)
);
assert!(cass_result_column_data_type(result_ptr, 0).is_null());
assert!(cass_result_first_row(result_ptr).is_null());

{
let mut name_ptr: *const c_char = std::ptr::null();
let mut name_length: size_t = 0;
let cass_err = cass_result_column_name(
result_ptr,
0,
addr_of_mut!(name_ptr),
addr_of_mut!(name_length),
);
assert_eq!(CassError::CASS_ERROR_LIB_INDEX_OUT_OF_BOUNDS, cass_err);
}
}
}
}

// CassResult functions:
/*
extern "C" {
Expand Down
2 changes: 1 addition & 1 deletion scylla-rust-wrapper/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ pub unsafe extern "C" fn cass_session_execute(
}
}

fn create_cass_rows_from_rows(
pub(crate) fn create_cass_rows_from_rows(
rows: Option<Vec<Row>>,
metadata: &Arc<CassResultData>,
) -> Option<Vec<CassRow>> {
Expand Down

0 comments on commit 69eb3bf

Please sign in to comment.