1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS Step FunctionsのTestState APIを用いて、ローカル環境でStateをテスト

Posted at

はじめに

AWS Step Functionsにて、単独のStateを確認するTestState APIがアップデートされ、ローカルでテストできるようになりました。別サービスを呼び出す箇所をモックで代わりにできます。

今回はそれを軽く動かしてみました。

概要

  • TestState APIにて、ローカルで単独のStateのテストができます
    • --definitionでステートの定義を指定します
      • 直接JSON文字列を指定しても、file://【ファイル】でもOK
    • 他のAWSサービスを呼んでいる場合、--mockでダミー出力を指定できます

参考

やってみる

実行場所はAWS CLIがあればどこでもよいため、CloudShell上で行っています。

最もシンプルなState定義の場合

AWS Lambdaを呼び出すステートを試してみます。ステートの定義をファイルに保存します。

MyTask.json
{
  "Type": "Task",
  "Resource": "arn:aws:states:::lambda:invoke",
  "Parameters": {
    "FunctionName": "MyFunction",
    "Payload.$": "$"
  },
  "ResultPath": "$.lambdaResult", 
  "End": true
}

実行するコマンドは以下になります。--mockにLambdaからの戻り値を設定します。

aws stepfunctions test-state \
    --definition file://MyTask.json \
    --input '{"key": "value", "original": 1}' \
    --mock '{"result": "{\"statusCode\": 200, \"body\": \"Success\"}"}'

出力結果は以下になりました。

{
    "output": "{\"key\":\"value\",\"original\":1,\"lambdaResult\":{\"statusCode\":200,\"body\":\"Success\"}}",
    "status": "SUCCEEDED"
}

エラーキャッチする定義の場合

モックのLambdaから例外を返却する場合は以下のように指定します。

aws stepfunctions test-state \
    --definition file://MyTask.json \
    --input '{"key": "value", "original": 1}' \
    --mock '{"errorOutput": {"error": "Lambda.ServiceException", "cause": "Service unavailable"}}'

先ほどのState定義をそのまま実行すると、以下のような出力になります。

{
    "error": "Lambda.ServiceException",
    "cause": "Service unavailable",
    "status": "FAILED"
}

State定義に例外のCatchを追加してみます。

MyTask.json
{
  "Type": "Task",
  "Resource": "arn:aws:states:::lambda:invoke",
  "Parameters": {
    "FunctionName": "MyFunction",
    "Payload.$": "$"
  },
  "Catch": [
    {
      "ErrorEquals": [ "States.ALL" ],
      "Next": "ErrorHandlerState"
    }
  ],
  "ResultPath": "$.lambdaResult", 
  "End": true
}

再度、mockに例外を設定したコマンドを実行すると、以下のようにstatus": "CAUGHT_ERROR"と、例外を捕まえた旨が出力されます。

{
    "output": "{\"Error\":\"Lambda.ServiceException\",\"Cause\":\"Service unavailable\"}",
    "error": "Lambda.ServiceException",
    "cause": "Service unavailable",
    "nextState": "ErrorHandlerState",
    "status": "CAUGHT_ERROR"
}

リトライ定義の場合

今度はリトライを定義します。

MyTask.json
{
  "Type": "Task",
  "Resource": "arn:aws:states:::lambda:invoke",
  "Parameters": {
    "FunctionName": "MyFunction",
    "Payload.$": "$"
  },
  "Retry": [{
    "ErrorEquals": ["Lambda.ServiceException"],
      "IntervalSeconds": 2,
      "MaxAttempts": 3,
      "BackoffRate": 2.0
  }],
  "ResultPath": "$.lambdaResult", 
  "End": true
}

モックはエラーで実行します。詳細に情報が欲しいので--inspection-level DEBUGを指定して実行します。

aws stepfunctions test-state \
    --definition file://MyTask.json \
    --input '{"key": "value", "original": 1}' \
    --mock '{"errorOutput": {"error": "Lambda.ServiceException", "cause": "Service unavailable"}}' \
    --inspection-level DEBUG

結果は以下のように出力されました。

{
    "error": "Lambda.ServiceException",
    "cause": "Service unavailable",
    "inspectionData": {
        "input": "{\"key\": \"value\", \"original\": 1}",
        "afterInputPath": "{\"key\": \"value\", \"original\": 1}",
        "afterParameters": "{\"FunctionName\":\"MyFunction\",\"Payload\":{\"key\":\"value\",\"original\":1}}",
        "errorDetails": {
            "retryIndex": 0,
            "retryBackoffIntervalSeconds": 2
        }
    },
    "status": "RETRIABLE"
}

Map定義の場合

今度はMapのState定義にします。

MyTask.json
{
    "Type": "Map",
    "ItemsPath": "$.items",
    "ItemSelector": {
        "value.$": "$$.Map.Item.Value",
        "index.$": "$$.Map.Item.Index"
    },
    "ItemProcessor": {
        "ProcessorConfig": {
            "Mode": "INLINE"
        },
        "StartAt": "ProcessItem",
        "States": {
            "ProcessItem": {
                "Type": "Task",
                "Resource": "arn:aws:states:::lambda:invoke",
                "Parameters": {
                    "FunctionName": "MyMockedMapLambda",
                    "Payload.$": "$"
                },
                "End": true
            }
        }
    },
    "End": true
}

--mockの定義を配列にします。--inputも気分で配列にしています。

aws stepfunctions test-state \
    --definition file://MyTask.json \
    --input '{"items": [1, 2, 3, 4, 5]}' \
    --mock '{"result": "[10, 20, 30, 40, 50]"}' \
    --inspection-level DEBUG

コマンドの結果は以下のようになります。

{
    "output": "[10, 20, 30, 40, 50]",
    "inspectionData": {
        "input": "{\"items\": [1, 2, 3, 4, 5]}",
        "afterInputPath": "{\"items\": [1, 2, 3, 4, 5]}",
        "afterResultSelector": "[10, 20, 30, 40, 50]",
        "afterResultPath": "[10, 20, 30, 40, 50]",
        "afterItemsPath": "[1, 2, 3, 4, 5]",
        "afterItemSelector": "[{\"index\":0,\"value\":1}, {\"index\":1,\"value\":2}, {\"index\":2,\"value\":3}, {\"index\":3,\"value\":4}, {\"index\":4,\"value\":5}]",
        "maxConcurrency": 0
    },
    "status": "SUCCEEDED"
}

おわりに

今回はAWS Step FunctionsのTestState APIがローカルで実行できる機能を記事にしました。
この機能を使えばAWS Step Functionsで複雑な、戻り値からの抽出データのパス指定が簡単に試せそうです。
この記事がどなたかのお役に立ちましたら幸いです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?