From dbf861f8a02f4a90ef68a4e2741b973becc53438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Thu, 14 Nov 2019 00:48:34 +0100 Subject: [PATCH] tests: share http server between tests (#3336) Re-enable flaky tests --- cli/test_util.rs | 83 +++++++++++++++++++--------------- cli/tests/integration_tests.rs | 12 ----- 2 files changed, 46 insertions(+), 49 deletions(-) diff --git a/cli/test_util.rs b/cli/test_util.rs index a42520ca51..a207823804 100644 --- a/cli/test_util.rs +++ b/cli/test_util.rs @@ -8,11 +8,13 @@ use std::path::PathBuf; use std::process::Child; use std::process::Command; use std::process::Stdio; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering; use std::sync::Mutex; -use std::sync::MutexGuard; lazy_static! { - static ref GUARD: Mutex<()> = Mutex::new(()); + static ref SERVER: Mutex> = Mutex::new(None); + static ref SERVER_COUNT: AtomicUsize = AtomicUsize::new(0); } pub fn root_path() -> PathBuf { @@ -35,45 +37,52 @@ pub fn deno_exe_path() -> PathBuf { p } -pub struct HttpServerGuard<'a> { - #[allow(dead_code)] - g: MutexGuard<'a, ()>, - child: Child, -} +pub struct HttpServerGuard {} -impl<'a> Drop for HttpServerGuard<'a> { +impl Drop for HttpServerGuard { fn drop(&mut self) { - match self.child.try_wait() { - Ok(None) => { - self.child.kill().expect("failed to kill http_server.py"); - } - Ok(Some(status)) => { - panic!("http_server.py exited unexpectedly {}", status) - } - Err(e) => panic!("http_server.py err {}", e), + let count = SERVER_COUNT.fetch_sub(1, Ordering::Relaxed); + // If no more tests hold guard we can kill the server + if count == 1 { + kill_http_server(); } } } -/// Starts tools/http_server.py when the returned guard is dropped, the server -/// will be killed. -pub fn http_server<'a>() -> HttpServerGuard<'a> { - // TODO(ry) Allow tests to use the http server in parallel. - let g = GUARD.lock().unwrap(); - - println!("tools/http_server.py starting..."); - let mut child = Command::new("python") - .current_dir(root_path()) - .args(&["-u", "tools/http_server.py"]) - .stdout(Stdio::piped()) - .spawn() - .expect("failed to execute child"); - - let stdout = child.stdout.as_mut().unwrap(); - use std::io::{BufRead, BufReader}; - let mut lines = BufReader::new(stdout).lines(); - let line = lines.next().unwrap().unwrap(); - assert!(line.starts_with("ready")); - - HttpServerGuard { child, g } +fn kill_http_server() { + let mut server_guard = SERVER.lock().unwrap(); + let mut child = server_guard + .take() + .expect("Trying to kill server but already killed"); + match child.try_wait() { + Ok(None) => { + child.kill().expect("failed to kill http_server.py"); + } + Ok(Some(status)) => panic!("http_server.py exited unexpectedly {}", status), + Err(e) => panic!("http_server.py err {}", e), + }; +} + +pub fn http_server() -> HttpServerGuard { + SERVER_COUNT.fetch_add(1, Ordering::Relaxed); + { + let mut server_guard = SERVER.lock().unwrap(); + if server_guard.is_none() { + println!("tools/http_server.py starting..."); + let mut child = Command::new("python") + .current_dir(root_path()) + .args(&["-u", "tools/http_server.py"]) + .stdout(Stdio::piped()) + .spawn() + .expect("failed to execute child"); + + let stdout = child.stdout.as_mut().unwrap(); + use std::io::{BufRead, BufReader}; + let mut lines = BufReader::new(stdout).lines(); + let line = lines.next().unwrap().unwrap(); + assert!(line.starts_with("ready")); + server_guard.replace(child); + } + } + HttpServerGuard {} } diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index b8dab2de8a..6357bf037c 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -156,13 +156,11 @@ itest!(_018_async_catch { output: "018_async_catch.ts.out", }); -/* TODO(ry) Re-enable this test. It is flaky and only fails occasionally. itest!(_019_media_types { args: "run --reload 019_media_types.ts", output: "019_media_types.ts.out", http_server: true, }); -*/ itest!(_020_json_modules { args: "run --reload 020_json_modules.ts", @@ -174,13 +172,11 @@ itest!(_021_mjs_modules { output: "021_mjs_modules.ts.out", }); -/* TODO(ry) Re-enable this test. It is flaky and only fails occasionally. itest!(_022_info_flag_script { args: "info http://127.0.0.1:4545/cli/tests/019_media_types.ts", output: "022_info_flag_script.out", http_server: true, }); -*/ itest!(_023_no_ext_with_headers { args: "run --reload 023_no_ext_with_headers", @@ -335,21 +331,17 @@ itest!(_047_jsx { output: "047_jsx_test.jsx.out", }); -/* TODO(ry) Re-enable this test. It is flaky and only fails occasionally. itest!(_048_media_types_jsx { args: "run --reload 048_media_types_jsx.ts", output: "048_media_types_jsx.ts.out", http_server: true, }); -*/ -/* TODO(ry) Re-enable this test. It is flaky and only fails occasionally. itest!(_049_info_flag_script_jsx { args: "info http://127.0.0.1:4545/cli/tests/048_media_types_jsx.ts", output: "049_info_flag_script_jsx.out", http_server: true, }); -*/ itest!(_050_more_jsons { args: "run --reload 050_more_jsons.ts", @@ -362,13 +354,11 @@ itest!(lock_check_ok { http_server: true, }); -/* TODO(ry) Re-enable this test. It is flaky and only fails occasionally. itest!(lock_check_ok2 { args: "run 019_media_types.ts --lock=lock_check_ok2.json", output: "019_media_types.ts.out", http_server: true, }); -*/ itest!(lock_check_err { args: "run --lock=lock_check_err.json http://127.0.0.1:4545/cli/tests/003_relative_import.ts", @@ -378,7 +368,6 @@ itest!(lock_check_err { http_server: true, }); -/* TODO(ry) Re-enable this test. It is flaky and only fails occasionally. itest!(lock_check_err2 { args: "run 019_media_types.ts --lock=lock_check_err2.json", output: "lock_check_err2.out", @@ -386,7 +375,6 @@ itest!(lock_check_err2 { exit_code: 10, http_server: true, }); -*/ itest!(async_error { exit_code: 1,