use std::os::unix::fs::FileExt;
use turmoil::fs::shim::std::fs::{create_dir, read, write, OpenOptions};
use turmoil::fs::FsHandle;
use turmoil::{Builder, Result};
#[test]
fn worker_thread_basic_io() -> Result {
let mut sim = Builder::new().build();
sim.client("test", async {
create_dir("/data")?;
let handle = FsHandle::current();
let worker = std::thread::spawn(move || {
let _guard = handle.enter();
write("/data/from_worker.txt", b"hello from worker")?;
Ok::<_, std::io::Error>(())
});
worker.join().unwrap()?;
assert_eq!(read("/data/from_worker.txt")?, b"hello from worker");
Ok(())
});
sim.run()
}
#[test]
fn worker_thread_file_handle() -> Result {
let mut sim = Builder::new().build();
sim.client("test", async {
create_dir("/data")?;
let handle = FsHandle::current();
let worker = std::thread::spawn(move || {
let _guard = handle.enter();
let file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open("/data/file.txt")?;
file.write_all_at(b"positioned write", 0)?;
file.sync_all()?;
let mut buf = [0u8; 16];
file.read_at(&mut buf, 0)?;
assert_eq!(&buf, b"positioned write");
Ok::<_, std::io::Error>(())
});
worker.join().unwrap()?;
assert_eq!(read("/data/file.txt")?, b"positioned write");
Ok(())
});
sim.run()
}
#[test]
fn worker_thread_multiple_operations() -> Result {
let mut sim = Builder::new().build();
sim.client("test", async {
create_dir("/data")?;
write("/data/initial.txt", b"initial data")?;
let handle = FsHandle::current();
let worker = std::thread::spawn(move || {
let _guard = handle.enter();
let initial = read("/data/initial.txt")?;
assert_eq!(initial, b"initial data");
write("/data/file1.txt", b"file one")?;
write("/data/file2.txt", b"file two")?;
write("/data/file3.txt", b"file three")?;
Ok::<_, std::io::Error>(())
});
worker.join().unwrap()?;
assert_eq!(read("/data/file1.txt")?, b"file one");
assert_eq!(read("/data/file2.txt")?, b"file two");
assert_eq!(read("/data/file3.txt")?, b"file three");
Ok(())
});
sim.run()
}
#[test]
fn worker_thread_guard_scoping() -> Result {
let mut sim = Builder::new().build();
sim.client("test", async {
create_dir("/data")?;
let handle = FsHandle::current();
let worker = std::thread::spawn(move || {
{
let _guard = handle.enter();
write("/data/scoped1.txt", b"scope 1")?;
}
{
let _guard = handle.enter();
write("/data/scoped2.txt", b"scope 2")?;
}
Ok::<_, std::io::Error>(())
});
worker.join().unwrap()?;
assert_eq!(read("/data/scoped1.txt")?, b"scope 1");
assert_eq!(read("/data/scoped2.txt")?, b"scope 2");
Ok(())
});
sim.run()
}
#[test]
fn worker_thread_with_sync() -> Result {
use turmoil::fs::shim::std::fs::sync_dir;
let mut sim = Builder::new().build();
sim.client("test", async {
create_dir("/data")?;
sync_dir("/")?;
let handle = FsHandle::current();
let worker = std::thread::spawn(move || {
let _guard = handle.enter();
let file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open("/data/durable.txt")?;
file.write_all_at(b"durable data", 0)?;
file.sync_all()?;
sync_dir("/data")?;
Ok::<_, std::io::Error>(())
});
worker.join().unwrap()?;
assert_eq!(read("/data/durable.txt")?, b"durable data");
Ok(())
});
sim.run()
}