sausage-vfs: layers (host, memory, generated, mounts), process guards, wasi:filesystem adapter
Checkpoint. More tests and the review findings follow.
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "vfs-files-guest"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
[workspace]
|
||||
[dependencies]
|
||||
tempfile = "3"
|
||||
rusqlite = { version = "0.38", features = ["bundled"] }
|
||||
@@ -0,0 +1,66 @@
|
||||
//! Exercises Rust filesystem clients through the virtual WASI filesystem.
|
||||
use std::{
|
||||
fs::{self, OpenOptions},
|
||||
io::{Read, Seek, SeekFrom, Write},
|
||||
};
|
||||
fn main() {
|
||||
fs::create_dir("/work").unwrap();
|
||||
fs::write("/work/a", b"hello").unwrap();
|
||||
let mut f = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open("/work/a")
|
||||
.unwrap();
|
||||
f.seek(SeekFrom::Start(1)).unwrap();
|
||||
f.write_all(b"A").unwrap();
|
||||
f.set_len(4).unwrap();
|
||||
f.sync_all().unwrap();
|
||||
OpenOptions::new()
|
||||
.append(true)
|
||||
.open("/work/a")
|
||||
.unwrap()
|
||||
.write_all(b"!")
|
||||
.unwrap();
|
||||
assert_eq!(fs::read("/work/a").unwrap(), b"hAll!");
|
||||
assert_eq!(fs::metadata("/work/a").unwrap().len(), 5);
|
||||
fs::rename("/work/a", "/work/b").unwrap();
|
||||
assert_eq!(fs::read("/work/../work/b").unwrap(), b"hAll!");
|
||||
assert_eq!(fs::read("work/b").unwrap(), b"hAll!");
|
||||
assert_eq!(fs::read_dir("/work").unwrap().count(), 1);
|
||||
assert_eq!(
|
||||
fs::write("/proc/no", b"no").unwrap_err().kind(),
|
||||
std::io::ErrorKind::ReadOnlyFilesystem
|
||||
);
|
||||
assert_eq!(
|
||||
fs::rename("/work/b", "/run/b").unwrap_err().kind(),
|
||||
std::io::ErrorKind::CrossesDevices
|
||||
);
|
||||
let root = fs::read_dir("/")
|
||||
.unwrap()
|
||||
.map(|e| e.unwrap().file_name())
|
||||
.collect::<Vec<_>>();
|
||||
for name in ["proc", "run", "self"] {
|
||||
assert!(root.iter().any(|n| n == name));
|
||||
}
|
||||
assert_eq!(fs::read("/proc/value").unwrap(), b"snapshot");
|
||||
fs::write("/run/test", b"memory").unwrap();
|
||||
assert_eq!(fs::read("/run/test").unwrap(), b"memory");
|
||||
fs::remove_file("/work/b").unwrap();
|
||||
fs::remove_dir("/work").unwrap();
|
||||
// WASI std does not implement env::temp_dir, so select the folder explicitly.
|
||||
let mut temp = tempfile::tempfile_in("/tmp").unwrap();
|
||||
temp.write_all(b"temporary").unwrap();
|
||||
temp.seek(SeekFrom::Start(0)).unwrap();
|
||||
let mut text = String::new();
|
||||
temp.read_to_string(&mut text).unwrap();
|
||||
assert_eq!(text, "temporary");
|
||||
let db = rusqlite::Connection::open("/database.sqlite").unwrap();
|
||||
db.execute_batch("CREATE TABLE data (value TEXT); INSERT INTO data VALUES ('row');")
|
||||
.unwrap();
|
||||
drop(db);
|
||||
let db = rusqlite::Connection::open("/database.sqlite").unwrap();
|
||||
let row: String = db
|
||||
.query_row("SELECT value FROM data", [], |r| r.get(0))
|
||||
.unwrap();
|
||||
assert_eq!(row, "row");
|
||||
}
|
||||
Reference in New Issue
Block a user