-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: dierbei <[email protected]>
- Loading branch information
Showing
8 changed files
with
531 additions
and
191 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
fn get_random_file_path() -> std::io::Result<PathBuf> { | ||
let filename: String = rand::thread_rng() | ||
.sample_iter(&Alphanumeric) | ||
.take(10) | ||
.map(char::from) | ||
.collect(); | ||
|
||
let filepath = PathBuf::from(format!("/tmp/.tmp{}", filename)); | ||
|
||
Ok(filepath) | ||
} | ||
|
||
// fn remove_random_file(path: PathBuf) -> std::io::Result<()> { | ||
// std::fs::remove_file(path)?; | ||
|
||
// Ok(()) | ||
// } | ||
|
||
fn file_exists(path: &PathBuf) -> bool { | ||
std::path::Path::new(path).exists() | ||
} | ||
|
||
#[test] | ||
fn test_retrieve_checksum() { | ||
let data_str = "Some data followed by a checksum".as_bytes(); | ||
let calculated_checksum = calculate_checksum(data_str); | ||
|
||
let data = [data_str, calculated_checksum.as_slice()].concat(); | ||
|
||
let retrieved_checksum = retrieve_checksum(&data); | ||
assert_eq!(calculated_checksum, retrieved_checksum); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_store_async() { | ||
let random_path = get_random_file_path().unwrap(); | ||
|
||
let storage: Box<dyn Storage> = Box::new(LocalStorage::new_from_path(&random_path).await); | ||
let payload_data = "Some data to test raft".as_bytes(); | ||
let store_result = storage.store(payload_data).await; | ||
assert!(store_result.is_ok()); | ||
|
||
let disk_data = storage.retrieve().await.unwrap(); | ||
assert_eq!(payload_data.len() + CHECKSUM_LEN, disk_data.len()); | ||
|
||
let data = &disk_data[..disk_data.len() - CHECKSUM_LEN]; | ||
assert_eq!(payload_data, data); | ||
|
||
storage.delete().await.unwrap(); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_delete() { | ||
let random_path = get_random_file_path().unwrap(); | ||
|
||
let storage: Box<dyn Storage> = Box::new(LocalStorage::new_from_path(&random_path).await); | ||
let delete_result = storage.delete().await; | ||
assert!(delete_result.is_ok()); | ||
assert!(!file_exists(&random_path)); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_compaction_file_lt_max_file_size() { | ||
let random_path = get_random_file_path().unwrap(); | ||
|
||
let storage: Box<dyn Storage> = Box::new(LocalStorage::new_from_path(&random_path).await); | ||
let mock_data = vec![0u8; 1_000_000 /*1 MB*/ - 500]; | ||
let store_result = storage.store(&mock_data).await; | ||
assert!(store_result.is_ok()); | ||
|
||
let compaction_result = storage.compaction().await; | ||
assert!(compaction_result.is_ok()); | ||
assert!(file_exists(&random_path)); | ||
|
||
storage.delete().await.unwrap(); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_compaction_file_gt_max_file_size() { | ||
let random_path = get_random_file_path().unwrap(); | ||
|
||
let storage: Box<dyn Storage> = Box::new(LocalStorage::new_from_path(&random_path).await); | ||
let mock_data = vec![0u8; 1_000_000 /*1 MB*/]; | ||
let store_result = storage.store(&mock_data).await; | ||
assert!(store_result.is_ok()); | ||
|
||
let compaction_result = storage.compaction().await; | ||
assert!(compaction_result.is_ok()); | ||
|
||
assert!(!file_exists(&random_path)); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_retrieve_data() { | ||
let random_path = get_random_file_path().unwrap(); | ||
|
||
let storage: Box<dyn Storage> = Box::new(LocalStorage::new_from_path(&random_path).await); | ||
let log_entry_size = std::mem::size_of::<LogEntry>(); | ||
|
||
// Insert the first data first | ||
let entry1 = LogEntry { | ||
leader_id: 1, | ||
server_id: 1, | ||
term: 1, | ||
command: LogCommand::Set, | ||
data: 1, | ||
}; | ||
let serialize_data = bincode::serialize(&entry1).unwrap(); | ||
storage.store(&serialize_data).await.unwrap(); | ||
let disk_data = storage.retrieve().await.unwrap(); | ||
let log_entry_bytes = &disk_data[0..log_entry_size]; | ||
let disk_entry: LogEntry = bincode::deserialize(log_entry_bytes).unwrap(); | ||
assert_eq!(entry1, disk_entry); | ||
|
||
// Then insert the second data | ||
let entry2 = LogEntry { | ||
leader_id: 2, | ||
server_id: 2, | ||
term: 2, | ||
command: LogCommand::Set, | ||
data: 2, | ||
}; | ||
let serialize_data = bincode::serialize(&entry2).unwrap(); | ||
storage.store(&serialize_data).await.unwrap(); | ||
let disk_data = storage.retrieve().await.unwrap(); | ||
|
||
// Try to read two pieces of data and sit down to compare | ||
let mut log_entrys = vec![]; | ||
let mut cursor = Cursor::new(&disk_data); | ||
loop { | ||
let mut bytes_data = vec![0u8; log_entry_size]; | ||
if cursor.read_exact(&mut bytes_data).is_err() { | ||
break; | ||
} | ||
let struct_data: LogEntry = bincode::deserialize(&bytes_data).unwrap(); | ||
|
||
let mut checksum = [0u8; CHECKSUM_LEN]; | ||
if cursor.read_exact(&mut checksum).is_err() { | ||
break; | ||
} | ||
|
||
log_entrys.push(struct_data); | ||
} | ||
|
||
assert_eq!(vec![entry1, entry2], log_entrys); | ||
|
||
storage.delete().await.unwrap(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.