

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# AWS SDK for Rust에서 정적 재생을 사용하여 HTTP 트래픽 시뮬레이션
<a name="testing-replay"></a>

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

`aws-smithy-http-client` 크레이트에는 [https://docs.rs/aws-smithy-http-client/latest/aws_smithy_http_client/test_util/struct.StaticReplayClient.html](https://docs.rs/aws-smithy-http-client/latest/aws_smithy_http_client/test_util/struct.StaticReplayClient.html)라는 테스트 유틸리티 클래스가 포함되어 있습니다. AWS 서비스 객체를 생성할 때 기본 HTTP 클라이언트 대신이 HTTP 클라이언트 클래스를 지정할 수 있습니다.

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

## 정적 재생 사용
<a name="testing-replay-steps"></a>

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

**참고**  
 AWS CLI 및 많은 네트워크 트래픽 분석기와 패킷 스니퍼 도구를 포함하여 예상 네트워크 트래픽을 수집하는 방법에는 여러 가지가 있습니다.
+ 예상 HTTP 요청과 반환해야 하는 응답을 지정하는 `ReplayEvent` 객체 목록을 생성합니다.
+ 이전 단계에서 생성한 HTTP 트랜잭션 목록을 사용하여 `StaticReplayClient`를 생성합니다.
+ 를 객체의 `StaticReplayClient`로 지정하여 AWS 클라이언트에 대한 구성 `Config` 객체를 생성합니다`http_client`.
+ 이전 단계에서 생성한 구성을 사용하여 AWS 서비스 클라이언트 객체를 생성합니다.
+ `StaticReplayClient`를 사용하도록 구성된 서비스 객체를 사용하여 테스트하려는 작업을 수행합니다. SDK가 API 요청을 보낼 때마다 목록의 AWS다음 응답이 사용됩니다.
**참고**  
전송된 요청이 `ReplayEvent` 객체 벡터의 응답과 일치하지 않더라도 목록의 다음 응답은 항상 반환됩니다.
+ 원하는 모든 요청이 이루어지면 `StaticReplayClient.assert_requests_match()` 함수를 직접 호출하여 SDK에서 보낸 요청이 `ReplayEvent` 객체 목록의 요청과 일치하는지 확인합니다.

## 예제
<a name="testing-replay-example"></a>

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

1. 프로젝트 디렉터리에 대한 명령 프롬프트에서 [https://crates.io/crates/aws-smithy-http-client](https://crates.io/crates/aws-smithy-http-client) 크레이트를 종속성으로 추가합니다.

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

   `--dev` [옵션](https://doc.rust-lang.org/cargo/commands/cargo-add.html)을 사용하면 `Cargo.toml` 파일의 `[dev-dependencies]` 섹션에 크레이트가 추가됩니다. [개발 종속성](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#development-dependencies)으로서 컴파일되지 않으며 프로덕션 코드에 사용되는 최종 바이너리에 포함되지 않습니다.

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

   ```
   $ cargo add aws-sdk-s3
   ```

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

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

   ```
   use aws_smithy_http_client::test_util::{ReplayEvent, StaticReplayClient};
   use aws_sdk_s3::primitives::SdkBody;
   ```

1. 테스트 중에 발생해야 하는 각 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 클라이언트를 나타냅니다.

1. 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로 전송되지 않으므로 유효하지 않아도 됩니다.

1. 테스트가 필요한 함수를 직접 호출하여 테스트를 실행합니다. 이 예제에서 해당 함수의 이름은 `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에서 [이러한 예제의 완성된 코드를 볼 수](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/rustv1/examples/testing) 있습니다.