在 CI(gitlab-ci kubernetes runner)中使用"sam local invoke"为 AWS Lambda w/ Layer 运行测试 (pytest)



我之所以尝试将sam本地调用作为CI管道的一部分来运行,是因为我想运行一些单元&对使用层的lambda进行集成测试。该层在中进行管理一个不同的项目,因此,它的代码和库在我的lambda函数项目中不直接可用。

在这篇文章的启发下,我得到了单元&集成测试使用sam本地调用在本地工作,该调用使用"samtemplate_tests.yaml",该调用调用app_tests.py来运行单元&在.tests/文件夹中定义的集成测试。

#samtemplate_tests.yaml
Resources:
MyFunctionTests:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: app_tests.lambda_handler
Layers: 
- arn:aws:lambda:us-east-1:<account#>:layer:MyLayer:1
#app_tests.py
import pytest
def lambda_handler(event, _):
res = pytest.main(["-x", "./tests"])
return res

这种解决方法在本地运行良好,我不介意在我的lambda项目中维护两个额外的文件(samtemplate_tests.yml、app_tests.py(来解决层依赖关系。

然而,让这个解决方案通过CI工作意味着我需要增强我的CI基础设施,以支持"docker in docker"。对于CI,我使用的是Gitlab CI w/kubernetes runner,它使用debian:buster构建映像,安装时需要预请求。我不太熟悉w/dind和其他高级docker功能,所以我想知道是否有人能为我探索的方法提供指导。

TL'DR:有没有一种方法可以将sam本地调用作为CI的一部分来运行?

更新:刚刚在aws-sam-cli上发现了这个开放功能请求,这肯定会有所帮助。

以下是我在lambda函数项目中的gitlab ci"测试"工作中实现的一个变通方法,用于通过ci:运行测试

  1. 下载layer.zip
  2. 解压缩到新目录
  3. 使用层需求.txt安装层依赖项
  4. 将层python代码文件复制到lambda函数目录
  5. 列出项目
  6. 运行测试
# !/usr/bin/env bash
# script/test: Run the test suite.
set -e
cd "$(dirname "$0")/.."
if [[ $CI ]] # ci-cd build
then
echo "==> Installing boto3 as it is required to run integration tests…"
poetry add boto3

echo "==> Downloading MyLayer zip…"
URL=$(aws lambda get-layer-version 
--layer-name arn:aws:lambda:us-east-1:<account#>:layer:MyLayer 
--version-number 6  #TODO: get version dynamically
--query Content.Location 
--output text)
curl $URL -o layer.zip

echo "==> Unzipping My Layer…"
unzip -qq -o layer.zip python/* -d Mylayer
echo "==> Installing python dependencies required for Mylayer…"
sed -i 's/;.*//' Mylayer/python/requirements.txt # Gets rid of string after ";" from the poetry generated requirements file.
poetry add `cat Mylayer/python/requirements.txt`
echo "==> Moving Mylayer python files to lambda src directory…"
find ./Mylayer/python/ -maxdepth 1 -type f -exec mv {} src/ ;
echo "==> Running tests…"
poetry run python -m pytest tests
else # local/dev build
echo "==> Building SAM artifacts for unit & integration tests lambda…"
sam build --config-env $1 --template-file samtemplate_tests.yaml
echo "==> Invoking lambda func to run unit & integration tests…"
sam local invoke MyLambdaFunctionTests 
--env-vars=src/.envs/test_env_dev.json
fi

您也可以尝试我在github问题中详细介绍的解决方法:

创建一个tests/conftest.py文件

# conftest.py
import sys
import os
sys.path.append(f"{os.getcwd()}/your/path/to/layers")

在创建了那个文件并添加了存储层的路径之后,我能够按照预期测试我的代码:python -m pytest tests/unit -v

最新更新