#![allow(missing_docs)]
use std::fs::{self, File, OpenOptions};
use tempfile::{tempdir, NamedTempFile};
use wireshift::ops::{Read, Write};
use wireshift::{BackendPreference, Ring, RingConfig};
fn fallback_ring() -> Ring {
Ring::new(RingConfig::default().with_backend(BackendPreference::Fallback)).expect("ring")
}
#[test]
fn batch_hundred_reads_complete_with_correct_data() {
let dir = tempdir().expect("dir");
let ring = Ring::new(
RingConfig::default()
.with_backend(BackendPreference::Fallback)
.with_queue_depth(32),
)
.expect("ring");
let mut paths = Vec::new();
for idx in 0..100 {
let path = dir.path().join(format!("file-{idx}.txt"));
fs::write(&path, format!("data-{idx:03}")).expect("write");
paths.push(path);
}
let ops = paths
.iter()
.map(|path| Read::new(File::open(path).expect("open"), 0, 16).expect("op"));
let results = ring.batch(ops).expect("batch");
assert_eq!(results.len(), 100);
for (idx, result) in results.iter().enumerate() {
assert_eq!(result.buffer.filled(), format!("data-{idx:03}").as_bytes());
}
}
#[test]
fn batch_write_then_readback_matches_each_payload() {
let dir = tempdir().expect("dir");
let ring = fallback_ring();
let mut writes = Vec::new();
let mut expected = Vec::new();
for idx in 0..24 {
let path = dir.path().join(format!("batch-{idx}.txt"));
let file = OpenOptions::new()
.create(true)
.truncate(true)
.write(true)
.open(&path)
.expect("open");
let payload = format!("batch-{idx}-payload");
expected.push((path, payload.clone()));
writes.push(Write::new(file, 0, payload.as_bytes()).expect("write"));
}
let results = ring.batch(writes).expect("batch");
assert!(results.iter().all(|bytes| *bytes > 0));
for (path, payload) in expected {
assert_eq!(fs::read(path).expect("read"), payload.as_bytes().to_vec());
}
}
#[test]
fn batch_returns_first_operation_error_with_context() {
let temp = NamedTempFile::new().expect("temp");
let ring = fallback_ring();
let file = File::open(temp.path()).expect("open");
let dir = File::open(".").expect("dir");
let error = ring
.batch([
Read::new(file, 0, 4).expect("read"),
Read::new(dir, 0, 4).expect("read"),
])
.expect_err("second read must fail");
assert!(error.to_string().contains("Fix:"));
}
#[test]
fn batch_can_process_more_than_one_thousand_operations() {
let dir = tempdir().expect("dir");
let ring = Ring::new(
RingConfig::default()
.with_backend(BackendPreference::Fallback)
.with_queue_depth(64),
)
.expect("ring");
let mut paths = Vec::new();
for idx in 0..1_024 {
let path = dir.path().join(format!("bulk-{idx}.txt"));
fs::write(&path, b"x").expect("write");
paths.push(path);
}
let results = ring
.batch(
paths
.iter()
.map(|path| Read::new(File::open(path).expect("open"), 0, 1).expect("op")),
)
.expect("batch");
assert_eq!(results.len(), 1_024);
assert!(results.iter().all(|result| result.buffer.filled() == b"x"));
}