#![forbid(unsafe_code)]
use std::error::Error;
use haematite::db::{DatabaseConfig, DatabaseError};
use haematite::store::NodeCacheBudget;
use haematite_cli::serve::protocol::Selection;
use haematite_cli::serve::storage::{Failure, Storage};
type TestResult = Result<(), Box<dyn Error>>;
#[test]
fn fresh_served_store_reopens_with_the_path_writer() -> TestResult {
let directory = tempfile::tempdir()?;
let path = directory.path().join("database");
let storage = Storage::create(
DatabaseConfig {
data_dir: path.clone(),
shard_count: 1,
distributed: None,
executor_threads: Some(1),
node_cache_budget: Some(NodeCacheBudget::Unlimited),
retention: haematite::Retention::KeepAll,
},
NodeCacheBudget::Unlimited,
long_wait_interval(),
)?;
let selection = Selection {
branch: "main".to_owned(),
version: None,
};
let before = storage.capture(&selection)?;
drop(storage);
let storage = Storage::open(&path, NodeCacheBudget::Unlimited, long_wait_interval())?;
let after = storage.capture(&selection)?;
assert_eq!(after.version, before.version);
assert_eq!(after.shards, before.shards);
storage.reader()?;
Ok(())
}
#[test]
fn path_writer_error_maps_to_the_named_serve_refusal() {
let failure = Failure::from(DatabaseError::PathWriterRequired { found: 1 });
assert_eq!(failure.code, "store_writer_unsupported");
assert_eq!(
failure.message,
"store format stamp 1; serve writes only bytes-v2 stores"
);
assert_eq!(failure.path, None);
}
#[test]
fn other_database_errors_keep_the_storage_failure_mapping() {
let failure = Failure::from(DatabaseError::InvalidShardCount);
assert_eq!(failure.code, "storage_unavailable");
assert_eq!(failure.message, "database shard_count must be at least 1");
}
const fn long_wait_interval() -> std::time::Duration {
const LONG_WAIT_INTERVAL: std::time::Duration = std::time::Duration::from_secs(1);
LONG_WAIT_INTERVAL
}