Unverified Commit bab31ab3 authored by Zelda Hessler's avatar Zelda Hessler Committed by GitHub
Browse files

update S3 timeout integration tests (#3214)

This modernizes the timeouts tests a teeny bit and adds a
non-event-stream upload timeout test.

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent 84b8db34
Loading
Loading
Loading
Loading
+52 −24
Original line number Diff line number Diff line
@@ -3,19 +3,16 @@
 * SPDX-License-Identifier: Apache-2.0
 */

use aws_config::SdkConfig;
use aws_credential_types::provider::SharedCredentialsProvider;
use aws_sdk_s3::config::{Credentials, Region};
use aws_sdk_s3::config::{timeout::TimeoutConfig, Region};
use aws_sdk_s3::error::DisplayErrorContext;
use aws_sdk_s3::primitives::ByteStream;
use aws_sdk_s3::types::{
    CompressionType, CsvInput, CsvOutput, ExpressionType, FileHeaderInfo, InputSerialization,
    OutputSerialization,
};
use aws_sdk_s3::Client;
use aws_sdk_s3::{Client, Config};
use aws_smithy_async::assert_elapsed;
use aws_smithy_async::rt::sleep::{default_async_sleep, SharedAsyncSleep, TokioSleep};
use aws_smithy_runtime::client::http::test_util::NeverClient;
use aws_smithy_types::error::display::DisplayErrorContext;
use aws_smithy_types::timeout::TimeoutConfig;
use std::future::Future;
use std::net::SocketAddr;
use std::time::Duration;
@@ -23,19 +20,18 @@ use tokio::net::TcpListener;
use tokio::time::timeout;

#[tokio::test(start_paused = true)]
async fn test_timeout_service_ends_request_that_never_completes() {
    let sdk_config = SdkConfig::builder()
        .region(Region::from_static("us-east-2"))
        .credentials_provider(SharedCredentialsProvider::new(Credentials::for_tests()))
async fn test_event_stream_request_times_out_if_server_is_unresponsive() {
    let config = Config::builder()
        .with_test_defaults()
        .region(Region::new("us-east-2"))
        .http_client(NeverClient::new())
        .timeout_config(
            TimeoutConfig::builder()
                .operation_timeout(Duration::from_secs_f32(0.5))
                .operation_timeout(Duration::from_millis(500))
                .build(),
        )
        .sleep_impl(SharedAsyncSleep::new(TokioSleep::new()))
        .build();
    let client = Client::new(&sdk_config);
    let client = Client::from_conf(config);

    let now = tokio::time::Instant::now();

@@ -64,6 +60,40 @@ async fn test_timeout_service_ends_request_that_never_completes() {
        .await
        .unwrap_err();

    let expected = "operation timeout (all attempts including retries) occurred after 500ms";
    let message = format!("{}", DisplayErrorContext(err));
    assert!(
        message.contains(expected),
        "expected '{message}' to contain '{expected}'"
    );
    assert_elapsed!(now, Duration::from_millis(500));
}

#[tokio::test(start_paused = true)]
async fn test_upload_request_times_out_if_server_is_unresponsive() {
    let config = Config::builder()
        .with_test_defaults()
        .region(Region::new("us-east-2"))
        .http_client(NeverClient::new())
        .timeout_config(
            TimeoutConfig::builder()
                .operation_timeout(Duration::from_millis(500))
                .build(),
        )
        .build();
    let client = Client::from_conf(config);

    let now = tokio::time::Instant::now();

    let err = client
        .put_object()
        .bucket("aws-rust-sdk")
        .key("sample_data.csv")
        .body(ByteStream::from_static(b"Hello world!"))
        .send()
        .await
        .unwrap_err();

    let expected = "operation timeout (all attempts including retries) occurred after 500ms";
    let message = format!("{}", DisplayErrorContext(err));
    assert!(
@@ -99,18 +129,17 @@ async fn test_read_timeout() {
    let server_handle = tokio::spawn(server_fut);
    tokio::time::sleep(Duration::from_millis(100)).await;

    let config = SdkConfig::builder()
        .sleep_impl(default_async_sleep().unwrap())
    let config = Config::builder()
        .with_test_defaults()
        .region(Region::new("us-east-1"))
        .timeout_config(
            TimeoutConfig::builder()
                .read_timeout(Duration::from_millis(300))
                .build(),
        )
        .endpoint_url(format!("http://{server_addr}"))
        .region(Some(Region::from_static("us-east-1")))
        .credentials_provider(SharedCredentialsProvider::new(Credentials::for_tests()))
        .build();
    let client = Client::new(&config);
    let client = Client::from_conf(config);

    if let Ok(result) = timeout(
        Duration::from_millis(1000),
@@ -139,8 +168,9 @@ async fn test_read_timeout() {

#[tokio::test]
async fn test_connect_timeout() {
    let config = SdkConfig::builder()
        .sleep_impl(default_async_sleep().unwrap())
    let config = Config::builder()
        .with_test_defaults()
        .region(Region::new("us-east-1"))
        .timeout_config(
            TimeoutConfig::builder()
                .connect_timeout(Duration::from_millis(300))
@@ -150,10 +180,8 @@ async fn test_connect_timeout() {
            // Emulate a connect timeout error by hitting an unroutable IP
            "http://172.255.255.0:18104",
        )
        .region(Some(Region::from_static("us-east-1")))
        .credentials_provider(SharedCredentialsProvider::new(Credentials::for_tests()))
        .build();
    let client = Client::new(&config);
    let client = Client::from_conf(config);

    if let Ok(result) = timeout(
        Duration::from_millis(1000),