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.

Reply via email to