This is an automated email from the ASF dual-hosted git repository. meteorgan pushed a commit to branch fix-lister-when-dir-not-exist in repository https://gitbox.apache.org/repos/asf/opendal.git
commit f604b667c5d7490c69fdfa5cc4f9a604e9d391a8 Author: meteorgan <[email protected]> AuthorDate: Tue Mar 11 01:18:16 2025 +0800 fix(core): fix list with recursive when object is not existing --- core/src/raw/oio/list/flat_list.rs | 18 ++++++++++++++++-- core/tests/behavior/async_list.rs | 15 +++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/core/src/raw/oio/list/flat_list.rs b/core/src/raw/oio/list/flat_list.rs index b368d2aea..c89d64551 100644 --- a/core/src/raw/oio/list/flat_list.rs +++ b/core/src/raw/oio/list/flat_list.rs @@ -92,8 +92,22 @@ where async fn next(&mut self) -> Result<Option<oio::Entry>> { loop { if let Some(de) = self.next_dir.take() { - let (_, l) = self.acc.list(de.path(), OpList::new()).await?; - self.active_lister.push((Some(de), l)); + let (_, mut l) = self.acc.list(de.path(), OpList::new()).await?; + if let Some(v) = l.next().await? { + self.active_lister.push((Some(de.clone()), l)); + + if v.mode().is_dir() { + // should not loop itself again + if v.path() != de.path() { + self.next_dir = Some(v); + continue; + } + } else { + return Ok(Some(v)); + } + } else { + return Ok(None); + } } let (de, lister) = match self.active_lister.last_mut() { diff --git a/core/tests/behavior/async_list.rs b/core/tests/behavior/async_list.rs index e59c07af7..0667a914a 100644 --- a/core/tests/behavior/async_list.rs +++ b/core/tests/behavior/async_list.rs @@ -42,6 +42,7 @@ pub fn tests(op: &Operator, tests: &mut Vec<Trial>) { test_list_nested_dir, test_list_dir_with_file_path, test_list_with_start_after, + test_list_non_exist_dir_with_recursive, test_list_dir_with_recursive, test_list_dir_with_recursive_no_trailing_slash, test_list_file_with_recursive, @@ -403,6 +404,20 @@ pub async fn test_list_with_start_after(op: Operator) -> Result<()> { Ok(()) } +pub async fn test_list_non_exist_dir_with_recursive(op: Operator) -> Result<()> { + let dir = format!("{}/", uuid::Uuid::new_v4()); + + 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); + } + debug!("got objects: {:?}", objects); + + assert_eq!(objects.len(), 0, "dir should only return empty"); + Ok(()) +} + pub async fn test_list_root_with_recursive(op: Operator) -> Result<()> { op.create_dir("/").await?;
