From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 901F01FF185 for ; Mon, 4 Aug 2025 18:08:30 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id EEC3C3634F; Mon, 4 Aug 2025 18:09:59 +0200 (CEST) From: Christian Ebner To: pbs-devel@lists.proxmox.com Date: Mon, 4 Aug 2025 18:09:37 +0200 Message-ID: <20250804160937.660470-7-c.ebner@proxmox.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250804160937.660470-1-c.ebner@proxmox.com> References: <20250804160937.660470-1-c.ebner@proxmox.com> MIME-Version: 1.0 X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1754323777362 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.044 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pbs-devel] [PATCH proxmox 6/6] s3 client: add basic regression tests for response parsing X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox Backup Server development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pbs-devel-bounces@lists.proxmox.com Sender: "pbs-devel" Adds regression tests for methods parsing the http response body by using responses as found in the AWS documentation for the respective api method. Requires to derive PartialEq on S3ObjectKey and LastModifiedTimestamp structs in order to be able to easily compare the resulting contents. Signed-off-by: Christian Ebner --- proxmox-s3-client/src/object_key.rs | 2 +- proxmox-s3-client/src/response_reader.rs | 113 ++++++++++++++++++++++- proxmox-s3-client/src/timestamps.rs | 2 +- 3 files changed, 113 insertions(+), 4 deletions(-) diff --git a/proxmox-s3-client/src/object_key.rs b/proxmox-s3-client/src/object_key.rs index 327e8ac7..a68a588f 100644 --- a/proxmox-s3-client/src/object_key.rs +++ b/proxmox-s3-client/src/object_key.rs @@ -4,7 +4,7 @@ use anyhow::{bail, Error}; /// See https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html const S3_OBJECT_KEY_MAX_LENGTH: usize = 1024; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] /// S3 Object Key pub enum S3ObjectKey { /// Object key which will not be prefixed any further by the client diff --git a/proxmox-s3-client/src/response_reader.rs b/proxmox-s3-client/src/response_reader.rs index da76ec3f..f895db19 100644 --- a/proxmox-s3-client/src/response_reader.rs +++ b/proxmox-s3-client/src/response_reader.rs @@ -79,7 +79,7 @@ impl ListObjectsV2ResponseBody { } } -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, PartialEq)] #[serde(rename_all = "PascalCase")] /// Subset of contents used to deserialize the listed object contents of a list objects v2 respsonse. /// https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html#API_ListObjectsV2_ResponseSyntax @@ -231,7 +231,7 @@ pub struct Buckets { bucket: Vec, } -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, PartialEq)] #[serde(rename_all = "PascalCase")] /// Subset of contents used to deserialize individual buckets for response of a list buckets api /// call. @@ -511,3 +511,112 @@ impl ResponseReader { Ok(value) } } + +#[test] +fn parse_list_objects_v2_response_test() { + let response_body = r#" + + bucket0 + .cnt + 2 + 1000 + false + + .cnt/key0 + 2011-02-26T01:56:20.000Z + "bf1d737a4d46a19f3bced6905cc8b902" + 10 + STANDARD + + + .cnt/key1 + 2011-02-26T01:56:20.000Z + "9b2cf535f27731c974343645a3985328" + 20 + STANDARD + + + "#; + let result: ListObjectsV2ResponseBody = serde_xml_rs::from_str(&response_body).unwrap(); + assert_eq!(result.name, "bucket0"); + assert_eq!(result.prefix, ".cnt"); + assert_eq!(result.key_count, 2); + assert_eq!(result.max_keys, 1000); + assert_eq!(result.is_truncated, false); + assert_eq!( + result.contents.unwrap(), + vec![ + ListObjectsV2Contents { + key: S3ObjectKey::try_from("/.cnt/key0").unwrap(), + last_modified: LastModifiedTimestamp::from_str("2011-02-26T01:56:20.000Z").unwrap(), + e_tag: "\"bf1d737a4d46a19f3bced6905cc8b902\"".to_string(), + size: 10, + storage_class: "STANDARD".to_string(), + }, + ListObjectsV2Contents { + key: S3ObjectKey::try_from("/.cnt/key1").unwrap(), + last_modified: LastModifiedTimestamp::from_str("2011-02-26T01:56:20.000Z").unwrap(), + e_tag: "\"9b2cf535f27731c974343645a3985328\"".to_string(), + size: 20, + storage_class: "STANDARD".to_string(), + }, + ] + ); +} + +#[test] +fn parse_copy_object_response_test() { + let response_body = r#" + + 2009-10-12T17:50:30.000Z + "9b2cf535f27731c974343645a3985328" + + "#; + let result: CopyObjectResult = serde_xml_rs::from_str(&response_body).unwrap(); + assert_eq!( + result.last_modified, + LastModifiedTimestamp::from_str("2009-10-12T17:50:30.000Z").unwrap() + ); + assert_eq!( + result.e_tag, + "\"9b2cf535f27731c974343645a3985328\"".to_string() + ); +} + +#[test] +fn parse_list_buckets_response_test() { + let response_body = r#" + + + + 2019-12-11T23:32:47+00:00 + bucket0 + + + 2019-11-10T23:32:13+00:00 + bucket1 + + + + "#; + let result: ListAllMyBucketsResult = serde_xml_rs::from_str(&response_body).unwrap(); + assert_eq!( + result.buckets.unwrap().bucket, + vec![ + Bucket { + name: "bucket0".to_string(), + creation_date: LastModifiedTimestamp::from_str("2019-12-11T23:32:47+00:00") + .unwrap(), + bucket_arn: None, + bucket_region: None, + }, + Bucket { + name: "bucket1".to_string(), + creation_date: LastModifiedTimestamp::from_str("2019-11-10T23:32:13+00:00") + .unwrap(), + bucket_arn: None, + bucket_region: None, + }, + ] + ); +} diff --git a/proxmox-s3-client/src/timestamps.rs b/proxmox-s3-client/src/timestamps.rs index 22330966..661e1fdf 100644 --- a/proxmox-s3-client/src/timestamps.rs +++ b/proxmox-s3-client/src/timestamps.rs @@ -5,7 +5,7 @@ const VALID_MONTHS: [&str; 12] = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ]; -#[derive(Debug)] +#[derive(Debug, PartialEq)] /// Last modified timestamp as obtained from API response http headers. pub struct LastModifiedTimestamp { _datetime: iso8601::DateTime, -- 2.47.2 _______________________________________________ pbs-devel mailing list pbs-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel