LocalStackContainer 集成测试 lambda
LocalStackContainer integration testing a lambda
有没有一种方法可以(集成)使用测试容器和以下 LocalStackContainer 为 AWS 测试 Lambda:
new LocalStackContainer(DockerImageName.parse('localstack/localstack:0.11.6'))
.withServices(LocalStackContainer.Service.LAMBDA)
具体来说,我如何将 Lambda“上传”到本地 运行 服务,以便我可以触发和测试它?
启动 LocalStackContainer
后,您可以在容器内执行命令来设置您的基础设施。 LocalStack 提供 awslocal
二进制文件来创建任何 AWS 资源。
在您的测试中,您可以有一个 @BeforeAll
步骤,您可以在其中使用容器引用并创建所有内容。
以下示例针对 S3 和 SQS 执行此操作(参考此 blog post):
@Testcontainers
@SpringBootTest
public class YourLocalStackIT {
@Container
static LocalStackContainer localStack = new LocalStackContainer("0.11.6")
.withServices(S3, SQS)
.withEnv("DEFAULT_REGION", "eu-central-1");
@BeforeAll
static void beforeAll() throws IOException, InterruptedException {
localStack.execInContainer("awslocal", "sqs", "create-queue", "--queue-name", QUEUE_NAME);
localStack.execInContainer("awslocal", "s3", "mb", "s3://" + BUCKET_NAME);
}
private static final String QUEUE_NAME = "order-event-test-queue";
private static final String BUCKET_NAME = "order-event-test-bucket";
// ... actual test
}
您现在可以使用它作为模板来准备您的 AWS Lambda 函数。
关于源代码上传,我想将您的 Lambda 的 .zip
版本也挂载或复制到您的容器然后在内部访问它是有意义的。
可以像下面这样创建一个 NodeJS lambda:
awslocal lambda create-function \
--region eu-central1 \
--function-name your-api \
--runtime nodejs8.10 \
--handler lambda.apiHandler \
--memory-size 128 \
--zip-file fileb://api-handler.zip
我已经成功设置了 Localstack 和 MySql 测试容器(在 groovy spock 中),如下所示:
@Shared
public static Network network = Network.newNetwork()
@Shared
@ClassRule
public static MySQLContainer mySql = new MySQLContainer(DockerImageName.parse('mysql:5.7'))
.withNetwork(network)
.withNetworkAliases(MY_SQL_HOST_NAME) as MySQLContainer
@Shared
@ClassRule
public static LocalStackContainer localStack = new LocalStackContainer(DockerImageName.parse('localstack/localstack:0.11.6'))
.withServices(SQS, LAMBDA, CLOUDWATCH, DYNAMODB, KMS, STS, IAM)
.withNetwork(network)
.withEnv('LAMBDA_DOCKER_NETWORK', network.name)
.withCopyFileToContainer(MountableFile.forHostPath(new File('the jar file').path), '/opt/code/localstack/lambda.jar')
.withCopyFileToContainer(MountableFile.forClasspathResource('seed.yaml'), '/init/seed.yaml')
- 这样就建立了一个桥接网络,这样两个容器就可以
相互沟通。还设置 LAMBDA_DOCKER_NETWORK 允许 lambda 与 MySql、SQS 等通信
- lambda jar文件复制到容器中(withCopyFileToContainer)
- 我还需要 KMS,所以 seed.yaml 对其进行了初始化(请参阅本地 KMS 文档)
容器启动后 运行 可以使用 awslocal 和标准 CLI 命令部署 lambda:
def result = localStack.execInContainer(
'awslocal', 'lambda', 'create-function',
'--function-name', 'lambda-name',
'--runtime', 'java8',
'--handler', 'uk.co.blah.blah.Handler',
'--role', 'arn:aws:iam::123456:role/irrelevant',
'--zip-file', 'fileb://lambda.jar',
'--environment', "Variables={MY_SQL_USERNAME=${mySql.username},MY_SQL_PASSWORD=${encryptedDbPassword},PLATFORM_DB_URL=${"jdbc:mysql://${MY_SQL_HOST_NAME}:3306"}," +
"AWS_REGION=${localStack.region}}"
)
最后,可以像这样在测试中手动触发 lambda:
localStack.execInContainer('awslocal', 'lambda', 'invoke', '--function-name', 'lambda-name', 'output0.json')
有没有一种方法可以(集成)使用测试容器和以下 LocalStackContainer 为 AWS 测试 Lambda:
new LocalStackContainer(DockerImageName.parse('localstack/localstack:0.11.6'))
.withServices(LocalStackContainer.Service.LAMBDA)
具体来说,我如何将 Lambda“上传”到本地 运行 服务,以便我可以触发和测试它?
启动 LocalStackContainer
后,您可以在容器内执行命令来设置您的基础设施。 LocalStack 提供 awslocal
二进制文件来创建任何 AWS 资源。
在您的测试中,您可以有一个 @BeforeAll
步骤,您可以在其中使用容器引用并创建所有内容。
以下示例针对 S3 和 SQS 执行此操作(参考此 blog post):
@Testcontainers
@SpringBootTest
public class YourLocalStackIT {
@Container
static LocalStackContainer localStack = new LocalStackContainer("0.11.6")
.withServices(S3, SQS)
.withEnv("DEFAULT_REGION", "eu-central-1");
@BeforeAll
static void beforeAll() throws IOException, InterruptedException {
localStack.execInContainer("awslocal", "sqs", "create-queue", "--queue-name", QUEUE_NAME);
localStack.execInContainer("awslocal", "s3", "mb", "s3://" + BUCKET_NAME);
}
private static final String QUEUE_NAME = "order-event-test-queue";
private static final String BUCKET_NAME = "order-event-test-bucket";
// ... actual test
}
您现在可以使用它作为模板来准备您的 AWS Lambda 函数。
关于源代码上传,我想将您的 Lambda 的 .zip
版本也挂载或复制到您的容器然后在内部访问它是有意义的。
可以像下面这样创建一个 NodeJS lambda:
awslocal lambda create-function \
--region eu-central1 \
--function-name your-api \
--runtime nodejs8.10 \
--handler lambda.apiHandler \
--memory-size 128 \
--zip-file fileb://api-handler.zip
我已经成功设置了 Localstack 和 MySql 测试容器(在 groovy spock 中),如下所示:
@Shared
public static Network network = Network.newNetwork()
@Shared
@ClassRule
public static MySQLContainer mySql = new MySQLContainer(DockerImageName.parse('mysql:5.7'))
.withNetwork(network)
.withNetworkAliases(MY_SQL_HOST_NAME) as MySQLContainer
@Shared
@ClassRule
public static LocalStackContainer localStack = new LocalStackContainer(DockerImageName.parse('localstack/localstack:0.11.6'))
.withServices(SQS, LAMBDA, CLOUDWATCH, DYNAMODB, KMS, STS, IAM)
.withNetwork(network)
.withEnv('LAMBDA_DOCKER_NETWORK', network.name)
.withCopyFileToContainer(MountableFile.forHostPath(new File('the jar file').path), '/opt/code/localstack/lambda.jar')
.withCopyFileToContainer(MountableFile.forClasspathResource('seed.yaml'), '/init/seed.yaml')
- 这样就建立了一个桥接网络,这样两个容器就可以 相互沟通。还设置 LAMBDA_DOCKER_NETWORK 允许 lambda 与 MySql、SQS 等通信
- lambda jar文件复制到容器中(withCopyFileToContainer)
- 我还需要 KMS,所以 seed.yaml 对其进行了初始化(请参阅本地 KMS 文档)
容器启动后 运行 可以使用 awslocal 和标准 CLI 命令部署 lambda:
def result = localStack.execInContainer(
'awslocal', 'lambda', 'create-function',
'--function-name', 'lambda-name',
'--runtime', 'java8',
'--handler', 'uk.co.blah.blah.Handler',
'--role', 'arn:aws:iam::123456:role/irrelevant',
'--zip-file', 'fileb://lambda.jar',
'--environment', "Variables={MY_SQL_USERNAME=${mySql.username},MY_SQL_PASSWORD=${encryptedDbPassword},PLATFORM_DB_URL=${"jdbc:mysql://${MY_SQL_HOST_NAME}:3306"}," +
"AWS_REGION=${localStack.region}}"
)
最后,可以像这样在测试中手动触发 lambda:
localStack.execInContainer('awslocal', 'lambda', 'invoke', '--function-name', 'lambda-name', 'output0.json')