Skip to content

Commit 4c6c511

Browse files
aws-sdk-rust-cilandonxjamesrcoh
committed
[smithy-rs] Rollup of 2 commits
Includes commits: 61007da6 Add configuration ability to `mock_client` macro (#4001) 80392478 Fix s3 `checksum-mode` header in presigned requests (#4000) Co-authored-by: Landon James <[email protected]> Co-authored-by: Russell Cohen <[email protected]>
1 parent 9eba201 commit 4c6c511

File tree

9 files changed

+90
-20
lines changed

9 files changed

+90
-20
lines changed

examples/examples/cloudwatchlogs/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ path = "../../test-utils"
3232
version = "0.1.0"
3333

3434
[dev-dependencies]
35-
aws-smithy-mocks-experimental= { version = "0.2.1", path = "../../../sdk/aws-smithy-mocks-experimental" }
35+
aws-smithy-mocks-experimental= { version = "0.2.2", path = "../../../sdk/aws-smithy-mocks-experimental" }

examples/examples/ses/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ tracing = "0.1.40"
1212
tmpfile = "0.0.2"
1313
open = "5.1.2"
1414
aws-smithy-http= { version = "0.60.12", path = "../../../sdk/aws-smithy-http" }
15-
aws-smithy-mocks-experimental= { version = "0.2.1", path = "../../../sdk/aws-smithy-mocks-experimental" }
15+
aws-smithy-mocks-experimental= { version = "0.2.2", path = "../../../sdk/aws-smithy-mocks-experimental" }
1616
aws-config= { version = "1.5.16", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] }
1717
aws-sdk-sesv2= { version = "1.66.0", path = "../../../sdk/sesv2", features = ["test-util"] }
1818

sdk/aws-smithy-mocks-experimental/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ doc-scrape-examples = true
55

66
[package]
77
name = "aws-smithy-mocks-experimental"
8-
version = "0.2.1"
8+
version = "0.2.2"
99
authors = ["AWS Rust SDK Team <[email protected]>"]
1010
description = "Experimental testing utilities for smithy-rs generated clients"
1111
edition = "2021"

sdk/aws-smithy-mocks-experimental/README.md

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,41 @@
11
# aws-smithy-mocks
22

3-
Experiment for mocking Smithy Clients using interceptors. See [`tests/get-object-mocks.rs`](tests/get-object-mocks.rs) for example usage.
3+
This package allows testing clients generated by smithy-rs (including all packages of the AWS Rust SDK) by using interceptors to return stub responses. This approach is quite useful for testing both happy-path and simple error scenarios and avoids the need for mocking the entire client or using traits.
4+
5+
As an example, consider this simple usage with S3:
6+
7+
```rust
8+
#[tokio::test]
9+
async fn test_s3() {
10+
let s3_real_object = mock!(Client::get_object).then_output(|| {
11+
GetObjectOutput::builder()
12+
.body(ByteStream::from_static(b"test-test-test"))
13+
.build()
14+
});
15+
let s3 = mock_client!(aws_sdk_s3, [&s3_real_object]);
16+
let data = s3
17+
.get_object()
18+
.bucket("test-bucket")
19+
.key("correct-key")
20+
.send()
21+
.await
22+
.expect("success response")
23+
.body
24+
.collect()
25+
.await
26+
.expect("successful read")
27+
.to_vec();
28+
assert_eq!(data, b"test-test-test");
29+
assert_eq!(s3_real_object.num_calls(), 1);
30+
}
31+
```
32+
33+
You can find more examples in the `tests` folder of this crate.
34+
35+
## Shortcomings of this approach
36+
This approach is not well suited for testing precise error handling, especially when considering retries or interactions with HTTP responses—This approach hijacks the request response flow entirely and is not a faithful model in these cases.
37+
38+
If you need to test behavior around retries or connection management, you should use HTTP-connection based mocking instead.
439

540
<!-- anchor_start:footer -->
641
This crate is part of the [AWS SDK for Rust](https://awslabs.github.io/aws-sdk-rust/) and the [smithy-rs](https://github.com/smithy-lang/smithy-rs) code generator.

sdk/aws-smithy-mocks-experimental/src/lib.rs

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6+
//! This crate allows mocking of smithy clients.
7+
68
/* Automatically managed default lints */
79
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
810
/* End of automatically managed default lints */
@@ -94,23 +96,51 @@ macro_rules! mock {
9496
/// .then_error(||GetObjectError::NoSuchKey(NoSuchKey::builder().build()));
9597
/// let client = mock_client!(aws_sdk_s3, RuleMode::Sequential, &[&get_object_error_path, &get_object_happy_path]);
9698
/// ```
99+
///
100+
/// **Create a client but customize a specific setting**:
101+
/// ```rust,ignore
102+
/// use aws_sdk_s3::operation::get_object::GetObjectOutput;
103+
/// use aws_sdk_s3::Client;
104+
/// use aws_smithy_types::byte_stream::ByteStream;
105+
/// use aws_smithy_mocks_experimental::{mock_client, mock, RuleMode};
106+
/// let get_object_happy_path = mock!(Client::get_object)
107+
/// .match_requests(|req|req.bucket() == Some("test-bucket") && req.key() == Some("test-key"))
108+
/// .then_output(||GetObjectOutput::builder().body(ByteStream::from_static(b"12345-abcde")).build());
109+
/// let client = mock_client!(
110+
/// aws_sdk_s3,
111+
/// RuleMode::Sequential,
112+
/// &[&get_object_happy_path],
113+
/// // Perhaps you need to force path style
114+
/// |client_builder|client_builder.force_path_style(true)
115+
/// );
116+
/// ```
117+
///
97118
#[macro_export]
98119
macro_rules! mock_client {
99120
($aws_crate: ident, $rules: expr) => {
100121
mock_client!($aws_crate, $crate::RuleMode::Sequential, $rules)
101122
};
102123
($aws_crate: ident, $rule_mode: expr, $rules: expr) => {{
124+
mock_client!($aws_crate, $rule_mode, $rules, |conf| conf)
125+
}};
126+
($aws_crate: ident, $rule_mode: expr, $rules: expr, $additional_configuration: expr) => {{
103127
let mut mock_response_interceptor =
104128
$crate::MockResponseInterceptor::new().rule_mode($rule_mode);
105129
for rule in $rules {
106130
mock_response_interceptor = mock_response_interceptor.with_rule(rule)
107131
}
132+
// allow callers to avoid explicitly specifying the type
133+
fn coerce<T: Fn($aws_crate::config::Builder) -> $aws_crate::config::Builder>(f: T) -> T {
134+
f
135+
}
108136
$aws_crate::client::Client::from_conf(
109-
$aws_crate::config::Config::builder()
110-
.with_test_defaults()
111-
.region($aws_crate::config::Region::from_static("us-east-1"))
112-
.interceptor(mock_response_interceptor)
113-
.build(),
137+
coerce($additional_configuration)(
138+
$aws_crate::config::Config::builder()
139+
.with_test_defaults()
140+
.region($aws_crate::config::Region::from_static("us-east-1"))
141+
.interceptor(mock_response_interceptor),
142+
)
143+
.build(),
114144
)
115145
}};
116146
}

sdk/s3/src/operation/get_object.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ impl ::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin for GetObje
140140
.load::<::aws_smithy_types::checksum_config::ResponseChecksumValidation>()
141141
.unwrap_or(&::aws_smithy_types::checksum_config::ResponseChecksumValidation::WhenSupported);
142142

143+
let is_presigned_req = cfg.load::<crate::presigning::PresigningMarker>().is_some();
144+
145+
// For presigned requests we do not enable the checksum-mode header.
146+
if is_presigned_req {
147+
return ::std::result::Result::Ok(());
148+
}
149+
143150
// If validation setting is WhenSupported (or unknown) we enable response checksum
144151
// validation. If it is WhenRequired we do not enable (since there is no way to
145152
// indicate that a response checksum is required).

sdk/s3/tests/express.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,8 @@ async fn presigning() {
182182
][..],
183183
&query_params
184184
);
185-
// Presigned request has one header and that is the x-amz-checksum-mode
186-
// header with default value ENABLED
187-
assert_eq!(presigned.headers().count(), 1);
188-
let headers = presigned.headers().collect::<Vec<(&str, &str)>>();
189-
assert_eq!(headers.get(0).unwrap(), &("x-amz-checksum-mode", "ENABLED"));
185+
// Presigned request has no headers by default
186+
assert_eq!(presigned.headers().count(), 0);
190187
}
191188

192189
fn operation_request_with_checksum(

sdk/s3/tests/presigning.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,13 @@ async fn test_presigning() {
100100
][..],
101101
&query_params
102102
);
103-
assert_eq!(presigned.headers().count(), 1);
103+
assert_eq!(presigned.headers().count(), 0);
104104
let headers = presigned.headers().collect::<HashMap<_, _>>();
105-
assert_eq!(headers.get("x-amz-checksum-mode").unwrap(), &"ENABLED");
106105

107106
// Checksum headers should not be included by default in presigned requests
108107
assert_eq!(headers.get("x-amz-sdk-checksum-algorithm"), None);
109108
assert_eq!(headers.get("x-amz-checksum-crc32"), None);
109+
assert_eq!(headers.get("x-amz-checksum-mode"), None);
110110
}
111111

112112
#[tokio::test]

versions.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
smithy_rs_revision = '935c2651d62e63d1891e11d0e12ac50a940ceaa4'
1+
smithy_rs_revision = '8039247882fe6bb3c83f71601a9ae0a3327d6be0'
22
aws_doc_sdk_examples_revision = '9cd7f3841f9e6ba950edbf265b251b811db357fc'
33

44
[manual_interventions]
@@ -1997,7 +1997,7 @@ model_hash = '34648839402316ab9da4bef0fe11beb9bc3ec1d05b3ff7d09664ab74c0cb3d2b'
19971997
[crates.aws-sdk-s3]
19981998
category = 'AwsSdk'
19991999
version = '1.75.0'
2000-
source_hash = 'acb0a00457996a2f03b70635220081e9de447648dad9f175c6d37a917ecf439d'
2000+
source_hash = '0960bc2685bd70a5dcb85e289f5187107dd1e2d6282db1cba9f8bd84829ae2f5'
20012001
model_hash = '0b6147c08cab02d5e98d5f341db4ba1cf84f56772e0469883cb5bb5d4ef690b5'
20022002

20032003
[crates.aws-sdk-s3control]
@@ -2532,8 +2532,8 @@ source_hash = '4ccb6d7086aa9b1488c994a914f6bbc457b0d892daa5be7306e5be62b677fea6'
25322532

25332533
[crates.aws-smithy-mocks-experimental]
25342534
category = 'SmithyRuntime'
2535-
version = '0.2.1'
2536-
source_hash = '7fa397d78403e57648a4f565bf7f2978bc0702a15ce7cd775274253cfbca57aa'
2535+
version = '0.2.2'
2536+
source_hash = '25816d50f13dd87e2059ba310861e0166c088b0829770eeca63f27833f566cb8'
25372537

25382538
[crates.aws-smithy-protocol-test]
25392539
category = 'SmithyRuntime'
@@ -2992,3 +2992,4 @@ aws-sdk-workspaces = '1.70.0'
29922992
aws-sdk-workspacesthinclient = '1.60.0'
29932993
aws-sdk-workspacesweb = '1.63.0'
29942994
aws-sdk-xray = '1.60.0'
2995+
aws-smithy-mocks-experimental = '0.2.2'

0 commit comments

Comments
 (0)