【问题标题】:Running tests (pytest) in CI (gitlab-ci kubernetes runner) for AWS Lambda w/ Layer using 'sam local invoke'使用“sam local invoke”在 CI (gitlab-ci kubernetes runner) 中为 AWS Lambda w/Layer 运行测试 (pytest)
【发布时间】:2024-01-05 05:18:01
【问题描述】:

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

post 获得一些启发,我使用 sam local invoke 使单元和集成测试在本地工作,该调用使用“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,我使用的是带有 kubernetes 运行器的 Gitlab ci,它使用了一个 debian:buster 构建映像,并安装了所需的 pre-reqs。我对 dind 和其他高级 docker 功能不太熟悉,所以想知道是否有人可以就我可以探索的方法提供指导。

TL'DR:有没有办法将 sam local invoke 作为 CI 的一部分运行?

更新:刚刚在 aws-sam-cli 上找到了这个 open feature request,这肯定会有所帮助。

【问题讨论】:

    标签: kubernetes pytest gitlab-ci aws-sam aws-lambda-layers


    【解决方案1】:

    这是我在 lambda 函数项目中作为 gitlab-ci 'test' 作业的一部分实施的解决方法,以通过 CI 运行测试:

    1. 下载layer.zip
    2. 解压到新目录
    3. 使用层 requirements.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
    

    【讨论】:

      最近更新 更多