use super::*;
#[test]
fn test_create_file() {
let sb = MemFsTestSandbox::new();
let (entry, handle) = sb.fuse_create_root("newfile.txt").unwrap();
assert!(entry.inode >= 3);
assert!(handle.is_some());
let looked = sb.lookup_root("newfile.txt").unwrap();
assert_eq!(looked.inode, entry.inode);
}
#[test]
fn test_create_file_with_content() {
let sb = MemFsTestSandbox::new();
let (entry, handle) = sb.fuse_create_root("data.txt").unwrap();
let handle = handle.unwrap();
sb.fuse_write(entry.inode, handle, b"hello world", 0)
.unwrap();
let data = sb.fuse_read(entry.inode, handle, 1024, 0).unwrap();
assert_eq!(&data[..], b"hello world");
}
#[test]
fn test_create_with_umask() {
let sb = MemFsTestSandbox::new();
let (entry, _handle, _opts) = sb
.fs
.create(
MemFsTestSandbox::ctx(),
ROOT_INODE,
&MemFsTestSandbox::cstr("masked.txt"),
0o777,
false,
libc::O_RDWR as u32,
0o022,
Extensions::default(),
)
.unwrap();
let mode = entry.attr.st_mode as u32;
assert_eq!(mode & 0o777, 0o755);
}
#[test]
fn test_create_context_ownership() {
let sb = MemFsTestSandbox::new();
let (entry, _) = sb.fuse_create_root("owned.txt").unwrap();
assert_eq!(entry.attr.st_uid, 1000);
assert_eq!(entry.attr.st_gid, 1000);
}
#[test]
fn test_create_duplicate() {
let sb = MemFsTestSandbox::new();
sb.fuse_create_root("dup.txt").unwrap();
let result = sb.fuse_create_root("dup.txt");
MemFsTestSandbox::assert_errno(result, LINUX_EEXIST);
}
#[test]
fn test_mkdir() {
let sb = MemFsTestSandbox::new();
let (st_before, _) = sb
.fs
.getattr(MemFsTestSandbox::ctx(), ROOT_INODE, None)
.unwrap();
let nlink_before = st_before.st_nlink;
let entry = sb.fuse_mkdir_root("mydir").unwrap();
let mode = entry.attr.st_mode as u32;
assert_eq!(mode & libc::S_IFMT as u32, libc::S_IFDIR as u32);
#[cfg(target_os = "linux")]
assert_eq!(entry.attr.st_nlink, 2);
#[cfg(target_os = "macos")]
assert_eq!(entry.attr.st_nlink, 2);
let (st_after, _) = sb
.fs
.getattr(MemFsTestSandbox::ctx(), ROOT_INODE, None)
.unwrap();
assert_eq!(st_after.st_nlink, nlink_before + 1);
}
#[test]
fn test_mkdir_nested() {
let sb = MemFsTestSandbox::new();
let dir_a = sb.fuse_mkdir_root("a").unwrap();
let dir_b = sb.fuse_mkdir(dir_a.inode, "b", 0o755).unwrap();
let dir_c = sb.fuse_mkdir(dir_b.inode, "c", 0o755).unwrap();
assert!(dir_c.inode >= 3);
let looked = sb.lookup(dir_b.inode, "c").unwrap();
assert_eq!(looked.inode, dir_c.inode);
}
#[test]
fn test_mknod_fifo() {
let sb = MemFsTestSandbox::new();
let entry = sb
.fs
.mknod(
MemFsTestSandbox::ctx(),
ROOT_INODE,
&MemFsTestSandbox::cstr("myfifo"),
libc::S_IFIFO as u32 | 0o644,
0,
0,
Extensions::default(),
)
.unwrap();
let mode = entry.attr.st_mode as u32;
assert_eq!(mode & libc::S_IFMT as u32, libc::S_IFIFO as u32);
}
#[test]
fn test_mknod_socket() {
let sb = MemFsTestSandbox::new();
let entry = sb
.fs
.mknod(
MemFsTestSandbox::ctx(),
ROOT_INODE,
&MemFsTestSandbox::cstr("mysock"),
libc::S_IFSOCK as u32 | 0o644,
0,
0,
Extensions::default(),
)
.unwrap();
let mode = entry.attr.st_mode as u32;
assert_eq!(mode & libc::S_IFMT as u32, libc::S_IFSOCK as u32);
}
#[test]
fn test_mknod_block_device() {
let sb = MemFsTestSandbox::new();
let entry = sb
.fs
.mknod(
MemFsTestSandbox::ctx(),
ROOT_INODE,
&MemFsTestSandbox::cstr("blkdev"),
libc::S_IFBLK as u32 | 0o660,
42,
0,
Extensions::default(),
)
.unwrap();
let mode = entry.attr.st_mode as u32;
assert_eq!(mode & libc::S_IFMT as u32, libc::S_IFBLK as u32);
#[cfg(target_os = "linux")]
assert_eq!(entry.attr.st_rdev, 42);
#[cfg(target_os = "macos")]
assert_eq!(entry.attr.st_rdev, 42);
}
#[test]
fn test_mknod_char_device() {
let sb = MemFsTestSandbox::new();
let entry = sb
.fs
.mknod(
MemFsTestSandbox::ctx(),
ROOT_INODE,
&MemFsTestSandbox::cstr("chrdev"),
libc::S_IFCHR as u32 | 0o660,
99,
0,
Extensions::default(),
)
.unwrap();
let mode = entry.attr.st_mode as u32;
assert_eq!(mode & libc::S_IFMT as u32, libc::S_IFCHR as u32);
#[cfg(target_os = "linux")]
assert_eq!(entry.attr.st_rdev, 99);
#[cfg(target_os = "macos")]
assert_eq!(entry.attr.st_rdev, 99);
}
#[test]
fn test_symlink() {
let sb = MemFsTestSandbox::new();
let entry = sb
.fs
.symlink(
MemFsTestSandbox::ctx(),
&MemFsTestSandbox::cstr("/target/path"),
ROOT_INODE,
&MemFsTestSandbox::cstr("mylink"),
Extensions::default(),
)
.unwrap();
let mode = entry.attr.st_mode as u32;
assert_eq!(mode & libc::S_IFMT as u32, libc::S_IFLNK as u32);
let target = sb
.fs
.readlink(MemFsTestSandbox::ctx(), entry.inode)
.unwrap();
assert_eq!(&target[..], b"/target/path");
}
#[test]
fn test_symlink_size() {
let sb = MemFsTestSandbox::new();
let target = "/some/long/target/path";
let entry = sb
.fs
.symlink(
MemFsTestSandbox::ctx(),
&MemFsTestSandbox::cstr(target),
ROOT_INODE,
&MemFsTestSandbox::cstr("sizelink"),
Extensions::default(),
)
.unwrap();
assert_eq!(entry.attr.st_size, target.len() as i64);
}
#[test]
fn test_link() {
let sb = MemFsTestSandbox::new();
let (entry, handle) = sb.fuse_create_root("original.txt").unwrap();
let handle = handle.unwrap();
sb.fs
.release(
MemFsTestSandbox::ctx(),
entry.inode,
0,
handle,
false,
false,
None,
)
.unwrap();
let link_entry = sb
.fs
.link(
MemFsTestSandbox::ctx(),
entry.inode,
ROOT_INODE,
&MemFsTestSandbox::cstr("hardlink.txt"),
)
.unwrap();
assert_eq!(link_entry.inode, entry.inode);
let (st, _) = sb
.fs
.getattr(MemFsTestSandbox::ctx(), entry.inode, None)
.unwrap();
#[cfg(target_os = "linux")]
assert_eq!(st.st_nlink, 2);
#[cfg(target_os = "macos")]
assert_eq!(st.st_nlink, 2);
}
#[test]
fn test_link_to_directory() {
let sb = MemFsTestSandbox::new();
let dir = sb.fuse_mkdir_root("dir_for_link").unwrap();
let result = sb.fs.link(
MemFsTestSandbox::ctx(),
dir.inode,
ROOT_INODE,
&MemFsTestSandbox::cstr("dir_hardlink"),
);
MemFsTestSandbox::assert_errno(result, LINUX_EPERM);
}
#[test]
fn test_link_shared_content() {
let sb = MemFsTestSandbox::new();
let (entry, handle) = sb.fuse_create_root("original.txt").unwrap();
let handle = handle.unwrap();
sb.fuse_write(entry.inode, handle, b"shared data", 0)
.unwrap();
sb.fs
.release(
MemFsTestSandbox::ctx(),
entry.inode,
0,
handle,
false,
false,
None,
)
.unwrap();
let link_entry = sb
.fs
.link(
MemFsTestSandbox::ctx(),
entry.inode,
ROOT_INODE,
&MemFsTestSandbox::cstr("hardlink.txt"),
)
.unwrap();
assert_eq!(link_entry.inode, entry.inode);
let (handle2, _) = sb.fuse_open(link_entry.inode, libc::O_RDWR as u32).unwrap();
let handle2 = handle2.unwrap();
let data = sb.fuse_read(link_entry.inode, handle2, 1024, 0).unwrap();
assert_eq!(&data[..], b"shared data");
sb.fuse_write(link_entry.inode, handle2, b"updated", 0)
.unwrap();
sb.fs
.release(
MemFsTestSandbox::ctx(),
link_entry.inode,
0,
handle2,
false,
false,
None,
)
.unwrap();
let looked = sb.lookup_root("original.txt").unwrap();
let (handle3, _) = sb.fuse_open(looked.inode, libc::O_RDONLY as u32).unwrap();
let handle3 = handle3.unwrap();
let data2 = sb.fuse_read(looked.inode, handle3, 1024, 0).unwrap();
assert_eq!(&data2[..7], b"updated");
}