Skip to content

Commit

Permalink
Create fastly-edge-assignments integration tests (#75)
Browse files Browse the repository at this point in the history
* Create fastly-edge-assignments integration tests.

* refactor

* add test for CORS headers

* rm fastly-edge-assignments/Makefile

* Update .github/workflows/fastly-edge-assignments.yml

Co-authored-by: Oleksii Shmalko <[email protected]>

* Revert "rm fastly-edge-assignments/Makefile"

This reverts commit 9131130.

---------

Co-authored-by: Oleksii Shmalko <[email protected]>
  • Loading branch information
leoromanovsky and rasendubi authored Dec 11, 2024
1 parent 4399595 commit d8dd6e5
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 2 deletions.
64 changes: 64 additions & 0 deletions .github/workflows/fastly-edge-assignments.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Fastly Edge Assignments

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
cargo_build_and_test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: fastly-edge-assignments
steps:
- uses: actions/checkout@v4
with:
submodules: true

# Cache Rust toolchain and dependencies
- uses: actions/cache@v3
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
~/.rustup/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
target: wasm32-wasi

# Install tools only if not cached
- name: Install Tools
run: |
if ! command -v cargo-nextest &> /dev/null; then
cargo install cargo-nextest
fi
if ! command -v fastly &> /dev/null; then
wget https://github.com/fastly/cli/releases/download/v10.17.0/fastly_10.17.0_linux_amd64.deb
sudo apt install ./fastly_10.17.0_linux_amd64.deb
fi
if ! command -v viceroy &> /dev/null; then
cargo install viceroy
fi
# Build WASM target
- run: make build

# Run unit and integration tests
- run: make test
3 changes: 3 additions & 0 deletions fastly-edge-assignments/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
[build]
target = "wasm32-wasi"

[target.wasm32-wasi]
runner = "viceroy run -C fastly.toml -- "

[patch.crates-io]
# Local override for development.
eppo_core = { path = '../eppo_core' }
31 changes: 31 additions & 0 deletions fastly-edge-assignments/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
SHELL := bash
.ONESHELL:
.SHELLFLAGS := -eu -o pipefail -c
.DELETE_ON_ERROR:
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules

WASM_TARGET=wasm32-wasi
BUILD_DIR=target/$(WASM_TARGET)/release
WASM_FILE=$(BUILD_DIR)/$(FASTLY_PACKAGE).wasm

# Help target for easy documentation
.PHONY: help
help:
@echo "Available targets:"
@echo " build - Build the WASM target"
@echo " test - Run unit and integration tests"
@echo " clean - Clean all build artifacts"

.PHONY: clean
clean:
rm -rf bin pkg

.PHONY: build
build:
rustup target add $(WASM_TARGET)
fastly compute build

.PHONY: test
test:
cargo nextest run
30 changes: 30 additions & 0 deletions fastly-edge-assignments/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
# Eppo Assignments on Fastly Compute@Edge

TODO: Add a description

## Development

Install Rust toolchain:

`curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`

Install Fastly CLI:

`brew install fastly/tap/fastly`

https://www.fastly.com/documentation/reference/tools/cli/

Install Viceroy:

`cargo install viceroy`

Build with Fastly:

`make build`

## Testing

Install nextest:

`cargo binstall cargo-nextest --secure`

Run tests:

`make test`
54 changes: 52 additions & 2 deletions fastly-edge-assignments/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,17 @@ mod handlers;
use fastly::http::{Method, StatusCode};
use fastly::{Error, Request, Response};

#[fastly::main]
fn main(req: Request) -> Result<Response, Error> {
#[cfg(test)]
const TEST_HOST: &str = "test-host";

fn main() -> Result<(), Error> {
let ds_req = Request::from_client();
let us_resp = handler(ds_req)?;
us_resp.send_to_client();
Ok(())
}

fn handler(req: Request) -> Result<Response, Error> {
// Handle CORS preflight requests
if req.get_method() == Method::OPTIONS {
return Ok(Response::from_status(StatusCode::NO_CONTENT)
Expand All @@ -26,3 +35,44 @@ fn main(req: Request) -> Result<Response, Error> {
.with_header("Access-Control-Allow-Origin", "*")
.with_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS"))
}

#[test]
fn test_health() {
let req = fastly::Request::get(&format!("https://{}/health", TEST_HOST));
let resp = handler(req).expect("request succeeds");
assert_eq!(resp.get_status(), StatusCode::OK);
assert_eq!(resp.into_body_str(), "OK");
}

#[test]
fn test_cors_headers() {
let req = Request::get(&format!("https://{}/health", TEST_HOST));
let resp = handler(req).expect("request succeeds");

assert_eq!(resp.get_header("Access-Control-Allow-Origin").unwrap(), "*");
assert_eq!(
resp.get_header("Access-Control-Allow-Methods").unwrap(),
"GET, POST, OPTIONS"
);
}

#[test]
fn test_options_request() {
let req = Request::new(
Method::OPTIONS,
&format!("https://{}/assignments", TEST_HOST),
);
let resp = handler(req).expect("request succeeds");

assert_eq!(resp.get_status(), StatusCode::NO_CONTENT);
assert_eq!(resp.get_header("Access-Control-Allow-Origin").unwrap(), "*");
assert_eq!(
resp.get_header("Access-Control-Allow-Methods").unwrap(),
"GET, POST, OPTIONS"
);
assert_eq!(
resp.get_header("Access-Control-Allow-Headers").unwrap(),
"Content-Type"
);
assert_eq!(resp.get_header("Access-Control-Max-Age").unwrap(), "86400");
}

0 comments on commit d8dd6e5

Please sign in to comment.