This is an automated email from the ASF dual-hosted git repository. xuanwo pushed a commit to branch fix-list-root in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git
commit 87f2370f1a684930d27133884344620da9ac264a Author: Xuanwo <[email protected]> AuthorDate: Tue Dec 26 11:40:24 2023 +0800 fix: List root should not return itself Signed-off-by: Xuanwo <[email protected]> --- core/src/services/azblob/lister.rs | 2 +- core/src/services/cos/lister.rs | 2 +- core/src/services/gcs/lister.rs | 2 +- core/src/services/obs/lister.rs | 2 +- core/src/services/oss/lister.rs | 2 +- core/src/services/s3/lister.rs | 2 +- core/tests/behavior/list.rs | 38 +++++++++++++++++++++++++++++++++++++- 7 files changed, 43 insertions(+), 7 deletions(-) diff --git a/core/src/services/azblob/lister.rs b/core/src/services/azblob/lister.rs index 6760cecb2..eeded0499 100644 --- a/core/src/services/azblob/lister.rs +++ b/core/src/services/azblob/lister.rs @@ -89,7 +89,7 @@ impl oio::PageList for AzblobLister { let path = build_rel_path(&self.core.root, &object.name); // azblob could return the dir itself in contents. - if path == self.path { + if path == self.path || path.is_empty() { continue; } diff --git a/core/src/services/cos/lister.rs b/core/src/services/cos/lister.rs index 6a8f62907..f289b3383 100644 --- a/core/src/services/cos/lister.rs +++ b/core/src/services/cos/lister.rs @@ -85,7 +85,7 @@ impl oio::PageList for CosLister { for object in output.contents { let path = build_rel_path(&self.core.root, &object.key); - if path == self.path { + if path == self.path || path.is_empty() { continue; } diff --git a/core/src/services/gcs/lister.rs b/core/src/services/gcs/lister.rs index c7da1a86e..0a0180198 100644 --- a/core/src/services/gcs/lister.rs +++ b/core/src/services/gcs/lister.rs @@ -105,7 +105,7 @@ impl oio::PageList for GcsLister { for object in output.items { // exclude the inclusive start_after itself let path = build_rel_path(&self.core.root, &object.name); - if path == self.path { + if path == self.path || path.is_empty() { continue; } if self.start_after.as_ref() == Some(&path) { diff --git a/core/src/services/obs/lister.rs b/core/src/services/obs/lister.rs index 3a9a5b4e7..ead6bbbea 100644 --- a/core/src/services/obs/lister.rs +++ b/core/src/services/obs/lister.rs @@ -87,7 +87,7 @@ impl oio::PageList for ObsLister { for object in output.contents { let path = build_rel_path(&self.core.root, &object.key); - if path == self.path { + if path == self.path || path.is_empty() { continue; } diff --git a/core/src/services/oss/lister.rs b/core/src/services/oss/lister.rs index 0e8864068..926946a61 100644 --- a/core/src/services/oss/lister.rs +++ b/core/src/services/oss/lister.rs @@ -96,7 +96,7 @@ impl oio::PageList for OssLister { for object in output.contents { let path = build_rel_path(&self.core.root, &object.key); - if path == self.path { + if path == self.path || path.is_empty() { continue; } if self.start_after.as_ref() == Some(&path) { diff --git a/core/src/services/s3/lister.rs b/core/src/services/s3/lister.rs index f0712e650..569d83ebe 100644 --- a/core/src/services/s3/lister.rs +++ b/core/src/services/s3/lister.rs @@ -116,7 +116,7 @@ impl oio::PageList for S3Lister { let path = build_rel_path(&self.core.root, &object.key); // s3 could return the dir itself in contents. - if path == self.path { + if path == self.path || path.is_empty() { continue; } diff --git a/core/tests/behavior/list.rs b/core/tests/behavior/list.rs index c29f0e2dc..1123dfa83 100644 --- a/core/tests/behavior/list.rs +++ b/core/tests/behavior/list.rs @@ -243,15 +243,51 @@ pub async fn test_list_empty_dir(op: Operator) -> Result<()> { op.create_dir(&dir).await.expect("write must succeed"); + // List "dir/" should return empty object. let mut obs = op.lister(&dir).await?; let mut objects = HashMap::new(); while let Some(de) = obs.try_next().await? { objects.insert(de.path().to_string(), de); } - debug!("got objects: {:?}", objects); + assert_eq!(objects.len(), 0, "dir should only return empty"); + // List "dir" should return "dir/". + let mut obs = op.lister(&dir.trim_end_matches('/')).await?; + let mut objects = HashMap::new(); + while let Some(de) = obs.try_next().await? { + objects.insert(de.path().to_string(), de); + } + assert_eq!(objects.len(), 1, "dir should only return empty"); + assert_eq!( + objects[&dir].metadata().mode(), + EntryMode::DIR, + "given dir should exist and must be dir" + ); + + // List "dir/" should return empty object. + let mut obs = op.lister_with(&dir).recursive(true).await?; + let mut objects = HashMap::new(); + while let Some(de) = obs.try_next().await? { + objects.insert(de.path().to_string(), de); + } assert_eq!(objects.len(), 0, "dir should only return empty"); + // List "dir" should return "dir/". + let mut obs = op + .lister_with(&dir.trim_end_matches('/')) + .recursive(true) + .await?; + let mut objects = HashMap::new(); + while let Some(de) = obs.try_next().await? { + objects.insert(de.path().to_string(), de); + } + assert_eq!(objects.len(), 1, "dir should only return empty"); + assert_eq!( + objects[&dir].metadata().mode(), + EntryMode::DIR, + "given dir should exist and must be dir" + ); + op.delete(&dir).await.expect("delete must succeed"); Ok(()) }
