Loading aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/IntegrationTestDependencies.kt +13 −3 Original line number Diff line number Diff line Loading @@ -82,7 +82,7 @@ class IntegrationTestDependencies( private fun serviceSpecificCustomizations(): List<LibRsCustomization> = when (moduleName) { "transcribestreaming" -> listOf(TranscribeTestDependencies()) "s3" -> listOf(S3TestDependencies()) "s3" -> listOf(S3TestDependencies(runtimeConfig)) else -> emptyList() } } Loading @@ -95,19 +95,29 @@ class TranscribeTestDependencies : LibRsCustomization() { } } class S3TestDependencies : LibRsCustomization() { class S3TestDependencies( private val runtimeConfig: RuntimeConfig ) : LibRsCustomization() { override fun section(section: LibRsSection): Writable = writable { addDependency(AsyncStd) addDependency(BytesUtils) addDependency(Smol) addDependency(TempFile) runtimeConfig.runtimeCrate("async", scope = DependencyScope.Dev) runtimeConfig.runtimeCrate("client", scope = DependencyScope.Dev) runtimeConfig.runtimeCrate("http", scope = DependencyScope.Dev) runtimeConfig.runtimeCrate("types", scope = DependencyScope.Dev) } } private val AsyncStd = CargoDependency("async-std", CratesIo("1.12"), scope = DependencyScope.Dev) private val AsyncStream = CargoDependency("async-stream", CratesIo("0.3"), DependencyScope.Dev) private val Criterion = CargoDependency("criterion", CratesIo("0.3"), scope = DependencyScope.Dev) private val FuturesCore = CargoDependency("futures-core", CratesIo("0.3"), DependencyScope.Dev) private val FuturesUtil = CargoDependency("futures-util", CratesIo("0.3"), scope = DependencyScope.Dev) private val Hound = CargoDependency("hound", CratesIo("3.4"), DependencyScope.Dev) private val SerdeJson = CargoDependency("serde_json", CratesIo("1"), features = emptySet(), scope = DependencyScope.Dev) private val Smol = CargoDependency("smol", CratesIo("1.2"), scope = DependencyScope.Dev) private val Tokio = CargoDependency("tokio", CratesIo("1"), features = setOf("macros", "test-util"), scope = DependencyScope.Dev) private val FuturesUtil = CargoDependency("futures-util", CratesIo("0.3"), scope = DependencyScope.Dev) private val Tracing = CargoDependency("tracing", CratesIo("0.1"), scope = DependencyScope.Dev) private val TracingSubscriber = CargoDependency("tracing-subscriber", CratesIo("0.2"), scope = DependencyScope.Dev) aws/sdk/integration-tests/s3/Cargo.toml +3 −0 Original line number Diff line number Diff line Loading @@ -8,8 +8,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dev-dependencies] async-std = "1.12" aws-config = { path = "../../build/aws-sdk/sdk/aws-config" } aws-http = { path = "../../build/aws-sdk/sdk/aws-http" } aws-types = { path = "../../build/aws-sdk/sdk/aws-types" } aws-sdk-s3 = { path = "../../build/aws-sdk/sdk/s3" } aws-sdk-sts = { path = "../../build/aws-sdk/sdk/sts" } aws-smithy-async = { path = "../../build/aws-sdk/sdk/aws-smithy-async", features = ["rt-tokio"] } Loading @@ -24,6 +26,7 @@ http-body = "0.4.5" hyper = "0.14" serde_json = "1" tempfile = "3" smol = "1.2" tokio = { version = "1", features = ["full", "test-util"] } tracing-subscriber = { version = "0.3.5", features = ["env-filter"] } tracing = "0.1" Loading aws/sdk/integration-tests/s3/tests/alternative-async-runtime.rs 0 → 100644 +159 −0 Original line number Diff line number Diff line /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ use aws_sdk_s3::model::{ CompressionType, CsvInput, CsvOutput, ExpressionType, FileHeaderInfo, InputSerialization, OutputSerialization, }; use aws_sdk_s3::{Client, Config, Credentials, Region}; use aws_smithy_async::assert_elapsed; use aws_smithy_async::rt::sleep::{AsyncSleep, Sleep}; use aws_smithy_client::never::NeverConnector; use aws_smithy_http::result::SdkError; use aws_smithy_types::timeout; use aws_smithy_types::tristate::TriState; use std::fmt::Debug; use std::sync::Arc; use std::time::Duration; #[derive(Debug)] struct SmolSleep; impl AsyncSleep for SmolSleep { fn sleep(&self, duration: Duration) -> Sleep { Sleep::new(async move { smol::Timer::after(duration).await; }) } } #[test] fn test_smol_runtime_timeouts() { if let Err(err) = smol::block_on(async { timeout_test(Arc::new(SmolSleep)).await }) { println!("{err}"); panic!(); } } #[test] fn test_smol_runtime_retry() { if let Err(err) = smol::block_on(async { retry_test(Arc::new(SmolSleep)).await }) { println!("{err}"); panic!(); } } #[derive(Debug)] struct AsyncStdSleep; impl AsyncSleep for AsyncStdSleep { fn sleep(&self, duration: Duration) -> Sleep { Sleep::new(async move { async_std::task::sleep(duration).await }) } } #[test] fn test_async_std_runtime_timeouts() { if let Err(err) = async_std::task::block_on(async { timeout_test(Arc::new(AsyncStdSleep)).await }) { println!("{err}"); panic!(); } } #[test] fn test_async_std_runtime_retry() { if let Err(err) = async_std::task::block_on(async { retry_test(Arc::new(AsyncStdSleep)).await }) { println!("{err}"); panic!(); } } async fn timeout_test(sleep_impl: Arc<dyn AsyncSleep>) -> Result<(), Box<dyn std::error::Error>> { let conn = NeverConnector::new(); let region = Region::from_static("us-east-2"); let credentials = Credentials::new("test", "test", None, None, "test"); let api_timeouts = timeout::Api::new().with_call_timeout(TriState::Set(Duration::from_secs_f32(0.5))); let timeout_config = timeout::Config::new().with_api_timeouts(api_timeouts); let config = Config::builder() .region(region) .credentials_provider(credentials) .timeout_config(timeout_config) .sleep_impl(sleep_impl) .build(); let client = Client::from_conf_conn(config, conn.clone()); let now = std::time::Instant::now(); let err = client .select_object_content() .bucket("aws-rust-sdk") .key("sample_data.csv") .expression_type(ExpressionType::Sql) .expression("SELECT * FROM s3object s WHERE s.\"Name\" = 'Jane'") .input_serialization( InputSerialization::builder() .csv( CsvInput::builder() .file_header_info(FileHeaderInfo::Use) .build(), ) .compression_type(CompressionType::None) .build(), ) .output_serialization( OutputSerialization::builder() .csv(CsvOutput::builder().build()) .build(), ) .send() .await .unwrap_err(); assert_eq!(format!("{:?}", err), "TimeoutError(RequestTimeoutError { kind: \"API call (all attempts including retries)\", duration: 500ms })"); assert_elapsed!(now, std::time::Duration::from_secs_f32(0.5)); Ok(()) } async fn retry_test(sleep_impl: Arc<dyn AsyncSleep>) -> Result<(), Box<dyn std::error::Error>> { let conn = NeverConnector::new(); let credentials = Credentials::new("test", "test", None, None, "test"); let conf = aws_types::SdkConfig::builder() .region(Region::new("us-east-2")) .credentials_provider(aws_types::credentials::SharedCredentialsProvider::new( credentials, )) .timeout_config( timeout::Config::new().with_api_timeouts( timeout::Api::new() .with_call_attempt_timeout(TriState::Set(Duration::from_secs_f64(0.1))), ), ) .sleep_impl(sleep_impl) .build(); let client = Client::from_conf_conn(Config::new(&conf), conn.clone()); let resp = client .list_buckets() .send() .await .expect_err("call should fail"); assert_eq!( conn.num_calls(), 3, "client level timeouts should be retried" ); assert!( matches!(resp, SdkError::TimeoutError { .. }), "expected a timeout error, got: {}", resp ); Ok(()) } aws/sdk/integration-tests/s3/tests/timeouts.rs +1 −2 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ use aws_smithy_types::tristate::TriState; use std::sync::Arc; use std::time::Duration; #[tokio::test] #[tokio::test(start_paused = true)] async fn test_timeout_service_ends_request_that_never_completes() { let conn: NeverService<http::Request<SdkBody>, http::Response<SdkBody>, ConnectorError> = NeverService::new(); Loading @@ -38,7 +38,6 @@ async fn test_timeout_service_ends_request_that_never_completes() { let client = Client::from_conf_conn(config, conn.clone()); let now = tokio::time::Instant::now(); tokio::time::pause(); let err = client .select_object_content() Loading codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/rustlang/CargoDependency.kt +1 −1 Original line number Diff line number Diff line Loading @@ -217,7 +217,7 @@ data class CargoDependency( fun SmithyHttp(runtimeConfig: RuntimeConfig) = runtimeConfig.runtimeCrate("http") fun SmithyHttpTower(runtimeConfig: RuntimeConfig) = runtimeConfig.runtimeCrate("http-tower") fun SmithyProtocolTestHelpers(runtimeConfig: RuntimeConfig) = runtimeConfig.runtimeCrate("protocol-test").copy(scope = DependencyScope.Dev) runtimeConfig.runtimeCrate("protocol-test", scope = DependencyScope.Dev) fun smithyJson(runtimeConfig: RuntimeConfig): CargoDependency = runtimeConfig.runtimeCrate("json") fun smithyQuery(runtimeConfig: RuntimeConfig): CargoDependency = runtimeConfig.runtimeCrate("query") fun smithyXml(runtimeConfig: RuntimeConfig): CargoDependency = runtimeConfig.runtimeCrate("xml") Loading Loading
aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/IntegrationTestDependencies.kt +13 −3 Original line number Diff line number Diff line Loading @@ -82,7 +82,7 @@ class IntegrationTestDependencies( private fun serviceSpecificCustomizations(): List<LibRsCustomization> = when (moduleName) { "transcribestreaming" -> listOf(TranscribeTestDependencies()) "s3" -> listOf(S3TestDependencies()) "s3" -> listOf(S3TestDependencies(runtimeConfig)) else -> emptyList() } } Loading @@ -95,19 +95,29 @@ class TranscribeTestDependencies : LibRsCustomization() { } } class S3TestDependencies : LibRsCustomization() { class S3TestDependencies( private val runtimeConfig: RuntimeConfig ) : LibRsCustomization() { override fun section(section: LibRsSection): Writable = writable { addDependency(AsyncStd) addDependency(BytesUtils) addDependency(Smol) addDependency(TempFile) runtimeConfig.runtimeCrate("async", scope = DependencyScope.Dev) runtimeConfig.runtimeCrate("client", scope = DependencyScope.Dev) runtimeConfig.runtimeCrate("http", scope = DependencyScope.Dev) runtimeConfig.runtimeCrate("types", scope = DependencyScope.Dev) } } private val AsyncStd = CargoDependency("async-std", CratesIo("1.12"), scope = DependencyScope.Dev) private val AsyncStream = CargoDependency("async-stream", CratesIo("0.3"), DependencyScope.Dev) private val Criterion = CargoDependency("criterion", CratesIo("0.3"), scope = DependencyScope.Dev) private val FuturesCore = CargoDependency("futures-core", CratesIo("0.3"), DependencyScope.Dev) private val FuturesUtil = CargoDependency("futures-util", CratesIo("0.3"), scope = DependencyScope.Dev) private val Hound = CargoDependency("hound", CratesIo("3.4"), DependencyScope.Dev) private val SerdeJson = CargoDependency("serde_json", CratesIo("1"), features = emptySet(), scope = DependencyScope.Dev) private val Smol = CargoDependency("smol", CratesIo("1.2"), scope = DependencyScope.Dev) private val Tokio = CargoDependency("tokio", CratesIo("1"), features = setOf("macros", "test-util"), scope = DependencyScope.Dev) private val FuturesUtil = CargoDependency("futures-util", CratesIo("0.3"), scope = DependencyScope.Dev) private val Tracing = CargoDependency("tracing", CratesIo("0.1"), scope = DependencyScope.Dev) private val TracingSubscriber = CargoDependency("tracing-subscriber", CratesIo("0.2"), scope = DependencyScope.Dev)
aws/sdk/integration-tests/s3/Cargo.toml +3 −0 Original line number Diff line number Diff line Loading @@ -8,8 +8,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dev-dependencies] async-std = "1.12" aws-config = { path = "../../build/aws-sdk/sdk/aws-config" } aws-http = { path = "../../build/aws-sdk/sdk/aws-http" } aws-types = { path = "../../build/aws-sdk/sdk/aws-types" } aws-sdk-s3 = { path = "../../build/aws-sdk/sdk/s3" } aws-sdk-sts = { path = "../../build/aws-sdk/sdk/sts" } aws-smithy-async = { path = "../../build/aws-sdk/sdk/aws-smithy-async", features = ["rt-tokio"] } Loading @@ -24,6 +26,7 @@ http-body = "0.4.5" hyper = "0.14" serde_json = "1" tempfile = "3" smol = "1.2" tokio = { version = "1", features = ["full", "test-util"] } tracing-subscriber = { version = "0.3.5", features = ["env-filter"] } tracing = "0.1" Loading
aws/sdk/integration-tests/s3/tests/alternative-async-runtime.rs 0 → 100644 +159 −0 Original line number Diff line number Diff line /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ use aws_sdk_s3::model::{ CompressionType, CsvInput, CsvOutput, ExpressionType, FileHeaderInfo, InputSerialization, OutputSerialization, }; use aws_sdk_s3::{Client, Config, Credentials, Region}; use aws_smithy_async::assert_elapsed; use aws_smithy_async::rt::sleep::{AsyncSleep, Sleep}; use aws_smithy_client::never::NeverConnector; use aws_smithy_http::result::SdkError; use aws_smithy_types::timeout; use aws_smithy_types::tristate::TriState; use std::fmt::Debug; use std::sync::Arc; use std::time::Duration; #[derive(Debug)] struct SmolSleep; impl AsyncSleep for SmolSleep { fn sleep(&self, duration: Duration) -> Sleep { Sleep::new(async move { smol::Timer::after(duration).await; }) } } #[test] fn test_smol_runtime_timeouts() { if let Err(err) = smol::block_on(async { timeout_test(Arc::new(SmolSleep)).await }) { println!("{err}"); panic!(); } } #[test] fn test_smol_runtime_retry() { if let Err(err) = smol::block_on(async { retry_test(Arc::new(SmolSleep)).await }) { println!("{err}"); panic!(); } } #[derive(Debug)] struct AsyncStdSleep; impl AsyncSleep for AsyncStdSleep { fn sleep(&self, duration: Duration) -> Sleep { Sleep::new(async move { async_std::task::sleep(duration).await }) } } #[test] fn test_async_std_runtime_timeouts() { if let Err(err) = async_std::task::block_on(async { timeout_test(Arc::new(AsyncStdSleep)).await }) { println!("{err}"); panic!(); } } #[test] fn test_async_std_runtime_retry() { if let Err(err) = async_std::task::block_on(async { retry_test(Arc::new(AsyncStdSleep)).await }) { println!("{err}"); panic!(); } } async fn timeout_test(sleep_impl: Arc<dyn AsyncSleep>) -> Result<(), Box<dyn std::error::Error>> { let conn = NeverConnector::new(); let region = Region::from_static("us-east-2"); let credentials = Credentials::new("test", "test", None, None, "test"); let api_timeouts = timeout::Api::new().with_call_timeout(TriState::Set(Duration::from_secs_f32(0.5))); let timeout_config = timeout::Config::new().with_api_timeouts(api_timeouts); let config = Config::builder() .region(region) .credentials_provider(credentials) .timeout_config(timeout_config) .sleep_impl(sleep_impl) .build(); let client = Client::from_conf_conn(config, conn.clone()); let now = std::time::Instant::now(); let err = client .select_object_content() .bucket("aws-rust-sdk") .key("sample_data.csv") .expression_type(ExpressionType::Sql) .expression("SELECT * FROM s3object s WHERE s.\"Name\" = 'Jane'") .input_serialization( InputSerialization::builder() .csv( CsvInput::builder() .file_header_info(FileHeaderInfo::Use) .build(), ) .compression_type(CompressionType::None) .build(), ) .output_serialization( OutputSerialization::builder() .csv(CsvOutput::builder().build()) .build(), ) .send() .await .unwrap_err(); assert_eq!(format!("{:?}", err), "TimeoutError(RequestTimeoutError { kind: \"API call (all attempts including retries)\", duration: 500ms })"); assert_elapsed!(now, std::time::Duration::from_secs_f32(0.5)); Ok(()) } async fn retry_test(sleep_impl: Arc<dyn AsyncSleep>) -> Result<(), Box<dyn std::error::Error>> { let conn = NeverConnector::new(); let credentials = Credentials::new("test", "test", None, None, "test"); let conf = aws_types::SdkConfig::builder() .region(Region::new("us-east-2")) .credentials_provider(aws_types::credentials::SharedCredentialsProvider::new( credentials, )) .timeout_config( timeout::Config::new().with_api_timeouts( timeout::Api::new() .with_call_attempt_timeout(TriState::Set(Duration::from_secs_f64(0.1))), ), ) .sleep_impl(sleep_impl) .build(); let client = Client::from_conf_conn(Config::new(&conf), conn.clone()); let resp = client .list_buckets() .send() .await .expect_err("call should fail"); assert_eq!( conn.num_calls(), 3, "client level timeouts should be retried" ); assert!( matches!(resp, SdkError::TimeoutError { .. }), "expected a timeout error, got: {}", resp ); Ok(()) }
aws/sdk/integration-tests/s3/tests/timeouts.rs +1 −2 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ use aws_smithy_types::tristate::TriState; use std::sync::Arc; use std::time::Duration; #[tokio::test] #[tokio::test(start_paused = true)] async fn test_timeout_service_ends_request_that_never_completes() { let conn: NeverService<http::Request<SdkBody>, http::Response<SdkBody>, ConnectorError> = NeverService::new(); Loading @@ -38,7 +38,6 @@ async fn test_timeout_service_ends_request_that_never_completes() { let client = Client::from_conf_conn(config, conn.clone()); let now = tokio::time::Instant::now(); tokio::time::pause(); let err = client .select_object_content() Loading
codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/rustlang/CargoDependency.kt +1 −1 Original line number Diff line number Diff line Loading @@ -217,7 +217,7 @@ data class CargoDependency( fun SmithyHttp(runtimeConfig: RuntimeConfig) = runtimeConfig.runtimeCrate("http") fun SmithyHttpTower(runtimeConfig: RuntimeConfig) = runtimeConfig.runtimeCrate("http-tower") fun SmithyProtocolTestHelpers(runtimeConfig: RuntimeConfig) = runtimeConfig.runtimeCrate("protocol-test").copy(scope = DependencyScope.Dev) runtimeConfig.runtimeCrate("protocol-test", scope = DependencyScope.Dev) fun smithyJson(runtimeConfig: RuntimeConfig): CargoDependency = runtimeConfig.runtimeCrate("json") fun smithyQuery(runtimeConfig: RuntimeConfig): CargoDependency = runtimeConfig.runtimeCrate("query") fun smithyXml(runtimeConfig: RuntimeConfig): CargoDependency = runtimeConfig.runtimeCrate("xml") Loading