AWS Step Function Localでステートマシンを分離環境でテストする(Mock Responseを使う場合)
こんにちは、CX事業本部 IoT事業部の若槻です。
前回の下記エントリでは、AWS Step Function LocalをMock Responseを使わずに試してみました。
今回は、AWS Step Function LocalでMock Responseを使った場合のテストを試してみました。
やってみた
準備
テスト対象のState MachineのASL(Amazon States Language)定義のファイルです。コンテナ上にState Machineを作成する際に読み込ませます。
{ "Comment": "A description of my state machine", "StartAt": "GetParameter", "States": { "GetParameter": { "Type": "Task", "Next": "Choice", "Parameters": { "Name": "hoge" }, "Resource": "arn:aws:states:::aws-sdk:ssm:getParameter", "ResultSelector": { "hoge.$": "$.Parameter.Value" } }, "Choice": { "Type": "Choice", "Choices": [ { "Variable": "$.hoge", "StringMatches": "fuga", "Next": "FugaPath" } ], "Default": "NotFugaPath" }, "FugaPath": { "Type": "Pass", "End": true }, "NotFugaPath": { "Type": "Pass", "End": true } } }
AWS Systems Manager Parameter StoreからGet:Parameter
で値を取得し、値の文字列により分岐を行うChoice Stateがあります。
Mock ResponseのConfigです。これによりAWS ServiceからTaskへのレスポンスをMockすることができます。またレスポンスは複数のパターンを記述し、テスト実行時に使用することが可能です。
{ "StateMachines": { "MyStateMachine": { "TestCases": { "FugaPathTest": { "GetParameter": "GetParameterFugaMockedSuccess" }, "NotFugaPathTest": { "GetParameter": "GetParameterNotFugaMockedSuccess" } } } }, "MockedResponses": { "GetParameterFugaMockedSuccess": { "0": { "Return": { "Parameter": { "Arn": "arn:aws:ssm:ap-northeast-1:123456789012:parameter/hoge", "DataType": "text", "LastModifiedDate": "2022-07-26T05:38:43.052Z", "Name": "hoge", "Type": "String", "Value": "fuga", "Version": 4 } } } }, "GetParameterNotFugaMockedSuccess": { "0": { "Return": { "Parameter": { "Arn": "arn:aws:ssm:ap-northeast-1:123456789012:parameter/hoge", "DataType": "text", "LastModifiedDate": "2022-07-26T05:38:43.052Z", "Name": "hoge", "Type": "String", "Value": "nyao", "Version": 4 } } } } } }
AWS Step Function LocalのDockerイメージamazon/aws-stepfunctions-local
をPullします。
docker pull amazon/aws-stepfunctions-local
Pullしたイメージからコンテナを実行します。
docker run -p 8083:8083 \ --mount type=bind,readonly,source=$(pwd)/MockConfigFile.json,destination=/home/StepFunctionsLocal/MockConfigFile.json \ -e SFN_MOCK_CONFIG="/home/StepFunctionsLocal/MockConfigFile.json" \ 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(FugaPathTest)
start-execution
コマンドでStateMachineを実行します。この時State Machineの指定の末尾で、MockConfigFile.json
で定義したテストケースを#{TestCase}
のように指定します。まずはFugaPathTest
です。
executionName=$(date +"%s") aws stepfunctions start-execution \ --endpoint http://localhost:8083 \ --name $executionName \ --state-machine arn:aws:states:us-east-1:123456789012:stateMachine:${stateMachineName}#FugaPathTest
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-26T15:08:27.554000+09:00", "type": "ExecutionStarted", "id": 1, "previousEventId": 0, "executionStartedEventDetails": { "input": "{}", "inputDetails": { "truncated": false }, "roleArn": "arn:aws:iam::123456789012:role/DummyRole" } }, { "timestamp": "2022-07-26T15:08:27.555000+09:00", "type": "TaskStateEntered", "id": 2, "previousEventId": 0, "stateEnteredEventDetails": { "name": "GetParameter", "input": "{}", "inputDetails": { "truncated": false } } }, { "timestamp": "2022-07-26T15:08:27.561000+09:00", "type": "TaskScheduled", "id": 3, "previousEventId": 2, "taskScheduledEventDetails": { "resourceType": "aws-sdk", "resource": "ssm:getParameter", "region": "us-east-1", "parameters": "{\"Name\":\"hoge\"}" } }, { "timestamp": "2022-07-26T15:08:27.562000+09:00", "type": "TaskStarted", "id": 4, "previousEventId": 3, "taskStartedEventDetails": { "resourceType": "aws-sdk", "resource": "ssm:getParameter" } }, { "timestamp": "2022-07-26T15:08:27.626000+09:00", "type": "TaskSucceeded", "id": 5, "previousEventId": 4, "taskSucceededEventDetails": { "resourceType": "aws-sdk", "resource": "ssm:getParameter", "output": "{\"hoge\":\"fuga\"}", "outputDetails": { "truncated": false } } }, { "timestamp": "2022-07-26T15:08:27.627000+09:00", "type": "TaskStateExited", "id": 6, "previousEventId": 5, "stateExitedEventDetails": { "name": "GetParameter", "output": "{\"hoge\":\"fuga\"}", "outputDetails": { "truncated": false } } }, { "timestamp": "2022-07-26T15:08:27.629000+09:00", "type": "ChoiceStateEntered", "id": 7, "previousEventId": 6, "stateEnteredEventDetails": { "name": "Choice", "input": "{\"hoge\":\"fuga\"}", "inputDetails": { "truncated": false } } }, { "timestamp": "2022-07-26T15:08:27.635000+09:00", "type": "ChoiceStateExited", "id": 8, "previousEventId": 7, "stateExitedEventDetails": { "name": "Choice", "output": "{\"hoge\":\"fuga\"}", "outputDetails": { "truncated": false } } }, { "timestamp": "2022-07-26T15:08:27.635000+09:00", "type": "PassStateEntered", "id": 9, "previousEventId": 8, "stateEnteredEventDetails": { "name": "FugaPath", "input": "{\"hoge\":\"fuga\"}", "inputDetails": { "truncated": false } } }, { "timestamp": "2022-07-26T15:08:27.637000+09:00", "type": "PassStateExited", "id": 10, "previousEventId": 9, "stateExitedEventDetails": { "name": "FugaPath", "output": "{\"hoge\":\"fuga\"}", "outputDetails": { "truncated": false } } }, { "timestamp": "2022-07-26T15:08:27.639000+09:00", "type": "ExecutionSucceeded", "id": 11, "previousEventId": 10, "executionSucceededEventDetails": { "output": "{\"hoge\":\"fuga\"}", "outputDetails": { "truncated": false } } } ] }
State Machine実行がFugaPath
を通り成功したことが確認できました。
成功パターン2(NotFugaPathTest)
次にNotFugaPathTest
のパターンです。
executionName=$(date +"%s") aws stepfunctions start-execution \ --endpoint http://localhost:8083 \ --name $executionName \ --state-machine arn:aws:states:us-east-1:123456789012:stateMachine:${stateMachineName}#NotFugaPathTest
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-26T15:17:55.153000+09:00", "type": "ExecutionStarted", "id": 1, "previousEventId": 0, "executionStartedEventDetails": { "input": "{}", "inputDetails": { "truncated": false }, "roleArn": "arn:aws:iam::123456789012:role/DummyRole" } }, { "timestamp": "2022-07-26T15:17:55.153000+09:00", "type": "TaskStateEntered", "id": 2, "previousEventId": 0, "stateEnteredEventDetails": { "name": "GetParameter", "input": "{}", "inputDetails": { "truncated": false } } }, { "timestamp": "2022-07-26T15:17:55.154000+09:00", "type": "TaskScheduled", "id": 3, "previousEventId": 2, "taskScheduledEventDetails": { "resourceType": "aws-sdk", "resource": "ssm:getParameter", "region": "us-east-1", "parameters": "{\"Name\":\"hoge\"}" } }, { "timestamp": "2022-07-26T15:17:55.154000+09:00", "type": "TaskStarted", "id": 4, "previousEventId": 3, "taskStartedEventDetails": { "resourceType": "aws-sdk", "resource": "ssm:getParameter" } }, { "timestamp": "2022-07-26T15:17:55.156000+09:00", "type": "TaskSucceeded", "id": 5, "previousEventId": 4, "taskSucceededEventDetails": { "resourceType": "aws-sdk", "resource": "ssm:getParameter", "output": "{\"hoge\":\"nyao\"}", "outputDetails": { "truncated": false } } }, { "timestamp": "2022-07-26T15:17:55.156000+09:00", "type": "TaskStateExited", "id": 6, "previousEventId": 5, "stateExitedEventDetails": { "name": "GetParameter", "output": "{\"hoge\":\"nyao\"}", "outputDetails": { "truncated": false } } }, { "timestamp": "2022-07-26T15:17:55.156000+09:00", "type": "ChoiceStateEntered", "id": 7, "previousEventId": 6, "stateEnteredEventDetails": { "name": "Choice", "input": "{\"hoge\":\"nyao\"}", "inputDetails": { "truncated": false } } }, { "timestamp": "2022-07-26T15:17:55.157000+09:00", "type": "ChoiceStateExited", "id": 8, "previousEventId": 7, "stateExitedEventDetails": { "name": "Choice", "output": "{\"hoge\":\"nyao\"}", "outputDetails": { "truncated": false } } }, { "timestamp": "2022-07-26T15:17:55.158000+09:00", "type": "PassStateEntered", "id": 9, "previousEventId": 8, "stateEnteredEventDetails": { "name": "NotFugaPath", "input": "{\"hoge\":\"nyao\"}", "inputDetails": { "truncated": false } } }, { "timestamp": "2022-07-26T15:17:55.158000+09:00", "type": "PassStateExited", "id": 10, "previousEventId": 9, "stateExitedEventDetails": { "name": "NotFugaPath", "output": "{\"hoge\":\"nyao\"}", "outputDetails": { "truncated": false } } }, { "timestamp": "2022-07-26T15:17:55.158000+09:00", "type": "ExecutionSucceeded", "id": 11, "previousEventId": 10, "executionSucceededEventDetails": { "output": "{\"hoge\":\"nyao\"}", "outputDetails": { "truncated": false } } } ] }
State Machine実行がNotFugaPath
を通り成功したことが確認できました。
おわりに
AWS Step Function LocalでMock Responseを使った場合のテストを試してみました。
State Machineのテストをしたい場合、今までは実環境を使用する他なかったのですが、その際にAWS Serviceからテストケースで期待したレスポンスを行うようにするのがとても大変で、また限界がありました。AWS Step Function Localを使えば柔軟かつ簡単にテストケースを設定できそうです。
以上