From 51da71082e4cd41d787b88354d1e14c69ce22f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81ngel=20M?= Date: Tue, 30 May 2023 16:54:26 +0200 Subject: [PATCH] fix: set a global timeout per e2e test and check for the command output (#146) * fix: set a global timeout per e2e test and check for the command output * fix: print a message when the test reaches the timeout --- .github/workflows/build.yml | 3 +- tests/e2e.rs | 69 +++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 40af955b..1d640d08 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,6 +44,8 @@ jobs: run: cargo deny check build: name: Build and test + env: + E2E_MAX_WAITING_TIME: 60 strategy: fail-fast: false matrix: @@ -65,7 +67,6 @@ jobs: 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 -- --show-output diff --git a/tests/e2e.rs b/tests/e2e.rs index d8d18676..bfe49a12 100644 --- a/tests/e2e.rs +++ b/tests/e2e.rs @@ -1,8 +1,13 @@ #[cfg(test)] mod test { + use std::io::{BufRead, BufReader}; use std::path::PathBuf; use std::process::{Child, Command, Stdio}; - use std::{env, io, thread, time}; + use std::time::Instant; + use std::{env, io}; + + // Default timeout when waiting for wws to be ready + static DEFAULT_MAX_TIMEOUT: u64 = 30; #[cfg(not(target_os = "windows"))] fn get_wws_path() -> PathBuf { @@ -36,7 +41,7 @@ mod test { wws_path } - fn run(example_path: &str) -> io::Result { + fn run(example_path: &str, max_timeout: u64) -> io::Result { 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(); @@ -52,11 +57,30 @@ mod test { // Run the example println!("[E2E] Running the service"); - Command::new(&wws_path).arg(&example_path).spawn() - } + let mut child = Command::new(&wws_path) + .arg(&example_path) + .stdout(Stdio::piped()) + .spawn()?; + + let stdout = child.stdout.take().unwrap(); + let reader = BufReader::new(stdout); + + // Set a max timeout + let instant = Instant::now(); + + for line in reader.lines() { + let line = line.unwrap(); + + // Break when ready of after the timeout + if line.contains("Start serving requests") { + break; + } else if instant.elapsed().as_secs() >= max_timeout { + println!("Timeout waiting for wws to be ready"); + break; + } + } - fn sleep_for(seconds: u64) { - thread::sleep(time::Duration::from_secs(seconds)); + Ok(child) } fn request_body(url: &str) -> Result { @@ -64,12 +88,12 @@ mod test { } // Check the examples/js-json works - fn run_end_to_end_test(example: &str, waiting_seconds: u64, url: &str, expected_text: &str) { + fn run_end_to_end_test(example: &str, max_timeout: u64, url: &str, expected_text: &str) { println!("[E2E] Running example: {example}"); - let mut child = run(example).expect("Failed to execute command"); + let mut child = run(example, max_timeout).expect("Failed to execute command"); - sleep_for(waiting_seconds); + // sleep_for(waiting_seconds); let body = match request_body(url) { Ok(body) => body, @@ -94,76 +118,61 @@ mod test { 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::().ok()); - - // env (Result(String)) -> map () + let max_timeout = env::var("E2E_MAX_WAITING_TIME").map_or(DEFAULT_MAX_TIMEOUT, |str| { + str.parse::().ok().unwrap_or(DEFAULT_MAX_TIMEOUT) + }); 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-kv", "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-async", - global_timeout.unwrap_or(5), "http://localhost:8080", "This page was generated by a JavaScript (async worker) 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); + for (example, url, expected_text) in tests { + run_end_to_end_test(example, max_timeout, url, expected_text); } } }