AWS Step Function Localでステートマシンを分離環境でテストする(Mock Responseを使わない場合)

2022.07.25

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 IoT事業部の若槻です。

AWS Step Functions Localを使用すれば、Dockerコンテナを使用してLocal環境でState Machineのテストを行うことができます。

これにより、AWS Serviceと連携しているState Machineの場合にも、Taskに対するMock Responseを設定し分離環境で実行のテストが可能です。しかしMock Responseを使う場合にはConfigの用意がいささか煩雑になります。

そこで今回は、まずAWS Step Functions Localの基礎的な動作を確認するために、Mock Responseを使わない場合の実行テストをしてみました。

やってみた

準備

テスト対象のState MachineのASL(Amazon States Language)定義のファイルです。コンテナ上にState Machineを作成する際に読み込ませます。

MyStateMachine.asl.json

{
  "Comment": "A description of my state machine",
  "StartAt": "Choice",
  "States": {
    "Choice": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.input.val",
          "NumericGreaterThan": 3,
          "Next": "GreaterThanPath"
        }
      ],
      "Default": "NotGreaterThanPath"
    },
    "GreaterThanPath": {
      "Type": "Pass",
      "End": true
    },
    "NotGreaterThanPath": {
      "Type": "Pass",
      "End": true
    }
  }
}

Inputの値が3より大きければGreaterThanPath3以下であればNotGreaterThanPathに進むChoice Stateがあります。

AWS Step Function LocalのDockerイメージamazon/aws-stepfunctions-localをPullします。

docker pull amazon/aws-stepfunctions-local

Pullしたイメージからコンテナを実行します。

docker run -p 8083:8083 amazon/aws-stepfunctions-local

create-state-machineコマンドを実行してコンテナ上にState Machineを作成します。

stateMachineName=MyStateMachine
aws stepfunctions create-state-machine \
  --endpoint-url http://localhost:8083 \
  --definition file://$(pwd)/MyStateMachine.asl.json \
  --name $stateMachineName \
  --role-arn "arn:aws:iam::123456789012:role/DummyRole"

テスト実行

成功パターン1

まず、次のInputによりState Machineを実行して、GreaterThanPathを通って実行成功することを確認します。

events/valid_input_1.json

{
  "input": {
    "val": 4
  }
}

start-executionコマンドでStateMachineを実行します。

executionName=$(date +"%s")
inputFile=valid_input_1.json
aws stepfunctions start-execution \
  --endpoint http://localhost:8083 \
  --name $executionName \
  --state-machine arn:aws:states:us-east-1:123456789012:stateMachine:${stateMachineName} \
  --input file://$(pwd)/events/${inputFile}

get-execution-historyコマンドで実行履歴を取得します。

$ aws stepfunctions get-execution-history \
  --endpoint http://localhost:8083 \
  --execution-arn arn:aws:states:us-east-1:123456789012:execution:${stateMachineName}:${executionName}
{
    "events": [
        {
            "timestamp": "2022-07-26T04:52:49.505000+09:00",
            "type": "ExecutionStarted",
            "id": 1,
            "previousEventId": 0,
            "executionStartedEventDetails": {
                "input": "{\n  \"input\": {\n    \"val\": 4\n  }\n}\n",
                "inputDetails": {
                    "truncated": false
                },
                "roleArn": "arn:aws:iam::123456789012:role/DummyRole"
            }
        },
        {
            "timestamp": "2022-07-26T04:52:49.506000+09:00",
            "type": "ChoiceStateEntered",
            "id": 2,
            "previousEventId": 0,
            "stateEnteredEventDetails": {
                "name": "Choice",
                "input": "{\n  \"input\": {\n    \"val\": 4\n  }\n}\n",
                "inputDetails": {
                    "truncated": false
                }
            }
        },
        {
            "timestamp": "2022-07-26T04:52:49.508000+09:00",
            "type": "ChoiceStateExited",
            "id": 3,
            "previousEventId": 2,
            "stateExitedEventDetails": {
                "name": "Choice",
                "output": "{\n  \"input\": {\n    \"val\": 4\n  }\n}\n",
                "outputDetails": {
                    "truncated": false
                }
            }
        },
        {
            "timestamp": "2022-07-26T04:52:49.508000+09:00",
            "type": "PassStateEntered",
            "id": 4,
            "previousEventId": 3,
            "stateEnteredEventDetails": {
                "name": "GreaterThanPath",
                "input": "{\n  \"input\": {\n    \"val\": 4\n  }\n}\n",
                "inputDetails": {
                    "truncated": false
                }
            }
        },
        {
            "timestamp": "2022-07-26T04:52:49.509000+09:00",
            "type": "PassStateExited",
            "id": 5,
            "previousEventId": 4,
            "stateExitedEventDetails": {
                "name": "GreaterThanPath",
                "output": "{\n  \"input\": {\n    \"val\": 4\n  }\n}\n",
                "outputDetails": {
                    "truncated": false
                }
            }
        },
        {
            "timestamp": "2022-07-26T04:52:49.509000+09:00",
            "type": "ExecutionSucceeded",
            "id": 6,
            "previousEventId": 5,
            "executionSucceededEventDetails": {
                "output": "{\n  \"input\": {\n    \"val\": 4\n  }\n}\n",
                "outputDetails": {
                    "truncated": false
                }
            }
        }
    ]
}

上記取得結果により、State Machine実行がGreaterThanPathを通り成功(ExecutionSucceeded)していることが確認できました。

成功パターン2

続いて、次のInputによりState Machineを実行して、NotGreaterThanPathを通って実行成功することを確認します。

events/valid_input_2.json

{
  "input": {
    "val": 3
  }
}

start-executionコマンドでStateMachineを実行します。

executionName=$(date +"%s")
inputFile=valid_input_2.json
aws stepfunctions start-execution \
  --endpoint http://localhost:8083 \
  --name $executionName \
  --state-machine arn:aws:states:us-east-1:123456789012:stateMachine:${stateMachineName} \
  --input file://$(pwd)/events/${inputFile}

get-execution-historyコマンドで実行履歴を取得します。取得結果をqueryパラメータで必要分に絞り込みます。

$ aws stepfunctions get-execution-history \
  --endpoint http://localhost:8083 \
  --execution-arn arn:aws:states:us-east-1:123456789012:execution:${stateMachineName}:${executionName} \
  --query 'events[?(type==`ExecutionSucceeded`) || (type==`PassStateExited` && stateExitedEventDetails.name==`NotGreaterThanPath`)]'
[
    {
        "timestamp": "2022-07-26T05:05:25.603000+09:00",
        "type": "PassStateExited",
        "id": 5,
        "previousEventId": 4,
        "stateExitedEventDetails": {
            "name": "NotGreaterThanPath",
            "output": "{\n  \"input\": {\n    \"val\": 3\n  }\n}\n",
            "outputDetails": {
                "truncated": false
            }
        }
    },
    {
        "timestamp": "2022-07-26T05:05:25.606000+09:00",
        "type": "ExecutionSucceeded",
        "id": 6,
        "previousEventId": 5,
        "executionSucceededEventDetails": {
            "output": "{\n  \"input\": {\n    \"val\": 3\n  }\n}\n",
            "outputDetails": {
                "truncated": false
            }
        }
    }
]

上記取得結果により、State Machine実行がNotGreaterThanPathを通り成功(ExecutionSucceeded)していることが確認できました。

失敗パターン

最後に、次のInputによりState Machineが実行失敗することを確認します。

events/invalid_input.json

{
  "input": {
    "hoge": "fuga"
  }
}

start-executionコマンドでStateMachineを実行します。

executionName=$(date +"%s")
inputFile=invalid_input.json
aws stepfunctions start-execution \
  --endpoint http://localhost:8083 \
  --name $executionName \
  --state-machine arn:aws:states:us-east-1:123456789012:stateMachine:${stateMachineName} \
  --input file://$(pwd)/events/${inputFile}

get-execution-historyコマンドで実行履歴を取得します。

aws stepfunctions get-execution-history \
  --endpoint http://localhost:8083 \
  --execution-arn arn:aws:states:us-east-1:123456789012:execution:${stateMachineName}:${executionName}
{
    "events": [
        {
            "timestamp": "2022-07-26T05:18:00.551000+09:00",
            "type": "ExecutionStarted",
            "id": 1,
            "previousEventId": 0,
            "executionStartedEventDetails": {
                "input": "{\n  \"input\": {\n    \"hoge\": \"fuga\"\n  }\n}\n",
                "inputDetails": {
                    "truncated": false
                },
                "roleArn": "arn:aws:iam::123456789012:role/DummyRole"
            }
        },
        {
            "timestamp": "2022-07-26T05:18:00.551000+09:00",
            "type": "ChoiceStateEntered",
            "id": 2,
            "previousEventId": 0,
            "stateEnteredEventDetails": {
                "name": "Choice",
                "input": "{\n  \"input\": {\n    \"hoge\": \"fuga\"\n  }\n}\n",
                "inputDetails": {
                    "truncated": false
                }
            }
        },
        {
            "timestamp": "2022-07-26T05:18:00.555000+09:00",
            "type": "ExecutionFailed",
            "id": 3,
            "previousEventId": 2,
            "executionFailedEventDetails": {
                "error": "States.Runtime",
                "cause": "An error occurred while executing the state 'Choice' (entered at the event id #2). Invalid path '$.input.val': Th
e choice state's condition path references an invalid value."
            }
        }
    ]
}

上記取得結果により、State Machine実行がChoice Stateでエラーとなり失敗することが確認できました。

おわりに

AWS Step Functions LocalでMock Responseを使わない場合の実行テストをしてみました。

ドキュメントにはMock Responseを使った利用例のみ紹介されており使い方を読解するのが少々大変だったので、これでAWS Step Functions Localの基礎を整理することができました。次回はMock Responseを使ってみようと思います。

以上