mirror of
https://github.com/denoland/deno.git
synced 2024-12-19 13:54:54 -05:00
b6e44f91ad
Some `deno_std` tests were failing to print output that was resolved after the last test finished. In addition, output printed before tests began would sometimes appear above the "running X tests ..." line, and sometimes below it depending on timing. We now guarantee that all output is flushed before and after tests run, making the output consistent. Pre-test and post-test output are captured in `------ pre-test output ------` and `------ post-test output ------` blocks to differentiate them from the regular output blocks. Here's an example of a test (that is much noisier than normal, but an example of what the output will look like): ``` Check ./load_unload.ts ------- pre-test output ------- load ----- output end ----- running 1 test from ./load_unload.ts test ... ------- output ------- test ----- output end ----- test ... ok ([WILDCARD]) ------- post-test output ------- unload ----- output end ----- ```
129 lines
3.2 KiB
Rust
129 lines
3.2 KiB
Rust
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
|
|
|
#[macro_export]
|
|
// https://stackoverflow.com/questions/38088067/equivalent-of-func-or-function-in-rust
|
|
macro_rules! function {
|
|
() => {{
|
|
fn f() {}
|
|
fn type_name_of<T>(_: T) -> &'static str {
|
|
::std::any::type_name::<T>()
|
|
}
|
|
let name = type_name_of(f);
|
|
let name = name.strip_suffix("::f").unwrap_or(name);
|
|
let name = name.strip_suffix("::{{closure}}").unwrap_or(name);
|
|
name
|
|
}};
|
|
}
|
|
|
|
/// Detect a test timeout and panic with a message that includes the test name.
|
|
/// By default, the test timeout is 300 seconds (5 minutes), but any value may
|
|
/// be specified as an argument to this function.
|
|
#[macro_export]
|
|
macro_rules! timeout {
|
|
( $($timeout:literal)? ) => {
|
|
struct TestTimeoutHolder(::std::sync::mpsc::Sender<()>);
|
|
|
|
let _test_timeout_holder = {
|
|
let function = $crate::function!();
|
|
let (tx, rx) = ::std::sync::mpsc::channel::<()>();
|
|
let timeout: &[u64] = &[$($timeout)?];
|
|
let timeout = *timeout.get(0).unwrap_or(&300);
|
|
::std::thread::spawn(move || {
|
|
if rx.recv_timeout(::std::time::Duration::from_secs(timeout)) == Err(::std::sync::mpsc::RecvTimeoutError::Timeout) {
|
|
use std::io::Write;
|
|
eprintln!("Test {function} timed out after {timeout} seconds, aborting");
|
|
_ = std::io::stderr().flush();
|
|
::std::process::exit(1);
|
|
}
|
|
});
|
|
TestTimeoutHolder(tx)
|
|
};
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! itest(
|
|
($name:ident {$( $key:ident: $value:expr,)*}) => {
|
|
#[test]
|
|
fn $name() {
|
|
$crate::timeout!();
|
|
let test = $crate::CheckOutputIntegrationTest {
|
|
$(
|
|
$key: $value,
|
|
)*
|
|
.. Default::default()
|
|
};
|
|
let output = test.output();
|
|
output.assert_exit_code(test.exit_code);
|
|
if !test.output.is_empty() {
|
|
assert!(test.output_str.is_none());
|
|
output.assert_matches_file(test.output);
|
|
} else {
|
|
output.assert_matches_text(test.output_str.unwrap_or(""));
|
|
}
|
|
}
|
|
}
|
|
);
|
|
|
|
#[macro_export]
|
|
macro_rules! itest_flaky(
|
|
($name:ident {$( $key:ident: $value:expr,)*}) => {
|
|
#[flaky_test::flaky_test]
|
|
fn $name() {
|
|
$crate::timeout!();
|
|
let test = $crate::CheckOutputIntegrationTest {
|
|
$(
|
|
$key: $value,
|
|
)*
|
|
.. Default::default()
|
|
};
|
|
let output = test.output();
|
|
output.assert_exit_code(test.exit_code);
|
|
if !test.output.is_empty() {
|
|
assert!(test.output_str.is_none());
|
|
output.assert_matches_file(test.output);
|
|
} else {
|
|
output.assert_matches_text(test.output_str.unwrap_or(""));
|
|
}
|
|
}
|
|
}
|
|
);
|
|
|
|
#[macro_export]
|
|
macro_rules! context(
|
|
({$( $key:ident: $value:expr,)*}) => {
|
|
$crate::TestContext::create($crate::TestContextOptions {
|
|
$(
|
|
$key: $value,
|
|
)*
|
|
.. Default::default()
|
|
})
|
|
}
|
|
);
|
|
|
|
#[macro_export]
|
|
macro_rules! itest_steps(
|
|
($name:ident {$( $key:ident: $value:expr,)*}) => {
|
|
#[test]
|
|
fn $name() {
|
|
($crate::CheckOutputIntegrationTestSteps {
|
|
$(
|
|
$key: $value,
|
|
)*
|
|
.. Default::default()
|
|
}).run()
|
|
}
|
|
}
|
|
);
|
|
|
|
#[macro_export]
|
|
macro_rules! command_step(
|
|
({$( $key:ident: $value:expr,)*}) => {
|
|
$crate::CheckOutputIntegrationTestCommandStep {
|
|
$(
|
|
$key: $value,
|
|
)*
|
|
.. Default::default()
|
|
}
|
|
}
|
|
);
|