Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ac612b2
Wip integration testing with testcontainers
prk-Jr Mar 5, 2026
2d2600e
Feature integration test with TestContainers
prk-Jr Mar 5, 2026
efbef4c
Suppress dead_code and unused_imports in integration-tests
prk-Jr Mar 5, 2026
a02c080
wip: integration tests
prk-Jr Mar 6, 2026
e9e466c
wip: AttributeRewriting
prk-Jr Mar 6, 2026
fef992f
HTTP-level improvements
prk-Jr Mar 6, 2026
582f80c
Enrich Next.js fixture and add browser integration tests
prk-Jr Mar 7, 2026
12bb1f1
Add deferred route script test for SPA transitions
prk-Jr Mar 7, 2026
1d79015
Update integration test documentation to reflect current state
prk-Jr Mar 7, 2026
814b6d2
Temporarily trigger integration tests on PR push
prk-Jr Mar 7, 2026
b903635
Add pull_request to job-level if conditions
prk-Jr Mar 7, 2026
eb2aa1c
Fix path for wasm binary in ci
prk-Jr Mar 7, 2026
9340a86
Merge branch 'main' into feature/integration-testing-with-testcontainers
aram356 Mar 8, 2026
012b8bd
Harden integration test infrastructure and fix production conventions
prk-Jr Mar 9, 2026
867d4e5
Merge branch 'feature/integration-testing-with-testcontainers' of git…
prk-Jr Mar 9, 2026
4dc2d3c
Update integration tests for latest error-stack API
prk-Jr Mar 9, 2026
437a9f4
Harden integration test dependency and fixture reproducibility
prk-Jr Mar 11, 2026
5b00113
Trigger integration test on pull requets only
prk-Jr Mar 13, 2026
10d96b5
Merge branch 'main' into feature/integration-testing-with-testcontainers
aram356 Mar 13, 2026
be5be73
Resolve PR review: pin Viceroy, fix CI triggers, add timeouts, and ha…
prk-Jr Mar 16, 2026
f5fd692
Resolve PR review findings in integration test infrastructure
prk-Jr Mar 17, 2026
dea5a8f
Refine integration test readiness and CI artifact reuse
prk-Jr Mar 17, 2026
97d2626
Merge branch 'main' into feature/integration-testing-with-testcontainers
prk-Jr Mar 18, 2026
1076a1b
Merge branch 'main' into feature/integration-testing-with-testcontainers
prk-Jr Mar 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions .github/actions/setup-integration-test-env/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Setup integration test environment
description: Prepare toolchains, Viceroy, and Docker images for integration test jobs.

inputs:
origin-port:
description: Fixed origin port baked into the WASM binary for integration tests.
required: true
check-dependency-versions:
description: Run the integration dependency version consistency check.
required: false
default: "true"
install-viceroy:
description: Install the Viceroy binary used by integration tests.
required: false
default: "true"
build-wasm:
description: Build the trusted-server WASM binary for integration tests.
required: false
default: "true"
build-test-images:
description: Build the framework Docker images used by integration tests.
required: false
default: "true"

outputs:
node-version:
description: Node.js version read from .tool-versions.
value: ${{ steps.node-version.outputs.node-version }}

runs:
using: composite
steps:
- name: Check shared dependency versions
if: ${{ inputs.check-dependency-versions == 'true' }}
shell: bash
run: ./scripts/check-integration-dependency-versions.sh

- name: Retrieve Rust version
id: rust-version
shell: bash
run: echo "rust-version=$(grep '^rust ' .tool-versions | awk '{print $2}')" >> "$GITHUB_OUTPUT"

- name: Retrieve Node.js version
id: node-version
shell: bash
run: echo "node-version=$(grep '^nodejs ' .tool-versions | awk '{print $2}')" >> "$GITHUB_OUTPUT"

- name: Set up Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: ${{ steps.rust-version.outputs.rust-version }}
target: wasm32-wasip1
cache-shared-key: cargo-${{ runner.os }}

- name: Cache Viceroy binary
if: ${{ inputs.install-viceroy == 'true' }}
id: cache-viceroy
uses: actions/cache@v4
with:
path: ~/.cargo/bin/viceroy
key: viceroy-${{ runner.os }}-v0.16.4

- name: Install Viceroy
if: ${{ inputs.install-viceroy == 'true' && steps.cache-viceroy.outputs.cache-hit != 'true' }}
shell: bash
run: cargo install --git https://github.com/fastly/Viceroy --tag v0.16.4 viceroy

- name: Build WASM binary
if: ${{ inputs.build-wasm == 'true' }}
shell: bash
env:
TRUSTED_SERVER__PUBLISHER__ORIGIN_URL: http://127.0.0.1:${{ inputs.origin-port }}
TRUSTED_SERVER__PROXY__CERTIFICATE_CHECK: "false"
run: cargo build --bin trusted-server-fastly --release --target wasm32-wasip1

- name: Build WordPress test container
if: ${{ inputs.build-test-images == 'true' }}
shell: bash
run: |
docker build -t test-wordpress:latest \
crates/integration-tests/fixtures/frameworks/wordpress/

- name: Build Next.js test container
if: ${{ inputs.build-test-images == 'true' }}
shell: bash
run: |
docker build \
--build-arg NODE_VERSION=${{ steps.node-version.outputs.node-version }} \
-t test-nextjs:latest \
crates/integration-tests/fixtures/frameworks/nextjs/
169 changes: 169 additions & 0 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
name: "Integration Tests"

permissions:
contents: read

on:
# Intentionally PR-only plus manual dispatch. Direct pushes to `main` are
# expected to arrive through PR merges, which already run this workflow.
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:

env:
ORIGIN_PORT: 8888
ARTIFACTS_DIR: /tmp/integration-test-artifacts
WASM_ARTIFACT_PATH: /tmp/integration-test-artifacts/wasm/trusted-server-fastly.wasm
DOCKER_ARTIFACT_PATH: /tmp/integration-test-artifacts/docker/test-images.tar

jobs:
prepare-artifacts:
name: prepare integration artifacts
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4

- name: Set up shared integration build environment
uses: ./.github/actions/setup-integration-test-env
with:
origin-port: ${{ env.ORIGIN_PORT }}
install-viceroy: "false"

- name: Package integration test artifacts
run: |
mkdir -p "$(dirname "$WASM_ARTIFACT_PATH")" "$(dirname "$DOCKER_ARTIFACT_PATH")"
cp target/wasm32-wasip1/release/trusted-server-fastly.wasm "$WASM_ARTIFACT_PATH"
docker save \
--output "$DOCKER_ARTIFACT_PATH" \
test-wordpress:latest test-nextjs:latest

- name: Upload integration test artifacts
uses: actions/upload-artifact@v4
with:
name: integration-test-artifacts
path: ${{ env.ARTIFACTS_DIR }}
retention-days: 1

integration-tests:
name: integration tests
needs: prepare-artifacts
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4

- name: Set up integration test runtime
id: shared-setup
uses: ./.github/actions/setup-integration-test-env
with:
origin-port: ${{ env.ORIGIN_PORT }}
check-dependency-versions: "false"
install-viceroy: "true"
build-wasm: "false"
build-test-images: "false"

- name: Download integration test artifacts
uses: actions/download-artifact@v4
with:
name: integration-test-artifacts
path: ${{ env.ARTIFACTS_DIR }}

- name: Load integration test Docker images
run: docker load --input "$DOCKER_ARTIFACT_PATH"

- name: Run integration tests
run: >-
cargo test
--manifest-path crates/integration-tests/Cargo.toml
--target x86_64-unknown-linux-gnu
-- --include-ignored --skip test_wordpress_fastly --skip test_nextjs_fastly --test-threads=1
env:
WASM_BINARY_PATH: ${{ env.WASM_ARTIFACT_PATH }}
INTEGRATION_ORIGIN_PORT: ${{ env.ORIGIN_PORT }}
RUST_LOG: info

browser-tests:
name: browser integration tests
needs: prepare-artifacts
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4

- name: Set up browser test runtime
id: shared-setup
uses: ./.github/actions/setup-integration-test-env
with:
origin-port: ${{ env.ORIGIN_PORT }}
check-dependency-versions: "false"
install-viceroy: "true"
build-wasm: "false"
build-test-images: "false"

- name: Download integration test artifacts
uses: actions/download-artifact@v4
with:
name: integration-test-artifacts
path: ${{ env.ARTIFACTS_DIR }}

- name: Load integration test Docker images
run: docker load --input "$DOCKER_ARTIFACT_PATH"

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ steps.shared-setup.outputs.node-version }}
cache: npm
cache-dependency-path: crates/integration-tests/browser/package-lock.json

- name: Install Playwright
working-directory: crates/integration-tests/browser
run: |
npm ci
npx playwright install --with-deps chromium

- name: Run browser tests (Next.js)
working-directory: crates/integration-tests/browser
env:
WASM_BINARY_PATH: ${{ env.WASM_ARTIFACT_PATH }}
INTEGRATION_ORIGIN_PORT: ${{ env.ORIGIN_PORT }}
VICEROY_CONFIG_PATH: ${{ github.workspace }}/crates/integration-tests/fixtures/configs/viceroy-template.toml
TEST_FRAMEWORK: nextjs
PLAYWRIGHT_HTML_REPORT: playwright-report-nextjs
run: npx playwright test

- name: Upload Playwright report (Next.js)
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report-nextjs
path: crates/integration-tests/browser/playwright-report-nextjs/
retention-days: 7

- name: Run browser tests (WordPress)
if: always()
working-directory: crates/integration-tests/browser
env:
WASM_BINARY_PATH: ${{ env.WASM_ARTIFACT_PATH }}
INTEGRATION_ORIGIN_PORT: ${{ env.ORIGIN_PORT }}
VICEROY_CONFIG_PATH: ${{ github.workspace }}/crates/integration-tests/fixtures/configs/viceroy-template.toml
TEST_FRAMEWORK: wordpress
PLAYWRIGHT_HTML_REPORT: playwright-report-wordpress
run: npx playwright test

- name: Upload Playwright report (WordPress)
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report-wordpress
path: crates/integration-tests/browser/playwright-report-wordpress/
retention-days: 7

- name: Upload Playwright traces and screenshots
uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-traces
path: crates/integration-tests/browser/test-results/
retention-days: 7
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
run: cargo install --git https://github.com/fastly/Viceroy viceroy

- name: Run tests
run: cargo test
run: cargo test --workspace

test-typescript:
name: vitest
Expand Down
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/bin
/pkg
/target
/crates/integration-tests/target

# env
.env*
Expand All @@ -28,4 +29,10 @@ src/*.html
*.pem

/guest-profiles
/benchmark-results/**
/benchmark-results/**

# Playwright browser tests
/crates/integration-tests/browser/node_modules/
/crates/integration-tests/browser/test-results/
/crates/integration-tests/browser/playwright-report/
/crates/integration-tests/browser/.browser-test-state.json
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@
resolver = "2"
members = [
"crates/common",
"crates/fastly",
"crates/fastly",
"crates/js",
]
# integration-tests is intentionally excluded from workspace members because it
# requires a native target (testcontainers, reqwest) while the workspace default
# is wasm32-wasip1. Run it via: ./scripts/integration-tests.sh
exclude = [
"crates/integration-tests",
]

# Build defaults exclude the web-only tsjs crate, which is compiled via wasm-pack.
default-members = [
"crates/common",
"crates/fastly",
Expand Down
10 changes: 8 additions & 2 deletions crates/fastly/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ use crate::error::to_error_response;
fn main(req: Request) -> Result<Response, Error> {
init_logger();

// Keep the health probe independent from settings loading and routing so
// readiness checks still get a cheap liveness response during startup.
if req.get_method() == Method::GET && req.get_path() == "/health" {
return Ok(Response::from_status(200).with_body_text_plain("ok"));
}

let settings = match get_settings() {
Ok(s) => s,
Err(e) => {
Expand Down Expand Up @@ -183,7 +189,7 @@ fn init_logger() {
.echo_stdout(true)
.max_level(log::LevelFilter::Debug)
.build()
.expect("Failed to build Logger");
.expect("should build Logger");

fern::Dispatch::new()
.format(|out, message, record| {
Expand All @@ -201,5 +207,5 @@ fn init_logger() {
})
.chain(Box::new(logger) as Box<dyn log::Log>)
.apply()
.expect("Failed to initialize logger");
.expect("should initialize logger");
}
6 changes: 6 additions & 0 deletions crates/integration-tests/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
target/
*.rs
Cargo.toml
Cargo.lock
tests/
README.md
Loading
Loading