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();