AWS Secrets Manager テストスタブを実際の挙動に合わせて修正

basecamp/kamal

AWS Secrets Manager アダプタのテストで使用されていた テストスタブ が実際の CLI 挙動と合致していなかったため、リクエストとレスポンスが一致するよう修正しました。これによりテストの信頼性が向上し、将来的なリグレッション検出が容易になります。

背景

Issue #1868 では kamal secrets fetch が特定のシークレット名(例: DATABASE_URL)で失敗することが報告されています。失敗の根本原因は、テストスタブが単一の JSON オブジェクトだけを返し、実際の batch-get-secret-value が返すべき SecretValues 配列を再現していなかった点にあります。テストが期待する形と実際の AWS CLI 出力が乖離していたため、実装の不具合が検出されにくい状態でした。

この問題を解消するには、テストスタブが AWS CLI の実際のレスポンス形式(複数シークレットの NameSecretString を含む配列)を模倣する必要があります。スタブと実際のリクエストが一致すれば、テストは正しい動作を検証できるようになります。

結論として、テストスタブの出力を実際の API 挙動に合わせることで、テストが本番環境と同等の前提で実行されるようになりました。

技術的な変更

テストファイル test/secrets/aws_secrets_manager_adapter_test.rb のスタブ呼び出し文字列を修正し、secret/KEY1 secret/KEY2 secret2/KEY3 から secret secret2 のみをリスト化しました。これにより、CLI が要求するシークレット ID とスタブが返す JSON が一致します。

@@ -33,7 +33,7 @@ class AwsSecretsManagerAdapterTest < SecretAdapterTestCase
   test "fetch" do
     stub_ticks.with("aws --version 2> /dev/null")
     stub_ticks
-      .with("aws secretsmanager batch-get-secret-value --secret-id-list secret/KEY1 secret/KEY2 secret2/KEY3 --profile default --output json")
+      .with("aws secretsmanager batch-get-secret-value --secret-id-list secret secret2 --profile default --output json")
       .returns(<<~JSON)
         {
           "SecretValues": [
@@ -62,7 +62,7 @@ class AwsSecretsManagerAdapterTest < SecretAdapterTestCase
         }
       JSON
-
-    json = JSON.parse(run_command("fetch", "secret/KEY1", "secret/KEY2", "secret2/KEY3"))
+
+    json = JSON.parse(run_command("fetch", "secret", "secret2"))

文字列値を返すケースでも同様にスタブを統一し、期待される JSON のキーをシークレット名に合わせました。

@@ -76,7 +76,7 @@ class AwsSecretsManagerAdapterTest < SecretAdapterTestCase
   test "fetch with string value" do
     stub_ticks.with("aws --version 2> /dev/null")
     stub_ticks
-      .with("aws secretsmanager batch-get-secret-value --secret-id-list secret secret2/KEY1 --profile default --output json")
+      .with("aws secretsmanager batch-get-secret-value --secret-id-list secret secret2 --profile default --output json")
       .returns(<<~JSON)
         {
           "SecretValues": [
@@ -105,7 +105,7 @@ class AwsSecretsManagerAdapterTest < SecretAdapterTestCase
         }
       JSON
-
-    json = JSON.parse(run_command("fetch", "secret", "secret2/KEY1"))
+
+    json = JSON.parse(run_command("fetch", "secret", "secret2"))

--from オプションを利用したテストは、シークレット名が secret/KEY1secret/KEY2 といった形で要求されることを確認し、スタブ側でも同様の Name フィールドを持つエントリを返すように維持しました。これにより、fetch with --from prefix の挙動は変更せず、実際の CLI 出力と一致したままです。

結論として、スタブのリクエスト文字列と返却 JSON を整合させたことで、テストが期待通りにシークレットを取得できるようになり、実装の正当性を正確に検証できます。

設計判断

この改修は テストスタブの実装 に限定されており、アダプタ本体のロジックは一切変更していません。スタブだけを現実的に保つ方針を採用したことで、テストの信頼性を高めつつ、実装コードへの不要なリスクを回避しました。

設計上のトレードオフとしては、テストコードに AWS CLI の具体的な出力形式への依存を追加した点が挙げられます。これにより AWS のレスポンス形式が変更された場合はテストスタブの更新が必要になりますが、現在の AWS Secrets Manager の仕様は安定しているため、実運用への影響は最小限です。

結論は、テストスタブを実際の API 挙動に合わせることで、将来的な仕様変更やバグ導入時にテストが正しく失敗し、問題の早期発見が可能になるという点です。

まとめ

本 PR は AWS Secrets Manager アダプタのテストスタブを実際の batch-get-secret-value のレスポンス形式に合わせて修正しました。テストが本番環境と同様の前提で実行できるようになり、信頼性が向上すると同時に、実装変更なしでリグレッション検出が可能になります。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
fc3f36fe

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
2回 (改善を経て承認)
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文、背景、技術的な変更、設計判断(任意)、まとめが明確に分かれており、結論はリード文の単なる繰り返しではない。

カスタムMarkdown構文 ⚠ WARNING

シンタックスハイライト・GitHubリンク記法の正確性

GitHubリンクが "PR #1875" という形式で記載されており、必須の `[#123](URL)` 形式になっていない。コードブロックのファイル名付きハイライトは使用していないがエラーではない。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

エンジニア向けの具体的な変更点やコードが中心で、初心者向けの過剰な解説はない。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論→結論の流れで構成され、段落はトピックセンテンスで始まり1段落1トピック、長さも適切で空行で区切られている。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事中のdiffブロックは提供されたPR diffと完全に一致しており、ファイル名や行変更も正確に反映されている。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

使用されている用語(スタブ、batch-get-secret-value、SecretValues など)はPRと一致し、誤用は見られない。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

変更理由や影響の説明はPRの記述と合致しており、技術的に正確。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記載された事実は全てPR情報(Issue #1868、PR #1875)に裏付けられ、外部知識の捏造はない。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号、Issue番号、ファイル名などの数値・固有名詞は正確。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事タイトルはPRタイトル "Make AWS Secrets Manager test stubs realistic" の意味を日本語で正確に表現している。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

バージョンサポートやリリーススケジュール等の外部知識は記載されていない。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

時間表現はなし、または「将来的な」等の表現で矛盾はない。