#[cfg(test)]
mod tests {
use bytes::Bytes;
use tempfile::TempDir;
use crate::{LogEntry, LogId};
use crate::model::LogEntryPayload;
use crate::storage::{LogReader, LogWriter};
use crate::storage::rocksdb_impl::RocksdbLogStore;
use crate::storage::rocksdb_impl::storage::{from_key, to_key};
fn create_temp_store() -> (TempDir, RocksdbLogStore) {
let tmp_dir = TempDir::with_prefix("pacifica-rs-test").unwrap();
let store = RocksdbLogStore::new(tmp_dir.path());
(tmp_dir, store)
}
fn create_test_log_entry(index: usize, term: usize) -> LogEntry {
let log_id = LogId::new(term, index);
let payload = LogEntryPayload::new(Bytes::from(vec![1, 2, 3, 4]));
LogEntry::new(log_id, payload)
}
fn run_async_test<F>(f: F) where F: std::future::Future<Output = ()> {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(f);
}
#[test]
fn test_append_and_get_entry() {
run_async_test(async {
let (_tmp_dir, mut store) = create_temp_store();
let entry = create_test_log_entry(1, 1);
store.append_entry(entry.clone()).await.unwrap();
let retrieved = store.get_log_entry(1).await.unwrap();
assert!(retrieved.is_some());
assert_eq!(retrieved.unwrap(), entry);
let not_found = store.get_log_entry(999).await.unwrap();
assert!(not_found.is_none());
});
}
#[test]
fn test_get_first_last_log_index() {
run_async_test(async {
let (_tmp_dir, mut store) = create_temp_store();
assert!(store.get_first_log_index().await.unwrap().is_none());
assert!(store.get_last_log_index().await.unwrap().is_none());
for i in 1..=5 {
store.append_entry(create_test_log_entry(i, 1)).await.unwrap();
}
assert_eq!(store.get_first_log_index().await.unwrap(), Some(1));
assert_eq!(store.get_last_log_index().await.unwrap(), Some(5));
});
}
#[test]
fn test_truncate_prefix() {
run_async_test(async {
let (_tmp_dir, mut store) = create_temp_store();
for i in 1..=5 {
store.append_entry(create_test_log_entry(i, 1)).await.unwrap();
}
store.truncate_prefix(3).await.unwrap();
assert!(store.get_log_entry(1).await.unwrap().is_none());
assert!(store.get_log_entry(2).await.unwrap().is_none());
assert!(store.get_log_entry(3).await.unwrap().is_some());
assert!(store.get_log_entry(4).await.unwrap().is_some());
assert!(store.get_log_entry(5).await.unwrap().is_some());
});
}
#[test]
fn test_truncate_suffix() {
run_async_test(async {
let (_tmp_dir, mut store) = create_temp_store();
for i in 1..=5 {
store.append_entry(create_test_log_entry(i, 1)).await.unwrap();
}
store.truncate_suffix(3).await.unwrap();
assert!(store.get_log_entry(1).await.unwrap().is_some());
assert!(store.get_log_entry(2).await.unwrap().is_some());
assert!(store.get_log_entry(3).await.unwrap().is_some());
assert!(store.get_log_entry(4).await.unwrap().is_none());
assert!(store.get_log_entry(5).await.unwrap().is_none());
});
}
#[test]
fn test_reset() {
run_async_test(async {
let (_tmp_dir, mut store) = create_temp_store();
for i in 1..=5 {
store.append_entry(create_test_log_entry(i, 1)).await.unwrap();
}
store.reset(0).await.unwrap();
for i in 1..=5 {
assert!(store.get_log_entry(i).await.unwrap().is_none());
}
});
}
#[test]
fn test_key_conversion() {
let test_index = 12345;
let key = to_key(test_index);
let converted_index = from_key(&key);
assert_eq!(test_index, converted_index);
}
#[test]
fn test_flush() {
run_async_test(async {
let (_tmp_dir, mut store) = create_temp_store();
store.append_entry(create_test_log_entry(1, 1)).await.unwrap();
store.flush().await.unwrap();
});
}
}