AWS SDK for Rust에서 정적 재생을 사용하여 HTTP 트래픽 시뮬레이션 - AWS SDK for Rust

AWS SDK for Rust에서 정적 재생을 사용하여 HTTP 트래픽 시뮬레이션

AWS SDK for Rust는 AWS 서비스와 상호 작용하는 코드를 테스트하기 위한 여러 접근 방식을 제공합니다. 이 주제에서는 StaticReplayClient를 사용하여 AWS 서비스에서 일반적으로 사용하는 표준 HTTP 클라이언트 대신 사용할 수 있는 가짜 HTTP 클라이언트를 생성하는 방법을 설명합니다. 이 클라이언트는 네트워크를 통해 서비스와 통신하는 대신 지정하는 HTTP 응답을 반환하므로 테스트가 테스트 목적으로 알려진 데이터를 가져옵니다.

aws-smithy-http-client 크레이트에는 StaticReplayClient라는 테스트 유틸리티 클래스가 포함되어 있습니다. AWS 서비스 객체를 생성할 때 기본 HTTP 클라이언트 대신 이 HTTP 클라이언트 클래스를 지정할 수 있습니다.

StaticReplayClient를 초기화할 때 HTTP 요청 및 응답 페어 목록을 ReplayEvent 객체로 제공합니다. 테스트가 실행되는 동안 각 HTTP 요청이 기록되고 클라이언트는 이벤트 목록의 다음 ReplayEvent에 있는 다음 HTTP 응답을 HTTP 클라이언트의 응답으로 반환합니다. 이렇게 하면 네트워크 연결 없이 알려진 데이터를 사용하여 테스트를 실행할 수 있습니다.

정적 재생 사용

정적 재생을 사용하려면 래퍼를 사용할 필요가 없습니다. 대신 테스트에서 사용할 데이터에 대해 실제 네트워크 트래픽이 어떤 형태여야 하는지 확인하고, SDK가 AWS 서비스 클라이언트로부터 요청을 보낼 때마다 사용할 수 있도록 해당 트래픽 데이터를 StaticReplayClient에 제공합니다.

참고

AWS CLI 및 많은 네트워크 트래픽 분석기와 패킷 스니퍼 도구 등 예상 네트워크 트래픽을 수집하는 방법에는 여러 가지가 있습니다.

  • 예상 HTTP 요청과 반환해야 하는 응답을 지정하는 ReplayEvent 객체 목록을 생성합니다.

  • 이전 단계에서 생성한 HTTP 트랜잭션 목록을 사용하여 StaticReplayClient를 생성합니다.

  • StaticReplayClientConfig 객체의 http_client로 지정하여 AWS 클라이언트에 대한 구성 객체를 생성합니다.

  • 이전 단계에서 생성한 구성을 사용하여 AWS 서비스 클라이언트 객체를 생성합니다.

  • StaticReplayClient를 사용하도록 구성된 서비스 객체를 사용하여 테스트하려는 작업을 수행합니다. SDK가 AWS에 API 요청을 보낼 때마다 목록의 다음 응답이 사용됩니다.

    참고

    전송된 요청이 ReplayEvent 객체 벡터의 응답과 일치하지 않더라도 목록의 다음 응답은 항상 반환됩니다.

  • 원하는 모든 요청이 이루어지면 StaticReplayClient.assert_requests_match() 함수를 직접 호출하여 SDK에서 보낸 요청이 ReplayEvent 객체 목록의 요청과 일치하는지 확인합니다.

예제

이전 예제의 동일한 determine_prefix_file_size() 함수에 대한 테스트를 살펴보겠습니다. 단, 모의 대신 정적 재생을 사용합니다.

  1. 프로젝트 디렉터리에 대한 명령 프롬프트에서 aws-smithy-http-client 크레이트를 종속성으로 추가합니다.

    $ cargo add --dev aws-smithy-http-client --features test-util

    --dev 옵션을 사용하면 Cargo.toml 파일의 [dev-dependencies] 섹션에 크레이트가 추가됩니다. 개발 종속성으로서 컴파일되지 않으며 프로덕션 코드에 사용되는 최종 바이너리에 포함되지 않습니다.

    이 예제 코드는 Amazon Simple Storage Service도 AWS 서비스 예제로 사용합니다.

    $ cargo add aws-sdk-s3

    이렇게 하면 [dependencies] 파일의 Cargo.toml 섹션에 크레이트가 추가됩니다.

  2. 테스트 코드 모듈에 필요한 두 가지 유형을 모두 포함합니다.

    use aws_smithy_http_client::test_util::{ReplayEvent, StaticReplayClient}; use aws_sdk_s3::primitives::SdkBody;
  3. 테스트 중에 발생해야 하는 각 HTTP 트랜잭션을 나타내는 ReplayEvent 구조를 생성하는 것으로 테스트가 시작됩니다. 각 이벤트에는 HTTP 요청 객체와 AWS 서비스가 일반적으로 응답하는 정보를 나타내는 HTTP 응답 객체가 포함되어 있습니다. 이러한 이벤트는 StaticReplayClient::new()에 대한 직접 호출로 전달됩니다.

    let page_1 = ReplayEvent::new( http::Request::builder() .method("GET") .uri("https://test-bucket.s3.us-east-1.amazonaws.com/?list-type=2&prefix=test-prefix") .body(SdkBody::empty()) .unwrap(), http::Response::builder() .status(200) .body(SdkBody::from(include_str!("./testing/response_multi_1.xml"))) .unwrap(), ); let page_2 = ReplayEvent::new( http::Request::builder() .method("GET") .uri("https://test-bucket.s3.us-east-1.amazonaws.com/?list-type=2&prefix=test-prefix&continuation-token=next") .body(SdkBody::empty()) .unwrap(), http::Response::builder() .status(200) .body(SdkBody::from(include_str!("./testing/response_multi_2.xml"))) .unwrap(), ); let replay_client = StaticReplayClient::new(vec![page_1, page_2]);

    결과는 replay_client에 저장됩니다. 이는 클라이언트의 구성에 지정하여 SDK for Rust에서 사용할 수 있는 HTTP 클라이언트를 나타냅니다.

  4. Amazon S3 클라이언트를 생성하려면 클라이언트 클래스의 from_conf() 함수를 직접 호출하여 구성 객체를 사용하여 클라이언트를 생성합니다.

    let client: s3::Client = s3::Client::from_conf( s3::Config::builder() .behavior_version(BehaviorVersion::latest()) .credentials_provider(make_s3_test_credentials()) .region(s3::config::Region::new("us-east-1")) .http_client(replay_client.clone()) .build(), );

    구성 객체는 빌더의 http_client() 메서드를 사용하여 지정되고 자격 증명은 credentials_provider() 메서드를 사용하여 지정됩니다. 자격 증명은 make_s3_test_credentials()라는 함수를 사용하여 생성되며, 이 함수는 가짜 자격 증명 구조를 반환합니다.

    fn make_s3_test_credentials() -> s3::config::Credentials { s3::config::Credentials::new( "ATESTCLIENT", "astestsecretkey", Some("atestsessiontoken".to_string()), None, "", ) }

    이러한 자격 증명은 실제로 AWS로 전송되지 않으므로 유효하지 않아도 됩니다.

  5. 테스트가 필요한 함수를 직접 호출하여 테스트를 실행합니다. 이 예제에서 해당 함수의 이름은 determine_prefix_file_size()입니다. 첫 번째 파라미터는 요청에 사용할 Amazon S3 클라이언트 객체입니다. 따라서 네트워크를 통해 나가지 않고 요청을 처리하도록 StaticReplayClient를 사용하여 생성된 클라이언트를 지정합니다.

    let size = determine_prefix_file_size(client, "test-bucket", "test-prefix") .await .unwrap(); assert_eq!(19, size); replay_client.assert_requests_match(&[]);

    determine_prefix_file_size()에 대한 직접 호출이 완료되면 어설트를 사용하여 반환된 값이 예상 값과 일치하는지 확인합니다. 그런 다음 StaticReplayClient 메서드 assert_requests_match() 함수를 직접 호출합니다. 이 함수는 기록된 HTTP 요청을 스캔하고 재생 클라이언트 생성 시 제공된 ReplayEvent 객체 배열에 지정된 요청과 모두 일치하는지 확인합니다.

GitHub에서 이러한 예제의 완성된 코드를 볼 수 있습니다.