From f87943a39d81efcd250ff7ddfa3bf562a2e61ece Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Wed, 19 Feb 2025 18:26:03 +0100 Subject: [PATCH] tests: add test for http preconditions --- src/garage/tests/s3/objects.rs | 126 ++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 1 deletion(-) diff --git a/src/garage/tests/s3/objects.rs b/src/garage/tests/s3/objects.rs index dfc5253d..d63ac000 100644 --- a/src/garage/tests/s3/objects.rs +++ b/src/garage/tests/s3/objects.rs @@ -1,5 +1,6 @@ use crate::common; -use aws_sdk_s3::primitives::ByteStream; +use aws_sdk_s3::error::SdkError; +use aws_sdk_s3::primitives::{ByteStream, DateTime}; use aws_sdk_s3::types::{Delete, ObjectIdentifier}; const STD_KEY: &str = "hello world"; @@ -125,6 +126,129 @@ async fn test_putobject() { } } +#[tokio::test] +async fn test_precondition() { + let ctx = common::context(); + let bucket = ctx.create_bucket("precondition"); + + let etag = "\"46cf18a9b447991b450cad3facf5937e\""; + let etag2 = "\"ae4984b984cd984fe98d4efa954dce98\""; + let data = ByteStream::from_static(BODY); + + let r = ctx + .client + .put_object() + .bucket(&bucket) + .key(STD_KEY) + .body(data) + .send() + .await + .unwrap(); + + assert_eq!(r.e_tag.unwrap().as_str(), etag); + + let last_modified; + { + let o = ctx + .client + .get_object() + .bucket(&bucket) + .key(STD_KEY) + .if_match(etag) + .send() + .await + .unwrap(); + assert_eq!(o.e_tag.as_ref().unwrap().as_str(), etag); + last_modified = o.last_modified.unwrap(); + + let err = ctx + .client + .get_object() + .bucket(&bucket) + .key(STD_KEY) + .if_match(etag2) + .send() + .await; + assert!( + matches!(err, Err(SdkError::ServiceError(se)) if se.raw().status().as_u16() == 412) + ); + } + { + let o = ctx + .client + .get_object() + .bucket(&bucket) + .key(STD_KEY) + .if_none_match(etag2) + .send() + .await + .unwrap(); + assert_eq!(o.e_tag.as_ref().unwrap().as_str(), etag); + + let err = ctx + .client + .get_object() + .bucket(&bucket) + .key(STD_KEY) + .if_none_match(etag) + .send() + .await; + assert!( + matches!(err, Err(SdkError::ServiceError(se)) if se.raw().status().as_u16() == 304) + ); + } + let older_date = DateTime::from_secs_f64(last_modified.as_secs_f64() - 10.0); + let newer_date = DateTime::from_secs_f64(last_modified.as_secs_f64() + 10.0); + { + let err = ctx + .client + .get_object() + .bucket(&bucket) + .key(STD_KEY) + .if_modified_since(newer_date) + .send() + .await; + assert!( + matches!(err, Err(SdkError::ServiceError(se)) if se.raw().status().as_u16() == 304) + ); + + let o = ctx + .client + .get_object() + .bucket(&bucket) + .key(STD_KEY) + .if_modified_since(older_date) + .send() + .await + .unwrap(); + assert_eq!(o.e_tag.as_ref().unwrap().as_str(), etag); + } + { + let err = ctx + .client + .get_object() + .bucket(&bucket) + .key(STD_KEY) + .if_unmodified_since(older_date) + .send() + .await; + assert!( + matches!(err, Err(SdkError::ServiceError(se)) if se.raw().status().as_u16() == 412) + ); + + let o = ctx + .client + .get_object() + .bucket(&bucket) + .key(STD_KEY) + .if_unmodified_since(newer_date) + .send() + .await + .unwrap(); + assert_eq!(o.e_tag.as_ref().unwrap().as_str(), etag); + } +} + #[tokio::test] async fn test_getobject() { let ctx = common::context();