Skip to content

Commit a1859d3

Browse files
authored
Add Windows Docker (WSL2) tier-1 integration tests (#8742)
* windows test * comment * fix * win * a * zig on windows * 1 * py * test * rust * bin * dns * resolveconf * test * wsl * split windows test * ignore * nit * update tf * Split tier1-windows-build into 2 halves, add Windows disk cleanup script * Run Windows disk cleanup non-blocking via Start-Job * Fix zig on Windows via choco, rebalance tier1-windows-build split * Split build-2 into build-2/3, fix CRLF for terraform tests, exclude Linux-only durable tests on Windows * Move arm64 tests to build-2 to balance with build-3 * reenable test * Fix binary tests for Windows: cross-platform setup-pytest, MSI installer, SCRIPT_PY detection; fix durable emulator temp file on Windows * nit * Install WSL on D: drive to save C: disk space * test install on disk d * n2 * Add retry logic to ECR login step to handle clock skew on Windows * retr * test * Use PowerShell Start-Process for MSI install on Windows to avoid hanging * Consolidate credential setup, ECR login, and credential clearing into single Python step * simplify * Fix Windows MSI install: detect AWSSAMCLI_NIGHTLY dir, create sam.cmd wrapper, set SAM_WINDOWS_BINARY_PATH * Fix Windows: use full path for sam version check, split version check by OS * Add pytest venv Scripts dir to GITHUB_PATH on Windows for nightly/latest-release flows * Merge CRLF fix into Stop Windows Docker Engine step * Fix reset script: search workspace root for reports, don't fail on account reset error * Set SAM_WINDOWS_BINARY_PATH for both nightly and latest-release on Windows * optimize * a * remove script * black * bump maven to 3.9.13 * feedback * maven * gradle * use custom wsl logic * test * windows path
1 parent 937358c commit a1859d3

50 files changed

Lines changed: 863 additions & 386 deletions

File tree

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: 118 additions & 77 deletions
Large diffs are not rendered by default.

‎Makefile‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,16 @@ init:
1313
SAM_CLI_DEV=1 pip install -e '.[dev]'; \
1414
fi
1515

16-
# Set up a pytest venv with test dependencies (without installing sam-cli itself)
16+
# Set up a pytest venv with test dependencies
17+
# Set up a pytest venv with test dependencies (cross-platform)
1718
setup-pytest:
18-
python3.11 -m venv $(HOME)/pytest
19-
uv pip install --python $(HOME)/pytest/bin/python3 --only-deps --extra dev '.'
20-
sudo ln -sf $(HOME)/pytest/bin/pytest /usr/local/bin/pytest
21-
pytest --version
19+
python3.11 -m venv $(HOME)/pytest || python3 -m venv $(HOME)/pytest || python -m venv $(HOME)/pytest
20+
uv pip install --python $(HOME)/pytest/bin/python3 --only-deps --extra dev '.' 2>/dev/null || \
21+
uv pip install --python $(HOME)/pytest/Scripts/python.exe --only-deps --extra dev '.'
22+
@if [ -f "$(HOME)/pytest/bin/pytest" ]; then \
23+
sudo ln -sf $(HOME)/pytest/bin/pytest /usr/local/bin/pytest 2>/dev/null || true; \
24+
fi
25+
$(HOME)/pytest/bin/pytest --version 2>/dev/null || $(HOME)/pytest/Scripts/pytest --version
2226

2327
# Install SAM CLI nightly binary
2428
init-nightly:

‎tests/free_disk_space.sh‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
#!/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.
2+
# Free up disk space on CI runners.
3+
# On Linux: cleans up unused packages if root partition has less than 50GB free.
4+
# On Windows: just reports disk usage for debugging.
45
set -e
56

7+
# Windows: just show disk usage and exit
8+
if [[ "${RUNNER_OS:-}" == "Windows" ]]; then
9+
echo "=== Windows Disk Usage ==="
10+
powershell.exe -Command "Get-PSDrive -PSProvider FileSystem | Format-Table Name, @{N='Used(GB)';E={[math]::Round(\$_.Used/1GB,1)}}, @{N='Free(GB)';E={[math]::Round(\$_.Free/1GB,1)}}, @{N='Total(GB)';E={[math]::Round((\$_.Used+\$_.Free)/1GB,1)}} -AutoSize"
11+
exit 0
12+
fi
13+
614
echo "=== Disk usage before cleanup ==="
715
df -h
816

‎tests/install-maven-gradle.sh‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/bin/bash
2+
# Install Maven 3.9.13 and Gradle 9.3.1 for SAM CLI integration tests.
3+
# Supports both Linux and Windows (Git Bash on GitHub Actions).
4+
set -euo pipefail
5+
6+
MAVEN_VERSION="3.9.13"
7+
GRADLE_VERSION="9.3.1"
8+
9+
# Check if correct versions are already installed
10+
MAVEN_INSTALLED=$(mvn --version 2>/dev/null | head -1 | grep -o "${MAVEN_VERSION}" || true)
11+
GRADLE_INSTALLED=$(gradle --version 2>/dev/null | grep "Gradle ${GRADLE_VERSION}" || true)
12+
13+
if [[ -n "$MAVEN_INSTALLED" && -n "$GRADLE_INSTALLED" ]]; then
14+
echo "Maven ${MAVEN_VERSION} and Gradle ${GRADLE_VERSION} are already installed, skipping."
15+
mvn --version
16+
gradle --version
17+
exit 0
18+
fi
19+
20+
if [[ "${RUNNER_OS:-}" == "Windows" ]]; then
21+
echo "=== Installing Maven ${MAVEN_VERSION} and Gradle ${GRADLE_VERSION} on Windows via choco ==="
22+
[[ -z "$MAVEN_INSTALLED" ]] && choco install maven --version="${MAVEN_VERSION}" -y --allow-downgrade
23+
[[ -z "$GRADLE_INSTALLED" ]] && choco install gradle --version="${GRADLE_VERSION}" -y --allow-downgrade
24+
25+
# Chocolatey updates the system PATH in the registry but the current bash session
26+
# doesn't see it. Explicitly add the known install paths so mvn/gradle are available
27+
# in this session and in subsequent workflow steps.
28+
CHOCO_MAVEN_BIN="C:/ProgramData/chocolatey/lib/maven/apache-maven-${MAVEN_VERSION}/bin"
29+
CHOCO_GRADLE_BIN="C:/ProgramData/chocolatey/lib/gradle/gradle-${GRADLE_VERSION}/bin"
30+
export PATH="${CHOCO_MAVEN_BIN}:${CHOCO_GRADLE_BIN}:${PATH}"
31+
echo "${CHOCO_MAVEN_BIN}" >> "$GITHUB_PATH"
32+
echo "${CHOCO_GRADLE_BIN}" >> "$GITHUB_PATH"
33+
else
34+
echo "=== Installing Maven ${MAVEN_VERSION} and Gradle ${GRADLE_VERSION} on Linux ==="
35+
sudo apt-get remove -y maven || true
36+
37+
wget -q "https://dlcdn.apache.org/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.zip" -P /tmp
38+
sudo unzip -o -q /tmp/apache-maven-*.zip -d /opt/mvn
39+
40+
wget -q "https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip" -P /tmp
41+
sudo unzip -o -q /tmp/gradle-*.zip -d /opt/gradle
42+
43+
sudo ln -sf "/opt/mvn/apache-maven-${MAVEN_VERSION}/bin/mvn" /usr/local/bin/mvn
44+
sudo ln -sf "/opt/gradle/gradle-${GRADLE_VERSION}/bin/gradle" /usr/local/bin/gradle
45+
46+
echo "/opt/mvn/apache-maven-${MAVEN_VERSION}/bin" >> "$GITHUB_PATH"
47+
echo "/opt/gradle/gradle-${GRADLE_VERSION}/bin" >> "$GITHUB_PATH"
48+
echo "MAVEN_HOME=/opt/mvn/apache-maven-${MAVEN_VERSION}" >> "$GITHUB_ENV"
49+
50+
export PATH="/opt/mvn/apache-maven-${MAVEN_VERSION}/bin:/opt/gradle/gradle-${GRADLE_VERSION}/bin:$PATH"
51+
fi
52+
53+
mvn --version || echo "WARNING: mvn --version failed"
54+
gradle --version || echo "WARNING: gradle --version failed"
55+
echo "=== Maven and Gradle installation complete ==="

‎tests/install-rust.sh‎

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,54 @@ CARGO_LAMBDA_VERSION="${1:-${CARGO_LAMBDA_VERSION:-v0.17.1}}"
1616
# Install rustup if not present
1717
if ! command -v rustup &> /dev/null; then
1818
curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL https://sh.rustup.rs | sh -s -- --default-toolchain none -y
19-
source "$HOME/.cargo/env"
19+
# source cargo env (file doesn't exist on Windows where Rust is pre-installed)
20+
if [ -f "$HOME/.cargo/env" ]; then
21+
source "$HOME/.cargo/env"
22+
fi
2023
if [ -n "${GITHUB_PATH:-}" ]; then
2124
echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> "$GITHUB_PATH"
2225
fi
2326
fi
2427

2528
rustup toolchain install stable --profile minimal --no-self-update
2629
rustup default stable
27-
rustup target add x86_64-unknown-linux-gnu --toolchain stable
28-
rustup target add aarch64-unknown-linux-gnu --toolchain stable
30+
31+
if [[ "${RUNNER_OS:-}" == "Windows" ]]; then
32+
# On Windows, add Windows-native targets
33+
rustup target add x86_64-pc-windows-msvc --toolchain stable || true
34+
else
35+
rustup target add x86_64-unknown-linux-gnu --toolchain stable
36+
rustup target add aarch64-unknown-linux-gnu --toolchain stable
37+
fi
2938

3039
# Install cargo-lambda and ziglang
3140
if [ "$USE_UV" = true ]; then
3241
PYTHON311="$(uv python find 3.11)"
3342
PYTHON311_BIN="$(dirname "$PYTHON311")"
34-
uv pip install --break-system-packages --python "$PYTHON311" "cargo-lambda==$CARGO_LAMBDA_VERSION"
43+
uv pip install --break-system-packages --python "$PYTHON311" "cargo-lambda==$CARGO_LAMBDA_VERSION" ziglang
44+
PYTHON_CMD="$PYTHON311"
3545
if [ -n "${GITHUB_PATH:-}" ]; then
3646
echo "$PYTHON311_BIN" >> "$GITHUB_PATH"
3747
fi
3848
else
39-
python3.11 -m pip install "cargo-lambda==$CARGO_LAMBDA_VERSION"
40-
PYTHON311="python3.11"
49+
python3.11 -m pip install "cargo-lambda==$CARGO_LAMBDA_VERSION" ziglang
50+
PYTHON_CMD="python3.11"
4151
fi
4252

4353
# Create a zig wrapper so SAM CLI's cargo-lambda can find it
44-
printf '#!/bin/bash\nexec %s -m ziglang "$@"\n' "$PYTHON311" | sudo tee /usr/local/bin/zig > /dev/null
45-
sudo chmod +x /usr/local/bin/zig
54+
if [[ "${RUNNER_OS:-}" == "Windows" ]]; then
55+
# Install zig via chocolatey (most reliable on Windows)
56+
choco install zig --no-progress -y 2>/dev/null || true
57+
# Fallback: create wrappers using the Python that has ziglang installed
58+
if ! command -v zig &>/dev/null; then
59+
ZIG_PYTHON="$PYTHON_CMD"
60+
printf '#!/bin/bash\nexec "%s" -m ziglang "$@"\n' "$ZIG_PYTHON" > /c/Windows/zig
61+
printf '@echo off\r\n"%s" -m ziglang %%*\r\n' "$ZIG_PYTHON" > /c/Windows/zig.cmd
62+
fi
63+
else
64+
printf '#!/bin/bash\nexec %s -m ziglang "$@"\n' "$PYTHON_CMD" | sudo tee /usr/local/bin/zig > /dev/null
65+
sudo chmod +x /usr/local/bin/zig
66+
fi
4667

4768
rustc -V
4869
cargo -V

‎tests/install-sam-cli-binary.sh‎

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ case "$OS" in
2525
*) echo "Unsupported macOS architecture: $ARCH"; exit 1 ;;
2626
esac
2727
;;
28+
msys*|mingw*|cygwin*)
29+
ASSET="AWS_SAM_CLI_64_PY3.msi"
30+
;;
2831
*)
2932
echo "Unsupported OS: $OS"; exit 1
3033
;;
@@ -51,11 +54,55 @@ case "$ASSET" in
5154
*.pkg)
5255
sudo installer -pkg "$TMPDIR/$ASSET" -target /
5356
;;
57+
*.msi)
58+
MSI_WIN="$(cygpath -w "$TMPDIR/$ASSET")"
59+
# Use PowerShell Start-Process for reliable non-interactive MSI install
60+
powershell.exe -Command "
61+
\$proc = Start-Process msiexec.exe -ArgumentList '/i', '$MSI_WIN', '/qn', '/norestart', '/l*v', 'D:\\msi-install.log' -Wait -PassThru
62+
if (\$proc.ExitCode -ne 0 -and \$proc.ExitCode -ne 3010) {
63+
Get-Content 'D:\\msi-install.log' -Tail 30 -ErrorAction SilentlyContinue
64+
exit \$proc.ExitCode
65+
}
66+
"
67+
# Nightly installs to AWSSAMCLI_NIGHTLY, release to AWSSAMCLI
68+
if [ -d "C:/Program Files/Amazon/AWSSAMCLI_NIGHTLY/bin" ]; then
69+
SAM_DIR="C:/Program Files/Amazon/AWSSAMCLI_NIGHTLY/bin"
70+
else
71+
SAM_DIR="C:/Program Files/Amazon/AWSSAMCLI/bin"
72+
fi
73+
if [ -n "${GITHUB_PATH:-}" ]; then
74+
echo "$SAM_DIR" >> "$GITHUB_PATH"
75+
fi
76+
export PATH="$SAM_DIR:$PATH"
77+
# Nightly binary is sam-nightly.cmd; create sam.cmd wrapper
78+
if [ -f "$SAM_DIR/sam-nightly.cmd" ]; then
79+
cp "$SAM_DIR/sam-nightly.cmd" "$SAM_DIR/sam.cmd"
80+
fi
81+
if [ -f "$SAM_DIR/sam-nightly.exe" ]; then
82+
cp "$SAM_DIR/sam-nightly.exe" "$SAM_DIR/sam.exe"
83+
fi
84+
;;
5485
esac
5586

56-
# Nightly installs as sam-nightly; rename to sam
87+
# Nightly installs as sam-nightly on Linux/macOS; rename to sam
5788
if [ -f /usr/local/bin/sam-nightly ]; then
5889
sudo mv /usr/local/bin/sam-nightly /usr/local/bin/sam
5990
fi
6091

61-
sam --version
92+
# On Windows, set SAM_WINDOWS_BINARY_PATH for tests
93+
case "$OS" in
94+
msys*|mingw*|cygwin*)
95+
if [ -f "$SAM_DIR/sam-nightly.cmd" ]; then
96+
WIN_SAM_PATH="$(cygpath -w "$SAM_DIR/sam-nightly.cmd")"
97+
elif [ -f "$SAM_DIR/sam.cmd" ]; then
98+
WIN_SAM_PATH="$(cygpath -w "$SAM_DIR/sam.cmd")"
99+
fi
100+
if [ -n "${WIN_SAM_PATH:-}" ] && [ -n "${GITHUB_ENV:-}" ]; then
101+
echo "SAM_WINDOWS_BINARY_PATH=$WIN_SAM_PATH" >> "$GITHUB_ENV"
102+
fi
103+
"$SAM_DIR/sam.cmd" --version || "$SAM_DIR/sam-nightly.cmd" --version
104+
;;
105+
*)
106+
sam --version
107+
;;
108+
esac

‎tests/install-terraform.sh‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash
2+
# Install the latest Terraform for SAM CLI integration tests.
3+
# Supports both Linux and Windows (Git Bash on GitHub Actions).
4+
set -euo pipefail
5+
6+
if [[ "${RUNNER_OS:-}" == "Windows" ]]; then
7+
echo "=== Installing Terraform on Windows via choco ==="
8+
choco install terraform -y
9+
else
10+
echo "=== Installing Terraform on Linux ==="
11+
for i in {1..3}; do
12+
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')
13+
if [ -n "$TER_VER" ]; then
14+
if wget -q "https://releases.hashicorp.com/terraform/${TER_VER}/terraform_${TER_VER}_linux_amd64.zip" -P /tmp; then
15+
sudo unzip -o -q /tmp/terraform_${TER_VER}_linux_amd64.zip -d /opt/terraform
16+
sudo mv /opt/terraform/terraform /usr/local/bin/
17+
break
18+
fi
19+
fi
20+
echo "Terraform installation attempt $i failed, retrying..."
21+
sleep 5
22+
done
23+
fi
24+
25+
terraform -version
26+
echo "=== Terraform installation complete ==="

‎tests/integration/buildcmd/test_build_cmd.py‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,6 @@ def _validate_skipped_built_function(
281281
@pytest.mark.ruby
282282
class TestBuildCommand_RubyFunctions(BuildIntegRubyBase):
283283
@parameterized.expand([(False,), ("use_container",)], name_func=show_container_in_test_name)
284-
@pytest.mark.tier1
285284
def test_building_ruby_3_2(self, use_container):
286285
if use_container and SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD:
287286
self.skipTest(SKIP_DOCKER_MESSAGE)
@@ -308,14 +307,25 @@ def test_building_ruby_3_2(self, use_container):
308307
[
309308
("ruby3.3", "Ruby33", False),
310309
("ruby3.3", "Ruby33", "use_container"),
311-
# ("ruby3.4", "Ruby34", False), # TODO: Try to make this work in AppVeyor (windows-al2023)
310+
],
311+
name_func=show_container_in_test_name,
312+
)
313+
@skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE)
314+
@pytest.mark.al2023
315+
def test_building_ruby_3_3_al2023(self, runtime, codeuri, use_container):
316+
self._test_with_default_gemfile(runtime, use_container, codeuri, self.test_data_path, "x86_64")
317+
318+
@parameterized.expand(
319+
[
320+
("ruby3.4", "Ruby34", False), # TODO: Try to make this work in AppVeyor (windows-al2023)
312321
("ruby3.4", "Ruby34", "use_container"),
313322
],
314323
name_func=show_container_in_test_name,
315324
)
316325
@skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE)
317326
@pytest.mark.al2023
318-
def test_building_ruby_al2023(self, runtime, codeuri, use_container):
327+
@pytest.mark.tier1
328+
def test_building_ruby_3_4_al2023(self, runtime, codeuri, use_container):
319329
self._test_with_default_gemfile(runtime, use_container, codeuri, self.test_data_path, "x86_64")
320330

321331

‎tests/integration/buildcmd/test_build_cmd_python.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,6 @@ class TestBuildCommand_PythonFunctions_WithDocker(BuildIntegPythonBase):
419419
# ("python3.11", "PythonPyProject", "template_uv.yaml"),
420420
]
421421
)
422-
@pytest.mark.tier1
423422
def test_with_default_requirements_in_container(self, runtime, codeuri, template="template.yaml"):
424423
self._test_with_default_requirements(
425424
runtime,
@@ -447,6 +446,7 @@ def test_with_default_requirements_in_container(self, runtime, codeuri, template
447446
]
448447
)
449448
@pytest.mark.al2023
449+
@pytest.mark.tier1
450450
def test_with_default_requirements_al2023_in_container(self, runtime, codeuri, template="template.yaml"):
451451
self._test_with_default_requirements(
452452
runtime,

0 commit comments

Comments
 (0)