1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -05:00

chore: maybe make watcher tests less flaky (#23683)

Closes #23637
This commit is contained in:
David Sherret 2024-05-03 17:31:12 -04:00 committed by GitHub
parent 121769844d
commit d81e97f92f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 194 additions and 152 deletions

View file

@ -192,7 +192,8 @@ fn child_lines(
(stdout_lines, stderr_lines) (stdout_lines, stderr_lines)
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn lint_watch_test() { async fn lint_watch_test() {
let t = TempDir::new(); let t = TempDir::new();
let badly_linted_original = let badly_linted_original =
@ -209,10 +210,10 @@ async fn lint_watch_test() {
util::testdata_path().join("lint/watch/badly_linted_fixed2.js.out"); util::testdata_path().join("lint/watch/badly_linted_fixed2.js.out");
let badly_linted = t.path().join("badly_linted.js"); let badly_linted = t.path().join("badly_linted.js");
std::fs::copy(badly_linted_original, &badly_linted).unwrap(); badly_linted_original.copy(&badly_linted);
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("lint") .arg("lint")
.arg(&badly_linted) .arg(&badly_linted)
.arg("--watch") .arg("--watch")
@ -224,32 +225,31 @@ async fn lint_watch_test() {
assert_contains!(&next_line, "Lint started"); assert_contains!(&next_line, "Lint started");
let mut output = read_all_lints(&mut stderr_lines).await; let mut output = read_all_lints(&mut stderr_lines).await;
let expected = std::fs::read_to_string(badly_linted_output).unwrap(); let expected = badly_linted_output.read_to_string();
assert_eq!(output, expected); assert_eq!(output, expected);
// Change content of the file again to be badly-linted // Change content of the file again to be badly-linted
std::fs::copy(badly_linted_fixed1, &badly_linted).unwrap(); badly_linted_fixed1.copy(&badly_linted);
std::thread::sleep(std::time::Duration::from_secs(1));
output = read_all_lints(&mut stderr_lines).await; output = read_all_lints(&mut stderr_lines).await;
let expected = std::fs::read_to_string(badly_linted_fixed1_output).unwrap(); let expected = badly_linted_fixed1_output.read_to_string();
assert_eq!(output, expected); assert_eq!(output, expected);
// Change content of the file again to be badly-linted // Change content of the file again to be badly-linted
std::fs::copy(badly_linted_fixed2, &badly_linted).unwrap(); badly_linted_fixed2.copy(&badly_linted);
output = read_all_lints(&mut stderr_lines).await; output = read_all_lints(&mut stderr_lines).await;
let expected = std::fs::read_to_string(badly_linted_fixed2_output).unwrap(); let expected = badly_linted_fixed2_output.read_to_string();
assert_eq!(output, expected); assert_eq!(output, expected);
// the watcher process is still alive // the watcher process is still alive
assert!(child.try_wait().unwrap().is_none()); assert!(child.try_wait().unwrap().is_none());
child.kill().unwrap(); child.kill().unwrap();
drop(t);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn lint_watch_without_args_test() { async fn lint_watch_without_args_test() {
let t = TempDir::new(); let t = TempDir::new();
let badly_linted_original = let badly_linted_original =
@ -266,7 +266,7 @@ async fn lint_watch_without_args_test() {
util::testdata_path().join("lint/watch/badly_linted_fixed2.js.out"); util::testdata_path().join("lint/watch/badly_linted_fixed2.js.out");
let badly_linted = t.path().join("badly_linted.js"); let badly_linted = t.path().join("badly_linted.js");
std::fs::copy(badly_linted_original, &badly_linted).unwrap(); badly_linted_original.copy(&badly_linted);
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(t.path()) .current_dir(t.path())
@ -280,22 +280,21 @@ async fn lint_watch_without_args_test() {
let next_line = next_line(&mut stderr_lines).await.unwrap(); let next_line = next_line(&mut stderr_lines).await.unwrap();
assert_contains!(&next_line, "Lint started"); assert_contains!(&next_line, "Lint started");
let mut output = read_all_lints(&mut stderr_lines).await; let mut output = read_all_lints(&mut stderr_lines).await;
let expected = std::fs::read_to_string(badly_linted_output).unwrap(); let expected = badly_linted_output.read_to_string();
assert_eq!(output, expected); assert_eq!(output, expected);
// Change content of the file again to be badly-linted // Change content of the file again to be badly-linted
std::fs::copy(badly_linted_fixed1, &badly_linted).unwrap(); badly_linted_fixed1.copy(&badly_linted);
output = read_all_lints(&mut stderr_lines).await; output = read_all_lints(&mut stderr_lines).await;
let expected = std::fs::read_to_string(badly_linted_fixed1_output).unwrap(); let expected = badly_linted_fixed1_output.read_to_string();
assert_eq!(output, expected); assert_eq!(output, expected);
// Change content of the file again to be badly-linted // Change content of the file again to be badly-linted
std::fs::copy(badly_linted_fixed2, &badly_linted).unwrap(); badly_linted_fixed2.copy(&badly_linted);
std::thread::sleep(std::time::Duration::from_secs(1));
output = read_all_lints(&mut stderr_lines).await; output = read_all_lints(&mut stderr_lines).await;
let expected = std::fs::read_to_string(badly_linted_fixed2_output).unwrap(); let expected = badly_linted_fixed2_output.read_to_string();
assert_eq!(output, expected); assert_eq!(output, expected);
// the watcher process is still alive // the watcher process is still alive
@ -305,7 +304,8 @@ async fn lint_watch_without_args_test() {
drop(t); drop(t);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn lint_all_files_on_each_change_test() { async fn lint_all_files_on_each_change_test() {
let t = TempDir::new(); let t = TempDir::new();
let badly_linted_fixed0 = let badly_linted_fixed0 =
@ -317,11 +317,11 @@ async fn lint_all_files_on_each_change_test() {
let badly_linted_1 = t.path().join("badly_linted_1.js"); let badly_linted_1 = t.path().join("badly_linted_1.js");
let badly_linted_2 = t.path().join("badly_linted_2.js"); let badly_linted_2 = t.path().join("badly_linted_2.js");
std::fs::copy(badly_linted_fixed0, badly_linted_1).unwrap(); badly_linted_fixed0.copy(&badly_linted_1);
std::fs::copy(badly_linted_fixed1, &badly_linted_2).unwrap(); badly_linted_fixed1.copy(&badly_linted_2);
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("lint") .arg("lint")
.arg(t.path()) .arg(t.path())
.arg("--watch") .arg("--watch")
@ -336,7 +336,7 @@ async fn lint_all_files_on_each_change_test() {
"Checked 2 files" "Checked 2 files"
); );
std::fs::copy(badly_linted_fixed2, badly_linted_2).unwrap(); badly_linted_fixed2.copy(&badly_linted_2);
assert_contains!( assert_contains!(
wait_contains("Checked", &mut stderr_lines).await, wait_contains("Checked", &mut stderr_lines).await,
@ -349,17 +349,18 @@ async fn lint_all_files_on_each_change_test() {
drop(t); drop(t);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn fmt_watch_test() { async fn fmt_watch_test() {
let fmt_testdata_path = util::testdata_path().join("fmt"); let fmt_testdata_path = util::testdata_path().join("fmt");
let t = TempDir::new(); let t = TempDir::new();
let fixed = fmt_testdata_path.join("badly_formatted_fixed.js"); let fixed = fmt_testdata_path.join("badly_formatted_fixed.js");
let badly_formatted_original = fmt_testdata_path.join("badly_formatted.mjs"); let badly_formatted_original = fmt_testdata_path.join("badly_formatted.mjs");
let badly_formatted = t.path().join("badly_formatted.js"); let badly_formatted = t.path().join("badly_formatted.js");
std::fs::copy(&badly_formatted_original, &badly_formatted).unwrap(); badly_formatted_original.copy(&badly_formatted);
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(&fmt_testdata_path) .current_dir(t.path())
.arg("fmt") .arg("fmt")
.arg(&badly_formatted) .arg(&badly_formatted)
.arg("--watch") .arg("--watch")
@ -380,12 +381,12 @@ async fn fmt_watch_test() {
); );
wait_contains("Fmt finished", &mut stderr_lines).await; wait_contains("Fmt finished", &mut stderr_lines).await;
let expected = std::fs::read_to_string(fixed.clone()).unwrap(); let expected = fixed.read_to_string();
let actual = std::fs::read_to_string(badly_formatted.clone()).unwrap(); let actual = badly_formatted.read_to_string();
assert_eq!(actual, expected); assert_eq!(actual, expected);
// Change content of the file again to be badly formatted // Change content of the file again to be badly formatted
std::fs::copy(&badly_formatted_original, &badly_formatted).unwrap(); badly_formatted_original.copy(&badly_formatted);
assert_contains!( assert_contains!(
skip_restarting_line(&mut stderr_lines).await, skip_restarting_line(&mut stderr_lines).await,
@ -398,20 +399,21 @@ async fn fmt_watch_test() {
wait_contains("Fmt finished", &mut stderr_lines).await; wait_contains("Fmt finished", &mut stderr_lines).await;
// Check if file has been automatically formatted by watcher // Check if file has been automatically formatted by watcher
let expected = std::fs::read_to_string(fixed).unwrap(); let expected = fixed.read_to_string();
let actual = std::fs::read_to_string(badly_formatted).unwrap(); let actual = badly_formatted.read_to_string();
assert_eq!(actual, expected); assert_eq!(actual, expected);
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn fmt_watch_without_args_test() { async fn fmt_watch_without_args_test() {
let fmt_testdata_path = util::testdata_path().join("fmt"); let fmt_testdata_path = util::testdata_path().join("fmt");
let t = TempDir::new(); let t = TempDir::new();
let fixed = fmt_testdata_path.join("badly_formatted_fixed.js"); let fixed = fmt_testdata_path.join("badly_formatted_fixed.js");
let badly_formatted_original = fmt_testdata_path.join("badly_formatted.mjs"); let badly_formatted_original = fmt_testdata_path.join("badly_formatted.mjs");
let badly_formatted = t.path().join("badly_formatted.js"); let badly_formatted = t.path().join("badly_formatted.js");
std::fs::copy(&badly_formatted_original, &badly_formatted).unwrap(); badly_formatted_original.copy(&badly_formatted);
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(t.path()) .current_dir(t.path())
@ -432,13 +434,14 @@ async fn fmt_watch_without_args_test() {
wait_contains("Checked", &mut stderr_lines).await, wait_contains("Checked", &mut stderr_lines).await,
"Checked 1 file" "Checked 1 file"
); );
wait_contains("Fmt finished.", &mut stderr_lines).await;
let expected = std::fs::read_to_string(fixed.clone()).unwrap(); let expected = fixed.read_to_string();
let actual = std::fs::read_to_string(badly_formatted.clone()).unwrap(); let actual = badly_formatted.read_to_string();
assert_eq!(actual, expected); assert_eq!(actual, expected);
// Change content of the file again to be badly formatted // Change content of the file again to be badly formatted
std::fs::copy(&badly_formatted_original, &badly_formatted).unwrap(); badly_formatted_original.copy(&badly_formatted);
assert_contains!( assert_contains!(
skip_restarting_line(&mut stderr_lines).await, skip_restarting_line(&mut stderr_lines).await,
"badly_formatted.js" "badly_formatted.js"
@ -449,25 +452,25 @@ async fn fmt_watch_without_args_test() {
); );
// Check if file has been automatically formatted by watcher // Check if file has been automatically formatted by watcher
let expected = std::fs::read_to_string(fixed).unwrap(); let expected = fixed.read_to_string();
let actual = std::fs::read_to_string(badly_formatted).unwrap(); let actual = badly_formatted.read_to_string();
assert_eq!(actual, expected); assert_eq!(actual, expected);
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[ignore = "https://github.com/denoland/deno/issues/19629"] #[flaky_test]
#[tokio::test] #[tokio::main]
async fn fmt_check_all_files_on_each_change_test() { async fn fmt_check_all_files_on_each_change_test() {
let t = TempDir::new(); let t = TempDir::new();
let fmt_testdata_path = util::testdata_path().join("fmt"); let fmt_testdata_path = util::testdata_path().join("fmt");
let badly_formatted_original = fmt_testdata_path.join("badly_formatted.mjs"); let badly_formatted_original = fmt_testdata_path.join("badly_formatted.mjs");
let badly_formatted_1 = t.path().join("badly_formatted_1.js"); let badly_formatted_1 = t.path().join("badly_formatted_1.js");
let badly_formatted_2 = t.path().join("badly_formatted_2.js"); let badly_formatted_2 = t.path().join("badly_formatted_2.js");
std::fs::copy(&badly_formatted_original, &badly_formatted_1).unwrap(); badly_formatted_original.copy(&badly_formatted_1);
std::fs::copy(&badly_formatted_original, badly_formatted_2).unwrap(); badly_formatted_original.copy(&badly_formatted_2);
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(&fmt_testdata_path) .current_dir(t.path())
.arg("fmt") .arg("fmt")
.arg(t.path()) .arg(t.path())
.arg("--watch") .arg("--watch")
@ -484,7 +487,7 @@ async fn fmt_check_all_files_on_each_change_test() {
); );
// Change content of the file again to be badly formatted // Change content of the file again to be badly formatted
std::fs::copy(&badly_formatted_original, &badly_formatted_1).unwrap(); badly_formatted_original.copy(&badly_formatted_1);
assert_contains!( assert_contains!(
wait_contains("error", &mut stderr_lines).await, wait_contains("error", &mut stderr_lines).await,
@ -494,7 +497,8 @@ async fn fmt_check_all_files_on_each_change_test() {
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn bundle_js_watch() { async fn bundle_js_watch() {
use std::path::PathBuf; use std::path::PathBuf;
// Test strategy extends this of test bundle_js by adding watcher // Test strategy extends this of test bundle_js by adding watcher
@ -505,7 +509,7 @@ async fn bundle_js_watch() {
let t = TempDir::new(); let t = TempDir::new();
let bundle = t.path().join("mod6.bundle.js"); let bundle = t.path().join("mod6.bundle.js");
let mut deno = util::deno_cmd() let mut deno = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("bundle") .arg("bundle")
.arg(&file_to_watch) .arg(&file_to_watch)
.arg(&bundle) .arg(&bundle)
@ -568,7 +572,8 @@ async fn bundle_js_watch() {
} }
/// Confirm that the watcher continues to work even if module resolution fails at the *first* attempt /// Confirm that the watcher continues to work even if module resolution fails at the *first* attempt
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn bundle_watch_not_exit() { async fn bundle_watch_not_exit() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.ts"); let file_to_watch = t.path().join("file_to_watch.ts");
@ -576,7 +581,7 @@ async fn bundle_watch_not_exit() {
let target_file = t.path().join("target.js"); let target_file = t.path().join("target.js");
let mut deno = util::deno_cmd() let mut deno = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("bundle") .arg("bundle")
.arg(&file_to_watch) .arg(&file_to_watch)
.arg(&target_file) .arg(&target_file)
@ -631,14 +636,15 @@ async fn bundle_watch_not_exit() {
check_alive_then_kill(deno); check_alive_then_kill(deno);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_watch_no_dynamic() { async fn run_watch_no_dynamic() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.js"); let file_to_watch = t.path().join("file_to_watch.js");
file_to_watch.write("console.log('Hello world');"); file_to_watch.write("console.log('Hello world');");
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--watch") .arg("--watch")
.arg("--unstable") .arg("--unstable")
@ -713,7 +719,8 @@ async fn run_watch_no_dynamic() {
// if that's because of a bug in code or the runner itself. We should reenable // if that's because of a bug in code or the runner itself. We should reenable
// it once we upgrade to XL runners for macOS. // it once we upgrade to XL runners for macOS.
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_watch_external_watch_files() { async fn run_watch_external_watch_files() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.js"); let file_to_watch = t.path().join("file_to_watch.js");
@ -727,7 +734,7 @@ async fn run_watch_external_watch_files() {
watch_arg.push_str(&external_file_to_watch_str); watch_arg.push_str(&external_file_to_watch_str);
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg(watch_arg) .arg(watch_arg)
.arg("-L") .arg("-L")
@ -756,7 +763,8 @@ async fn run_watch_external_watch_files() {
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_watch_load_unload_events() { async fn run_watch_load_unload_events() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.js"); let file_to_watch = t.path().join("file_to_watch.js");
@ -774,7 +782,7 @@ async fn run_watch_load_unload_events() {
); );
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--watch") .arg("--watch")
.arg("--unstable") .arg("--unstable")
@ -819,14 +827,15 @@ async fn run_watch_load_unload_events() {
} }
/// Confirm that the watcher continues to work even if module resolution fails at the *first* attempt /// Confirm that the watcher continues to work even if module resolution fails at the *first* attempt
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_watch_not_exit() { async fn run_watch_not_exit() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.js"); let file_to_watch = t.path().join("file_to_watch.js");
file_to_watch.write("syntax error ^^"); file_to_watch.write("syntax error ^^");
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--watch") .arg("--watch")
.arg("--unstable") .arg("--unstable")
@ -852,7 +861,8 @@ async fn run_watch_not_exit() {
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_watch_with_import_map_and_relative_paths() { async fn run_watch_with_import_map_and_relative_paths() {
fn create_relative_tmp_file( fn create_relative_tmp_file(
directory: &TempDir, directory: &TempDir,
@ -905,14 +915,15 @@ async fn run_watch_with_import_map_and_relative_paths() {
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_watch_with_ext_flag() { async fn run_watch_with_ext_flag() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch"); let file_to_watch = t.path().join("file_to_watch");
file_to_watch.write("interface I{}; console.log(42);"); file_to_watch.write("interface I{}; console.log(42);");
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--watch") .arg("--watch")
.arg("--log-level") .arg("--log-level")
@ -941,7 +952,8 @@ async fn run_watch_with_ext_flag() {
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_watch_error_messages() { async fn run_watch_error_messages() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.js"); let file_to_watch = t.path().join("file_to_watch.js");
@ -949,7 +961,7 @@ async fn run_watch_error_messages() {
.write("throw SyntaxError(`outer`, {cause: TypeError(`inner`)})"); .write("throw SyntaxError(`outer`, {cause: TypeError(`inner`)})");
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--watch") .arg("--watch")
.arg(&file_to_watch) .arg(&file_to_watch)
@ -971,12 +983,13 @@ async fn run_watch_error_messages() {
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn test_watch_basic() { async fn test_watch_basic() {
let t = TempDir::new(); let t = TempDir::new();
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("test") .arg("test")
.arg("--watch") .arg("--watch")
.arg("--unstable") .arg("--unstable")
@ -1132,7 +1145,7 @@ async fn test_watch_doc() {
let t = TempDir::new(); let t = TempDir::new();
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("test") .arg("test")
.arg("--watch") .arg("--watch")
.arg("--doc") .arg("--doc")
@ -1175,13 +1188,14 @@ async fn test_watch_doc() {
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn test_watch_module_graph_error_referrer() { async fn test_watch_module_graph_error_referrer() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.js"); let file_to_watch = t.path().join("file_to_watch.js");
file_to_watch.write("import './nonexistent.js';"); file_to_watch.write("import './nonexistent.js';");
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--watch") .arg("--watch")
.arg(&file_to_watch) .arg(&file_to_watch)
@ -1203,7 +1217,8 @@ async fn test_watch_module_graph_error_referrer() {
} }
// Regression test for https://github.com/denoland/deno/issues/15428. // Regression test for https://github.com/denoland/deno/issues/15428.
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn test_watch_unload_handler_error_on_drop() { async fn test_watch_unload_handler_error_on_drop() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.js"); let file_to_watch = t.path().join("file_to_watch.js");
@ -1218,7 +1233,7 @@ async fn test_watch_unload_handler_error_on_drop() {
"#, "#,
); );
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--watch") .arg("--watch")
.arg(&file_to_watch) .arg(&file_to_watch)
@ -1233,7 +1248,8 @@ async fn test_watch_unload_handler_error_on_drop() {
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_watch_blob_urls_reset() { async fn run_watch_blob_urls_reset() {
let _g = util::http_server(); let _g = util::http_server();
let t = TempDir::new(); let t = TempDir::new();
@ -1255,7 +1271,7 @@ async fn run_watch_blob_urls_reset() {
"#; "#;
file_to_watch.write(file_content); file_to_watch.write(file_content);
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--watch") .arg("--watch")
.arg(&file_to_watch) .arg(&file_to_watch)
@ -1274,7 +1290,8 @@ async fn run_watch_blob_urls_reset() {
} }
#[cfg(unix)] #[cfg(unix)]
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn test_watch_sigint() { async fn test_watch_sigint() {
use nix::sys::signal; use nix::sys::signal;
use nix::sys::signal::Signal; use nix::sys::signal::Signal;
@ -1299,12 +1316,13 @@ async fn test_watch_sigint() {
assert_eq!(exit_status.code(), Some(130)); assert_eq!(exit_status.code(), Some(130));
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn bench_watch_basic() { async fn bench_watch_basic() {
let t = TempDir::new(); let t = TempDir::new();
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("bench") .arg("bench")
.arg("--watch") .arg("--watch")
.arg("--no-check") .arg("--no-check")
@ -1412,7 +1430,8 @@ async fn bench_watch_basic() {
} }
// Regression test for https://github.com/denoland/deno/issues/15465. // Regression test for https://github.com/denoland/deno/issues/15465.
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_watch_reload_once() { async fn run_watch_reload_once() {
let _g = util::http_server(); let _g = util::http_server();
let t = TempDir::new(); let t = TempDir::new();
@ -1424,7 +1443,7 @@ async fn run_watch_reload_once() {
file_to_watch.write(file_content); file_to_watch.write(file_content);
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--watch") .arg("--watch")
.arg("--reload") .arg("--reload")
@ -1450,7 +1469,8 @@ async fn run_watch_reload_once() {
/// Regression test for https://github.com/denoland/deno/issues/18960. Ensures that Deno.serve /// Regression test for https://github.com/denoland/deno/issues/18960. Ensures that Deno.serve
/// operates properly after a watch restart. /// operates properly after a watch restart.
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn test_watch_serve() { async fn test_watch_serve() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.js"); let file_to_watch = t.path().join("file_to_watch.js");
@ -1461,7 +1481,7 @@ async fn test_watch_serve() {
file_to_watch.write(file_content); file_to_watch.write(file_content);
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--watch") .arg("--watch")
.arg("--allow-net") .arg("--allow-net")
@ -1486,7 +1506,8 @@ async fn test_watch_serve() {
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_watch_dynamic_imports() { async fn run_watch_dynamic_imports() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.js"); let file_to_watch = t.path().join("file_to_watch.js");
@ -1511,7 +1532,7 @@ async fn run_watch_dynamic_imports() {
); );
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--watch") .arg("--watch")
.arg("--unstable") .arg("--unstable")
@ -1572,7 +1593,8 @@ async fn run_watch_dynamic_imports() {
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_watch_inspect() { async fn run_watch_inspect() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.js"); let file_to_watch = t.path().join("file_to_watch.js");
@ -1583,7 +1605,7 @@ async fn run_watch_inspect() {
); );
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--watch") .arg("--watch")
.arg("--inspect") .arg("--inspect")
@ -1613,7 +1635,8 @@ async fn run_watch_inspect() {
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_watch_with_excluded_paths() { async fn run_watch_with_excluded_paths() {
let t = TempDir::new(); let t = TempDir::new();
@ -1628,7 +1651,7 @@ async fn run_watch_with_excluded_paths() {
mjs_file_to_exclude.write("export const foo = 0;"); mjs_file_to_exclude.write("export const foo = 0;");
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--watch") .arg("--watch")
.arg("--watch-exclude=file_to_exclude.js,*.mjs") .arg("--watch-exclude=file_to_exclude.js,*.mjs")
@ -1652,7 +1675,8 @@ async fn run_watch_with_excluded_paths() {
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_hmr_server() { async fn run_hmr_server() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.js"); let file_to_watch = t.path().join("file_to_watch.js");
@ -1676,7 +1700,7 @@ console.log("Listening...")
); );
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--unstable-hmr") .arg("--unstable-hmr")
.arg("--allow-net") .arg("--allow-net")
@ -1719,7 +1743,8 @@ console.log("Listening...")
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_hmr_jsx() { async fn run_hmr_jsx() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.js"); let file_to_watch = t.path().join("file_to_watch.js");
@ -1743,7 +1768,7 @@ export function foo() {
); );
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--unstable-hmr") .arg("--unstable-hmr")
.arg("-L") .arg("-L")
@ -1774,7 +1799,8 @@ export function foo() {
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_hmr_uncaught_error() { async fn run_hmr_uncaught_error() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.js"); let file_to_watch = t.path().join("file_to_watch.js");
@ -1801,7 +1827,7 @@ export function foo() {
); );
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--unstable-hmr") .arg("--unstable-hmr")
.arg("-L") .arg("-L")
@ -1834,7 +1860,8 @@ export function foo() {
check_alive_then_kill(child); check_alive_then_kill(child);
} }
#[tokio::test] #[flaky_test]
#[tokio::main]
async fn run_hmr_unhandled_rejection() { async fn run_hmr_unhandled_rejection() {
let t = TempDir::new(); let t = TempDir::new();
let file_to_watch = t.path().join("file_to_watch.js"); let file_to_watch = t.path().join("file_to_watch.js");
@ -1866,7 +1893,7 @@ export function foo() {
); );
let mut child = util::deno_cmd() let mut child = util::deno_cmd()
.current_dir(util::testdata_path()) .current_dir(t.path())
.arg("run") .arg("run")
.arg("--unstable-hmr") .arg("--unstable-hmr")
.arg("-L") .arg("-L")

View file

@ -150,24 +150,29 @@ impl PathRef {
.unwrap_or_else(|| panic!("JSON file was empty for {}", self)) .unwrap_or_else(|| panic!("JSON file was empty for {}", self))
} }
#[track_caller]
pub fn rename(&self, to: impl AsRef<Path>) { pub fn rename(&self, to: impl AsRef<Path>) {
fs::rename(self, self.join(to)).unwrap(); fs::rename(self, self.join(to)).unwrap();
} }
#[track_caller]
pub fn append(&self, text: impl AsRef<str>) { pub fn append(&self, text: impl AsRef<str>) {
let mut file = OpenOptions::new().append(true).open(self).unwrap(); let mut file = OpenOptions::new().append(true).open(self).unwrap();
file.write_all(text.as_ref().as_bytes()).unwrap(); file.write_all(text.as_ref().as_bytes()).unwrap();
} }
#[track_caller]
pub fn write(&self, text: impl AsRef<[u8]>) { pub fn write(&self, text: impl AsRef<[u8]>) {
fs::write(self, text).unwrap(); fs::write(self, text).unwrap();
} }
#[track_caller]
pub fn write_json<TValue: Serialize>(&self, value: &TValue) { pub fn write_json<TValue: Serialize>(&self, value: &TValue) {
let text = serde_json::to_string_pretty(value).unwrap(); let text = serde_json::to_string_pretty(value).unwrap();
self.write(text); self.write(text);
} }
#[track_caller]
pub fn symlink_dir( pub fn symlink_dir(
&self, &self,
oldpath: impl AsRef<Path>, oldpath: impl AsRef<Path>,
@ -187,6 +192,7 @@ impl PathRef {
} }
} }
#[track_caller]
pub fn symlink_file( pub fn symlink_file(
&self, &self,
oldpath: impl AsRef<Path>, oldpath: impl AsRef<Path>,
@ -206,12 +212,14 @@ impl PathRef {
} }
} }
#[track_caller]
pub fn read_dir(&self) -> fs::ReadDir { pub fn read_dir(&self) -> fs::ReadDir {
fs::read_dir(self.as_path()) fs::read_dir(self.as_path())
.with_context(|| format!("Reading {}", self.as_path().display())) .with_context(|| format!("Reading {}", self.as_path().display()))
.unwrap() .unwrap()
} }
#[track_caller]
pub fn copy(&self, to: &impl AsRef<Path>) { pub fn copy(&self, to: &impl AsRef<Path>) {
std::fs::copy(self.as_path(), to) std::fs::copy(self.as_path(), to)
.with_context(|| format!("Copying {} to {}", self, to.as_ref().display())) .with_context(|| format!("Copying {} to {}", self, to.as_ref().display()))
@ -247,6 +255,7 @@ impl PathRef {
} }
} }
#[track_caller]
pub fn make_dir_readonly(&self) { pub fn make_dir_readonly(&self) {
self.create_dir_all(); self.create_dir_all();
if cfg!(windows) { if cfg!(windows) {

View file

@ -1,14 +1,5 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// Usage: provide a port as argument to run hyper_hello benchmark server
// otherwise this starts multiple servers on many ports for test endpoints.
use futures::FutureExt;
use futures::Stream;
use futures::StreamExt;
use once_cell::sync::Lazy;
use pretty_assertions::assert_eq;
use pty::Pty;
use regex::Regex;
use serde::Serialize;
use std::collections::HashMap; use std::collections::HashMap;
use std::env; use std::env;
use std::io::Write; use std::io::Write;
@ -18,8 +9,17 @@ use std::process::Command;
use std::process::Output; use std::process::Output;
use std::process::Stdio; use std::process::Stdio;
use std::result::Result; use std::result::Result;
use std::sync::Mutex;
use std::sync::MutexGuard; use futures::FutureExt;
use futures::Stream;
use futures::StreamExt;
use once_cell::sync::Lazy;
use parking_lot::Mutex;
use parking_lot::MutexGuard;
use pretty_assertions::assert_eq;
use pty::Pty;
use regex::Regex;
use serde::Serialize;
use tokio::net::TcpStream; use tokio::net::TcpStream;
use url::Url; use url::Url;
@ -47,8 +47,7 @@ pub const PERMISSION_VARIANTS: [&str; 5] =
["read", "write", "env", "net", "run"]; ["read", "write", "env", "net", "run"];
pub const PERMISSION_DENIED_PATTERN: &str = "PermissionDenied"; pub const PERMISSION_DENIED_PATTERN: &str = "PermissionDenied";
static GUARD: Lazy<Mutex<HttpServerCount>> = static GUARD: Lazy<Mutex<HttpServerCount>> = Lazy::new(Default::default);
Lazy::new(|| Mutex::new(HttpServerCount::default()));
pub fn env_vars_for_npm_tests() -> Vec<(String, String)> { pub fn env_vars_for_npm_tests() -> Vec<(String, String)> {
vec![ vec![
@ -308,41 +307,14 @@ async fn get_tcp_listener_stream(
#[derive(Default)] #[derive(Default)]
struct HttpServerCount { struct HttpServerCount {
count: usize, count: usize,
test_server: Option<Child>, test_server: Option<HttpServerStarter>,
} }
impl HttpServerCount { impl HttpServerCount {
fn inc(&mut self) { fn inc(&mut self) {
self.count += 1; self.count += 1;
if self.test_server.is_none() { if self.test_server.is_none() {
assert_eq!(self.count, 1); self.test_server = Some(Default::default());
println!("test_server starting...");
let mut test_server = Command::new(test_server_path())
.current_dir(testdata_path())
.stdout(Stdio::piped())
.spawn()
.expect("failed to execute test_server");
let stdout = test_server.stdout.as_mut().unwrap();
use std::io::BufRead;
use std::io::BufReader;
let lines = BufReader::new(stdout).lines();
// Wait for all the servers to report being ready.
let mut ready_count = 0;
for maybe_line in lines {
if let Ok(line) = maybe_line {
if line.starts_with("ready:") {
ready_count += 1;
}
if ready_count == 12 {
break;
}
} else {
panic!("{}", maybe_line.unwrap_err());
}
}
self.test_server = Some(test_server);
} }
} }
@ -350,17 +322,7 @@ impl HttpServerCount {
assert!(self.count > 0); assert!(self.count > 0);
self.count -= 1; self.count -= 1;
if self.count == 0 { if self.count == 0 {
let mut test_server = self.test_server.take().unwrap(); self.test_server.take();
match test_server.try_wait() {
Ok(None) => {
test_server.kill().expect("failed to kill test_server");
let _ = test_server.wait();
}
Ok(Some(status)) => {
panic!("test_server exited unexpectedly {status}")
}
Err(e) => panic!("test_server error: {e}"),
}
} }
} }
} }
@ -372,16 +334,60 @@ impl Drop for HttpServerCount {
} }
} }
fn lock_http_server<'a>() -> MutexGuard<'a, HttpServerCount> { struct HttpServerStarter {
let r = GUARD.lock(); test_server: Child,
if let Err(poison_err) = r { }
// If panics happened, ignore it. This is for tests.
poison_err.into_inner() impl Default for HttpServerStarter {
} else { fn default() -> Self {
r.unwrap() println!("test_server starting...");
let mut test_server = Command::new(test_server_path())
.current_dir(testdata_path())
.stdout(Stdio::piped())
.spawn()
.expect("failed to execute test_server");
let stdout = test_server.stdout.as_mut().unwrap();
use std::io::BufRead;
use std::io::BufReader;
let lines = BufReader::new(stdout).lines();
// Wait for all the servers to report being ready.
let mut ready_count = 0;
for maybe_line in lines {
if let Ok(line) = maybe_line {
if line.starts_with("ready:") {
ready_count += 1;
}
if ready_count == 12 {
break;
}
} else {
panic!("{}", maybe_line.unwrap_err());
}
}
Self { test_server }
} }
} }
impl Drop for HttpServerStarter {
fn drop(&mut self) {
match self.test_server.try_wait() {
Ok(None) => {
self.test_server.kill().expect("failed to kill test_server");
let _ = self.test_server.wait();
}
Ok(Some(status)) => {
panic!("test_server exited unexpectedly {status}")
}
Err(e) => panic!("test_server error: {e}"),
}
}
}
fn lock_http_server<'a>() -> MutexGuard<'a, HttpServerCount> {
GUARD.lock()
}
pub struct HttpServerGuard {} pub struct HttpServerGuard {}
impl Drop for HttpServerGuard { impl Drop for HttpServerGuard {