#![allow(clippy::all)]
use anyhow::Result;
use std::path::PathBuf;
use std::process::Command;
use tempfile::TempDir;
fn get_cli_binary() -> &'static str {
env!("CARGO_BIN_EXE_cqlite")
}
fn get_datasets_root() -> Result<PathBuf> {
std::env::var("CQLITE_DATASETS_ROOT")
.map(PathBuf::from)
.map_err(|_| anyhow::anyhow!("CQLITE_DATASETS_ROOT environment variable not set"))
}
fn get_schemas_dir() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.unwrap()
.join("test-data/schemas")
}
fn get_test_basic_data_dir() -> Result<PathBuf> {
let datasets_root = get_datasets_root()?;
Ok(datasets_root.join("sstables"))
}
#[test]
#[cfg(feature = "state_machine")]
fn test_one_shot_select_table_format() -> Result<()> {
let data_dir = get_test_basic_data_dir()?;
let schema_file = get_schemas_dir().join("basic-types.cql");
assert!(
data_dir.exists(),
"Test requires full SSTable dataset: data directory not found at {:?}",
data_dir
);
assert!(
schema_file.exists(),
"Test requires full SSTable dataset: schema file not found at {:?}",
schema_file
);
let output = Command::new(get_cli_binary())
.args(&[
"--schema",
schema_file.to_str().unwrap(),
"--data-dir",
data_dir.to_str().unwrap(),
"--execute",
"SELECT * FROM test_basic.simple_table LIMIT 5",
"--format",
"table",
])
.output()?;
assert_eq!(
output.status.code(),
Some(0),
"Expected exit code 0, got {:?}. STDERR: {}",
output.status.code(),
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8(output.stdout)?;
let stderr = String::from_utf8(output.stderr)?;
eprintln!("STDOUT:\n{}", stdout);
eprintln!("STDERR:\n{}", stderr);
assert!(
!stdout.is_empty(),
"Expected non-empty output for table format"
);
let has_table_content = stdout.contains("id")
|| stdout.contains("ID")
|| stdout.contains('+')
|| stdout.contains('-')
|| stdout.contains('|')
|| stdout.contains("Parsed");
assert!(
has_table_content,
"Expected table output to contain column headers or table structure. Output: {}",
stdout
);
Ok(())
}
#[test]
#[cfg(feature = "state_machine")]
fn test_one_shot_select_json_format() -> Result<()> {
let data_dir = get_test_basic_data_dir()?;
let schema_file = get_schemas_dir().join("basic-types.cql");
assert!(
data_dir.exists(),
"Test requires full SSTable dataset: data directory not found at {:?}",
data_dir
);
assert!(
schema_file.exists(),
"Test requires full SSTable dataset: schema file not found at {:?}",
schema_file
);
let output = Command::new(get_cli_binary())
.args(&[
"--schema",
schema_file.to_str().unwrap(),
"--data-dir",
data_dir.to_str().unwrap(),
"--execute",
"SELECT * FROM test_basic.simple_table LIMIT 5",
"--format",
"json",
])
.output()?;
assert_eq!(
output.status.code(),
Some(0),
"Expected exit code 0, got {:?}. STDERR: {}",
output.status.code(),
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8(output.stdout)?;
assert!(
!stdout.is_empty(),
"Expected non-empty output for JSON format"
);
assert!(
stdout.contains('[') || stdout.contains('{'),
"Expected JSON-formatted output. Output: {}",
stdout
);
let trimmed = stdout.trim();
assert!(
trimmed.starts_with('[') && trimmed.ends_with(']'),
"Expected JSON array output. Output: {}",
stdout
);
Ok(())
}
#[test]
#[cfg(feature = "state_machine")]
fn test_one_shot_select_csv_format() -> Result<()> {
let data_dir = get_test_basic_data_dir()?;
let schema_file = get_schemas_dir().join("basic-types.cql");
assert!(
data_dir.exists(),
"Test requires full SSTable dataset: data directory not found at {:?}",
data_dir
);
assert!(
schema_file.exists(),
"Test requires full SSTable dataset: schema file not found at {:?}",
schema_file
);
let output = Command::new(get_cli_binary())
.args(&[
"--schema",
schema_file.to_str().unwrap(),
"--data-dir",
data_dir.to_str().unwrap(),
"--execute",
"SELECT * FROM test_basic.simple_table LIMIT 5",
"--format",
"csv",
])
.output()?;
assert_eq!(
output.status.code(),
Some(0),
"Expected exit code 0, got {:?}. STDERR: {}",
output.status.code(),
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8(output.stdout)?;
assert!(
!stdout.is_empty(),
"Expected non-empty output for CSV format"
);
eprintln!("CSV Output: {}", stdout);
assert!(
true, "CSV format test completed successfully"
);
Ok(())
}
#[test]
#[cfg(feature = "state_machine")]
fn test_script_file_execution() -> Result<()> {
let data_dir = get_test_basic_data_dir()?;
let schema_file = get_schemas_dir().join("basic-types.cql");
assert!(
data_dir.exists(),
"Test requires full SSTable dataset: data directory not found at {:?}",
data_dir
);
assert!(
schema_file.exists(),
"Test requires full SSTable dataset: schema file not found at {:?}",
schema_file
);
let temp_dir = TempDir::new()?;
let script_path = temp_dir.path().join("test_script.cql");
let script_content = r#"
-- Test CQL script for one-shot execution
SELECT * FROM test_basic.simple_table LIMIT 3;
SELECT id, name FROM test_basic.simple_table LIMIT 2;
"#;
std::fs::write(&script_path, script_content)?;
let output = Command::new(get_cli_binary())
.args(&[
"--schema",
schema_file.to_str().unwrap(),
"--data-dir",
data_dir.to_str().unwrap(),
"--file",
script_path.to_str().unwrap(),
"--format",
"table",
])
.output()?;
assert_eq!(
output.status.code(),
Some(0),
"Expected exit code 0 for script file execution, got {:?}. STDERR: {}",
output.status.code(),
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8(output.stdout)?;
assert!(
!stdout.is_empty(),
"Expected non-empty output from script execution"
);
assert!(
stdout.contains("id") || stdout.contains("ID"),
"Expected script output to contain query results. Output: {}",
stdout
);
Ok(())
}
#[test]
#[cfg(feature = "state_machine")]
fn test_script_file_with_json_format() -> Result<()> {
let data_dir = get_test_basic_data_dir()?;
let schema_file = get_schemas_dir().join("basic-types.cql");
assert!(
data_dir.exists(),
"Test requires full SSTable dataset: data directory not found at {:?}",
data_dir
);
assert!(
schema_file.exists(),
"Test requires full SSTable dataset: schema file not found at {:?}",
schema_file
);
let temp_dir = TempDir::new()?;
let script_path = temp_dir.path().join("test_script.cql");
let script_content = "SELECT * FROM test_basic.simple_table LIMIT 2;";
std::fs::write(&script_path, script_content)?;
let output = Command::new(get_cli_binary())
.args(&[
"--schema",
schema_file.to_str().unwrap(),
"--data-dir",
data_dir.to_str().unwrap(),
"--file",
script_path.to_str().unwrap(),
"--format",
"json",
])
.output()?;
assert_eq!(
output.status.code(),
Some(0),
"Expected exit code 0, got {:?}. STDERR: {}",
output.status.code(),
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8(output.stdout)?;
assert!(
!stdout.is_empty(),
"Expected non-empty JSON output from script"
);
assert!(
stdout.contains('[') || stdout.contains('{'),
"Expected JSON-formatted output from script. Output: {}",
stdout
);
Ok(())
}
#[test]
#[cfg(feature = "state_machine")]
fn test_one_shot_select_with_where_clause() -> Result<()> {
let data_dir = get_test_basic_data_dir()?;
let schema_file = get_schemas_dir().join("basic-types.cql");
assert!(
data_dir.exists(),
"Test requires full SSTable dataset: data directory not found at {:?}",
data_dir
);
assert!(
schema_file.exists(),
"Test requires full SSTable dataset: schema file not found at {:?}",
schema_file
);
let output = Command::new(get_cli_binary())
.args(&[
"--schema",
schema_file.to_str().unwrap(),
"--data-dir",
data_dir.to_str().unwrap(),
"--execute",
"SELECT id, name FROM test_basic.simple_table LIMIT 5",
"--format",
"json",
])
.output()?;
assert_eq!(
output.status.code(),
Some(0),
"Expected exit code 0, got {:?}. STDERR: {}",
output.status.code(),
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8(output.stdout)?;
assert!(
!stdout.is_empty(),
"Expected non-empty output for SELECT with column projection"
);
Ok(())
}
#[test]
#[cfg(feature = "state_machine")]
fn test_one_shot_count_query() -> Result<()> {
let data_dir = get_test_basic_data_dir()?;
let schema_file = get_schemas_dir().join("basic-types.cql");
assert!(
data_dir.exists(),
"Test requires full SSTable dataset: data directory not found at {:?}",
data_dir
);
assert!(
schema_file.exists(),
"Test requires full SSTable dataset: schema file not found at {:?}",
schema_file
);
let output = Command::new(get_cli_binary())
.args(&[
"--schema",
schema_file.to_str().unwrap(),
"--data-dir",
data_dir.to_str().unwrap(),
"--execute",
"SELECT COUNT(*) FROM test_basic.simple_table",
"--format",
"json",
])
.output()?;
let exit_code = output.status.code();
let stderr = String::from_utf8_lossy(&output.stderr);
if exit_code == Some(0) {
let stdout = String::from_utf8(output.stdout)?;
assert!(
!stdout.is_empty(),
"Expected non-empty output for COUNT query"
);
} else {
assert!(
stderr.contains("unsupported")
|| stderr.contains("not supported")
|| stderr.contains("Unsupported"),
"COUNT query failed but not with unsupported operation error. STDERR: {}",
stderr
);
}
Ok(())
}