editor tests: Reintroduce block_on_ticks.

Co-authored-by: Antonio <antonio@zed.dev>
This commit is contained in:
Piotr Osiewicz 2023-12-01 17:22:12 +01:00
parent a40a5fb212
commit e0ccaa60ff
3 changed files with 353 additions and 313 deletions

View file

@ -128,11 +128,19 @@ impl BackgroundExecutor {
#[cfg(any(test, feature = "test-support"))]
#[track_caller]
pub fn block_test<R>(&self, future: impl Future<Output = R>) -> R {
self.block_internal(false, future)
if let Ok(value) = self.block_internal(false, future, usize::MAX) {
value
} else {
unreachable!()
}
}
pub fn block<R>(&self, future: impl Future<Output = R>) -> R {
self.block_internal(true, future)
if let Ok(value) = self.block_internal(true, future, usize::MAX) {
value
} else {
unreachable!()
}
}
#[track_caller]
@ -140,7 +148,8 @@ impl BackgroundExecutor {
&self,
background_only: bool,
future: impl Future<Output = R>,
) -> R {
mut max_ticks: usize,
) -> Result<R, ()> {
pin_mut!(future);
let unparker = self.dispatcher.unparker();
let awoken = Arc::new(AtomicBool::new(false));
@ -156,8 +165,13 @@ impl BackgroundExecutor {
loop {
match future.as_mut().poll(&mut cx) {
Poll::Ready(result) => return result,
Poll::Ready(result) => return Ok(result),
Poll::Pending => {
if max_ticks == 0 {
return Err(());
}
max_ticks -= 1;
if !self.dispatcher.tick(background_only) {
if awoken.swap(false, SeqCst) {
continue;
@ -192,16 +206,24 @@ impl BackgroundExecutor {
return Err(future);
}
let max_ticks = if cfg!(any(test, feature = "test-support")) {
self.dispatcher
.as_test()
.map_or(usize::MAX, |dispatcher| dispatcher.gen_block_on_ticks())
} else {
usize::MAX
};
let mut timer = self.timer(duration).fuse();
let timeout = async {
futures::select_biased! {
value = future => Ok(value),
_ = timer => Err(()),
}
};
match self.block(timeout) {
Ok(value) => Ok(value),
Err(_) => Err(future),
match self.block_internal(true, timeout, max_ticks) {
Ok(Ok(value)) => Ok(value),
_ => Err(future),
}
}
@ -281,6 +303,11 @@ impl BackgroundExecutor {
pub fn is_main_thread(&self) -> bool {
self.dispatcher.is_main_thread()
}
#[cfg(any(test, feature = "test-support"))]
pub fn set_block_on_ticks(&self, range: std::ops::RangeInclusive<usize>) {
self.dispatcher.as_test().unwrap().set_block_on_ticks(range);
}
}
impl ForegroundExecutor {

View file

@ -7,6 +7,7 @@ use parking_lot::Mutex;
use rand::prelude::*;
use std::{
future::Future,
ops::RangeInclusive,
pin::Pin,
sync::Arc,
task::{Context, Poll},
@ -36,6 +37,7 @@ struct TestDispatcherState {
allow_parking: bool,
waiting_backtrace: Option<Backtrace>,
deprioritized_task_labels: HashSet<TaskLabel>,
block_on_ticks: RangeInclusive<usize>,
}
impl TestDispatcher {
@ -53,6 +55,7 @@ impl TestDispatcher {
allow_parking: false,
waiting_backtrace: None,
deprioritized_task_labels: Default::default(),
block_on_ticks: 0..=1000,
};
TestDispatcher {
@ -82,8 +85,8 @@ impl TestDispatcher {
}
pub fn simulate_random_delay(&self) -> impl 'static + Send + Future<Output = ()> {
pub struct YieldNow {
count: usize,
struct YieldNow {
pub(crate) count: usize,
}
impl Future for YieldNow {
@ -142,6 +145,16 @@ impl TestDispatcher {
pub fn rng(&self) -> StdRng {
self.state.lock().random.clone()
}
pub fn set_block_on_ticks(&self, range: std::ops::RangeInclusive<usize>) {
self.state.lock().block_on_ticks = range;
}
pub fn gen_block_on_ticks(&self) -> usize {
let mut lock = self.state.lock();
let block_on_ticks = lock.block_on_ticks.clone();
lock.random.gen_range(block_on_ticks)
}
}
impl Clone for TestDispatcher {