diff --git a/lib/vfs/src/mem_fs/filesystem.rs b/lib/vfs/src/mem_fs/filesystem.rs index e8a9dc178d9..50a947eb4f7 100644 --- a/lib/vfs/src/mem_fs/filesystem.rs +++ b/lib/vfs/src/mem_fs/filesystem.rs @@ -937,9 +937,25 @@ impl Default for FileSystemInner { } } +#[allow(dead_code)] // The `No` variant. +pub(super) enum DirectoryMustBeEmpty { + Yes, + No, +} + +impl DirectoryMustBeEmpty { + pub(super) fn yes(&self) -> bool { + matches!(self, Self::Yes) + } + + pub(super) fn no(&self) -> bool { + !self.yes() + } +} + #[cfg(test)] mod test_filesystem { - use crate::{mem_fs::*, DirEntry, FileSystem as FS, FileType, FsError}; + use crate::{mem_fs::*, DirEntry, FileSystem as FS, FileSystemExt, FileType, FsError}; macro_rules! path { ($path:expr) => { @@ -1686,20 +1702,26 @@ mod test_filesystem { "canonicalizing a crazily stupid path name", ); } -} - -#[allow(dead_code)] // The `No` variant. -pub(super) enum DirectoryMustBeEmpty { - Yes, - No, -} -impl DirectoryMustBeEmpty { - pub(super) fn yes(&self) -> bool { - matches!(self, Self::Yes) - } + #[test] + #[ignore = "Not yet supported. See https://github.com/wasmerio/wasmer/issues/3678"] + fn mount_to_overlapping_directories() { + let top_level = FileSystem::default(); + top_level.touch("/file.txt").unwrap(); + let nested = FileSystem::default(); + nested.touch("/another-file.txt").unwrap(); + let top_level: Arc = Arc::new(top_level); + let nested: Arc = Arc::new(nested); - pub(super) fn no(&self) -> bool { - !self.yes() + let fs = FileSystem::default(); + fs.mount("/top-level".into(), &top_level, "/".into()) + .unwrap(); + fs.mount("/top-level/nested".into(), &nested, "/".into()) + .unwrap(); + + assert!(fs.is_dir("/top-level")); + assert!(fs.is_file("/top-level/file.txt")); + assert!(fs.is_dir("/top-level/nested")); + assert!(fs.is_file("/top-level/nested/another-file.txt")); } } diff --git a/lib/vfs/src/union_fs.rs b/lib/vfs/src/union_fs.rs index 61df13517fc..5908558ac79 100644 --- a/lib/vfs/src/union_fs.rs +++ b/lib/vfs/src/union_fs.rs @@ -460,14 +460,14 @@ impl FileOpener for UnionFileSystem { #[cfg(test)] mod tests { + use std::{path::Path, sync::Arc}; + use tokio::io::AsyncWriteExt; - use crate::host_fs::FileSystem; - use crate::mem_fs; - use crate::FileSystem as FileSystemTrait; - use crate::FsError; - use crate::UnionFileSystem; - use std::path::Path; + use crate::{ + host_fs::FileSystem, mem_fs, FileSystem as FileSystemTrait, FileSystemExt, FsError, + UnionFileSystem, + }; fn gen_filesystem() -> UnionFileSystem { let mut union = UnionFileSystem::new(); @@ -1073,4 +1073,34 @@ mod tests { let _ = fs_extra::remove_items(&["./test_canonicalize"]); } */ + + #[test] + #[ignore = "Not yet supported. See https://github.com/wasmerio/wasmer/issues/3678"] + fn mount_to_overlapping_directories() { + let top_level = mem_fs::FileSystem::default(); + top_level.touch("/file.txt").unwrap(); + let nested = mem_fs::FileSystem::default(); + nested.touch("/another-file.txt").unwrap(); + + let mut fs = UnionFileSystem::default(); + fs.mount( + "top-level", + "/", + false, + Box::new(top_level), + Some("/top-level"), + ); + fs.mount( + "nested", + "/", + false, + Box::new(nested), + Some("/top-level/nested"), + ); + + assert!(fs.is_dir("/top-level")); + assert!(fs.is_file("/top-level/file.txt")); + assert!(fs.is_dir("/top-level/nested")); + assert!(fs.is_file("/top-level/nested/another-file.txt")); + } }