Skip to content

Commit 8b878af

Browse files
authored
refactor(test): restructure integration tests with tiered CI, parallel jobs, and Finch cross-platform smoke tests (#8666)
* test * skip credential setup * test * Restructure integration tests: remove finch/container_runtime matrix, add test tiering, scope Docker cleanup - Remove container_runtime matrix (docker/finch/no-container) in favor of explicit test_suite entries - Split build tests into build-x86, build-arm64, build-x86-container, build-arm64-container - Merge local-start1/local-start2 into local-start with -n 2 parallelism - Add cloud-based-tests job using @pytest.mark.requires_credential marker - Skip credential-requiring tests (SAR, layers, STS) in local-only jobs via SAM_CLI_NO_CREDENTIALS - Scope Docker container/image cleanup to per-test-class snapshots to prevent cross-worker interference - Extract credential setup/reset into setup_testing_resources.py and reset_testing_resources.py - Update credential test runtimes: dotnet10, java25, python3.12, ruby3.4, nodejs22.x, provided.al2023 for Go - Remove Free up disk space step - Add uv availability check in Makefile init * Fix test failures: credential markers, parallel isolation, runtime updates, schema registry lookup - Add requires_credential marker to terraform S3 backend and layer tests - Exclude requires_credential tests from terraform job, run in cloud-based-tests - Remove AWS credentials from terraform job (no longer needed) - Add Terraform install to cloud-based-tests job - Fix java25 dir rename and pom.xml compiler version - Add go.sum for Go STS credential test - Remove global Docker image cleanup from WarmContainersRemoteLayers tests - Add xdist_group markers for durable tests (port 9014) and rapid image tests - Use --dist loadgroup for local-invoke and local-start jobs - Fix EventBridge schema registry tests with dynamic position lookup - Update CONTRIBUTING.md with integration test guidelines * test * Simplify credential handling, fix parallel isolation, split terraform jobs - All jobs now get credentials unconditionally (remove conditional OIDC/ECR/reset) - Use -m "not requires_credential" in build/local jobs instead of SAM_CLI_NO_CREDENTIALS env var - Remove SKIP_CREDENTIAL_TESTS and skipIf patterns from test files - Remove requires_credential from terraform tests (run in terraform jobs directly) - Split terraform into terraform-build (-n 4) and terraform-local (sequential) - Mark TestBuildCommand_LayerBuilds as requires_credential - Add xdist groups: durable (callback, execution), remote_layers, docker_watcher - Add TestSamPython36HelloWorldIntegrationImages to docker_images group - Update CONTRIBUTING.md with simplified marker-only approach * Fix verify_pulled_image runtime mismatch, delete test robustness, xdist groups - Fix verify_pulled_image/verify_docker_container_cleanedup to use python3.11 matching the actual template runtimes (was incorrectly hardcoded to python3.12) - Make test_delete_no_prompts_with_s3_prefix_present_zip robust against deploy failures (CloudFormation EarlyValidation hooks) - Add xdist groups for TestSamPython36HelloWorldIntegrationImages (docker_images), TestLocalCallback/TestLocalExecution (durable), WarmContainersRemoteLayers* (remote_layers), Watching*Image*/DockerFileLocation* (docker_watcher) * Split slow jobs, fix layer test robustness, update Node STS SDK - Split local-start into local-start-api and local-start-lambda - Split sync into sync-code (-n 2) and sync-watch (sequential) - Split package-delete-deploy into package (+ delete) and deploy - Remove Docker image cleanup from layer tests (images persist, reused) - Add lambda_layers xdist group to all layer test classes - Add flaky(reruns=3) at class level for TestLayerVersion - Update Node.js STS SDK to ^3.700.0 (fix @smithy/protocol-http missing) * Fix setup step conditions for split jobs (sync -> sync-code/sync-watch) * Split slow jobs into 20 matrix entries for faster CI - build-x86 -> build-x86-1 (general) + build-x86-2 (language-specific) - build-x86-container -> build-x86-container-1 + build-x86-container-2 - build-arm64-container -> build-arm64-container-1 (non-java) + build-arm64-container-2 (java) - terraform-local -> terraform-start-api + terraform-invoke-start-lambda - Update all setup step conditions for new job names - Remove samcli image cleanup from layer tests, add lambda_layers xdist group * Use --ignore pattern for build-x86-2 and build-x86-container-2 so new test files are auto-included * Rebalance build splits, move sync_build_in_source to sync-watch - Move test_build_cmd_python.py and test_build_cmd_java.py to build-x86-1/container-1 - Move test_sync_build_in_source.py from sync-code to sync-watch * Apply autofix formatting to workflow * Release test account early for local-only jobs, mark docker image tests as requires_credential - Add early reset step after ECR login for build/local jobs to free test account - Skip final reset for jobs that already released early - Mark TestSamPython36HelloWorldIntegrationImages and TestDeleteOldRapidImages as requires_credential * Apply autofix formatting * Merge upload_test_report into reset_testing_resources, fix warm container assertion - Merge S3 report upload into reset_testing_resources.py (always uploads, conditionally resets) - Use SKIP_ACCOUNT_RESET env var for local-only jobs instead of workflow condition - Delete standalone upload_test_report.py - Fix TestWarmContainersHandlesSigTermInterrupt to use assertGreaterEqual for container count * Add tier1 markers, fix S3 upload role chaining, update report - Add @pytest.mark.tier1 to 23 test classes across all feature areas - Fix S3 report upload: use configure-aws-credentials role-chaining for OIDC->RoleA->RoleB - Simplify upload_test_reports to use default credentials (set by workflow) - Add tier1 markers for: durable, layers, sync, deploy, terraform, regression, callback, execution - Update TIER1_TESTS.md with complete coverage table * Fix: remove secrets context from if condition (not allowed in expressions) * Fix: add missing pytest import in test_build_cmd_rust.py * Add tier1-finch as matrix entry, move setup_finch.sh to tests/, fix rust import - Add tier1-finch to matrix with conditional Finch setup, ECR login, and runtime - Move setup_finch.sh from scripts/ to tests/ - Add tier1-finch to all toolchain setup conditions - Remove separate tier1-finch job (now part of matrix) - Fix missing pytest import in test_build_cmd_rust.py * Fix Finch install: remove Docker packages first to avoid containerd.io conflict * Finalize tier1 tests: method-level markers, deduplicate parameterized cases, add missing commands - Move tier1 from class-level to method-level with dedicated test_tier1_* methods - Add container + non-container tier1 for each runtime (Python, Java, Node, Dotnet, Rust, Provided) - Remove duplicated parameterized cases covered by tier1 methods - Add tier1 for: sam delete, sam package, symlink builds, layer builds, sam sync - Fix missing pytest imports in delete and package tests - Revert cargo-lambda to pip install - Update CONTRIBUTING.md and TIER1_TESTS.md * Fix tier1 test errors, add ARM64 build tests for all runtimes - Fix tier1 methods that called parameterized methods (inline logic instead) - Fix dotnet validate_build_command params (mode=None, use_container=True) - Fix Python tier1 skip condition to check template and codeuri - Add ARM64 tier1 build tests: Python, Java, Node, Ruby, Provided, Rust - Update TIER1_TESTS.md with ARM64 section * Fix tier1 failures: restore Rust container test, fix dotnet/layer params, skip ARM64 without Docker - Restore test_tier1_rust_build_in_container (was accidentally deleted) - Fix dotnet container tier1 to use dotnet8 (dotnet10 container image not available) - Fix layer tier1 to use correct overrides (LayerContentUri, python3.11) - Add skipIf(SKIP_DOCKER_TESTS) to ARM64 tier1 tests (need Docker for invoke) - All container tier1 methods have _in_container suffix for -k filter compatibility * Fix tier1 tests: match exact params from original parameterized tests - Dotnet container: use mount_mode=MountMode.WRITE (not use_container=True) - Layer build: use python3.12 (matching original test_build_single_layer) - Rust: remove container tier1 (cargo-lambda doesn't support container builds) - These match the exact parameter combinations that pass in the original tests * Final cleanup: fix ARM64 naming, QEMU for build-arm64, mypy import, remove temp docs - Revert ARM64 tier1 names (no _in_container since use_container=False) - Enable QEMU for build-arm64 job (needed for local invoke) - Fix mypy import error in setup_testing_resources.py - Remove Rust container tier1 (cargo-lambda doesn't support container builds) - Fix dotnet container tier1 to use MountMode.WRITE - Fix layer tier1 to use python3.12 - Remove CLOUD_VS_LOCAL_REPORT.md and TIER1_TESTS.md * Skip credentials for non-credential jobs, clear AWS creds after ECR login, add skipIf to dotnet tier1 * Add disk cleanup, mark credential-requiring tests, skip creds for local jobs - Add tests/free_disk_space.sh: cleanup if <25GB free, reduce swap to 1GB, nohup rm - Mark git function tests and WarmContainersRemoteLayers as requires_credential - Skip Get testing resources for non-credential jobs, clear AWS creds after ECR login - Add skipIf(SKIP_DOCKER_TESTS) to dotnet tier1 non-container test * remove duplicates * remove duplicate, add arm64 test with container * remove dup * add paramter back, add tier1 extra * extra * change temp to mnt if exist
1 parent 216c71f commit 8b878af

50 files changed

Lines changed: 1121 additions & 465 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/integration-tests.yml

Lines changed: 206 additions & 249 deletions
Large diffs are not rendered by default.

CONTRIBUTING.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,70 @@ GitHub provides additional document on [forking a repository](https://help.githu
6060
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
6161

6262

63+
## Integration Test Guidelines
64+
65+
Integration tests run in CI via `.github/workflows/integration-tests.yml`. All jobs have AWS credentials. Tests in `build` and `local` jobs that require credentials are separated using a pytest marker.
66+
67+
### Tests that require AWS credentials
68+
69+
Some tests in `tests/integration/buildcmd/` and `tests/integration/local/` need AWS credentials (e.g. STS calls, Lambda layer publishing, SAR template resolution). These are:
70+
71+
- **Excluded** from build/local jobs via `-m "not requires_credential"`
72+
- **Collected and run** in the dedicated `cloud-based-tests` CI job via `-m requires_credential`
73+
74+
To mark a test that requires AWS credentials, add the marker:
75+
76+
```python
77+
import pytest
78+
79+
@pytest.mark.requires_credential
80+
class TestMyCloudFeature(SomeBaseClass):
81+
...
82+
```
83+
84+
The marker is registered in `tests/conftest.py`. Build and local jobs automatically exclude these tests; `cloud-based-tests` automatically includes them.
85+
86+
### Docker container cleanup in parallel tests
87+
88+
`start-api` and `start-lambda` tests run in parallel (`-n 2`). Each test class snapshots existing Docker container IDs before starting its local server, and on teardown only removes containers created after the snapshot. This prevents one worker from killing another worker's containers.
89+
90+
If you write a new base class that manages Docker containers, follow the same pattern in `start_lambda_api_integ_base.py` and `start_api_integ_base.py`: snapshot container IDs in `setUpClass`, and scope removal to only new containers in `tearDownClass`.
91+
92+
### Tier 1 cross-platform smoke tests
93+
94+
A curated subset of ~50 tests marked with `@pytest.mark.tier1` runs on every OS/container-runtime combination (e.g. Linux+Finch). These validate platform-specific code paths: file system operations, container runtime interaction, process spawning, and network operations.
95+
96+
There are two markers:
97+
98+
- `tier1` — standalone tests that don't duplicate any parameterized entry (e.g. a dedicated `test_tier1_*` method calling unique logic)
99+
- `tier1_extra` — dedicated `test_tier1_*` methods whose parameter set already exists in a `@parameterized.expand` list on the same class. These are excluded from normal Linux+Docker CI (via `-m "not tier1_extra"`) to avoid running the same test twice, but included in the tier1 Finch job (via `-m "tier1 or tier1_extra"`).
100+
101+
Run locally with: `pytest -m "tier1 or tier1_extra" tests/integration tests/regression`
102+
103+
To add a tier 1 test for a new feature:
104+
105+
1. Add a dedicated `test_tier1_*` method that calls the existing test logic with one specific parameter set:
106+
107+
```python
108+
@pytest.mark.tier1
109+
def test_tier1_my_feature(self):
110+
"""Single test for cross-platform validation."""
111+
self._test_my_feature("runtime_x", use_container=False)
112+
113+
@pytest.mark.tier1
114+
@skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE)
115+
def test_tier1_my_feature_in_container(self):
116+
"""Single container test for cross-platform validation."""
117+
self._test_my_feature("runtime_x", use_container=True)
118+
```
119+
120+
2. If the parameter set already exists in a `@parameterized.expand` list, keep it in the original list and use `@pytest.mark.tier1_extra` instead of `@pytest.mark.tier1` on the dedicated method. This avoids running the same test twice in Linux+Docker CI.
121+
122+
3. If the parameter set does NOT exist in any parameterized list (i.e. it's unique to the tier1 method), use `@pytest.mark.tier1`.
123+
124+
4. Each runtime should have one non-container and one container tier 1 test.
125+
126+
63127
## Finding contributions to work on
64128
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels ((enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/aws/aws-sam-cli/labels/help%20wanted) issues is a great place to start.
65129

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ SAM_CLI_TELEMETRY ?= 0
77
# Initialize environment specifically for Github action tests using uv
88
init:
99
@if [ "$$GITHUB_ACTIONS" = "true" ]; then \
10-
pip install uv==0.9.1 && SAM_CLI_DEV=1 uv pip install --system -e '.[dev]'; \
10+
command -v uv >/dev/null 2>&1 || pip install uv==0.9.1; \
11+
SAM_CLI_DEV=1 uv pip install --system -e '.[dev]'; \
1112
else \
1213
SAM_CLI_DEV=1 pip install -e '.[dev]'; \
1314
fi

tests/conftest.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
1+
"""Root conftest for integration/unit tests."""
2+
3+
import pytest
14
import os
25

36

47
if "__SAM_CLI_TELEMETRY_ENDPOINT_URL" not in os.environ:
58
os.environ["__SAM_CLI_TELEMETRY_ENDPOINT_URL"] = ""
9+
10+
11+
def pytest_configure(config):
12+
config.addinivalue_line(
13+
"markers",
14+
"requires_credential: mark test as requiring AWS credentials (skipped in local-only CI jobs)",
15+
)
16+
config.addinivalue_line(
17+
"markers",
18+
"tier1: cross-platform smoke tests that run on every OS/container-runtime combination",
19+
)
20+
config.addinivalue_line(
21+
"markers",
22+
"tier1_extra: parameterized expansions of tier1 tests (excluded from normal CI, included in tier1 jobs)",
23+
)

tests/free_disk_space.sh

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/bin/bash
2+
# Free up disk space on CI runners if root partition has less than 50GB free.
3+
# Removes common unused resources that ship with GitHub Actions runners.
4+
set -e
5+
6+
echo "=== Disk usage before cleanup ==="
7+
df -h
8+
9+
ROOT_FREE_GB=$(df -BG / | awk 'NR==2 {gsub("G",""); print $4}')
10+
echo "Free disk space on root: ${ROOT_FREE_GB}GB"
11+
12+
if [ "$ROOT_FREE_GB" -ge 50 ]; then
13+
echo "Sufficient disk space available, skipping cleanup."
14+
exit 0
15+
fi
16+
17+
# If /mnt is mounted and has > 50GB free, redirect temp dirs there
18+
if mountpoint -q /mnt 2>/dev/null; then
19+
MNT_FREE_GB=$(df -BG /mnt | awk 'NR==2 {gsub("G",""); print $4}')
20+
if [ "$MNT_FREE_GB" -gt 50 ]; then
21+
echo "Root has ${ROOT_FREE_GB}GB free, /mnt has ${MNT_FREE_GB}GB free. Redirecting temp dirs to /mnt."
22+
sudo mkdir -p /mnt/tmp
23+
sudo chmod 1777 /mnt/tmp
24+
echo "TMPDIR=/mnt/tmp" >> "$GITHUB_ENV"
25+
echo "TEMP=/mnt/tmp" >> "$GITHUB_ENV"
26+
echo "TMP=/mnt/tmp" >> "$GITHUB_ENV"
27+
echo "RUNNER_TEMP=/mnt/tmp" >> "$GITHUB_ENV"
28+
29+
# # Move Docker data-root to /mnt to free root partition
30+
# echo "Relocating Docker storage to /mnt/docker..."
31+
# sudo systemctl stop docker || true
32+
# sudo mkdir -p /mnt/docker
33+
# sudo mkdir -p /etc/docker
34+
# echo '{"data-root": "/mnt/docker"}' | sudo tee /etc/docker/daemon.json > /dev/null
35+
# if [ -d /var/lib/docker ]; then
36+
# sudo rsync -a /var/lib/docker/ /mnt/docker/ 2>/dev/null || true
37+
# sudo rm -rf /var/lib/docker
38+
# fi
39+
# sudo systemctl start docker || true
40+
fi
41+
fi
42+
43+
echo "Free space below 50GB, cleaning up..."
44+
45+
# Reduce swap to 1GB (only use /mnt if it exists)
46+
sudo swapoff -a || true
47+
if mountpoint -q /mnt 2>/dev/null; then
48+
sudo fallocate -l 1G /mnt/swapfile || true
49+
sudo chmod 600 /mnt/swapfile || true
50+
sudo mkswap /mnt/swapfile || true
51+
sudo swapon /mnt/swapfile || true
52+
fi
53+
54+
# Reduce system reserved space to 512MB
55+
sudo tune2fs -m 0.5 $(df / | awk 'NR==2 {print $1}') 2>/dev/null || true
56+
57+
# Remove large unused packages (run in background with nohup)
58+
nohup sudo rm -rf /usr/local/lib/android > /dev/null 2>&1 &
59+
nohup sudo rm -rf /opt/ghc > /dev/null 2>&1 &
60+
nohup sudo rm -rf /opt/hostedtoolcache/CodeQL > /dev/null 2>&1 &
61+
nohup sudo rm -rf /usr/local/share/powershell > /dev/null 2>&1 &
62+
63+
# Clean apt cache
64+
nohup sudo apt-get clean > /dev/null 2>&1 &
65+
66+
# Remove existing Docker images to free space
67+
nohup docker system prune -af --volumes > /dev/null 2>&1 &
68+
69+
echo "Cleanup jobs started in background."

tests/integration/buildcmd/test_build_cmd.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ def _validate_skipped_built_function(
282282
@pytest.mark.ruby
283283
class TestBuildCommand_RubyFunctions(BuildIntegRubyBase):
284284
@parameterized.expand([(False,), ("use_container",)], name_func=show_container_in_test_name)
285+
@pytest.mark.tier1
285286
def test_building_ruby_3_2(self, use_container):
286287
if use_container and SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD:
287288
self.skipTest(SKIP_DOCKER_MESSAGE)
@@ -509,6 +510,7 @@ def _verify_resources_excluded(self, build_dir, excluded_resources, function_ide
509510
((IS_WINDOWS and RUNNING_ON_CI) and not CI_OVERRIDE),
510511
"Skip build tests on windows when running in CI unless overridden",
511512
)
513+
@pytest.mark.requires_credential
512514
class TestBuildCommand_LayerBuilds(BuildIntegBase):
513515
template = "layers-functions-template.yaml"
514516

@@ -529,7 +531,9 @@ class TestBuildCommand_LayerBuilds(BuildIntegBase):
529531
def test_build_single_layer(self, runtime, use_container, layer_identifier, content_property):
530532
if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD):
531533
self.skipTest(SKIP_DOCKER_MESSAGE)
534+
self._do_build_single_layer(runtime, use_container, layer_identifier, content_property)
532535

536+
def _do_build_single_layer(self, runtime, use_container, layer_identifier, content_property):
533537
overrides = {"LayerBuildMethod": runtime, "LayerContentUri": "PyLayer"}
534538
cmdlist = self.get_command_list(
535539
use_container=use_container, parameter_overrides=overrides, function_identifier=layer_identifier
@@ -812,6 +816,11 @@ def test_build_function_with_dependent_layer_invoke_in_container(self, runtime,
812816
self.verify_docker_container_cleanedup(runtime)
813817
self.verify_pulled_image(runtime)
814818

819+
@pytest.mark.tier1_extra
820+
def test_tier1_layer_build(self):
821+
"""Single layer build test for cross-platform validation."""
822+
self._do_build_single_layer("python3.12", False, "LayerOne", "ContentUri")
823+
815824
def _verify_built_artifact(
816825
self, build_dir, resource_logical_id, expected_files, code_property_name, artifact_subfolder=""
817826
):
@@ -1416,8 +1425,8 @@ def test_inline_not_built(self, use_container):
14161425
self._verify_built_artifact(self.default_build_dir)
14171426

14181427
if use_container:
1419-
self.verify_docker_container_cleanedup("python3.12")
1420-
self.verify_pulled_image("python3.12")
1428+
self.verify_docker_container_cleanedup("python3.11")
1429+
self.verify_pulled_image("python3.11")
14211430

14221431
def _verify_built_artifact(self, build_dir):
14231432
self.assertTrue(build_dir.exists(), "Build directory should be created")
@@ -1466,8 +1475,8 @@ def test_json_env_vars_passed(self, use_container, env_vars_file):
14661475
self._verify_built_env_var(self.default_build_dir)
14671476

14681477
if use_container:
1469-
self.verify_docker_container_cleanedup("python3.12")
1470-
self.verify_pulled_image("python3.12")
1478+
self.verify_docker_container_cleanedup("python3.11")
1479+
self.verify_pulled_image("python3.11")
14711480

14721481
@staticmethod
14731482
def get_env_file(filename):
@@ -1515,8 +1524,8 @@ def test_inline_env_vars_passed(self, use_container, inline_env_var):
15151524
self._verify_built_env_var(self.default_build_dir)
15161525

15171526
if use_container:
1518-
self.verify_docker_container_cleanedup("python3.12")
1519-
self.verify_pulled_image("python3.12")
1527+
self.verify_docker_container_cleanedup("python3.11")
1528+
self.verify_pulled_image("python3.11")
15201529

15211530
def _verify_built_env_var(self, build_dir):
15221531
self.assertTrue(build_dir.exists(), "Build directory should be created")
@@ -1558,6 +1567,7 @@ class TestBuildWithNestedStacks(NestedBuildIntegBase):
15581567
],
15591568
name_func=show_container_in_test_name,
15601569
)
1570+
@pytest.mark.tier1
15611571
def test_nested_build_invoke_in_container(self, use_container, cached, parallel):
15621572
if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD):
15631573
self.skipTest(SKIP_DOCKER_MESSAGE)
@@ -1676,6 +1686,7 @@ def test_nested_build_in_container(self):
16761686

16771687

16781688
@skipIf(IS_WINDOWS, "symlink is not resolved consistently on windows")
1689+
@pytest.mark.tier1
16791690
class TestBuildWithNestedStacks3LevelWithSymlink(NestedBuildIntegBase):
16801691
"""
16811692
In this template, it has the same structure as .aws-sam/build
@@ -1852,7 +1863,7 @@ def test_custom_build_image_succeeds(self, use_container, build_image):
18521863
self._verify_right_image_pulled(build_image, process_stderr)
18531864
self._verify_build_succeeds(self.default_build_dir)
18541865

1855-
self.verify_docker_container_cleanedup("python3.12")
1866+
self.verify_docker_container_cleanedup("python3.11")
18561867

18571868
def _verify_right_image_pulled(self, build_image, process_stderr):
18581869
image_name = build_image if build_image is not None else "public.ecr.aws/sam/build-python3.11:latest-x86_64"
@@ -1982,6 +1993,7 @@ def test_functions_layers_with_s3_codeuri_in_container(self):
19821993

19831994

19841995
@skipIf(SKIP_SAR_TESTS, "Skip SAR tests")
1996+
@pytest.mark.requires_credential
19851997
class TestBuildSAR(BuildIntegBase):
19861998
template = "aws-serverless-application-with-application-id-map.yaml"
19871999

tests/integration/buildcmd/test_build_cmd_arm64.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,19 @@ def test_with_default_requirements_invoke_in_container(self, runtime, codeuri, u
6767
def test_with_default_requirements_al2023(self, runtime, codeuri, use_container):
6868
self._test_with_default_requirements(runtime, codeuri, use_container, self.test_data_path, architecture=ARM64)
6969

70+
@parameterized.expand(
71+
[
72+
("python3.11", "Python", False),
73+
("python3.11", "Python", "use_container"),
74+
],
75+
name_func=show_container_in_test_name,
76+
)
77+
@pytest.mark.tier1_extra
78+
@skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE)
79+
def test_tier1_python_arm64_build_in_container(self, runtime, codeuri, use_container):
80+
"""Python ARM64 build tests for cross-platform validation."""
81+
self._test_with_default_requirements(runtime, codeuri, use_container, self.test_data_path, architecture=ARM64)
82+
7083

7184
class TestBuildCommand_EsbuildFunctions_arm64(BuildIntegEsbuildBase):
7285
template = "template_with_metadata_esbuild.yaml"
@@ -89,6 +102,19 @@ class TestBuildCommand_EsbuildFunctions_arm64(BuildIntegEsbuildBase):
89102
def test_building_default_package_json(self, runtime, code_uri, expected_files, handler, use_container):
90103
self._test_with_default_package_json(runtime, use_container, code_uri, expected_files, handler, ARM64)
91104

105+
@parameterized.expand(
106+
[
107+
("nodejs20.x", "Esbuild/Node", {"main.js", "main.js.map"}, "main.lambdaHandler", False),
108+
("nodejs20.x", "Esbuild/Node", {"main.js", "main.js.map"}, "main.lambdaHandler", "use_container"),
109+
],
110+
name_func=show_container_in_test_name,
111+
)
112+
@pytest.mark.tier1_extra
113+
@skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE)
114+
def test_tier1_node_arm64_build_in_container(self, runtime, code_uri, expected_files, handler, use_container):
115+
"""Node.js ARM64 build tests for cross-platform validation."""
116+
self._test_with_default_package_json(runtime, use_container, code_uri, expected_files, handler, ARM64)
117+
92118

93119
@pytest.mark.nodejs
94120
class TestBuildCommand_EsbuildFunctions_With_External_Manifest_arm64(BuildIntegEsbuildBase):
@@ -186,6 +212,19 @@ def test_building_ruby_in_container_with_specified_architecture(self, runtime, c
186212
def test_building_ruby_in_process_with_specified_architecture(self, runtime, code_uri):
187213
self._test_with_default_gemfile(runtime, False, code_uri, self.test_data_path, ARM64)
188214

215+
@parameterized.expand(
216+
[
217+
("ruby3.4", "Ruby34", False),
218+
("ruby3.4", "Ruby34", "use_container"),
219+
],
220+
name_func=show_container_in_test_name,
221+
)
222+
@pytest.mark.tier1_extra
223+
@skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE)
224+
def test_tier1_ruby_arm64_build_in_container(self, runtime, code_uri, use_container):
225+
"""Ruby ARM64 build tests for cross-platform validation."""
226+
self._test_with_default_gemfile(runtime, use_container, code_uri, self.test_data_path, ARM64)
227+
189228

190229
@skipIf(
191230
(IS_WINDOWS and not CI_OVERRIDE),
@@ -529,6 +568,27 @@ def test_building_java_in_process_with_arm_architecture(
529568
ARM64,
530569
)
531570

571+
@parameterized.expand(
572+
[
573+
(False,),
574+
("use_container",),
575+
],
576+
name_func=show_container_in_test_name,
577+
)
578+
@pytest.mark.tier1_extra
579+
@skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE)
580+
def test_tier1_java_arm64_build_in_container(self, use_container):
581+
"""Java ARM64 build tests for cross-platform validation."""
582+
self._test_with_building_java(
583+
"java25",
584+
os.path.join(self.USING_MAVEN_PATH, "25"),
585+
self.EXPECTED_FILES_PROJECT_MANIFEST_MAVEN,
586+
self.EXPECTED_MAVEN_DEPENDENCIES,
587+
use_container,
588+
self.test_data_path,
589+
ARM64,
590+
)
591+
532592

533593
class TestBuildCommand_Go_Modules_With_Specified_Architecture_arm64(BuildIntegGoBase):
534594
template = "template_with_architecture.yaml"
@@ -605,6 +665,12 @@ def test_building_Makefile(self, runtime, use_container, manifest):
605665
def test_building_Makefile_al2023(self, runtime, use_container, manifest):
606666
self._test_with_Makefile(runtime, use_container, manifest, ARM64)
607667

668+
@pytest.mark.tier1_extra
669+
@skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE)
670+
def test_tier1_provided_arm64_build(self):
671+
"""Single Provided ARM64 build test for cross-platform validation."""
672+
self._test_with_Makefile("provided.al2023", False, None, ARM64)
673+
608674

609675
@skipIf(
610676
((IS_WINDOWS and RUNNING_ON_CI) and not CI_OVERRIDE),
@@ -632,3 +698,17 @@ def test_build(self, runtime, build_mode, use_container):
632698
expected_invoke_result=self.expected_invoke_result,
633699
use_container=use_container,
634700
)
701+
702+
@pytest.mark.tier1_extra
703+
@skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE)
704+
def test_tier1_rust_arm64_build(self):
705+
"""Single Rust ARM64 build test for cross-platform validation."""
706+
self._test_with_rust_cargo_lambda(
707+
runtime="provided.al2023",
708+
code_uri=self.code_uri,
709+
binary=self.binary,
710+
architecture=ARM64,
711+
build_mode=None,
712+
expected_invoke_result=self.expected_invoke_result,
713+
use_container=False,
714+
)

0 commit comments

Comments
 (0)