Skip to content

Commit

Permalink
feat: Add write_can_empty in Capability and related tests (#3200)
Browse files Browse the repository at this point in the history
* feat: Add write_can_empty in Capability and related tests

Signed-off-by: Xuanwo <github@xuanwo.io>

* Fix gcs

Signed-off-by: Xuanwo <github@xuanwo.io>

---------

Signed-off-by: Xuanwo <github@xuanwo.io>
  • Loading branch information
Xuanwo authored Sep 28, 2023
1 parent 838cea9 commit 359771a
Show file tree
Hide file tree
Showing 14 changed files with 44 additions and 2 deletions.
1 change: 1 addition & 0 deletions core/src/raw/adapters/kv/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl<S: Adapter> Accessor for Backend<S> {
}

if cap.write {
cap.write_can_empty = true;
cap.create_dir = true;
cap.delete = true;
}
Expand Down
1 change: 1 addition & 0 deletions core/src/raw/adapters/typed_kv/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl<S: Adapter> Accessor for Backend<S> {

if kv_cap.set {
cap.write = true;
cap.write_can_empty = true;
cap.create_dir = true;
}

Expand Down
8 changes: 7 additions & 1 deletion core/src/raw/oio/write/multipart_upload_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,13 @@ where
(w, res)
}));
}
None => return Poll::Ready(Ok(())),
None => {
// Call write_once if there is no data in cache and no upload_id.
self.state = State::Close(Box::pin(async move {
let res = w.write_once(0, AsyncBody::Empty).await;
(w, res)
}));
}
},
}
}
Expand Down
8 changes: 7 additions & 1 deletion core/src/raw/oio/write/range_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,13 @@ impl<W: RangeWrite> oio::Write for RangeWriter<W> {
(w, res)
}));
}
None => return Poll::Ready(Ok(())),
None => {
// Call write_once if there is no data in buffer and no location.
self.state = State::Complete(Box::pin(async move {
let res = w.write_once(0, AsyncBody::Empty).await;
(w, res)
}));
}
},
}
}
Expand Down
1 change: 1 addition & 0 deletions core/src/services/azblob/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ impl Accessor for AzblobBackend {
read_with_override_content_disposition: true,

write: true,
write_can_empty: true,
write_can_append: true,
write_with_cache_control: true,
write_with_content_type: true,
Expand Down
1 change: 1 addition & 0 deletions core/src/services/cos/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ impl Accessor for CosBackend {
read_with_if_none_match: true,

write: true,
write_can_empty: true,
write_can_append: true,
write_can_multi: true,
write_with_content_type: true,
Expand Down
1 change: 1 addition & 0 deletions core/src/services/fs/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ impl Accessor for FsBackend {
read_with_range: true,

write: true,
write_can_empty: true,
write_can_append: true,
write_can_multi: true,
create_dir: true,
Expand Down
1 change: 1 addition & 0 deletions core/src/services/gcs/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ impl Accessor for GcsBackend {
read_with_if_none_match: true,

write: true,
write_can_empty: true,
write_can_multi: true,
write_with_content_type: true,
// The buffer size should be a multiple of 256 KiB (256 x 1024 bytes), unless it's the last chunk that completes the upload.
Expand Down
1 change: 1 addition & 0 deletions core/src/services/obs/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ impl Accessor for ObsBackend {
read_with_if_none_match: true,

write: true,
write_can_empty: true,
write_can_append: true,
write_can_multi: true,
write_with_content_type: true,
Expand Down
1 change: 1 addition & 0 deletions core/src/services/oss/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ impl Accessor for OssBackend {
read_with_if_none_match: true,

write: true,
write_can_empty: true,
write_can_append: true,
write_can_multi: true,
write_with_cache_control: true,
Expand Down
1 change: 1 addition & 0 deletions core/src/services/s3/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,7 @@ impl Accessor for S3Backend {
read_with_override_content_type: true,

write: true,
write_can_empty: true,
write_can_multi: true,
write_with_cache_control: true,
write_with_content_type: true,
Expand Down
1 change: 1 addition & 0 deletions core/src/services/webdav/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ impl Accessor for WebdavBackend {
read_with_range: true,

write: true,
write_can_empty: true,

create_dir: true,
delete: true,
Expand Down
2 changes: 2 additions & 0 deletions core/src/types/capability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ pub struct Capability {
pub write: bool,
/// If operator supports write can be called in multi times.
pub write_can_multi: bool,
/// If operator supports write with empty content.
pub write_can_empty: bool,
/// If operator supports write by append.
pub write_can_append: bool,
/// If operator supports write with content type.
Expand Down
18 changes: 18 additions & 0 deletions core/tests/behavior/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub fn behavior_write_tests(op: &Operator) -> Vec<Trial> {
test_create_dir,
test_create_dir_existing,
test_write_only,
test_write_with_empty_content,
test_write_with_dir_path,
test_write_with_special_chars,
test_write_with_cache_control,
Expand Down Expand Up @@ -136,6 +137,23 @@ pub async fn test_write_only(op: Operator) -> Result<()> {
Ok(())
}

/// Write a file with empty content.
pub async fn test_write_with_empty_content(op: Operator) -> Result<()> {
if !op.info().full_capability().write_can_empty {
return Ok(());
}

let path = uuid::Uuid::new_v4().to_string();

op.write(&path, vec![]).await?;

let meta = op.stat(&path).await.expect("stat must succeed");
assert_eq!(meta.content_length(), 0);

op.delete(&path).await.expect("delete must succeed");
Ok(())
}

/// Write file with dir path should return an error
pub async fn test_write_with_dir_path(op: Operator) -> Result<()> {
let path = format!("{}/", uuid::Uuid::new_v4());
Expand Down

0 comments on commit 359771a

Please sign in to comment.