2.3 KiB
2.3 KiB
SQ-003: Simulation I/O Traits
Status: [x] DONE
Blocked by: SQ-000
Priority: High
Description
Define the trait abstractions for Clock and FileSystem that allow swapping real I/O for deterministic simulated I/O. This is the foundation of TigerBeetle-style testing.
Files to Create/Modify
crates/sq-sim/src/lib.rs- re-exportscrates/sq-sim/src/clock.rs- Clock trait + RealClock + SimClockcrates/sq-sim/src/fs.rs- FileSystem trait + FileHandle trait + RealFileSystem + InMemoryFileSystem
Key Traits
pub trait Clock: Send + Sync {
fn now(&self) -> std::time::Instant;
async fn sleep(&self, duration: Duration);
}
pub trait FileSystem: Send + Sync {
async fn create_dir_all(&self, path: &Path) -> Result<()>;
async fn open_read(&self, path: &Path) -> Result<Box<dyn FileHandle>>;
async fn open_write(&self, path: &Path) -> Result<Box<dyn FileHandle>>;
async fn open_append(&self, path: &Path) -> Result<Box<dyn FileHandle>>;
async fn remove_file(&self, path: &Path) -> Result<()>;
async fn list_dir(&self, path: &Path) -> Result<Vec<PathBuf>>;
async fn exists(&self, path: &Path) -> bool;
}
pub trait FileHandle: Send + Sync {
async fn write_all(&mut self, buf: &[u8]) -> Result<usize>;
async fn read_exact(&mut self, buf: &mut [u8]) -> Result<usize>;
async fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize>;
async fn fsync(&mut self) -> Result<()>;
fn position(&self) -> u64;
async fn seek(&mut self, pos: u64) -> Result<()>;
}
Fault Injection (InMemoryFileSystem)
impl InMemoryFileSystem {
pub fn fail_next_fsync(&self, error: io::Error);
pub fn simulate_disk_full(&self);
pub fn corrupt_bytes(&self, path: &Path, offset: u64, len: usize);
pub fn clear_faults(&self);
}
Acceptance Criteria
- InMemoryFileSystem: write, read back, verify content
- InMemoryFileSystem: create_dir_all, list_dir
- InMemoryFileSystem: fsync succeeds normally
- InMemoryFileSystem: fail_next_fsync causes next fsync to error
- InMemoryFileSystem: simulate_disk_full causes writes to fail
- SimClock: starts at time 0, advance(Duration) changes now()
- SimClock: sleep returns immediately when time is advanced
- RealClock: delegates to std::time
- RealFileSystem: delegates to tokio::fs (basic smoke test)