use std::path::{Path, PathBuf};
use crate::{Runtime, block_on};
use super::*;
use tempest_io::{
OpenOptions, Statx, VirtualIo,
virtual_io::{Fault, VirtualIoConfig},
};
#[test]
fn test_open_file_create() {
let io = VirtualIo::new(VirtualIoConfig::default().report_unclosed_fds(false));
block_on(io, async {
let path = PathBuf::from("/new_file.bin");
let _fd = open_file::<VirtualIo>(path, OpenOptions::new().write(true).create(true))
.await
.unwrap();
});
}
#[test]
fn test_open_file_not_found() {
let io = VirtualIo::new(VirtualIoConfig::default().report_unclosed_fds(false));
block_on(io, async {
let path = PathBuf::from("/does_not_exist.bin");
let result = open_file::<VirtualIo>(path, OpenOptions::new().read(true)).await;
assert!(result.is_err());
})
}
#[test]
fn test_close_file() {
let mut io = VirtualIo::default();
let fd = io.create_file_sync("/file_that_must_be_closed.txt");
let mut rt = Runtime::new(io);
rt.block_on(async {
close_file::<VirtualIo>(fd).await.unwrap();
});
assert!(rt.inspect_io().all_fds_closed(), "unclosed fds");
}
#[test]
fn test_write_at_read_at() {
let io = VirtualIo::new(VirtualIoConfig::default().report_unclosed_fds(false));
block_on(io, async {
let path = PathBuf::from("/file.txt");
let fd = open_file::<VirtualIo>(path, OpenOptions::new().write(true).create(true))
.await
.unwrap();
let text = b"hello world";
let (result, _buf) = write_at::<&[u8], VirtualIo>(fd, text, 0).await;
assert_eq!(result.unwrap(), text.len());
let (result, buf) = read_at::<_, VirtualIo>(fd, vec![0; text.len()], 0).await;
assert_eq!(result.unwrap(), text.len());
assert_eq!(buf, text);
})
}
#[test]
fn test_write_exact_read_exact() {
let mut io = VirtualIo::new(VirtualIoConfig::default().report_unclosed_fds(false));
io.inject(Fault::PartialRead { bytes: 4 });
io.inject(Fault::PartialRead { bytes: 3 });
io.inject(Fault::PartialWrite { bytes: 4 });
io.inject(Fault::PartialWrite { bytes: 3 });
let mut rt = Runtime::new(io);
rt.block_on(async {
let path = PathBuf::from("/file.txt");
let fd = open_file::<VirtualIo>(path, OpenOptions::new().write(true).create(true))
.await
.unwrap();
let text = b"hello world";
let (result, _buf) = write_exact::<&[u8], VirtualIo>(fd, text, 0).await;
result.unwrap();
let (result, buf) = read_exact::<_, VirtualIo>(fd, vec![0; text.len()], 0).await;
result.unwrap();
assert_eq!(buf, text);
});
}
#[test]
fn test_remove_file() {
let mut io = VirtualIo::default();
let path = PathBuf::from("/file.txt");
let fd = io.create_file_sync(path.clone());
io.close_fd_sync(fd);
block_on(io, async {
remove_file::<VirtualIo>(path.clone()).await.unwrap();
assert!(
open_file::<VirtualIo>(path, OpenOptions::new().read(true))
.await
.is_err()
);
})
}
#[test]
fn test_remove_file_nonexistent() {
block_on(VirtualIo::default(), async {
let result = remove_file::<VirtualIo>(PathBuf::from("/does_not_exist.txt")).await;
assert!(result.is_err());
});
}
#[test]
fn test_sync_file() {
block_on(VirtualIo::default(), async {
let fd = open_file::<VirtualIo>(
PathBuf::from("/file.txt"),
OpenOptions::new().write(true).create(true),
)
.await
.unwrap();
let (result, _) = write_exact::<&[u8], VirtualIo>(fd, b"hello", 0).await;
result.unwrap();
sync_file::<VirtualIo>(fd).await.unwrap();
close_file::<VirtualIo>(fd).await.unwrap();
});
}
#[test]
fn test_list_dir() {
block_on(VirtualIo::default(), async {
let fd_a = open_file::<VirtualIo>(
PathBuf::from("/a.txt"),
OpenOptions::new().write(true).create(true),
)
.await
.unwrap();
let fd_b = open_file::<VirtualIo>(
PathBuf::from("/b.txt"),
OpenOptions::new().write(true).create(true),
)
.await
.unwrap();
close_file::<VirtualIo>(fd_a).await.unwrap();
close_file::<VirtualIo>(fd_b).await.unwrap();
let entries = list_dir::<VirtualIo>(PathBuf::from("/")).unwrap();
let paths: Vec<_> = entries.iter().map(|e| e.path.as_path()).collect();
assert!(paths.contains(&Path::new("/a.txt")));
assert!(paths.contains(&Path::new("/b.txt")));
});
}
#[test]
fn test_stat_file() {
let io = VirtualIo::default();
block_on(io, async {
let path = PathBuf::from("/file.txt");
let fd = open_file::<VirtualIo>(path, OpenOptions::new().write(true).create(true))
.await
.unwrap();
let buf = b"hello world";
let (result, _buf) = write_exact::<&[u8], VirtualIo>(fd, buf, 0).await;
result.unwrap();
let statx = stat_file::<VirtualIo>(fd).await.unwrap();
let size = buf.len() as u64;
assert_eq!(statx.stx_size(), size);
close_file::<VirtualIo>(fd).await.unwrap();
})
}