This is an automated email from the ASF dual-hosted git repository. xuanwo pushed a commit to branch fix-stat in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git
commit e8181fd26a0724a3a6cf5400aaaa4cc2e184b59f Author: Xuanwo <[email protected]> AuthorDate: Tue Nov 21 16:53:04 2023 +0800 Fix kv on new test cases Signed-off-by: Xuanwo <[email protected]> --- core/src/raw/adapters/kv/backend.rs | 16 ++++++++++++++++ core/src/raw/adapters/typed_kv/backend.rs | 16 ++++++++++++++++ core/tests/behavior/write.rs | 20 ++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/core/src/raw/adapters/kv/backend.rs b/core/src/raw/adapters/kv/backend.rs index ed821bc10..580ab204a 100644 --- a/core/src/raw/adapters/kv/backend.rs +++ b/core/src/raw/adapters/kv/backend.rs @@ -162,6 +162,14 @@ impl<S: Adapter> Accessor for Backend<S> { if p == build_abs_path(&self.root, "") { Ok(RpStat::new(Metadata::new(EntryMode::DIR))) + } else if p.ends_with('/') { + // FIXME: we don't need to scan the whole kv to get this info. + let keys = self.kv.scan(&p).await?; + if keys.is_empty() { + Err(Error::new(ErrorKind::NotFound, "kv doesn't have this dir")) + } else { + Ok(RpStat::new(Metadata::new(EntryMode::DIR))) + } } else { let bs = self.kv.get(&p).await?; match bs { @@ -178,6 +186,14 @@ impl<S: Adapter> Accessor for Backend<S> { if p == build_abs_path(&self.root, "") { Ok(RpStat::new(Metadata::new(EntryMode::DIR))) + } else if p.ends_with('/') { + // FIXME: we don't need to scan the whole kv to get this info. + let keys = self.kv.blocking_scan(&p)?; + if keys.is_empty() { + Err(Error::new(ErrorKind::NotFound, "kv doesn't have this dir")) + } else { + Ok(RpStat::new(Metadata::new(EntryMode::DIR))) + } } else { let bs = self.kv.blocking_get(&p)?; match bs { diff --git a/core/src/raw/adapters/typed_kv/backend.rs b/core/src/raw/adapters/typed_kv/backend.rs index e3c620010..e117a170b 100644 --- a/core/src/raw/adapters/typed_kv/backend.rs +++ b/core/src/raw/adapters/typed_kv/backend.rs @@ -169,6 +169,14 @@ impl<S: Adapter> Accessor for Backend<S> { if p == build_abs_path(&self.root, "") { Ok(RpStat::new(Metadata::new(EntryMode::DIR))) + } else if p.ends_with('/') { + // FIXME: we don't need to scan the whole kv to get this info. + let keys = self.kv.scan(&p).await?; + if keys.is_empty() { + Err(Error::new(ErrorKind::NotFound, "kv doesn't have this dir")) + } else { + Ok(RpStat::new(Metadata::new(EntryMode::DIR))) + } } else { let bs = self.kv.get(&p).await?; match bs { @@ -183,6 +191,14 @@ impl<S: Adapter> Accessor for Backend<S> { if p == build_abs_path(&self.root, "") { Ok(RpStat::new(Metadata::new(EntryMode::DIR))) + } else if p.ends_with('/') { + // FIXME: we don't need to scan the whole kv to get this info. + let keys = self.kv.blocking_scan(&p)?; + if keys.is_empty() { + Err(Error::new(ErrorKind::NotFound, "kv doesn't have this dir")) + } else { + Ok(RpStat::new(Metadata::new(EntryMode::DIR))) + } } else { let bs = self.kv.blocking_get(&p)?; match bs { diff --git a/core/tests/behavior/write.rs b/core/tests/behavior/write.rs index 617630ada..66705fcd8 100644 --- a/core/tests/behavior/write.rs +++ b/core/tests/behavior/write.rs @@ -56,6 +56,7 @@ pub fn behavior_write_tests(op: &Operator) -> Vec<Trial> { test_write_with_content_disposition, test_stat_file, test_stat_dir, + test_stat_nested_parent_dir, test_stat_with_special_chars, test_stat_not_cleaned_path, test_stat_not_exist, @@ -311,6 +312,25 @@ pub async fn test_stat_dir(op: Operator) -> Result<()> { Ok(()) } +/// Stat the parent dir of existing dir should return metadata +pub async fn test_stat_nested_parent_dir(op: Operator) -> Result<()> { + let parent = format!("{}", uuid::Uuid::new_v4()); + let file = format!("{}", uuid::Uuid::new_v4()); + let (content, _) = gen_bytes(op.info().full_capability()); + + op.write(&format!("{parent}/{file}"), content.clone()) + .await + .expect("write must succeed"); + + let meta = op.stat(&format!("{parent}/")).await?; + assert_eq!(meta.mode(), EntryMode::DIR); + + op.delete(&format!("{parent}/{file}")) + .await + .expect("delete must succeed"); + Ok(()) +} + /// Stat existing file with special chars should return metadata pub async fn test_stat_with_special_chars(op: Operator) -> Result<()> { // Ignore test for supabase until https://github.com/apache/incubator-opendal/issues/2194 addressed.
