55 lines
1.7 KiB
Rust
55 lines
1.7 KiB
Rust
#![warn(rust_2018_idioms)]
|
|
#![cfg(all(feature = "time", not(target_os = "wasi")))] // Wasi does not support panic recovery
|
|
|
|
use parking_lot::{const_mutex, Mutex};
|
|
use std::error::Error;
|
|
use std::panic;
|
|
use std::sync::Arc;
|
|
use tokio::time::Duration;
|
|
use tokio_stream::{self as stream, StreamExt};
|
|
|
|
fn test_panic<Func: FnOnce() + panic::UnwindSafe>(func: Func) -> Option<String> {
|
|
static PANIC_MUTEX: Mutex<()> = const_mutex(());
|
|
|
|
{
|
|
let _guard = PANIC_MUTEX.lock();
|
|
let panic_file: Arc<Mutex<Option<String>>> = Arc::new(Mutex::new(None));
|
|
|
|
let prev_hook = panic::take_hook();
|
|
{
|
|
let panic_file = panic_file.clone();
|
|
panic::set_hook(Box::new(move |panic_info| {
|
|
let panic_location = panic_info.location().unwrap();
|
|
panic_file
|
|
.lock()
|
|
.clone_from(&Some(panic_location.file().to_string()));
|
|
}));
|
|
}
|
|
|
|
let result = panic::catch_unwind(func);
|
|
// Return to the previously set panic hook (maybe default) so that we get nice error
|
|
// messages in the tests.
|
|
panic::set_hook(prev_hook);
|
|
|
|
if result.is_err() {
|
|
panic_file.lock().clone()
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn stream_chunks_timeout_panic_caller() -> Result<(), Box<dyn Error>> {
|
|
let panic_location_file = test_panic(|| {
|
|
let iter = vec![1, 2, 3].into_iter();
|
|
let stream0 = stream::iter(iter);
|
|
|
|
let _chunk_stream = stream0.chunks_timeout(0, Duration::from_secs(2));
|
|
});
|
|
|
|
// The panic location should be in this file
|
|
assert_eq!(&panic_location_file.unwrap(), file!());
|
|
|
|
Ok(())
|
|
}
|