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 c6a37ad7 test(core): test for `read_with_if_none_match` (#2141)
c6a37ad7 is described below
commit c6a37ad7f0cafee7215f473117af11acaec8825f
Author: Suyan <[email protected]>
AuthorDate: Thu Apr 27 19:13:45 2023 +0800
test(core): test for `read_with_if_none_match` (#2141)
* add test for read_with_if_none_match
Signed-off-by: suyanhanx <[email protected]>
* enable read for webdav
Signed-off-by: suyanhanx <[email protected]>
* Revert "enable read for webdav"
This reverts commit addb51870d8ddb1740017b9ecee66920a24904e0.
---------
Signed-off-by: suyanhanx <[email protected]>
---
core/src/services/gcs/backend.rs | 2 ++
core/src/services/http/backend.rs | 2 ++
core/src/services/obs/backend.rs | 2 ++
core/src/services/oss/backend.rs | 2 ++
core/tests/behavior/read_only.rs | 71 +++++++++++++++++++++++++++++++++++++++
core/tests/behavior/write.rs | 49 +++++++++++++++++++++++----
6 files changed, 122 insertions(+), 6 deletions(-)
diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs
index a53a20ab..28ba61e1 100644
--- a/core/src/services/gcs/backend.rs
+++ b/core/src/services/gcs/backend.rs
@@ -381,6 +381,8 @@ impl Accessor for GcsBackend {
read: true,
read_can_next: true,
+ read_with_if_match: true,
+ read_with_if_none_match: true,
write: true,
write_with_content_type: true,
diff --git a/core/src/services/http/backend.rs
b/core/src/services/http/backend.rs
index 8a4d3fb6..a39b645c 100644
--- a/core/src/services/http/backend.rs
+++ b/core/src/services/http/backend.rs
@@ -265,6 +265,8 @@ impl Accessor for HttpBackend {
read: true,
read_can_next: true,
+ read_with_if_match: true,
+ read_with_if_none_match: true,
..Default::default()
});
diff --git a/core/src/services/obs/backend.rs b/core/src/services/obs/backend.rs
index 4eaf9c01..e67492c3 100644
--- a/core/src/services/obs/backend.rs
+++ b/core/src/services/obs/backend.rs
@@ -312,6 +312,8 @@ impl Accessor for ObsBackend {
read: true,
read_can_next: true,
+ read_with_if_match: true,
+ read_with_if_none_match: true,
write: true,
write_with_content_type: true,
diff --git a/core/src/services/oss/backend.rs b/core/src/services/oss/backend.rs
index 1388c25a..47bed953 100644
--- a/core/src/services/oss/backend.rs
+++ b/core/src/services/oss/backend.rs
@@ -430,6 +430,8 @@ impl Accessor for OssBackend {
read: true,
read_can_next: true,
+ read_with_if_match: true,
+ read_with_if_none_match: true,
write: true,
write_with_cache_control: true,
diff --git a/core/tests/behavior/read_only.rs b/core/tests/behavior/read_only.rs
index fdaf939e..5fe41660 100644
--- a/core/tests/behavior/read_only.rs
+++ b/core/tests/behavior/read_only.rs
@@ -17,6 +17,7 @@
use anyhow::Result;
use futures::AsyncReadExt;
+use opendal::ops::OpRead;
use opendal::ops::OpStat;
use opendal::EntryMode;
use opendal::ErrorKind;
@@ -76,6 +77,8 @@ macro_rules! behavior_read_tests {
test_reader_tail,
test_read_not_exist,
test_read_with_dir_path,
+ test_read_with_if_match,
+ test_read_with_if_none_match,
);
)*
};
@@ -304,3 +307,71 @@ pub async fn test_read_with_dir_path(op: Operator) ->
Result<()> {
Ok(())
}
+
+/// Read with if_match should match, else get a ConditionNotMatch error.
+pub async fn test_read_with_if_match(op: Operator) -> Result<()> {
+ if !op.info().capability().read_with_if_match {
+ return Ok(());
+ }
+
+ let path = "normal_file";
+
+ let meta = op.stat(path).await?;
+
+ let mut op_read = OpRead::default();
+ op_read = op_read.with_if_match("invalid_etag");
+
+ let res = op.read_with(path, op_read).await;
+ assert!(res.is_err());
+ assert_eq!(res.unwrap_err().kind(), ErrorKind::ConditionNotMatch);
+
+ let mut op_read = OpRead::default();
+ op_read = op_read.with_if_match(meta.etag().expect("etag must exist"));
+
+ let bs = op
+ .read_with(path, op_read)
+ .await
+ .expect("read must succeed");
+ assert_eq!(bs.len(), 262144, "read size");
+ assert_eq!(
+ format!("{:x}", Sha256::digest(&bs)),
+ "e7541d0f50d2d5c79dc41f28ccba8e0cdfbbc8c4b1aa1a0110184ef0ef67689f",
+ "read content"
+ );
+
+ Ok(())
+}
+
+/// Read with if_none_match should match, else get a ConditionNotMatch error.
+pub async fn test_read_with_if_none_match(op: Operator) -> Result<()> {
+ if !op.info().capability().read_with_if_none_match {
+ return Ok(());
+ }
+
+ let path = "normal_file";
+
+ let meta = op.stat(path).await?;
+
+ let mut op_read = OpRead::default();
+ op_read = op_read.with_if_none_match(meta.etag().expect("etag must
exist"));
+
+ let res = op.read_with(path, op_read).await;
+ assert!(res.is_err());
+ assert_eq!(res.unwrap_err().kind(), ErrorKind::ConditionNotMatch);
+
+ let mut op_read = OpRead::default();
+ op_read = op_read.with_if_none_match("invalid_etag");
+
+ let bs = op
+ .read_with(path, op_read)
+ .await
+ .expect("read must succeed");
+ assert_eq!(bs.len(), 262144, "read size");
+ assert_eq!(
+ format!("{:x}", Sha256::digest(&bs)),
+ "e7541d0f50d2d5c79dc41f28ccba8e0cdfbbc8c4b1aa1a0110184ef0ef67689f",
+ "read content"
+ );
+
+ Ok(())
+}
diff --git a/core/tests/behavior/write.rs b/core/tests/behavior/write.rs
index c1212cfb..d15b8b25 100644
--- a/core/tests/behavior/write.rs
+++ b/core/tests/behavior/write.rs
@@ -95,6 +95,7 @@ macro_rules! behavior_write_tests {
test_reader_tail,
test_read_not_exist,
test_read_with_if_match,
+ test_read_with_if_none_match,
test_fuzz_range_reader,
test_fuzz_offset_reader,
test_fuzz_part_reader,
@@ -585,18 +586,54 @@ pub async fn test_read_with_if_match(op: Operator) ->
Result<()> {
let meta = op.stat(&path).await?;
- let mut op_if_match = OpRead::default();
- op_if_match = op_if_match.with_if_match("invalid_etag");
+ let mut op_read = OpRead::default();
+ op_read = op_read.with_if_match("invalid_etag");
- let res = op.read_with(&path, op_if_match).await;
+ let res = op.read_with(&path, op_read).await;
assert!(res.is_err());
assert_eq!(res.unwrap_err().kind(), ErrorKind::ConditionNotMatch);
- let mut op_if_match = OpRead::default();
- op_if_match = op_if_match.with_if_match(meta.etag().expect("etag must
exist"));
+ let mut op_read = OpRead::default();
+ op_read = op_read.with_if_match(meta.etag().expect("etag must exist"));
+
+ let bs = op
+ .read_with(&path, op_read)
+ .await
+ .expect("read must succeed");
+ assert_eq!(bs, content);
+
+ op.delete(&path).await.expect("delete must succeed");
+ Ok(())
+}
+
+/// Read with if_none_match should match, else get a ConditionNotMatch error.
+pub async fn test_read_with_if_none_match(op: Operator) -> Result<()> {
+ if !op.info().capability().read_with_if_none_match {
+ return Ok(());
+ }
+
+ let path = uuid::Uuid::new_v4().to_string();
+ debug!("Generate a random file: {}", &path);
+ let (content, _) = gen_bytes();
+
+ op.write(&path, content.clone())
+ .await
+ .expect("write must succeed");
+
+ let meta = op.stat(&path).await?;
+
+ let mut op_read = OpRead::default();
+ op_read = op_read.with_if_none_match(meta.etag().expect("etag must
exist"));
+
+ let res = op.read_with(&path, op_read).await;
+ assert!(res.is_err());
+ assert_eq!(res.unwrap_err().kind(), ErrorKind::ConditionNotMatch);
+
+ let mut op_read = OpRead::default();
+ op_read = op_read.with_if_none_match("invalid_etag");
let bs = op
- .read_with(&path, op_if_match)
+ .read_with(&path, op_read)
.await
.expect("read must succeed");
assert_eq!(bs, content);