英文:
stepfunctions-local not picking up mock definition file
问题
我正在使用 amazon/aws-stepfunctions-local 镜像在本地运行 AWS Step Functions。我遇到的问题是,当在 jest 测试中从 testcontainers 中加载时,以及从 Docker CLI 启动的正在运行的容器中运行测试时,都发生了相同的问题。
当我使用 MockConfigFile 创建并执行一个步骤函数时,它在调用具有类似以下错误的 Lambda 步骤时出错:"请求中包含的安全令牌无效。":
2023-07-13 20:09:27.708: arn:aws:states:us-east-1:123456789012:execution:createApp:5cc02245-ce24-4e28-a3de-25edd6a81ce7 : {"Type":"TaskFailed","PreviousEventId":4,"TaskFailedEventDetails":{"ResourceType":"lambda","Resource":"invoke","Error":"Lambda.AWSLambdaException","Cause":"The security token included in the request is invalid. (Service: AWSLambda; Status Code: 403; Error Code: UnrecognizedClientException; Request ID: 4cc1f11b-cc78-4092-8733-c77397823ee2; Proxy: null)}}
启动容器:
const mockFileContainerPath = '/home/stepfunctionslocal/MockConfigFile.json';
let container;
let host;
let port;
const exposedPort = 8083;
process.env.TESTCONTAINERS_RYUK_DISABLED = true;
jest.setTimeout(90000);
beforeAll(async () => {
container = await new GenericContainer('amazon/aws-stepfunctions-local')
.withExposedPorts(exposedPort)
.withLogConsumer(stream => {
stream.on("data", line => console.info(line));
stream.on("err", line => console.error(line));
stream.on("end", () => console.info("Stream closed"));
})
.withBindMounts([{
source: path.resolve('./step-function-tests/assets/MockConfigFile.json'),
target: mockFileContainerPath,
mode: "ro"
}])
.withEnvironment({
SFN_MOCK_CONFIG: mockFileContainerPath},
AWS_ACCESS_KEY_ID: "blahblah",
AWS_SECRET_ACCESS_KEY: "supersecret"
})
.withWaitStrategy(
Wait.forLogMessage(RegExp(`.*Starting server on port ${exposedPort}.*`))
).start();
host = container.getHost();
port = container.getMappedPort(exposedPort);
});
我可以连接到正在运行的容器并查看 MockConfigFile.json 是否存在于 /home/stepfunctionslocal/MockConfigFile.json。
看起来 step-functions-local 实际上正在尝试调用 Lambda,而不是使用配置文件中的模拟响应。我是否应该在日志中看到 step-functions-local 已加载模拟文件的任何指示?我的模拟文件如下所示:
{
"StateMachines": {
"createApp": {
"TestCases": {
"HappyPath": {
"Create application": "MockedCreateApplicationSuccess"
}
}
}
},
"MockedResponses": {
"MockedCreateApplicationSuccess": {
"0": {
"Return": {
"StatusCode": 200,
"Payload": {
"hello": "world"
}
}
}
}
}
}
其中 "Create application" 是调用 Lambda 函数的状态的名称。
英文:
I am using the amazon/aws-stepfunctions-local image to run AWS Step Functions locally. While the problem I'm having is happening when loading from testcontainers within a jest test, I am having the same problem when running a test against a running container starting from docker cli.
When I create and execute a step function using the MockConfigFile, it errors on a step where it calls a lambda with an error like "The security token included in the request is invalid.":
2023-07-13 20:09:27.708: arn:aws:states:us-east-1:123456789012:execution:createApp:5cc02245-ce24-4e28-a3de-25edd6a81ce7 : {"Type":"TaskFailed","PreviousEventId":4,"TaskFailedEventDetails":{"ResourceType":"lambda","Resource":"invoke","Error":"Lambda.AWSLambdaException","Cause":"The security token included in the request is invalid. (Service: AWSLambda; Status Code: 403; Error Code: UnrecognizedClientException; Request ID: 4cc1f11b-cc78-4092-8733-c77397823ee2; Proxy: null)"}}
Starting the container:
const mockFileContainerPath = '/home/stepfunctionslocal/MockConfigFile.json';
let container;
let host;
let port;
const exposedPort = 8083;
process.env.TESTCONTAINERS_RYUK_DISABLED = true;
jest.setTimeout(90000);
beforeAll(async () => {
container = await new GenericContainer('amazon/aws-stepfunctions-local')
.withExposedPorts(exposedPort)
.withLogConsumer(stream => {
stream.on("data", line => console.info(line));
stream.on("err", line => console.error(line));
stream.on("end", () => console.info("Stream closed"));
})
.withBindMounts([{
source: path.resolve('./step-function-tests/assets/MockConfigFile.json'),
target: mockFileContainerPath,
mode: "ro"
}])
.withEnvironment({
SFN_MOCK_CONFIG: mockFileContainerPath},
AWS_ACCESS_KEY_ID: "blahblah",
AWS_SECRET_ACCESS_KEY: "supersecret"
})
.withWaitStrategy(
Wait.forLogMessage(RegExp(`.*Starting server on port ${exposedPort}.*`))
).start();
host = container.getHost();
port = container.getMappedPort(exposedPort);`
});
I can attach to the running container and see that the MockConfigFile.json exists at /home/stepfunctionslocal/MockConfigFile.json.
It seems like step-functions-local is actually trying to invoke the lambda, as opposed to using the mock response from the config file. Should I expect to see any indication in the logs that step-functions-local has loaded the mock file? My mock file looks like:
{
"StateMachines": {
"createApp": {
"TestCases": {
"HappyPath": {
"Create application": "MockedCreateApplicationSuccess"
}
}
}
},
"MockedResponses": {
"MockedCreateApplicationSuccess": {
"0": {
"Return": {
"StatusCode": 200,
"Payload": {
"hello": "world"
}
}
}
}
}
}
Where "Create application" is the name of a state that invokes the lambda function.
答案1
得分: 0
1中明确说明,为了使模拟引擎返回响应,执行必须以将测试用例的名称附加到stateMachineArn的方式启动,我之前没有这样做。每次阅读它时都会忽略这部分内容,似乎是这样的。
const startCommandInput = {
stateMachineArn: `${stateMachineArn}#HappyPath`,
input: JSON.stringify({
hello: "world"
})
};
const startCommand = new StartExecutionCommand(startCommandInput);
const { executionArn } = await client.send(startCommand);
英文:
The documentation clearly states that in order for the mock engine to return a response, the execution has to be started with the name of the test case appended to the stateMachineArn, which I was not doing. Skimmed over that part every time I read it, it seems.
const startCommandInput = {
stateMachineArn: `${stateMachineArn}#HappyPath`,
input: JSON.stringify({
hello: "world"
})
};
const startCommand = new StartExecutionCommand(startCommandInput);
const { executionArn } = await client.send(startCommand);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论