AWS SDK for Rust での静的リプレイによる HTTP トラフィックのシミュレーション - AWS SDK for Rust

AWS SDK for Rust での静的リプレイによる HTTP トラフィックのシミュレーション

AWS SDK for Rust では、AWS のサービスとやり取りするコードをテストするために複数のアプローチを利用できます。このトピックでは、AWS のサービスを使用して、StaticReplayClient が通常使用する標準 HTTP クライアントの代わりに使用できる擬似 HTTP クライアントを作成する方法について説明します。このクライアントは、ネットワーク経由でサービスと通信する代わりに、指定した HTTP レスポンスを返します。これにより、テストはテスト目的で既知のデータを取得します。

aws-smithy-http-client クレートには、StaticReplayClient というテストユーティリティクラスが含まれています。この HTTP クライアントクラスは、AWS のサービス オブジェクトの作成時にデフォルトの HTTP クライアントの代わりに指定できます。

StaticReplayClient を初期化する場合は、HTTP リクエストとレスポンスのペアのリストを ReplayEvent オブジェクトとして指定します。テストの実行中に、各 HTTP リクエストが記録され、クライアントはイベントリストの次の ReplayEvent にある次の HTTP レスポンスを HTTP クライアントのレスポンスとして返します。これにより、既知のデータを使用することにより、ネットワークに接続せずにテストを実行できます。

静的リプレイの使用

静的リプレイを使用するには、ラッパーを使用する必要はありません。代わりに、テストで使用するデータに対し、実際のネットワークトラフィックがどのような状態かを判断し、SDK が AWS のサービス クライアントからリクエストを発行するたびに、そのトラフィックデータを StaticReplayClient に提供します。

注記

予想されるネットワークトラフィックを収集するには、AWS CLI や多数のネットワークトラフィックアナライザー、パケットスニッファツールなど、複数の方法があります。

  • 予想される HTTP リクエストと、それに対して返されるレスポンスを指定する ReplayEvent オブジェクトのリストを作成します。

  • 前のステップで作成した HTTP トランザクションリストを使用して StaticReplayClient を作成します。

  • AWS クライアントの設定オブジェクトを作成し、StaticReplayClientConfig オブジェクトの http_client として指定します。

  • 前のステップで作成した設定を使用して、AWS のサービス クライアントオブジェクトを作成します。

  • StaticReplayClient を使用するように設定されたサービスオブジェクトを使用して、テストするオペレーションを実行します。SDK が API リクエストを AWS に送信するたびに、リスト内の次のレスポンスが使用されます。

    注記

    送信されたリクエストが 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] セクションにクレートが追加されます。開発の依存関係として扱われるため、これはコンパイルされず、本番コードで使用される最終バイナリには含まれません。

    また、このサンプルコードは、AWS のサービス の例として Amazon Simple Storage Service を使用します。

    $ 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 に保存されます。これは HTTP クライアントを表しており、SDK for Rust ではクライアントの設定で指定することにより使用できます。

  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 で これらの例の完全なコードを表示できます。