From ed15aad400e49fae6eaf4e6c1faf74b4770168ff Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 22 Oct 2025 15:39:15 -0700 Subject: [PATCH 01/54] integ --- .github/workflows/integration-tests.yml | 1148 +++++++++++++++++++++++ 1 file changed, 1148 insertions(+) create mode 100644 .github/workflows/integration-tests.yml diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml new file mode 100644 index 00000000000..66a8dea30a2 --- /dev/null +++ b/.github/workflows/integration-tests.yml @@ -0,0 +1,1148 @@ +name: Integration Tests + +on: + push: + branches: + - integ + pull_request: + branches: + - integ + +permissions: + id-token: write # Required for OIDC + contents: read + +env: + PYTHON_VERSION: "3.9" + AWS_DEFAULT_REGION: us-west-2 + SAM_CLI_DEV: 1 + SAM_CLI_TELEMETRY: 0 + SAM_CLI_CONTAINER_CONNECTION_TIMEOUT: 60 + NODE_VERSION: "18.18.2" + CARGO_LAMBDA_VERSION: "v0.17.1" + NOSE_PARAMETERIZED_NO_WARN: 1 + +jobs: + build-integ-testing: + name: Build Integration Testing + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + container_runtime: [docker, finch] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Configure AWS credentials via OIDC + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole + aws-region: us-west-2 + + - name: Verify AWS identity + run: aws sts get-caller-identity + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Set up Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Set up Java 21 + uses: actions/setup-java@v4 + with: + distribution: 'corretto' + java-version: '21' + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.19' + + - name: Install Maven 3.9.11 + run: | + wget https://dlcdn.apache.org/maven/maven-3/3.9.11/binaries/apache-maven-3.9.11-bin.zip -P /tmp + sudo unzip -d /opt/mvn /tmp/apache-maven-*.zip + echo "/opt/mvn/apache-maven-3.9.11/bin" >> $GITHUB_PATH + + - name: Install Gradle 9.0.0 + run: | + wget https://services.gradle.org/distributions/gradle-9.0.0-bin.zip -P /tmp + sudo unzip -d /opt/gradle /tmp/gradle-*.zip + echo "/opt/gradle/gradle-9.0.0/bin" >> $GITHUB_PATH + + - name: Install .NET 8 SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0.x' + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.3.7' + + - name: Install Rust toolchain + run: | + curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL https://sh.rustup.rs | sh -s -- --default-toolchain none -y + source $HOME/.cargo/env + rustup toolchain install stable --profile minimal --no-self-update + rustup default stable + rustup target add x86_64-unknown-linux-gnu --toolchain stable + rustup target add aarch64-unknown-linux-gnu --toolchain stable + echo "$HOME/.cargo/bin" >> $GITHUB_PATH + + - name: Install cargo-lambda + run: pip install cargo-lambda==${{ env.CARGO_LAMBDA_VERSION }} + + - name: Setup Finch runtime + if: matrix.container_runtime == 'finch' + run: | + echo "=== Initializing Finch runtime ===" + + # Stop Docker services + sudo systemctl stop docker || true + sudo systemctl stop docker.socket || true + sudo systemctl disable docker || true + sudo systemctl disable docker.socket || true + + # Install Finch GPG key + for i in {1..3}; do + if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then + break + fi + sleep 10 + done + + # Add Finch repository + echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list + sudo apt update + + # Install Finch + sudo apt install -y runfinch-finch + + # Start Finch services + sudo systemctl enable --now finch + sudo systemctl enable --now finch-buildkit + sleep 3 + + # Set permissions + sudo chmod 666 /var/run/finch.sock + + # Wait for Finch to be ready + for i in {1..12}; do + if sudo finch info >/dev/null 2>&1; then + break + fi + sleep 5 + done + + # Setup BuildKit sockets + sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock + sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock + sudo chmod 666 /run/buildkit-*/buildkitd.sock + + # Setup cross-platform build support + sudo finch run --privileged --rm tonistiigi/binfmt:master --install all + + sudo finch info + sudo finch version + + - name: Setup Docker runtime + if: matrix.container_runtime == 'docker' + run: | + echo "=== Initializing Docker runtime ===" + docker info + docker version + + - name: Setup QEMU for ARM64 emulation + run: | + if [ "${{ matrix.container_runtime }}" = "finch" ]; then + sudo finch run --rm --privileged multiarch/qemu-user-static --reset -p yes + else + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + fi + + - name: Get testing resources + run: | + python3.9 -m venv .venv_env_vars + .venv_env_vars/bin/pip install boto3 + test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) + + echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV + echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV + echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV + echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV + echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV + echo "AWS_KMS_KEY=$(echo "$test_env_var" | jq -j ".TestKMSKeyArn")" >> $GITHUB_ENV + echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV + echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV + + - name: Initialize project + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + make init + + - name: Run build integration tests + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-build-integ-${{ matrix.container_runtime }} + path: TEST_REPORT-*.json + + build-integ-testing-java-python-provided: + name: Build Integration Testing (Java/Python/Provided) + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + container_runtime: [docker, finch] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Configure AWS credentials via OIDC + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole + aws-region: us-west-2 + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Set up Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Set up Java 21 + uses: actions/setup-java@v4 + with: + distribution: 'corretto' + java-version: '21' + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.19' + + - name: Install Maven 3.9.11 + run: | + wget https://dlcdn.apache.org/maven/maven-3/3.9.11/binaries/apache-maven-3.9.11-bin.zip -P /tmp + sudo unzip -d /opt/mvn /tmp/apache-maven-*.zip + echo "/opt/mvn/apache-maven-3.9.11/bin" >> $GITHUB_PATH + + - name: Install Gradle 9.0.0 + run: | + wget https://services.gradle.org/distributions/gradle-9.0.0-bin.zip -P /tmp + sudo unzip -d /opt/gradle /tmp/gradle-*.zip + echo "/opt/gradle/gradle-9.0.0/bin" >> $GITHUB_PATH + + - name: Install .NET 8 SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0.x' + + - name: Install Rust toolchain + run: | + curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL https://sh.rustup.rs | sh -s -- --default-toolchain none -y + source $HOME/.cargo/env + rustup toolchain install stable --profile minimal --no-self-update + rustup default stable + rustup target add x86_64-unknown-linux-gnu --toolchain stable + rustup target add aarch64-unknown-linux-gnu --toolchain stable + echo "$HOME/.cargo/bin" >> $GITHUB_PATH + + - name: Install cargo-lambda + run: pip install cargo-lambda==${{ env.CARGO_LAMBDA_VERSION }} + + - name: Setup Finch runtime + if: matrix.container_runtime == 'finch' + run: | + echo "=== Initializing Finch runtime ===" + sudo systemctl stop docker || true + sudo systemctl stop docker.socket || true + sudo systemctl disable docker || true + sudo systemctl disable docker.socket || true + + for i in {1..3}; do + if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then + break + fi + sleep 10 + done + + echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list + sudo apt update + sudo apt install -y runfinch-finch + sudo systemctl enable --now finch + sudo systemctl enable --now finch-buildkit + sleep 3 + sudo chmod 666 /var/run/finch.sock + + for i in {1..12}; do + if sudo finch info >/dev/null 2>&1; then + break + fi + sleep 5 + done + + sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock + sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock + sudo chmod 666 /run/buildkit-*/buildkitd.sock + sudo finch run --privileged --rm tonistiigi/binfmt:master --install all + + - name: Setup Docker runtime + if: matrix.container_runtime == 'docker' + run: | + docker info + docker version + + - name: Setup QEMU for ARM64 emulation + run: | + if [ "${{ matrix.container_runtime }}" = "finch" ]; then + sudo finch run --rm --privileged multiarch/qemu-user-static --reset -p yes + else + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + fi + + - name: Get testing resources + run: | + python3.9 -m venv .venv_env_vars + .venv_env_vars/bin/pip install boto3 + test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) + + echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV + echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV + echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV + echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV + echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV + echo "AWS_KMS_KEY=$(echo "$test_env_var" | jq -j ".TestKMSKeyArn")" >> $GITHUB_ENV + echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV + echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV + + - name: Initialize project + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + make init + + - name: Run build integration tests (Java/Python/Provided) + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-build-integ-java-python-provided-${{ matrix.container_runtime }} + path: TEST_REPORT-*.json + + build-integ-testing-arm64: + name: Build Integration Testing ARM64 + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + container_runtime: [docker, finch] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Configure AWS credentials via OIDC + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole + aws-region: us-west-2 + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Set up Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Set up Java 21 + uses: actions/setup-java@v4 + with: + distribution: 'corretto' + java-version: '21' + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.19' + + - name: Install Maven and Gradle + run: | + wget https://dlcdn.apache.org/maven/maven-3/3.9.11/binaries/apache-maven-3.9.11-bin.zip -P /tmp + sudo unzip -d /opt/mvn /tmp/apache-maven-*.zip + echo "/opt/mvn/apache-maven-3.9.11/bin" >> $GITHUB_PATH + wget https://services.gradle.org/distributions/gradle-9.0.0-bin.zip -P /tmp + sudo unzip -d /opt/gradle /tmp/gradle-*.zip + echo "/opt/gradle/gradle-9.0.0/bin" >> $GITHUB_PATH + + - name: Install .NET 8 SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0.x' + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.3.7' + + - name: Install Rust toolchain + run: | + curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL https://sh.rustup.rs | sh -s -- --default-toolchain none -y + source $HOME/.cargo/env + rustup toolchain install stable --profile minimal --no-self-update + rustup default stable + rustup target add x86_64-unknown-linux-gnu --toolchain stable + rustup target add aarch64-unknown-linux-gnu --toolchain stable + echo "$HOME/.cargo/bin" >> $GITHUB_PATH + + - name: Install cargo-lambda + run: pip install cargo-lambda==${{ env.CARGO_LAMBDA_VERSION }} + + - name: Setup Finch runtime + if: matrix.container_runtime == 'finch' + run: | + sudo systemctl stop docker || true + sudo systemctl stop docker.socket || true + for i in {1..3}; do + if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then + break + fi + sleep 10 + done + echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list + sudo apt update + sudo apt install -y runfinch-finch + sudo systemctl enable --now finch + sudo systemctl enable --now finch-buildkit + sleep 3 + sudo chmod 666 /var/run/finch.sock + for i in {1..12}; do + if sudo finch info >/dev/null 2>&1; then + break + fi + sleep 5 + done + sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock + sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock + sudo chmod 666 /run/buildkit-*/buildkitd.sock + sudo finch run --privileged --rm tonistiigi/binfmt:master --install all + + - name: Setup QEMU for ARM64 emulation + run: | + if [ "${{ matrix.container_runtime }}" = "finch" ]; then + sudo finch run --rm --privileged multiarch/qemu-user-static --reset -p yes + else + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + fi + + - name: Get testing resources + run: | + python3.9 -m venv .venv_env_vars + .venv_env_vars/bin/pip install boto3 + test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) + + echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV + echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV + echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV + echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV + echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV + echo "AWS_KMS_KEY=$(echo "$test_env_var" | jq -j ".TestKMSKeyArn")" >> $GITHUB_ENV + echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV + echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV + + - name: Initialize project + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + make init + + - name: Run ARM64 build integration tests + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-build-integ-arm64-${{ matrix.container_runtime }} + path: TEST_REPORT-*.json + + build-integ-testing-arm64-java: + name: Build Integration Testing ARM64 Java + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + container_runtime: [docker, finch] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Configure AWS credentials via OIDC + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole + aws-region: us-west-2 + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Set up Java 21 + uses: actions/setup-java@v4 + with: + distribution: 'corretto' + java-version: '21' + + - name: Install Maven and Gradle + run: | + wget https://dlcdn.apache.org/maven/maven-3/3.9.11/binaries/apache-maven-3.9.11-bin.zip -P /tmp + sudo unzip -d /opt/mvn /tmp/apache-maven-*.zip + echo "/opt/mvn/apache-maven-3.9.11/bin" >> $GITHUB_PATH + wget https://services.gradle.org/distributions/gradle-9.0.0-bin.zip -P /tmp + sudo unzip -d /opt/gradle /tmp/gradle-*.zip + echo "/opt/gradle/gradle-9.0.0/bin" >> $GITHUB_PATH + + - name: Setup Finch runtime + if: matrix.container_runtime == 'finch' + run: | + sudo systemctl stop docker || true + sudo systemctl stop docker.socket || true + for i in {1..3}; do + if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then + break + fi + sleep 10 + done + echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list + sudo apt update + sudo apt install -y runfinch-finch + sudo systemctl enable --now finch + sudo systemctl enable --now finch-buildkit + sleep 3 + sudo chmod 666 /var/run/finch.sock + for i in {1..12}; do + if sudo finch info >/dev/null 2>&1; then + break + fi + sleep 5 + done + sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock + sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock + sudo chmod 666 /run/buildkit-*/buildkitd.sock + sudo finch run --privileged --rm tonistiigi/binfmt:master --install all + + - name: Setup QEMU for ARM64 emulation + run: | + if [ "${{ matrix.container_runtime }}" = "finch" ]; then + sudo finch run --rm --privileged multiarch/qemu-user-static --reset -p yes + else + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + fi + + - name: Get testing resources + run: | + python3.9 -m venv .venv_env_vars + .venv_env_vars/bin/pip install boto3 + test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) + + echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV + echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV + echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV + echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV + echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV + echo "AWS_KMS_KEY=$(echo "$test_env_var" | jq -j ".TestKMSKeyArn")" >> $GITHUB_ENV + echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV + echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV + + - name: Initialize project + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + make init + + - name: Run ARM64 Java build integration tests + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-build-integ-arm64-java-${{ matrix.container_runtime }} + path: TEST_REPORT-*.json + + terraform-build-testing: + name: Terraform Build Testing + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + container_runtime: [docker, finch] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Configure AWS credentials via OIDC + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole + aws-region: us-west-2 + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Install Terraform + run: | + TER_VER=$(curl -s https://api.github.com/repos/hashicorp/terraform/releases/latest | grep tag_name | cut -d: -f2 | tr -d \"\,\v | awk '{$1=$1};1') + wget https://releases.hashicorp.com/terraform/${TER_VER}/terraform_${TER_VER}_linux_amd64.zip -P /tmp + sudo unzip -d /opt/terraform /tmp/terraform_${TER_VER}_linux_amd64.zip + sudo mv /opt/terraform/terraform /usr/local/bin/ + terraform -version + + - name: Setup Finch runtime + if: matrix.container_runtime == 'finch' + run: | + sudo systemctl stop docker || true + sudo systemctl stop docker.socket || true + for i in {1..3}; do + if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then + break + fi + sleep 10 + done + echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list + sudo apt update + sudo apt install -y runfinch-finch + sudo systemctl enable --now finch + sudo systemctl enable --now finch-buildkit + sleep 3 + sudo chmod 666 /var/run/finch.sock + for i in {1..12}; do + if sudo finch info >/dev/null 2>&1; then + break + fi + sleep 5 + done + sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock + sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock + sudo chmod 666 /run/buildkit-*/buildkitd.sock + + - name: Get testing resources + run: | + python3.9 -m venv .venv_env_vars + .venv_env_vars/bin/pip install boto3 + test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) + + echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV + echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV + echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV + echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV + echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV + + - name: Initialize project + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + make init + + - name: Run Terraform build tests + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + pytest -vv -n 4 --reruns 4 tests/integration/buildcmd/test_build_terraform_applications.py tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-terraform-${{ matrix.container_runtime }}.json + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-terraform-${{ matrix.container_runtime }} + path: TEST_REPORT-*.json + + package-delete-deploy-testing: + name: Package/Delete/Deploy Testing + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + container_runtime: [docker, finch] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Configure AWS credentials via OIDC + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole + aws-region: us-west-2 + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Setup Finch runtime + if: matrix.container_runtime == 'finch' + run: | + sudo systemctl stop docker || true + sudo systemctl stop docker.socket || true + for i in {1..3}; do + if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then + break + fi + sleep 10 + done + echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list + sudo apt update + sudo apt install -y runfinch-finch + sudo systemctl enable --now finch + sudo systemctl enable --now finch-buildkit + sleep 3 + sudo chmod 666 /var/run/finch.sock + for i in {1..12}; do + if sudo finch info >/dev/null 2>&1; then + break + fi + sleep 5 + done + sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock + sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock + sudo chmod 666 /run/buildkit-*/buildkitd.sock + + - name: Get testing resources + run: | + python3.9 -m venv .venv_env_vars + .venv_env_vars/bin/pip install boto3 + test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) + + echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV + echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV + echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV + echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV + echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV + + - name: Initialize project + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + make init + + - name: Run package/delete/deploy tests + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + pytest -vv tests/integration/package tests/integration/delete tests/integration/deploy --dist=loadgroup -n 4 --reruns 4 --json-report --json-report-file=TEST_REPORT-integration-package-delete-deploy-${{ matrix.container_runtime }}.json + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-package-delete-deploy-${{ matrix.container_runtime }} + path: TEST_REPORT-*.json + + sync-testing: + name: Sync Testing + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + container_runtime: [docker, finch] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Configure AWS credentials via OIDC + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole + aws-region: us-west-2 + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.3.7' + + - name: Setup Finch runtime + if: matrix.container_runtime == 'finch' + run: | + sudo systemctl stop docker || true + sudo systemctl stop docker.socket || true + for i in {1..3}; do + if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then + break + fi + sleep 10 + done + echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list + sudo apt update + sudo apt install -y runfinch-finch + sudo systemctl enable --now finch + sudo systemctl enable --now finch-buildkit + sleep 3 + sudo chmod 666 /var/run/finch.sock + for i in {1..12}; do + if sudo finch info >/dev/null 2>&1; then + break + fi + sleep 5 + done + sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock + sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock + sudo chmod 666 /run/buildkit-*/buildkitd.sock + + - name: Get testing resources + run: | + python3.9 -m venv .venv_env_vars + .venv_env_vars/bin/pip install boto3 + test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) + + echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV + echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV + echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV + echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV + echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV + + - name: Initialize project + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + make init + + - name: Run sync tests + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + pytest -vv tests/integration/sync -n 3 --reruns 3 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-sync-${{ matrix.container_runtime }} + path: TEST_REPORT-*.json + + local-invoke-testing: + name: Local Invoke Testing + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + container_runtime: [docker, finch] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Configure AWS credentials via OIDC + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole + aws-region: us-west-2 + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Install Terraform + run: | + TER_VER=$(curl -s https://api.github.com/repos/hashicorp/terraform/releases/latest | grep tag_name | cut -d: -f2 | tr -d \"\,\v | awk '{$1=$1};1') + wget https://releases.hashicorp.com/terraform/${TER_VER}/terraform_${TER_VER}_linux_amd64.zip -P /tmp + sudo unzip -d /opt/terraform /tmp/terraform_${TER_VER}_linux_amd64.zip + sudo mv /opt/terraform/terraform /usr/local/bin/ + terraform -version + + - name: Setup Finch runtime + if: matrix.container_runtime == 'finch' + run: | + sudo systemctl stop docker || true + sudo systemctl stop docker.socket || true + for i in {1..3}; do + if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then + break + fi + sleep 10 + done + echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list + sudo apt update + sudo apt install -y runfinch-finch + sudo systemctl enable --now finch + sudo systemctl enable --now finch-buildkit + sleep 3 + sudo chmod 666 /var/run/finch.sock + for i in {1..12}; do + if sudo finch info >/dev/null 2>&1; then + break + fi + sleep 5 + done + sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock + sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock + sudo chmod 666 /run/buildkit-*/buildkitd.sock + + - name: Get testing resources + run: | + python3.9 -m venv .venv_env_vars + .venv_env_vars/bin/pip install boto3 + test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) + + echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV + echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV + echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV + echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV + echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV + + - name: Initialize project + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + make init + + - name: Run local invoke tests + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + pytest -vv --reruns 3 tests/integration/local/invoke tests/integration/local/generate_event --json-report --json-report-file=TEST_REPORT-integration-local-invoke-${{ matrix.container_runtime }}.json + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-local-invoke-${{ matrix.container_runtime }} + path: TEST_REPORT-*.json + + local-start-testing: + name: Local Start Testing + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + container_runtime: [docker, finch] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Configure AWS credentials via OIDC + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole + aws-region: us-west-2 + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Install Terraform + run: | + TER_VER=$(curl -s https://api.github.com/repos/hashicorp/terraform/releases/latest | grep tag_name | cut -d: -f2 | tr -d \"\,\v | awk '{$1=$1};1') + wget https://releases.hashicorp.com/terraform/${TER_VER}/terraform_${TER_VER}_linux_amd64.zip -P /tmp + sudo unzip -d /opt/terraform /tmp/terraform_${TER_VER}_linux_amd64.zip + sudo mv /opt/terraform/terraform /usr/local/bin/ + terraform -version + + - name: Setup Finch runtime + if: matrix.container_runtime == 'finch' + run: | + sudo systemctl stop docker || true + sudo systemctl stop docker.socket || true + for i in {1..3}; do + if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then + break + fi + sleep 10 + done + echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list + sudo apt update + sudo apt install -y runfinch-finch + sudo systemctl enable --now finch + sudo systemctl enable --now finch-buildkit + sleep 3 + sudo chmod 666 /var/run/finch.sock + for i in {1..12}; do + if sudo finch info >/dev/null 2>&1; then + break + fi + sleep 5 + done + sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock + sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock + sudo chmod 666 /run/buildkit-*/buildkitd.sock + + - name: Get testing resources + run: | + python3.9 -m venv .venv_env_vars + .venv_env_vars/bin/pip install boto3 + test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) + + echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV + echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV + echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV + echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV + echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV + + - name: Initialize project + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + make init + + - name: Run local start tests + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + pytest -vv --reruns 3 tests/integration/local/start_api tests/integration/local/start_lambda --json-report --json-report-file=TEST_REPORT-integration-local-start-${{ matrix.container_runtime }}.json + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-local-start-${{ matrix.container_runtime }} + path: TEST_REPORT-*.json + + other-and-e2e-testing: + name: Other and End-to-End Testing + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + container_runtime: [docker, finch] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Configure AWS credentials via OIDC + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole + aws-region: us-west-2 + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.3.7' + + - name: Setup Finch runtime + if: matrix.container_runtime == 'finch' + run: | + sudo systemctl stop docker || true + sudo systemctl stop docker.socket || true + for i in {1..3}; do + if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then + break + fi + sleep 10 + done + echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list + sudo apt update + sudo apt install -y runfinch-finch + sudo systemctl enable --now finch + sudo systemctl enable --now finch-buildkit + sleep 3 + sudo chmod 666 /var/run/finch.sock + for i in {1..12}; do + if sudo finch info >/dev/null 2>&1; then + break + fi + sleep 5 + done + sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock + sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock + sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock + sudo chmod 666 /run/buildkit-*/buildkitd.sock + + - name: Get testing resources + run: | + python3.9 -m venv .venv_env_vars + .venv_env_vars/bin/pip install boto3 + test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) + + echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV + echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV + echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV + echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV + echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV + + - name: Initialize project + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + make init + + - name: Run other integration and end-to-end tests + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + pytest -vv -n 4 --reruns 4 --dist loadgroup tests/integration tests/end_to_end --ignore=tests/integration/buildcmd --ignore=tests/integration/delete --ignore=tests/integration/deploy --ignore=tests/integration/package --ignore=tests/integration/sync --ignore=tests/integration/local --json-report --json-report-file=TEST_REPORT-integration-others-${{ matrix.container_runtime }}.json + + - name: Run regression tests + run: | + export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + pytest -vv --reruns 3 tests/regression --json-report --json-report-file=TEST_REPORT-regression-${{ matrix.container_runtime }}.json + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-other-e2e-${{ matrix.container_runtime }} + path: TEST_REPORT-*.json From c2bb33b3f951331f17b4a4da196ee0d0040e5e1b Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 22 Oct 2025 15:47:53 -0700 Subject: [PATCH 02/54] remove cred --- .github/workflows/integration-tests.yml | 123 ------------------------ 1 file changed, 123 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 66a8dea30a2..029df5935e7 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -171,21 +171,6 @@ jobs: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi - - name: Get testing resources - run: | - python3.9 -m venv .venv_env_vars - .venv_env_vars/bin/pip install boto3 - test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) - - echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV - echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV - echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV - echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV - echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV - echo "AWS_KMS_KEY=$(echo "$test_env_var" | jq -j ".TestKMSKeyArn")" >> $GITHUB_ENV - echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV - echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV - - name: Initialize project run: | export CONTAINER_RUNTIME=${{ matrix.container_runtime }} @@ -325,18 +310,6 @@ jobs: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi - - name: Get testing resources - run: | - python3.9 -m venv .venv_env_vars - .venv_env_vars/bin/pip install boto3 - test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) - - echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV - echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV - echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV - echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV - echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV - echo "AWS_KMS_KEY=$(echo "$test_env_var" | jq -j ".TestKMSKeyArn")" >> $GITHUB_ENV echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV @@ -468,18 +441,6 @@ jobs: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi - - name: Get testing resources - run: | - python3.9 -m venv .venv_env_vars - .venv_env_vars/bin/pip install boto3 - test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) - - echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV - echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV - echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV - echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV - echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV - echo "AWS_KMS_KEY=$(echo "$test_env_var" | jq -j ".TestKMSKeyArn")" >> $GITHUB_ENV echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV @@ -578,18 +539,6 @@ jobs: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi - - name: Get testing resources - run: | - python3.9 -m venv .venv_env_vars - .venv_env_vars/bin/pip install boto3 - test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) - - echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV - echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV - echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV - echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV - echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV - echo "AWS_KMS_KEY=$(echo "$test_env_var" | jq -j ".TestKMSKeyArn")" >> $GITHUB_ENV echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV @@ -672,18 +621,6 @@ jobs: sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock sudo chmod 666 /run/buildkit-*/buildkitd.sock - - name: Get testing resources - run: | - python3.9 -m venv .venv_env_vars - .venv_env_vars/bin/pip install boto3 - test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) - - echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV - echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV - echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV - echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV - echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV - - name: Initialize project run: | export CONTAINER_RUNTIME=${{ matrix.container_runtime }} @@ -755,18 +692,6 @@ jobs: sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock sudo chmod 666 /run/buildkit-*/buildkitd.sock - - name: Get testing resources - run: | - python3.9 -m venv .venv_env_vars - .venv_env_vars/bin/pip install boto3 - test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) - - echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV - echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV - echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV - echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV - echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV - - name: Initialize project run: | export CONTAINER_RUNTIME=${{ matrix.container_runtime }} @@ -843,18 +768,6 @@ jobs: sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock sudo chmod 666 /run/buildkit-*/buildkitd.sock - - name: Get testing resources - run: | - python3.9 -m venv .venv_env_vars - .venv_env_vars/bin/pip install boto3 - test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) - - echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV - echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV - echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV - echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV - echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV - - name: Initialize project run: | export CONTAINER_RUNTIME=${{ matrix.container_runtime }} @@ -934,18 +847,6 @@ jobs: sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock sudo chmod 666 /run/buildkit-*/buildkitd.sock - - name: Get testing resources - run: | - python3.9 -m venv .venv_env_vars - .venv_env_vars/bin/pip install boto3 - test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) - - echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV - echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV - echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV - echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV - echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV - - name: Initialize project run: | export CONTAINER_RUNTIME=${{ matrix.container_runtime }} @@ -1025,18 +926,6 @@ jobs: sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock sudo chmod 666 /run/buildkit-*/buildkitd.sock - - name: Get testing resources - run: | - python3.9 -m venv .venv_env_vars - .venv_env_vars/bin/pip install boto3 - test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) - - echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV - echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV - echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV - echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV - echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV - - name: Initialize project run: | export CONTAINER_RUNTIME=${{ matrix.container_runtime }} @@ -1113,18 +1002,6 @@ jobs: sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock sudo chmod 666 /run/buildkit-*/buildkitd.sock - - name: Get testing resources - run: | - python3.9 -m venv .venv_env_vars - .venv_env_vars/bin/pip install boto3 - test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) - - echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV - echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV - echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV - echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV - echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV - - name: Initialize project run: | export CONTAINER_RUNTIME=${{ matrix.container_runtime }} From ecf95b84ba2419f893dedfc20d10dfdf38285f3d Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 22 Oct 2025 16:15:39 -0700 Subject: [PATCH 03/54] fix multiple failures --- .github/workflows/integration-tests.yml | 168 ++++++++++++++++++------ tests/testing_utils.py | 8 +- 2 files changed, 132 insertions(+), 44 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 029df5935e7..45d7e5164cc 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -13,14 +13,14 @@ permissions: contents: read env: - PYTHON_VERSION: "3.9" - AWS_DEFAULT_REGION: us-west-2 + AWS_DEFAULT_REGION: us-east-1 SAM_CLI_DEV: 1 SAM_CLI_TELEMETRY: 0 SAM_CLI_CONTAINER_CONNECTION_TIMEOUT: 60 NODE_VERSION: "18.18.2" CARGO_LAMBDA_VERSION: "v0.17.1" NOSE_PARAMETERIZED_NO_WARN: 1 + GITHUB_ACTIONS_INTEG: true jobs: build-integ-testing: @@ -39,15 +39,20 @@ jobs: uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-west-2 + aws-region: us-east-1 - name: Verify AWS identity run: aws sts get-caller-identity - - name: Set up Python ${{ env.PYTHON_VERSION }} + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ env.PYTHON_VERSION }} + python-version: | + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Set up Node.js ${{ env.NODE_VERSION }} uses: actions/setup-node@v4 @@ -82,11 +87,21 @@ jobs: with: dotnet-version: '8.0.x' - - name: Set up Ruby + - name: Set up Ruby 3.2.7 + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.2.7' + + - name: Set up Ruby 3.3.7 uses: ruby/setup-ruby@v1 with: ruby-version: '3.3.7' + - name: Set up Ruby 3.4.2 + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.4.2' + - name: Install Rust toolchain run: | curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL https://sh.rustup.rs | sh -s -- --default-toolchain none -y @@ -204,12 +219,17 @@ jobs: uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-west-2 + aws-region: us-east-1 - - name: Set up Python ${{ env.PYTHON_VERSION }} + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ env.PYTHON_VERSION }} + python-version: | + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Set up Node.js ${{ env.NODE_VERSION }} uses: actions/setup-node@v4 @@ -310,8 +330,6 @@ jobs: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi - echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV - echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV - name: Initialize project run: | @@ -346,12 +364,17 @@ jobs: uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-west-2 + aws-region: us-east-1 - - name: Set up Python ${{ env.PYTHON_VERSION }} + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ env.PYTHON_VERSION }} + python-version: | + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Set up Node.js ${{ env.NODE_VERSION }} uses: actions/setup-node@v4 @@ -383,11 +406,21 @@ jobs: with: dotnet-version: '8.0.x' - - name: Set up Ruby + - name: Set up Ruby 3.2.7 + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.2.7' + + - name: Set up Ruby 3.3.7 uses: ruby/setup-ruby@v1 with: ruby-version: '3.3.7' + - name: Set up Ruby 3.4.2 + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.4.2' + - name: Install Rust toolchain run: | curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL https://sh.rustup.rs | sh -s -- --default-toolchain none -y @@ -441,8 +474,6 @@ jobs: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi - echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV - echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV - name: Initialize project run: | @@ -477,12 +508,17 @@ jobs: uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-west-2 + aws-region: us-east-1 - - name: Set up Python ${{ env.PYTHON_VERSION }} + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ env.PYTHON_VERSION }} + python-version: | + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Set up Java 21 uses: actions/setup-java@v4 @@ -539,8 +575,6 @@ jobs: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi - echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV - echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV - name: Initialize project run: | @@ -575,12 +609,17 @@ jobs: uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-west-2 + aws-region: us-east-1 - - name: Set up Python ${{ env.PYTHON_VERSION }} + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ env.PYTHON_VERSION }} + python-version: | + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Install Terraform run: | @@ -654,12 +693,17 @@ jobs: uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-west-2 + aws-region: us-east-1 - - name: Set up Python ${{ env.PYTHON_VERSION }} + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ env.PYTHON_VERSION }} + python-version: | + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Setup Finch runtime if: matrix.container_runtime == 'finch' @@ -725,18 +769,33 @@ jobs: uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-west-2 + aws-region: us-east-1 - - name: Set up Python ${{ env.PYTHON_VERSION }} + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ env.PYTHON_VERSION }} + python-version: | + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 + + - name: Set up Ruby 3.2.7 + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.2.7' - - name: Set up Ruby + - name: Set up Ruby 3.3.7 uses: ruby/setup-ruby@v1 with: ruby-version: '3.3.7' + - name: Set up Ruby 3.4.2 + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.4.2' + - name: Setup Finch runtime if: matrix.container_runtime == 'finch' run: | @@ -801,12 +860,17 @@ jobs: uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-west-2 + aws-region: us-east-1 - - name: Set up Python ${{ env.PYTHON_VERSION }} + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ env.PYTHON_VERSION }} + python-version: | + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Install Terraform run: | @@ -880,12 +944,17 @@ jobs: uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-west-2 + aws-region: us-east-1 - - name: Set up Python ${{ env.PYTHON_VERSION }} + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ env.PYTHON_VERSION }} + python-version: | + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Install Terraform run: | @@ -959,18 +1028,33 @@ jobs: uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-west-2 + aws-region: us-east-1 - - name: Set up Python ${{ env.PYTHON_VERSION }} + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ env.PYTHON_VERSION }} + python-version: | + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 + + - name: Set up Ruby 3.2.7 + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.2.7' - - name: Set up Ruby + - name: Set up Ruby 3.3.7 uses: ruby/setup-ruby@v1 with: ruby-version: '3.3.7' + - name: Set up Ruby 3.4.2 + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.4.2' + - name: Setup Finch runtime if: matrix.container_runtime == 'finch' run: | diff --git a/tests/testing_utils.py b/tests/testing_utils.py index f93a12e78b6..87a2181f71f 100644 --- a/tests/testing_utils.py +++ b/tests/testing_utils.py @@ -24,12 +24,16 @@ RUNNING_ON_APPVEYOR = os.environ.get("APPVEYOR", False) IS_WINDOWS = platform.system().lower() == "windows" -RUNNING_ON_GITHUB_ACTIONS = os.environ.get("CI", False) +RUNNING_ON_GITHUB_ACTIONS = os.environ.get("CI", False) or os.environ.get("GITHUB_ACTIONS", False) RUNNING_ON_CI = RUNNING_ON_APPVEYOR or RUNNING_ON_GITHUB_ACTIONS RUNNING_TEST_FOR_MASTER_ON_CI = ( os.environ.get("APPVEYOR_REPO_BRANCH", os.environ.get("GITHUB_REF_NAME", "master")) != "master" ) -CI_OVERRIDE = os.environ.get("APPVEYOR_CI_OVERRIDE", False) or os.environ.get("CI_OVERRIDE", False) +CI_OVERRIDE = ( + os.environ.get("APPVEYOR_CI_OVERRIDE", False) + or os.environ.get("CI_OVERRIDE", False) + or os.environ.get("GITHUB_ACTIONS_INTEG", False) +) RUN_BY_CANARY = os.environ.get("BY_CANARY", False) USING_FINCH_RUNTIME = os.environ.get("CONTAINER_RUNTIME") == "finch" From 0bcbfa691f3e8187db7935d930ef72b1fc9443f3 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 22 Oct 2025 16:17:00 -0700 Subject: [PATCH 04/54] nit --- .github/workflows/integration-tests.yml | 100 ++++++++++++------------ 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 45d7e5164cc..db64baa08df 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -48,11 +48,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.9 - 3.10 - 3.11 - 3.12 - 3.13 + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Set up Node.js ${{ env.NODE_VERSION }} uses: actions/setup-node@v4 @@ -225,11 +225,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.9 - 3.10 - 3.11 - 3.12 - 3.13 + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Set up Node.js ${{ env.NODE_VERSION }} uses: actions/setup-node@v4 @@ -370,11 +370,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.9 - 3.10 - 3.11 - 3.12 - 3.13 + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Set up Node.js ${{ env.NODE_VERSION }} uses: actions/setup-node@v4 @@ -514,11 +514,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.9 - 3.10 - 3.11 - 3.12 - 3.13 + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Set up Java 21 uses: actions/setup-java@v4 @@ -615,11 +615,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.9 - 3.10 - 3.11 - 3.12 - 3.13 + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Install Terraform run: | @@ -699,11 +699,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.9 - 3.10 - 3.11 - 3.12 - 3.13 + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Setup Finch runtime if: matrix.container_runtime == 'finch' @@ -775,11 +775,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.9 - 3.10 - 3.11 - 3.12 - 3.13 + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Set up Ruby 3.2.7 uses: ruby/setup-ruby@v1 @@ -866,11 +866,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.9 - 3.10 - 3.11 - 3.12 - 3.13 + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Install Terraform run: | @@ -950,11 +950,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.9 - 3.10 - 3.11 - 3.12 - 3.13 + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Install Terraform run: | @@ -1034,11 +1034,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.9 - 3.10 - 3.11 - 3.12 - 3.13 + 3.9 + 3.10 + 3.11 + 3.12 + 3.13 - name: Set up Ruby 3.2.7 uses: ruby/setup-ruby@v1 From 3c67cf9359a21295ec46186905d24e4eecca5fcc Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 22 Oct 2025 16:32:04 -0700 Subject: [PATCH 05/54] nit2 --- .github/workflows/integration-tests.yml | 39 +++++++++++++++---------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index db64baa08df..153dcca1961 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -21,6 +21,7 @@ env: CARGO_LAMBDA_VERSION: "v0.17.1" NOSE_PARAMETERIZED_NO_WARN: 1 GITHUB_ACTIONS_INTEG: true + BY_CANARY: true jobs: build-integ-testing: @@ -48,9 +49,9 @@ jobs: uses: actions/setup-python@v5 with: python-version: | + 3.11 3.9 3.10 - 3.11 3.12 3.13 @@ -225,9 +226,9 @@ jobs: uses: actions/setup-python@v5 with: python-version: | + 3.11 3.9 3.10 - 3.11 3.12 3.13 @@ -370,9 +371,9 @@ jobs: uses: actions/setup-python@v5 with: python-version: | + 3.11 3.9 3.10 - 3.11 3.12 3.13 @@ -514,9 +515,9 @@ jobs: uses: actions/setup-python@v5 with: python-version: | + 3.11 3.9 3.10 - 3.11 3.12 3.13 @@ -615,19 +616,27 @@ jobs: uses: actions/setup-python@v5 with: python-version: | + 3.11 3.9 3.10 - 3.11 3.12 3.13 - name: Install Terraform run: | - TER_VER=$(curl -s https://api.github.com/repos/hashicorp/terraform/releases/latest | grep tag_name | cut -d: -f2 | tr -d \"\,\v | awk '{$1=$1};1') - wget https://releases.hashicorp.com/terraform/${TER_VER}/terraform_${TER_VER}_linux_amd64.zip -P /tmp - sudo unzip -d /opt/terraform /tmp/terraform_${TER_VER}_linux_amd64.zip - sudo mv /opt/terraform/terraform /usr/local/bin/ - terraform -version + for i in {1..3}; do + TER_VER=$(curl -s https://api.github.com/repos/hashicorp/terraform/releases/latest | grep tag_name | cut -d: -f2 | tr -d \"\,\v | awk '{$1=$1};1') + if [ -n "$TER_VER" ]; then + if wget https://releases.hashicorp.com/terraform/${TER_VER}/terraform_${TER_VER}_linux_amd64.zip -P /tmp; then + sudo unzip -d /opt/terraform /tmp/terraform_${TER_VER}_linux_amd64.zip + sudo mv /opt/terraform/terraform /usr/local/bin/ + terraform -version + break + fi + fi + echo "Terraform installation attempt $i failed, retrying..." + sleep 5 + done - name: Setup Finch runtime if: matrix.container_runtime == 'finch' @@ -699,9 +708,9 @@ jobs: uses: actions/setup-python@v5 with: python-version: | + 3.11 3.9 3.10 - 3.11 3.12 3.13 @@ -775,9 +784,9 @@ jobs: uses: actions/setup-python@v5 with: python-version: | + 3.11 3.9 3.10 - 3.11 3.12 3.13 @@ -866,9 +875,9 @@ jobs: uses: actions/setup-python@v5 with: python-version: | + 3.11 3.9 3.10 - 3.11 3.12 3.13 @@ -950,9 +959,9 @@ jobs: uses: actions/setup-python@v5 with: python-version: | + 3.11 3.9 3.10 - 3.11 3.12 3.13 @@ -1034,9 +1043,9 @@ jobs: uses: actions/setup-python@v5 with: python-version: | + 3.11 3.9 3.10 - 3.11 3.12 3.13 From 664cc03289717a959ff48842131ddf00abfda250 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 22 Oct 2025 16:55:09 -0700 Subject: [PATCH 06/54] nit3 --- .github/workflows/integration-tests.yml | 1044 +++-------------------- 1 file changed, 106 insertions(+), 938 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 153dcca1961..b1857be665d 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -4,9 +4,6 @@ on: push: branches: - integ - pull_request: - branches: - - integ permissions: id-token: write # Required for OIDC @@ -24,18 +21,50 @@ env: BY_CANARY: true jobs: - build-integ-testing: - name: Build Integration Testing + integration-tests: + name: ${{ matrix.test_suite }} (${{ matrix.container_runtime }}) runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: container_runtime: [docker, finch] + test_suite: + - build-integ + - build-integ-java-python-provided + - build-integ-arm64 + - build-integ-arm64-java + - terraform-build + - package-delete-deploy + - sync + - local-invoke + - local-start + - other-and-e2e steps: - name: Checkout code uses: actions/checkout@v4 + - name: Free up disk space + run: | + echo "Disk space before cleanup:" + df -h + + # Remove unnecessary software + sudo rm -rf /usr/share/dotnet + sudo rm -rf /usr/local/lib/android + sudo rm -rf /opt/ghc + sudo rm -rf /opt/hostedtoolcache/CodeQL + sudo rm -rf "$AGENT_TOOLSDIRECTORY" + + # Clean apt cache + sudo apt-get clean + + # Remove docker images + docker rmi $(docker images -q) 2>/dev/null || true + + echo "Disk space after cleanup:" + df -h + - name: Configure AWS credentials via OIDC uses: aws-actions/configure-aws-credentials@v4 with: @@ -43,6 +72,7 @@ jobs: aws-region: us-east-1 - name: Verify AWS identity + if: matrix.test_suite == 'build-integ' run: aws sts get-caller-identity - name: Set up Python @@ -55,55 +85,69 @@ jobs: 3.12 3.13 - - name: Set up Node.js ${{ env.NODE_VERSION }} + - name: Set Python 3.11 as default + if: matrix.test_suite == 'build-integ' + run: | + echo "$(python3.11 -m site --user-base)/bin" >> $GITHUB_PATH + python3.11 -m pip install --upgrade pip + python3.11 --version + which python3.11 + + - name: Set up Node.js + if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: Set up Java 21 + if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64", "build-integ-arm64-java"]'), matrix.test_suite) uses: actions/setup-java@v4 with: distribution: 'corretto' java-version: '21' - name: Set up Go + if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) uses: actions/setup-go@v5 with: go-version: '1.19' - - name: Install Maven 3.9.11 + - name: Install Maven and Gradle + if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64", "build-integ-arm64-java"]'), matrix.test_suite) run: | wget https://dlcdn.apache.org/maven/maven-3/3.9.11/binaries/apache-maven-3.9.11-bin.zip -P /tmp sudo unzip -d /opt/mvn /tmp/apache-maven-*.zip echo "/opt/mvn/apache-maven-3.9.11/bin" >> $GITHUB_PATH - - - name: Install Gradle 9.0.0 - run: | wget https://services.gradle.org/distributions/gradle-9.0.0-bin.zip -P /tmp sudo unzip -d /opt/gradle /tmp/gradle-*.zip echo "/opt/gradle/gradle-9.0.0/bin" >> $GITHUB_PATH - name: Install .NET 8 SDK + if: contains(fromJSON('["build-integ", "build-integ-arm64"]'), matrix.test_suite) uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.x' - name: Set up Ruby 3.2.7 + if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) uses: ruby/setup-ruby@v1 with: ruby-version: '3.2.7' - name: Set up Ruby 3.3.7 + if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) uses: ruby/setup-ruby@v1 with: ruby-version: '3.3.7' - name: Set up Ruby 3.4.2 + if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) uses: ruby/setup-ruby@v1 with: ruby-version: '3.4.2' - name: Install Rust toolchain + if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) run: | curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL https://sh.rustup.rs | sh -s -- --default-toolchain none -y source $HOME/.cargo/env @@ -114,169 +158,25 @@ jobs: echo "$HOME/.cargo/bin" >> $GITHUB_PATH - name: Install cargo-lambda + if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) run: pip install cargo-lambda==${{ env.CARGO_LAMBDA_VERSION }} - - name: Setup Finch runtime - if: matrix.container_runtime == 'finch' + - name: Install Terraform + if: contains(fromJSON('["terraform-build", "local-invoke", "local-start"]'), matrix.test_suite) run: | - echo "=== Initializing Finch runtime ===" - - # Stop Docker services - sudo systemctl stop docker || true - sudo systemctl stop docker.socket || true - sudo systemctl disable docker || true - sudo systemctl disable docker.socket || true - - # Install Finch GPG key for i in {1..3}; do - if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then - break - fi - sleep 10 - done - - # Add Finch repository - echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list - sudo apt update - - # Install Finch - sudo apt install -y runfinch-finch - - # Start Finch services - sudo systemctl enable --now finch - sudo systemctl enable --now finch-buildkit - sleep 3 - - # Set permissions - sudo chmod 666 /var/run/finch.sock - - # Wait for Finch to be ready - for i in {1..12}; do - if sudo finch info >/dev/null 2>&1; then - break + TER_VER=$(curl -s https://api.github.com/repos/hashicorp/terraform/releases/latest | grep tag_name | cut -d: -f2 | tr -d \"\,\v | awk '{$1=$1};1') + if [ -n "$TER_VER" ]; then + if wget https://releases.hashicorp.com/terraform/${TER_VER}/terraform_${TER_VER}_linux_amd64.zip -P /tmp; then + sudo unzip -d /opt/terraform /tmp/terraform_${TER_VER}_linux_amd64.zip + sudo mv /opt/terraform/terraform /usr/local/bin/ + terraform -version + break + fi fi + echo "Terraform installation attempt $i failed, retrying..." sleep 5 done - - # Setup BuildKit sockets - sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock - sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock - sudo chmod 666 /run/buildkit-*/buildkitd.sock - - # Setup cross-platform build support - sudo finch run --privileged --rm tonistiigi/binfmt:master --install all - - sudo finch info - sudo finch version - - - name: Setup Docker runtime - if: matrix.container_runtime == 'docker' - run: | - echo "=== Initializing Docker runtime ===" - docker info - docker version - - - name: Setup QEMU for ARM64 emulation - run: | - if [ "${{ matrix.container_runtime }}" = "finch" ]; then - sudo finch run --rm --privileged multiarch/qemu-user-static --reset -p yes - else - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - fi - - - name: Initialize project - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - make init - - - name: Run build integration tests - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-results-build-integ-${{ matrix.container_runtime }} - path: TEST_REPORT-*.json - - build-integ-testing-java-python-provided: - name: Build Integration Testing (Java/Python/Provided) - runs-on: ubuntu-22.04 - strategy: - fail-fast: false - matrix: - container_runtime: [docker, finch] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Configure AWS credentials via OIDC - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-east-1 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: | - 3.11 - 3.9 - 3.10 - 3.12 - 3.13 - - - name: Set up Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Set up Java 21 - uses: actions/setup-java@v4 - with: - distribution: 'corretto' - java-version: '21' - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: '1.19' - - - name: Install Maven 3.9.11 - run: | - wget https://dlcdn.apache.org/maven/maven-3/3.9.11/binaries/apache-maven-3.9.11-bin.zip -P /tmp - sudo unzip -d /opt/mvn /tmp/apache-maven-*.zip - echo "/opt/mvn/apache-maven-3.9.11/bin" >> $GITHUB_PATH - - - name: Install Gradle 9.0.0 - run: | - wget https://services.gradle.org/distributions/gradle-9.0.0-bin.zip -P /tmp - sudo unzip -d /opt/gradle /tmp/gradle-*.zip - echo "/opt/gradle/gradle-9.0.0/bin" >> $GITHUB_PATH - - - name: Install .NET 8 SDK - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '8.0.x' - - - name: Install Rust toolchain - run: | - curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL https://sh.rustup.rs | sh -s -- --default-toolchain none -y - source $HOME/.cargo/env - rustup toolchain install stable --profile minimal --no-self-update - rustup default stable - rustup target add x86_64-unknown-linux-gnu --toolchain stable - rustup target add aarch64-unknown-linux-gnu --toolchain stable - echo "$HOME/.cargo/bin" >> $GITHUB_PATH - - - name: Install cargo-lambda - run: pip install cargo-lambda==${{ env.CARGO_LAMBDA_VERSION }} - name: Setup Finch runtime if: matrix.container_runtime == 'finch' @@ -316,10 +216,14 @@ jobs: sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock sudo chmod 666 /run/buildkit-*/buildkitd.sock sudo finch run --privileged --rm tonistiigi/binfmt:master --install all + + sudo finch info + sudo finch version - name: Setup Docker runtime if: matrix.container_runtime == 'docker' run: | + echo "=== Initializing Docker runtime ===" docker info docker version @@ -331,788 +235,52 @@ jobs: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi - - name: Initialize project run: | export CONTAINER_RUNTIME=${{ matrix.container_runtime }} make init - - name: Run build integration tests (Java/Python/Provided) + - name: Run tests run: | export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-results-build-integ-java-python-provided-${{ matrix.container_runtime }} - path: TEST_REPORT-*.json - - build-integ-testing-arm64: - name: Build Integration Testing ARM64 - runs-on: ubuntu-22.04 - strategy: - fail-fast: false - matrix: - container_runtime: [docker, finch] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Configure AWS credentials via OIDC - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-east-1 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: | - 3.11 - 3.9 - 3.10 - 3.12 - 3.13 - - - name: Set up Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Set up Java 21 - uses: actions/setup-java@v4 - with: - distribution: 'corretto' - java-version: '21' - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: '1.19' - - - name: Install Maven and Gradle - run: | - wget https://dlcdn.apache.org/maven/maven-3/3.9.11/binaries/apache-maven-3.9.11-bin.zip -P /tmp - sudo unzip -d /opt/mvn /tmp/apache-maven-*.zip - echo "/opt/mvn/apache-maven-3.9.11/bin" >> $GITHUB_PATH - wget https://services.gradle.org/distributions/gradle-9.0.0-bin.zip -P /tmp - sudo unzip -d /opt/gradle /tmp/gradle-*.zip - echo "/opt/gradle/gradle-9.0.0/bin" >> $GITHUB_PATH - - - name: Install .NET 8 SDK - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '8.0.x' - - - name: Set up Ruby 3.2.7 - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.2.7' - - - name: Set up Ruby 3.3.7 - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.3.7' - - - name: Set up Ruby 3.4.2 - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.4.2' - - - name: Install Rust toolchain - run: | - curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL https://sh.rustup.rs | sh -s -- --default-toolchain none -y - source $HOME/.cargo/env - rustup toolchain install stable --profile minimal --no-self-update - rustup default stable - rustup target add x86_64-unknown-linux-gnu --toolchain stable - rustup target add aarch64-unknown-linux-gnu --toolchain stable - echo "$HOME/.cargo/bin" >> $GITHUB_PATH - - - name: Install cargo-lambda - run: pip install cargo-lambda==${{ env.CARGO_LAMBDA_VERSION }} - - - name: Setup Finch runtime - if: matrix.container_runtime == 'finch' - run: | - sudo systemctl stop docker || true - sudo systemctl stop docker.socket || true - for i in {1..3}; do - if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then - break - fi - sleep 10 - done - echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list - sudo apt update - sudo apt install -y runfinch-finch - sudo systemctl enable --now finch - sudo systemctl enable --now finch-buildkit - sleep 3 - sudo chmod 666 /var/run/finch.sock - for i in {1..12}; do - if sudo finch info >/dev/null 2>&1; then - break - fi - sleep 5 - done - sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock - sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock - sudo chmod 666 /run/buildkit-*/buildkitd.sock - sudo finch run --privileged --rm tonistiigi/binfmt:master --install all - - - name: Setup QEMU for ARM64 emulation - run: | - if [ "${{ matrix.container_runtime }}" = "finch" ]; then - sudo finch run --rm --privileged multiarch/qemu-user-static --reset -p yes - else - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - fi - - - - name: Initialize project - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - make init - - - name: Run ARM64 build integration tests - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-results-build-integ-arm64-${{ matrix.container_runtime }} - path: TEST_REPORT-*.json - - build-integ-testing-arm64-java: - name: Build Integration Testing ARM64 Java - runs-on: ubuntu-22.04 - strategy: - fail-fast: false - matrix: - container_runtime: [docker, finch] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Configure AWS credentials via OIDC - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-east-1 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: | - 3.11 - 3.9 - 3.10 - 3.12 - 3.13 - - - name: Set up Java 21 - uses: actions/setup-java@v4 - with: - distribution: 'corretto' - java-version: '21' - - - name: Install Maven and Gradle - run: | - wget https://dlcdn.apache.org/maven/maven-3/3.9.11/binaries/apache-maven-3.9.11-bin.zip -P /tmp - sudo unzip -d /opt/mvn /tmp/apache-maven-*.zip - echo "/opt/mvn/apache-maven-3.9.11/bin" >> $GITHUB_PATH - wget https://services.gradle.org/distributions/gradle-9.0.0-bin.zip -P /tmp - sudo unzip -d /opt/gradle /tmp/gradle-*.zip - echo "/opt/gradle/gradle-9.0.0/bin" >> $GITHUB_PATH - - - name: Setup Finch runtime - if: matrix.container_runtime == 'finch' - run: | - sudo systemctl stop docker || true - sudo systemctl stop docker.socket || true - for i in {1..3}; do - if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then - break - fi - sleep 10 - done - echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list - sudo apt update - sudo apt install -y runfinch-finch - sudo systemctl enable --now finch - sudo systemctl enable --now finch-buildkit - sleep 3 - sudo chmod 666 /var/run/finch.sock - for i in {1..12}; do - if sudo finch info >/dev/null 2>&1; then - break - fi - sleep 5 - done - sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock - sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock - sudo chmod 666 /run/buildkit-*/buildkitd.sock - sudo finch run --privileged --rm tonistiigi/binfmt:master --install all - - - name: Setup QEMU for ARM64 emulation - run: | - if [ "${{ matrix.container_runtime }}" = "finch" ]; then - sudo finch run --rm --privileged multiarch/qemu-user-static --reset -p yes - else - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - fi - - - - name: Initialize project - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - make init - - - name: Run ARM64 Java build integration tests - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-results-build-integ-arm64-java-${{ matrix.container_runtime }} - path: TEST_REPORT-*.json - - terraform-build-testing: - name: Terraform Build Testing - runs-on: ubuntu-22.04 - strategy: - fail-fast: false - matrix: - container_runtime: [docker, finch] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Configure AWS credentials via OIDC - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-east-1 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: | - 3.11 - 3.9 - 3.10 - 3.12 - 3.13 - - - name: Install Terraform - run: | - for i in {1..3}; do - TER_VER=$(curl -s https://api.github.com/repos/hashicorp/terraform/releases/latest | grep tag_name | cut -d: -f2 | tr -d \"\,\v | awk '{$1=$1};1') - if [ -n "$TER_VER" ]; then - if wget https://releases.hashicorp.com/terraform/${TER_VER}/terraform_${TER_VER}_linux_amd64.zip -P /tmp; then - sudo unzip -d /opt/terraform /tmp/terraform_${TER_VER}_linux_amd64.zip - sudo mv /opt/terraform/terraform /usr/local/bin/ - terraform -version - break - fi - fi - echo "Terraform installation attempt $i failed, retrying..." - sleep 5 - done - - - name: Setup Finch runtime - if: matrix.container_runtime == 'finch' - run: | - sudo systemctl stop docker || true - sudo systemctl stop docker.socket || true - for i in {1..3}; do - if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then - break - fi - sleep 10 - done - echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list - sudo apt update - sudo apt install -y runfinch-finch - sudo systemctl enable --now finch - sudo systemctl enable --now finch-buildkit - sleep 3 - sudo chmod 666 /var/run/finch.sock - for i in {1..12}; do - if sudo finch info >/dev/null 2>&1; then - break - fi - sleep 5 - done - sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock - sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock - sudo chmod 666 /run/buildkit-*/buildkitd.sock - - - name: Initialize project - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - make init - - - name: Run Terraform build tests - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - pytest -vv -n 4 --reruns 4 tests/integration/buildcmd/test_build_terraform_applications.py tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-terraform-${{ matrix.container_runtime }}.json - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-results-terraform-${{ matrix.container_runtime }} - path: TEST_REPORT-*.json - - package-delete-deploy-testing: - name: Package/Delete/Deploy Testing - runs-on: ubuntu-22.04 - strategy: - fail-fast: false - matrix: - container_runtime: [docker, finch] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Configure AWS credentials via OIDC - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-east-1 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: | - 3.11 - 3.9 - 3.10 - 3.12 - 3.13 - - - name: Setup Finch runtime - if: matrix.container_runtime == 'finch' - run: | - sudo systemctl stop docker || true - sudo systemctl stop docker.socket || true - for i in {1..3}; do - if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then - break - fi - sleep 10 - done - echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list - sudo apt update - sudo apt install -y runfinch-finch - sudo systemctl enable --now finch - sudo systemctl enable --now finch-buildkit - sleep 3 - sudo chmod 666 /var/run/finch.sock - for i in {1..12}; do - if sudo finch info >/dev/null 2>&1; then - break - fi - sleep 5 - done - sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock - sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock - sudo chmod 666 /run/buildkit-*/buildkitd.sock - - - name: Initialize project - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - make init - - - name: Run package/delete/deploy tests - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - pytest -vv tests/integration/package tests/integration/delete tests/integration/deploy --dist=loadgroup -n 4 --reruns 4 --json-report --json-report-file=TEST_REPORT-integration-package-delete-deploy-${{ matrix.container_runtime }}.json - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-results-package-delete-deploy-${{ matrix.container_runtime }} - path: TEST_REPORT-*.json - - sync-testing: - name: Sync Testing - runs-on: ubuntu-22.04 - strategy: - fail-fast: false - matrix: - container_runtime: [docker, finch] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Configure AWS credentials via OIDC - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-east-1 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: | - 3.11 - 3.9 - 3.10 - 3.12 - 3.13 - - - name: Set up Ruby 3.2.7 - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.2.7' - - - name: Set up Ruby 3.3.7 - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.3.7' - - - name: Set up Ruby 3.4.2 - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.4.2' - - - name: Setup Finch runtime - if: matrix.container_runtime == 'finch' - run: | - sudo systemctl stop docker || true - sudo systemctl stop docker.socket || true - for i in {1..3}; do - if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then - break - fi - sleep 10 - done - echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list - sudo apt update - sudo apt install -y runfinch-finch - sudo systemctl enable --now finch - sudo systemctl enable --now finch-buildkit - sleep 3 - sudo chmod 666 /var/run/finch.sock - for i in {1..12}; do - if sudo finch info >/dev/null 2>&1; then - break - fi - sleep 5 - done - sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock - sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock - sudo chmod 666 /run/buildkit-*/buildkitd.sock - - - name: Initialize project - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - make init - - - name: Run sync tests - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - pytest -vv tests/integration/sync -n 3 --reruns 3 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-results-sync-${{ matrix.container_runtime }} - path: TEST_REPORT-*.json - - local-invoke-testing: - name: Local Invoke Testing - runs-on: ubuntu-22.04 - strategy: - fail-fast: false - matrix: - container_runtime: [docker, finch] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Configure AWS credentials via OIDC - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-east-1 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: | - 3.11 - 3.9 - 3.10 - 3.12 - 3.13 - - - name: Install Terraform - run: | - TER_VER=$(curl -s https://api.github.com/repos/hashicorp/terraform/releases/latest | grep tag_name | cut -d: -f2 | tr -d \"\,\v | awk '{$1=$1};1') - wget https://releases.hashicorp.com/terraform/${TER_VER}/terraform_${TER_VER}_linux_amd64.zip -P /tmp - sudo unzip -d /opt/terraform /tmp/terraform_${TER_VER}_linux_amd64.zip - sudo mv /opt/terraform/terraform /usr/local/bin/ - terraform -version - - - name: Setup Finch runtime - if: matrix.container_runtime == 'finch' - run: | - sudo systemctl stop docker || true - sudo systemctl stop docker.socket || true - for i in {1..3}; do - if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then - break - fi - sleep 10 - done - echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list - sudo apt update - sudo apt install -y runfinch-finch - sudo systemctl enable --now finch - sudo systemctl enable --now finch-buildkit - sleep 3 - sudo chmod 666 /var/run/finch.sock - for i in {1..12}; do - if sudo finch info >/dev/null 2>&1; then - break - fi - sleep 5 - done - sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock - sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock - sudo chmod 666 /run/buildkit-*/buildkitd.sock - - - name: Initialize project - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - make init - - - name: Run local invoke tests - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - pytest -vv --reruns 3 tests/integration/local/invoke tests/integration/local/generate_event --json-report --json-report-file=TEST_REPORT-integration-local-invoke-${{ matrix.container_runtime }}.json - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-results-local-invoke-${{ matrix.container_runtime }} - path: TEST_REPORT-*.json - - local-start-testing: - name: Local Start Testing - runs-on: ubuntu-22.04 - strategy: - fail-fast: false - matrix: - container_runtime: [docker, finch] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Configure AWS credentials via OIDC - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-east-1 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: | - 3.11 - 3.9 - 3.10 - 3.12 - 3.13 - - - name: Install Terraform - run: | - TER_VER=$(curl -s https://api.github.com/repos/hashicorp/terraform/releases/latest | grep tag_name | cut -d: -f2 | tr -d \"\,\v | awk '{$1=$1};1') - wget https://releases.hashicorp.com/terraform/${TER_VER}/terraform_${TER_VER}_linux_amd64.zip -P /tmp - sudo unzip -d /opt/terraform /tmp/terraform_${TER_VER}_linux_amd64.zip - sudo mv /opt/terraform/terraform /usr/local/bin/ - terraform -version - - - name: Setup Finch runtime - if: matrix.container_runtime == 'finch' - run: | - sudo systemctl stop docker || true - sudo systemctl stop docker.socket || true - for i in {1..3}; do - if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then - break - fi - sleep 10 - done - echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list - sudo apt update - sudo apt install -y runfinch-finch - sudo systemctl enable --now finch - sudo systemctl enable --now finch-buildkit - sleep 3 - sudo chmod 666 /var/run/finch.sock - for i in {1..12}; do - if sudo finch info >/dev/null 2>&1; then - break - fi - sleep 5 - done - sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock - sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock - sudo chmod 666 /run/buildkit-*/buildkitd.sock - - - name: Initialize project - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - make init - - - name: Run local start tests - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - pytest -vv --reruns 3 tests/integration/local/start_api tests/integration/local/start_lambda --json-report --json-report-file=TEST_REPORT-integration-local-start-${{ matrix.container_runtime }}.json - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-results-local-start-${{ matrix.container_runtime }} - path: TEST_REPORT-*.json - - other-and-e2e-testing: - name: Other and End-to-End Testing - runs-on: ubuntu-22.04 - strategy: - fail-fast: false - matrix: - container_runtime: [docker, finch] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Configure AWS credentials via OIDC - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-east-1 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: | - 3.11 - 3.9 - 3.10 - 3.12 - 3.13 - - - name: Set up Ruby 3.2.7 - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.2.7' - - - name: Set up Ruby 3.3.7 - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.3.7' - - - name: Set up Ruby 3.4.2 - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.4.2' - - - name: Setup Finch runtime - if: matrix.container_runtime == 'finch' - run: | - sudo systemctl stop docker || true - sudo systemctl stop docker.socket || true - for i in {1..3}; do - if curl -fsSL https://artifact.runfinch.com/deb/GPG_KEY.pub | sudo gpg --dearmor -o /usr/share/keyrings/runfinch-finch-archive-keyring.gpg; then - break - fi - sleep 10 - done - echo 'deb [signed-by=/usr/share/keyrings/runfinch-finch-archive-keyring.gpg arch=amd64] https://artifact.runfinch.com/deb noble main' | sudo tee /etc/apt/sources.list.d/runfinch-finch.list - sudo apt update - sudo apt install -y runfinch-finch - sudo systemctl enable --now finch - sudo systemctl enable --now finch-buildkit - sleep 3 - sudo chmod 666 /var/run/finch.sock - for i in {1..12}; do - if sudo finch info >/dev/null 2>&1; then - break - fi - sleep 5 - done - sudo mkdir -p /run/buildkit-finch /run/buildkit-default /run/buildkit - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-finch/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit-default/buildkitd.sock - sudo ln -sf /var/lib/finch/buildkit/buildkitd.sock /run/buildkit/buildkitd.sock - sudo chmod 666 /var/lib/finch/buildkit/buildkitd.sock - sudo chmod 666 /run/buildkit-*/buildkitd.sock - - - name: Initialize project - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - make init - - - name: Run other integration and end-to-end tests - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - pytest -vv -n 4 --reruns 4 --dist loadgroup tests/integration tests/end_to_end --ignore=tests/integration/buildcmd --ignore=tests/integration/delete --ignore=tests/integration/deploy --ignore=tests/integration/package --ignore=tests/integration/sync --ignore=tests/integration/local --json-report --json-report-file=TEST_REPORT-integration-others-${{ matrix.container_runtime }}.json - - - name: Run regression tests - run: | - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - pytest -vv --reruns 3 tests/regression --json-report --json-report-file=TEST_REPORT-regression-${{ matrix.container_runtime }}.json + + case "${{ matrix.test_suite }}" in + "build-integ") + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json + ;; + "build-integ-java-python-provided") + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json + ;; + "build-integ-arm64") + pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json + ;; + "build-integ-arm64-java") + pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json + ;; + "terraform-build") + pytest -vv -n 4 --reruns 4 tests/integration/buildcmd/test_build_terraform_applications.py tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-terraform-${{ matrix.container_runtime }}.json + ;; + "package-delete-deploy") + pytest -vv tests/integration/package tests/integration/delete tests/integration/deploy --dist=loadgroup -n 4 --reruns 4 --json-report --json-report-file=TEST_REPORT-integration-package-delete-deploy-${{ matrix.container_runtime }}.json + ;; + "sync") + pytest -vv tests/integration/sync -n 3 --reruns 3 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json + ;; + "local-invoke") + pytest -vv --reruns 3 tests/integration/local/invoke tests/integration/local/generate_event --json-report --json-report-file=TEST_REPORT-integration-local-invoke-${{ matrix.container_runtime }}.json + ;; + "local-start") + pytest -vv --reruns 3 tests/integration/local/start_api tests/integration/local/start_lambda --json-report --json-report-file=TEST_REPORT-integration-local-start-${{ matrix.container_runtime }}.json + ;; + "other-and-e2e") + pytest -vv -n 4 --reruns 4 --dist loadgroup tests/integration tests/end_to_end --ignore=tests/integration/buildcmd --ignore=tests/integration/delete --ignore=tests/integration/deploy --ignore=tests/integration/package --ignore=tests/integration/sync --ignore=tests/integration/local --json-report --json-report-file=TEST_REPORT-integration-others-${{ matrix.container_runtime }}.json + pytest -vv --reruns 3 tests/regression --json-report --json-report-file=TEST_REPORT-regression-${{ matrix.container_runtime }}.json + ;; + esac - name: Upload test results if: always() uses: actions/upload-artifact@v4 with: - name: test-results-other-e2e-${{ matrix.container_runtime }} + name: test-results-${{ matrix.test_suite }}-${{ matrix.container_runtime }} path: TEST_REPORT-*.json From f654a14d1a68b54163c6cd63df7604f1b64bc3df Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 22 Oct 2025 17:07:38 -0700 Subject: [PATCH 07/54] nit4 --- .github/workflows/integration-tests.yml | 33 +++++++++---------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index b1857be665d..95594375f28 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -49,12 +49,11 @@ jobs: echo "Disk space before cleanup:" df -h - # Remove unnecessary software + # Remove unnecessary software (but keep Python) sudo rm -rf /usr/share/dotnet sudo rm -rf /usr/local/lib/android sudo rm -rf /opt/ghc sudo rm -rf /opt/hostedtoolcache/CodeQL - sudo rm -rf "$AGENT_TOOLSDIRECTORY" # Clean apt cache sudo apt-get clean @@ -85,14 +84,6 @@ jobs: 3.12 3.13 - - name: Set Python 3.11 as default - if: matrix.test_suite == 'build-integ' - run: | - echo "$(python3.11 -m site --user-base)/bin" >> $GITHUB_PATH - python3.11 -m pip install --upgrade pip - python3.11 --version - which python3.11 - - name: Set up Node.js if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) uses: actions/setup-node@v4 @@ -246,35 +237,35 @@ jobs: case "${{ matrix.test_suite }}" in "build-integ") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json + python3.11 -m pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json ;; "build-integ-java-python-provided") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json + python3.11 -m pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json ;; "build-integ-arm64") - pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json + python3.11 -m pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json ;; "build-integ-arm64-java") - pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json + python3.11 -m pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json ;; "terraform-build") - pytest -vv -n 4 --reruns 4 tests/integration/buildcmd/test_build_terraform_applications.py tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-terraform-${{ matrix.container_runtime }}.json + python3.11 -m pytest -vv -n 4 --reruns 4 tests/integration/buildcmd/test_build_terraform_applications.py tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-terraform-${{ matrix.container_runtime }}.json ;; "package-delete-deploy") - pytest -vv tests/integration/package tests/integration/delete tests/integration/deploy --dist=loadgroup -n 4 --reruns 4 --json-report --json-report-file=TEST_REPORT-integration-package-delete-deploy-${{ matrix.container_runtime }}.json + python3.11 -m pytest -vv tests/integration/package tests/integration/delete tests/integration/deploy --dist=loadgroup -n 4 --reruns 4 --json-report --json-report-file=TEST_REPORT-integration-package-delete-deploy-${{ matrix.container_runtime }}.json ;; "sync") - pytest -vv tests/integration/sync -n 3 --reruns 3 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json + python3.11 -m pytest -vv tests/integration/sync -n 3 --reruns 3 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json ;; "local-invoke") - pytest -vv --reruns 3 tests/integration/local/invoke tests/integration/local/generate_event --json-report --json-report-file=TEST_REPORT-integration-local-invoke-${{ matrix.container_runtime }}.json + python3.11 -m pytest -vv --reruns 3 tests/integration/local/invoke tests/integration/local/generate_event --json-report --json-report-file=TEST_REPORT-integration-local-invoke-${{ matrix.container_runtime }}.json ;; "local-start") - pytest -vv --reruns 3 tests/integration/local/start_api tests/integration/local/start_lambda --json-report --json-report-file=TEST_REPORT-integration-local-start-${{ matrix.container_runtime }}.json + python3.11 -m pytest -vv --reruns 3 tests/integration/local/start_api tests/integration/local/start_lambda --json-report --json-report-file=TEST_REPORT-integration-local-start-${{ matrix.container_runtime }}.json ;; "other-and-e2e") - pytest -vv -n 4 --reruns 4 --dist loadgroup tests/integration tests/end_to_end --ignore=tests/integration/buildcmd --ignore=tests/integration/delete --ignore=tests/integration/deploy --ignore=tests/integration/package --ignore=tests/integration/sync --ignore=tests/integration/local --json-report --json-report-file=TEST_REPORT-integration-others-${{ matrix.container_runtime }}.json - pytest -vv --reruns 3 tests/regression --json-report --json-report-file=TEST_REPORT-regression-${{ matrix.container_runtime }}.json + python3.11 -m pytest -vv -n 4 --reruns 4 --dist loadgroup tests/integration tests/end_to_end --ignore=tests/integration/buildcmd --ignore=tests/integration/delete --ignore=tests/integration/deploy --ignore=tests/integration/package --ignore=tests/integration/sync --ignore=tests/integration/local --json-report --json-report-file=TEST_REPORT-integration-others-${{ matrix.container_runtime }}.json + python3.11 -m pytest -vv --reruns 3 tests/regression --json-report --json-report-file=TEST_REPORT-regression-${{ matrix.container_runtime }}.json ;; esac From 4ed12fd06ed505686ccf1858b5ab6270eecb005e Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 22 Oct 2025 17:14:53 -0700 Subject: [PATCH 08/54] nit o --- .github/workflows/integration-tests.yml | 47 ++++++++++++------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 95594375f28..4b3c10717fb 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -19,6 +19,7 @@ env: NOSE_PARAMETERIZED_NO_WARN: 1 GITHUB_ACTIONS_INTEG: true BY_CANARY: true + UV_PYTHON: python3.11 jobs: integration-tests: @@ -44,25 +45,21 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Free up disk space + - name: Free up disk space (background) run: | echo "Disk space before cleanup:" df -h - # Remove unnecessary software (but keep Python) - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/local/lib/android - sudo rm -rf /opt/ghc - sudo rm -rf /opt/hostedtoolcache/CodeQL + # Run cleanup in background to not block workflow + nohup bash -c ' + sudo apt-get clean + sudo rm -rf /usr/share/dotnet + sudo rm -rf /usr/local/lib/android + sudo rm -rf /opt/ghc + sudo rm -rf /opt/hostedtoolcache/CodeQL + ' > /dev/null 2>&1 & - # Clean apt cache - sudo apt-get clean - - # Remove docker images - docker rmi $(docker images -q) 2>/dev/null || true - - echo "Disk space after cleanup:" - df -h + echo "Cleanup started in background" - name: Configure AWS credentials via OIDC uses: aws-actions/configure-aws-credentials@v4 @@ -237,35 +234,35 @@ jobs: case "${{ matrix.test_suite }}" in "build-integ") - python3.11 -m pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json ;; "build-integ-java-python-provided") - python3.11 -m pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json ;; "build-integ-arm64") - python3.11 -m pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json + pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json ;; "build-integ-arm64-java") - python3.11 -m pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json + pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json ;; "terraform-build") - python3.11 -m pytest -vv -n 4 --reruns 4 tests/integration/buildcmd/test_build_terraform_applications.py tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-terraform-${{ matrix.container_runtime }}.json + pytest -vv -n 4 --reruns 4 tests/integration/buildcmd/test_build_terraform_applications.py tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-terraform-${{ matrix.container_runtime }}.json ;; "package-delete-deploy") - python3.11 -m pytest -vv tests/integration/package tests/integration/delete tests/integration/deploy --dist=loadgroup -n 4 --reruns 4 --json-report --json-report-file=TEST_REPORT-integration-package-delete-deploy-${{ matrix.container_runtime }}.json + pytest -vv tests/integration/package tests/integration/delete tests/integration/deploy --dist=loadgroup -n 4 --reruns 4 --json-report --json-report-file=TEST_REPORT-integration-package-delete-deploy-${{ matrix.container_runtime }}.json ;; "sync") - python3.11 -m pytest -vv tests/integration/sync -n 3 --reruns 3 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json + pytest -vv tests/integration/sync -n 3 --reruns 3 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json ;; "local-invoke") - python3.11 -m pytest -vv --reruns 3 tests/integration/local/invoke tests/integration/local/generate_event --json-report --json-report-file=TEST_REPORT-integration-local-invoke-${{ matrix.container_runtime }}.json + pytest -vv --reruns 3 tests/integration/local/invoke tests/integration/local/generate_event --json-report --json-report-file=TEST_REPORT-integration-local-invoke-${{ matrix.container_runtime }}.json ;; "local-start") - python3.11 -m pytest -vv --reruns 3 tests/integration/local/start_api tests/integration/local/start_lambda --json-report --json-report-file=TEST_REPORT-integration-local-start-${{ matrix.container_runtime }}.json + pytest -vv --reruns 3 tests/integration/local/start_api tests/integration/local/start_lambda --json-report --json-report-file=TEST_REPORT-integration-local-start-${{ matrix.container_runtime }}.json ;; "other-and-e2e") - python3.11 -m pytest -vv -n 4 --reruns 4 --dist loadgroup tests/integration tests/end_to_end --ignore=tests/integration/buildcmd --ignore=tests/integration/delete --ignore=tests/integration/deploy --ignore=tests/integration/package --ignore=tests/integration/sync --ignore=tests/integration/local --json-report --json-report-file=TEST_REPORT-integration-others-${{ matrix.container_runtime }}.json - python3.11 -m pytest -vv --reruns 3 tests/regression --json-report --json-report-file=TEST_REPORT-regression-${{ matrix.container_runtime }}.json + pytest -vv -n 4 --reruns 4 --dist loadgroup tests/integration tests/end_to_end --ignore=tests/integration/buildcmd --ignore=tests/integration/delete --ignore=tests/integration/deploy --ignore=tests/integration/package --ignore=tests/integration/sync --ignore=tests/integration/local --json-report --json-report-file=TEST_REPORT-integration-others-${{ matrix.container_runtime }}.json + pytest -vv --reruns 3 tests/regression --json-report --json-report-file=TEST_REPORT-regression-${{ matrix.container_runtime }}.json ;; esac From 1fc5a5d03b6e9236f4177a5b04bf5b73762446c5 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 23 Oct 2025 15:02:11 -0700 Subject: [PATCH 09/54] use test account --- .github/workflows/integration-tests.yml | 61 ++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 4b3c10717fb..c65533e21f4 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -10,7 +10,7 @@ permissions: contents: read env: - AWS_DEFAULT_REGION: us-east-1 + AWS_DEFAULT_REGION: us-west-2 SAM_CLI_DEV: 1 SAM_CLI_TELEMETRY: 0 SAM_CLI_CONTAINER_CONNECTION_TIMEOUT: 60 @@ -19,7 +19,9 @@ env: NOSE_PARAMETERIZED_NO_WARN: 1 GITHUB_ACTIONS_INTEG: true BY_CANARY: true - UV_PYTHON: python3.11 + UV_PYTHON: python3.9 + CREDENTIAL_DISTRIBUTION_LAMBDA_ARN: arn:aws:lambda:us-west-2:123087993316:function:test-account-management-CredentialDistributionLamb-o1sEaa8lvO1L + ACCOUNT_RESET_LAMBDA_ARN: arn:aws:lambda:us-west-2:123087993316:function:test-account-management-AccountResetLambdaFunction-nBZDo6oLCH80 jobs: integration-tests: @@ -65,11 +67,14 @@ jobs: uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-east-1 + aws-region: us-west-2 - - name: Verify AWS identity - if: matrix.test_suite == 'build-integ' - run: aws sts get-caller-identity + - name: Assume TAM caller role + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::670246014611:role/aws-sam-cli-canary-tam-caller-TAMCallerRole-dgaIJ7W7Byha + aws-region: us-west-2 + role-chaining: true - name: Set up Python uses: actions/setup-python@v5 @@ -166,6 +171,33 @@ jobs: sleep 5 done + - name: Get testing resources and credentials + run: | + python3.9 -m venv .venv_env_vars + .venv_env_vars/bin/pip install boto3 + test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) + + if [ $? -ne 0 ]; then + echo "get_testing_resources failed. Failed to acquire credentials or test resources." + exit 1 + fi + + # Save current credentials for account reset later + echo "CI_ACCESS_ROLE_AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" >> $GITHUB_ENV + echo "CI_ACCESS_ROLE_AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" >> $GITHUB_ENV + echo "CI_ACCESS_ROLE_AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN" >> $GITHUB_ENV + + # Set test credentials + echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV + echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV + echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV + echo "TASK_TOKEN=$(echo "$test_env_var" | jq -j ".taskToken")" >> $GITHUB_ENV + echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV + echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV + echo "AWS_KMS_KEY=$(echo "$test_env_var" | jq -j ".TestKMSKeyArn")" >> $GITHUB_ENV + echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV + echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV + - name: Setup Finch runtime if: matrix.container_runtime == 'finch' run: | @@ -272,3 +304,20 @@ jobs: with: name: test-results-${{ matrix.test_suite }}-${{ matrix.container_runtime }} path: TEST_REPORT-*.json + + - name: Reset test account + if: always() + run: | + # Switch back to TAM caller role credentials + export AWS_ACCESS_KEY_ID=$CI_ACCESS_ROLE_AWS_ACCESS_KEY_ID + export AWS_SECRET_ACCESS_KEY=$CI_ACCESS_ROLE_AWS_SECRET_ACCESS_KEY + export AWS_SESSION_TOKEN=$CI_ACCESS_ROLE_AWS_SESSION_TOKEN + + # Invoke account reset Lambda + aws lambda invoke \ + --function-name "$ACCOUNT_RESET_LAMBDA_ARN" \ + --payload "{\"taskToken\": \"$TASK_TOKEN\", \"output\": \"{}\"}" \ + ./lambda-output.txt \ + --region us-west-2 + + cat ./lambda-output.txt From 8be6a5ea40e2104828f5b9f337200ee6896da142 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 23 Oct 2025 15:57:17 -0700 Subject: [PATCH 10/54] direct --- .github/workflows/integration-tests.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index c65533e21f4..ee05d923330 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -64,17 +64,10 @@ jobs: echo "Cleanup started in background" - name: Configure AWS credentials via OIDC - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: arn:aws:iam::881620123898:role/GitHubActionsAdminRole - aws-region: us-west-2 - - - name: Assume TAM caller role uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::670246014611:role/aws-sam-cli-canary-tam-caller-TAMCallerRole-dgaIJ7W7Byha aws-region: us-west-2 - role-chaining: true - name: Set up Python uses: actions/setup-python@v5 From bd574e7dbf3dd04ebee7fa2d6c2cf3633b2e9703 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 23 Oct 2025 16:04:20 -0700 Subject: [PATCH 11/54] retry --- .github/workflows/integration-tests.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index ee05d923330..239f240ea39 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -10,7 +10,6 @@ permissions: contents: read env: - AWS_DEFAULT_REGION: us-west-2 SAM_CLI_DEV: 1 SAM_CLI_TELEMETRY: 0 SAM_CLI_CONTAINER_CONNECTION_TIMEOUT: 60 @@ -306,10 +305,10 @@ jobs: export AWS_SECRET_ACCESS_KEY=$CI_ACCESS_ROLE_AWS_SECRET_ACCESS_KEY export AWS_SESSION_TOKEN=$CI_ACCESS_ROLE_AWS_SESSION_TOKEN - # Invoke account reset Lambda + # Invoke account reset Lambda with properly formatted payload aws lambda invoke \ --function-name "$ACCOUNT_RESET_LAMBDA_ARN" \ - --payload "{\"taskToken\": \"$TASK_TOKEN\", \"output\": \"{}\"}" \ + --payload '{"taskToken": "'"$TASK_TOKEN"'", "output": "{}"}' \ ./lambda-output.txt \ --region us-west-2 From c9628375140b725c6acd9958d66943bbadaeb758 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 23 Oct 2025 16:14:00 -0700 Subject: [PATCH 12/54] nit --- .github/workflows/integration-tests.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 239f240ea39..4cde8d90993 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -10,6 +10,7 @@ permissions: contents: read env: + AWS_DEFAULT_REGION: us-east-1 SAM_CLI_DEV: 1 SAM_CLI_TELEMETRY: 0 SAM_CLI_CONTAINER_CONNECTION_TIMEOUT: 60 @@ -305,10 +306,13 @@ jobs: export AWS_SECRET_ACCESS_KEY=$CI_ACCESS_ROLE_AWS_SECRET_ACCESS_KEY export AWS_SESSION_TOKEN=$CI_ACCESS_ROLE_AWS_SESSION_TOKEN - # Invoke account reset Lambda with properly formatted payload + # Create payload file to avoid escaping issues + echo "{\"taskToken\": \"$TASK_TOKEN\", \"output\": \"{}\"}" > ./lambda-payload.json + + # Invoke account reset Lambda aws lambda invoke \ --function-name "$ACCOUNT_RESET_LAMBDA_ARN" \ - --payload '{"taskToken": "'"$TASK_TOKEN"'", "output": "{}"}' \ + --payload file://./lambda-payload.json \ ./lambda-output.txt \ --region us-west-2 From 1612fd87a7eca4766b7f2550d11caf8d9016d075 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 23 Oct 2025 16:29:55 -0700 Subject: [PATCH 13/54] nit --- .github/workflows/integration-tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 4cde8d90993..12eb69af7a6 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -67,7 +67,7 @@ jobs: uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::670246014611:role/aws-sam-cli-canary-tam-caller-TAMCallerRole-dgaIJ7W7Byha - aws-region: us-west-2 + aws-region: us-east-1 - name: Set up Python uses: actions/setup-python@v5 @@ -306,8 +306,8 @@ jobs: export AWS_SECRET_ACCESS_KEY=$CI_ACCESS_ROLE_AWS_SECRET_ACCESS_KEY export AWS_SESSION_TOKEN=$CI_ACCESS_ROLE_AWS_SESSION_TOKEN - # Create payload file to avoid escaping issues - echo "{\"taskToken\": \"$TASK_TOKEN\", \"output\": \"{}\"}" > ./lambda-payload.json + # Create payload file using Python to handle special characters properly + python3.9 -c "import json; print(json.dumps({'taskToken': '$TASK_TOKEN', 'output': '{}'}))" > ./lambda-payload.json # Invoke account reset Lambda aws lambda invoke \ From 15547ccc2e412b6416ca7ee1692b72bd33acff82 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 23 Oct 2025 17:43:58 -0700 Subject: [PATCH 14/54] fix multiple stuff --- .github/workflows/integration-tests.yml | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 12eb69af7a6..eb8312d0d7d 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -20,7 +20,7 @@ env: GITHUB_ACTIONS_INTEG: true BY_CANARY: true UV_PYTHON: python3.9 - CREDENTIAL_DISTRIBUTION_LAMBDA_ARN: arn:aws:lambda:us-west-2:123087993316:function:test-account-management-CredentialDistributionLamb-o1sEaa8lvO1L + CREDENTIAL_DISTRIBUTION_LAMBDA_ARN: arn:aws:lambda:us-west-2:123087993316:function:test-account-management-CredentialDistributionLamb-7CwJ4B8P4hth ACCOUNT_RESET_LAMBDA_ARN: arn:aws:lambda:us-west-2:123087993316:function:test-account-management-AccountResetLambdaFunction-nBZDo6oLCH80 jobs: @@ -30,7 +30,8 @@ jobs: strategy: fail-fast: false matrix: - container_runtime: [docker, finch] + # container_runtime: [docker, finch] + container_runtime: [docker] test_suite: - build-integ - build-integ-java-python-provided @@ -132,6 +133,12 @@ jobs: with: ruby-version: '3.4.2' + - name: Set Ruby 3.3.7 as global + if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) + run: | + echo "$(ruby-3.3.7 -e 'puts RbConfig::CONFIG["bindir"]')" >> $GITHUB_PATH + ruby --version + - name: Install Rust toolchain if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) run: | @@ -166,8 +173,8 @@ jobs: - name: Get testing resources and credentials run: | - python3.9 -m venv .venv_env_vars - .venv_env_vars/bin/pip install boto3 + uv venv .venv_env_vars --python python3.9 + uv pip install --python .venv_env_vars boto3 test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) if [ $? -ne 0 ]; then @@ -306,14 +313,12 @@ jobs: export AWS_SECRET_ACCESS_KEY=$CI_ACCESS_ROLE_AWS_SECRET_ACCESS_KEY export AWS_SESSION_TOKEN=$CI_ACCESS_ROLE_AWS_SESSION_TOKEN - # Create payload file using Python to handle special characters properly - python3.9 -c "import json; print(json.dumps({'taskToken': '$TASK_TOKEN', 'output': '{}'}))" > ./lambda-payload.json - - # Invoke account reset Lambda + # Invoke account reset Lambda with raw binary format aws lambda invoke \ --function-name "$ACCOUNT_RESET_LAMBDA_ARN" \ - --payload file://./lambda-payload.json \ + --payload "{\"taskToken\": \"$TASK_TOKEN\", \"output\": \"{}\"}" \ ./lambda-output.txt \ - --region us-west-2 + --region us-west-2 \ + --cli-binary-format raw-in-base64-out cat ./lambda-output.txt From c218a3d9d9153b363b426b53c699db39dd76f808 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 23 Oct 2025 17:47:42 -0700 Subject: [PATCH 15/54] move get cred after init --- .github/workflows/integration-tests.yml | 52 ++++++++++++------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index eb8312d0d7d..f3361fb5aeb 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -171,33 +171,6 @@ jobs: sleep 5 done - - name: Get testing resources and credentials - run: | - uv venv .venv_env_vars --python python3.9 - uv pip install --python .venv_env_vars boto3 - test_env_var=$(.venv_env_vars/bin/python tests/get_testing_resources.py) - - if [ $? -ne 0 ]; then - echo "get_testing_resources failed. Failed to acquire credentials or test resources." - exit 1 - fi - - # Save current credentials for account reset later - echo "CI_ACCESS_ROLE_AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" >> $GITHUB_ENV - echo "CI_ACCESS_ROLE_AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" >> $GITHUB_ENV - echo "CI_ACCESS_ROLE_AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN" >> $GITHUB_ENV - - # Set test credentials - echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV - echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV - echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV - echo "TASK_TOKEN=$(echo "$test_env_var" | jq -j ".taskToken")" >> $GITHUB_ENV - echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV - echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV - echo "AWS_KMS_KEY=$(echo "$test_env_var" | jq -j ".TestKMSKeyArn")" >> $GITHUB_ENV - echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV - echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV - - name: Setup Finch runtime if: matrix.container_runtime == 'finch' run: | @@ -260,6 +233,31 @@ jobs: export CONTAINER_RUNTIME=${{ matrix.container_runtime }} make init + - name: Get testing resources and credentials + run: | + test_env_var=$(python3.9 tests/get_testing_resources.py) + + if [ $? -ne 0 ]; then + echo "get_testing_resources failed. Failed to acquire credentials or test resources." + exit 1 + fi + + # Save current credentials for account reset later + echo "CI_ACCESS_ROLE_AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" >> $GITHUB_ENV + echo "CI_ACCESS_ROLE_AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" >> $GITHUB_ENV + echo "CI_ACCESS_ROLE_AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN" >> $GITHUB_ENV + + # Set test credentials + echo "AWS_ACCESS_KEY_ID=$(echo "$test_env_var" | jq -j ".accessKeyID")" >> $GITHUB_ENV + echo "AWS_SECRET_ACCESS_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey")" >> $GITHUB_ENV + echo "AWS_SESSION_TOKEN=$(echo "$test_env_var" | jq -j ".sessionToken")" >> $GITHUB_ENV + echo "TASK_TOKEN=$(echo "$test_env_var" | jq -j ".taskToken")" >> $GITHUB_ENV + echo "AWS_S3_TESTING=$(echo "$test_env_var" | jq -j ".TestBucketName")" >> $GITHUB_ENV + echo "AWS_ECR_TESTING=$(echo "$test_env_var" | jq -j ".TestECRURI")" >> $GITHUB_ENV + echo "AWS_KMS_KEY=$(echo "$test_env_var" | jq -j ".TestKMSKeyArn")" >> $GITHUB_ENV + echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV + echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV + - name: Run tests run: | export CONTAINER_RUNTIME=${{ matrix.container_runtime }} From 76de15bc4580029e851097df002c4eadbbc94bd8 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 23 Oct 2025 17:59:05 -0700 Subject: [PATCH 16/54] test --- .github/workflows/integration-tests.yml | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index f3361fb5aeb..ccb887ed3db 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -33,16 +33,16 @@ jobs: # container_runtime: [docker, finch] container_runtime: [docker] test_suite: - - build-integ - - build-integ-java-python-provided - - build-integ-arm64 - - build-integ-arm64-java - - terraform-build - - package-delete-deploy + #- build-integ + #- build-integ-java-python-provided + #- build-integ-arm64 + #- build-integ-arm64-java + #- terraform-build + #- package-delete-deploy - sync - - local-invoke - - local-start - - other-and-e2e + #- local-invoke + #- local-start + #- other-and-e2e steps: - name: Checkout code @@ -257,6 +257,12 @@ jobs: echo "AWS_KMS_KEY=$(echo "$test_env_var" | jq -j ".TestKMSKeyArn")" >> $GITHUB_ENV echo "AWS_SIGNING_PROFILE_NAME=$(echo "$test_env_var" | jq -j ".TestSigningProfileName")" >> $GITHUB_ENV echo "AWS_SIGNING_PROFILE_VERSION_ARN=$(echo "$test_env_var" | jq -j ".TestSigningProfileARN")" >> $GITHUB_ENV + + # Display first 6 characters of credentials for verification + ACCESS_KEY=$(echo "$test_env_var" | jq -j ".accessKeyID") + SECRET_KEY=$(echo "$test_env_var" | jq -j ".secretAccessKey") + echo "AWS_ACCESS_KEY_ID (first 6 chars): ${ACCESS_KEY:0:6}..." + echo "AWS_SECRET_ACCESS_KEY (first 6 chars): ${SECRET_KEY:0:6}..." - name: Run tests run: | From d0782de9d21f1e6f19235e06681ea3e6d395c568 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Tue, 28 Oct 2025 15:46:03 -0700 Subject: [PATCH 17/54] use maven version --- .github/workflows/integration-tests.yml | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index ccb887ed3db..9e50eb990ba 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -14,7 +14,7 @@ env: SAM_CLI_DEV: 1 SAM_CLI_TELEMETRY: 0 SAM_CLI_CONTAINER_CONNECTION_TIMEOUT: 60 - NODE_VERSION: "18.18.2" + NODE_VERSION: "22.21.1" CARGO_LAMBDA_VERSION: "v0.17.1" NOSE_PARAMETERIZED_NO_WARN: 1 GITHUB_ACTIONS_INTEG: true @@ -56,7 +56,6 @@ jobs: # Run cleanup in background to not block workflow nohup bash -c ' sudo apt-get clean - sudo rm -rf /usr/share/dotnet sudo rm -rf /usr/local/lib/android sudo rm -rf /opt/ghc sudo rm -rf /opt/hostedtoolcache/CodeQL @@ -97,17 +96,30 @@ jobs: if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) uses: actions/setup-go@v5 with: - go-version: '1.19' + go-version: '1.25' - name: Install Maven and Gradle if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64", "build-integ-arm64-java"]'), matrix.test_suite) run: | + # Remove system Maven if it exists + sudo apt-get remove -y maven || true + + # Install Maven 3.9.11 wget https://dlcdn.apache.org/maven/maven-3/3.9.11/binaries/apache-maven-3.9.11-bin.zip -P /tmp sudo unzip -d /opt/mvn /tmp/apache-maven-*.zip - echo "/opt/mvn/apache-maven-3.9.11/bin" >> $GITHUB_PATH + + # Install Gradle 9.0.0 wget https://services.gradle.org/distributions/gradle-9.0.0-bin.zip -P /tmp sudo unzip -d /opt/gradle /tmp/gradle-*.zip + + # Add to PATH (prepend to ensure our versions are used first) + echo "/opt/mvn/apache-maven-3.9.11/bin" >> $GITHUB_PATH echo "/opt/gradle/gradle-9.0.0/bin" >> $GITHUB_PATH + + # Verify versions + export PATH="/opt/mvn/apache-maven-3.9.11/bin:/opt/gradle/gradle-9.0.0/bin:$PATH" + mvn --version + gradle --version - name: Install .NET 8 SDK if: contains(fromJSON('["build-integ", "build-integ-arm64"]'), matrix.test_suite) @@ -288,7 +300,7 @@ jobs: pytest -vv tests/integration/package tests/integration/delete tests/integration/deploy --dist=loadgroup -n 4 --reruns 4 --json-report --json-report-file=TEST_REPORT-integration-package-delete-deploy-${{ matrix.container_runtime }}.json ;; "sync") - pytest -vv tests/integration/sync -n 3 --reruns 3 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json + pytest -vv tests/integration/sync -n 6 --reruns 3 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json ;; "local-invoke") pytest -vv --reruns 3 tests/integration/local/invoke tests/integration/local/generate_event --json-report --json-report-file=TEST_REPORT-integration-local-invoke-${{ matrix.container_runtime }}.json From 5f682a69c5de8a953914385cca10fa2351ba88fd Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Tue, 28 Oct 2025 17:29:19 -0700 Subject: [PATCH 18/54] use original function --- .github/workflows/integration-tests.yml | 14 ++++++++++---- tests/get_testing_resources.py | 15 ++++++++++++--- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 9e50eb990ba..b7f30a21819 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -20,7 +20,7 @@ env: GITHUB_ACTIONS_INTEG: true BY_CANARY: true UV_PYTHON: python3.9 - CREDENTIAL_DISTRIBUTION_LAMBDA_ARN: arn:aws:lambda:us-west-2:123087993316:function:test-account-management-CredentialDistributionLamb-7CwJ4B8P4hth + CREDENTIAL_DISTRIBUTION_LAMBDA_ARN: arn:aws:lambda:us-west-2:123087993316:function:test-account-management-CredentialDistributionLamb-o1sEaa8lvO1L ACCOUNT_RESET_LAMBDA_ARN: arn:aws:lambda:us-west-2:123087993316:function:test-account-management-AccountResetLambdaFunction-nBZDo6oLCH80 jobs: @@ -247,11 +247,17 @@ jobs: - name: Get testing resources and credentials run: | - test_env_var=$(python3.9 tests/get_testing_resources.py) + # Try with skip_role_deletion parameter first + test_env_var=$(python3.9 tests/get_testing_resources.py skip_role_deletion 2>&1) if [ $? -ne 0 ]; then - echo "get_testing_resources failed. Failed to acquire credentials or test resources." - exit 1 + echo "First attempt with skip_role_deletion failed, trying without parameter..." + test_env_var=$(python3.9 tests/get_testing_resources.py) + + if [ $? -ne 0 ]; then + echo "get_testing_resources failed. Failed to acquire credentials or test resources." + exit 1 + fi fi # Save current credentials for account reset later diff --git a/tests/get_testing_resources.py b/tests/get_testing_resources.py index c91a79fd77c..581e924deb0 100644 --- a/tests/get_testing_resources.py +++ b/tests/get_testing_resources.py @@ -5,6 +5,7 @@ import json import os +import sys import boto3 from boto3.session import Session @@ -16,7 +17,8 @@ def main(): - env_vars = get_testing_credentials() + skip_role_deletion = len(sys.argv) > 1 and sys.argv[1] == "skip_role_deletion" + env_vars = get_testing_credentials(skip_role_deletion) # Assume testing account credential in order to access managed test resource stack test_session = Session( aws_access_key_id=env_vars["accessKeyID"], @@ -37,7 +39,7 @@ def get_managed_test_resource_outputs(session: Session): return outputs_dict -def get_testing_credentials(): +def get_testing_credentials(skip_role_deletion=False): lambda_arn = os.environ["CREDENTIAL_DISTRIBUTION_LAMBDA_ARN"] # Max attempts to 0 so that boto3 will not invoke multiple times lambda_client = boto3.client( @@ -49,7 +51,14 @@ def get_testing_credentials(): ), region_name="us-west-2", ) - response = lambda_client.invoke(FunctionName=lambda_arn) + + # Prepare payload if skip_role_deletion is True + if skip_role_deletion: + payload_data = json.dumps({"skip_role_deletion": True}) + response = lambda_client.invoke(FunctionName=lambda_arn, Payload=payload_data) + else: + response = lambda_client.invoke(FunctionName=lambda_arn) + payload = json.loads(response["Payload"].read()) if response.get("FunctionError"): raise ValueError(f"Failed to get credential. {payload['errorType']}") From 8a13551fdda64c82634a324c1577df008138becd Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 09:36:40 -0700 Subject: [PATCH 19/54] nit --- .github/workflows/integration-tests.yml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index b7f30a21819..69d77c22e0b 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -127,17 +127,18 @@ jobs: with: dotnet-version: '8.0.x' - - name: Set up Ruby 3.2.7 + - name: Set up Ruby 3.3.7 if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) uses: ruby/setup-ruby@v1 with: - ruby-version: '3.2.7' + ruby-version: '3.3.7' - - name: Set up Ruby 3.3.7 + - name: Set up Ruby 3.2.7 if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) uses: ruby/setup-ruby@v1 with: - ruby-version: '3.3.7' + ruby-version: '3.2.7' + - name: Set up Ruby 3.4.2 if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) @@ -145,11 +146,6 @@ jobs: with: ruby-version: '3.4.2' - - name: Set Ruby 3.3.7 as global - if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) - run: | - echo "$(ruby-3.3.7 -e 'puts RbConfig::CONFIG["bindir"]')" >> $GITHUB_PATH - ruby --version - name: Install Rust toolchain if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) @@ -284,8 +280,14 @@ jobs: - name: Run tests run: | + # Set up PATH like AppVeyor does + export PATH="/opt/mvn/apache-maven-3.9.11/bin:/opt/gradle/gradle-9.0.0/bin:$PATH" export CONTAINER_RUNTIME=${{ matrix.container_runtime }} + # Verify Maven version before running tests + which mvn + mvn --version + case "${{ matrix.test_suite }}" in "build-integ") pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json From de07739c2a89ad463557d64f09e0c7e5f91a03fa Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 09:46:00 -0700 Subject: [PATCH 20/54] check ruby issue --- .github/workflows/integration-tests.yml | 5 +- tests/integration/sync/test_sync_infra.py | 880 +++++++++++----------- 2 files changed, 443 insertions(+), 442 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 69d77c22e0b..b3035e90a65 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -127,6 +127,7 @@ jobs: with: dotnet-version: '8.0.x' + # sync test only need ruby 3.3.7 - name: Set up Ruby 3.3.7 if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) uses: ruby/setup-ruby@v1 @@ -134,14 +135,14 @@ jobs: ruby-version: '3.3.7' - name: Set up Ruby 3.2.7 - if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) + if: contains(fromJSON('["build-integ", "build-integ-arm64", "other-and-e2e"]'), matrix.test_suite) uses: ruby/setup-ruby@v1 with: ruby-version: '3.2.7' - name: Set up Ruby 3.4.2 - if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) + if: contains(fromJSON('["build-integ", "build-integ-arm64", "other-and-e2e"]'), matrix.test_suite) uses: ruby/setup-ruby@v1 with: ruby-version: '3.4.2' diff --git a/tests/integration/sync/test_sync_infra.py b/tests/integration/sync/test_sync_infra.py index da4d304b8df..ef10ace3052 100644 --- a/tests/integration/sync/test_sync_infra.py +++ b/tests/integration/sync/test_sync_infra.py @@ -145,443 +145,443 @@ def test_sync_infra(self, runtime, use_container): else: self._verify_infra_changes(self.stack_resources) - @parameterized.expand([["python", False], ["python", True]]) - @pytest.mark.flaky(reruns=3) - def test_sync_infra_auto_skip(self, runtime, use_container): - template_before = f"infra/template-{runtime}-before.yaml" - template_path = str(self.test_data_path.joinpath(template_before)) - stack_name = self._method_to_stack_name(self.id()) - self.stacks.append({"name": stack_name}) - - # Run infra sync - sync_command_list = self.get_sync_command_list( - template_file=template_path, - code=False, - watch=False, - dependency_layer=self.dependency_layer, - stack_name=stack_name, - parameter_overrides=self.parameter_overrides, - image_repository=self.ecr_repo_name, - s3_prefix=self.s3_prefix, - kms_key_id=self.kms_key, - tags="integ=true clarity=yes foo_bar=baz", - use_container=use_container, - ) - - sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) - self.assertEqual(sync_process_execute.process.returncode, 0) - self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) - - template_after = f"infra/template-{runtime}-auto-skip.yaml" - template_path = str(self.test_data_path.joinpath(template_after)) - - # Run infra sync - sync_command_list = self.get_sync_command_list( - template_file=template_path, - code=False, - watch=False, - dependency_layer=self.dependency_layer, - stack_name=stack_name, - parameter_overrides=self.parameter_overrides, - image_repository=self.ecr_repo_name, - s3_prefix=self.s3_prefix, - kms_key_id=self.kms_key, - tags="integ=true clarity=yes foo_bar=baz", - use_container=use_container, - ) - - sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) - self.assertEqual(sync_process_execute.process.returncode, 0) - self.assertIn( - "Template haven't been changed since last deployment, skipping infra sync...", - str(sync_process_execute.stderr), - ) - self.assertIn( - "Queuing up code sync for the resources that require an update", - str(sync_process_execute.stderr), - ) - - # CFN Api call here to collect all the stack resources - self.stack_resources = self._get_stacks(stack_name) - # Lambda Api call here, which tests both the python function and the layer - self._verify_infra_changes(self.stack_resources) - - @parameterized.expand([["python", False], ["python", True]]) - @pytest.mark.flaky(reruns=3) - def test_sync_infra_auto_skip_nested(self, runtime, use_container): - template_before = str(Path("infra", "parent-stack.yaml")) - template_path = str(self.test_data_path.joinpath(template_before)) - - stack_name = self._method_to_stack_name(self.id()) - self.stacks.append({"name": stack_name}) - - # Run infra sync - sync_command_list = self.get_sync_command_list( - template_file=template_path, - code=False, - watch=False, - dependency_layer=self.dependency_layer, - stack_name=stack_name, - parameter_overrides=self.parameter_overrides, - image_repository=self.ecr_repo_name, - s3_prefix=self.s3_prefix, - kms_key_id=self.kms_key, - tags="integ=true clarity=yes foo_bar=baz", - use_container=use_container, - ) - - sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) - self.assertEqual(sync_process_execute.process.returncode, 0) - self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) - - self.update_file( - self.test_data_path.joinpath("infra", f"template-{runtime}-auto-skip.yaml"), - self.test_data_path.joinpath("infra", f"template-{runtime}-before.yaml"), - ) - - sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) - self.assertEqual(sync_process_execute.process.returncode, 0) - self.assertIn( - "Template haven't been changed since last deployment, skipping infra sync...", - str(sync_process_execute.stderr), - ) - self.assertIn( - "Queuing up code sync for the resources that require an update", - str(sync_process_execute.stderr), - ) - - # CFN Api call here to collect all the stack resources - self.stack_resources = self._get_stacks(stack_name) - # Lambda Api call here, which tests both the python function and the layer - self._verify_infra_changes(self.stack_resources) - - @parameterized.expand(["infra/template-python-before.yaml"]) - def test_sync_infra_no_confirm(self, template_file): - template_path = str(self.test_data_path.joinpath(template_file)) - stack_name = self._method_to_stack_name(self.id()) - - # Run infra sync - sync_command_list = self.get_sync_command_list( - template_file=template_path, - code=False, - watch=False, - dependency_layer=self.dependency_layer, - stack_name=stack_name, - parameter_overrides=self.parameter_overrides, - image_repository=self.ecr_repo_name, - s3_prefix=self.s3_prefix, - kms_key_id=self.kms_key, - tags="integ=true clarity=yes foo_bar=baz", - ) - sync_process_execute = run_command_with_input(sync_command_list, "n\n".encode(), cwd=self.test_data_path) - - self.assertEqual(sync_process_execute.process.returncode, 0) - self.assertNotIn("Build Succeeded", str(sync_process_execute.stderr)) - - @parameterized.expand(["infra/template-python-before.yaml"]) - def test_sync_infra_no_stack_name(self, template_file): - template_path = str(self.test_data_path.joinpath(template_file)) - - # Run infra sync - sync_command_list = self.get_sync_command_list( - template_file=template_path, - code=False, - watch=False, - dependency_layer=self.dependency_layer, - parameter_overrides=self.parameter_overrides, - image_repository=self.ecr_repo_name, - s3_prefix=self.s3_prefix, - kms_key_id=self.kms_key, - tags="integ=true clarity=yes foo_bar=baz", - ) - - sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) - self.assertEqual(sync_process_execute.process.returncode, 2) - self.assertIn("Error: Missing option '--stack-name'.", str(sync_process_execute.stderr)) - - @parameterized.expand(["infra/template-python-before.yaml"]) - def test_sync_infra_no_capabilities(self, template_file): - template_path = str(self.test_data_path.joinpath(template_file)) - stack_name = self._method_to_stack_name(self.id()) - self.stacks.append({"name": stack_name}) - - # Run infra sync - sync_command_list = self.get_sync_command_list( - template_file=template_path, - code=False, - watch=False, - dependency_layer=self.dependency_layer, - stack_name=stack_name, - parameter_overrides=self.parameter_overrides, - image_repository=self.ecr_repo_name, - s3_prefix=self.s3_prefix, - kms_key_id=self.kms_key, - capabilities="CAPABILITY_IAM", - tags="integ=true clarity=yes foo_bar=baz", - ) - - sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) - self.assertEqual(sync_process_execute.process.returncode, 1) - self.assertIn( - "An error occurred (InsufficientCapabilitiesException) when calling the CreateStack operation: \ -Requires capabilities : [CAPABILITY_AUTO_EXPAND]", - str(sync_process_execute.stderr), - ) - - @parameterized.expand(["infra/template-python-before.yaml"]) - def test_sync_infra_s3_bucket_option(self, template_file): - template_path = str(self.test_data_path.joinpath(template_file)) - stack_name = self._method_to_stack_name(self.id()) - - sync_command_list = self.get_sync_command_list( - template_file=template_path, - code=False, - watch=False, - dependency_layer=self.dependency_layer, - stack_name=stack_name, - parameter_overrides=self.parameter_overrides, - image_repository=self.ecr_repo_name, - s3_bucket=self.bucket_name, - s3_prefix=self.s3_prefix, - kms_key_id=self.kms_key, - capabilities_list=["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"], - tags="integ=true clarity=yes foo_bar=baz", - ) - - sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) - self.assertEqual(sync_process_execute.process.returncode, 0) - self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) - - # Make sure all resources are created properly after specifying custom bucket - # CFN Api call here to collect all the stack resources - self.stack_resources = self._get_stacks(stack_name) - - # Lambda Api call here, which tests both the python function and the layer - lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) - for lambda_function in lambda_functions: - lambda_response = json.loads(self._get_lambda_response(lambda_function)) - self.assertIn("extra_message", lambda_response) - self.assertEqual(lambda_response.get("message"), "7") - - # ApiGateway Api call here, which tests both of the RestApi - rest_api = self.stack_resources.get(AWS_APIGATEWAY_RESTAPI)[0] - self.assertEqual(self._get_api_message(rest_api), '{"message": "hello 1"}') - - # SFN Api call here, which tests the StateMachine - state_machine = self.stack_resources.get(AWS_STEPFUNCTIONS_STATEMACHINE)[0] - self.assertEqual(self._get_sfn_response(state_machine), '"World 1"') - - -@skipIf(SKIP_SYNC_TESTS, "Skip sync tests in CI/CD only") -class TestSyncInfraCDKTemplates(SyncIntegBase): - dependency_layer = None - - @parameterized.expand( - [ - ( - "cdk_v1_synthesized_template_zip_functions.json", - "cdk_v1_synthesized_template_zip_functions_after.json", - None, - False, - ), - ( - "cdk_v1_synthesized_template_zip_functions.json", - "cdk_v1_synthesized_template_zip_functions_after.json", - None, - True, - ), - ( - "cdk_v1_synthesized_template_Level1_nested_zip_functions.json", - "cdk_v1_synthesized_template_Level1_nested_zip_functions_after.json", - None, - False, - ), - ( - "cdk_v1_synthesized_template_image_functions.json", - "cdk_v1_synthesized_template_image_functions_after.json", - "ColorsRandomFunctionF61B9209", - False, - ), - ( - "cdk_v1_synthesized_template_image_functions.json", - "cdk_v1_synthesized_template_image_functions_after.json", - "ColorsRandomFunction", - False, - ), - ( - "cdk_v1_synthesized_template_Level1_nested_image_functions.json", - "cdk_v1_synthesized_template_Level1_nested_image_functions_after.json", - "ColorsRandomFunctionF61B9209", - False, - ), - ( - "cdk_v1_synthesized_template_Level1_nested_image_functions.json", - "cdk_v1_synthesized_template_Level1_nested_image_functions_after.json", - "ColorsRandomFunction", - False, - ), - ( - "cdk_v1_synthesized_template_Level1_nested_image_functions.json", - "cdk_v1_synthesized_template_Level1_nested_image_functions_after.json", - "Level1Stack/Level2Stack/ColorsRandomFunction", - False, - ), - ] - ) - def test_cdk_templates(self, template_file, template_after, function_id, dependency_layer): - repository = "" - if function_id: - repository = f"{function_id}={self.ecr_repo_name}" - template_path = str(self.test_data_path.joinpath("infra/cdk").joinpath(template_file)) - stack_name = self._method_to_stack_name(self.id()) - self.stacks.append({"name": stack_name}) - - # Run infra sync - sync_command_list = self.get_sync_command_list( - template_file=template_path, - code=False, - watch=False, - dependency_layer=dependency_layer, - stack_name=stack_name, - image_repositories=repository, - s3_prefix=self.s3_prefix, - kms_key_id=self.kms_key, - tags="integ=true clarity=yes foo_bar=baz", - ) - sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) - self.assertEqual(sync_process_execute.process.returncode, 0) - self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) - - # CFN Api call here to collect all the stack resources - self.stack_resources = self._get_stacks(stack_name) - # Lambda Api call here, which tests both the python function and the layer - lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) - for lambda_function in lambda_functions: - lambda_response = json.loads(self._get_lambda_response(lambda_function)) - self.assertIn("extra_message", lambda_response) - self.assertEqual(lambda_response.get("message"), "7") - - template_path = str(self.test_data_path.joinpath("infra/cdk").joinpath(template_after)) - - after_asset_path = self.test_data_path.joinpath("infra/cdk").joinpath( - "after/asset.6598609927b272b36fdf01072092f9851ddcd1b41ba294f736ce77091f5cc456" - ) - layer_method_file = str(after_asset_path.joinpath("layer_method.py")) - main_file = str(after_asset_path.joinpath("main.py")) - - # touch layer_method_file and main_file - Path(layer_method_file).touch() - Path(main_file).touch() - - # Run infra sync - sync_command_list = self.get_sync_command_list( - template_file=template_path, - code=False, - watch=False, - dependency_layer=dependency_layer, - stack_name=stack_name, - image_repositories=repository, - s3_prefix=self.s3_prefix, - kms_key_id=self.kms_key, - tags="integ=true clarity=yes foo_bar=baz", - ) - - sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) - self.assertEqual(sync_process_execute.process.returncode, 0) - self.assertIn("Stack update succeeded. Sync infra completed.", str(sync_process_execute.stderr)) - - # CFN Api call here to collect all the stack resources - self.stack_resources = self._get_stacks(stack_name) - # Lambda Api call here, which tests both the python function and the layer - lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) - for lambda_function in lambda_functions: - lambda_response = json.loads(self._get_lambda_response(lambda_function)) - self.assertIn("extra_message", lambda_response) - self.assertEqual(lambda_response.get("message"), "9") - - -@skipIf(SKIP_SYNC_TESTS, "Skip sync tests in CI/CD only") -@parameterized_class([{"dependency_layer": True}, {"dependency_layer": False}]) -class TestSyncInfraWithJava(SyncIntegBase): - ecr_repo_name = None - kms_key = None - parameter_overrides: Dict[str, str] = {} - - @classmethod - def setUpClass(cls) -> None: - super().setUpClass() - cls.parameter_overrides = {"HelloWorldLayerName": f"HelloWorldLayer-{uuid.uuid4().hex}"[:140]} - - @parameterized.expand(["infra/template-java.yaml"]) - def test_sync_infra_with_java(self, template_file): - """This will test a case where user will flip ADL flag between sync sessions""" - template_path = str(self.test_data_path.joinpath(template_file)) - stack_name = self._method_to_stack_name(self.id()) - self.stacks.append({"name": stack_name}) - - # first run with current dependency layer value - self._run_sync_and_validate_lambda_call(self.dependency_layer, template_path, stack_name) - - # now flip the dependency layer value and re-run the sync & tests - self._run_sync_and_validate_lambda_call(not self.dependency_layer, template_path, stack_name) - - def _run_sync_and_validate_lambda_call(self, dependency_layer: bool, template_path: str, stack_name: str) -> None: - # Run infra sync - sync_command_list = self.get_sync_command_list( - template_file=template_path, - code=False, - watch=False, - dependency_layer=dependency_layer, - stack_name=stack_name, - parameter_overrides=self.parameter_overrides, - image_repository=self.ecr_repo_name, - s3_prefix=self.s3_prefix, - kms_key_id=self.kms_key, - capabilities_list=["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"], - tags="integ=true clarity=yes foo_bar=baz", - ) - sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) - self.assertEqual(sync_process_execute.process.returncode, 0) - self.assertIn("Sync infra completed.", str(sync_process_execute.stderr)) - - self.stack_resources = self._get_stacks(stack_name) - lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) - for lambda_function in lambda_functions: - lambda_response = json.loads(self._get_lambda_response(lambda_function)) - self.assertIn("message", lambda_response) - self.assertIn("sum", lambda_response) - self.assertEqual(lambda_response.get("message"), "hello world") - self.assertEqual(lambda_response.get("sum"), 12) - - -@skipIf(SKIP_SYNC_TESTS, "Skip sync tests in CI/CD only") -class TestSyncInfraWithEsbuild(SyncIntegBase): - dependency_layer = False - - @parameterized.expand(["code/before/template-esbuild.yaml"]) - def test_sync_infra_esbuild(self, template_file): - template_path = str(self.test_data_path.joinpath(template_file)) - stack_name = self._method_to_stack_name(self.id()) - self.stacks.append({"name": stack_name}) - - sync_command_list = self.get_sync_command_list( - template_file=template_path, - code=False, - watch=False, - dependency_layer=self.dependency_layer, - stack_name=stack_name, - image_repository=self.ecr_repo_name, - s3_prefix=self.s3_prefix, - kms_key_id=self.kms_key, - capabilities_list=["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"], - tags="integ=true clarity=yes foo_bar=baz", - ) - sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) - self.assertEqual(sync_process_execute.process.returncode, 0) - self.assertIn("Sync infra completed.", str(sync_process_execute.stderr)) - - self.stack_resources = self._get_stacks(stack_name) - lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) - for lambda_function in lambda_functions: - lambda_response = json.loads(self._get_lambda_response(lambda_function)) - self.assertEqual(lambda_response.get("message"), "hello world") +# @parameterized.expand([["python", False], ["python", True]]) +# @pytest.mark.flaky(reruns=3) +# def test_sync_infra_auto_skip(self, runtime, use_container): +# template_before = f"infra/template-{runtime}-before.yaml" +# template_path = str(self.test_data_path.joinpath(template_before)) +# stack_name = self._method_to_stack_name(self.id()) +# self.stacks.append({"name": stack_name}) + +# # Run infra sync +# sync_command_list = self.get_sync_command_list( +# template_file=template_path, +# code=False, +# watch=False, +# dependency_layer=self.dependency_layer, +# stack_name=stack_name, +# parameter_overrides=self.parameter_overrides, +# image_repository=self.ecr_repo_name, +# s3_prefix=self.s3_prefix, +# kms_key_id=self.kms_key, +# tags="integ=true clarity=yes foo_bar=baz", +# use_container=use_container, +# ) + +# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) +# self.assertEqual(sync_process_execute.process.returncode, 0) +# self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) + +# template_after = f"infra/template-{runtime}-auto-skip.yaml" +# template_path = str(self.test_data_path.joinpath(template_after)) + +# # Run infra sync +# sync_command_list = self.get_sync_command_list( +# template_file=template_path, +# code=False, +# watch=False, +# dependency_layer=self.dependency_layer, +# stack_name=stack_name, +# parameter_overrides=self.parameter_overrides, +# image_repository=self.ecr_repo_name, +# s3_prefix=self.s3_prefix, +# kms_key_id=self.kms_key, +# tags="integ=true clarity=yes foo_bar=baz", +# use_container=use_container, +# ) + +# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) +# self.assertEqual(sync_process_execute.process.returncode, 0) +# self.assertIn( +# "Template haven't been changed since last deployment, skipping infra sync...", +# str(sync_process_execute.stderr), +# ) +# self.assertIn( +# "Queuing up code sync for the resources that require an update", +# str(sync_process_execute.stderr), +# ) + +# # CFN Api call here to collect all the stack resources +# self.stack_resources = self._get_stacks(stack_name) +# # Lambda Api call here, which tests both the python function and the layer +# self._verify_infra_changes(self.stack_resources) + +# @parameterized.expand([["python", False], ["python", True]]) +# @pytest.mark.flaky(reruns=3) +# def test_sync_infra_auto_skip_nested(self, runtime, use_container): +# template_before = str(Path("infra", "parent-stack.yaml")) +# template_path = str(self.test_data_path.joinpath(template_before)) + +# stack_name = self._method_to_stack_name(self.id()) +# self.stacks.append({"name": stack_name}) + +# # Run infra sync +# sync_command_list = self.get_sync_command_list( +# template_file=template_path, +# code=False, +# watch=False, +# dependency_layer=self.dependency_layer, +# stack_name=stack_name, +# parameter_overrides=self.parameter_overrides, +# image_repository=self.ecr_repo_name, +# s3_prefix=self.s3_prefix, +# kms_key_id=self.kms_key, +# tags="integ=true clarity=yes foo_bar=baz", +# use_container=use_container, +# ) + +# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) +# self.assertEqual(sync_process_execute.process.returncode, 0) +# self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) + +# self.update_file( +# self.test_data_path.joinpath("infra", f"template-{runtime}-auto-skip.yaml"), +# self.test_data_path.joinpath("infra", f"template-{runtime}-before.yaml"), +# ) + +# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) +# self.assertEqual(sync_process_execute.process.returncode, 0) +# self.assertIn( +# "Template haven't been changed since last deployment, skipping infra sync...", +# str(sync_process_execute.stderr), +# ) +# self.assertIn( +# "Queuing up code sync for the resources that require an update", +# str(sync_process_execute.stderr), +# ) + +# # CFN Api call here to collect all the stack resources +# self.stack_resources = self._get_stacks(stack_name) +# # Lambda Api call here, which tests both the python function and the layer +# self._verify_infra_changes(self.stack_resources) + +# @parameterized.expand(["infra/template-python-before.yaml"]) +# def test_sync_infra_no_confirm(self, template_file): +# template_path = str(self.test_data_path.joinpath(template_file)) +# stack_name = self._method_to_stack_name(self.id()) + +# # Run infra sync +# sync_command_list = self.get_sync_command_list( +# template_file=template_path, +# code=False, +# watch=False, +# dependency_layer=self.dependency_layer, +# stack_name=stack_name, +# parameter_overrides=self.parameter_overrides, +# image_repository=self.ecr_repo_name, +# s3_prefix=self.s3_prefix, +# kms_key_id=self.kms_key, +# tags="integ=true clarity=yes foo_bar=baz", +# ) +# sync_process_execute = run_command_with_input(sync_command_list, "n\n".encode(), cwd=self.test_data_path) + +# self.assertEqual(sync_process_execute.process.returncode, 0) +# self.assertNotIn("Build Succeeded", str(sync_process_execute.stderr)) + +# @parameterized.expand(["infra/template-python-before.yaml"]) +# def test_sync_infra_no_stack_name(self, template_file): +# template_path = str(self.test_data_path.joinpath(template_file)) + +# # Run infra sync +# sync_command_list = self.get_sync_command_list( +# template_file=template_path, +# code=False, +# watch=False, +# dependency_layer=self.dependency_layer, +# parameter_overrides=self.parameter_overrides, +# image_repository=self.ecr_repo_name, +# s3_prefix=self.s3_prefix, +# kms_key_id=self.kms_key, +# tags="integ=true clarity=yes foo_bar=baz", +# ) + +# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) +# self.assertEqual(sync_process_execute.process.returncode, 2) +# self.assertIn("Error: Missing option '--stack-name'.", str(sync_process_execute.stderr)) + +# @parameterized.expand(["infra/template-python-before.yaml"]) +# def test_sync_infra_no_capabilities(self, template_file): +# template_path = str(self.test_data_path.joinpath(template_file)) +# stack_name = self._method_to_stack_name(self.id()) +# self.stacks.append({"name": stack_name}) + +# # Run infra sync +# sync_command_list = self.get_sync_command_list( +# template_file=template_path, +# code=False, +# watch=False, +# dependency_layer=self.dependency_layer, +# stack_name=stack_name, +# parameter_overrides=self.parameter_overrides, +# image_repository=self.ecr_repo_name, +# s3_prefix=self.s3_prefix, +# kms_key_id=self.kms_key, +# capabilities="CAPABILITY_IAM", +# tags="integ=true clarity=yes foo_bar=baz", +# ) + +# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) +# self.assertEqual(sync_process_execute.process.returncode, 1) +# self.assertIn( +# "An error occurred (InsufficientCapabilitiesException) when calling the CreateStack operation: \ +# Requires capabilities : [CAPABILITY_AUTO_EXPAND]", +# str(sync_process_execute.stderr), +# ) + +# @parameterized.expand(["infra/template-python-before.yaml"]) +# def test_sync_infra_s3_bucket_option(self, template_file): +# template_path = str(self.test_data_path.joinpath(template_file)) +# stack_name = self._method_to_stack_name(self.id()) + +# sync_command_list = self.get_sync_command_list( +# template_file=template_path, +# code=False, +# watch=False, +# dependency_layer=self.dependency_layer, +# stack_name=stack_name, +# parameter_overrides=self.parameter_overrides, +# image_repository=self.ecr_repo_name, +# s3_bucket=self.bucket_name, +# s3_prefix=self.s3_prefix, +# kms_key_id=self.kms_key, +# capabilities_list=["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"], +# tags="integ=true clarity=yes foo_bar=baz", +# ) + +# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) +# self.assertEqual(sync_process_execute.process.returncode, 0) +# self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) + +# # Make sure all resources are created properly after specifying custom bucket +# # CFN Api call here to collect all the stack resources +# self.stack_resources = self._get_stacks(stack_name) + +# # Lambda Api call here, which tests both the python function and the layer +# lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) +# for lambda_function in lambda_functions: +# lambda_response = json.loads(self._get_lambda_response(lambda_function)) +# self.assertIn("extra_message", lambda_response) +# self.assertEqual(lambda_response.get("message"), "7") + +# # ApiGateway Api call here, which tests both of the RestApi +# rest_api = self.stack_resources.get(AWS_APIGATEWAY_RESTAPI)[0] +# self.assertEqual(self._get_api_message(rest_api), '{"message": "hello 1"}') + +# # SFN Api call here, which tests the StateMachine +# state_machine = self.stack_resources.get(AWS_STEPFUNCTIONS_STATEMACHINE)[0] +# self.assertEqual(self._get_sfn_response(state_machine), '"World 1"') + + +# @skipIf(SKIP_SYNC_TESTS, "Skip sync tests in CI/CD only") +# class TestSyncInfraCDKTemplates(SyncIntegBase): +# dependency_layer = None + +# @parameterized.expand( +# [ +# ( +# "cdk_v1_synthesized_template_zip_functions.json", +# "cdk_v1_synthesized_template_zip_functions_after.json", +# None, +# False, +# ), +# ( +# "cdk_v1_synthesized_template_zip_functions.json", +# "cdk_v1_synthesized_template_zip_functions_after.json", +# None, +# True, +# ), +# ( +# "cdk_v1_synthesized_template_Level1_nested_zip_functions.json", +# "cdk_v1_synthesized_template_Level1_nested_zip_functions_after.json", +# None, +# False, +# ), +# ( +# "cdk_v1_synthesized_template_image_functions.json", +# "cdk_v1_synthesized_template_image_functions_after.json", +# "ColorsRandomFunctionF61B9209", +# False, +# ), +# ( +# "cdk_v1_synthesized_template_image_functions.json", +# "cdk_v1_synthesized_template_image_functions_after.json", +# "ColorsRandomFunction", +# False, +# ), +# ( +# "cdk_v1_synthesized_template_Level1_nested_image_functions.json", +# "cdk_v1_synthesized_template_Level1_nested_image_functions_after.json", +# "ColorsRandomFunctionF61B9209", +# False, +# ), +# ( +# "cdk_v1_synthesized_template_Level1_nested_image_functions.json", +# "cdk_v1_synthesized_template_Level1_nested_image_functions_after.json", +# "ColorsRandomFunction", +# False, +# ), +# ( +# "cdk_v1_synthesized_template_Level1_nested_image_functions.json", +# "cdk_v1_synthesized_template_Level1_nested_image_functions_after.json", +# "Level1Stack/Level2Stack/ColorsRandomFunction", +# False, +# ), +# ] +# ) +# def test_cdk_templates(self, template_file, template_after, function_id, dependency_layer): +# repository = "" +# if function_id: +# repository = f"{function_id}={self.ecr_repo_name}" +# template_path = str(self.test_data_path.joinpath("infra/cdk").joinpath(template_file)) +# stack_name = self._method_to_stack_name(self.id()) +# self.stacks.append({"name": stack_name}) + +# # Run infra sync +# sync_command_list = self.get_sync_command_list( +# template_file=template_path, +# code=False, +# watch=False, +# dependency_layer=dependency_layer, +# stack_name=stack_name, +# image_repositories=repository, +# s3_prefix=self.s3_prefix, +# kms_key_id=self.kms_key, +# tags="integ=true clarity=yes foo_bar=baz", +# ) +# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) +# self.assertEqual(sync_process_execute.process.returncode, 0) +# self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) + +# # CFN Api call here to collect all the stack resources +# self.stack_resources = self._get_stacks(stack_name) +# # Lambda Api call here, which tests both the python function and the layer +# lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) +# for lambda_function in lambda_functions: +# lambda_response = json.loads(self._get_lambda_response(lambda_function)) +# self.assertIn("extra_message", lambda_response) +# self.assertEqual(lambda_response.get("message"), "7") + +# template_path = str(self.test_data_path.joinpath("infra/cdk").joinpath(template_after)) + +# after_asset_path = self.test_data_path.joinpath("infra/cdk").joinpath( +# "after/asset.6598609927b272b36fdf01072092f9851ddcd1b41ba294f736ce77091f5cc456" +# ) +# layer_method_file = str(after_asset_path.joinpath("layer_method.py")) +# main_file = str(after_asset_path.joinpath("main.py")) + +# # touch layer_method_file and main_file +# Path(layer_method_file).touch() +# Path(main_file).touch() + +# # Run infra sync +# sync_command_list = self.get_sync_command_list( +# template_file=template_path, +# code=False, +# watch=False, +# dependency_layer=dependency_layer, +# stack_name=stack_name, +# image_repositories=repository, +# s3_prefix=self.s3_prefix, +# kms_key_id=self.kms_key, +# tags="integ=true clarity=yes foo_bar=baz", +# ) + +# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) +# self.assertEqual(sync_process_execute.process.returncode, 0) +# self.assertIn("Stack update succeeded. Sync infra completed.", str(sync_process_execute.stderr)) + +# # CFN Api call here to collect all the stack resources +# self.stack_resources = self._get_stacks(stack_name) +# # Lambda Api call here, which tests both the python function and the layer +# lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) +# for lambda_function in lambda_functions: +# lambda_response = json.loads(self._get_lambda_response(lambda_function)) +# self.assertIn("extra_message", lambda_response) +# self.assertEqual(lambda_response.get("message"), "9") + + +# @skipIf(SKIP_SYNC_TESTS, "Skip sync tests in CI/CD only") +# @parameterized_class([{"dependency_layer": True}, {"dependency_layer": False}]) +# class TestSyncInfraWithJava(SyncIntegBase): +# ecr_repo_name = None +# kms_key = None +# parameter_overrides: Dict[str, str] = {} + +# @classmethod +# def setUpClass(cls) -> None: +# super().setUpClass() +# cls.parameter_overrides = {"HelloWorldLayerName": f"HelloWorldLayer-{uuid.uuid4().hex}"[:140]} + +# @parameterized.expand(["infra/template-java.yaml"]) +# def test_sync_infra_with_java(self, template_file): +# """This will test a case where user will flip ADL flag between sync sessions""" +# template_path = str(self.test_data_path.joinpath(template_file)) +# stack_name = self._method_to_stack_name(self.id()) +# self.stacks.append({"name": stack_name}) + +# # first run with current dependency layer value +# self._run_sync_and_validate_lambda_call(self.dependency_layer, template_path, stack_name) + +# # now flip the dependency layer value and re-run the sync & tests +# self._run_sync_and_validate_lambda_call(not self.dependency_layer, template_path, stack_name) + +# def _run_sync_and_validate_lambda_call(self, dependency_layer: bool, template_path: str, stack_name: str) -> None: +# # Run infra sync +# sync_command_list = self.get_sync_command_list( +# template_file=template_path, +# code=False, +# watch=False, +# dependency_layer=dependency_layer, +# stack_name=stack_name, +# parameter_overrides=self.parameter_overrides, +# image_repository=self.ecr_repo_name, +# s3_prefix=self.s3_prefix, +# kms_key_id=self.kms_key, +# capabilities_list=["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"], +# tags="integ=true clarity=yes foo_bar=baz", +# ) +# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) +# self.assertEqual(sync_process_execute.process.returncode, 0) +# self.assertIn("Sync infra completed.", str(sync_process_execute.stderr)) + +# self.stack_resources = self._get_stacks(stack_name) +# lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) +# for lambda_function in lambda_functions: +# lambda_response = json.loads(self._get_lambda_response(lambda_function)) +# self.assertIn("message", lambda_response) +# self.assertIn("sum", lambda_response) +# self.assertEqual(lambda_response.get("message"), "hello world") +# self.assertEqual(lambda_response.get("sum"), 12) + + +# @skipIf(SKIP_SYNC_TESTS, "Skip sync tests in CI/CD only") +# class TestSyncInfraWithEsbuild(SyncIntegBase): +# dependency_layer = False + +# @parameterized.expand(["code/before/template-esbuild.yaml"]) +# def test_sync_infra_esbuild(self, template_file): +# template_path = str(self.test_data_path.joinpath(template_file)) +# stack_name = self._method_to_stack_name(self.id()) +# self.stacks.append({"name": stack_name}) + +# sync_command_list = self.get_sync_command_list( +# template_file=template_path, +# code=False, +# watch=False, +# dependency_layer=self.dependency_layer, +# stack_name=stack_name, +# image_repository=self.ecr_repo_name, +# s3_prefix=self.s3_prefix, +# kms_key_id=self.kms_key, +# capabilities_list=["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"], +# tags="integ=true clarity=yes foo_bar=baz", +# ) +# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) +# self.assertEqual(sync_process_execute.process.returncode, 0) +# self.assertIn("Sync infra completed.", str(sync_process_execute.stderr)) + +# self.stack_resources = self._get_stacks(stack_name) +# lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) +# for lambda_function in lambda_functions: +# lambda_response = json.loads(self._get_lambda_response(lambda_function)) +# self.assertEqual(lambda_response.get("message"), "hello world") From 444c6cba55bec3123492d3cd44ace00705b02e4b Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 09:50:02 -0700 Subject: [PATCH 21/54] ruby --- .github/workflows/integration-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index b3035e90a65..49ced914105 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -309,7 +309,7 @@ jobs: pytest -vv tests/integration/package tests/integration/delete tests/integration/deploy --dist=loadgroup -n 4 --reruns 4 --json-report --json-report-file=TEST_REPORT-integration-package-delete-deploy-${{ matrix.container_runtime }}.json ;; "sync") - pytest -vv tests/integration/sync -n 6 --reruns 3 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json + pytest -vv tests/integration/sync/test_sync_infra.py -n 6 --reruns 3 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json ;; "local-invoke") pytest -vv --reruns 3 tests/integration/local/invoke tests/integration/local/generate_event --json-report --json-report-file=TEST_REPORT-integration-local-invoke-${{ matrix.container_runtime }}.json From caffa1803cfa09e5ae6d36cddf6e122918924792 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 10:03:11 -0700 Subject: [PATCH 22/54] ruby 3.4 --- .github/workflows/integration-tests.yml | 9 +- tests/integration/sync/test_sync_infra.py | 96 +++++++++---------- .../sync/infra/template-ruby-after.yaml | 6 +- .../sync/infra/template-ruby-before.yaml | 6 +- 4 files changed, 58 insertions(+), 59 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 49ced914105..b94ad766912 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -127,9 +127,8 @@ jobs: with: dotnet-version: '8.0.x' - # sync test only need ruby 3.3.7 - name: Set up Ruby 3.3.7 - if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) + if: contains(fromJSON('["build-integ", "build-integ-arm64", "other-and-e2e"]'), matrix.test_suite) uses: ruby/setup-ruby@v1 with: ruby-version: '3.3.7' @@ -140,9 +139,9 @@ jobs: with: ruby-version: '3.2.7' - + # sync test only need ruby 3.4 - name: Set up Ruby 3.4.2 - if: contains(fromJSON('["build-integ", "build-integ-arm64", "other-and-e2e"]'), matrix.test_suite) + if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) uses: ruby/setup-ruby@v1 with: ruby-version: '3.4.2' @@ -309,7 +308,7 @@ jobs: pytest -vv tests/integration/package tests/integration/delete tests/integration/deploy --dist=loadgroup -n 4 --reruns 4 --json-report --json-report-file=TEST_REPORT-integration-package-delete-deploy-${{ matrix.container_runtime }}.json ;; "sync") - pytest -vv tests/integration/sync/test_sync_infra.py -n 6 --reruns 3 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json + pytest -vv tests/integration/sync/test_sync_infra.py -n 6 --reruns 1 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json ;; "local-invoke") pytest -vv --reruns 3 tests/integration/local/invoke tests/integration/local/generate_event --json-report --json-report-file=TEST_REPORT-integration-local-invoke-${{ matrix.container_runtime }}.json diff --git a/tests/integration/sync/test_sync_infra.py b/tests/integration/sync/test_sync_infra.py index ef10ace3052..d1b27ffc608 100644 --- a/tests/integration/sync/test_sync_infra.py +++ b/tests/integration/sync/test_sync_infra.py @@ -500,58 +500,58 @@ def test_sync_infra(self, runtime, use_container): # self.assertEqual(lambda_response.get("message"), "9") -# @skipIf(SKIP_SYNC_TESTS, "Skip sync tests in CI/CD only") -# @parameterized_class([{"dependency_layer": True}, {"dependency_layer": False}]) -# class TestSyncInfraWithJava(SyncIntegBase): -# ecr_repo_name = None -# kms_key = None -# parameter_overrides: Dict[str, str] = {} - -# @classmethod -# def setUpClass(cls) -> None: -# super().setUpClass() -# cls.parameter_overrides = {"HelloWorldLayerName": f"HelloWorldLayer-{uuid.uuid4().hex}"[:140]} - -# @parameterized.expand(["infra/template-java.yaml"]) -# def test_sync_infra_with_java(self, template_file): -# """This will test a case where user will flip ADL flag between sync sessions""" -# template_path = str(self.test_data_path.joinpath(template_file)) -# stack_name = self._method_to_stack_name(self.id()) -# self.stacks.append({"name": stack_name}) +@skipIf(SKIP_SYNC_TESTS, "Skip sync tests in CI/CD only") +@parameterized_class([{"dependency_layer": True}, {"dependency_layer": False}]) +class TestSyncInfraWithJava(SyncIntegBase): + ecr_repo_name = None + kms_key = None + parameter_overrides: Dict[str, str] = {} -# # first run with current dependency layer value -# self._run_sync_and_validate_lambda_call(self.dependency_layer, template_path, stack_name) + @classmethod + def setUpClass(cls) -> None: + super().setUpClass() + cls.parameter_overrides = {"HelloWorldLayerName": f"HelloWorldLayer-{uuid.uuid4().hex}"[:140]} -# # now flip the dependency layer value and re-run the sync & tests -# self._run_sync_and_validate_lambda_call(not self.dependency_layer, template_path, stack_name) + @parameterized.expand(["infra/template-java.yaml"]) + def test_sync_infra_with_java(self, template_file): + """This will test a case where user will flip ADL flag between sync sessions""" + template_path = str(self.test_data_path.joinpath(template_file)) + stack_name = self._method_to_stack_name(self.id()) + self.stacks.append({"name": stack_name}) -# def _run_sync_and_validate_lambda_call(self, dependency_layer: bool, template_path: str, stack_name: str) -> None: -# # Run infra sync -# sync_command_list = self.get_sync_command_list( -# template_file=template_path, -# code=False, -# watch=False, -# dependency_layer=dependency_layer, -# stack_name=stack_name, -# parameter_overrides=self.parameter_overrides, -# image_repository=self.ecr_repo_name, -# s3_prefix=self.s3_prefix, -# kms_key_id=self.kms_key, -# capabilities_list=["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"], -# tags="integ=true clarity=yes foo_bar=baz", -# ) -# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) -# self.assertEqual(sync_process_execute.process.returncode, 0) -# self.assertIn("Sync infra completed.", str(sync_process_execute.stderr)) + # first run with current dependency layer value + self._run_sync_and_validate_lambda_call(self.dependency_layer, template_path, stack_name) -# self.stack_resources = self._get_stacks(stack_name) -# lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) -# for lambda_function in lambda_functions: -# lambda_response = json.loads(self._get_lambda_response(lambda_function)) -# self.assertIn("message", lambda_response) -# self.assertIn("sum", lambda_response) -# self.assertEqual(lambda_response.get("message"), "hello world") -# self.assertEqual(lambda_response.get("sum"), 12) + # now flip the dependency layer value and re-run the sync & tests + self._run_sync_and_validate_lambda_call(not self.dependency_layer, template_path, stack_name) + + def _run_sync_and_validate_lambda_call(self, dependency_layer: bool, template_path: str, stack_name: str) -> None: + # Run infra sync + sync_command_list = self.get_sync_command_list( + template_file=template_path, + code=False, + watch=False, + dependency_layer=dependency_layer, + stack_name=stack_name, + parameter_overrides=self.parameter_overrides, + image_repository=self.ecr_repo_name, + s3_prefix=self.s3_prefix, + kms_key_id=self.kms_key, + capabilities_list=["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"], + tags="integ=true clarity=yes foo_bar=baz", + ) + sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) + self.assertEqual(sync_process_execute.process.returncode, 0) + self.assertIn("Sync infra completed.", str(sync_process_execute.stderr)) + + self.stack_resources = self._get_stacks(stack_name) + lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) + for lambda_function in lambda_functions: + lambda_response = json.loads(self._get_lambda_response(lambda_function)) + self.assertIn("message", lambda_response) + self.assertIn("sum", lambda_response) + self.assertEqual(lambda_response.get("message"), "hello world") + self.assertEqual(lambda_response.get("sum"), 12) # @skipIf(SKIP_SYNC_TESTS, "Skip sync tests in CI/CD only") diff --git a/tests/integration/testdata/sync/infra/template-ruby-after.yaml b/tests/integration/testdata/sync/infra/template-ruby-after.yaml index 2a4a8b11ce1..84ef4d7e871 100644 --- a/tests/integration/testdata/sync/infra/template-ruby-after.yaml +++ b/tests/integration/testdata/sync/infra/template-ruby-after.yaml @@ -17,7 +17,7 @@ Resources: AutoPublishAlias: Hello1Alias CodeUri: after/Ruby/function/ Handler: app.lambda_handler - Runtime: ruby3.2 + Runtime: ruby3.4 Architectures: - x86_64 Layers: @@ -30,6 +30,6 @@ Resources: Description: Hello World Ruby Layer ContentUri: after/Ruby/layer/ CompatibleRuntimes: - - ruby3.2 + - ruby3.4 Metadata: - BuildMethod: ruby3.2 + BuildMethod: ruby3.4 diff --git a/tests/integration/testdata/sync/infra/template-ruby-before.yaml b/tests/integration/testdata/sync/infra/template-ruby-before.yaml index 0449e40e1e8..df1fab060c3 100644 --- a/tests/integration/testdata/sync/infra/template-ruby-before.yaml +++ b/tests/integration/testdata/sync/infra/template-ruby-before.yaml @@ -17,7 +17,7 @@ Resources: AutoPublishAlias: Hello1Alias CodeUri: before/Ruby/function/ Handler: app.lambda_handler - Runtime: ruby3.2 + Runtime: ruby3.4 Architectures: - x86_64 Layers: @@ -30,6 +30,6 @@ Resources: Description: Hello World Ruby Layer ContentUri: before/Ruby/layer/ CompatibleRuntimes: - - ruby3.2 + - ruby3.4 Metadata: - BuildMethod: ruby3.2 + BuildMethod: ruby3.4 From e0ad3be386abe49ac55a899606d051873b6e47bd Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 10:18:13 -0700 Subject: [PATCH 23/54] maven --- .github/workflows/integration-tests.yml | 9 ++++++++- .../sync/infra/after/Ruby/function/.ruby-version | 2 +- .../testdata/sync/infra/after/Ruby/function/Gemfile | 2 +- .../testdata/sync/infra/after/Ruby/layer/.ruby-version | 2 +- .../testdata/sync/infra/after/Ruby/layer/Gemfile | 2 +- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index b94ad766912..62cb8405d13 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -112,10 +112,17 @@ jobs: wget https://services.gradle.org/distributions/gradle-9.0.0-bin.zip -P /tmp sudo unzip -d /opt/gradle /tmp/gradle-*.zip + # Create symlinks to ensure our Maven is used + sudo ln -sf /opt/mvn/apache-maven-3.9.11/bin/mvn /usr/local/bin/mvn + sudo ln -sf /opt/gradle/gradle-9.0.0/bin/gradle /usr/local/bin/gradle + # Add to PATH (prepend to ensure our versions are used first) echo "/opt/mvn/apache-maven-3.9.11/bin" >> $GITHUB_PATH echo "/opt/gradle/gradle-9.0.0/bin" >> $GITHUB_PATH + # Set MAVEN_HOME + echo "MAVEN_HOME=/opt/mvn/apache-maven-3.9.11" >> $GITHUB_ENV + # Verify versions export PATH="/opt/mvn/apache-maven-3.9.11/bin:/opt/gradle/gradle-9.0.0/bin:$PATH" mvn --version @@ -144,7 +151,7 @@ jobs: if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) uses: ruby/setup-ruby@v1 with: - ruby-version: '3.4.2' + ruby-version: '3.4.7' - name: Install Rust toolchain diff --git a/tests/integration/testdata/sync/infra/after/Ruby/function/.ruby-version b/tests/integration/testdata/sync/infra/after/Ruby/function/.ruby-version index 406ebcbd95f..2aa51319921 100644 --- a/tests/integration/testdata/sync/infra/after/Ruby/function/.ruby-version +++ b/tests/integration/testdata/sync/infra/after/Ruby/function/.ruby-version @@ -1 +1 @@ -3.2.7 +3.4.7 diff --git a/tests/integration/testdata/sync/infra/after/Ruby/function/Gemfile b/tests/integration/testdata/sync/infra/after/Ruby/function/Gemfile index ffdfcccc1ed..40ebd6d26ab 100644 --- a/tests/integration/testdata/sync/infra/after/Ruby/function/Gemfile +++ b/tests/integration/testdata/sync/infra/after/Ruby/function/Gemfile @@ -2,4 +2,4 @@ source "https://rubygems.org" gem "ruby-statistics" -ruby '~> 3.2' +ruby '~> 3.4' diff --git a/tests/integration/testdata/sync/infra/after/Ruby/layer/.ruby-version b/tests/integration/testdata/sync/infra/after/Ruby/layer/.ruby-version index 406ebcbd95f..2aa51319921 100644 --- a/tests/integration/testdata/sync/infra/after/Ruby/layer/.ruby-version +++ b/tests/integration/testdata/sync/infra/after/Ruby/layer/.ruby-version @@ -1 +1 @@ -3.2.7 +3.4.7 diff --git a/tests/integration/testdata/sync/infra/after/Ruby/layer/Gemfile b/tests/integration/testdata/sync/infra/after/Ruby/layer/Gemfile index 8d2ee9edd67..5549805b974 100644 --- a/tests/integration/testdata/sync/infra/after/Ruby/layer/Gemfile +++ b/tests/integration/testdata/sync/infra/after/Ruby/layer/Gemfile @@ -1,3 +1,3 @@ source "https://rubygems.org" -ruby '~> 3.2' +ruby '~> 3.4' From 26a8d5764b64b435e1073d1019d4654105b8e393 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 10:20:55 -0700 Subject: [PATCH 24/54] nit --- .github/workflows/integration-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 62cb8405d13..d87a6213824 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -99,7 +99,7 @@ jobs: go-version: '1.25' - name: Install Maven and Gradle - if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64", "build-integ-arm64-java"]'), matrix.test_suite) + if: contains(fromJSON('["build-integ", "sync", "build-integ-java-python-provided", "build-integ-arm64", "build-integ-arm64-java"]'), matrix.test_suite) run: | # Remove system Maven if it exists sudo apt-get remove -y maven || true From ce6c9162ba31b6676532c305fb148baef95af83e Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 10:27:23 -0700 Subject: [PATCH 25/54] enable java 21 --- .github/workflows/integration-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index d87a6213824..2649454999c 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -86,7 +86,7 @@ jobs: node-version: ${{ env.NODE_VERSION }} - name: Set up Java 21 - if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64", "build-integ-arm64-java"]'), matrix.test_suite) + if: contains(fromJSON('["build-integ", "sync", "build-integ-java-python-provided", "build-integ-arm64", "build-integ-arm64-java"]'), matrix.test_suite) uses: actions/setup-java@v4 with: distribution: 'corretto' From 71cceafd7539cd055a6e5143990c5dd693a802d5 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 10:34:28 -0700 Subject: [PATCH 26/54] finalize sync test --- .github/workflows/integration-tests.yml | 10 +- tests/integration/sync/test_sync_infra.py | 768 +++++++++++----------- 2 files changed, 385 insertions(+), 393 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 2649454999c..cc643d3b1ad 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -287,14 +287,6 @@ jobs: - name: Run tests run: | - # Set up PATH like AppVeyor does - export PATH="/opt/mvn/apache-maven-3.9.11/bin:/opt/gradle/gradle-9.0.0/bin:$PATH" - export CONTAINER_RUNTIME=${{ matrix.container_runtime }} - - # Verify Maven version before running tests - which mvn - mvn --version - case "${{ matrix.test_suite }}" in "build-integ") pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json @@ -315,7 +307,7 @@ jobs: pytest -vv tests/integration/package tests/integration/delete tests/integration/deploy --dist=loadgroup -n 4 --reruns 4 --json-report --json-report-file=TEST_REPORT-integration-package-delete-deploy-${{ matrix.container_runtime }}.json ;; "sync") - pytest -vv tests/integration/sync/test_sync_infra.py -n 6 --reruns 1 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json + pytest -vv tests/integration/sync -n 6 --reruns 3 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json ;; "local-invoke") pytest -vv --reruns 3 tests/integration/local/invoke tests/integration/local/generate_event --json-report --json-report-file=TEST_REPORT-integration-local-invoke-${{ matrix.container_runtime }}.json diff --git a/tests/integration/sync/test_sync_infra.py b/tests/integration/sync/test_sync_infra.py index d1b27ffc608..da4d304b8df 100644 --- a/tests/integration/sync/test_sync_infra.py +++ b/tests/integration/sync/test_sync_infra.py @@ -145,359 +145,359 @@ def test_sync_infra(self, runtime, use_container): else: self._verify_infra_changes(self.stack_resources) -# @parameterized.expand([["python", False], ["python", True]]) -# @pytest.mark.flaky(reruns=3) -# def test_sync_infra_auto_skip(self, runtime, use_container): -# template_before = f"infra/template-{runtime}-before.yaml" -# template_path = str(self.test_data_path.joinpath(template_before)) -# stack_name = self._method_to_stack_name(self.id()) -# self.stacks.append({"name": stack_name}) - -# # Run infra sync -# sync_command_list = self.get_sync_command_list( -# template_file=template_path, -# code=False, -# watch=False, -# dependency_layer=self.dependency_layer, -# stack_name=stack_name, -# parameter_overrides=self.parameter_overrides, -# image_repository=self.ecr_repo_name, -# s3_prefix=self.s3_prefix, -# kms_key_id=self.kms_key, -# tags="integ=true clarity=yes foo_bar=baz", -# use_container=use_container, -# ) - -# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) -# self.assertEqual(sync_process_execute.process.returncode, 0) -# self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) - -# template_after = f"infra/template-{runtime}-auto-skip.yaml" -# template_path = str(self.test_data_path.joinpath(template_after)) - -# # Run infra sync -# sync_command_list = self.get_sync_command_list( -# template_file=template_path, -# code=False, -# watch=False, -# dependency_layer=self.dependency_layer, -# stack_name=stack_name, -# parameter_overrides=self.parameter_overrides, -# image_repository=self.ecr_repo_name, -# s3_prefix=self.s3_prefix, -# kms_key_id=self.kms_key, -# tags="integ=true clarity=yes foo_bar=baz", -# use_container=use_container, -# ) - -# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) -# self.assertEqual(sync_process_execute.process.returncode, 0) -# self.assertIn( -# "Template haven't been changed since last deployment, skipping infra sync...", -# str(sync_process_execute.stderr), -# ) -# self.assertIn( -# "Queuing up code sync for the resources that require an update", -# str(sync_process_execute.stderr), -# ) - -# # CFN Api call here to collect all the stack resources -# self.stack_resources = self._get_stacks(stack_name) -# # Lambda Api call here, which tests both the python function and the layer -# self._verify_infra_changes(self.stack_resources) - -# @parameterized.expand([["python", False], ["python", True]]) -# @pytest.mark.flaky(reruns=3) -# def test_sync_infra_auto_skip_nested(self, runtime, use_container): -# template_before = str(Path("infra", "parent-stack.yaml")) -# template_path = str(self.test_data_path.joinpath(template_before)) - -# stack_name = self._method_to_stack_name(self.id()) -# self.stacks.append({"name": stack_name}) - -# # Run infra sync -# sync_command_list = self.get_sync_command_list( -# template_file=template_path, -# code=False, -# watch=False, -# dependency_layer=self.dependency_layer, -# stack_name=stack_name, -# parameter_overrides=self.parameter_overrides, -# image_repository=self.ecr_repo_name, -# s3_prefix=self.s3_prefix, -# kms_key_id=self.kms_key, -# tags="integ=true clarity=yes foo_bar=baz", -# use_container=use_container, -# ) - -# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) -# self.assertEqual(sync_process_execute.process.returncode, 0) -# self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) - -# self.update_file( -# self.test_data_path.joinpath("infra", f"template-{runtime}-auto-skip.yaml"), -# self.test_data_path.joinpath("infra", f"template-{runtime}-before.yaml"), -# ) - -# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) -# self.assertEqual(sync_process_execute.process.returncode, 0) -# self.assertIn( -# "Template haven't been changed since last deployment, skipping infra sync...", -# str(sync_process_execute.stderr), -# ) -# self.assertIn( -# "Queuing up code sync for the resources that require an update", -# str(sync_process_execute.stderr), -# ) - -# # CFN Api call here to collect all the stack resources -# self.stack_resources = self._get_stacks(stack_name) -# # Lambda Api call here, which tests both the python function and the layer -# self._verify_infra_changes(self.stack_resources) - -# @parameterized.expand(["infra/template-python-before.yaml"]) -# def test_sync_infra_no_confirm(self, template_file): -# template_path = str(self.test_data_path.joinpath(template_file)) -# stack_name = self._method_to_stack_name(self.id()) - -# # Run infra sync -# sync_command_list = self.get_sync_command_list( -# template_file=template_path, -# code=False, -# watch=False, -# dependency_layer=self.dependency_layer, -# stack_name=stack_name, -# parameter_overrides=self.parameter_overrides, -# image_repository=self.ecr_repo_name, -# s3_prefix=self.s3_prefix, -# kms_key_id=self.kms_key, -# tags="integ=true clarity=yes foo_bar=baz", -# ) -# sync_process_execute = run_command_with_input(sync_command_list, "n\n".encode(), cwd=self.test_data_path) - -# self.assertEqual(sync_process_execute.process.returncode, 0) -# self.assertNotIn("Build Succeeded", str(sync_process_execute.stderr)) - -# @parameterized.expand(["infra/template-python-before.yaml"]) -# def test_sync_infra_no_stack_name(self, template_file): -# template_path = str(self.test_data_path.joinpath(template_file)) - -# # Run infra sync -# sync_command_list = self.get_sync_command_list( -# template_file=template_path, -# code=False, -# watch=False, -# dependency_layer=self.dependency_layer, -# parameter_overrides=self.parameter_overrides, -# image_repository=self.ecr_repo_name, -# s3_prefix=self.s3_prefix, -# kms_key_id=self.kms_key, -# tags="integ=true clarity=yes foo_bar=baz", -# ) - -# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) -# self.assertEqual(sync_process_execute.process.returncode, 2) -# self.assertIn("Error: Missing option '--stack-name'.", str(sync_process_execute.stderr)) - -# @parameterized.expand(["infra/template-python-before.yaml"]) -# def test_sync_infra_no_capabilities(self, template_file): -# template_path = str(self.test_data_path.joinpath(template_file)) -# stack_name = self._method_to_stack_name(self.id()) -# self.stacks.append({"name": stack_name}) - -# # Run infra sync -# sync_command_list = self.get_sync_command_list( -# template_file=template_path, -# code=False, -# watch=False, -# dependency_layer=self.dependency_layer, -# stack_name=stack_name, -# parameter_overrides=self.parameter_overrides, -# image_repository=self.ecr_repo_name, -# s3_prefix=self.s3_prefix, -# kms_key_id=self.kms_key, -# capabilities="CAPABILITY_IAM", -# tags="integ=true clarity=yes foo_bar=baz", -# ) - -# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) -# self.assertEqual(sync_process_execute.process.returncode, 1) -# self.assertIn( -# "An error occurred (InsufficientCapabilitiesException) when calling the CreateStack operation: \ -# Requires capabilities : [CAPABILITY_AUTO_EXPAND]", -# str(sync_process_execute.stderr), -# ) - -# @parameterized.expand(["infra/template-python-before.yaml"]) -# def test_sync_infra_s3_bucket_option(self, template_file): -# template_path = str(self.test_data_path.joinpath(template_file)) -# stack_name = self._method_to_stack_name(self.id()) - -# sync_command_list = self.get_sync_command_list( -# template_file=template_path, -# code=False, -# watch=False, -# dependency_layer=self.dependency_layer, -# stack_name=stack_name, -# parameter_overrides=self.parameter_overrides, -# image_repository=self.ecr_repo_name, -# s3_bucket=self.bucket_name, -# s3_prefix=self.s3_prefix, -# kms_key_id=self.kms_key, -# capabilities_list=["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"], -# tags="integ=true clarity=yes foo_bar=baz", -# ) - -# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) -# self.assertEqual(sync_process_execute.process.returncode, 0) -# self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) - -# # Make sure all resources are created properly after specifying custom bucket -# # CFN Api call here to collect all the stack resources -# self.stack_resources = self._get_stacks(stack_name) - -# # Lambda Api call here, which tests both the python function and the layer -# lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) -# for lambda_function in lambda_functions: -# lambda_response = json.loads(self._get_lambda_response(lambda_function)) -# self.assertIn("extra_message", lambda_response) -# self.assertEqual(lambda_response.get("message"), "7") - -# # ApiGateway Api call here, which tests both of the RestApi -# rest_api = self.stack_resources.get(AWS_APIGATEWAY_RESTAPI)[0] -# self.assertEqual(self._get_api_message(rest_api), '{"message": "hello 1"}') - -# # SFN Api call here, which tests the StateMachine -# state_machine = self.stack_resources.get(AWS_STEPFUNCTIONS_STATEMACHINE)[0] -# self.assertEqual(self._get_sfn_response(state_machine), '"World 1"') - - -# @skipIf(SKIP_SYNC_TESTS, "Skip sync tests in CI/CD only") -# class TestSyncInfraCDKTemplates(SyncIntegBase): -# dependency_layer = None - -# @parameterized.expand( -# [ -# ( -# "cdk_v1_synthesized_template_zip_functions.json", -# "cdk_v1_synthesized_template_zip_functions_after.json", -# None, -# False, -# ), -# ( -# "cdk_v1_synthesized_template_zip_functions.json", -# "cdk_v1_synthesized_template_zip_functions_after.json", -# None, -# True, -# ), -# ( -# "cdk_v1_synthesized_template_Level1_nested_zip_functions.json", -# "cdk_v1_synthesized_template_Level1_nested_zip_functions_after.json", -# None, -# False, -# ), -# ( -# "cdk_v1_synthesized_template_image_functions.json", -# "cdk_v1_synthesized_template_image_functions_after.json", -# "ColorsRandomFunctionF61B9209", -# False, -# ), -# ( -# "cdk_v1_synthesized_template_image_functions.json", -# "cdk_v1_synthesized_template_image_functions_after.json", -# "ColorsRandomFunction", -# False, -# ), -# ( -# "cdk_v1_synthesized_template_Level1_nested_image_functions.json", -# "cdk_v1_synthesized_template_Level1_nested_image_functions_after.json", -# "ColorsRandomFunctionF61B9209", -# False, -# ), -# ( -# "cdk_v1_synthesized_template_Level1_nested_image_functions.json", -# "cdk_v1_synthesized_template_Level1_nested_image_functions_after.json", -# "ColorsRandomFunction", -# False, -# ), -# ( -# "cdk_v1_synthesized_template_Level1_nested_image_functions.json", -# "cdk_v1_synthesized_template_Level1_nested_image_functions_after.json", -# "Level1Stack/Level2Stack/ColorsRandomFunction", -# False, -# ), -# ] -# ) -# def test_cdk_templates(self, template_file, template_after, function_id, dependency_layer): -# repository = "" -# if function_id: -# repository = f"{function_id}={self.ecr_repo_name}" -# template_path = str(self.test_data_path.joinpath("infra/cdk").joinpath(template_file)) -# stack_name = self._method_to_stack_name(self.id()) -# self.stacks.append({"name": stack_name}) - -# # Run infra sync -# sync_command_list = self.get_sync_command_list( -# template_file=template_path, -# code=False, -# watch=False, -# dependency_layer=dependency_layer, -# stack_name=stack_name, -# image_repositories=repository, -# s3_prefix=self.s3_prefix, -# kms_key_id=self.kms_key, -# tags="integ=true clarity=yes foo_bar=baz", -# ) -# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) -# self.assertEqual(sync_process_execute.process.returncode, 0) -# self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) - -# # CFN Api call here to collect all the stack resources -# self.stack_resources = self._get_stacks(stack_name) -# # Lambda Api call here, which tests both the python function and the layer -# lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) -# for lambda_function in lambda_functions: -# lambda_response = json.loads(self._get_lambda_response(lambda_function)) -# self.assertIn("extra_message", lambda_response) -# self.assertEqual(lambda_response.get("message"), "7") - -# template_path = str(self.test_data_path.joinpath("infra/cdk").joinpath(template_after)) - -# after_asset_path = self.test_data_path.joinpath("infra/cdk").joinpath( -# "after/asset.6598609927b272b36fdf01072092f9851ddcd1b41ba294f736ce77091f5cc456" -# ) -# layer_method_file = str(after_asset_path.joinpath("layer_method.py")) -# main_file = str(after_asset_path.joinpath("main.py")) - -# # touch layer_method_file and main_file -# Path(layer_method_file).touch() -# Path(main_file).touch() - -# # Run infra sync -# sync_command_list = self.get_sync_command_list( -# template_file=template_path, -# code=False, -# watch=False, -# dependency_layer=dependency_layer, -# stack_name=stack_name, -# image_repositories=repository, -# s3_prefix=self.s3_prefix, -# kms_key_id=self.kms_key, -# tags="integ=true clarity=yes foo_bar=baz", -# ) - -# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) -# self.assertEqual(sync_process_execute.process.returncode, 0) -# self.assertIn("Stack update succeeded. Sync infra completed.", str(sync_process_execute.stderr)) - -# # CFN Api call here to collect all the stack resources -# self.stack_resources = self._get_stacks(stack_name) -# # Lambda Api call here, which tests both the python function and the layer -# lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) -# for lambda_function in lambda_functions: -# lambda_response = json.loads(self._get_lambda_response(lambda_function)) -# self.assertIn("extra_message", lambda_response) -# self.assertEqual(lambda_response.get("message"), "9") + @parameterized.expand([["python", False], ["python", True]]) + @pytest.mark.flaky(reruns=3) + def test_sync_infra_auto_skip(self, runtime, use_container): + template_before = f"infra/template-{runtime}-before.yaml" + template_path = str(self.test_data_path.joinpath(template_before)) + stack_name = self._method_to_stack_name(self.id()) + self.stacks.append({"name": stack_name}) + + # Run infra sync + sync_command_list = self.get_sync_command_list( + template_file=template_path, + code=False, + watch=False, + dependency_layer=self.dependency_layer, + stack_name=stack_name, + parameter_overrides=self.parameter_overrides, + image_repository=self.ecr_repo_name, + s3_prefix=self.s3_prefix, + kms_key_id=self.kms_key, + tags="integ=true clarity=yes foo_bar=baz", + use_container=use_container, + ) + + sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) + self.assertEqual(sync_process_execute.process.returncode, 0) + self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) + + template_after = f"infra/template-{runtime}-auto-skip.yaml" + template_path = str(self.test_data_path.joinpath(template_after)) + + # Run infra sync + sync_command_list = self.get_sync_command_list( + template_file=template_path, + code=False, + watch=False, + dependency_layer=self.dependency_layer, + stack_name=stack_name, + parameter_overrides=self.parameter_overrides, + image_repository=self.ecr_repo_name, + s3_prefix=self.s3_prefix, + kms_key_id=self.kms_key, + tags="integ=true clarity=yes foo_bar=baz", + use_container=use_container, + ) + + sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) + self.assertEqual(sync_process_execute.process.returncode, 0) + self.assertIn( + "Template haven't been changed since last deployment, skipping infra sync...", + str(sync_process_execute.stderr), + ) + self.assertIn( + "Queuing up code sync for the resources that require an update", + str(sync_process_execute.stderr), + ) + + # CFN Api call here to collect all the stack resources + self.stack_resources = self._get_stacks(stack_name) + # Lambda Api call here, which tests both the python function and the layer + self._verify_infra_changes(self.stack_resources) + + @parameterized.expand([["python", False], ["python", True]]) + @pytest.mark.flaky(reruns=3) + def test_sync_infra_auto_skip_nested(self, runtime, use_container): + template_before = str(Path("infra", "parent-stack.yaml")) + template_path = str(self.test_data_path.joinpath(template_before)) + + stack_name = self._method_to_stack_name(self.id()) + self.stacks.append({"name": stack_name}) + + # Run infra sync + sync_command_list = self.get_sync_command_list( + template_file=template_path, + code=False, + watch=False, + dependency_layer=self.dependency_layer, + stack_name=stack_name, + parameter_overrides=self.parameter_overrides, + image_repository=self.ecr_repo_name, + s3_prefix=self.s3_prefix, + kms_key_id=self.kms_key, + tags="integ=true clarity=yes foo_bar=baz", + use_container=use_container, + ) + + sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) + self.assertEqual(sync_process_execute.process.returncode, 0) + self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) + + self.update_file( + self.test_data_path.joinpath("infra", f"template-{runtime}-auto-skip.yaml"), + self.test_data_path.joinpath("infra", f"template-{runtime}-before.yaml"), + ) + + sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) + self.assertEqual(sync_process_execute.process.returncode, 0) + self.assertIn( + "Template haven't been changed since last deployment, skipping infra sync...", + str(sync_process_execute.stderr), + ) + self.assertIn( + "Queuing up code sync for the resources that require an update", + str(sync_process_execute.stderr), + ) + + # CFN Api call here to collect all the stack resources + self.stack_resources = self._get_stacks(stack_name) + # Lambda Api call here, which tests both the python function and the layer + self._verify_infra_changes(self.stack_resources) + + @parameterized.expand(["infra/template-python-before.yaml"]) + def test_sync_infra_no_confirm(self, template_file): + template_path = str(self.test_data_path.joinpath(template_file)) + stack_name = self._method_to_stack_name(self.id()) + + # Run infra sync + sync_command_list = self.get_sync_command_list( + template_file=template_path, + code=False, + watch=False, + dependency_layer=self.dependency_layer, + stack_name=stack_name, + parameter_overrides=self.parameter_overrides, + image_repository=self.ecr_repo_name, + s3_prefix=self.s3_prefix, + kms_key_id=self.kms_key, + tags="integ=true clarity=yes foo_bar=baz", + ) + sync_process_execute = run_command_with_input(sync_command_list, "n\n".encode(), cwd=self.test_data_path) + + self.assertEqual(sync_process_execute.process.returncode, 0) + self.assertNotIn("Build Succeeded", str(sync_process_execute.stderr)) + + @parameterized.expand(["infra/template-python-before.yaml"]) + def test_sync_infra_no_stack_name(self, template_file): + template_path = str(self.test_data_path.joinpath(template_file)) + + # Run infra sync + sync_command_list = self.get_sync_command_list( + template_file=template_path, + code=False, + watch=False, + dependency_layer=self.dependency_layer, + parameter_overrides=self.parameter_overrides, + image_repository=self.ecr_repo_name, + s3_prefix=self.s3_prefix, + kms_key_id=self.kms_key, + tags="integ=true clarity=yes foo_bar=baz", + ) + + sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) + self.assertEqual(sync_process_execute.process.returncode, 2) + self.assertIn("Error: Missing option '--stack-name'.", str(sync_process_execute.stderr)) + + @parameterized.expand(["infra/template-python-before.yaml"]) + def test_sync_infra_no_capabilities(self, template_file): + template_path = str(self.test_data_path.joinpath(template_file)) + stack_name = self._method_to_stack_name(self.id()) + self.stacks.append({"name": stack_name}) + + # Run infra sync + sync_command_list = self.get_sync_command_list( + template_file=template_path, + code=False, + watch=False, + dependency_layer=self.dependency_layer, + stack_name=stack_name, + parameter_overrides=self.parameter_overrides, + image_repository=self.ecr_repo_name, + s3_prefix=self.s3_prefix, + kms_key_id=self.kms_key, + capabilities="CAPABILITY_IAM", + tags="integ=true clarity=yes foo_bar=baz", + ) + + sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) + self.assertEqual(sync_process_execute.process.returncode, 1) + self.assertIn( + "An error occurred (InsufficientCapabilitiesException) when calling the CreateStack operation: \ +Requires capabilities : [CAPABILITY_AUTO_EXPAND]", + str(sync_process_execute.stderr), + ) + + @parameterized.expand(["infra/template-python-before.yaml"]) + def test_sync_infra_s3_bucket_option(self, template_file): + template_path = str(self.test_data_path.joinpath(template_file)) + stack_name = self._method_to_stack_name(self.id()) + + sync_command_list = self.get_sync_command_list( + template_file=template_path, + code=False, + watch=False, + dependency_layer=self.dependency_layer, + stack_name=stack_name, + parameter_overrides=self.parameter_overrides, + image_repository=self.ecr_repo_name, + s3_bucket=self.bucket_name, + s3_prefix=self.s3_prefix, + kms_key_id=self.kms_key, + capabilities_list=["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"], + tags="integ=true clarity=yes foo_bar=baz", + ) + + sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) + self.assertEqual(sync_process_execute.process.returncode, 0) + self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) + + # Make sure all resources are created properly after specifying custom bucket + # CFN Api call here to collect all the stack resources + self.stack_resources = self._get_stacks(stack_name) + + # Lambda Api call here, which tests both the python function and the layer + lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) + for lambda_function in lambda_functions: + lambda_response = json.loads(self._get_lambda_response(lambda_function)) + self.assertIn("extra_message", lambda_response) + self.assertEqual(lambda_response.get("message"), "7") + + # ApiGateway Api call here, which tests both of the RestApi + rest_api = self.stack_resources.get(AWS_APIGATEWAY_RESTAPI)[0] + self.assertEqual(self._get_api_message(rest_api), '{"message": "hello 1"}') + + # SFN Api call here, which tests the StateMachine + state_machine = self.stack_resources.get(AWS_STEPFUNCTIONS_STATEMACHINE)[0] + self.assertEqual(self._get_sfn_response(state_machine), '"World 1"') + + +@skipIf(SKIP_SYNC_TESTS, "Skip sync tests in CI/CD only") +class TestSyncInfraCDKTemplates(SyncIntegBase): + dependency_layer = None + + @parameterized.expand( + [ + ( + "cdk_v1_synthesized_template_zip_functions.json", + "cdk_v1_synthesized_template_zip_functions_after.json", + None, + False, + ), + ( + "cdk_v1_synthesized_template_zip_functions.json", + "cdk_v1_synthesized_template_zip_functions_after.json", + None, + True, + ), + ( + "cdk_v1_synthesized_template_Level1_nested_zip_functions.json", + "cdk_v1_synthesized_template_Level1_nested_zip_functions_after.json", + None, + False, + ), + ( + "cdk_v1_synthesized_template_image_functions.json", + "cdk_v1_synthesized_template_image_functions_after.json", + "ColorsRandomFunctionF61B9209", + False, + ), + ( + "cdk_v1_synthesized_template_image_functions.json", + "cdk_v1_synthesized_template_image_functions_after.json", + "ColorsRandomFunction", + False, + ), + ( + "cdk_v1_synthesized_template_Level1_nested_image_functions.json", + "cdk_v1_synthesized_template_Level1_nested_image_functions_after.json", + "ColorsRandomFunctionF61B9209", + False, + ), + ( + "cdk_v1_synthesized_template_Level1_nested_image_functions.json", + "cdk_v1_synthesized_template_Level1_nested_image_functions_after.json", + "ColorsRandomFunction", + False, + ), + ( + "cdk_v1_synthesized_template_Level1_nested_image_functions.json", + "cdk_v1_synthesized_template_Level1_nested_image_functions_after.json", + "Level1Stack/Level2Stack/ColorsRandomFunction", + False, + ), + ] + ) + def test_cdk_templates(self, template_file, template_after, function_id, dependency_layer): + repository = "" + if function_id: + repository = f"{function_id}={self.ecr_repo_name}" + template_path = str(self.test_data_path.joinpath("infra/cdk").joinpath(template_file)) + stack_name = self._method_to_stack_name(self.id()) + self.stacks.append({"name": stack_name}) + + # Run infra sync + sync_command_list = self.get_sync_command_list( + template_file=template_path, + code=False, + watch=False, + dependency_layer=dependency_layer, + stack_name=stack_name, + image_repositories=repository, + s3_prefix=self.s3_prefix, + kms_key_id=self.kms_key, + tags="integ=true clarity=yes foo_bar=baz", + ) + sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) + self.assertEqual(sync_process_execute.process.returncode, 0) + self.assertIn("Stack creation succeeded. Sync infra completed.", str(sync_process_execute.stderr)) + + # CFN Api call here to collect all the stack resources + self.stack_resources = self._get_stacks(stack_name) + # Lambda Api call here, which tests both the python function and the layer + lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) + for lambda_function in lambda_functions: + lambda_response = json.loads(self._get_lambda_response(lambda_function)) + self.assertIn("extra_message", lambda_response) + self.assertEqual(lambda_response.get("message"), "7") + + template_path = str(self.test_data_path.joinpath("infra/cdk").joinpath(template_after)) + + after_asset_path = self.test_data_path.joinpath("infra/cdk").joinpath( + "after/asset.6598609927b272b36fdf01072092f9851ddcd1b41ba294f736ce77091f5cc456" + ) + layer_method_file = str(after_asset_path.joinpath("layer_method.py")) + main_file = str(after_asset_path.joinpath("main.py")) + + # touch layer_method_file and main_file + Path(layer_method_file).touch() + Path(main_file).touch() + + # Run infra sync + sync_command_list = self.get_sync_command_list( + template_file=template_path, + code=False, + watch=False, + dependency_layer=dependency_layer, + stack_name=stack_name, + image_repositories=repository, + s3_prefix=self.s3_prefix, + kms_key_id=self.kms_key, + tags="integ=true clarity=yes foo_bar=baz", + ) + + sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) + self.assertEqual(sync_process_execute.process.returncode, 0) + self.assertIn("Stack update succeeded. Sync infra completed.", str(sync_process_execute.stderr)) + + # CFN Api call here to collect all the stack resources + self.stack_resources = self._get_stacks(stack_name) + # Lambda Api call here, which tests both the python function and the layer + lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) + for lambda_function in lambda_functions: + lambda_response = json.loads(self._get_lambda_response(lambda_function)) + self.assertIn("extra_message", lambda_response) + self.assertEqual(lambda_response.get("message"), "9") @skipIf(SKIP_SYNC_TESTS, "Skip sync tests in CI/CD only") @@ -554,34 +554,34 @@ def _run_sync_and_validate_lambda_call(self, dependency_layer: bool, template_pa self.assertEqual(lambda_response.get("sum"), 12) -# @skipIf(SKIP_SYNC_TESTS, "Skip sync tests in CI/CD only") -# class TestSyncInfraWithEsbuild(SyncIntegBase): -# dependency_layer = False - -# @parameterized.expand(["code/before/template-esbuild.yaml"]) -# def test_sync_infra_esbuild(self, template_file): -# template_path = str(self.test_data_path.joinpath(template_file)) -# stack_name = self._method_to_stack_name(self.id()) -# self.stacks.append({"name": stack_name}) - -# sync_command_list = self.get_sync_command_list( -# template_file=template_path, -# code=False, -# watch=False, -# dependency_layer=self.dependency_layer, -# stack_name=stack_name, -# image_repository=self.ecr_repo_name, -# s3_prefix=self.s3_prefix, -# kms_key_id=self.kms_key, -# capabilities_list=["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"], -# tags="integ=true clarity=yes foo_bar=baz", -# ) -# sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) -# self.assertEqual(sync_process_execute.process.returncode, 0) -# self.assertIn("Sync infra completed.", str(sync_process_execute.stderr)) - -# self.stack_resources = self._get_stacks(stack_name) -# lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) -# for lambda_function in lambda_functions: -# lambda_response = json.loads(self._get_lambda_response(lambda_function)) -# self.assertEqual(lambda_response.get("message"), "hello world") +@skipIf(SKIP_SYNC_TESTS, "Skip sync tests in CI/CD only") +class TestSyncInfraWithEsbuild(SyncIntegBase): + dependency_layer = False + + @parameterized.expand(["code/before/template-esbuild.yaml"]) + def test_sync_infra_esbuild(self, template_file): + template_path = str(self.test_data_path.joinpath(template_file)) + stack_name = self._method_to_stack_name(self.id()) + self.stacks.append({"name": stack_name}) + + sync_command_list = self.get_sync_command_list( + template_file=template_path, + code=False, + watch=False, + dependency_layer=self.dependency_layer, + stack_name=stack_name, + image_repository=self.ecr_repo_name, + s3_prefix=self.s3_prefix, + kms_key_id=self.kms_key, + capabilities_list=["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"], + tags="integ=true clarity=yes foo_bar=baz", + ) + sync_process_execute = run_command_with_input(sync_command_list, "y\n".encode(), cwd=self.test_data_path) + self.assertEqual(sync_process_execute.process.returncode, 0) + self.assertIn("Sync infra completed.", str(sync_process_execute.stderr)) + + self.stack_resources = self._get_stacks(stack_name) + lambda_functions = self.stack_resources.get(AWS_LAMBDA_FUNCTION) + for lambda_function in lambda_functions: + lambda_response = json.loads(self._get_lambda_response(lambda_function)) + self.assertEqual(lambda_response.get("message"), "hello world") From c6150f9235b42490b92cfec39ab96f9fdab291f0 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 14:47:12 -0700 Subject: [PATCH 27/54] test build integ test --- .github/workflows/integration-tests.yml | 23 +++-- .../integration/buildcmd/build_integ_base.py | 95 ++++++++++++++++++- 2 files changed, 106 insertions(+), 12 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index cc643d3b1ad..a5ed2028632 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -33,13 +33,13 @@ jobs: # container_runtime: [docker, finch] container_runtime: [docker] test_suite: - #- build-integ - #- build-integ-java-python-provided - #- build-integ-arm64 - #- build-integ-arm64-java - #- terraform-build + - build-integ + - build-integ-java-python-provided + - build-integ-arm64 + - build-integ-arm64-java + - terraform-build #- package-delete-deploy - - sync + # - sync # good #- local-invoke #- local-start #- other-and-e2e @@ -53,6 +53,11 @@ jobs: echo "Disk space before cleanup:" df -h + # Remove all existing Docker images to free up space + echo "Removing all existing Docker images..." + docker image prune -af || true + docker system prune -af --volumes || true + # Run cleanup in background to not block workflow nohup bash -c ' sudo apt-get clean @@ -62,6 +67,8 @@ jobs: ' > /dev/null 2>&1 & echo "Cleanup started in background" + echo "Disk space after Docker cleanup:" + df -h - name: Configure AWS credentials via OIDC uses: aws-actions/configure-aws-credentials@v4 @@ -295,10 +302,10 @@ jobs: pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json ;; "build-integ-arm64") - pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json ;; "build-integ-arm64-java") - pytest -vv --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json ;; "terraform-build") pytest -vv -n 4 --reruns 4 tests/integration/buildcmd/test_build_terraform_applications.py tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-terraform-${{ matrix.container_runtime }}.json diff --git a/tests/integration/buildcmd/build_integ_base.py b/tests/integration/buildcmd/build_integ_base.py index 35f8b1e0f33..8340b1e2d46 100644 --- a/tests/integration/buildcmd/build_integ_base.py +++ b/tests/integration/buildcmd/build_integ_base.py @@ -7,6 +7,7 @@ import time import logging import json +from datetime import datetime, timezone from typing import Optional from unittest import TestCase @@ -62,9 +63,95 @@ def setUp(self): self.built_template = self.default_build_dir.joinpath("template.yaml") def tearDown(self): - self.custom_build_dir and shutil.rmtree(self.custom_build_dir, ignore_errors=True) - self.working_dir and shutil.rmtree(self.working_dir, ignore_errors=True) - self.scratch_dir and shutil.rmtree(self.scratch_dir, ignore_errors=True) + """ + Clean up all test-generated artifacts after each test. + Cleanup order is important: child directories before parent directories. + """ + # Clean up Docker images and layers created more than 3 minutes ago + self._cleanup_old_docker_images() + + # Clean up custom build directory if it exists + if self.custom_build_dir and os.path.exists(self.custom_build_dir): + try: + shutil.rmtree(self.custom_build_dir) + LOG.debug(f"Cleaned up custom_build_dir: {self.custom_build_dir}") + except Exception as e: + LOG.warning(f"Failed to clean up custom_build_dir {self.custom_build_dir}: {e}") + + # Clean up working directory (contains default_build_dir) if it exists + if self.working_dir and os.path.exists(self.working_dir): + try: + shutil.rmtree(self.working_dir) + LOG.debug(f"Cleaned up working_dir: {self.working_dir}") + except Exception as e: + LOG.warning(f"Failed to clean up working_dir {self.working_dir}: {e}") + + # Clean up scratch directory (parent of all test artifacts) if it exists + if self.scratch_dir and os.path.exists(self.scratch_dir): + try: + shutil.rmtree(self.scratch_dir) + LOG.debug(f"Cleaned up scratch_dir: {self.scratch_dir}") + except Exception as e: + LOG.warning(f"Failed to clean up scratch_dir {self.scratch_dir}: {e}") + + def _cleanup_old_docker_images(self): + """ + Clean up Docker images and layers that were created more than 3 minutes ago. + This helps prevent disk space issues from accumulating test artifacts. + """ + if SKIP_DOCKER_TESTS: + return + + try: + docker_client = get_validated_container_client() + current_time = datetime.now(timezone.utc) + three_minutes_ago = current_time.timestamp() - 180 # 3 minutes in seconds + + # Get all images + all_images = docker_client.images.list() + removed_count = 0 + + for image in all_images: + try: + # Get image creation time + image_created = image.attrs.get('Created', '') + if not image_created: + continue + + # Parse the creation timestamp + # Docker API returns ISO 8601 format with nanoseconds + if isinstance(image_created, str): + # Remove nanoseconds and parse + created_dt = datetime.fromisoformat(image_created.replace('Z', '+00:00').split('.')[0] + '+00:00') + created_timestamp = created_dt.timestamp() + else: + created_timestamp = image_created + + # Check if image was created more than 3 minutes ago + if created_timestamp < three_minutes_ago: + # Get image tags for logging + image_tags = image.tags if image.tags else [image.id[:12]] + + try: + # Force remove the image (including layers) + docker_client.images.remove(image.id, force=True) + removed_count += 1 + LOG.debug(f"Removed old Docker image: {image_tags}") + except Exception as remove_error: + # Image might be in use or already removed, log but continue + LOG.debug(f"Could not remove Docker image {image_tags}: {remove_error}") + + except Exception as image_error: + # Continue with other images if one fails + LOG.debug(f"Error processing Docker image: {image_error}") + continue + + if removed_count > 0: + LOG.info(f"Cleaned up {removed_count} old Docker image(s)") + + except Exception as e: + # Don't fail the test if Docker cleanup fails + LOG.warning(f"Failed to clean up old Docker images: {e}") def get_command_list( self, @@ -638,7 +725,7 @@ def _test_with_building_java( osutils.convert_to_unix_line_ending(os.path.join(self.test_data_path, self.USING_GRADLEW_PATH, "gradlew")) # Use shorter timeout in GitHub Actions to fail faster; # Putting 1800 because Windows Canary Instances takes longer - timeout = 90 if os.environ.get("GITHUB_ACTIONS") else 1800 + timeout = 180 if os.environ.get("GITHUB_ACTIONS") else 1800 run_command(cmdlist, cwd=self.working_dir, timeout=timeout) self._verify_built_artifact( From 92629ea284d518564c6b3af20be97de8914ca679 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 15:21:51 -0700 Subject: [PATCH 28/54] split container/no container tests --- .github/workflows/integration-tests.yml | 33 +++++++++++++++++++------ 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index a5ed2028632..de7910d7c79 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -30,8 +30,8 @@ jobs: strategy: fail-fast: false matrix: - # container_runtime: [docker, finch] - container_runtime: [docker] + # container_runtime: [docker, finch, no-container] + container_runtime: [docker, finch , no-container] test_suite: - build-integ - build-integ-java-python-provided @@ -43,6 +43,12 @@ jobs: #- local-invoke #- local-start #- other-and-e2e + exclude: + # no-container mode only applies to build-integ test suites + - container_runtime: no-container + test_suite: terraform-build + - container_runtime: no-container + test_suite: sync steps: - name: Checkout code @@ -55,7 +61,7 @@ jobs: # Remove all existing Docker images to free up space echo "Removing all existing Docker images..." - docker image prune -af || true + # docker image prune -af || true docker system prune -af --volumes || true # Run cleanup in background to not block workflow @@ -106,7 +112,7 @@ jobs: go-version: '1.25' - name: Install Maven and Gradle - if: contains(fromJSON('["build-integ", "sync", "build-integ-java-python-provided", "build-integ-arm64", "build-integ-arm64-java"]'), matrix.test_suite) + if: (contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64", "build-integ-arm64-java"]'), matrix.test_suite) && matrix.container_runtime == 'no-container') || matrix.test_suite == 'sync' run: | # Remove system Maven if it exists sudo apt-get remove -y maven || true @@ -294,18 +300,29 @@ jobs: - name: Run tests run: | + # Determine test filtering based on container_runtime + if [ "${{ matrix.container_runtime }}" = "no-container" ]; then + # For no-container mode, deselect tests with "container" in the name + CONTAINER_FILTER="--deselect-by-keyword=container" + elif [ "${{ matrix.container_runtime }}" = "docker" ] || [ "${{ matrix.container_runtime }}" = "finch" ]; then + # For docker/finch mode, only select tests with "container" in the name + CONTAINER_FILTER="-k container" + else + CONTAINER_FILTER="" + fi + case "${{ matrix.test_suite }}" in "build-integ") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json ;; "build-integ-java-python-provided") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json ;; "build-integ-arm64") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json ;; "build-integ-arm64-java") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json ;; "terraform-build") pytest -vv -n 4 --reruns 4 tests/integration/buildcmd/test_build_terraform_applications.py tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-terraform-${{ matrix.container_runtime }}.json From 8bfcc4e986874c0d2c4b41f03e6f1d23fdeff4fc Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 15:35:16 -0700 Subject: [PATCH 29/54] fix --- .github/workflows/integration-tests.yml | 8 +++----- tests/integration/buildcmd/build_integ_base.py | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index de7910d7c79..d91e81319af 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -62,7 +62,7 @@ jobs: # Remove all existing Docker images to free up space echo "Removing all existing Docker images..." # docker image prune -af || true - docker system prune -af --volumes || true + nohup docker system prune -af --volumes || true & # Run cleanup in background to not block workflow nohup bash -c ' @@ -72,9 +72,6 @@ jobs: sudo rm -rf /opt/hostedtoolcache/CodeQL ' > /dev/null 2>&1 & - echo "Cleanup started in background" - echo "Disk space after Docker cleanup:" - df -h - name: Configure AWS credentials via OIDC uses: aws-actions/configure-aws-credentials@v4 @@ -249,6 +246,7 @@ jobs: docker version - name: Setup QEMU for ARM64 emulation + if: matrix.container_runtime != 'no-container' run: | if [ "${{ matrix.container_runtime }}" = "finch" ]; then sudo finch run --rm --privileged multiarch/qemu-user-static --reset -p yes @@ -303,7 +301,7 @@ jobs: # Determine test filtering based on container_runtime if [ "${{ matrix.container_runtime }}" = "no-container" ]; then # For no-container mode, deselect tests with "container" in the name - CONTAINER_FILTER="--deselect-by-keyword=container" + CONTAINER_FILTER="-k 'not container'" elif [ "${{ matrix.container_runtime }}" = "docker" ] || [ "${{ matrix.container_runtime }}" = "finch" ]; then # For docker/finch mode, only select tests with "container" in the name CONTAINER_FILTER="-k container" diff --git a/tests/integration/buildcmd/build_integ_base.py b/tests/integration/buildcmd/build_integ_base.py index 8340b1e2d46..b0f35a18ca4 100644 --- a/tests/integration/buildcmd/build_integ_base.py +++ b/tests/integration/buildcmd/build_integ_base.py @@ -725,7 +725,7 @@ def _test_with_building_java( osutils.convert_to_unix_line_ending(os.path.join(self.test_data_path, self.USING_GRADLEW_PATH, "gradlew")) # Use shorter timeout in GitHub Actions to fail faster; # Putting 1800 because Windows Canary Instances takes longer - timeout = 180 if os.environ.get("GITHUB_ACTIONS") else 1800 + timeout = 300 if os.environ.get("GITHUB_ACTIONS") else 1800 run_command(cmdlist, cwd=self.working_dir, timeout=timeout) self._verify_built_artifact( From 15cf1ac0b3c804de8d5769b7cebfce0a9315011d Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 15:42:56 -0700 Subject: [PATCH 30/54] fix container --- .github/workflows/integration-tests.yml | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index d91e81319af..f8df21c847f 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -298,29 +298,25 @@ jobs: - name: Run tests run: | - # Determine test filtering based on container_runtime + # Determine container marker filter based on container_runtime if [ "${{ matrix.container_runtime }}" = "no-container" ]; then - # For no-container mode, deselect tests with "container" in the name - CONTAINER_FILTER="-k 'not container'" - elif [ "${{ matrix.container_runtime }}" = "docker" ] || [ "${{ matrix.container_runtime }}" = "finch" ]; then - # For docker/finch mode, only select tests with "container" in the name - CONTAINER_FILTER="-k container" + CONTAINER_MARKER="not container" else - CONTAINER_FILTER="" + CONTAINER_MARKER="container" fi case "${{ matrix.test_suite }}" in "build-integ") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m "not java and not python and not provided and $CONTAINER_MARKER" --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json ;; "build-integ-java-python-provided") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m "(java or python or provided) and $CONTAINER_MARKER" --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json ;; "build-integ-arm64") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m "not java and $CONTAINER_MARKER" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json ;; "build-integ-arm64-java") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m "java and $CONTAINER_MARKER" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json ;; "terraform-build") pytest -vv -n 4 --reruns 4 tests/integration/buildcmd/test_build_terraform_applications.py tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-terraform-${{ matrix.container_runtime }}.json From f8b823f50df57ab3511d5a3bcf592671ac3da785 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 15:54:46 -0700 Subject: [PATCH 31/54] use -k correctly --- .github/workflows/integration-tests.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index f8df21c847f..923c28d43f2 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -298,25 +298,25 @@ jobs: - name: Run tests run: | - # Determine container marker filter based on container_runtime + # Determine container keyword filter based on container_runtime if [ "${{ matrix.container_runtime }}" = "no-container" ]; then - CONTAINER_MARKER="not container" + CONTAINER_FILTER="-k 'not container'" else - CONTAINER_MARKER="container" + CONTAINER_FILTER="-k container" fi case "${{ matrix.test_suite }}" in "build-integ") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m "not java and not python and not provided and $CONTAINER_MARKER" --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json ;; "build-integ-java-python-provided") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m "(java or python or provided) and $CONTAINER_MARKER" --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json ;; "build-integ-arm64") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m "not java and $CONTAINER_MARKER" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json ;; "build-integ-arm64-java") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m "java and $CONTAINER_MARKER" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json ;; "terraform-build") pytest -vv -n 4 --reruns 4 tests/integration/buildcmd/test_build_terraform_applications.py tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-terraform-${{ matrix.container_runtime }}.json From 7749640527d59fb0a483e16a6783508ac89092e2 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 16:08:38 -0700 Subject: [PATCH 32/54] k --- .github/workflows/integration-tests.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 923c28d43f2..ef85065fd54 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -37,7 +37,7 @@ jobs: - build-integ-java-python-provided - build-integ-arm64 - build-integ-arm64-java - - terraform-build + # - terraform-build # good #- package-delete-deploy # - sync # good #- local-invoke @@ -300,23 +300,23 @@ jobs: run: | # Determine container keyword filter based on container_runtime if [ "${{ matrix.container_runtime }}" = "no-container" ]; then - CONTAINER_FILTER="-k 'not container'" + CONTAINER_FILTER="not container" else - CONTAINER_FILTER="-k container" + CONTAINER_FILTER="container" fi case "${{ matrix.test_suite }}" in "build-integ") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${=CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json ;; "build-integ-java-python-provided") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${=CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json ;; "build-integ-arm64") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' -k "${=CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json ;; "build-integ-arm64-java") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' $CONTAINER_FILTER --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' -k "${=CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json ;; "terraform-build") pytest -vv -n 4 --reruns 4 tests/integration/buildcmd/test_build_terraform_applications.py tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-terraform-${{ matrix.container_runtime }}.json From f80595d3e485e10811ea023425535576655c7361 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 16:13:07 -0700 Subject: [PATCH 33/54] k2 --- .github/workflows/integration-tests.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index ef85065fd54..0d681b503f1 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -300,23 +300,23 @@ jobs: run: | # Determine container keyword filter based on container_runtime if [ "${{ matrix.container_runtime }}" = "no-container" ]; then - CONTAINER_FILTER="not container" + CONTAINER_FILTER=(not container) else - CONTAINER_FILTER="container" + CONTAINER_FILTER=(container) fi case "${{ matrix.test_suite }}" in "build-integ") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${=CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json ;; "build-integ-java-python-provided") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${=CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json ;; "build-integ-arm64") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' -k "${=CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json ;; "build-integ-arm64-java") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' -k "${=CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'java' -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-java-${{ matrix.container_runtime }}.json ;; "terraform-build") pytest -vv -n 4 --reruns 4 tests/integration/buildcmd/test_build_terraform_applications.py tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-terraform-${{ matrix.container_runtime }}.json From 8b36964be9aef562db75f19077bca5acfb010f5a Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 16:28:17 -0700 Subject: [PATCH 34/54] kk --- .github/workflows/integration-tests.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 0d681b503f1..e15d875a28d 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -90,20 +90,20 @@ jobs: 3.13 - name: Set up Node.js - if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) + if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: Set up Java 21 - if: contains(fromJSON('["build-integ", "sync", "build-integ-java-python-provided", "build-integ-arm64", "build-integ-arm64-java"]'), matrix.test_suite) + if: (contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64", "build-integ-arm64-java"]'), matrix.test_suite) && matrix.container_runtime == 'no-container') || matrix.test_suite == 'sync' uses: actions/setup-java@v4 with: distribution: 'corretto' java-version: '21' - name: Set up Go - if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) + if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' uses: actions/setup-go@v5 with: go-version: '1.25' @@ -139,33 +139,33 @@ jobs: gradle --version - name: Install .NET 8 SDK - if: contains(fromJSON('["build-integ", "build-integ-arm64"]'), matrix.test_suite) + if: contains(fromJSON('["build-integ", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.x' - name: Set up Ruby 3.3.7 - if: contains(fromJSON('["build-integ", "build-integ-arm64", "other-and-e2e"]'), matrix.test_suite) + if: (contains(fromJSON('["build-integ", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container') || matrix.test_suite == 'other-and-e2e' uses: ruby/setup-ruby@v1 with: ruby-version: '3.3.7' - name: Set up Ruby 3.2.7 - if: contains(fromJSON('["build-integ", "build-integ-arm64", "other-and-e2e"]'), matrix.test_suite) + if: (contains(fromJSON('["build-integ", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container') || matrix.test_suite == 'other-and-e2e' uses: ruby/setup-ruby@v1 with: ruby-version: '3.2.7' # sync test only need ruby 3.4 - name: Set up Ruby 3.4.2 - if: contains(fromJSON('["build-integ", "build-integ-arm64", "sync", "other-and-e2e"]'), matrix.test_suite) + if: (contains(fromJSON('["build-integ", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container') || contains(fromJSON('["sync", "other-and-e2e"]'), matrix.test_suite) uses: ruby/setup-ruby@v1 with: ruby-version: '3.4.7' - name: Install Rust toolchain - if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) + if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' run: | curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL https://sh.rustup.rs | sh -s -- --default-toolchain none -y source $HOME/.cargo/env @@ -176,7 +176,7 @@ jobs: echo "$HOME/.cargo/bin" >> $GITHUB_PATH - name: Install cargo-lambda - if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) + if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' run: pip install cargo-lambda==${{ env.CARGO_LAMBDA_VERSION }} - name: Install Terraform @@ -300,9 +300,9 @@ jobs: run: | # Determine container keyword filter based on container_runtime if [ "${{ matrix.container_runtime }}" = "no-container" ]; then - CONTAINER_FILTER=(not container) + CONTAINER_FILTER="not container" else - CONTAINER_FILTER=(container) + CONTAINER_FILTER=container fi case "${{ matrix.test_suite }}" in From b2076f96a06ab3a22d68f3143e480c5dd891d32f Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Wed, 29 Oct 2025 17:17:45 -0700 Subject: [PATCH 35/54] split container/non-container integ test --- .../integration/buildcmd/build_integ_base.py | 62 +------- tests/integration/buildcmd/test_build_cmd.py | 44 ++++-- .../buildcmd/test_build_cmd_arm64.py | 137 ++++++++---------- .../buildcmd/test_build_cmd_dotnet.py | 6 +- .../buildcmd/test_build_cmd_node.py | 19 ++- .../buildcmd/test_build_cmd_provided.py | 80 ++++++---- .../buildcmd/test_build_cmd_python.py | 57 +++++--- .../buildcmd/test_build_cmd_rust.py | 12 +- 8 files changed, 207 insertions(+), 210 deletions(-) diff --git a/tests/integration/buildcmd/build_integ_base.py b/tests/integration/buildcmd/build_integ_base.py index b0f35a18ca4..0ac5f4ccf42 100644 --- a/tests/integration/buildcmd/build_integ_base.py +++ b/tests/integration/buildcmd/build_integ_base.py @@ -67,8 +67,6 @@ def tearDown(self): Clean up all test-generated artifacts after each test. Cleanup order is important: child directories before parent directories. """ - # Clean up Docker images and layers created more than 3 minutes ago - self._cleanup_old_docker_images() # Clean up custom build directory if it exists if self.custom_build_dir and os.path.exists(self.custom_build_dir): @@ -94,64 +92,6 @@ def tearDown(self): except Exception as e: LOG.warning(f"Failed to clean up scratch_dir {self.scratch_dir}: {e}") - def _cleanup_old_docker_images(self): - """ - Clean up Docker images and layers that were created more than 3 minutes ago. - This helps prevent disk space issues from accumulating test artifacts. - """ - if SKIP_DOCKER_TESTS: - return - - try: - docker_client = get_validated_container_client() - current_time = datetime.now(timezone.utc) - three_minutes_ago = current_time.timestamp() - 180 # 3 minutes in seconds - - # Get all images - all_images = docker_client.images.list() - removed_count = 0 - - for image in all_images: - try: - # Get image creation time - image_created = image.attrs.get('Created', '') - if not image_created: - continue - - # Parse the creation timestamp - # Docker API returns ISO 8601 format with nanoseconds - if isinstance(image_created, str): - # Remove nanoseconds and parse - created_dt = datetime.fromisoformat(image_created.replace('Z', '+00:00').split('.')[0] + '+00:00') - created_timestamp = created_dt.timestamp() - else: - created_timestamp = image_created - - # Check if image was created more than 3 minutes ago - if created_timestamp < three_minutes_ago: - # Get image tags for logging - image_tags = image.tags if image.tags else [image.id[:12]] - - try: - # Force remove the image (including layers) - docker_client.images.remove(image.id, force=True) - removed_count += 1 - LOG.debug(f"Removed old Docker image: {image_tags}") - except Exception as remove_error: - # Image might be in use or already removed, log but continue - LOG.debug(f"Could not remove Docker image {image_tags}: {remove_error}") - - except Exception as image_error: - # Continue with other images if one fails - LOG.debug(f"Error processing Docker image: {image_error}") - continue - - if removed_count > 0: - LOG.info(f"Cleaned up {removed_count} old Docker image(s)") - - except Exception as e: - # Don't fail the test if Docker cleanup fails - LOG.warning(f"Failed to clean up old Docker images: {e}") def get_command_list( self, @@ -725,7 +665,7 @@ def _test_with_building_java( osutils.convert_to_unix_line_ending(os.path.join(self.test_data_path, self.USING_GRADLEW_PATH, "gradlew")) # Use shorter timeout in GitHub Actions to fail faster; # Putting 1800 because Windows Canary Instances takes longer - timeout = 300 if os.environ.get("GITHUB_ACTIONS") else 1800 + timeout = 600 if os.environ.get("GITHUB_ACTIONS") else 1800 run_command(cmdlist, cwd=self.working_dir, timeout=timeout) self._verify_built_artifact( diff --git a/tests/integration/buildcmd/test_build_cmd.py b/tests/integration/buildcmd/test_build_cmd.py index b5e4f0e8f55..969e3fd3378 100644 --- a/tests/integration/buildcmd/test_build_cmd.py +++ b/tests/integration/buildcmd/test_build_cmd.py @@ -280,41 +280,53 @@ def _validate_skipped_built_function( @pytest.mark.ruby class TestBuildCommand_RubyFunctions(BuildIntegRubyBase): - @parameterized.expand([(False,), ("use_container",)]) - def test_building_ruby_3_2(self, use_container): - if use_container and SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: - self.skipTest(SKIP_DOCKER_MESSAGE) + def test_building_ruby_3_2(self): + self._test_with_default_gemfile("ruby3.2", False, "Ruby", self.test_data_path) - self._test_with_default_gemfile("ruby3.2", use_container, "Ruby", self.test_data_path) + def test_building_ruby_3_2_in_container(self): + if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: + self.skipTest(SKIP_DOCKER_MESSAGE) + self._test_with_default_gemfile("ruby3.2", "use_container", "Ruby", self.test_data_path) @parameterized.expand([("ruby3.3",), ("ruby3.4",)]) @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) @pytest.mark.al2023 - def test_building_ruby_al2023(self, runtime): + def test_building_ruby_in_container_al2023(self, runtime): self._test_with_default_gemfile(runtime, "use_container", "Ruby", self.test_data_path) class TestBuildCommand_RubyFunctions_With_Architecture(BuildIntegRubyBase): template = "template_with_architecture.yaml" - @parameterized.expand([(False,), ("use_container",)]) - def test_building_ruby_3_2(self, use_container): - if use_container and SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: + def test_building_ruby_3_2(self): + self._test_with_default_gemfile("ruby3.2", False, "Ruby32", self.test_data_path, "x86_64") + + def test_building_ruby_3_2_in_container(self): + if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: self.skipTest(SKIP_DOCKER_MESSAGE) - self._test_with_default_gemfile("ruby3.2", use_container, "Ruby32", self.test_data_path, "x86_64") + self._test_with_default_gemfile("ruby3.2", "use_container", "Ruby32", self.test_data_path, "x86_64") + + @parameterized.expand( + [ + ("ruby3.3", "Ruby33"), + # ("ruby3.4", "Ruby34"), # TODO: Try to make this work in AppVeyor (windows-al2023) + ] + ) + @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) + @pytest.mark.al2023 + def test_building_ruby_al2023(self, runtime, codeuri): + self._test_with_default_gemfile(runtime, False, codeuri, self.test_data_path, "x86_64") @parameterized.expand( [ - ("ruby3.3", "Ruby33", False), - ("ruby3.3", "Ruby33", True), - # ("ruby3.4", "Ruby34", False), # TODO: Try to make this work in AppVeyor (windows-al2023) - ("ruby3.4", "Ruby34", True), + ("ruby3.3", "Ruby33"), + ("ruby3.4", "Ruby34"), ] ) @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) @pytest.mark.al2023 - def test_building_ruby_al2023(self, runtime, codeuri, use_container): - self._test_with_default_gemfile(runtime, use_container, codeuri, self.test_data_path, "x86_64") + def test_building_ruby_in_container_al2023(self, runtime, codeuri): + self._test_with_default_gemfile(runtime, "use_container", codeuri, self.test_data_path, "x86_64") class TestBuildCommand_RubyFunctionsWithGemfileInTheRoot(BuildIntegRubyBase): diff --git a/tests/integration/buildcmd/test_build_cmd_arm64.py b/tests/integration/buildcmd/test_build_cmd_arm64.py index b9862404eed..635f5651568 100644 --- a/tests/integration/buildcmd/test_build_cmd_arm64.py +++ b/tests/integration/buildcmd/test_build_cmd_arm64.py @@ -32,33 +32,40 @@ class TestBuildCommand_PythonFunctions_With_Specified_Architecture_arm64(BuildIn @parameterized.expand( [ - ("python3.9", "Python", False), - ("python3.10", "Python", False), - ("python3.11", "Python", False), - ("python3.12", "Python", False), - ("python3.13", "Python", False), - ("python3.9", "PythonPEP600", False), - ("python3.10", "PythonPEP600", False), - ("python3.11", "PythonPEP600", False), - ("python3.12", "PythonPEP600", False), - ("python3.13", "PythonPEP600", False), - ("python3.9", "Python", "use_container"), - ("python3.10", "Python", "use_container"), - ("python3.11", "Python", "use_container"), + ("python3.9", "Python"), + ("python3.10", "Python"), + ("python3.11", "Python"), + ("python3.12", "Python"), + ("python3.13", "Python"), + ("python3.9", "PythonPEP600"), + ("python3.10", "PythonPEP600"), + ("python3.11", "PythonPEP600"), + ("python3.12", "PythonPEP600"), + ("python3.13", "PythonPEP600"), ] ) - def test_with_default_requirements(self, runtime, codeuri, use_container): - self._test_with_default_requirements(runtime, codeuri, use_container, self.test_data_path, architecture=ARM64) + def test_with_default_requirements(self, runtime, codeuri): + self._test_with_default_requirements(runtime, codeuri, False, self.test_data_path, architecture=ARM64) @parameterized.expand( [ - ("python3.12", "Python", "use_container"), - ("python3.13", "Python", "use_container"), + ("python3.9", "Python"), + ("python3.10", "Python"), + ("python3.11", "Python"), + ] + ) + def test_with_default_requirements_in_container(self, runtime, codeuri): + self._test_with_default_requirements(runtime, codeuri, "use_container", self.test_data_path, architecture=ARM64) + + @parameterized.expand( + [ + ("python3.12", "Python"), + ("python3.13", "Python"), ] ) @pytest.mark.al2023 - def test_with_default_requirements_al2023(self, runtime, codeuri, use_container): - self._test_with_default_requirements(runtime, codeuri, use_container, self.test_data_path, architecture=ARM64) + def test_with_default_requirements_in_container_al2023(self, runtime, codeuri): + self._test_with_default_requirements(runtime, codeuri, "use_container", self.test_data_path, architecture=ARM64) class TestBuildCommand_EsbuildFunctions_arm64(BuildIntegEsbuildBase): @@ -66,20 +73,21 @@ class TestBuildCommand_EsbuildFunctions_arm64(BuildIntegEsbuildBase): @parameterized.expand( [ - ("nodejs20.x", "Esbuild/Node", {"main.js", "main.js.map"}, "main.lambdaHandler", False), - ("nodejs20.x", "Esbuild/TypeScript", {"app.js", "app.js.map"}, "app.lambdaHandler", False), - ("nodejs20.x", "Esbuild/Node", {"main.js", "main.js.map"}, "main.lambdaHandler", "use_container"), - ( - "nodejs20.x", - "Esbuild/TypeScript", - {"app.js", "app.js.map"}, - "app.lambdaHandler", - "use_container", - ), + ("nodejs20.x", "Esbuild/Node", {"main.js", "main.js.map"}, "main.lambdaHandler"), + ("nodejs20.x", "Esbuild/TypeScript", {"app.js", "app.js.map"}, "app.lambdaHandler"), ] ) - def test_building_default_package_json(self, runtime, code_uri, expected_files, handler, use_container): - self._test_with_default_package_json(runtime, use_container, code_uri, expected_files, handler, ARM64) + def test_building_default_package_json(self, runtime, code_uri, expected_files, handler): + self._test_with_default_package_json(runtime, False, code_uri, expected_files, handler, ARM64) + + @parameterized.expand( + [ + ("nodejs20.x", "Esbuild/Node", {"main.js", "main.js.map"}, "main.lambdaHandler"), + ("nodejs20.x", "Esbuild/TypeScript", {"app.js", "app.js.map"}, "app.lambdaHandler"), + ] + ) + def test_building_default_package_json_in_container(self, runtime, code_uri, expected_files, handler): + self._test_with_default_package_json(runtime, "use_container", code_uri, expected_files, handler, ARM64) @pytest.mark.nodejs @@ -129,22 +137,22 @@ class TestBuildCommand_NodeFunctions_With_Specified_Architecture_arm64(BuildInte @parameterized.expand( [ - ("nodejs20.x", False), - ("nodejs22.x", False), + ("nodejs20.x",), + ("nodejs22.x",), ] ) - def test_building_default_package_json(self, runtime, use_container): - self._test_with_default_package_json(runtime, use_container, self.test_data_path, ARM64) + def test_building_default_package_json(self, runtime): + self._test_with_default_package_json(runtime, False, self.test_data_path, ARM64) @parameterized.expand( [ - ("nodejs20.x", "use_container"), - ("nodejs22.x", "use_container"), + ("nodejs20.x",), + ("nodejs22.x",), ] ) @pytest.mark.al2023 - def test_building_default_package_json_al2023(self, runtime, use_container): - self._test_with_default_package_json(runtime, use_container, self.test_data_path, ARM64) + def test_building_default_package_json_in_container_al2023(self, runtime): + self._test_with_default_package_json(runtime, "use_container", self.test_data_path, ARM64) class TestBuildCommand_RubyFunctions_With_Architecture_arm64(BuildIntegRubyBase): @@ -478,48 +486,31 @@ def test_building_go(self, runtime, code_uri, mode): class TestBuildCommand_ProvidedFunctions_With_Specified_Architecture_arm64(BuildIntegProvidedBase): @parameterized.expand( [ - ( - "provided", - False, - None, - ), - ( - "provided.al2023", - False, - None, - ), - ( - "provided", - "use_container", - "Makefile-container", - ), - ( - "provided.al2", - False, - None, - ), - ( - "provided.al2", - "use_container", - "Makefile-container", - ), + ("provided", None), + ("provided.al2023", None), + ("provided.al2", None), ] ) - def test_building_Makefile(self, runtime, use_container, manifest): - self._test_with_Makefile(runtime, use_container, manifest, ARM64) + def test_building_Makefile(self, runtime, manifest): + self._test_with_Makefile(runtime, False, manifest, ARM64) @parameterized.expand( [ - ( - "provided.al2023", - "use_container", - "Makefile-container", - ), + ("provided", "Makefile-container"), + ("provided.al2", "Makefile-container"), + ] + ) + def test_building_Makefile_in_container(self, runtime, manifest): + self._test_with_Makefile(runtime, "use_container", manifest, ARM64) + + @parameterized.expand( + [ + ("provided.al2023", "Makefile-container"), ] ) @pytest.mark.al2023 - def test_building_Makefile_al2023(self, runtime, use_container, manifest): - self._test_with_Makefile(runtime, use_container, manifest, ARM64) + def test_building_Makefile_in_container_al2023(self, runtime, manifest): + self._test_with_Makefile(runtime, "use_container", manifest, ARM64) @skipIf( diff --git a/tests/integration/buildcmd/test_build_cmd_dotnet.py b/tests/integration/buildcmd/test_build_cmd_dotnet.py index 0316f8e4ed6..10c81be1523 100644 --- a/tests/integration/buildcmd/test_build_cmd_dotnet.py +++ b/tests/integration/buildcmd/test_build_cmd_dotnet.py @@ -115,7 +115,7 @@ class TestBuildCommand_Dotnet_cli_package_interactive(BuildIntegDotnetBase): ("provided.al2", "Dotnet7", None), ] ) - def test_dotnet_al2(self, runtime, code_uri, mode): + def test_dotnet_al2_in_container(self, runtime, code_uri, mode): overrides = { "Runtime": runtime, "CodeUri": code_uri, @@ -135,7 +135,7 @@ def test_dotnet_al2(self, runtime, code_uri, mode): ("dotnet6", "Dotnet6", "debug"), ] ) - def test_dotnet_6(self, runtime, code_uri, mode): + def test_dotnet_6_in_container(self, runtime, code_uri, mode): overrides = { "Runtime": runtime, "CodeUri": code_uri, @@ -155,7 +155,7 @@ def test_dotnet_6(self, runtime, code_uri, mode): ) @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) @pytest.mark.al2023 - def test_dotnet_al2023(self, runtime, code_uri, mode): + def test_dotnet_al2023_in_container(self, runtime, code_uri, mode): overrides = { "Runtime": runtime, "CodeUri": code_uri, diff --git a/tests/integration/buildcmd/test_build_cmd_node.py b/tests/integration/buildcmd/test_build_cmd_node.py index f4bc7a9a469..2174ddc997b 100644 --- a/tests/integration/buildcmd/test_build_cmd_node.py +++ b/tests/integration/buildcmd/test_build_cmd_node.py @@ -121,11 +121,18 @@ class TestBuildCommand_NodeFunctions_With_Specified_Architecture(BuildIntegNodeB @parameterized.expand( [ - ("nodejs20.x", False, "x86_64"), - ("nodejs22.x", False, "x86_64"), - ("nodejs20.x", "use_container", "x86_64"), - ("nodejs22.x", "use_container", "x86_64"), + ("nodejs20.x", "x86_64"), + ("nodejs22.x", "x86_64"), ] ) - def test_building_default_package_json(self, runtime, use_container, architecture): - self._test_with_default_package_json(runtime, use_container, self.test_data_path, architecture) + def test_building_default_package_json(self, runtime, architecture): + self._test_with_default_package_json(runtime, False, self.test_data_path, architecture) + + @parameterized.expand( + [ + ("nodejs20.x", "x86_64"), + ("nodejs22.x", "x86_64"), + ] + ) + def test_building_default_package_json_in_container(self, runtime, architecture): + self._test_with_default_package_json(runtime, "use_container", self.test_data_path, architecture) diff --git a/tests/integration/buildcmd/test_build_cmd_provided.py b/tests/integration/buildcmd/test_build_cmd_provided.py index e072b938a6a..215245f3fbd 100644 --- a/tests/integration/buildcmd/test_build_cmd_provided.py +++ b/tests/integration/buildcmd/test_build_cmd_provided.py @@ -35,30 +35,43 @@ class TestBuildCommand_ProvidedFunctions(BuildIntegProvidedBase): # if the makefile is present. @parameterized.expand( [ - ("provided", False, None), - ("provided", "use_container", "Makefile-container"), - ("provided.al2", False, None), - ("provided.al2", "use_container", "Makefile-container"), + ("provided", None), + ("provided.al2", None), ] ) - def test_building_Makefile(self, runtime, use_container, manifest): - if use_container: - if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: - self.skipTest(SKIP_DOCKER_MESSAGE) - self._test_with_Makefile(runtime, use_container, manifest) + def test_building_Makefile(self, runtime, manifest): + self._test_with_Makefile(runtime, False, manifest) @parameterized.expand( [ - ("provided.al2023", False, None), - ("provided.al2023", "use_container", "Makefile-container"), + ("provided", "Makefile-container"), + ("provided.al2", "Makefile-container"), + ] + ) + def test_building_Makefile_in_container(self, runtime, manifest): + if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: + self.skipTest(SKIP_DOCKER_MESSAGE) + self._test_with_Makefile(runtime, "use_container", manifest) + + @parameterized.expand( + [ + ("provided.al2023", None), ] ) @pytest.mark.al2023 - def test_building_Makefile_al2023(self, runtime, use_container, manifest): - if use_container: - if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: - self.skipTest(SKIP_DOCKER_MESSAGE) - self._test_with_Makefile(runtime, use_container, manifest) + def test_building_Makefile_al2023(self, runtime, manifest): + self._test_with_Makefile(runtime, False, manifest) + + @parameterized.expand( + [ + ("provided.al2023", "Makefile-container"), + ] + ) + @pytest.mark.al2023 + def test_building_Makefile_in_container_al2023(self, runtime, manifest): + if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: + self.skipTest(SKIP_DOCKER_MESSAGE) + self._test_with_Makefile(runtime, "use_container", manifest) @parameterized_class( @@ -73,24 +86,39 @@ class TestBuildCommand_ProvidedFunctions_With_Specified_Architecture(BuildIntegP # if the makefile is present. @parameterized.expand( [ - ("provided", False, None, "x86_64"), - ("provided", "use_container", "Makefile-container", "x86_64"), - ("provided.al2", False, None, "x86_64"), - ("provided.al2", "use_container", "Makefile-container", "x86_64"), + ("provided", None, "x86_64"), + ("provided.al2", None, "x86_64"), + ] + ) + def test_building_Makefile(self, runtime, manifest, architecture): + self._test_with_Makefile(runtime, False, manifest, architecture) + + @parameterized.expand( + [ + ("provided", "Makefile-container", "x86_64"), + ("provided.al2", "Makefile-container", "x86_64"), ] ) - def test_building_Makefile(self, runtime, use_container, manifest, architecture): - self._test_with_Makefile(runtime, use_container, manifest, architecture) + def test_building_Makefile_in_container(self, runtime, manifest, architecture): + self._test_with_Makefile(runtime, "use_container", manifest, architecture) + + @parameterized.expand( + [ + ("provided.al2023", None, "x86_64"), + ] + ) + @pytest.mark.al2023 + def test_building_Makefile_al2023(self, runtime, manifest, architecture): + self._test_with_Makefile(runtime, False, manifest, architecture) @parameterized.expand( [ - ("provided.al2023", False, None, "x86_64"), - ("provided.al2023", "use_container", "Makefile-container", "x86_64"), + ("provided.al2023", "Makefile-container", "x86_64"), ] ) @pytest.mark.al2023 - def test_building_Makefile_al2023(self, runtime, use_container, manifest, architecture): - self._test_with_Makefile(runtime, use_container, manifest, architecture) + def test_building_Makefile_in_container_al2023(self, runtime, manifest, architecture): + self._test_with_Makefile(runtime, "use_container", manifest, architecture) @parameterized_class( diff --git a/tests/integration/buildcmd/test_build_cmd_python.py b/tests/integration/buildcmd/test_build_cmd_python.py index f822f206e2e..5f1d3e1e84a 100644 --- a/tests/integration/buildcmd/test_build_cmd_python.py +++ b/tests/integration/buildcmd/test_build_cmd_python.py @@ -464,36 +464,55 @@ class TestBuildCommand_PythonFunctions_With_Specified_Architecture(BuildIntegPyt @parameterized.expand( [ - ("python3.9", "Python", False, "x86_64"), - ("python3.10", "Python", False, "x86_64"), - ("python3.11", "Python", False, "x86_64"), - ("python3.9", "PythonPEP600", False, "x86_64"), - ("python3.10", "PythonPEP600", False, "x86_64"), - ("python3.11", "PythonPEP600", False, "x86_64"), - ("python3.9", "Python", "use_container", "x86_64"), - ("python3.10", "Python", "use_container", "x86_64"), - ("python3.11", "Python", "use_container", "x86_64"), + ("python3.9", "Python", "x86_64"), + ("python3.10", "Python", "x86_64"), + ("python3.11", "Python", "x86_64"), + ("python3.9", "PythonPEP600", "x86_64"), + ("python3.10", "PythonPEP600", "x86_64"), + ("python3.11", "PythonPEP600", "x86_64"), ] ) - def test_with_default_requirements(self, runtime, codeuri, use_container, architecture): + def test_with_default_requirements(self, runtime, codeuri, architecture): self._test_with_default_requirements( - runtime, codeuri, use_container, self.test_data_path, architecture=architecture + runtime, codeuri, False, self.test_data_path, architecture=architecture ) @parameterized.expand( [ - ("python3.12", "Python", False, "x86_64"), - ("python3.12", "PythonPEP600", False, "x86_64"), - ("python3.12", "Python", "use_container", "x86_64"), - ("python3.13", "Python", False, "x86_64"), - ("python3.13", "PythonPEP600", False, "x86_64"), - ("python3.13", "Python", "use_container", "x86_64"), + ("python3.9", "Python", "x86_64"), + ("python3.10", "Python", "x86_64"), + ("python3.11", "Python", "x86_64"), + ] + ) + def test_with_default_requirements_in_container(self, runtime, codeuri, architecture): + self._test_with_default_requirements( + runtime, codeuri, "use_container", self.test_data_path, architecture=architecture + ) + + @parameterized.expand( + [ + ("python3.12", "Python", "x86_64"), + ("python3.12", "PythonPEP600", "x86_64"), + ("python3.13", "Python", "x86_64"), + ("python3.13", "PythonPEP600", "x86_64"), + ] + ) + @pytest.mark.al2023 + def test_with_default_requirements_al2023(self, runtime, codeuri, architecture): + self._test_with_default_requirements( + runtime, codeuri, False, self.test_data_path, architecture=architecture + ) + + @parameterized.expand( + [ + ("python3.12", "Python", "x86_64"), + ("python3.13", "Python", "x86_64"), ] ) @pytest.mark.al2023 - def test_with_default_requirements_al2023(self, runtime, codeuri, use_container, architecture): + def test_with_default_requirements_in_container_al2023(self, runtime, codeuri, architecture): self._test_with_default_requirements( - runtime, codeuri, use_container, self.test_data_path, architecture=architecture + runtime, codeuri, "use_container", self.test_data_path, architecture=architecture ) def test_invalid_architecture(self): diff --git a/tests/integration/buildcmd/test_build_cmd_rust.py b/tests/integration/buildcmd/test_build_cmd_rust.py index 2c5b2dd7c5b..b345a366a03 100644 --- a/tests/integration/buildcmd/test_build_cmd_rust.py +++ b/tests/integration/buildcmd/test_build_cmd_rust.py @@ -28,13 +28,13 @@ class TestBuildCommand_Rust(BuildIntegRustBase): @parameterized.expand( [ - ("provided.al2", "x86_64", None, False), - ("provided.al2", "x86_64", "debug", False), - ("provided.al2023", "x86_64", None, False), - ("provided.al2023", "x86_64", "debug", False), + ("provided.al2", "x86_64", None), + ("provided.al2", "x86_64", "debug"), + ("provided.al2023", "x86_64", None), + ("provided.al2023", "x86_64", "debug"), ] ) - def test_build(self, runtime, architecture, build_mode, use_container): + def test_build(self, runtime, architecture, build_mode): self._test_with_rust_cargo_lambda( runtime=runtime, code_uri=self.code_uri, @@ -42,5 +42,5 @@ def test_build(self, runtime, architecture, build_mode, use_container): architecture=architecture, build_mode=build_mode, expected_invoke_result=self.expected_invoke_result, - use_container=use_container, + use_container=False, ) From 3a28473e71af1d1c23716ce7435d43e9097849c7 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 30 Oct 2025 13:31:58 -0700 Subject: [PATCH 36/54] revert test --- .github/workflows/integration-tests.yml | 2 +- .../integration/buildcmd/build_integ_base.py | 62 +++++++- tests/integration/buildcmd/test_build_cmd.py | 44 ++---- .../buildcmd/test_build_cmd_arm64.py | 137 ++++++++++-------- .../buildcmd/test_build_cmd_dotnet.py | 6 +- .../buildcmd/test_build_cmd_node.py | 19 +-- .../buildcmd/test_build_cmd_provided.py | 80 ++++------ .../buildcmd/test_build_cmd_python.py | 57 +++----- .../buildcmd/test_build_cmd_rust.py | 12 +- 9 files changed, 211 insertions(+), 208 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index e15d875a28d..8fb37ab323f 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -3,7 +3,7 @@ name: Integration Tests on: push: branches: - - integ + - main permissions: id-token: write # Required for OIDC diff --git a/tests/integration/buildcmd/build_integ_base.py b/tests/integration/buildcmd/build_integ_base.py index 0ac5f4ccf42..ee2cdef17b4 100644 --- a/tests/integration/buildcmd/build_integ_base.py +++ b/tests/integration/buildcmd/build_integ_base.py @@ -67,6 +67,8 @@ def tearDown(self): Clean up all test-generated artifacts after each test. Cleanup order is important: child directories before parent directories. """ + # Clean up Docker images and layers created more than 5 minutes ago + self._cleanup_old_docker_images() # Clean up custom build directory if it exists if self.custom_build_dir and os.path.exists(self.custom_build_dir): @@ -92,6 +94,64 @@ def tearDown(self): except Exception as e: LOG.warning(f"Failed to clean up scratch_dir {self.scratch_dir}: {e}") + def _cleanup_old_docker_images(self): + """ + Clean up Docker images and layers that were created more than 3 minutes ago. + This helps prevent disk space issues from accumulating test artifacts. + """ + if SKIP_DOCKER_TESTS: + return + + try: + docker_client = get_validated_container_client() + current_time = datetime.now(timezone.utc) + five_minutes_ago = current_time.timestamp() - 300 # 5 minutes in seconds + + # Get all images + all_images = docker_client.images.list() + removed_count = 0 + + for image in all_images: + try: + # Get image creation time + image_created = image.attrs.get('Created', '') + if not image_created: + continue + + # Parse the creation timestamp + # Docker API returns ISO 8601 format with nanoseconds + if isinstance(image_created, str): + # Remove nanoseconds and parse + created_dt = datetime.fromisoformat(image_created.replace('Z', '+00:00').split('.')[0] + '+00:00') + created_timestamp = created_dt.timestamp() + else: + created_timestamp = image_created + + # Check if image was created more than 3 minutes ago + if created_timestamp < five_minutes_ago: + # Get image tags for logging + image_tags = image.tags if image.tags else [image.id[:12]] + + try: + # Force remove the image (including layers) + docker_client.images.remove(image.id, force=True) + removed_count += 1 + LOG.debug(f"Removed old Docker image: {image_tags}") + except Exception as remove_error: + # Image might be in use or already removed, log but continue + LOG.debug(f"Could not remove Docker image {image_tags}: {remove_error}") + + except Exception as image_error: + # Continue with other images if one fails + LOG.debug(f"Error processing Docker image: {image_error}") + continue + + if removed_count > 0: + LOG.info(f"Cleaned up {removed_count} old Docker image(s)") + + except Exception as e: + # Don't fail the test if Docker cleanup fails + LOG.warning(f"Failed to clean up old Docker images: {e}") def get_command_list( self, @@ -665,7 +725,7 @@ def _test_with_building_java( osutils.convert_to_unix_line_ending(os.path.join(self.test_data_path, self.USING_GRADLEW_PATH, "gradlew")) # Use shorter timeout in GitHub Actions to fail faster; # Putting 1800 because Windows Canary Instances takes longer - timeout = 600 if os.environ.get("GITHUB_ACTIONS") else 1800 + timeout = 300 if os.environ.get("GITHUB_ACTIONS") else 1800 run_command(cmdlist, cwd=self.working_dir, timeout=timeout) self._verify_built_artifact( diff --git a/tests/integration/buildcmd/test_build_cmd.py b/tests/integration/buildcmd/test_build_cmd.py index 969e3fd3378..b5e4f0e8f55 100644 --- a/tests/integration/buildcmd/test_build_cmd.py +++ b/tests/integration/buildcmd/test_build_cmd.py @@ -280,53 +280,41 @@ def _validate_skipped_built_function( @pytest.mark.ruby class TestBuildCommand_RubyFunctions(BuildIntegRubyBase): - def test_building_ruby_3_2(self): - self._test_with_default_gemfile("ruby3.2", False, "Ruby", self.test_data_path) - - def test_building_ruby_3_2_in_container(self): - if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: + @parameterized.expand([(False,), ("use_container",)]) + def test_building_ruby_3_2(self, use_container): + if use_container and SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: self.skipTest(SKIP_DOCKER_MESSAGE) - self._test_with_default_gemfile("ruby3.2", "use_container", "Ruby", self.test_data_path) + + self._test_with_default_gemfile("ruby3.2", use_container, "Ruby", self.test_data_path) @parameterized.expand([("ruby3.3",), ("ruby3.4",)]) @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) @pytest.mark.al2023 - def test_building_ruby_in_container_al2023(self, runtime): + def test_building_ruby_al2023(self, runtime): self._test_with_default_gemfile(runtime, "use_container", "Ruby", self.test_data_path) class TestBuildCommand_RubyFunctions_With_Architecture(BuildIntegRubyBase): template = "template_with_architecture.yaml" - def test_building_ruby_3_2(self): - self._test_with_default_gemfile("ruby3.2", False, "Ruby32", self.test_data_path, "x86_64") - - def test_building_ruby_3_2_in_container(self): - if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: + @parameterized.expand([(False,), ("use_container",)]) + def test_building_ruby_3_2(self, use_container): + if use_container and SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: self.skipTest(SKIP_DOCKER_MESSAGE) - self._test_with_default_gemfile("ruby3.2", "use_container", "Ruby32", self.test_data_path, "x86_64") - - @parameterized.expand( - [ - ("ruby3.3", "Ruby33"), - # ("ruby3.4", "Ruby34"), # TODO: Try to make this work in AppVeyor (windows-al2023) - ] - ) - @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) - @pytest.mark.al2023 - def test_building_ruby_al2023(self, runtime, codeuri): - self._test_with_default_gemfile(runtime, False, codeuri, self.test_data_path, "x86_64") + self._test_with_default_gemfile("ruby3.2", use_container, "Ruby32", self.test_data_path, "x86_64") @parameterized.expand( [ - ("ruby3.3", "Ruby33"), - ("ruby3.4", "Ruby34"), + ("ruby3.3", "Ruby33", False), + ("ruby3.3", "Ruby33", True), + # ("ruby3.4", "Ruby34", False), # TODO: Try to make this work in AppVeyor (windows-al2023) + ("ruby3.4", "Ruby34", True), ] ) @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) @pytest.mark.al2023 - def test_building_ruby_in_container_al2023(self, runtime, codeuri): - self._test_with_default_gemfile(runtime, "use_container", codeuri, self.test_data_path, "x86_64") + def test_building_ruby_al2023(self, runtime, codeuri, use_container): + self._test_with_default_gemfile(runtime, use_container, codeuri, self.test_data_path, "x86_64") class TestBuildCommand_RubyFunctionsWithGemfileInTheRoot(BuildIntegRubyBase): diff --git a/tests/integration/buildcmd/test_build_cmd_arm64.py b/tests/integration/buildcmd/test_build_cmd_arm64.py index 635f5651568..b9862404eed 100644 --- a/tests/integration/buildcmd/test_build_cmd_arm64.py +++ b/tests/integration/buildcmd/test_build_cmd_arm64.py @@ -32,40 +32,33 @@ class TestBuildCommand_PythonFunctions_With_Specified_Architecture_arm64(BuildIn @parameterized.expand( [ - ("python3.9", "Python"), - ("python3.10", "Python"), - ("python3.11", "Python"), - ("python3.12", "Python"), - ("python3.13", "Python"), - ("python3.9", "PythonPEP600"), - ("python3.10", "PythonPEP600"), - ("python3.11", "PythonPEP600"), - ("python3.12", "PythonPEP600"), - ("python3.13", "PythonPEP600"), + ("python3.9", "Python", False), + ("python3.10", "Python", False), + ("python3.11", "Python", False), + ("python3.12", "Python", False), + ("python3.13", "Python", False), + ("python3.9", "PythonPEP600", False), + ("python3.10", "PythonPEP600", False), + ("python3.11", "PythonPEP600", False), + ("python3.12", "PythonPEP600", False), + ("python3.13", "PythonPEP600", False), + ("python3.9", "Python", "use_container"), + ("python3.10", "Python", "use_container"), + ("python3.11", "Python", "use_container"), ] ) - def test_with_default_requirements(self, runtime, codeuri): - self._test_with_default_requirements(runtime, codeuri, False, self.test_data_path, architecture=ARM64) + def test_with_default_requirements(self, runtime, codeuri, use_container): + self._test_with_default_requirements(runtime, codeuri, use_container, self.test_data_path, architecture=ARM64) @parameterized.expand( [ - ("python3.9", "Python"), - ("python3.10", "Python"), - ("python3.11", "Python"), - ] - ) - def test_with_default_requirements_in_container(self, runtime, codeuri): - self._test_with_default_requirements(runtime, codeuri, "use_container", self.test_data_path, architecture=ARM64) - - @parameterized.expand( - [ - ("python3.12", "Python"), - ("python3.13", "Python"), + ("python3.12", "Python", "use_container"), + ("python3.13", "Python", "use_container"), ] ) @pytest.mark.al2023 - def test_with_default_requirements_in_container_al2023(self, runtime, codeuri): - self._test_with_default_requirements(runtime, codeuri, "use_container", self.test_data_path, architecture=ARM64) + def test_with_default_requirements_al2023(self, runtime, codeuri, use_container): + self._test_with_default_requirements(runtime, codeuri, use_container, self.test_data_path, architecture=ARM64) class TestBuildCommand_EsbuildFunctions_arm64(BuildIntegEsbuildBase): @@ -73,21 +66,20 @@ class TestBuildCommand_EsbuildFunctions_arm64(BuildIntegEsbuildBase): @parameterized.expand( [ - ("nodejs20.x", "Esbuild/Node", {"main.js", "main.js.map"}, "main.lambdaHandler"), - ("nodejs20.x", "Esbuild/TypeScript", {"app.js", "app.js.map"}, "app.lambdaHandler"), - ] - ) - def test_building_default_package_json(self, runtime, code_uri, expected_files, handler): - self._test_with_default_package_json(runtime, False, code_uri, expected_files, handler, ARM64) - - @parameterized.expand( - [ - ("nodejs20.x", "Esbuild/Node", {"main.js", "main.js.map"}, "main.lambdaHandler"), - ("nodejs20.x", "Esbuild/TypeScript", {"app.js", "app.js.map"}, "app.lambdaHandler"), + ("nodejs20.x", "Esbuild/Node", {"main.js", "main.js.map"}, "main.lambdaHandler", False), + ("nodejs20.x", "Esbuild/TypeScript", {"app.js", "app.js.map"}, "app.lambdaHandler", False), + ("nodejs20.x", "Esbuild/Node", {"main.js", "main.js.map"}, "main.lambdaHandler", "use_container"), + ( + "nodejs20.x", + "Esbuild/TypeScript", + {"app.js", "app.js.map"}, + "app.lambdaHandler", + "use_container", + ), ] ) - def test_building_default_package_json_in_container(self, runtime, code_uri, expected_files, handler): - self._test_with_default_package_json(runtime, "use_container", code_uri, expected_files, handler, ARM64) + def test_building_default_package_json(self, runtime, code_uri, expected_files, handler, use_container): + self._test_with_default_package_json(runtime, use_container, code_uri, expected_files, handler, ARM64) @pytest.mark.nodejs @@ -137,22 +129,22 @@ class TestBuildCommand_NodeFunctions_With_Specified_Architecture_arm64(BuildInte @parameterized.expand( [ - ("nodejs20.x",), - ("nodejs22.x",), + ("nodejs20.x", False), + ("nodejs22.x", False), ] ) - def test_building_default_package_json(self, runtime): - self._test_with_default_package_json(runtime, False, self.test_data_path, ARM64) + def test_building_default_package_json(self, runtime, use_container): + self._test_with_default_package_json(runtime, use_container, self.test_data_path, ARM64) @parameterized.expand( [ - ("nodejs20.x",), - ("nodejs22.x",), + ("nodejs20.x", "use_container"), + ("nodejs22.x", "use_container"), ] ) @pytest.mark.al2023 - def test_building_default_package_json_in_container_al2023(self, runtime): - self._test_with_default_package_json(runtime, "use_container", self.test_data_path, ARM64) + def test_building_default_package_json_al2023(self, runtime, use_container): + self._test_with_default_package_json(runtime, use_container, self.test_data_path, ARM64) class TestBuildCommand_RubyFunctions_With_Architecture_arm64(BuildIntegRubyBase): @@ -486,31 +478,48 @@ def test_building_go(self, runtime, code_uri, mode): class TestBuildCommand_ProvidedFunctions_With_Specified_Architecture_arm64(BuildIntegProvidedBase): @parameterized.expand( [ - ("provided", None), - ("provided.al2023", None), - ("provided.al2", None), - ] - ) - def test_building_Makefile(self, runtime, manifest): - self._test_with_Makefile(runtime, False, manifest, ARM64) - - @parameterized.expand( - [ - ("provided", "Makefile-container"), - ("provided.al2", "Makefile-container"), + ( + "provided", + False, + None, + ), + ( + "provided.al2023", + False, + None, + ), + ( + "provided", + "use_container", + "Makefile-container", + ), + ( + "provided.al2", + False, + None, + ), + ( + "provided.al2", + "use_container", + "Makefile-container", + ), ] ) - def test_building_Makefile_in_container(self, runtime, manifest): - self._test_with_Makefile(runtime, "use_container", manifest, ARM64) + def test_building_Makefile(self, runtime, use_container, manifest): + self._test_with_Makefile(runtime, use_container, manifest, ARM64) @parameterized.expand( [ - ("provided.al2023", "Makefile-container"), + ( + "provided.al2023", + "use_container", + "Makefile-container", + ), ] ) @pytest.mark.al2023 - def test_building_Makefile_in_container_al2023(self, runtime, manifest): - self._test_with_Makefile(runtime, "use_container", manifest, ARM64) + def test_building_Makefile_al2023(self, runtime, use_container, manifest): + self._test_with_Makefile(runtime, use_container, manifest, ARM64) @skipIf( diff --git a/tests/integration/buildcmd/test_build_cmd_dotnet.py b/tests/integration/buildcmd/test_build_cmd_dotnet.py index 10c81be1523..47155e519e9 100644 --- a/tests/integration/buildcmd/test_build_cmd_dotnet.py +++ b/tests/integration/buildcmd/test_build_cmd_dotnet.py @@ -115,7 +115,7 @@ class TestBuildCommand_Dotnet_cli_package_interactive(BuildIntegDotnetBase): ("provided.al2", "Dotnet7", None), ] ) - def test_dotnet_al2_in_container(self, runtime, code_uri, mode): + def test_dotnet_al2_on_container(self, runtime, code_uri, mode): overrides = { "Runtime": runtime, "CodeUri": code_uri, @@ -135,7 +135,7 @@ def test_dotnet_al2_in_container(self, runtime, code_uri, mode): ("dotnet6", "Dotnet6", "debug"), ] ) - def test_dotnet_6_in_container(self, runtime, code_uri, mode): + def test_dotnet_6_on_container(self, runtime, code_uri, mode): overrides = { "Runtime": runtime, "CodeUri": code_uri, @@ -155,7 +155,7 @@ def test_dotnet_6_in_container(self, runtime, code_uri, mode): ) @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) @pytest.mark.al2023 - def test_dotnet_al2023_in_container(self, runtime, code_uri, mode): + def test_dotnet_al2023_on_container(self, runtime, code_uri, mode): overrides = { "Runtime": runtime, "CodeUri": code_uri, diff --git a/tests/integration/buildcmd/test_build_cmd_node.py b/tests/integration/buildcmd/test_build_cmd_node.py index 2174ddc997b..f4bc7a9a469 100644 --- a/tests/integration/buildcmd/test_build_cmd_node.py +++ b/tests/integration/buildcmd/test_build_cmd_node.py @@ -121,18 +121,11 @@ class TestBuildCommand_NodeFunctions_With_Specified_Architecture(BuildIntegNodeB @parameterized.expand( [ - ("nodejs20.x", "x86_64"), - ("nodejs22.x", "x86_64"), + ("nodejs20.x", False, "x86_64"), + ("nodejs22.x", False, "x86_64"), + ("nodejs20.x", "use_container", "x86_64"), + ("nodejs22.x", "use_container", "x86_64"), ] ) - def test_building_default_package_json(self, runtime, architecture): - self._test_with_default_package_json(runtime, False, self.test_data_path, architecture) - - @parameterized.expand( - [ - ("nodejs20.x", "x86_64"), - ("nodejs22.x", "x86_64"), - ] - ) - def test_building_default_package_json_in_container(self, runtime, architecture): - self._test_with_default_package_json(runtime, "use_container", self.test_data_path, architecture) + def test_building_default_package_json(self, runtime, use_container, architecture): + self._test_with_default_package_json(runtime, use_container, self.test_data_path, architecture) diff --git a/tests/integration/buildcmd/test_build_cmd_provided.py b/tests/integration/buildcmd/test_build_cmd_provided.py index 215245f3fbd..e072b938a6a 100644 --- a/tests/integration/buildcmd/test_build_cmd_provided.py +++ b/tests/integration/buildcmd/test_build_cmd_provided.py @@ -35,43 +35,30 @@ class TestBuildCommand_ProvidedFunctions(BuildIntegProvidedBase): # if the makefile is present. @parameterized.expand( [ - ("provided", None), - ("provided.al2", None), - ] - ) - def test_building_Makefile(self, runtime, manifest): - self._test_with_Makefile(runtime, False, manifest) - - @parameterized.expand( - [ - ("provided", "Makefile-container"), - ("provided.al2", "Makefile-container"), - ] - ) - def test_building_Makefile_in_container(self, runtime, manifest): - if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: - self.skipTest(SKIP_DOCKER_MESSAGE) - self._test_with_Makefile(runtime, "use_container", manifest) - - @parameterized.expand( - [ - ("provided.al2023", None), + ("provided", False, None), + ("provided", "use_container", "Makefile-container"), + ("provided.al2", False, None), + ("provided.al2", "use_container", "Makefile-container"), ] ) - @pytest.mark.al2023 - def test_building_Makefile_al2023(self, runtime, manifest): - self._test_with_Makefile(runtime, False, manifest) + def test_building_Makefile(self, runtime, use_container, manifest): + if use_container: + if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: + self.skipTest(SKIP_DOCKER_MESSAGE) + self._test_with_Makefile(runtime, use_container, manifest) @parameterized.expand( [ - ("provided.al2023", "Makefile-container"), + ("provided.al2023", False, None), + ("provided.al2023", "use_container", "Makefile-container"), ] ) @pytest.mark.al2023 - def test_building_Makefile_in_container_al2023(self, runtime, manifest): - if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: - self.skipTest(SKIP_DOCKER_MESSAGE) - self._test_with_Makefile(runtime, "use_container", manifest) + def test_building_Makefile_al2023(self, runtime, use_container, manifest): + if use_container: + if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: + self.skipTest(SKIP_DOCKER_MESSAGE) + self._test_with_Makefile(runtime, use_container, manifest) @parameterized_class( @@ -86,39 +73,24 @@ class TestBuildCommand_ProvidedFunctions_With_Specified_Architecture(BuildIntegP # if the makefile is present. @parameterized.expand( [ - ("provided", None, "x86_64"), - ("provided.al2", None, "x86_64"), - ] - ) - def test_building_Makefile(self, runtime, manifest, architecture): - self._test_with_Makefile(runtime, False, manifest, architecture) - - @parameterized.expand( - [ - ("provided", "Makefile-container", "x86_64"), - ("provided.al2", "Makefile-container", "x86_64"), + ("provided", False, None, "x86_64"), + ("provided", "use_container", "Makefile-container", "x86_64"), + ("provided.al2", False, None, "x86_64"), + ("provided.al2", "use_container", "Makefile-container", "x86_64"), ] ) - def test_building_Makefile_in_container(self, runtime, manifest, architecture): - self._test_with_Makefile(runtime, "use_container", manifest, architecture) - - @parameterized.expand( - [ - ("provided.al2023", None, "x86_64"), - ] - ) - @pytest.mark.al2023 - def test_building_Makefile_al2023(self, runtime, manifest, architecture): - self._test_with_Makefile(runtime, False, manifest, architecture) + def test_building_Makefile(self, runtime, use_container, manifest, architecture): + self._test_with_Makefile(runtime, use_container, manifest, architecture) @parameterized.expand( [ - ("provided.al2023", "Makefile-container", "x86_64"), + ("provided.al2023", False, None, "x86_64"), + ("provided.al2023", "use_container", "Makefile-container", "x86_64"), ] ) @pytest.mark.al2023 - def test_building_Makefile_in_container_al2023(self, runtime, manifest, architecture): - self._test_with_Makefile(runtime, "use_container", manifest, architecture) + def test_building_Makefile_al2023(self, runtime, use_container, manifest, architecture): + self._test_with_Makefile(runtime, use_container, manifest, architecture) @parameterized_class( diff --git a/tests/integration/buildcmd/test_build_cmd_python.py b/tests/integration/buildcmd/test_build_cmd_python.py index 5f1d3e1e84a..f822f206e2e 100644 --- a/tests/integration/buildcmd/test_build_cmd_python.py +++ b/tests/integration/buildcmd/test_build_cmd_python.py @@ -464,55 +464,36 @@ class TestBuildCommand_PythonFunctions_With_Specified_Architecture(BuildIntegPyt @parameterized.expand( [ - ("python3.9", "Python", "x86_64"), - ("python3.10", "Python", "x86_64"), - ("python3.11", "Python", "x86_64"), - ("python3.9", "PythonPEP600", "x86_64"), - ("python3.10", "PythonPEP600", "x86_64"), - ("python3.11", "PythonPEP600", "x86_64"), + ("python3.9", "Python", False, "x86_64"), + ("python3.10", "Python", False, "x86_64"), + ("python3.11", "Python", False, "x86_64"), + ("python3.9", "PythonPEP600", False, "x86_64"), + ("python3.10", "PythonPEP600", False, "x86_64"), + ("python3.11", "PythonPEP600", False, "x86_64"), + ("python3.9", "Python", "use_container", "x86_64"), + ("python3.10", "Python", "use_container", "x86_64"), + ("python3.11", "Python", "use_container", "x86_64"), ] ) - def test_with_default_requirements(self, runtime, codeuri, architecture): + def test_with_default_requirements(self, runtime, codeuri, use_container, architecture): self._test_with_default_requirements( - runtime, codeuri, False, self.test_data_path, architecture=architecture + runtime, codeuri, use_container, self.test_data_path, architecture=architecture ) @parameterized.expand( [ - ("python3.9", "Python", "x86_64"), - ("python3.10", "Python", "x86_64"), - ("python3.11", "Python", "x86_64"), - ] - ) - def test_with_default_requirements_in_container(self, runtime, codeuri, architecture): - self._test_with_default_requirements( - runtime, codeuri, "use_container", self.test_data_path, architecture=architecture - ) - - @parameterized.expand( - [ - ("python3.12", "Python", "x86_64"), - ("python3.12", "PythonPEP600", "x86_64"), - ("python3.13", "Python", "x86_64"), - ("python3.13", "PythonPEP600", "x86_64"), - ] - ) - @pytest.mark.al2023 - def test_with_default_requirements_al2023(self, runtime, codeuri, architecture): - self._test_with_default_requirements( - runtime, codeuri, False, self.test_data_path, architecture=architecture - ) - - @parameterized.expand( - [ - ("python3.12", "Python", "x86_64"), - ("python3.13", "Python", "x86_64"), + ("python3.12", "Python", False, "x86_64"), + ("python3.12", "PythonPEP600", False, "x86_64"), + ("python3.12", "Python", "use_container", "x86_64"), + ("python3.13", "Python", False, "x86_64"), + ("python3.13", "PythonPEP600", False, "x86_64"), + ("python3.13", "Python", "use_container", "x86_64"), ] ) @pytest.mark.al2023 - def test_with_default_requirements_in_container_al2023(self, runtime, codeuri, architecture): + def test_with_default_requirements_al2023(self, runtime, codeuri, use_container, architecture): self._test_with_default_requirements( - runtime, codeuri, "use_container", self.test_data_path, architecture=architecture + runtime, codeuri, use_container, self.test_data_path, architecture=architecture ) def test_invalid_architecture(self): diff --git a/tests/integration/buildcmd/test_build_cmd_rust.py b/tests/integration/buildcmd/test_build_cmd_rust.py index b345a366a03..2c5b2dd7c5b 100644 --- a/tests/integration/buildcmd/test_build_cmd_rust.py +++ b/tests/integration/buildcmd/test_build_cmd_rust.py @@ -28,13 +28,13 @@ class TestBuildCommand_Rust(BuildIntegRustBase): @parameterized.expand( [ - ("provided.al2", "x86_64", None), - ("provided.al2", "x86_64", "debug"), - ("provided.al2023", "x86_64", None), - ("provided.al2023", "x86_64", "debug"), + ("provided.al2", "x86_64", None, False), + ("provided.al2", "x86_64", "debug", False), + ("provided.al2023", "x86_64", None, False), + ("provided.al2023", "x86_64", "debug", False), ] ) - def test_build(self, runtime, architecture, build_mode): + def test_build(self, runtime, architecture, build_mode, use_container): self._test_with_rust_cargo_lambda( runtime=runtime, code_uri=self.code_uri, @@ -42,5 +42,5 @@ def test_build(self, runtime, architecture, build_mode): architecture=architecture, build_mode=build_mode, expected_invoke_result=self.expected_invoke_result, - use_container=False, + use_container=use_container, ) From dd460dc373adc54fe99c207e772f744726da755c Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 30 Oct 2025 14:09:10 -0700 Subject: [PATCH 37/54] make sure in buildcmd, all container test has container in its name --- .github/workflows/integration-tests.yml | 2 +- .../integration/buildcmd/build_integ_base.py | 19 +++ tests/integration/buildcmd/test_build_cmd.py | 128 +++++++++++------- .../buildcmd/test_build_cmd_arm64.py | 25 ++-- .../buildcmd/test_build_cmd_dotnet.py | 8 +- .../buildcmd/test_build_cmd_node.py | 16 ++- .../buildcmd/test_build_cmd_provided.py | 13 +- .../buildcmd/test_build_cmd_python.py | 11 +- .../buildcmd/test_build_cmd_rust.py | 4 +- 9 files changed, 147 insertions(+), 79 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 8fb37ab323f..e15d875a28d 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -3,7 +3,7 @@ name: Integration Tests on: push: branches: - - main + - integ permissions: id-token: write # Required for OIDC diff --git a/tests/integration/buildcmd/build_integ_base.py b/tests/integration/buildcmd/build_integ_base.py index ee2cdef17b4..5cc0484b5be 100644 --- a/tests/integration/buildcmd/build_integ_base.py +++ b/tests/integration/buildcmd/build_integ_base.py @@ -36,6 +36,25 @@ LOG = logging.getLogger(__name__) +def show_container_in_test_name(testcase_func, param_num, param): + """ + Generates a custom name for parameterized test cases. + Adds '_in_container' suffix when any parameter contains 'container' in its string representation. + """ + # Get the base test name + base_name = f"{testcase_func.__name__}_{param_num}" + + # Check if any parameter contains "container" in its string representation + for arg in param.args: + if isinstance(arg, str) and "container" in arg.lower(): + base_name += "_in_container" + break + elif arg is True: # Also check for boolean True which might indicate use_container + # Check if this might be a use_container parameter by position + # This is a fallback for cases where True is used instead of "use_container" + continue + + return base_name class BuildIntegBase(TestCase): template: Optional[str] = "template.yaml" diff --git a/tests/integration/buildcmd/test_build_cmd.py b/tests/integration/buildcmd/test_build_cmd.py index b5e4f0e8f55..5c27c1bab74 100644 --- a/tests/integration/buildcmd/test_build_cmd.py +++ b/tests/integration/buildcmd/test_build_cmd.py @@ -36,6 +36,7 @@ IntrinsicIntegBase, BuildIntegGoBase, BuildIntegPythonBase, + show_container_in_test_name, ) @@ -46,7 +47,7 @@ @skipIf(SKIP_DOCKER_TESTS, SKIP_DOCKER_MESSAGE) -class TestBuildingImageTypeLambdaDockerFileFailures(BuildIntegBase): +class TestBuildingImageTypeLambdaDockerFileFailuresContainer(BuildIntegBase): template = "template_image.yaml" def test_with_invalid_dockerfile_location(self): @@ -86,7 +87,7 @@ def test_with_invalid_dockerfile_definition(self): @skipIf(SKIP_DOCKER_TESTS, SKIP_DOCKER_MESSAGE) -class TestLoadingImagesFromArchive(BuildIntegBase): +class TestLoadingImagesFromArchiveContainer(BuildIntegBase): template = "template_loadable_image.yaml" FUNCTION_LOGICAL_ID = "ImageFunction" @@ -145,7 +146,7 @@ def test_load_success(self): ("template_cfn_local_prebuilt_image.yaml", "Code.ImageUri"), ], ) -class TestSkipBuildingFunctionsWithLocalImageUri(BuildIntegBase): +class TestSkipBuildingFunctionsWithLocalImageUriContainer(BuildIntegBase): EXPECTED_FILES_PROJECT_MANIFEST: Set[str] = set() FUNCTION_LOGICAL_ID_IMAGE = "ImageFunction" @@ -280,7 +281,7 @@ def _validate_skipped_built_function( @pytest.mark.ruby class TestBuildCommand_RubyFunctions(BuildIntegRubyBase): - @parameterized.expand([(False,), ("use_container",)]) + @parameterized.expand([(False,), ("use_container",)],name_func=show_container_in_test_name) def test_building_ruby_3_2(self, use_container): if use_container and SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: self.skipTest(SKIP_DOCKER_MESSAGE) @@ -290,14 +291,14 @@ def test_building_ruby_3_2(self, use_container): @parameterized.expand([("ruby3.3",), ("ruby3.4",)]) @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) @pytest.mark.al2023 - def test_building_ruby_al2023(self, runtime): + def test_building_ruby_al2023_in_container(self, runtime): self._test_with_default_gemfile(runtime, "use_container", "Ruby", self.test_data_path) class TestBuildCommand_RubyFunctions_With_Architecture(BuildIntegRubyBase): template = "template_with_architecture.yaml" - @parameterized.expand([(False,), ("use_container",)]) + @parameterized.expand([(False,), ("use_container",)],name_func=show_container_in_test_name) def test_building_ruby_3_2(self, use_container): if use_container and SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: self.skipTest(SKIP_DOCKER_MESSAGE) @@ -306,10 +307,11 @@ def test_building_ruby_3_2(self, use_container): @parameterized.expand( [ ("ruby3.3", "Ruby33", False), - ("ruby3.3", "Ruby33", True), + ("ruby3.3", "Ruby33", "use_container"), # ("ruby3.4", "Ruby34", False), # TODO: Try to make this work in AppVeyor (windows-al2023) - ("ruby3.4", "Ruby34", True), - ] + ("ruby3.4", "Ruby34", "use_container"), + ], + name_func=show_container_in_test_name ) @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) @pytest.mark.al2023 @@ -357,7 +359,7 @@ def _prepare_application_environment(self, runtime): class TestBuildCommand_Go_Modules(BuildIntegGoBase): - @parameterized.expand([("go1.x", "Go", None, False), ("go1.x", "Go", "debug", True)]) + @parameterized.expand([("go1.x", "Go", None, False), ("go1.x", "Go", "debug", "use_container")],name_func=show_container_in_test_name) def test_building_go(self, runtime, code_uri, mode, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -413,7 +415,7 @@ def test_function_not_found(self): ("python3.11", "use_container", "FunctionOne"), ("python3.11", False, "FunctionTwo"), ("python3.11", "use_container", "FunctionTwo"), - ] + ],name_func=show_container_in_test_name ) def test_build_single_function(self, runtime, use_container, function_identifier): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -518,7 +520,8 @@ class TestBuildCommand_LayerBuilds(BuildIntegBase): ("python3.12", "use_container", "LayerOne", "ContentUri"), ("python3.12", False, "LambdaLayerOne", "Content"), ("python3.12", "use_container", "LambdaLayerOne", "Content"), - ] + ], + name_func=show_container_in_test_name ) def test_build_single_layer(self, runtime, use_container, layer_identifier, content_property): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -542,7 +545,8 @@ def test_build_single_layer(self, runtime, use_container, layer_identifier, cont ) @parameterized.expand( - [("makefile", False, "LayerWithMakefile"), ("makefile", "use_container", "LayerWithMakefile")] + [("makefile", False, "LayerWithMakefile"), ("makefile", "use_container", "LayerWithMakefile")], + name_func=show_container_in_test_name ) def test_build_layer_with_makefile(self, build_method, use_container, layer_identifier): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -566,7 +570,7 @@ def test_build_layer_with_makefile(self, build_method, use_container, layer_iden ) @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) - def test_build_layer_with_makefile_no_compatible_runtimes(self): + def test_build_layer_with_makefile_no_compatible_runtimes_in_container(self): build_method = "makefile" use_container = True layer_identifier = "LayerWithMakefileNoCompatibleRuntimes" @@ -589,7 +593,8 @@ def test_build_layer_with_makefile_no_compatible_runtimes(self): ) @parameterized.expand( - [("makefile", False), ("makefile", "use_container"), ("python3.9", False), ("python3.9", "use_container")] + [("makefile", False), ("makefile", "use_container"), ("python3.9", False), ("python3.9", "use_container")], + name_func=show_container_in_test_name ) def test_build_layer_with_architecture_not_compatible(self, build_method, use_container): # The BuildArchitecture is not one of the listed CompatibleArchitectures @@ -617,7 +622,8 @@ def test_build_layer_with_architecture_not_compatible(self, build_method, use_co # Build should still succeed self.assertEqual(command_result.process.returncode, 0) - @parameterized.expand([("python3.11", False), ("python3.11", "use_container")]) + @parameterized.expand([("python3.11", False), ("python3.11", "use_container")], + name_func=show_container_in_test_name) def test_build_arch_no_compatible_arch(self, runtime, use_container): # BuildArchitecture is present, but CompatibleArchitectures section is missing if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -643,7 +649,8 @@ def test_build_arch_no_compatible_arch(self, runtime, use_container): # Build should still succeed self.assertEqual(command_result.process.returncode, 0) - @parameterized.expand([("python3.11", False), ("python3.11", "use_container")]) + @parameterized.expand([("python3.11", False), ("python3.11", "use_container")], + name_func=show_container_in_test_name) def test_compatible_arch_no_build_arch(self, runtime, use_container): # CompatibleArchitectures is present, but BuildArchitecture section is missing if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -694,7 +701,8 @@ def test_build_layer_with_makefile_with_fake_build_architecture(self): # Build should still succeed self.assertEqual(command_result.process.returncode, 0) - @parameterized.expand([("python3.12", False, "LayerTwo"), ("python3.12", "use_container", "LayerTwo")]) + @parameterized.expand([("python3.12", False, "LayerTwo"), ("python3.12", "use_container", "LayerTwo")], + name_func=show_container_in_test_name) def test_build_fails_with_missing_metadata(self, runtime, use_container, layer_identifier): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -708,7 +716,8 @@ def test_build_fails_with_missing_metadata(self, runtime, use_container, layer_i self.assertEqual(command_result.process.returncode, 1) self.assertFalse(self.default_build_dir.joinpath(layer_identifier).exists()) - @parameterized.expand([False, "use_container"]) + @parameterized.expand([False, "use_container"], + name_func=show_container_in_test_name) def test_function_build_succeeds_with_referenced_layer(self, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -722,7 +731,8 @@ def test_function_build_succeeds_with_referenced_layer(self, use_container): command_result = run_command(cmdlist, cwd=self.working_dir) self.assertEqual(command_result.process.returncode, 0) - @parameterized.expand([("python3.12", False), ("python3.12", "use_container")]) + @parameterized.expand([("python3.12", False), ("python3.12", "use_container")], + name_func=show_container_in_test_name) def test_build_function_and_layer(self, runtime, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -757,7 +767,8 @@ def test_build_function_and_layer(self, runtime, use_container): self.verify_docker_container_cleanedup(runtime) self.verify_pulled_image(runtime) - @parameterized.expand([("python3.12", False), ("python3.12", "use_container")]) + @parameterized.expand([("python3.12", False), ("python3.12", "use_container")], + name_func=show_container_in_test_name) def test_build_function_with_dependent_layer(self, runtime, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -828,7 +839,8 @@ class TestBuildWithBuildMethod(BuildIntegBase): FUNCTION_LOGICAL_ID = "Function" - @parameterized.expand([(False, None, "makefile"), ("use_container", "Makefile-container", "makefile")]) + @parameterized.expand([(False, None, "makefile"), ("use_container", "Makefile-container", "makefile")], + name_func=show_container_in_test_name) def test_with_makefile_builder_specified_python_runtime(self, use_container, manifest, build_method): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -864,7 +876,8 @@ def test_with_makefile_builder_specified_python_runtime(self, use_container, man self.verify_docker_container_cleanedup(runtime) self.verify_pulled_image(runtime) - @parameterized.expand([(False,), ("use_container")]) + @parameterized.expand([(False,), ("use_container")], + name_func=show_container_in_test_name) def test_with_native_builder_specified_python_runtime(self, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -973,16 +986,17 @@ class TestBuildWithDedupBuilds(DedupBuildIntegBase): (False, "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby3.4"), # container ( - True, + "use_container", "Java/gradlew/8", "aws.example.Hello::myHandler", "aws.example.SecondFunction::myHandler", "java8.al2", ), - (True, "Node", "main.lambdaHandler", "main.secondLambdaHandler", "nodejs20.x"), - (True, "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), - (True, "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby3.4"), - ] + ("use_container", "Node", "main.lambdaHandler", "main.secondLambdaHandler", "nodejs20.x"), + ("use_container", "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), + ("use_container", "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby3.4"), + ], + name_func=show_container_in_test_name ) def test_dedup_build(self, use_container, code_uri, function1_handler, function2_handler, runtime): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -1104,16 +1118,17 @@ class TestBuildWithCacheBuilds(CachedBuildIntegBase): (False, "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby3.4"), # container ( - True, + "use_container", "Java/gradlew/8", "aws.example.Hello::myHandler", "aws.example.SecondFunction::myHandler", "java8.al2", ), - (True, "Node", "main.lambdaHandler", "main.secondLambdaHandler", "nodejs20.x"), - (True, "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), - (True, "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby3.4"), - ] + ("use_container", "Node", "main.lambdaHandler", "main.secondLambdaHandler", "nodejs20.x"), + ("use_container", "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), + ("use_container", "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby3.4"), + ], + name_func=show_container_in_test_name ) def test_cache_build(self, use_container, code_uri, function1_handler, function2_handler, runtime): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -1175,7 +1190,7 @@ def test_no_cached_override_build(self): ) @skipIf(SKIP_DOCKER_TESTS, SKIP_DOCKER_MESSAGE) - def test_cached_build_with_env_vars(self): + def test_cached_build_with_env_vars_in_container(self): """ Build 2 times to verify that second time hits the cached build """ @@ -1214,7 +1229,8 @@ class TestRepeatedBuildHitsCache(BuildIntegBase): # Use template containing both functions and layers template = "layers-functions-template.yaml" - @parameterized.expand([(True,), (False,)]) + @parameterized.expand([("use_container",), (False,)], + name_func=show_container_in_test_name) def test_repeated_cached_build_hits_cache(self, use_container): """ Build 2 times to verify that second time hits the cached build @@ -1295,16 +1311,17 @@ class TestParallelBuilds(DedupBuildIntegBase): (False, "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby3.4"), # container ( - True, + "use_container", "Java/gradlew/8", "aws.example.Hello::myHandler", "aws.example.SecondFunction::myHandler", "java8.al2", ), - (True, "Node", "main.lambdaHandler", "main.secondLambdaHandler", "nodejs20.x"), - (True, "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), - (True, "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby3.4"), - ] + ("use_container", "Node", "main.lambdaHandler", "main.secondLambdaHandler", "nodejs20.x"), + ("use_container", "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), + ("use_container", "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby3.4"), + ], + name_func=show_container_in_test_name ) def test_dedup_build(self, use_container, code_uri, function1_handler, function2_handler, runtime): """ @@ -1374,7 +1391,8 @@ class TestBuildWithInlineCode(BuildIntegBase): [ (False,), ("use_container",), - ] + ], + name_func=show_container_in_test_name ) def test_inline_not_built(self, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -1421,7 +1439,8 @@ class TestBuildWithJsonContainerEnvVars(BuildIntegBase): [ ("use_container", "env_vars_function.json"), ("use_container", "env_vars_parameters.json"), - ] + ], + name_func=show_container_in_test_name ) def test_json_env_vars_passed(self, use_container, env_vars_file): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -1471,7 +1490,8 @@ class TestBuildWithInlineContainerEnvVars(BuildIntegBase): [ ("use_container", "TEST_ENV_VAR=MyVar"), ("use_container", "CheckEnvVarsFunction.TEST_ENV_VAR=MyVar"), - ] + ], + name_func=show_container_in_test_name ) def test_inline_env_vars_passed(self, use_container, inline_env_var): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -1525,7 +1545,8 @@ class TestBuildWithNestedStacks(NestedBuildIntegBase): True, True, ), - ] + ], + name_func=show_container_in_test_name ) def test_nested_build(self, use_container, cached, parallel): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -1601,7 +1622,7 @@ class TestBuildWithNestedStacks3Level(NestedBuildIntegBase): template = os.path.join("deep-nested", "template.yaml") - def test_nested_build(self): + def test_nested_build_in_conatiner(self): if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: self.skipTest(SKIP_DOCKER_MESSAGE) @@ -1663,7 +1684,7 @@ class TestBuildWithNestedStacks3LevelWithSymlink(NestedBuildIntegBase): template = os.path.join("deep-nested", "template-with-symlink.yaml") - def test_nested_build(self): + def test_nested_build_in_container(self): if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: self.skipTest(SKIP_DOCKER_MESSAGE) @@ -1743,7 +1764,8 @@ class TestBuildWithNestedStacksImage(NestedBuildIntegBase): True, True, ), - ] + ], + name_func=show_container_in_test_name ) def test_nested_build(self, use_container, cached, parallel): """ @@ -1803,7 +1825,8 @@ class TestBuildWithCustomBuildImage(BuildIntegBase): [ ("use_container", None), ("use_container", "public.ecr.aws/sam/build-python3.11:latest-x86_64"), - ] + ], + name_func=show_container_in_test_name ) def test_custom_build_image_succeeds(self, use_container, build_image): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -1860,7 +1883,7 @@ def _verify_build_succeeds(self, build_dir): ], ) class TestBuildPassingLayerAcrossStacks(IntrinsicIntegBase): - def test_nested_build(self): + def test_nested_build_in_container(self): if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: self.skipTest(SKIP_DOCKER_MESSAGE) @@ -1898,7 +1921,7 @@ class TestBuildWithS3FunctionsOrLayers(NestedBuildIntegBase): "requirements.txt", } - def test_functions_layers_with_s3_codeuri(self): + def test_functions_layers_with_s3_codeuri_in_container(self): if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: self.skipTest(SKIP_DOCKER_MESSAGE) @@ -1927,7 +1950,7 @@ def test_functions_layers_with_s3_codeuri(self): class TestBuildWithZipFunctionsOrLayers(NestedBuildIntegBase): template = "template-with-zip-code.yaml" - def test_functions_layers_with_s3_codeuri(self): + def test_functions_layers_with_s3_codeuri_in_container(self): if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: self.skipTest(SKIP_DOCKER_MESSAGE) @@ -1974,7 +1997,8 @@ def tearDownClass(cls): (False, "us-east-2"), (False, "eu-west-1"), (False, None), - ] + ], + name_func=show_container_in_test_name ) def test_sar_application_with_location_resolved_from_map(self, use_container, region): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): diff --git a/tests/integration/buildcmd/test_build_cmd_arm64.py b/tests/integration/buildcmd/test_build_cmd_arm64.py index b9862404eed..cefb41533ed 100644 --- a/tests/integration/buildcmd/test_build_cmd_arm64.py +++ b/tests/integration/buildcmd/test_build_cmd_arm64.py @@ -15,6 +15,7 @@ BuildIntegRubyBase, BuildIntegRustBase, rust_parameterized_class, + show_container_in_test_name, ) from tests.testing_utils import ( SKIP_DOCKER_TESTS, @@ -45,7 +46,8 @@ class TestBuildCommand_PythonFunctions_With_Specified_Architecture_arm64(BuildIn ("python3.9", "Python", "use_container"), ("python3.10", "Python", "use_container"), ("python3.11", "Python", "use_container"), - ] + ], + name_func=show_container_in_test_name ) def test_with_default_requirements(self, runtime, codeuri, use_container): self._test_with_default_requirements(runtime, codeuri, use_container, self.test_data_path, architecture=ARM64) @@ -54,7 +56,8 @@ def test_with_default_requirements(self, runtime, codeuri, use_container): [ ("python3.12", "Python", "use_container"), ("python3.13", "Python", "use_container"), - ] + ], + name_func=show_container_in_test_name ) @pytest.mark.al2023 def test_with_default_requirements_al2023(self, runtime, codeuri, use_container): @@ -76,7 +79,8 @@ class TestBuildCommand_EsbuildFunctions_arm64(BuildIntegEsbuildBase): "app.lambdaHandler", "use_container", ), - ] + ], + name_func=show_container_in_test_name ) def test_building_default_package_json(self, runtime, code_uri, expected_files, handler, use_container): self._test_with_default_package_json(runtime, use_container, code_uri, expected_files, handler, ARM64) @@ -117,7 +121,8 @@ class TestBuildCommand_EsbuildFunctions_With_External_Manifest_arm64(BuildIntegE "app.lambdaHandler", False, ), - ] + ], + name_func=show_container_in_test_name ) def test_building_default_package_json(self, runtime, code_uri, expected_files, handler, use_container): self._test_with_default_package_json(runtime, use_container, code_uri, expected_files, handler, ARM64) @@ -131,7 +136,8 @@ class TestBuildCommand_NodeFunctions_With_Specified_Architecture_arm64(BuildInte [ ("nodejs20.x", False), ("nodejs22.x", False), - ] + ], + name_func=show_container_in_test_name ) def test_building_default_package_json(self, runtime, use_container): self._test_with_default_package_json(runtime, use_container, self.test_data_path, ARM64) @@ -140,7 +146,8 @@ def test_building_default_package_json(self, runtime, use_container): [ ("nodejs20.x", "use_container"), ("nodejs22.x", "use_container"), - ] + ], + name_func=show_container_in_test_name ) @pytest.mark.al2023 def test_building_default_package_json_al2023(self, runtime, use_container): @@ -515,7 +522,8 @@ def test_building_Makefile(self, runtime, use_container, manifest): "use_container", "Makefile-container", ), - ] + ], + name_func=show_container_in_test_name ) @pytest.mark.al2023 def test_building_Makefile_al2023(self, runtime, use_container, manifest): @@ -535,7 +543,8 @@ class TestBuildCommand_Rust_arm64(BuildIntegRustBase): ("provided.al2", "debug", False), ("provided.al2023", None, False), ("provided.al2023", "debug", False), - ] + ], + name_func=show_container_in_test_name ) def test_build(self, runtime, build_mode, use_container): self._test_with_rust_cargo_lambda( diff --git a/tests/integration/buildcmd/test_build_cmd_dotnet.py b/tests/integration/buildcmd/test_build_cmd_dotnet.py index 47155e519e9..4179b098527 100644 --- a/tests/integration/buildcmd/test_build_cmd_dotnet.py +++ b/tests/integration/buildcmd/test_build_cmd_dotnet.py @@ -115,7 +115,7 @@ class TestBuildCommand_Dotnet_cli_package_interactive(BuildIntegDotnetBase): ("provided.al2", "Dotnet7", None), ] ) - def test_dotnet_al2_on_container(self, runtime, code_uri, mode): + def test_dotnet_al2_in_container(self, runtime, code_uri, mode): overrides = { "Runtime": runtime, "CodeUri": code_uri, @@ -135,7 +135,7 @@ def test_dotnet_al2_on_container(self, runtime, code_uri, mode): ("dotnet6", "Dotnet6", "debug"), ] ) - def test_dotnet_6_on_container(self, runtime, code_uri, mode): + def test_dotnet_6_in_container(self, runtime, code_uri, mode): overrides = { "Runtime": runtime, "CodeUri": code_uri, @@ -155,7 +155,7 @@ def test_dotnet_6_on_container(self, runtime, code_uri, mode): ) @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) @pytest.mark.al2023 - def test_dotnet_al2023_on_container(self, runtime, code_uri, mode): + def test_dotnet_al2023_in_container(self, runtime, code_uri, mode): overrides = { "Runtime": runtime, "CodeUri": code_uri, @@ -168,7 +168,7 @@ def test_dotnet_al2023_on_container(self, runtime, code_uri, mode): self.validate_invoke_command(overrides, runtime) @parameterized.expand([("dotnet6", "Dotnet6"), ("dotnet8", "Dotnet8")]) - def test_must_fail_on_container_mount_without_write_interactive(self, runtime, code_uri): + def test_must_fail_in_container_mount_without_write_interactive(self, runtime, code_uri): use_container = True overrides = { "Runtime": runtime, diff --git a/tests/integration/buildcmd/test_build_cmd_node.py b/tests/integration/buildcmd/test_build_cmd_node.py index f4bc7a9a469..38677f25e64 100644 --- a/tests/integration/buildcmd/test_build_cmd_node.py +++ b/tests/integration/buildcmd/test_build_cmd_node.py @@ -13,6 +13,7 @@ from tests.integration.buildcmd.build_integ_base import ( BuildIntegNodeBase, BuildIntegEsbuildBase, + show_container_in_test_name, ) @@ -32,7 +33,8 @@ class TestBuildCommand_NodeFunctions_With_External_Manifest(BuildIntegNodeBase): [ ("nodejs20.x",), ("nodejs22.x",), - ] + ], + name_func=show_container_in_test_name ) @pytest.mark.al2023 def test_building_default_package_json_al2023(self, runtime): @@ -46,7 +48,8 @@ class TestBuildCommand_EsbuildFunctions(BuildIntegEsbuildBase): [ ("nodejs20.x", "Esbuild/Node", {"main.js", "main.js.map"}, "main.lambdaHandler", False, "x86_64"), ("nodejs20.x", "Esbuild/TypeScript", {"app.js", "app.js.map"}, "app.lambdaHandler", False, "x86_64"), - ] + ], + name_func=show_container_in_test_name ) @pytest.mark.al2023 def test_building_default_package_json_al2023( @@ -78,7 +81,8 @@ class TestBuildCommand_EsbuildFunctions_With_External_Manifest(BuildIntegEsbuild False, "x86_64", ), - ] + ], + name_func=show_container_in_test_name ) @pytest.mark.al2023 def test_building_default_package_json( @@ -103,7 +107,8 @@ class TestBuildCommand_EsbuildFunctionProperties(BuildIntegEsbuildBase): [ ("nodejs20.x", "../Esbuild/TypeScript", "app.lambdaHandler", "x86_64"), ("nodejs20.x", "../Esbuild/TypeScript", "nested/function/app.lambdaHandler", "x86_64"), - ] + ], + name_func=show_container_in_test_name ) @pytest.mark.al2023 def test_environment_generates_sourcemap_al2023(self, runtime, code_uri, handler, architecture): @@ -125,7 +130,8 @@ class TestBuildCommand_NodeFunctions_With_Specified_Architecture(BuildIntegNodeB ("nodejs22.x", False, "x86_64"), ("nodejs20.x", "use_container", "x86_64"), ("nodejs22.x", "use_container", "x86_64"), - ] + ], + name_func=show_container_in_test_name ) def test_building_default_package_json(self, runtime, use_container, architecture): self._test_with_default_package_json(runtime, use_container, self.test_data_path, architecture) diff --git a/tests/integration/buildcmd/test_build_cmd_provided.py b/tests/integration/buildcmd/test_build_cmd_provided.py index e072b938a6a..d1c101d8f7e 100644 --- a/tests/integration/buildcmd/test_build_cmd_provided.py +++ b/tests/integration/buildcmd/test_build_cmd_provided.py @@ -13,6 +13,7 @@ ) from tests.integration.buildcmd.build_integ_base import ( BuildIntegProvidedBase, + show_container_in_test_name, ) @@ -39,7 +40,8 @@ class TestBuildCommand_ProvidedFunctions(BuildIntegProvidedBase): ("provided", "use_container", "Makefile-container"), ("provided.al2", False, None), ("provided.al2", "use_container", "Makefile-container"), - ] + ], + name_func=show_container_in_test_name ) def test_building_Makefile(self, runtime, use_container, manifest): if use_container: @@ -51,7 +53,8 @@ def test_building_Makefile(self, runtime, use_container, manifest): [ ("provided.al2023", False, None), ("provided.al2023", "use_container", "Makefile-container"), - ] + ], + name_func=show_container_in_test_name ) @pytest.mark.al2023 def test_building_Makefile_al2023(self, runtime, use_container, manifest): @@ -114,7 +117,8 @@ class TestBuildCommand_ProvidedFunctionsWithCustomMetadata(BuildIntegProvidedBas [ ("provided", False, None), ("provided.al2", False, None), - ] + ], + name_func=show_container_in_test_name ) def test_building_Makefile(self, runtime, use_container, manifest): self._test_with_Makefile(runtime, use_container, manifest) @@ -122,7 +126,8 @@ def test_building_Makefile(self, runtime, use_container, manifest): @parameterized.expand( [ ("provided.al2023", False, None), - ] + ], + name_func=show_container_in_test_name ) @pytest.mark.al2023 def test_building_Makefile_al2023(self, runtime, use_container, manifest): diff --git a/tests/integration/buildcmd/test_build_cmd_python.py b/tests/integration/buildcmd/test_build_cmd_python.py index f822f206e2e..a7a47eea499 100644 --- a/tests/integration/buildcmd/test_build_cmd_python.py +++ b/tests/integration/buildcmd/test_build_cmd_python.py @@ -10,6 +10,7 @@ from tests.integration.buildcmd.build_integ_base import ( BuildIntegBase, BuildIntegPythonBase, + show_container_in_test_name, ) from tests.testing_utils import ( CI_OVERRIDE, @@ -348,7 +349,7 @@ class TestBuildCommand_PythonFunctions_WithDocker(BuildIntegPythonBase): ("python3.11",), ] ) - def test_with_default_requirements(self, runtime): + def test_with_default_requirements_in_container(self, runtime): self._test_with_default_requirements( runtime, self.codeuri, @@ -365,7 +366,7 @@ def test_with_default_requirements(self, runtime): ] ) @pytest.mark.al2023 - def test_with_default_requirements_al2023(self, runtime): + def test_with_default_requirements_al2023_in_container(self, runtime): self._test_with_default_requirements( runtime, self.codeuri, @@ -473,7 +474,8 @@ class TestBuildCommand_PythonFunctions_With_Specified_Architecture(BuildIntegPyt ("python3.9", "Python", "use_container", "x86_64"), ("python3.10", "Python", "use_container", "x86_64"), ("python3.11", "Python", "use_container", "x86_64"), - ] + ], + name_func=show_container_in_test_name ) def test_with_default_requirements(self, runtime, codeuri, use_container, architecture): self._test_with_default_requirements( @@ -488,7 +490,8 @@ def test_with_default_requirements(self, runtime, codeuri, use_container, archit ("python3.13", "Python", False, "x86_64"), ("python3.13", "PythonPEP600", False, "x86_64"), ("python3.13", "Python", "use_container", "x86_64"), - ] + ], + name_func=show_container_in_test_name ) @pytest.mark.al2023 def test_with_default_requirements_al2023(self, runtime, codeuri, use_container, architecture): diff --git a/tests/integration/buildcmd/test_build_cmd_rust.py b/tests/integration/buildcmd/test_build_cmd_rust.py index 2c5b2dd7c5b..b69b99c9ce8 100644 --- a/tests/integration/buildcmd/test_build_cmd_rust.py +++ b/tests/integration/buildcmd/test_build_cmd_rust.py @@ -15,6 +15,7 @@ from .build_integ_base import ( BuildIntegRustBase, rust_parameterized_class, + show_container_in_test_name, ) LOG = logging.getLogger(__name__) @@ -32,7 +33,8 @@ class TestBuildCommand_Rust(BuildIntegRustBase): ("provided.al2", "x86_64", "debug", False), ("provided.al2023", "x86_64", None, False), ("provided.al2023", "x86_64", "debug", False), - ] + ], + name_func=show_container_in_test_name ) def test_build(self, runtime, architecture, build_mode, use_container): self._test_with_rust_cargo_lambda( From f3bd8de95f6a89711d8eb44167f78ce8071df698 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 30 Oct 2025 14:54:19 -0700 Subject: [PATCH 38/54] fix test issues --- .../integration/buildcmd/build_integ_base.py | 35 +++++++++++++++---- tests/integration/buildcmd/test_build_cmd.py | 20 +++++------ .../buildcmd/test_build_cmd_arm64.py | 6 ++-- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/tests/integration/buildcmd/build_integ_base.py b/tests/integration/buildcmd/build_integ_base.py index 5cc0484b5be..aae02aa49c2 100644 --- a/tests/integration/buildcmd/build_integ_base.py +++ b/tests/integration/buildcmd/build_integ_base.py @@ -115,8 +115,9 @@ def tearDown(self): def _cleanup_old_docker_images(self): """ - Clean up Docker images and layers that were created more than 3 minutes ago. + Clean up Docker images and layers that were created more than 5 minutes ago. This helps prevent disk space issues from accumulating test artifacts. + Excludes official SAM build images from public.ecr.aws/sam/build*. """ if SKIP_DOCKER_TESTS: return @@ -132,6 +133,20 @@ def _cleanup_old_docker_images(self): for image in all_images: try: + # Get image tags for logging and filtering + image_tags = image.tags if image.tags else [image.id[:12]] + + # Skip official SAM build images from public.ecr.aws/sam/build* + should_skip = False + for tag in image_tags: + if isinstance(tag, str) and tag.startswith("public.ecr.aws"): + should_skip = True + LOG.debug(f"Skipping official SAM build image: {tag}") + break + + if should_skip: + continue + # Get image creation time image_created = image.attrs.get('Created', '') if not image_created: @@ -146,11 +161,8 @@ def _cleanup_old_docker_images(self): else: created_timestamp = image_created - # Check if image was created more than 3 minutes ago + # Check if image was created more than 5 minutes ago if created_timestamp < five_minutes_ago: - # Get image tags for logging - image_tags = image.tags if image.tags else [image.id[:12]] - try: # Force remove the image (including layers) docker_client.images.remove(image.id, force=True) @@ -648,6 +660,17 @@ def _test_with_go(self, runtime, code_uri, mode, relative_path, architecture=Non newenv["GOPROXY"] = "direct" newenv["GOPATH"] = str(self.working_dir) + + # Build with musl target to avoid glibc compatibility issues + # This ensures the binary works in the Lambda execution environment + if architecture == ARM64: + newenv["GOOS"] = "linux" + newenv["GOARCH"] = "arm64" + newenv["CGO_ENABLED"] = "0" + else: + newenv["GOOS"] = "linux" + newenv["GOARCH"] = "amd64" + newenv["CGO_ENABLED"] = "0" run_command(cmdlist, cwd=self.working_dir, env=newenv) @@ -744,7 +767,7 @@ def _test_with_building_java( osutils.convert_to_unix_line_ending(os.path.join(self.test_data_path, self.USING_GRADLEW_PATH, "gradlew")) # Use shorter timeout in GitHub Actions to fail faster; # Putting 1800 because Windows Canary Instances takes longer - timeout = 300 if os.environ.get("GITHUB_ACTIONS") else 1800 + timeout = 1800 if os.environ.get("BY_CANARY") else 180 run_command(cmdlist, cwd=self.working_dir, timeout=timeout) self._verify_built_artifact( diff --git a/tests/integration/buildcmd/test_build_cmd.py b/tests/integration/buildcmd/test_build_cmd.py index 5c27c1bab74..121cbcc009b 100644 --- a/tests/integration/buildcmd/test_build_cmd.py +++ b/tests/integration/buildcmd/test_build_cmd.py @@ -224,7 +224,7 @@ def test_with_default_requirements(self, runtime): ), ], ) -class TestSkipBuildingFlaggedFunctions(BuildIntegPythonBase): +class TestSkipBuildingFlaggedFunctionsContainer(BuildIntegPythonBase): template = "template_cfn_function_flagged_to_skip_build.yaml" SKIPPED_FUNCTION_LOGICAL_ID = "SkippedFunction" src_code_path = "PreBuiltPython" @@ -417,7 +417,7 @@ def test_function_not_found(self): ("python3.11", "use_container", "FunctionTwo"), ],name_func=show_container_in_test_name ) - def test_build_single_function(self, runtime, use_container, function_identifier): + def test_build_single_function_invoke_in_container(self, runtime, use_container, function_identifier): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -733,7 +733,7 @@ def test_function_build_succeeds_with_referenced_layer(self, use_container): @parameterized.expand([("python3.12", False), ("python3.12", "use_container")], name_func=show_container_in_test_name) - def test_build_function_and_layer(self, runtime, use_container): + def test_build_function_and_layer_invoke_in_conatiner(self, runtime, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -769,7 +769,7 @@ def test_build_function_and_layer(self, runtime, use_container): @parameterized.expand([("python3.12", False), ("python3.12", "use_container")], name_func=show_container_in_test_name) - def test_build_function_with_dependent_layer(self, runtime, use_container): + def test_build_function_with_dependent_layer_invoke_in_container(self, runtime, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -841,7 +841,7 @@ class TestBuildWithBuildMethod(BuildIntegBase): @parameterized.expand([(False, None, "makefile"), ("use_container", "Makefile-container", "makefile")], name_func=show_container_in_test_name) - def test_with_makefile_builder_specified_python_runtime(self, use_container, manifest, build_method): + def test_with_makefile_builder_specified_python_runtime_invoke_in_container(self, use_container, manifest, build_method): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -878,7 +878,7 @@ def test_with_makefile_builder_specified_python_runtime(self, use_container, man @parameterized.expand([(False,), ("use_container")], name_func=show_container_in_test_name) - def test_with_native_builder_specified_python_runtime(self, use_container): + def test_with_native_builder_specified_python_runtime_invoke_in_container(self, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -1032,7 +1032,7 @@ def test_dedup_build(self, use_container, code_uri, function1_handler, function2 class TestBuildWithDedupImageBuilds(DedupBuildIntegBase): template = "dedup-functions-image-template.yaml" - def test_dedup_build(self): + def test_dedup_build_invoke_in_container(self): """ Build template above and verify that each function call returns as expected """ @@ -1359,7 +1359,7 @@ class TestParallelBuildsJavaWithLayers(DedupBuildIntegBase): template = "template-java-maven-with-layers.yaml" beta_features = False # parameterized - def test_dedup_build(self): + def test_dedup_build_invoke_in_container(self): """ Build template above and verify that each function call returns as expected """ @@ -1548,7 +1548,7 @@ class TestBuildWithNestedStacks(NestedBuildIntegBase): ], name_func=show_container_in_test_name ) - def test_nested_build(self, use_container, cached, parallel): + def test_nested_build_invoke_in_container(self, use_container, cached, parallel): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -1767,7 +1767,7 @@ class TestBuildWithNestedStacksImage(NestedBuildIntegBase): ], name_func=show_container_in_test_name ) - def test_nested_build(self, use_container, cached, parallel): + def test_nested_build_invoke_in_container(self, use_container, cached, parallel): """ Build template above and verify that each function call returns as expected """ diff --git a/tests/integration/buildcmd/test_build_cmd_arm64.py b/tests/integration/buildcmd/test_build_cmd_arm64.py index cefb41533ed..a6f975c82e2 100644 --- a/tests/integration/buildcmd/test_build_cmd_arm64.py +++ b/tests/integration/buildcmd/test_build_cmd_arm64.py @@ -27,6 +27,7 @@ ) +# this test will use docker to invoke in the end, we need to mark all these test as in_container @pytest.mark.python class TestBuildCommand_PythonFunctions_With_Specified_Architecture_arm64(BuildIntegPythonBase): template = "template_with_architecture.yaml" @@ -46,10 +47,9 @@ class TestBuildCommand_PythonFunctions_With_Specified_Architecture_arm64(BuildIn ("python3.9", "Python", "use_container"), ("python3.10", "Python", "use_container"), ("python3.11", "Python", "use_container"), - ], - name_func=show_container_in_test_name + ] ) - def test_with_default_requirements(self, runtime, codeuri, use_container): + def test_with_default_requirements_invoke_in_container(self, runtime, codeuri, use_container): self._test_with_default_requirements(runtime, codeuri, use_container, self.test_data_path, architecture=ARM64) @parameterized.expand( From ab8a735de1a826e8f8f09edad3570075abec69ea Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 30 Oct 2025 15:38:00 -0700 Subject: [PATCH 39/54] disk space --- .github/workflows/integration-tests.yml | 21 +-- .../integration/buildcmd/build_integ_base.py | 124 +++++++++--------- 2 files changed, 75 insertions(+), 70 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index e15d875a28d..4c54616a888 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -54,25 +54,30 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Free up disk space (background) + - name: Free up disk space run: | echo "Disk space before cleanup:" df -h - - # Remove all existing Docker images to free up space - echo "Removing all existing Docker images..." - # docker image prune -af || true - nohup docker system prune -af --volumes || true & - # Run cleanup in background to not block workflow nohup bash -c ' sudo apt-get clean + sudo rm -rf /usr/share/dotnet /usr/local/share/powershell sudo rm -rf /usr/local/lib/android sudo rm -rf /opt/ghc sudo rm -rf /opt/hostedtoolcache/CodeQL ' > /dev/null 2>&1 & - + # Remove all existing Docker images to free up space + echo "Removing all existing Docker images..." + if [ "${{ matrix.container_runtime }}" = "finch" ]; then + # For finch, run as blocking command to ensure cleanup completes + docker system prune -af --volumes || true + else + # For docker and no-container, run in background + nohup docker system prune -af --volumes || true & + fi + + - name: Configure AWS credentials via OIDC uses: aws-actions/configure-aws-credentials@v4 with: diff --git a/tests/integration/buildcmd/build_integ_base.py b/tests/integration/buildcmd/build_integ_base.py index aae02aa49c2..b1938a2d826 100644 --- a/tests/integration/buildcmd/build_integ_base.py +++ b/tests/integration/buildcmd/build_integ_base.py @@ -119,70 +119,70 @@ def _cleanup_old_docker_images(self): This helps prevent disk space issues from accumulating test artifacts. Excludes official SAM build images from public.ecr.aws/sam/build*. """ - if SKIP_DOCKER_TESTS: - return - - try: - docker_client = get_validated_container_client() - current_time = datetime.now(timezone.utc) - five_minutes_ago = current_time.timestamp() - 300 # 5 minutes in seconds - - # Get all images - all_images = docker_client.images.list() - removed_count = 0 - - for image in all_images: - try: - # Get image tags for logging and filtering - image_tags = image.tags if image.tags else [image.id[:12]] + # if SKIP_DOCKER_TESTS: + # return + + # try: + # docker_client = get_validated_container_client() + # current_time = datetime.now(timezone.utc) + # five_minutes_ago = current_time.timestamp() - 300 # 5 minutes in seconds + + # # Get all images + # all_images = docker_client.images.list() + # removed_count = 0 + + # for image in all_images: + # try: + # # Get image tags for logging and filtering + # image_tags = image.tags if image.tags else [image.id] - # Skip official SAM build images from public.ecr.aws/sam/build* - should_skip = False - for tag in image_tags: - if isinstance(tag, str) and tag.startswith("public.ecr.aws"): - should_skip = True - LOG.debug(f"Skipping official SAM build image: {tag}") - break + # # Skip official SAM build images from public.ecr.aws/sam/build* + # should_skip = False + # for tag in image_tags: + # if isinstance(tag, str) and tag.startswith("public.ecr.aws/sam"): + # should_skip = True + # LOG.debug(f"Skipping official SAM build image: {tag}") + # break - if should_skip: - continue - - # Get image creation time - image_created = image.attrs.get('Created', '') - if not image_created: - continue - - # Parse the creation timestamp - # Docker API returns ISO 8601 format with nanoseconds - if isinstance(image_created, str): - # Remove nanoseconds and parse - created_dt = datetime.fromisoformat(image_created.replace('Z', '+00:00').split('.')[0] + '+00:00') - created_timestamp = created_dt.timestamp() - else: - created_timestamp = image_created - - # Check if image was created more than 5 minutes ago - if created_timestamp < five_minutes_ago: - try: - # Force remove the image (including layers) - docker_client.images.remove(image.id, force=True) - removed_count += 1 - LOG.debug(f"Removed old Docker image: {image_tags}") - except Exception as remove_error: - # Image might be in use or already removed, log but continue - LOG.debug(f"Could not remove Docker image {image_tags}: {remove_error}") - - except Exception as image_error: - # Continue with other images if one fails - LOG.debug(f"Error processing Docker image: {image_error}") - continue - - if removed_count > 0: - LOG.info(f"Cleaned up {removed_count} old Docker image(s)") - - except Exception as e: - # Don't fail the test if Docker cleanup fails - LOG.warning(f"Failed to clean up old Docker images: {e}") + # if should_skip: + # continue + + # # Get image creation time + # image_created = image.attrs.get('Created', '') + # if not image_created: + # continue + + # # Parse the creation timestamp + # # Docker API returns ISO 8601 format with nanoseconds + # if isinstance(image_created, str): + # # Remove nanoseconds and parse + # created_dt = datetime.fromisoformat(image_created.replace('Z', '+00:00').split('.')[0] + '+00:00') + # created_timestamp = created_dt.timestamp() + # else: + # created_timestamp = image_created + + # # Check if image was created more than 5 minutes ago + # if created_timestamp < five_minutes_ago: + # try: + # # Force remove the image (including layers) + # docker_client.images.remove(image.id, force=True) + # removed_count += 1 + # LOG.debug(f"Removed old Docker image: {image_tags}") + # except Exception as remove_error: + # # Image might be in use or already removed, log but continue + # LOG.debug(f"Could not remove Docker image {image_tags}: {remove_error}") + + # except Exception as image_error: + # # Continue with other images if one fails + # LOG.debug(f"Error processing Docker image: {image_error}") + # continue + + # if removed_count > 0: + # LOG.info(f"Cleaned up {removed_count} old Docker image(s)") + + # except Exception as e: + # # Don't fail the test if Docker cleanup fails + # LOG.warning(f"Failed to clean up old Docker images: {e}") def get_command_list( self, From 3860bf4308115fd05a2e795dd8c9597c07184ae3 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 30 Oct 2025 16:10:07 -0700 Subject: [PATCH 40/54] tweak disk usage --- .github/workflows/integration-tests.yml | 11 +- .../integration/buildcmd/build_integ_base.py | 124 +++++++++--------- 2 files changed, 66 insertions(+), 69 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 4c54616a888..a9d7576e3e2 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -35,8 +35,8 @@ jobs: test_suite: - build-integ - build-integ-java-python-provided - - build-integ-arm64 - - build-integ-arm64-java + #- build-integ-arm64 # good + # - build-integ-arm64-java # good # - terraform-build # good #- package-delete-deploy # - sync # good @@ -60,11 +60,8 @@ jobs: df -h # Run cleanup in background to not block workflow nohup bash -c ' + sudo rm -rf /usr/share/dotnet /usr/local/share/powershell /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL sudo apt-get clean - sudo rm -rf /usr/share/dotnet /usr/local/share/powershell - sudo rm -rf /usr/local/lib/android - sudo rm -rf /opt/ghc - sudo rm -rf /opt/hostedtoolcache/CodeQL ' > /dev/null 2>&1 & # Remove all existing Docker images to free up space @@ -77,7 +74,7 @@ jobs: nohup docker system prune -af --volumes || true & fi - + - name: Configure AWS credentials via OIDC uses: aws-actions/configure-aws-credentials@v4 with: diff --git a/tests/integration/buildcmd/build_integ_base.py b/tests/integration/buildcmd/build_integ_base.py index b1938a2d826..7c9df2f1cce 100644 --- a/tests/integration/buildcmd/build_integ_base.py +++ b/tests/integration/buildcmd/build_integ_base.py @@ -119,70 +119,70 @@ def _cleanup_old_docker_images(self): This helps prevent disk space issues from accumulating test artifacts. Excludes official SAM build images from public.ecr.aws/sam/build*. """ - # if SKIP_DOCKER_TESTS: - # return - - # try: - # docker_client = get_validated_container_client() - # current_time = datetime.now(timezone.utc) - # five_minutes_ago = current_time.timestamp() - 300 # 5 minutes in seconds - - # # Get all images - # all_images = docker_client.images.list() - # removed_count = 0 - - # for image in all_images: - # try: - # # Get image tags for logging and filtering - # image_tags = image.tags if image.tags else [image.id] + if SKIP_DOCKER_TESTS: + return + + try: + docker_client = get_validated_container_client() + current_time = datetime.now(timezone.utc) + five_minutes_ago = current_time.timestamp() - 600 # 5 minutes in seconds + + # Get all images + all_images = docker_client.images.list() + removed_count = 0 + + for image in all_images: + try: + # Get image tags for logging and filtering + image_tags = image.tags if image.tags else [image.id] - # # Skip official SAM build images from public.ecr.aws/sam/build* - # should_skip = False - # for tag in image_tags: - # if isinstance(tag, str) and tag.startswith("public.ecr.aws/sam"): - # should_skip = True - # LOG.debug(f"Skipping official SAM build image: {tag}") - # break + # Skip official SAM build images from public.ecr.aws/sam/build* + should_skip = False + for tag in image_tags: + if isinstance(tag, str) and tag.startswith("public.ecr.aws/sam"): + should_skip = True + LOG.debug(f"Skipping official SAM build image: {tag}") + break - # if should_skip: - # continue - - # # Get image creation time - # image_created = image.attrs.get('Created', '') - # if not image_created: - # continue - - # # Parse the creation timestamp - # # Docker API returns ISO 8601 format with nanoseconds - # if isinstance(image_created, str): - # # Remove nanoseconds and parse - # created_dt = datetime.fromisoformat(image_created.replace('Z', '+00:00').split('.')[0] + '+00:00') - # created_timestamp = created_dt.timestamp() - # else: - # created_timestamp = image_created - - # # Check if image was created more than 5 minutes ago - # if created_timestamp < five_minutes_ago: - # try: - # # Force remove the image (including layers) - # docker_client.images.remove(image.id, force=True) - # removed_count += 1 - # LOG.debug(f"Removed old Docker image: {image_tags}") - # except Exception as remove_error: - # # Image might be in use or already removed, log but continue - # LOG.debug(f"Could not remove Docker image {image_tags}: {remove_error}") - - # except Exception as image_error: - # # Continue with other images if one fails - # LOG.debug(f"Error processing Docker image: {image_error}") - # continue - - # if removed_count > 0: - # LOG.info(f"Cleaned up {removed_count} old Docker image(s)") - - # except Exception as e: - # # Don't fail the test if Docker cleanup fails - # LOG.warning(f"Failed to clean up old Docker images: {e}") + if should_skip: + continue + + # Get image creation time + image_created = image.attrs.get('Created', '') + if not image_created: + continue + + # Parse the creation timestamp + # Docker API returns ISO 8601 format with nanoseconds + if isinstance(image_created, str): + # Remove nanoseconds and parse + created_dt = datetime.fromisoformat(image_created.replace('Z', '+00:00').split('.')[0] + '+00:00') + created_timestamp = created_dt.timestamp() + else: + created_timestamp = image_created + + # Check if image was created more than 5 minutes ago + if created_timestamp < five_minutes_ago: + try: + # Force remove the image (including layers) + docker_client.images.remove(image.id, force=True) + removed_count += 1 + LOG.debug(f"Removed old Docker image: {image_tags}") + except Exception as remove_error: + # Image might be in use or already removed, log but continue + LOG.debug(f"Could not remove Docker image {image_tags}: {remove_error}") + + except Exception as image_error: + # Continue with other images if one fails + LOG.debug(f"Error processing Docker image: {image_error}") + continue + + if removed_count > 0: + LOG.info(f"Cleaned up {removed_count} old Docker image(s)") + + except Exception as e: + # Don't fail the test if Docker cleanup fails + LOG.warning(f"Failed to clean up old Docker images: {e}") def get_command_list( self, From 77d1134f78b3f2a533e28f7ff2e2e81898a6fe50 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 30 Oct 2025 16:23:42 -0700 Subject: [PATCH 41/54] rest --- .github/workflows/integration-tests.yml | 28 ++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index a9d7576e3e2..7cefd3310ca 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -38,18 +38,29 @@ jobs: #- build-integ-arm64 # good # - build-integ-arm64-java # good # - terraform-build # good - #- package-delete-deploy + - package-delete-deploy # - sync # good - #- local-invoke - #- local-start - #- other-and-e2e + - local-invoke + - local-start + - local-start2 + - other-and-e2e exclude: # no-container mode only applies to build-integ test suites - container_runtime: no-container test_suite: terraform-build - container_runtime: no-container test_suite: sync - + - container_runtime: no-container + test_suite: package-delete-deploy + - container_runtime: no-container + test_suite: local-invoke + - container_runtime: no-container + test_suite: local-start + - container_runtime: no-container + test_suite: local-start2 + - container_runtime: no-container + test_suite: other-and-e2e + steps: - name: Checkout code uses: actions/checkout@v4 @@ -182,7 +193,7 @@ jobs: run: pip install cargo-lambda==${{ env.CARGO_LAMBDA_VERSION }} - name: Install Terraform - if: contains(fromJSON('["terraform-build", "local-invoke", "local-start"]'), matrix.test_suite) + if: contains(fromJSON('["terraform-build", "local-invoke", "local-start", "local-start2"]'), matrix.test_suite) run: | for i in {1..3}; do TER_VER=$(curl -s https://api.github.com/repos/hashicorp/terraform/releases/latest | grep tag_name | cut -d: -f2 | tr -d \"\,\v | awk '{$1=$1};1') @@ -333,7 +344,10 @@ jobs: pytest -vv --reruns 3 tests/integration/local/invoke tests/integration/local/generate_event --json-report --json-report-file=TEST_REPORT-integration-local-invoke-${{ matrix.container_runtime }}.json ;; "local-start") - pytest -vv --reruns 3 tests/integration/local/start_api tests/integration/local/start_lambda --json-report --json-report-file=TEST_REPORT-integration-local-start-${{ matrix.container_runtime }}.json + pytest -vv --reruns 3 tests/integration/local/start_api/test_start_api.py --json-report --json-report-file=TEST_REPORT-integration-local-start-${{ matrix.container_runtime }}.json + ;; + "local-start2") + pytest -vv --reruns 3 tests/integration/local/start_api tests/integration/local/start_lambda --ignore=tests/integration/local/start_api/test_start_api.py --json-report --json-report-file=TEST_REPORT-integration-local-start2-${{ matrix.container_runtime }}.json ;; "other-and-e2e") pytest -vv -n 4 --reruns 4 --dist loadgroup tests/integration tests/end_to_end --ignore=tests/integration/buildcmd --ignore=tests/integration/delete --ignore=tests/integration/deploy --ignore=tests/integration/package --ignore=tests/integration/sync --ignore=tests/integration/local --json-report --json-report-file=TEST_REPORT-integration-others-${{ matrix.container_runtime }}.json From 3535bb773d406d7df8de2271a8159058ebe1f4ad Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 30 Oct 2025 18:13:20 -0700 Subject: [PATCH 42/54] nit --- .github/workflows/integration-tests.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 7cefd3310ca..4319b77a7a5 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -152,7 +152,7 @@ jobs: gradle --version - name: Install .NET 8 SDK - if: contains(fromJSON('["build-integ", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' + if: contains(fromJSON('["build-integ", "build-integ-arm64", "other-and-e2e"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.x' @@ -320,10 +320,10 @@ jobs: case "${{ matrix.test_suite }}" in "build-integ") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not dotnet and not ruby and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json ;; "build-integ-java-python-provided") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or dotnet or ruby or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json ;; "build-integ-arm64") pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json @@ -335,7 +335,7 @@ jobs: pytest -vv -n 4 --reruns 4 tests/integration/buildcmd/test_build_terraform_applications.py tests/integration/buildcmd/test_build_terraform_applications_other_cases.py --json-report --json-report-file=TEST_REPORT-integration-terraform-${{ matrix.container_runtime }}.json ;; "package-delete-deploy") - pytest -vv tests/integration/package tests/integration/delete tests/integration/deploy --dist=loadgroup -n 4 --reruns 4 --json-report --json-report-file=TEST_REPORT-integration-package-delete-deploy-${{ matrix.container_runtime }}.json + pytest -vv tests/integration/package tests/integration/delete tests/integration/deploy --dist=loadgroup -n 6 --reruns 4 --json-report --json-report-file=TEST_REPORT-integration-package-delete-deploy-${{ matrix.container_runtime }}.json ;; "sync") pytest -vv tests/integration/sync -n 6 --reruns 3 --dist loadscope --json-report --json-report-file=TEST_REPORT-integration-sync-${{ matrix.container_runtime }}.json @@ -344,10 +344,10 @@ jobs: pytest -vv --reruns 3 tests/integration/local/invoke tests/integration/local/generate_event --json-report --json-report-file=TEST_REPORT-integration-local-invoke-${{ matrix.container_runtime }}.json ;; "local-start") - pytest -vv --reruns 3 tests/integration/local/start_api/test_start_api.py --json-report --json-report-file=TEST_REPORT-integration-local-start-${{ matrix.container_runtime }}.json + pytest -vv --reruns 3 tests/integration/local/start_api --json-report --json-report-file=TEST_REPORT-integration-local-start-${{ matrix.container_runtime }}.json ;; "local-start2") - pytest -vv --reruns 3 tests/integration/local/start_api tests/integration/local/start_lambda --ignore=tests/integration/local/start_api/test_start_api.py --json-report --json-report-file=TEST_REPORT-integration-local-start2-${{ matrix.container_runtime }}.json + pytest -vv --reruns 3 tests/integration/local/start_lambda --json-report --json-report-file=TEST_REPORT-integration-local-start2-${{ matrix.container_runtime }}.json ;; "other-and-e2e") pytest -vv -n 4 --reruns 4 --dist loadgroup tests/integration tests/end_to_end --ignore=tests/integration/buildcmd --ignore=tests/integration/delete --ignore=tests/integration/deploy --ignore=tests/integration/package --ignore=tests/integration/sync --ignore=tests/integration/local --json-report --json-report-file=TEST_REPORT-integration-others-${{ matrix.container_runtime }}.json From 56448dafb2a467252c6dd772e090f9e4d1d6efa3 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 30 Oct 2025 19:14:07 -0700 Subject: [PATCH 43/54] n --- .github/workflows/integration-tests.yml | 6 +++--- samcli/lib/utils/name_utils.py | 2 +- tests/integration/buildcmd/build_integ_base.py | 10 ++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 4319b77a7a5..7e6bc36aea3 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -152,7 +152,7 @@ jobs: gradle --version - name: Install .NET 8 SDK - if: contains(fromJSON('["build-integ", "build-integ-arm64", "other-and-e2e"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' + if: contains(fromJSON('["build-integ", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' || matrix.test_suite == 'other-and-e2e' uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.x' @@ -320,10 +320,10 @@ jobs: case "${{ matrix.test_suite }}" in "build-integ") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not dotnet and not ruby and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json ;; "build-integ-java-python-provided") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or dotnet or ruby or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json ;; "build-integ-arm64") pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json diff --git a/samcli/lib/utils/name_utils.py b/samcli/lib/utils/name_utils.py index ce74816e268..64f2476f882 100644 --- a/samcli/lib/utils/name_utils.py +++ b/samcli/lib/utils/name_utils.py @@ -12,7 +12,7 @@ MIN_ARN_PARTS = 5 # Minimum parts for a valid ARN structure LAMBDA_FUNCTION_NAME_PATTERN = ( - r"^(arn:[^:]+:lambda:[^:]*:\d{12}:function:|\d{12}:function:)?[a-zA-Z0-9-_\.]+(:[\w$-]+)?$" + r"^(arn:[^:]+:lambda:[^:]*:\d{12}:function:|\d{12}:function:)?[a-zA-Z0-9-_\.\[\]]+(:[\w$-]+)?$" ) diff --git a/tests/integration/buildcmd/build_integ_base.py b/tests/integration/buildcmd/build_integ_base.py index 7c9df2f1cce..f8f836a6d28 100644 --- a/tests/integration/buildcmd/build_integ_base.py +++ b/tests/integration/buildcmd/build_integ_base.py @@ -113,6 +113,16 @@ def tearDown(self): except Exception as e: LOG.warning(f"Failed to clean up scratch_dir {self.scratch_dir}: {e}") + # Close any Docker client connections to prevent socket warnings + try: + if not SKIP_DOCKER_TESTS: + docker_client = get_validated_container_client() + if hasattr(docker_client, 'close'): + docker_client.close() + LOG.debug("Closed Docker client connection") + except Exception as e: + LOG.debug(f"Could not close Docker client: {e}") + def _cleanup_old_docker_images(self): """ Clean up Docker images and layers that were created more than 5 minutes ago. From 67832b5c679e0be9d621fe3909af5356e12a2c62 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 30 Oct 2025 19:43:37 -0700 Subject: [PATCH 44/54] n --- .github/workflows/integration-tests.yml | 20 +++++++++++++++---- .../integration/buildcmd/build_integ_base.py | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 7e6bc36aea3..b9ffae843f6 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -71,7 +71,7 @@ jobs: df -h # Run cleanup in background to not block workflow nohup bash -c ' - sudo rm -rf /usr/share/dotnet /usr/local/share/powershell /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL + sudo rm -rf /usr/local/share/powershell /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL sudo apt-get clean ' > /dev/null 2>&1 & @@ -193,7 +193,7 @@ jobs: run: pip install cargo-lambda==${{ env.CARGO_LAMBDA_VERSION }} - name: Install Terraform - if: contains(fromJSON('["terraform-build", "local-invoke", "local-start", "local-start2"]'), matrix.test_suite) + if: contains(fromJSON('["terraform-build", "local-invoke", "local-start2"]'), matrix.test_suite) run: | for i in {1..3}; do TER_VER=$(curl -s https://api.github.com/repos/hashicorp/terraform/releases/latest | grep tag_name | cut -d: -f2 | tr -d \"\,\v | awk '{$1=$1};1') @@ -267,6 +267,18 @@ jobs: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi + - name: Login to Public ECR + if: matrix.container_runtime != 'no-container' && env.BY_CANARY == 'true' + run: | + if [ "${{ matrix.container_runtime }}" = "finch" ]; then + echo "Logging in Public ECR with Finch" + aws ecr-public get-login-password --region us-east-1 | sudo finch login --username AWS --password-stdin public.ecr.aws || { echo "FATAL: Finch Public ECR login failed"; exit 1; } + else + echo "Logging in Public ECR with Docker" + aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws || { echo "FATAL: Docker Public ECR login failed"; exit 1; } + fi + echo "Public ECR authentication completed successfully" + - name: Initialize project run: | export CONTAINER_RUNTIME=${{ matrix.container_runtime }} @@ -344,10 +356,10 @@ jobs: pytest -vv --reruns 3 tests/integration/local/invoke tests/integration/local/generate_event --json-report --json-report-file=TEST_REPORT-integration-local-invoke-${{ matrix.container_runtime }}.json ;; "local-start") - pytest -vv --reruns 3 tests/integration/local/start_api --json-report --json-report-file=TEST_REPORT-integration-local-start-${{ matrix.container_runtime }}.json + pytest -vv --reruns 3 tests/integration/local/start_api --ignore tests/integration/local/start_api/test_start_api_with_terraform_application.py --json-report --json-report-file=TEST_REPORT-integration-local-start-${{ matrix.container_runtime }}.json ;; "local-start2") - pytest -vv --reruns 3 tests/integration/local/start_lambda --json-report --json-report-file=TEST_REPORT-integration-local-start2-${{ matrix.container_runtime }}.json + pytest -vv --reruns 3 tests/integration/local/start_lambda tests/integration/local/start_api/test_start_api_with_terraform_application.py --json-report --json-report-file=TEST_REPORT-integration-local-start2-${{ matrix.container_runtime }}.json ;; "other-and-e2e") pytest -vv -n 4 --reruns 4 --dist loadgroup tests/integration tests/end_to_end --ignore=tests/integration/buildcmd --ignore=tests/integration/delete --ignore=tests/integration/deploy --ignore=tests/integration/package --ignore=tests/integration/sync --ignore=tests/integration/local --json-report --json-report-file=TEST_REPORT-integration-others-${{ matrix.container_runtime }}.json diff --git a/tests/integration/buildcmd/build_integ_base.py b/tests/integration/buildcmd/build_integ_base.py index f8f836a6d28..0ea894c4d51 100644 --- a/tests/integration/buildcmd/build_integ_base.py +++ b/tests/integration/buildcmd/build_integ_base.py @@ -135,7 +135,7 @@ def _cleanup_old_docker_images(self): try: docker_client = get_validated_container_client() current_time = datetime.now(timezone.utc) - five_minutes_ago = current_time.timestamp() - 600 # 5 minutes in seconds + five_minutes_ago = current_time.timestamp() - 300 # 5 minutes in seconds # Get all images all_images = docker_client.images.list() From 414b238f15d11683349dede59e490f17d5c684bf Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 30 Oct 2025 20:18:06 -0700 Subject: [PATCH 45/54] use secret --- .github/workflows/integration-tests.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index b9ffae843f6..e8764f034ac 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -15,6 +15,8 @@ env: SAM_CLI_TELEMETRY: 0 SAM_CLI_CONTAINER_CONNECTION_TIMEOUT: 60 NODE_VERSION: "22.21.1" + AWS_S3: 'AWS_S3_TESTING' + AWS_ECR: 'AWS_ECR_TESTING' CARGO_LAMBDA_VERSION: "v0.17.1" NOSE_PARAMETERIZED_NO_WARN: 1 GITHUB_ACTIONS_INTEG: true @@ -269,13 +271,16 @@ jobs: - name: Login to Public ECR if: matrix.container_runtime != 'no-container' && env.BY_CANARY == 'true' + env: + CI_DOCKER_USER: ${{ secrets.CI_DOCKER_USER }} + CI_DOCKER_PASSWD: ${{ secrets.CI_DOCKER_PASSWD }} run: | if [ "${{ matrix.container_runtime }}" = "finch" ]; then echo "Logging in Public ECR with Finch" - aws ecr-public get-login-password --region us-east-1 | sudo finch login --username AWS --password-stdin public.ecr.aws || { echo "FATAL: Finch Public ECR login failed"; exit 1; } + echo "$CI_DOCKER_PASSWD" | sudo finch login --username "$CI_DOCKER_USER" --password-stdin public.ecr.aws || { echo "FATAL: Finch Public ECR login failed"; exit 1; } else echo "Logging in Public ECR with Docker" - aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws || { echo "FATAL: Docker Public ECR login failed"; exit 1; } + echo "$CI_DOCKER_PASSWD" | docker login --username "$CI_DOCKER_USER" --password-stdin public.ecr.aws || { echo "FATAL: Docker Public ECR login failed"; exit 1; } fi echo "Public ECR authentication completed successfully" From bc79b1d2855abddd4396aa6f305382eb3c62adea Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 30 Oct 2025 20:32:49 -0700 Subject: [PATCH 46/54] secr --- .github/workflows/integration-tests.yml | 32 ++++++++++++------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index e8764f034ac..a6961d1e9c9 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -15,8 +15,8 @@ env: SAM_CLI_TELEMETRY: 0 SAM_CLI_CONTAINER_CONNECTION_TIMEOUT: 60 NODE_VERSION: "22.21.1" - AWS_S3: 'AWS_S3_TESTING' - AWS_ECR: 'AWS_ECR_TESTING' + AWS_S3: "AWS_S3_TESTING" + AWS_ECR: "AWS_ECR_TESTING" CARGO_LAMBDA_VERSION: "v0.17.1" NOSE_PARAMETERIZED_NO_WARN: 1 GITHUB_ACTIONS_INTEG: true @@ -269,21 +269,6 @@ jobs: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi - - name: Login to Public ECR - if: matrix.container_runtime != 'no-container' && env.BY_CANARY == 'true' - env: - CI_DOCKER_USER: ${{ secrets.CI_DOCKER_USER }} - CI_DOCKER_PASSWD: ${{ secrets.CI_DOCKER_PASSWD }} - run: | - if [ "${{ matrix.container_runtime }}" = "finch" ]; then - echo "Logging in Public ECR with Finch" - echo "$CI_DOCKER_PASSWD" | sudo finch login --username "$CI_DOCKER_USER" --password-stdin public.ecr.aws || { echo "FATAL: Finch Public ECR login failed"; exit 1; } - else - echo "Logging in Public ECR with Docker" - echo "$CI_DOCKER_PASSWD" | docker login --username "$CI_DOCKER_USER" --password-stdin public.ecr.aws || { echo "FATAL: Docker Public ECR login failed"; exit 1; } - fi - echo "Public ECR authentication completed successfully" - - name: Initialize project run: | export CONTAINER_RUNTIME=${{ matrix.container_runtime }} @@ -326,6 +311,19 @@ jobs: echo "AWS_ACCESS_KEY_ID (first 6 chars): ${ACCESS_KEY:0:6}..." echo "AWS_SECRET_ACCESS_KEY (first 6 chars): ${SECRET_KEY:0:6}..." + + - name: Login to Public ECR + if: matrix.container_runtime != 'no-container' && env.BY_CANARY == 'true' + run: | + if [ "${{ matrix.container_runtime }}" = "finch" ]; then + echo "Logging in Public ECR with Finch" + aws ecr-public get-login-password --region us-east-1 | sudo finch login --username AWS --password-stdin public.ecr.aws || { echo "FATAL: Finch Public ECR login failed"; exit 1; } + else + echo "Logging in Public ECR with Docker" + aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws || { echo "FATAL: Docker Public ECR login failed"; exit 1; } + fi + echo "Public ECR authentication completed successfully" + - name: Run tests run: | # Determine container keyword filter based on container_runtime From b522f542010484af12f71ae2c2d769161b908e19 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 30 Oct 2025 21:31:29 -0700 Subject: [PATCH 47/54] n --- .github/workflows/integration-tests.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index a6961d1e9c9..04185dbf62a 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -71,6 +71,13 @@ jobs: run: | echo "Disk space before cleanup:" df -h + + # Remove .NET if not needed (not other-and-e2e and not no-container) + if [ "${{ matrix.test_suite }}" != "other-and-e2e" ] && [ "${{ matrix.container_runtime }}" != "no-container" ]; then + echo "Removing .NET to free up disk space..." + nohup sudo rm -rf /usr/share/dotnet & + fi + # Run cleanup in background to not block workflow nohup bash -c ' sudo rm -rf /usr/local/share/powershell /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL @@ -86,7 +93,6 @@ jobs: # For docker and no-container, run in background nohup docker system prune -af --volumes || true & fi - - name: Configure AWS credentials via OIDC uses: aws-actions/configure-aws-credentials@v4 @@ -154,7 +160,7 @@ jobs: gradle --version - name: Install .NET 8 SDK - if: contains(fromJSON('["build-integ", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' || matrix.test_suite == 'other-and-e2e' + if: contains(fromJSON('["build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' || matrix.test_suite == 'other-and-e2e' uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.x' @@ -335,10 +341,10 @@ jobs: case "${{ matrix.test_suite }}" in "build-integ") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided and not dotnet' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json ;; "build-integ-java-python-provided") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided or dotnet' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json ;; "build-integ-arm64") pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json From 7e0fdfc50fc93453cbda41537becb1ef0b23d952 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 30 Oct 2025 23:04:04 -0700 Subject: [PATCH 48/54] run all test --- .github/workflows/integration-tests.yml | 26 +++--- samcli/lib/providers/sam_function_provider.py | 3 + tests/get_testing_resources.py | 4 +- .../integration/buildcmd/build_integ_base.py | 20 +++-- tests/integration/buildcmd/test_build_cmd.py | 84 +++++++++++-------- .../buildcmd/test_build_cmd_arm64.py | 14 ++-- .../buildcmd/test_build_cmd_node.py | 10 +-- .../buildcmd/test_build_cmd_provided.py | 8 +- .../buildcmd/test_build_cmd_python.py | 4 +- .../buildcmd/test_build_cmd_rust.py | 2 +- .../test_event/test_remote_test_event.py | 2 + tests/testing_utils.py | 2 +- 12 files changed, 101 insertions(+), 78 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 04185dbf62a..501ecfc10c6 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -37,11 +37,12 @@ jobs: test_suite: - build-integ - build-integ-java-python-provided - #- build-integ-arm64 # good - # - build-integ-arm64-java # good - # - terraform-build # good + - build-integ-dotnet-node-ruby + - build-integ-arm64 + - build-integ-arm64-java + - terraform-build - package-delete-deploy - # - sync # good + - sync - local-invoke - local-start - local-start2 @@ -111,7 +112,7 @@ jobs: 3.13 - name: Set up Node.js - if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' + if: contains(fromJSON('["build-integ", "build-integ-java-python-provided", "build-integ-dotnet-node-ruby", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} @@ -160,26 +161,26 @@ jobs: gradle --version - name: Install .NET 8 SDK - if: contains(fromJSON('["build-integ-java-python-provided", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' || matrix.test_suite == 'other-and-e2e' + if: contains(fromJSON('["build-integ-java-python-provided", "build-integ-dotnet-node-ruby", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container' || matrix.test_suite == 'other-and-e2e' uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.x' - name: Set up Ruby 3.3.7 - if: (contains(fromJSON('["build-integ", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container') || matrix.test_suite == 'other-and-e2e' + if: (contains(fromJSON('["build-integ","build-integ-dotnet-node-ruby", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container') || matrix.test_suite == 'other-and-e2e' uses: ruby/setup-ruby@v1 with: ruby-version: '3.3.7' - name: Set up Ruby 3.2.7 - if: (contains(fromJSON('["build-integ", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container') || matrix.test_suite == 'other-and-e2e' + if: (contains(fromJSON('["build-integ","build-integ-dotnet-node-ruby", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container') || matrix.test_suite == 'other-and-e2e' uses: ruby/setup-ruby@v1 with: ruby-version: '3.2.7' # sync test only need ruby 3.4 - name: Set up Ruby 3.4.2 - if: (contains(fromJSON('["build-integ", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container') || contains(fromJSON('["sync", "other-and-e2e"]'), matrix.test_suite) + if: (contains(fromJSON('["build-integ","build-integ-dotnet-node-ruby", "build-integ-arm64"]'), matrix.test_suite) && matrix.container_runtime == 'no-container') || contains(fromJSON('["sync", "other-and-e2e"]'), matrix.test_suite) uses: ruby/setup-ruby@v1 with: ruby-version: '3.4.7' @@ -341,10 +342,13 @@ jobs: case "${{ matrix.test_suite }}" in "build-integ") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided and not dotnet' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'not java and not python and not provided and not dotnet and not nodejs and not ruby' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-${{ matrix.container_runtime }}.json ;; "build-integ-java-python-provided") - pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided or dotnet' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'java or python or provided' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-java-python-provided-${{ matrix.container_runtime }}.json + ;; + "build-integ-dotnet-node-ruby") + pytest -vv -n 2 --reruns 3 tests/integration/buildcmd -m 'dotnet or nodejs or ruby' --ignore=tests/integration/buildcmd/test_build_cmd_arm64.py --ignore=tests/integration/buildcmd/test_build_terraform_applications.py --ignore=tests/integration/buildcmd/test_build_terraform_applications_other_cases.py -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-build-integ-dotnet-node-ruby-${{ matrix.container_runtime }}.json ;; "build-integ-arm64") pytest -vv -n 2 --reruns 3 tests/integration/buildcmd/test_build_cmd_arm64.py -m 'not java' -k "${CONTAINER_FILTER}" --json-report --json-report-file=TEST_REPORT-integration-buildcmd-arm64-${{ matrix.container_runtime }}.json diff --git a/samcli/lib/providers/sam_function_provider.py b/samcli/lib/providers/sam_function_provider.py index 5787fb409f8..b546fbfc8b6 100644 --- a/samcli/lib/providers/sam_function_provider.py +++ b/samcli/lib/providers/sam_function_provider.py @@ -542,6 +542,9 @@ def _parse_layer_info( ) if found_layer: layers.append(found_layer) + # When locate_layer_nested is True, we've already processed all layers from the template + # Return early to avoid processing them again from list_of_layers + return layers for layer in list_of_layers: if layer == "arn:aws:lambda:::awslayer:AmazonLinux1803": diff --git a/tests/get_testing_resources.py b/tests/get_testing_resources.py index 581e924deb0..1df5d622ad4 100644 --- a/tests/get_testing_resources.py +++ b/tests/get_testing_resources.py @@ -51,14 +51,14 @@ def get_testing_credentials(skip_role_deletion=False): ), region_name="us-west-2", ) - + # Prepare payload if skip_role_deletion is True if skip_role_deletion: payload_data = json.dumps({"skip_role_deletion": True}) response = lambda_client.invoke(FunctionName=lambda_arn, Payload=payload_data) else: response = lambda_client.invoke(FunctionName=lambda_arn) - + payload = json.loads(response["Payload"].read()) if response.get("FunctionError"): raise ValueError(f"Failed to get credential. {payload['errorType']}") diff --git a/tests/integration/buildcmd/build_integ_base.py b/tests/integration/buildcmd/build_integ_base.py index 0ea894c4d51..a423c6a6a2e 100644 --- a/tests/integration/buildcmd/build_integ_base.py +++ b/tests/integration/buildcmd/build_integ_base.py @@ -36,6 +36,7 @@ LOG = logging.getLogger(__name__) + def show_container_in_test_name(testcase_func, param_num, param): """ Generates a custom name for parameterized test cases. @@ -43,7 +44,7 @@ def show_container_in_test_name(testcase_func, param_num, param): """ # Get the base test name base_name = f"{testcase_func.__name__}_{param_num}" - + # Check if any parameter contains "container" in its string representation for arg in param.args: if isinstance(arg, str) and "container" in arg.lower(): @@ -53,9 +54,10 @@ def show_container_in_test_name(testcase_func, param_num, param): # Check if this might be a use_container parameter by position # This is a fallback for cases where True is used instead of "use_container" continue - + return base_name + class BuildIntegBase(TestCase): template: Optional[str] = "template.yaml" @@ -117,7 +119,7 @@ def tearDown(self): try: if not SKIP_DOCKER_TESTS: docker_client = get_validated_container_client() - if hasattr(docker_client, 'close'): + if hasattr(docker_client, "close"): docker_client.close() LOG.debug("Closed Docker client connection") except Exception as e: @@ -145,7 +147,7 @@ def _cleanup_old_docker_images(self): try: # Get image tags for logging and filtering image_tags = image.tags if image.tags else [image.id] - + # Skip official SAM build images from public.ecr.aws/sam/build* should_skip = False for tag in image_tags: @@ -153,12 +155,12 @@ def _cleanup_old_docker_images(self): should_skip = True LOG.debug(f"Skipping official SAM build image: {tag}") break - + if should_skip: continue # Get image creation time - image_created = image.attrs.get('Created', '') + image_created = image.attrs.get("Created", "") if not image_created: continue @@ -166,7 +168,9 @@ def _cleanup_old_docker_images(self): # Docker API returns ISO 8601 format with nanoseconds if isinstance(image_created, str): # Remove nanoseconds and parse - created_dt = datetime.fromisoformat(image_created.replace('Z', '+00:00').split('.')[0] + '+00:00') + created_dt = datetime.fromisoformat( + image_created.replace("Z", "+00:00").split(".")[0] + "+00:00" + ) created_timestamp = created_dt.timestamp() else: created_timestamp = image_created @@ -670,7 +674,7 @@ def _test_with_go(self, runtime, code_uri, mode, relative_path, architecture=Non newenv["GOPROXY"] = "direct" newenv["GOPATH"] = str(self.working_dir) - + # Build with musl target to avoid glibc compatibility issues # This ensures the binary works in the Lambda execution environment if architecture == ARM64: diff --git a/tests/integration/buildcmd/test_build_cmd.py b/tests/integration/buildcmd/test_build_cmd.py index 121cbcc009b..f59c8399431 100644 --- a/tests/integration/buildcmd/test_build_cmd.py +++ b/tests/integration/buildcmd/test_build_cmd.py @@ -281,7 +281,7 @@ def _validate_skipped_built_function( @pytest.mark.ruby class TestBuildCommand_RubyFunctions(BuildIntegRubyBase): - @parameterized.expand([(False,), ("use_container",)],name_func=show_container_in_test_name) + @parameterized.expand([(False,), ("use_container",)], name_func=show_container_in_test_name) def test_building_ruby_3_2(self, use_container): if use_container and SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: self.skipTest(SKIP_DOCKER_MESSAGE) @@ -298,7 +298,7 @@ def test_building_ruby_al2023_in_container(self, runtime): class TestBuildCommand_RubyFunctions_With_Architecture(BuildIntegRubyBase): template = "template_with_architecture.yaml" - @parameterized.expand([(False,), ("use_container",)],name_func=show_container_in_test_name) + @parameterized.expand([(False,), ("use_container",)], name_func=show_container_in_test_name) def test_building_ruby_3_2(self, use_container): if use_container and SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: self.skipTest(SKIP_DOCKER_MESSAGE) @@ -311,7 +311,7 @@ def test_building_ruby_3_2(self, use_container): # ("ruby3.4", "Ruby34", False), # TODO: Try to make this work in AppVeyor (windows-al2023) ("ruby3.4", "Ruby34", "use_container"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) @pytest.mark.al2023 @@ -359,7 +359,9 @@ def _prepare_application_environment(self, runtime): class TestBuildCommand_Go_Modules(BuildIntegGoBase): - @parameterized.expand([("go1.x", "Go", None, False), ("go1.x", "Go", "debug", "use_container")],name_func=show_container_in_test_name) + @parameterized.expand( + [("go1.x", "Go", None, False), ("go1.x", "Go", "debug", "use_container")], name_func=show_container_in_test_name + ) def test_building_go(self, runtime, code_uri, mode, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -415,7 +417,8 @@ def test_function_not_found(self): ("python3.11", "use_container", "FunctionOne"), ("python3.11", False, "FunctionTwo"), ("python3.11", "use_container", "FunctionTwo"), - ],name_func=show_container_in_test_name + ], + name_func=show_container_in_test_name, ) def test_build_single_function_invoke_in_container(self, runtime, use_container, function_identifier): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -521,7 +524,7 @@ class TestBuildCommand_LayerBuilds(BuildIntegBase): ("python3.12", False, "LambdaLayerOne", "Content"), ("python3.12", "use_container", "LambdaLayerOne", "Content"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_build_single_layer(self, runtime, use_container, layer_identifier, content_property): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -546,7 +549,7 @@ def test_build_single_layer(self, runtime, use_container, layer_identifier, cont @parameterized.expand( [("makefile", False, "LayerWithMakefile"), ("makefile", "use_container", "LayerWithMakefile")], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_build_layer_with_makefile(self, build_method, use_container, layer_identifier): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -594,7 +597,7 @@ def test_build_layer_with_makefile_no_compatible_runtimes_in_container(self): @parameterized.expand( [("makefile", False), ("makefile", "use_container"), ("python3.9", False), ("python3.9", "use_container")], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_build_layer_with_architecture_not_compatible(self, build_method, use_container): # The BuildArchitecture is not one of the listed CompatibleArchitectures @@ -622,8 +625,9 @@ def test_build_layer_with_architecture_not_compatible(self, build_method, use_co # Build should still succeed self.assertEqual(command_result.process.returncode, 0) - @parameterized.expand([("python3.11", False), ("python3.11", "use_container")], - name_func=show_container_in_test_name) + @parameterized.expand( + [("python3.11", False), ("python3.11", "use_container")], name_func=show_container_in_test_name + ) def test_build_arch_no_compatible_arch(self, runtime, use_container): # BuildArchitecture is present, but CompatibleArchitectures section is missing if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -649,8 +653,9 @@ def test_build_arch_no_compatible_arch(self, runtime, use_container): # Build should still succeed self.assertEqual(command_result.process.returncode, 0) - @parameterized.expand([("python3.11", False), ("python3.11", "use_container")], - name_func=show_container_in_test_name) + @parameterized.expand( + [("python3.11", False), ("python3.11", "use_container")], name_func=show_container_in_test_name + ) def test_compatible_arch_no_build_arch(self, runtime, use_container): # CompatibleArchitectures is present, but BuildArchitecture section is missing if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -701,8 +706,10 @@ def test_build_layer_with_makefile_with_fake_build_architecture(self): # Build should still succeed self.assertEqual(command_result.process.returncode, 0) - @parameterized.expand([("python3.12", False, "LayerTwo"), ("python3.12", "use_container", "LayerTwo")], - name_func=show_container_in_test_name) + @parameterized.expand( + [("python3.12", False, "LayerTwo"), ("python3.12", "use_container", "LayerTwo")], + name_func=show_container_in_test_name, + ) def test_build_fails_with_missing_metadata(self, runtime, use_container, layer_identifier): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -716,8 +723,7 @@ def test_build_fails_with_missing_metadata(self, runtime, use_container, layer_i self.assertEqual(command_result.process.returncode, 1) self.assertFalse(self.default_build_dir.joinpath(layer_identifier).exists()) - @parameterized.expand([False, "use_container"], - name_func=show_container_in_test_name) + @parameterized.expand([False, "use_container"], name_func=show_container_in_test_name) def test_function_build_succeeds_with_referenced_layer(self, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -731,8 +737,9 @@ def test_function_build_succeeds_with_referenced_layer(self, use_container): command_result = run_command(cmdlist, cwd=self.working_dir) self.assertEqual(command_result.process.returncode, 0) - @parameterized.expand([("python3.12", False), ("python3.12", "use_container")], - name_func=show_container_in_test_name) + @parameterized.expand( + [("python3.12", False), ("python3.12", "use_container")], name_func=show_container_in_test_name + ) def test_build_function_and_layer_invoke_in_conatiner(self, runtime, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -767,8 +774,9 @@ def test_build_function_and_layer_invoke_in_conatiner(self, runtime, use_contain self.verify_docker_container_cleanedup(runtime) self.verify_pulled_image(runtime) - @parameterized.expand([("python3.12", False), ("python3.12", "use_container")], - name_func=show_container_in_test_name) + @parameterized.expand( + [("python3.12", False), ("python3.12", "use_container")], name_func=show_container_in_test_name + ) def test_build_function_with_dependent_layer_invoke_in_container(self, runtime, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -839,9 +847,13 @@ class TestBuildWithBuildMethod(BuildIntegBase): FUNCTION_LOGICAL_ID = "Function" - @parameterized.expand([(False, None, "makefile"), ("use_container", "Makefile-container", "makefile")], - name_func=show_container_in_test_name) - def test_with_makefile_builder_specified_python_runtime_invoke_in_container(self, use_container, manifest, build_method): + @parameterized.expand( + [(False, None, "makefile"), ("use_container", "Makefile-container", "makefile")], + name_func=show_container_in_test_name, + ) + def test_with_makefile_builder_specified_python_runtime_invoke_in_container( + self, use_container, manifest, build_method + ): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -876,8 +888,7 @@ def test_with_makefile_builder_specified_python_runtime_invoke_in_container(self self.verify_docker_container_cleanedup(runtime) self.verify_pulled_image(runtime) - @parameterized.expand([(False,), ("use_container")], - name_func=show_container_in_test_name) + @parameterized.expand([(False,), ("use_container")], name_func=show_container_in_test_name) def test_with_native_builder_specified_python_runtime_invoke_in_container(self, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): self.skipTest(SKIP_DOCKER_MESSAGE) @@ -996,7 +1007,7 @@ class TestBuildWithDedupBuilds(DedupBuildIntegBase): ("use_container", "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), ("use_container", "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby3.4"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_dedup_build(self, use_container, code_uri, function1_handler, function2_handler, runtime): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -1128,7 +1139,7 @@ class TestBuildWithCacheBuilds(CachedBuildIntegBase): ("use_container", "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), ("use_container", "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby3.4"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_cache_build(self, use_container, code_uri, function1_handler, function2_handler, runtime): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -1229,8 +1240,7 @@ class TestRepeatedBuildHitsCache(BuildIntegBase): # Use template containing both functions and layers template = "layers-functions-template.yaml" - @parameterized.expand([("use_container",), (False,)], - name_func=show_container_in_test_name) + @parameterized.expand([("use_container",), (False,)], name_func=show_container_in_test_name) def test_repeated_cached_build_hits_cache(self, use_container): """ Build 2 times to verify that second time hits the cached build @@ -1321,7 +1331,7 @@ class TestParallelBuilds(DedupBuildIntegBase): ("use_container", "Python", "main.first_function_handler", "main.second_function_handler", "python3.9"), ("use_container", "Ruby", "app.lambda_handler", "app.second_lambda_handler", "ruby3.4"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_dedup_build(self, use_container, code_uri, function1_handler, function2_handler, runtime): """ @@ -1392,7 +1402,7 @@ class TestBuildWithInlineCode(BuildIntegBase): (False,), ("use_container",), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_inline_not_built(self, use_container): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -1440,7 +1450,7 @@ class TestBuildWithJsonContainerEnvVars(BuildIntegBase): ("use_container", "env_vars_function.json"), ("use_container", "env_vars_parameters.json"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_json_env_vars_passed(self, use_container, env_vars_file): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -1491,7 +1501,7 @@ class TestBuildWithInlineContainerEnvVars(BuildIntegBase): ("use_container", "TEST_ENV_VAR=MyVar"), ("use_container", "CheckEnvVarsFunction.TEST_ENV_VAR=MyVar"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_inline_env_vars_passed(self, use_container, inline_env_var): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -1546,7 +1556,7 @@ class TestBuildWithNestedStacks(NestedBuildIntegBase): True, ), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_nested_build_invoke_in_container(self, use_container, cached, parallel): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -1765,7 +1775,7 @@ class TestBuildWithNestedStacksImage(NestedBuildIntegBase): True, ), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_nested_build_invoke_in_container(self, use_container, cached, parallel): """ @@ -1826,7 +1836,7 @@ class TestBuildWithCustomBuildImage(BuildIntegBase): ("use_container", None), ("use_container", "public.ecr.aws/sam/build-python3.11:latest-x86_64"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_custom_build_image_succeeds(self, use_container, build_image): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): @@ -1998,7 +2008,7 @@ def tearDownClass(cls): (False, "eu-west-1"), (False, None), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_sar_application_with_location_resolved_from_map(self, use_container, region): if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD): diff --git a/tests/integration/buildcmd/test_build_cmd_arm64.py b/tests/integration/buildcmd/test_build_cmd_arm64.py index a6f975c82e2..cb0ff24f452 100644 --- a/tests/integration/buildcmd/test_build_cmd_arm64.py +++ b/tests/integration/buildcmd/test_build_cmd_arm64.py @@ -57,7 +57,7 @@ def test_with_default_requirements_invoke_in_container(self, runtime, codeuri, u ("python3.12", "Python", "use_container"), ("python3.13", "Python", "use_container"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) @pytest.mark.al2023 def test_with_default_requirements_al2023(self, runtime, codeuri, use_container): @@ -80,7 +80,7 @@ class TestBuildCommand_EsbuildFunctions_arm64(BuildIntegEsbuildBase): "use_container", ), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_building_default_package_json(self, runtime, code_uri, expected_files, handler, use_container): self._test_with_default_package_json(runtime, use_container, code_uri, expected_files, handler, ARM64) @@ -122,7 +122,7 @@ class TestBuildCommand_EsbuildFunctions_With_External_Manifest_arm64(BuildIntegE False, ), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_building_default_package_json(self, runtime, code_uri, expected_files, handler, use_container): self._test_with_default_package_json(runtime, use_container, code_uri, expected_files, handler, ARM64) @@ -137,7 +137,7 @@ class TestBuildCommand_NodeFunctions_With_Specified_Architecture_arm64(BuildInte ("nodejs20.x", False), ("nodejs22.x", False), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_building_default_package_json(self, runtime, use_container): self._test_with_default_package_json(runtime, use_container, self.test_data_path, ARM64) @@ -147,7 +147,7 @@ def test_building_default_package_json(self, runtime, use_container): ("nodejs20.x", "use_container"), ("nodejs22.x", "use_container"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) @pytest.mark.al2023 def test_building_default_package_json_al2023(self, runtime, use_container): @@ -523,7 +523,7 @@ def test_building_Makefile(self, runtime, use_container, manifest): "Makefile-container", ), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) @pytest.mark.al2023 def test_building_Makefile_al2023(self, runtime, use_container, manifest): @@ -544,7 +544,7 @@ class TestBuildCommand_Rust_arm64(BuildIntegRustBase): ("provided.al2023", None, False), ("provided.al2023", "debug", False), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_build(self, runtime, build_mode, use_container): self._test_with_rust_cargo_lambda( diff --git a/tests/integration/buildcmd/test_build_cmd_node.py b/tests/integration/buildcmd/test_build_cmd_node.py index 38677f25e64..72e4ffb8143 100644 --- a/tests/integration/buildcmd/test_build_cmd_node.py +++ b/tests/integration/buildcmd/test_build_cmd_node.py @@ -34,7 +34,7 @@ class TestBuildCommand_NodeFunctions_With_External_Manifest(BuildIntegNodeBase): ("nodejs20.x",), ("nodejs22.x",), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) @pytest.mark.al2023 def test_building_default_package_json_al2023(self, runtime): @@ -49,7 +49,7 @@ class TestBuildCommand_EsbuildFunctions(BuildIntegEsbuildBase): ("nodejs20.x", "Esbuild/Node", {"main.js", "main.js.map"}, "main.lambdaHandler", False, "x86_64"), ("nodejs20.x", "Esbuild/TypeScript", {"app.js", "app.js.map"}, "app.lambdaHandler", False, "x86_64"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) @pytest.mark.al2023 def test_building_default_package_json_al2023( @@ -82,7 +82,7 @@ class TestBuildCommand_EsbuildFunctions_With_External_Manifest(BuildIntegEsbuild "x86_64", ), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) @pytest.mark.al2023 def test_building_default_package_json( @@ -108,7 +108,7 @@ class TestBuildCommand_EsbuildFunctionProperties(BuildIntegEsbuildBase): ("nodejs20.x", "../Esbuild/TypeScript", "app.lambdaHandler", "x86_64"), ("nodejs20.x", "../Esbuild/TypeScript", "nested/function/app.lambdaHandler", "x86_64"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) @pytest.mark.al2023 def test_environment_generates_sourcemap_al2023(self, runtime, code_uri, handler, architecture): @@ -131,7 +131,7 @@ class TestBuildCommand_NodeFunctions_With_Specified_Architecture(BuildIntegNodeB ("nodejs20.x", "use_container", "x86_64"), ("nodejs22.x", "use_container", "x86_64"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_building_default_package_json(self, runtime, use_container, architecture): self._test_with_default_package_json(runtime, use_container, self.test_data_path, architecture) diff --git a/tests/integration/buildcmd/test_build_cmd_provided.py b/tests/integration/buildcmd/test_build_cmd_provided.py index d1c101d8f7e..dfbe5595972 100644 --- a/tests/integration/buildcmd/test_build_cmd_provided.py +++ b/tests/integration/buildcmd/test_build_cmd_provided.py @@ -41,7 +41,7 @@ class TestBuildCommand_ProvidedFunctions(BuildIntegProvidedBase): ("provided.al2", False, None), ("provided.al2", "use_container", "Makefile-container"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_building_Makefile(self, runtime, use_container, manifest): if use_container: @@ -54,7 +54,7 @@ def test_building_Makefile(self, runtime, use_container, manifest): ("provided.al2023", False, None), ("provided.al2023", "use_container", "Makefile-container"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) @pytest.mark.al2023 def test_building_Makefile_al2023(self, runtime, use_container, manifest): @@ -118,7 +118,7 @@ class TestBuildCommand_ProvidedFunctionsWithCustomMetadata(BuildIntegProvidedBas ("provided", False, None), ("provided.al2", False, None), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_building_Makefile(self, runtime, use_container, manifest): self._test_with_Makefile(runtime, use_container, manifest) @@ -127,7 +127,7 @@ def test_building_Makefile(self, runtime, use_container, manifest): [ ("provided.al2023", False, None), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) @pytest.mark.al2023 def test_building_Makefile_al2023(self, runtime, use_container, manifest): diff --git a/tests/integration/buildcmd/test_build_cmd_python.py b/tests/integration/buildcmd/test_build_cmd_python.py index a7a47eea499..4956ab15022 100644 --- a/tests/integration/buildcmd/test_build_cmd_python.py +++ b/tests/integration/buildcmd/test_build_cmd_python.py @@ -475,7 +475,7 @@ class TestBuildCommand_PythonFunctions_With_Specified_Architecture(BuildIntegPyt ("python3.10", "Python", "use_container", "x86_64"), ("python3.11", "Python", "use_container", "x86_64"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_with_default_requirements(self, runtime, codeuri, use_container, architecture): self._test_with_default_requirements( @@ -491,7 +491,7 @@ def test_with_default_requirements(self, runtime, codeuri, use_container, archit ("python3.13", "PythonPEP600", False, "x86_64"), ("python3.13", "Python", "use_container", "x86_64"), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) @pytest.mark.al2023 def test_with_default_requirements_al2023(self, runtime, codeuri, use_container, architecture): diff --git a/tests/integration/buildcmd/test_build_cmd_rust.py b/tests/integration/buildcmd/test_build_cmd_rust.py index b69b99c9ce8..f50502d8ce2 100644 --- a/tests/integration/buildcmd/test_build_cmd_rust.py +++ b/tests/integration/buildcmd/test_build_cmd_rust.py @@ -34,7 +34,7 @@ class TestBuildCommand_Rust(BuildIntegRustBase): ("provided.al2023", "x86_64", None, False), ("provided.al2023", "x86_64", "debug", False), ], - name_func=show_container_in_test_name + name_func=show_container_in_test_name, ) def test_build(self, runtime, architecture, build_mode, use_container): self._test_with_rust_cargo_lambda( diff --git a/tests/integration/remote/test_event/test_remote_test_event.py b/tests/integration/remote/test_event/test_remote_test_event.py index d3d0bb62b55..4f062a805f7 100644 --- a/tests/integration/remote/test_event/test_remote_test_event.py +++ b/tests/integration/remote/test_event/test_remote_test_event.py @@ -1,5 +1,6 @@ import json import os +import time import uuid import pytest @@ -63,6 +64,7 @@ def test_event_workflow(self): # Check two events self.list_events_and_check(self.stack_name, function_to_check, os.linesep.join(["event1", "event2"])) + time.sleep(2) # Invoke with two events (function returns the same event that it receives) self.remote_invoke_and_check(self.stack_name, function_to_check, "event1", event_contents1) self.remote_invoke_and_check(self.stack_name, function_to_check, "event2", event_contents2) diff --git a/tests/testing_utils.py b/tests/testing_utils.py index 87a2181f71f..e92e6b75e00 100644 --- a/tests/testing_utils.py +++ b/tests/testing_utils.py @@ -30,7 +30,7 @@ os.environ.get("APPVEYOR_REPO_BRANCH", os.environ.get("GITHUB_REF_NAME", "master")) != "master" ) CI_OVERRIDE = ( - os.environ.get("APPVEYOR_CI_OVERRIDE", False) + os.environ.get("APPVEYOR_CI_OVERRIDE", False) or os.environ.get("CI_OVERRIDE", False) or os.environ.get("GITHUB_ACTIONS_INTEG", False) ) From d4a6f2c7866b9f26155f75fa9dfce2be87ff1e46 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Thu, 30 Oct 2025 23:59:11 -0700 Subject: [PATCH 49/54] m --- .github/workflows/integration-tests.yml | 3 +- samcli/lib/providers/sam_function_provider.py | 3 - .../integration/buildcmd/build_integ_base.py | 116 +----------------- .../test_event/test_remote_test_event.py | 1 - tests/testing_utils.py | 2 +- 5 files changed, 5 insertions(+), 120 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 501ecfc10c6..b6e97c9277c 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -19,7 +19,6 @@ env: AWS_ECR: "AWS_ECR_TESTING" CARGO_LAMBDA_VERSION: "v0.17.1" NOSE_PARAMETERIZED_NO_WARN: 1 - GITHUB_ACTIONS_INTEG: true BY_CANARY: true UV_PYTHON: python3.9 CREDENTIAL_DISTRIBUTION_LAMBDA_ARN: arn:aws:lambda:us-west-2:123087993316:function:test-account-management-CredentialDistributionLamb-o1sEaa8lvO1L @@ -74,7 +73,7 @@ jobs: df -h # Remove .NET if not needed (not other-and-e2e and not no-container) - if [ "${{ matrix.test_suite }}" != "other-and-e2e" ] && [ "${{ matrix.container_runtime }}" != "no-container" ]; then + if [ "${{ matrix.test_suite }}" != "other-and-e2e" ] && [ "${{ matrix.test_suite }}" != "sync" ] && [ "${{ matrix.container_runtime }}" != "no-container" ]; then echo "Removing .NET to free up disk space..." nohup sudo rm -rf /usr/share/dotnet & fi diff --git a/samcli/lib/providers/sam_function_provider.py b/samcli/lib/providers/sam_function_provider.py index b546fbfc8b6..5787fb409f8 100644 --- a/samcli/lib/providers/sam_function_provider.py +++ b/samcli/lib/providers/sam_function_provider.py @@ -542,9 +542,6 @@ def _parse_layer_info( ) if found_layer: layers.append(found_layer) - # When locate_layer_nested is True, we've already processed all layers from the template - # Return early to avoid processing them again from list_of_layers - return layers for layer in list_of_layers: if layer == "arn:aws:lambda:::awslayer:AmazonLinux1803": diff --git a/tests/integration/buildcmd/build_integ_base.py b/tests/integration/buildcmd/build_integ_base.py index a423c6a6a2e..8291bce4e20 100644 --- a/tests/integration/buildcmd/build_integ_base.py +++ b/tests/integration/buildcmd/build_integ_base.py @@ -84,119 +84,9 @@ def setUp(self): self.built_template = self.default_build_dir.joinpath("template.yaml") def tearDown(self): - """ - Clean up all test-generated artifacts after each test. - Cleanup order is important: child directories before parent directories. - """ - # Clean up Docker images and layers created more than 5 minutes ago - self._cleanup_old_docker_images() - - # Clean up custom build directory if it exists - if self.custom_build_dir and os.path.exists(self.custom_build_dir): - try: - shutil.rmtree(self.custom_build_dir) - LOG.debug(f"Cleaned up custom_build_dir: {self.custom_build_dir}") - except Exception as e: - LOG.warning(f"Failed to clean up custom_build_dir {self.custom_build_dir}: {e}") - - # Clean up working directory (contains default_build_dir) if it exists - if self.working_dir and os.path.exists(self.working_dir): - try: - shutil.rmtree(self.working_dir) - LOG.debug(f"Cleaned up working_dir: {self.working_dir}") - except Exception as e: - LOG.warning(f"Failed to clean up working_dir {self.working_dir}: {e}") - - # Clean up scratch directory (parent of all test artifacts) if it exists - if self.scratch_dir and os.path.exists(self.scratch_dir): - try: - shutil.rmtree(self.scratch_dir) - LOG.debug(f"Cleaned up scratch_dir: {self.scratch_dir}") - except Exception as e: - LOG.warning(f"Failed to clean up scratch_dir {self.scratch_dir}: {e}") - - # Close any Docker client connections to prevent socket warnings - try: - if not SKIP_DOCKER_TESTS: - docker_client = get_validated_container_client() - if hasattr(docker_client, "close"): - docker_client.close() - LOG.debug("Closed Docker client connection") - except Exception as e: - LOG.debug(f"Could not close Docker client: {e}") - - def _cleanup_old_docker_images(self): - """ - Clean up Docker images and layers that were created more than 5 minutes ago. - This helps prevent disk space issues from accumulating test artifacts. - Excludes official SAM build images from public.ecr.aws/sam/build*. - """ - if SKIP_DOCKER_TESTS: - return - - try: - docker_client = get_validated_container_client() - current_time = datetime.now(timezone.utc) - five_minutes_ago = current_time.timestamp() - 300 # 5 minutes in seconds - - # Get all images - all_images = docker_client.images.list() - removed_count = 0 - - for image in all_images: - try: - # Get image tags for logging and filtering - image_tags = image.tags if image.tags else [image.id] - - # Skip official SAM build images from public.ecr.aws/sam/build* - should_skip = False - for tag in image_tags: - if isinstance(tag, str) and tag.startswith("public.ecr.aws/sam"): - should_skip = True - LOG.debug(f"Skipping official SAM build image: {tag}") - break - - if should_skip: - continue - - # Get image creation time - image_created = image.attrs.get("Created", "") - if not image_created: - continue - - # Parse the creation timestamp - # Docker API returns ISO 8601 format with nanoseconds - if isinstance(image_created, str): - # Remove nanoseconds and parse - created_dt = datetime.fromisoformat( - image_created.replace("Z", "+00:00").split(".")[0] + "+00:00" - ) - created_timestamp = created_dt.timestamp() - else: - created_timestamp = image_created - - # Check if image was created more than 5 minutes ago - if created_timestamp < five_minutes_ago: - try: - # Force remove the image (including layers) - docker_client.images.remove(image.id, force=True) - removed_count += 1 - LOG.debug(f"Removed old Docker image: {image_tags}") - except Exception as remove_error: - # Image might be in use or already removed, log but continue - LOG.debug(f"Could not remove Docker image {image_tags}: {remove_error}") - - except Exception as image_error: - # Continue with other images if one fails - LOG.debug(f"Error processing Docker image: {image_error}") - continue - - if removed_count > 0: - LOG.info(f"Cleaned up {removed_count} old Docker image(s)") - - except Exception as e: - # Don't fail the test if Docker cleanup fails - LOG.warning(f"Failed to clean up old Docker images: {e}") + self.custom_build_dir and shutil.rmtree(self.custom_build_dir, ignore_errors=True) + self.working_dir and shutil.rmtree(self.working_dir, ignore_errors=True) + self.scratch_dir and shutil.rmtree(self.scratch_dir, ignore_errors=True) def get_command_list( self, diff --git a/tests/integration/remote/test_event/test_remote_test_event.py b/tests/integration/remote/test_event/test_remote_test_event.py index 4f062a805f7..7377d5ed802 100644 --- a/tests/integration/remote/test_event/test_remote_test_event.py +++ b/tests/integration/remote/test_event/test_remote_test_event.py @@ -64,7 +64,6 @@ def test_event_workflow(self): # Check two events self.list_events_and_check(self.stack_name, function_to_check, os.linesep.join(["event1", "event2"])) - time.sleep(2) # Invoke with two events (function returns the same event that it receives) self.remote_invoke_and_check(self.stack_name, function_to_check, "event1", event_contents1) self.remote_invoke_and_check(self.stack_name, function_to_check, "event2", event_contents2) diff --git a/tests/testing_utils.py b/tests/testing_utils.py index e92e6b75e00..13a0331fe88 100644 --- a/tests/testing_utils.py +++ b/tests/testing_utils.py @@ -24,7 +24,7 @@ RUNNING_ON_APPVEYOR = os.environ.get("APPVEYOR", False) IS_WINDOWS = platform.system().lower() == "windows" -RUNNING_ON_GITHUB_ACTIONS = os.environ.get("CI", False) or os.environ.get("GITHUB_ACTIONS", False) +RUNNING_ON_GITHUB_ACTIONS = os.environ.get("CI", False) RUNNING_ON_CI = RUNNING_ON_APPVEYOR or RUNNING_ON_GITHUB_ACTIONS RUNNING_TEST_FOR_MASTER_ON_CI = ( os.environ.get("APPVEYOR_REPO_BRANCH", os.environ.get("GITHUB_REF_NAME", "master")) != "master" From 161f10689bdcf961cbe909f2e1bbaf48ac1940fa Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Fri, 31 Oct 2025 09:45:38 -0700 Subject: [PATCH 50/54] schedule --- .github/workflows/integration-tests.yml | 37 ++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index b6e97c9277c..497df9aa238 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -1,9 +1,23 @@ name: Integration Tests on: - push: + schedule: + # Run at 7pm PST (3am UTC next day) Monday-Friday + # This translates to Tuesday-Saturday 3am UTC + - cron: '0 3 * * 2-6' + workflow_dispatch: # Allow manual triggering branches: - - integ + - develop # Allow manual trigger on develop branch + - main # Allow manual trigger on main branch + inputs: + branch: + description: 'Branch to run tests on' + required: false + default: 'develop' + type: choice + options: + - develop + - main permissions: id-token: write # Required for OIDC @@ -21,8 +35,8 @@ env: NOSE_PARAMETERIZED_NO_WARN: 1 BY_CANARY: true UV_PYTHON: python3.9 - CREDENTIAL_DISTRIBUTION_LAMBDA_ARN: arn:aws:lambda:us-west-2:123087993316:function:test-account-management-CredentialDistributionLamb-o1sEaa8lvO1L - ACCOUNT_RESET_LAMBDA_ARN: arn:aws:lambda:us-west-2:123087993316:function:test-account-management-AccountResetLambdaFunction-nBZDo6oLCH80 + CREDENTIAL_DISTRIBUTION_LAMBDA_ARN: ${{ secrets.CREDENTIAL_DISTRIBUTION_LAMBDA_ARN }} + ACCOUNT_RESET_LAMBDA_ARN: ${{ secrets.ACCOUNT_RESET_LAMBDA_ARN }} jobs: integration-tests: @@ -64,8 +78,23 @@ jobs: test_suite: other-and-e2e steps: + - name: Determine branch to checkout + id: determine-branch + run: | + # For scheduled runs, always use develop + if [ "${{ github.event_name }}" = "schedule" ]; then + echo "branch=develop" >> $GITHUB_OUTPUT + # For manual runs, use the input branch or default to develop + elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + echo "branch=${{ inputs.branch || 'develop' }}" >> $GITHUB_OUTPUT + else + echo "branch=develop" >> $GITHUB_OUTPUT + fi + - name: Checkout code uses: actions/checkout@v4 + with: + ref: ${{ steps.determine-branch.outputs.branch }} - name: Free up disk space run: | From ed9744ee6d555f0a15218a9e9127060210d3ad3e Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Fri, 31 Oct 2025 09:56:30 -0700 Subject: [PATCH 51/54] test --- .github/workflows/integration-tests.yml | 28 +++++-------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 497df9aa238..f7b098146c1 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -6,18 +6,11 @@ on: # This translates to Tuesday-Saturday 3am UTC - cron: '0 3 * * 2-6' workflow_dispatch: # Allow manual triggering + # NOTE: This workflow can only be manually triggered from develop or main branches + # Use the "Use workflow from" dropdown in GitHub Actions to select the branch branches: - develop # Allow manual trigger on develop branch - main # Allow manual trigger on main branch - inputs: - branch: - description: 'Branch to run tests on' - required: false - default: 'develop' - type: choice - options: - - develop - - main permissions: id-token: write # Required for OIDC @@ -78,23 +71,12 @@ jobs: test_suite: other-and-e2e steps: - - name: Determine branch to checkout - id: determine-branch - run: | - # For scheduled runs, always use develop - if [ "${{ github.event_name }}" = "schedule" ]; then - echo "branch=develop" >> $GITHUB_OUTPUT - # For manual runs, use the input branch or default to develop - elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - echo "branch=${{ inputs.branch || 'develop' }}" >> $GITHUB_OUTPUT - else - echo "branch=develop" >> $GITHUB_OUTPUT - fi - - name: Checkout code uses: actions/checkout@v4 with: - ref: ${{ steps.determine-branch.outputs.branch }} + # For scheduled runs, always use develop + # For manual runs, use the branch from "Use workflow from" dropdown + ref: ${{ github.event_name == 'schedule' && 'develop' || github.ref }} - name: Free up disk space run: | From ca85b00efb5a7deeeca3f7214b266ce184104071 Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Mon, 3 Nov 2025 16:37:31 -0800 Subject: [PATCH 52/54] fix remote test event failure --- .github/workflows/integration-tests.yml | 9 +++++++-- samcli/commands/remote/invoke/cli.py | 2 +- .../remote/test_event/remote_test_event_integ_base.py | 5 ++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index f7b098146c1..fd7aafed970 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -7,7 +7,7 @@ on: - cron: '0 3 * * 2-6' workflow_dispatch: # Allow manual triggering # NOTE: This workflow can only be manually triggered from develop or main branches - # Use the "Use workflow from" dropdown in GitHub Actions to select the branch + # The other branch will not pass the OIDC permission check branches: - develop # Allow manual trigger on develop branch - main # Allow manual trigger on main branch @@ -108,7 +108,7 @@ jobs: - name: Configure AWS credentials via OIDC uses: aws-actions/configure-aws-credentials@v4 with: - role-to-assume: arn:aws:iam::670246014611:role/aws-sam-cli-canary-tam-caller-TAMCallerRole-dgaIJ7W7Byha + role-to-assume: ${{ secrets.OIDC_ROLE_ARN }} aws-region: us-east-1 - name: Set up Python @@ -343,6 +343,11 @@ jobs: - name: Run tests run: | + # Set USING_FINCH_RUNTIME environment variable for finch tests + if [ "${{ matrix.container_runtime }}" = "finch" ]; then + export USING_FINCH_RUNTIME=1 + fi + # Determine container keyword filter based on container_runtime if [ "${{ matrix.container_runtime }}" = "no-container" ]; then CONTAINER_FILTER="not container" diff --git a/samcli/commands/remote/invoke/cli.py b/samcli/commands/remote/invoke/cli.py index b9919fda71f..9bc1469e614 100644 --- a/samcli/commands/remote/invoke/cli.py +++ b/samcli/commands/remote/invoke/cli.py @@ -173,7 +173,7 @@ def do_cli( event = lambda_test_event["json"] LOG.debug("Remote event contents: %s", event) metadata = lambda_test_event["metadata"] - if "invocationType" in metadata: + if "invocationType" in metadata and metadata["invocationType"] is not None: parameter.setdefault("InvocationType", metadata["invocationType"]) elif test_event_name: LOG.info("Note: remote event is only supported for AWS Lambda Function resource.") diff --git a/tests/integration/remote/test_event/remote_test_event_integ_base.py b/tests/integration/remote/test_event/remote_test_event_integ_base.py index 4d4ad3bb362..22b1aa73d39 100644 --- a/tests/integration/remote/test_event/remote_test_event_integ_base.py +++ b/tests/integration/remote/test_event/remote_test_event_integ_base.py @@ -35,7 +35,10 @@ def tearDownClass(cls): cls.delete_all_test_events() # Delete the deployed stack cls.cfn_client.delete_stack(StackName=cls.stack_name) - cls.schemas_client.delete_registry(RegistryName=LAMBDA_TEST_EVENT_REGISTRY) + try: + cls.schemas_client.delete_registry(RegistryName=LAMBDA_TEST_EVENT_REGISTRY) + except Exception as e: + LOG.info("test event schema cleanup failed %s", e) @classmethod def create_resources_and_boto_clients(cls): From f50ea5ee016d82edae37ac7b1a75e38ac1512a5e Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Mon, 3 Nov 2025 17:16:49 -0800 Subject: [PATCH 53/54] address feedback --- .github/workflows/integration-tests.yml | 4 +++- tests/integration/buildcmd/build_integ_base.py | 11 +++-------- tests/integration/buildcmd/test_build_cmd.py | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index fd7aafed970..4b6cc4c4bc7 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -33,6 +33,8 @@ env: jobs: integration-tests: + # Only run scheduled jobs on the main aws/aws-sam-cli repository, not on forks + if: github.event_name != 'schedule' || github.repository == 'aws/aws-sam-cli' name: ${{ matrix.test_suite }} (${{ matrix.container_runtime }}) runs-on: ubuntu-22.04 strategy: @@ -345,7 +347,7 @@ jobs: run: | # Set USING_FINCH_RUNTIME environment variable for finch tests if [ "${{ matrix.container_runtime }}" = "finch" ]; then - export USING_FINCH_RUNTIME=1 + export container_runtime="finch" fi # Determine container keyword filter based on container_runtime diff --git a/tests/integration/buildcmd/build_integ_base.py b/tests/integration/buildcmd/build_integ_base.py index 8291bce4e20..5edca627b1c 100644 --- a/tests/integration/buildcmd/build_integ_base.py +++ b/tests/integration/buildcmd/build_integ_base.py @@ -567,14 +567,9 @@ def _test_with_go(self, runtime, code_uri, mode, relative_path, architecture=Non # Build with musl target to avoid glibc compatibility issues # This ensures the binary works in the Lambda execution environment - if architecture == ARM64: - newenv["GOOS"] = "linux" - newenv["GOARCH"] = "arm64" - newenv["CGO_ENABLED"] = "0" - else: - newenv["GOOS"] = "linux" - newenv["GOARCH"] = "amd64" - newenv["CGO_ENABLED"] = "0" + newenv["GOOS"] = "linux" + newenv["GOARCH"] = "arm64" if architecture == ARM64 else "amd64" + newenv["CGO_ENABLED"] = "0" run_command(cmdlist, cwd=self.working_dir, env=newenv) diff --git a/tests/integration/buildcmd/test_build_cmd.py b/tests/integration/buildcmd/test_build_cmd.py index f59c8399431..d8351d4eb5e 100644 --- a/tests/integration/buildcmd/test_build_cmd.py +++ b/tests/integration/buildcmd/test_build_cmd.py @@ -1632,7 +1632,7 @@ class TestBuildWithNestedStacks3Level(NestedBuildIntegBase): template = os.path.join("deep-nested", "template.yaml") - def test_nested_build_in_conatiner(self): + def test_nested_build_in_container(self): if SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: self.skipTest(SKIP_DOCKER_MESSAGE) From 72cc4d773eb741a3edc1ab6aafd4c49e58a4f82b Mon Sep 17 00:00:00 2001 From: Roger Zhang Date: Mon, 3 Nov 2025 17:23:07 -0800 Subject: [PATCH 54/54] Update test_remote_test_event.py --- tests/integration/remote/test_event/test_remote_test_event.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/remote/test_event/test_remote_test_event.py b/tests/integration/remote/test_event/test_remote_test_event.py index 7377d5ed802..d3d0bb62b55 100644 --- a/tests/integration/remote/test_event/test_remote_test_event.py +++ b/tests/integration/remote/test_event/test_remote_test_event.py @@ -1,6 +1,5 @@ import json import os -import time import uuid import pytest