Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add e2e tests to check different examples are working properly #134

Merged
merged 18 commits into from
May 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
4016d9d
feat: add e2e tests to check different examples are working properly
Angelmmiguel May 23, 2023
7098bb2
fix: add wasm32-wasi target on the CI and format code
Angelmmiguel May 23, 2023
80abb5e
fix: make e2e timeouts configurable on the CI
Angelmmiguel May 23, 2023
62cc591
fix: format code correctly
Angelmmiguel May 23, 2023
4c2f03c
feat: use wws release binary when available on e2e tests
Angelmmiguel May 23, 2023
571cb22
fix: avoid using / in e2e for windows compatibility
Angelmmiguel May 23, 2023
ae47441
fix: configure wws binary to run in Windows
Angelmmiguel May 23, 2023
1c0a9ee
feat: redirect stderr on e2e tests and increase the timeouts in Windows
Angelmmiguel May 23, 2023
8684e0f
fix: increase Windows e2e timeout and print body
Angelmmiguel May 23, 2023
11f3b91
fix: remove unnecesary matrix element. Reduce timeouts
Angelmmiguel May 25, 2023
b3cc380
feat: add ruby and python e2e tests. Reuse wws release from cache
Angelmmiguel May 25, 2023
c9e854d
fix: use a bash script to check if the release file exists
Angelmmiguel May 25, 2023
c3111b6
fix: remove file detection as cache should be enough
Angelmmiguel May 25, 2023
b468c05
fix: increase timeouts for interpreted e2e tests and inherith the Stdio
Angelmmiguel May 25, 2023
b25b9cb
fix: wait for wws to install the runtimes
Angelmmiguel May 25, 2023
20d6303
fix: format the file correctly
Angelmmiguel May 25, 2023
3d0f5d9
format: improve E2E_WAITING_TIME load
Angelmmiguel May 25, 2023
37d7fcf
fix: use the right types when parsing the E2E_WAITING_TIME env variable
Angelmmiguel May 25, 2023
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
20 changes: 11 additions & 9 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ jobs:
run: cargo fmt --check
- name: Clippy
run: cargo clippy -- -D warnings
test:
build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
Expand All @@ -42,11 +42,13 @@ jobs:
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Install Wasm32-wasi target
run: rustup target add wasm32-wasi
- name: Build Rust examples
working-directory: ./examples
run: make all
- name: Build wws on release mode
if: steps.check_file_release.outputs.files_exists != 'true'
run: cargo build --verbose --release
- name: Test
run: cargo test --workspace --exclude wasm-workers-quick-js-engine
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build
run: cargo build --verbose
run: cargo test --workspace --exclude wasm-workers-quick-js-engine -- --show-output
11 changes: 11 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ wws-router = { workspace = true }
wws-server = { workspace = true }
wws-runtimes-manager = { workspace = true }

[dev-dependencies]
reqwest = { version = "0.11", features = ["blocking"] }

[target.x86_64-unknown-linux-musl.dependencies]
openssl = { version = "=0.10.48", features = ["vendored"] }

Expand Down
2 changes: 1 addition & 1 deletion examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ pdf-create:
cargo build --target wasm32-wasi --release && \
mv target/wasm32-wasi/release/pdf-create.wasm ./index.wasm

all: rust-basic rust-kv rust-params pdf-create
all: rust-basic rust-kv rust-params
44 changes: 44 additions & 0 deletions examples/ruby-basic/.wws.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
version = 1

[[repositories]]
name = "wasmlabs"
url = "https://workers.wasmlabs.dev/repository/v1/index.toml"

[[repositories.runtimes]]
name = "ruby"
version = "3.2.0+20230215-1"
tags = [
"latest",
"3.2",
"3.2.0",
]
status = "active"
extensions = ["rb"]
args = [
"--",
"/src/index.rb",
]

[repositories.runtimes.binary]
url = "https://github.com/vmware-labs/webassembly-language-runtimes/releases/download/ruby%2F3.2.0%2B20230215-1349da9/ruby-3.2.0.wasm"
filename = "ruby.wasm"

[repositories.runtimes.binary.checksum]
type = "sha256"
value = "abe348fba157a756f86194be445c77c99e8ed64ca76495ea07ed984f09eb66ae"

[repositories.runtimes.polyfill]
url = "https://workers.wasmlabs.dev/repository/v1/files/ruby/3-1/poly.rb"
filename = "poly.rb"

[repositories.runtimes.polyfill.checksum]
type = "sha256"
value = "449855a5d315879ab0ad830aa6a3f689e68fed4490617ea03efc77c9da64f630"

[repositories.runtimes.wrapper]
url = "https://workers.wasmlabs.dev/repository/v1/files/ruby/3-1/wrapper.txt"
filename = "wrapper.txt"

[repositories.runtimes.wrapper.checksum]
type = "sha256"
value = "6d808b4747cf30f82665a38a47e1176513bbdd6ad558c09db03d719e33ad2da0"
163 changes: 163 additions & 0 deletions tests/e2e.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
#[cfg(test)]
mod test {
use std::path::PathBuf;
use std::process::{Child, Command, Stdio};
use std::{env, io, thread, time};

#[cfg(not(target_os = "windows"))]
fn get_wws_path() -> PathBuf {
let path = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());

// Use release when it's available
let wws_path = if path.join("target/release/wws").exists() {
path.join("target/release/wws")
} else {
path.join("target/debug/wws")
};

println!("[E2E] Running wws from {}", wws_path.display());

wws_path
}

#[cfg(target_os = "windows")]
fn get_wws_path() -> PathBuf {
let path = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());

// Use release when it's available
let wws_path = if path.join("target/release/wws.exe").exists() {
path.join("target/release/wws.exe")
} else {
path.join("target/debug/wws.exe")
};

println!("[E2E] Running wws from {}", wws_path.display());

wws_path
}

fn run(example_path: &str) -> io::Result<Child> {
let path = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
let example_path = path.join("examples").join(example_path);
let wws_path = get_wws_path();

// Install missing runtimes
println!("[E2E] Installing missing runtimes");
Command::new(&wws_path)
.current_dir(&example_path)
.args(["runtimes", "install"])
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.status()?;

// Run the example
println!("[E2E] Running the service");
Command::new(&wws_path).arg(&example_path).spawn()
}

fn sleep_for(seconds: u64) {
thread::sleep(time::Duration::from_secs(seconds));
}

fn request_body(url: &str) -> Result<String, reqwest::Error> {
reqwest::blocking::get(url)?.text()
}

// Check the examples/js-json works
fn run_end_to_end_test(example: &str, waiting_seconds: u64, url: &str, expected_text: &str) {
println!("[E2E] Running example: {example}");

let mut child = run(example).expect("Failed to execute command");

sleep_for(waiting_seconds);

let body = match request_body(url) {
Ok(body) => body,
Err(err) => {
eprintln!("[E2E] Error getting the body from the request to {url}");
eprintln!("[E2E] Error: {}", err);
String::new()
}
};

println!("[E2E] Body content: {body}");

println!("[E2E] Stopping wws process [{}]", &child.id());
child.kill().expect("Error stopping wws");

// Test
assert!(body.contains(expected_text));
}

#[test]
// Use this approach to run tests sequentially
fn test_end_to_end() {
// Allow configuring waiting times. It avoids having long waiting times
// in development, while making it configurable in the CI
let global_timeout =
env::var("E2E_WAITING_TIME").map_or(None, |str| str.parse::<u64>().ok());

// env (Result(String)) -> map ()

let tests = [
(
"rust-basic",
global_timeout.unwrap_or(5),
"http://localhost:8080/basic",
"This page was generated by a Wasm module built from Rust",
),
(
"rust-kv",
global_timeout.unwrap_or(5),
"http://localhost:8080/kv",
"Counter: 0",
),
(
"rust-params",
global_timeout.unwrap_or(5),
"http://localhost:8080/thisisatest",
"thisisatest",
),
(
"js-basic",
global_timeout.unwrap_or(5),
"http://localhost:8080",
"This page was generated by a JavaScript file",
),
(
"js-json",
global_timeout.unwrap_or(5),
"http://localhost:8080/handler",
"This message comes from an environment variable",
),
(
"js-params",
global_timeout.unwrap_or(10),
"http://localhost:8080/thisisatest",
"thisisatest",
),
(
"python-basic",
global_timeout.unwrap_or(20),
"http://localhost:8080/",
"This page was generated by a Python script",
),
(
"python-mount",
global_timeout.unwrap_or(20),
"http://localhost:8080/",
"This page was loaded from a mounted file",
),
(
"ruby-basic",
global_timeout.unwrap_or(20),
"http://localhost:8080/",
"This page was generated by a Ruby script",
),
];

for (example, waiting_seconds, url, expected_text) in tests {
run_end_to_end_test(example, waiting_seconds, url, expected_text);
}
}
}