#![cfg(all(test, feature = "state_machine"))]
#![allow(clippy::all)]
use assert_cmd::Command;
use predicates::prelude::*;
use std::path::PathBuf;
fn test_data_dir() -> PathBuf {
let root = std::env::var("CQLITE_DATASETS_ROOT")
.map(PathBuf::from)
.unwrap_or_else(|_| {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.expect("Failed to get parent directory")
.join("test-data/datasets")
});
let sstables_path = root.join("sstables");
if sstables_path.exists() {
sstables_path
} else {
root
}
}
fn test_schema_file() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.expect("Failed to get parent directory")
.join("test-data/schemas/basic-types.cql")
}
fn get_simple_table_path() -> PathBuf {
let root = test_data_dir();
let table_dir = root
.join("test_basic")
.join("simple_table-6aa08200a25111f0a3fef1a551383fb9");
table_dir.join("nb-1-big-Data.db")
}
#[test]
#[ignore = "Requires working ingestion system - table discovery not yet stable"]
fn test_valid_table_query_succeeds() {
let schema = test_schema_file();
let data_dir = test_data_dir();
assert!(
schema.exists() && data_dir.exists(),
"Test requires schema at {:?} and data at {:?}",
schema,
data_dir
);
let mut cmd = Command::cargo_bin("cqlite").expect("Failed to find cqlite binary");
cmd.arg("--schema")
.arg(&schema)
.arg("--data-dir")
.arg(&data_dir)
.arg("-e")
.arg("SELECT * FROM test_basic.simple_table LIMIT 1")
.arg("--format")
.arg("json");
cmd.assert().success();
}
#[test]
fn test_nonexistent_table_fails_fast() {
let schema = test_schema_file();
let data_dir = test_data_dir();
assert!(
schema.exists() && data_dir.exists(),
"Test requires schema at {:?} and data at {:?}",
schema,
data_dir
);
let mut cmd = Command::cargo_bin("cqlite").expect("Failed to find cqlite binary");
cmd.arg("--schema")
.arg(&schema)
.arg("--data-dir")
.arg(&data_dir)
.arg("-e")
.arg("SELECT * FROM test_basic.nonexistent_table");
cmd.assert()
.failure()
.stderr(predicate::str::contains("Schema not found for table"))
.stderr(predicate::str::contains("nonexistent_table"))
.stderr(predicate::str::contains("Troubleshooting"));
}
#[test]
fn test_error_message_includes_troubleshooting() {
let schema = test_schema_file();
let data_dir = test_data_dir();
assert!(
schema.exists() && data_dir.exists(),
"Test requires schema at {:?} and data at {:?}",
schema,
data_dir
);
let mut cmd = Command::cargo_bin("cqlite").expect("Failed to find cqlite binary");
cmd.arg("--schema")
.arg(&schema)
.arg("--data-dir")
.arg(&data_dir)
.arg("-e")
.arg("SELECT * FROM test_basic.missing_table");
cmd.assert()
.failure()
.stderr(predicate::str::contains(
"Verify table name matches schema definition",
))
.stderr(predicate::str::contains(
"Check that schema file was loaded correctly",
));
}
#[test]
fn test_insert_statement_validation() {
let schema = test_schema_file();
let data_dir = test_data_dir();
assert!(
schema.exists() && data_dir.exists(),
"Test requires schema at {:?} and data at {:?}",
schema,
data_dir
);
let mut cmd = Command::cargo_bin("cqlite").expect("Failed to find cqlite binary");
cmd.arg("--schema")
.arg(&schema)
.arg("--data-dir")
.arg(&data_dir)
.arg("-e")
.arg(
"INSERT INTO test_basic.nonexistent (id) VALUES (550e8400-e29b-41d4-a716-446655440000)",
);
cmd.assert()
.failure()
.stderr(predicate::str::contains("Schema not found"));
}
#[test]
fn test_update_statement_validation() {
let schema = test_schema_file();
let data_dir = test_data_dir();
assert!(
schema.exists() && data_dir.exists(),
"Test requires schema at {:?} and data at {:?}",
schema,
data_dir
);
let mut cmd = Command::cargo_bin("cqlite").expect("Failed to find cqlite binary");
cmd.arg("--schema")
.arg(&schema)
.arg("--data-dir")
.arg(&data_dir)
.arg("-e")
.arg("UPDATE test_basic.nonexistent SET name = 'test' WHERE id = 550e8400-e29b-41d4-a716-446655440000");
cmd.assert()
.failure()
.stderr(predicate::str::contains("Schema not found"));
}
#[test]
fn test_delete_statement_validation() {
let schema = test_schema_file();
let data_dir = test_data_dir();
assert!(
schema.exists() && data_dir.exists(),
"Test requires schema at {:?} and data at {:?}",
schema,
data_dir
);
let mut cmd = Command::cargo_bin("cqlite").expect("Failed to find cqlite binary");
cmd.arg("--schema")
.arg(&schema)
.arg("--data-dir")
.arg(&data_dir)
.arg("-e")
.arg("DELETE FROM test_basic.nonexistent WHERE id = 550e8400-e29b-41d4-a716-446655440000");
cmd.assert()
.failure()
.stderr(predicate::str::contains("Schema not found"));
}
#[test]
fn test_fallback_feature_bypasses_validation() {
let table_path = get_simple_table_path();
let mut cmd = Command::cargo_bin("cqlite").expect("Failed to find cqlite binary");
cmd.arg("--enable-select-fallback")
.arg("-e")
.arg(format!("SELECT * FROM {}", table_path.display()));
let output = cmd.output().expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
!stderr.contains("Schema not found for table"),
"Fallback should bypass schema validation. Stderr: {}",
stderr
);
}
#[test]
fn test_unqualified_table_name_fails() {
let schema = test_schema_file();
let data_dir = test_data_dir();
assert!(
schema.exists() && data_dir.exists(),
"Test requires schema at {:?} and data at {:?}",
schema,
data_dir
);
let mut cmd = Command::cargo_bin("cqlite").expect("Failed to find cqlite binary");
cmd.arg("--schema")
.arg(&schema)
.arg("--data-dir")
.arg(&data_dir)
.arg("-e")
.arg("SELECT * FROM nonexistent_table");
cmd.assert().failure();
}
#[test]
#[ignore = "Requires working ingestion system - table discovery not yet stable"]
fn test_qualified_table_name_with_valid_keyspace_succeeds() {
let schema = test_schema_file();
let data_dir = test_data_dir();
assert!(
schema.exists() && data_dir.exists(),
"Test requires schema at {:?} and data at {:?}",
schema,
data_dir
);
let mut cmd = Command::cargo_bin("cqlite").expect("Failed to find cqlite binary");
cmd.arg("--schema")
.arg(&schema)
.arg("--data-dir")
.arg(&data_dir)
.arg("-e")
.arg("SELECT * FROM test_basic.simple_table LIMIT 1")
.arg("--format")
.arg("json");
cmd.assert().success();
}
#[test]
fn test_schema_validation_failure_exit_code() {
let schema = test_schema_file();
let data_dir = test_data_dir();
assert!(
schema.exists() && data_dir.exists(),
"Test requires schema at {:?} and data at {:?}",
schema,
data_dir
);
let mut cmd = Command::cargo_bin("cqlite").expect("Failed to find cqlite binary");
cmd.arg("--schema")
.arg(&schema)
.arg("--data-dir")
.arg(&data_dir)
.arg("-e")
.arg("SELECT * FROM test_basic.nonexistent_table");
let output = cmd.output().expect("Failed to execute command");
assert!(
!output.status.success(),
"Schema validation failure should return non-zero exit code"
);
let exit_code = output.status.code().unwrap_or(1);
assert_ne!(exit_code, 0, "Exit code should be non-zero for errors");
}