1 + | /*
|
2 + | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
3 + | * SPDX-License-Identifier: Apache-2.0
|
4 + | */
|
5 + |
|
6 + | #![cfg(feature = "test-util")]
|
7 + |
|
8 + | use aws_sdk_s3::{config::Region, Client, Config};
|
9 + | use aws_smithy_async::test_util::ManualTimeSource;
|
10 + | use aws_smithy_async::time::SharedTimeSource;
|
11 + | use aws_smithy_http_client::test_util::{ReplayEvent, StaticReplayClient};
|
12 + | use aws_smithy_runtime::client::retries::TokenBucket;
|
13 + | use aws_smithy_runtime_api::box_error::BoxError;
|
14 + | use aws_smithy_runtime_api::client::interceptors::context::BeforeTransmitInterceptorContextMut;
|
15 + | use aws_smithy_runtime_api::client::interceptors::Intercept;
|
16 + | use aws_smithy_runtime_api::client::runtime_components::RuntimeComponents;
|
17 + | use aws_smithy_types::body::SdkBody;
|
18 + | use aws_smithy_types::config_bag::ConfigBag;
|
19 + | use std::sync::LazyLock;
|
20 + | use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
21 + |
|
22 + | static THE_TIME: LazyLock<SystemTime> =
|
23 + | LazyLock::new(|| UNIX_EPOCH + Duration::from_secs(12344321));
|
24 + |
|
25 + | #[derive(Debug)]
|
26 + | struct TimeSourceValidationInterceptor;
|
27 + |
|
28 + | impl Intercept for TimeSourceValidationInterceptor {
|
29 + | fn name(&self) -> &'static str {
|
30 + | "TimeSourceValidationInterceptor"
|
31 + | }
|
32 + |
|
33 + | fn modify_before_transmit(
|
34 + | &self,
|
35 + | _context: &mut BeforeTransmitInterceptorContextMut<'_>,
|
36 + | _runtime_components: &RuntimeComponents,
|
37 + | cfg: &mut ConfigBag,
|
38 + | ) -> Result<(), BoxError> {
|
39 + | if let Some(token_bucket) = cfg.load::<TokenBucket>() {
|
40 + | let token_bucket_time_source = token_bucket.time_source();
|
41 + | let token_time = token_bucket_time_source.now();
|
42 + |
|
43 + | assert_eq!(
|
44 + | *THE_TIME, token_time,
|
45 + | "Token source should match the configured time source"
|
46 + | );
|
47 + | }
|
48 + | Ok(())
|
49 + | }
|
50 + | }
|
51 + |
|
52 + | #[tokio::test]
|
53 + | async fn test_token_bucket_gets_time_source_from_config() {
|
54 + | let time_source = ManualTimeSource::new(*THE_TIME);
|
55 + | let shared_time_source = SharedTimeSource::new(time_source);
|
56 + |
|
57 + | let http_client = StaticReplayClient::new(vec![ReplayEvent::new(
|
58 + | http_1x::Request::builder()
|
59 + | .uri("https://www.doesntmatter.com")
|
60 + | .body(SdkBody::empty())
|
61 + | .unwrap(),
|
62 + | http_1x::Response::builder()
|
63 + | .status(200)
|
64 + | .body(SdkBody::from("<ListBucketResult></ListBucketResult>"))
|
65 + | .unwrap(),
|
66 + | )]);
|
67 + |
|
68 + | let config = Config::builder()
|
69 + | .region(Region::new("us-east-1"))
|
70 + | .http_client(http_client)
|
71 + | .time_source(shared_time_source)
|
72 + | .interceptor(TimeSourceValidationInterceptor)
|
73 + | .build();
|
74 + |
|
75 + | let client = Client::from_conf(config);
|
76 + |
|
77 + | let _result = client
|
78 + | .list_objects_v2()
|
79 + | .bucket("test-bucket")
|
80 + | .send()
|
81 + | .await
|
82 + | .unwrap();
|
83 + | }
|