Skip to content

Commit

Permalink
read/stat non-existent version returns NotFound, delete non-existent …
Browse files Browse the repository at this point in the history
…version returns Ok
  • Loading branch information
meteorgan committed Sep 25, 2024
1 parent d76f776 commit fc794d9
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 31 deletions.
8 changes: 4 additions & 4 deletions core/src/services/s3/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -902,15 +902,15 @@ impl Access for S3Backend {
stat_with_override_cache_control: !self.core.disable_stat_with_override,
stat_with_override_content_disposition: !self.core.disable_stat_with_override,
stat_with_override_content_type: !self.core.disable_stat_with_override,
stat_with_versioning: self.core.enable_versioning,
stat_with_version: self.core.enable_versioning,

read: true,
read_with_if_match: true,
read_with_if_none_match: true,
read_with_override_cache_control: true,
read_with_override_content_disposition: true,
read_with_override_content_type: true,
read_with_versioning: self.core.enable_versioning,
read_with_version: self.core.enable_versioning,

write: true,
write_can_empty: true,
Expand All @@ -933,15 +933,15 @@ impl Access for S3Backend {
},

delete: true,
delete_with_versioning: self.core.enable_versioning,
delete_with_version: self.core.enable_versioning,

copy: true,

list: true,
list_with_limit: true,
list_with_start_after: true,
list_with_recursive: true,
list_with_versioning: self.core.enable_versioning,
list_with_version: self.core.enable_versioning,

presign: true,
presign_stat: true,
Expand Down
2 changes: 1 addition & 1 deletion core/src/services/s3/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub(super) fn parse_error(resp: Response<Buffer>) -> Error {
let (mut kind, mut retryable) = match parts.status.as_u16() {
403 => (ErrorKind::PermissionDenied, false),
404 => (ErrorKind::NotFound, false),
304 | 400 | 412 => (ErrorKind::ConditionNotMatch, false),
304 | 412 => (ErrorKind::ConditionNotMatch, false),
// Service like R2 could return 499 error with a message like:
// Client Disconnect, we should retry it.
499 => (ErrorKind::Unexpected, true),
Expand Down
8 changes: 4 additions & 4 deletions core/src/types/capability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub struct Capability {
/// if operator supports stat with override content type.
pub stat_with_override_content_type: bool,
/// if operator supports stat with versioning.
pub stat_with_versioning: bool,
pub stat_with_version: bool,

/// If operator supports read.
pub read: bool,
Expand All @@ -83,7 +83,7 @@ pub struct Capability {
/// if operator supports read with override content type.
pub read_with_override_content_type: bool,
/// if operator supports read with versioning.
pub read_with_versioning: bool,
pub read_with_version: bool,

/// If operator supports write.
pub write: bool,
Expand Down Expand Up @@ -124,7 +124,7 @@ pub struct Capability {
/// If operator supports delete.
pub delete: bool,
/// if operator supports delete with versioning.
pub delete_with_versioning: bool,
pub delete_with_version: bool,

/// If operator supports copy.
pub copy: bool,
Expand All @@ -141,7 +141,7 @@ pub struct Capability {
/// If backend supports list with recursive.
pub list_with_recursive: bool,
/// if operator supports list with versioning.
pub list_with_versioning: bool,
pub list_with_version: bool,

/// If operator supports presign.
pub presign: bool,
Expand Down
21 changes: 16 additions & 5 deletions core/tests/behavior/async_delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ pub async fn test_remove_all_with_prefix_exists(op: Operator) -> Result<()> {
}

pub async fn test_delete_with_version(op: Operator) -> Result<()> {
if !op.info().full_capability().delete_with_versioning {
if !op.info().full_capability().delete_with_version {
return Ok(());
}

Expand Down Expand Up @@ -252,21 +252,32 @@ pub async fn test_delete_with_version(op: Operator) -> Result<()> {
}

pub async fn test_delete_with_not_existing_version(op: Operator) -> Result<()> {
if !op.info().full_capability().delete_with_versioning {
if !op.info().full_capability().delete_with_version {
return Ok(());
}

// retrieve a valid version
let (path, content, _) = TEST_FIXTURE.new_file(op.clone());
op.write(path.as_str(), content)
.await
.expect("write must success");
let version = op
.stat(path.as_str())
.await
.expect("stat must success")
.version()
.expect("must have stat")
.to_string();

let (path, content, _) = TEST_FIXTURE.new_file(op.clone());
op.write(path.as_str(), content)
.await
.expect("write must success");
let ret = op
.delete_with(path.as_str())
.version("not-existing-version")
.version(version.as_str())
.await;
assert!(ret.is_err());
assert_eq!(ret.unwrap_err().kind(), ErrorKind::ConditionNotMatch);
assert!(ret.is_ok());

Ok(())
}
6 changes: 3 additions & 3 deletions core/tests/behavior/async_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ pub async fn test_list_only(op: Operator) -> Result<()> {
}

pub async fn test_list_files_with_version(op: Operator) -> Result<()> {
if !op.info().full_capability().list_with_versioning {
if !op.info().full_capability().list_with_version {
return Ok(());
}

Expand Down Expand Up @@ -722,7 +722,7 @@ pub async fn test_list_with_version_and_limit(op: Operator) -> Result<()> {
if op.info().scheme() == Scheme::Gdrive {
return Ok(());
}
if !op.info().full_capability().list_with_versioning {
if !op.info().full_capability().list_with_version {
return Ok(());
}

Expand Down Expand Up @@ -775,7 +775,7 @@ pub async fn test_list_with_version_and_limit(op: Operator) -> Result<()> {
}

pub async fn test_list_with_version_and_start_after(op: Operator) -> Result<()> {
if !op.info().full_capability().list_with_versioning {
if !op.info().full_capability().list_with_version {
return Ok(());
}

Expand Down
23 changes: 16 additions & 7 deletions core/tests/behavior/async_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ pub async fn test_read_only_read_with_if_none_match(op: Operator) -> anyhow::Res
}

pub async fn test_read_with_version(op: Operator) -> anyhow::Result<()> {
if !op.info().full_capability().read_with_versioning {
if !op.info().full_capability().read_with_version {
return Ok(());
}

Expand Down Expand Up @@ -591,21 +591,30 @@ pub async fn test_read_with_version(op: Operator) -> anyhow::Result<()> {
}

pub async fn test_read_with_not_existing_version(op: Operator) -> anyhow::Result<()> {
if !op.info().full_capability().read_with_versioning {
if !op.info().full_capability().read_with_version {
return Ok(());
}

// retrieve a valid version
let (path, content, _) = TEST_FIXTURE.new_file(op.clone());
op.write(path.as_str(), content.clone())
.await
.expect("write must success");
let version = op
.stat(path.as_str())
.await
.expect("stat must success")
.version()
.expect("must have version")
.to_string();

let ret = op
.read_with(path.as_str())
.version("not-existing-version")
.await;
let (path, content, _) = TEST_FIXTURE.new_file(op.clone());
op.write(path.as_str(), content)
.await
.expect("write must success");
let ret = op.read_with(path.as_str()).version(&version).await;
assert!(ret.is_err());
assert_eq!(ret.unwrap_err().kind(), ErrorKind::ConditionNotMatch);
assert_eq!(ret.unwrap_err().kind(), ErrorKind::NotFound);

Ok(())
}
23 changes: 16 additions & 7 deletions core/tests/behavior/async_stat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ pub async fn test_read_only_stat_root(op: Operator) -> Result<()> {
}

pub async fn test_stat_with_version(op: Operator) -> Result<()> {
if !op.info().full_capability().stat_with_versioning {
if !op.info().full_capability().stat_with_version {
return Ok(());
}

Expand Down Expand Up @@ -540,21 +540,30 @@ pub async fn test_stat_with_version(op: Operator) -> Result<()> {
}

pub async fn stat_with_not_existing_version(op: Operator) -> Result<()> {
if !op.info().full_capability().stat_with_versioning {
if !op.info().full_capability().stat_with_version {
return Ok(());
}

// retrieve a valid version
let (path, content, _) = TEST_FIXTURE.new_file(op.clone());
op.write(path.as_str(), content.clone())
.await
.expect("write must success");
let version = op
.stat(path.as_str())
.await
.expect("stat must success")
.version()
.expect("must have version")
.to_string();

let ret = op
.stat_with(path.as_str())
.version("not-existing-version")
.await;
let (path, content, _) = TEST_FIXTURE.new_file(op.clone());
op.write(path.as_str(), content)
.await
.expect("write must success");
let ret = op.stat_with(path.as_str()).version(version.as_str()).await;
assert!(ret.is_err());
assert_eq!(ret.unwrap_err().kind(), ErrorKind::ConditionNotMatch);
assert_eq!(ret.unwrap_err().kind(), ErrorKind::NotFound);

Ok(())
}

0 comments on commit fc794d9

Please sign in to comment.