Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
179 changes: 179 additions & 0 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
name: "Integration Tests"

permissions:
contents: read

on:
push:
branches: [main]
pull_request:
pull_request_review:
types: [submitted]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🌱 pull_request_review trigger means integration tests re-run on every review submission, even when no code changed. Combined with the pull_request trigger, an approval on an existing PR triggers a full redundant run. Consider removing this trigger or using workflow_dispatch for on-demand runs.

workflow_dispatch:

env:
ORIGIN_PORT: 8888

jobs:
integration-tests:
name: integration tests
runs-on: ubuntu-latest
if: >-
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'pull_request_review' && github.event.review.state == 'approved')
steps:
- uses: actions/checkout@v4

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

- 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: Get Viceroy cache key
id: viceroy-rev
run: echo "sha=$(git ls-remote https://github.com/fastly/Viceroy HEAD | cut -f1)" >> $GITHUB_OUTPUT

- name: Cache Viceroy binary
id: cache-viceroy
uses: actions/cache@v4
with:
path: ~/.cargo/bin/viceroy
key: viceroy-${{ runner.os }}-${{ steps.viceroy-rev.outputs.sha }}

- name: Install Viceroy
if: steps.cache-viceroy.outputs.cache-hit != 'true'
run: cargo install --git https://github.com/fastly/Viceroy viceroy

- name: Build WASM binary
run: cargo build --bin trusted-server-fastly --release --target wasm32-wasip1
env:
TRUSTED_SERVER__PUBLISHER__ORIGIN_URL: "http://127.0.0.1:${{ env.ORIGIN_PORT }}"
TRUSTED_SERVER__PROXY__CERTIFICATE_CHECK: "false"

- name: Build WordPress test container
run: |
docker build -t test-wordpress:latest \
crates/integration-tests/fixtures/frameworks/wordpress/

- name: Build Next.js test container
run: |
docker build -t test-nextjs:latest \
crates/integration-tests/fixtures/frameworks/nextjs/

- name: Run integration tests
run: >-
cargo test
--manifest-path crates/integration-tests/Cargo.toml
--target x86_64-unknown-linux-gnu
-- --include-ignored --test-threads=1
env:
INTEGRATION_ORIGIN_PORT: ${{ env.ORIGIN_PORT }}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 The browser-tests and integration-tests jobs duplicate ~80 lines of identical setup: checkout, Rust toolchain, Viceroy cache, WASM build, and both Docker image builds. When any of these steps change (e.g. Viceroy install command), one job can be updated while the other is missed.

Consider extracting the shared setup into a composite action or reusable workflow.

RUST_LOG: info

browser-tests:
name: browser integration tests
runs-on: ubuntu-latest
if: >-
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'pull_request_review' && github.event.review.state == 'approved')
steps:
- uses: actions/checkout@v4

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

- 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: Get Viceroy cache key
id: viceroy-rev
run: echo "sha=$(git ls-remote https://github.com/fastly/Viceroy HEAD | cut -f1)" >> $GITHUB_OUTPUT

- name: Cache Viceroy binary
id: cache-viceroy
uses: actions/cache@v4
with:
path: ~/.cargo/bin/viceroy
key: viceroy-${{ runner.os }}-${{ steps.viceroy-rev.outputs.sha }}

- name: Install Viceroy
if: steps.cache-viceroy.outputs.cache-hit != 'true'
run: cargo install --git https://github.com/fastly/Viceroy viceroy

- name: Build WASM binary
run: cargo build --bin trusted-server-fastly --release --target wasm32-wasip1
env:
TRUSTED_SERVER__PUBLISHER__ORIGIN_URL: "http://127.0.0.1:${{ env.ORIGIN_PORT }}"
TRUSTED_SERVER__PROXY__CERTIFICATE_CHECK: "false"

- name: Build WordPress test container
run: |
docker build -t test-wordpress:latest \
crates/integration-tests/fixtures/frameworks/wordpress/

- name: Build Next.js test container
run: |
docker build -t test-nextjs:latest \
crates/integration-tests/fixtures/frameworks/nextjs/

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*

- 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: ${{ github.workspace }}/target/wasm32-wasip1/release/trusted-server-fastly.wasm
INTEGRATION_ORIGIN_PORT: ${{ env.ORIGIN_PORT }}
VICEROY_CONFIG_PATH: ${{ github.workspace }}/crates/integration-tests/fixtures/configs/viceroy-template.toml
TEST_FRAMEWORK: nextjs
run: npx playwright test

- name: Run browser tests (WordPress)
working-directory: crates/integration-tests/browser
env:
WASM_BINARY_PATH: ${{ github.workspace }}/target/wasm32-wasip1/release/trusted-server-fastly.wasm
INTEGRATION_ORIGIN_PORT: ${{ env.ORIGIN_PORT }}
VICEROY_CONFIG_PATH: ${{ github.workspace }}/crates/integration-tests/fixtures/configs/viceroy-template.toml
TEST_FRAMEWORK: wordpress
run: npx playwright test

- name: Upload Playwright HTML report
uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
path: crates/integration-tests/browser/playwright-report/
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 @@ -80,6 +80,12 @@ async fn route_request(

// Match known routes and handle them
let result = match (method, path.as_str()) {
// Health check endpoint for integration tests and monitoring.
// Namespaced to avoid shadowing publisher routes.
(Method::GET, "/__trusted-server/health") => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ This adds a hard intercept for GET /__trusted-server/health returning 200 ok before the catch-all publisher proxy.

Previously this path fell through to the origin. The /__trusted-server/ namespace makes collision unlikely, but if any publisher origin serves content at this path, behavior regresses from origin content to a forced health response.

Is the intent to keep this in production, or should it be gated behind a build-time flag so it's only active during testing?

Ok(Response::from_status(200).with_body_text_plain("ok"))
}

// Serve the tsjs library
(Method::GET, path) if path.starts_with("/static/tsjs=") => {
handle_tsjs_dynamic(&req, integration_registry)
Expand Down Expand Up @@ -176,7 +182,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 @@ -194,5 +200,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