Skip to content

Commit

Permalink
Ignore broken symlinks for LocalFileSystem object store (#2195)
Browse files Browse the repository at this point in the history
* Re-enable test_list_root test for MacOS

* LocalFileSystem: ignore broken links in convert_walkdir_result
  • Loading branch information
jccampagne committed Jul 28, 2022
1 parent cc96687 commit b8e034c
Showing 1 changed file with 27 additions and 4 deletions.
31 changes: 27 additions & 4 deletions object_store/src/local.rs
Expand Up @@ -27,7 +27,7 @@ use futures::future::BoxFuture;
use futures::FutureExt;
use futures::{stream::BoxStream, StreamExt};
use snafu::{ensure, OptionExt, ResultExt, Snafu};
use std::fs::File;
use std::fs::{metadata, symlink_metadata, File};
use std::io::{Read, Seek, SeekFrom, Write};
use std::ops::Range;
use std::pin::Pin;
Expand Down Expand Up @@ -804,11 +804,36 @@ fn convert_metadata(metadata: std::fs::Metadata, location: Path) -> Result<Objec
}

/// Convert walkdir results and converts not-found errors into `None`.
/// Convert broken symlinks to `None`.
fn convert_walkdir_result(
res: std::result::Result<walkdir::DirEntry, walkdir::Error>,
) -> Result<Option<walkdir::DirEntry>> {
match res {
Ok(entry) => Ok(Some(entry)),
Ok(entry) => {
// To check for broken symlink: call symlink_metadata() - it does not traverse symlinks);
// if ok: check if entry is symlink; and try to read it by calling metadata().
match symlink_metadata(entry.path()) {
Ok(attr) => {
if attr.is_symlink() {
let target_metadata = metadata(entry.path());
match target_metadata {
Ok(_) => {
// symlink is valid
Ok(Some(entry))
}
Err(_) => {
// this is a broken symlink, return None
Ok(None)
}
}
} else {
Ok(Some(entry))
}
}
Err(_) => Ok(None),
}
}

Err(walkdir_err) => match walkdir_err.io_error() {
Some(io_err) => match io_err.kind() {
io::ErrorKind::NotFound => Ok(None),
Expand Down Expand Up @@ -990,8 +1015,6 @@ mod tests {
}

#[tokio::test]
#[cfg(target_os = "linux")]
// macos has some magic in its root '/.VolumeIcon.icns"' which causes this test to fail
async fn test_list_root() {
let integration = LocalFileSystem::new();
let result = integration.list_with_delimiter(None).await;
Expand Down

0 comments on commit b8e034c

Please sign in to comment.