This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new a040f1da feat: add behavioral test for Write::abort (#2018)
a040f1da is described below

commit a040f1da329914b7ef58a1b1b3d65716443165c9
Author: Lei, HUANG <[email protected]>
AuthorDate: Mon Apr 17 18:12:34 2023 +0800

    feat: add behavioral test for Write::abort (#2018)
    
    * feat: add abort API to opendal::types::writer::Writer. Add behavoiral 
test for abort
    
    * fix: skip test if abort/append is not supported yet
    
    * fix: s3 returns 204 when abort suceeds
---
 core/src/services/s3/writer.rs |  3 ++-
 core/src/types/writer.rs       | 13 +++++++++++++
 core/tests/behavior/write.rs   | 29 +++++++++++++++++++++++++++++
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/core/src/services/s3/writer.rs b/core/src/services/s3/writer.rs
index ccb7e96d..d75906f9 100644
--- a/core/src/services/s3/writer.rs
+++ b/core/src/services/s3/writer.rs
@@ -137,7 +137,8 @@ impl oio::Write for S3Writer {
             .s3_abort_multipart_upload(&self.path, upload_id)
             .await?;
         match resp.status() {
-            StatusCode::OK => {
+            // s3 returns code 204 if abort succeeds.
+            StatusCode::NO_CONTENT => {
                 resp.into_body().consume().await?;
                 Ok(())
             }
diff --git a/core/src/types/writer.rs b/core/src/types/writer.rs
index 96c8c0e5..dc4d2bfd 100644
--- a/core/src/types/writer.rs
+++ b/core/src/types/writer.rs
@@ -28,6 +28,7 @@ use futures::AsyncWrite;
 use futures::FutureExt;
 
 use crate::ops::OpWrite;
+use crate::raw::oio::Write;
 use crate::raw::*;
 use crate::*;
 
@@ -75,6 +76,18 @@ impl Writer {
         }
     }
 
+    /// Abort inner writer.
+    pub async fn abort(&mut self) -> Result<()> {
+        if let State::Idle(Some(w)) = &mut self.state {
+            w.abort().await
+        } else {
+            unreachable!(
+                "writer state invalid while abort, expect Idle, actual {}",
+                self.state
+            );
+        }
+    }
+
     /// Close the writer and make sure all data have been stored.
     pub async fn close(&mut self) -> Result<()> {
         if let State::Idle(Some(w)) = &mut self.state {
diff --git a/core/tests/behavior/write.rs b/core/tests/behavior/write.rs
index bb682031..91c9ec08 100644
--- a/core/tests/behavior/write.rs
+++ b/core/tests/behavior/write.rs
@@ -98,6 +98,7 @@ macro_rules! behavior_write_tests {
                 test_delete_not_existing,
                 test_delete_stream,
                 test_append,
+                test_abort_writer,
             );
         )*
     };
@@ -578,6 +579,34 @@ pub async fn test_read_with_special_chars(op: Operator) -> 
Result<()> {
     Ok(())
 }
 
+// Delete existing file should succeed.
+pub async fn test_abort_writer(op: Operator) -> Result<()> {
+    let path = uuid::Uuid::new_v4().to_string();
+    let (content, _) = gen_bytes();
+
+    let mut writer = match op.writer(&path).await {
+        Ok(writer) => writer,
+        Err(e) => {
+            assert_eq!(e.kind(), ErrorKind::Unsupported);
+            return Ok(());
+        }
+    };
+
+    if let Err(e) = writer.append(content).await {
+        assert_eq!(e.kind(), ErrorKind::Unsupported);
+        return Ok(());
+    }
+
+    if let Err(e) = writer.abort().await {
+        assert_eq!(e.kind(), ErrorKind::Unsupported);
+        return Ok(());
+    }
+
+    // Aborted writer should not write actual file.
+    assert!(!op.is_exist(&path).await?);
+    Ok(())
+}
+
 // Delete existing file should succeed.
 pub async fn test_delete(op: Operator) -> Result<()> {
     let path = uuid::Uuid::new_v4().to_string();

Reply via email to