Skip to content

Commit

Permalink
feat(vfs) Add test cases for mem_fs::FileSystem::rename.
Browse files Browse the repository at this point in the history
This patch adds test cases for renaming a file or a directory, and for
renaming + moving. That's different because this patch also implements
a shortcut when a file or directory is simply renamed, we don't need
to update the parent's children, only the modified time.
  • Loading branch information
Hywan committed Sep 3, 2021
1 parent af6dc30 commit 3d27db8
Showing 1 changed file with 107 additions and 16 deletions.
123 changes: 107 additions & 16 deletions lib/vfs/src/mem_fs/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,17 +196,29 @@ impl crate::FileSystem for FileSystem {
// Write lock.
let mut fs = self.inner.try_write().map_err(|_| FsError::Lock)?;

// Update the directory name, and update the modified
// time.
// Update the file name, and update the modified time.
fs.update_node_name(inode, name_of_to)?;

// Remove the file from its parent, and update the
// modified time.
fs.remove_child_from_node(inode_of_from_parent, position_of_from)?;
// The parents are different. Let's update them.
if inode_of_from_parent != inode_of_to_parent {
// Remove the file from its parent, and update the
// modified time.
fs.remove_child_from_node(inode_of_from_parent, position_of_from)?;

// Add the file to its new parent, and update the modified
// time.
fs.add_child_to_node(inode_of_to_parent, inode)?;
// Add the file to its new parent, and update the modified
// time.
fs.add_child_to_node(inode_of_to_parent, inode)?;
}
// Otherwise, we need to at least update the modified time of the parent.
else {
match fs.storage.get_mut(inode_of_from_parent) {
Some(Node::Directory {
metadata: Metadata { modified, .. },
..
}) => *modified = time(),
_ => return Err(FsError::UnknownError),
}
}
}

Ok(())
Expand Down Expand Up @@ -832,10 +844,31 @@ mod test_filesystem {

assert_eq!(fs.create_dir(path!("/bar")), Ok(()));

assert!(
matches!(
fs.new_open_options()
.write(true)
.create_new(true)
.open(path!("/bar/hello1.txt")),
Ok(_),
),
"creating a new file (`hello1.txt`)",
);
assert!(
matches!(
fs.new_open_options()
.write(true)
.create_new(true)
.open(path!("/bar/hello2.txt")),
Ok(_),
),
"creating a new file (`hello2.txt`)",
);

{
let fs_inner = fs.inner.read().unwrap();

assert_eq!(fs_inner.storage.len(), 4, "storage has all directories");
assert_eq!(fs_inner.storage.len(), 6, "storage has all files");
assert!(
matches!(
fs_inner.storage.get(ROOT_INODE),
Expand Down Expand Up @@ -880,24 +913,60 @@ mod test_filesystem {
name,
children,
..
}) if name == "bar" && children.is_empty()
}) if name == "bar" && children == &[4, 5]
),
"`bar` is contains `hello.txt`",
);
assert!(
matches!(
fs_inner.storage.get(4),
Some(Node::File {
inode: 4,
name,
..
}) if name == "hello1.txt"
),
"`hello1.txt` exists",
);
assert!(
matches!(
fs_inner.storage.get(5),
Some(Node::File {
inode: 5,
name,
..
}) if name == "hello2.txt"
),
"`bar` is empty",
"`hello2.txt` exists",
);
}

assert_eq!(
fs.rename(path!("/bar/hello2.txt"), path!("/foo/world2.txt")),
Ok(()),
"renaming (and moving) a file",
);

assert_eq!(
fs.rename(path!("/foo"), path!("/bar/baz")),
Ok(()),
"renaming a directory",
);

assert_eq!(
fs.rename(path!("/bar/hello1.txt"), path!("/bar/world1.txt")),
Ok(()),
"renaming a file (in the same directory)",
);

{
let fs_inner = fs.inner.read().unwrap();

dbg!(&fs_inner);

assert_eq!(
fs_inner.storage.len(),
4,
6,
"storage has still all directories"
);
assert!(
Expand All @@ -920,9 +989,9 @@ mod test_filesystem {
name,
children,
..
}) if name == "baz" && children == &[2]
}) if name == "baz" && children == &[2, 5]
),
"`foo` has been renamed to `baz` and contains `qux`",
"`foo` has been renamed to `baz` and contains `qux` and `world2.txt`",
);
assert!(
matches!(
Expand All @@ -944,9 +1013,31 @@ mod test_filesystem {
name,
children,
..
}) if name == "bar" && children == &[1]
}) if name == "bar" && children == &[4, 1]
),
"`bar` contains `bar` (ex `foo`) and `world1.txt` (ex `hello1`)",
);
assert!(
matches!(
fs_inner.storage.get(4),
Some(Node::File {
inode: 4,
name,
..
}) if name == "world1.txt"
),
"`hello1.txt` has been renamed to `world1.txt`",
);
assert!(
matches!(
fs_inner.storage.get(5),
Some(Node::File {
inode: 5,
name,
..
}) if name == "world2.txt"
),
"`bar` contains `baz` (ex `foo`)",
"`hello2.txt` has been renamed to `world2.txt`",
);
}
}
Expand Down

0 comments on commit 3d27db8

Please sign in to comment.