stepfunctions-local未能识别模拟定义文件。

huangapple go评论81阅读模式
英文:

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);

huangapple
  • 本文由 发表于 2023年7月14日 04:20:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76682989.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定