Revert "editor tests: Reintroduce block_on_ticks."

This reverts commit aed11ee8cb.
This commit is contained in:
Piotr Osiewicz 2023-12-01 17:24:20 +01:00
parent aed11ee8cb
commit a40a5fb212
3 changed files with 313 additions and 353 deletions

View file

@ -1026,337 +1026,337 @@ fn consolidate_wrap_edits(edits: &mut Vec<WrapEdit>) {
} }
} }
#[cfg(test)] // #[cfg(test)]
mod tests { // mod tests {
use super::*; // use super::*;
use crate::{ // use crate::{
display_map::{fold_map::FoldMap, inlay_map::InlayMap, tab_map::TabMap}, // display_map::{fold_map::FoldMap, inlay_map::InlayMap, tab_map::TabMap},
MultiBuffer, // MultiBuffer,
}; // };
use gpui::test::observe; // use gpui::test::observe;
use rand::prelude::*; // use rand::prelude::*;
use settings::SettingsStore; // use settings::SettingsStore;
use smol::stream::StreamExt; // use smol::stream::StreamExt;
use std::{cmp, env, num::NonZeroU32}; // use std::{cmp, env, num::NonZeroU32};
use text::Rope; // use text::Rope;
#[gpui::test(iterations = 100)] // #[gpui::test(iterations = 100)]
async fn test_random_wraps(cx: &mut gpui::TestAppContext, mut rng: StdRng) { // async fn test_random_wraps(cx: &mut gpui::TestAppContext, mut rng: StdRng) {
init_test(cx); // init_test(cx);
cx.background_executor.set_block_on_ticks(0..=50); // cx.foreground().set_block_on_ticks(0..=50);
let operations = env::var("OPERATIONS") // let operations = env::var("OPERATIONS")
.map(|i| i.parse().expect("invalid `OPERATIONS` variable")) // .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
.unwrap_or(10); // .unwrap_or(10);
let font_cache = cx.read(|cx| cx.font_cache().clone()); // let font_cache = cx.font_cache().clone();
let font_system = cx.platform().fonts(); // let font_system = cx.platform().fonts();
let mut wrap_width = if rng.gen_bool(0.1) { // let mut wrap_width = if rng.gen_bool(0.1) {
None // None
} else { // } else {
Some(rng.gen_range(0.0..=1000.0)) // Some(rng.gen_range(0.0..=1000.0))
}; // };
let tab_size = NonZeroU32::new(rng.gen_range(1..=4)).unwrap(); // let tab_size = NonZeroU32::new(rng.gen_range(1..=4)).unwrap();
let family_id = font_cache // let family_id = font_cache
.load_family(&["Helvetica"], &Default::default()) // .load_family(&["Helvetica"], &Default::default())
.unwrap(); // .unwrap();
let font_id = font_cache // let font_id = font_cache
.select_font(family_id, &Default::default()) // .select_font(family_id, &Default::default())
.unwrap(); // .unwrap();
let font_size = 14.0; // let font_size = 14.0;
log::info!("Tab size: {}", tab_size); // log::info!("Tab size: {}", tab_size);
log::info!("Wrap width: {:?}", wrap_width); // log::info!("Wrap width: {:?}", wrap_width);
let buffer = cx.update(|cx| { // let buffer = cx.update(|cx| {
if rng.gen() { // if rng.gen() {
MultiBuffer::build_random(&mut rng, cx) // MultiBuffer::build_random(&mut rng, cx)
} else { // } else {
let len = rng.gen_range(0..10); // let len = rng.gen_range(0..10);
let text = util::RandomCharIter::new(&mut rng) // let text = util::RandomCharIter::new(&mut rng)
.take(len) // .take(len)
.collect::<String>(); // .collect::<String>();
MultiBuffer::build_simple(&text, cx) // MultiBuffer::build_simple(&text, cx)
} // }
}); // });
let mut buffer_snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx)); // let mut buffer_snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx));
log::info!("Buffer text: {:?}", buffer_snapshot.text()); // log::info!("Buffer text: {:?}", buffer_snapshot.text());
let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone()); // let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
log::info!("InlayMap text: {:?}", inlay_snapshot.text()); // log::info!("InlayMap text: {:?}", inlay_snapshot.text());
let (mut fold_map, fold_snapshot) = FoldMap::new(inlay_snapshot.clone()); // let (mut fold_map, fold_snapshot) = FoldMap::new(inlay_snapshot.clone());
log::info!("FoldMap text: {:?}", fold_snapshot.text()); // log::info!("FoldMap text: {:?}", fold_snapshot.text());
let (mut tab_map, _) = TabMap::new(fold_snapshot.clone(), tab_size); // let (mut tab_map, _) = TabMap::new(fold_snapshot.clone(), tab_size);
let tabs_snapshot = tab_map.set_max_expansion_column(32); // let tabs_snapshot = tab_map.set_max_expansion_column(32);
log::info!("TabMap text: {:?}", tabs_snapshot.text()); // log::info!("TabMap text: {:?}", tabs_snapshot.text());
let mut line_wrapper = LineWrapper::new(font_id, font_size, font_system); // let mut line_wrapper = LineWrapper::new(font_id, font_size, font_system);
let unwrapped_text = tabs_snapshot.text(); // let unwrapped_text = tabs_snapshot.text();
let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper); // let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper);
let (wrap_map, _) = // let (wrap_map, _) =
cx.update(|cx| WrapMap::new(tabs_snapshot.clone(), font_id, font_size, wrap_width, cx)); // cx.update(|cx| WrapMap::new(tabs_snapshot.clone(), font_id, font_size, wrap_width, cx));
let mut notifications = observe(&wrap_map, cx); // let mut notifications = observe(&wrap_map, cx);
if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { // if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
notifications.next().await.unwrap(); // notifications.next().await.unwrap();
} // }
let (initial_snapshot, _) = wrap_map.update(cx, |map, cx| { // let (initial_snapshot, _) = wrap_map.update(cx, |map, cx| {
assert!(!map.is_rewrapping()); // assert!(!map.is_rewrapping());
map.sync(tabs_snapshot.clone(), Vec::new(), cx) // map.sync(tabs_snapshot.clone(), Vec::new(), cx)
}); // });
let actual_text = initial_snapshot.text(); // let actual_text = initial_snapshot.text();
assert_eq!( // assert_eq!(
actual_text, expected_text, // actual_text, expected_text,
"unwrapped text is: {:?}", // "unwrapped text is: {:?}",
unwrapped_text // unwrapped_text
); // );
log::info!("Wrapped text: {:?}", actual_text); // log::info!("Wrapped text: {:?}", actual_text);
let mut next_inlay_id = 0; // let mut next_inlay_id = 0;
let mut edits = Vec::new(); // let mut edits = Vec::new();
for _i in 0..operations { // for _i in 0..operations {
log::info!("{} ==============================================", _i); // log::info!("{} ==============================================", _i);
let mut buffer_edits = Vec::new(); // let mut buffer_edits = Vec::new();
match rng.gen_range(0..=100) { // match rng.gen_range(0..=100) {
0..=19 => { // 0..=19 => {
wrap_width = if rng.gen_bool(0.2) { // wrap_width = if rng.gen_bool(0.2) {
None // None
} else { // } else {
Some(rng.gen_range(0.0..=1000.0)) // Some(rng.gen_range(0.0..=1000.0))
}; // };
log::info!("Setting wrap width to {:?}", wrap_width); // log::info!("Setting wrap width to {:?}", wrap_width);
wrap_map.update(cx, |map, cx| map.set_wrap_width(wrap_width, cx)); // wrap_map.update(cx, |map, cx| map.set_wrap_width(wrap_width, cx));
} // }
20..=39 => { // 20..=39 => {
for (fold_snapshot, fold_edits) in fold_map.randomly_mutate(&mut rng) { // for (fold_snapshot, fold_edits) in fold_map.randomly_mutate(&mut rng) {
let (tabs_snapshot, tab_edits) = // let (tabs_snapshot, tab_edits) =
tab_map.sync(fold_snapshot, fold_edits, tab_size); // tab_map.sync(fold_snapshot, fold_edits, tab_size);
let (mut snapshot, wrap_edits) = // let (mut snapshot, wrap_edits) =
wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx)); // wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx));
snapshot.check_invariants(); // snapshot.check_invariants();
snapshot.verify_chunks(&mut rng); // snapshot.verify_chunks(&mut rng);
edits.push((snapshot, wrap_edits)); // edits.push((snapshot, wrap_edits));
} // }
} // }
40..=59 => { // 40..=59 => {
let (inlay_snapshot, inlay_edits) = // let (inlay_snapshot, inlay_edits) =
inlay_map.randomly_mutate(&mut next_inlay_id, &mut rng); // inlay_map.randomly_mutate(&mut next_inlay_id, &mut rng);
let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits); // let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits);
let (tabs_snapshot, tab_edits) = // let (tabs_snapshot, tab_edits) =
tab_map.sync(fold_snapshot, fold_edits, tab_size); // tab_map.sync(fold_snapshot, fold_edits, tab_size);
let (mut snapshot, wrap_edits) = // let (mut snapshot, wrap_edits) =
wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx)); // wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx));
snapshot.check_invariants(); // snapshot.check_invariants();
snapshot.verify_chunks(&mut rng); // snapshot.verify_chunks(&mut rng);
edits.push((snapshot, wrap_edits)); // edits.push((snapshot, wrap_edits));
} // }
_ => { // _ => {
buffer.update(cx, |buffer, cx| { // buffer.update(cx, |buffer, cx| {
let subscription = buffer.subscribe(); // let subscription = buffer.subscribe();
let edit_count = rng.gen_range(1..=5); // let edit_count = rng.gen_range(1..=5);
buffer.randomly_mutate(&mut rng, edit_count, cx); // buffer.randomly_mutate(&mut rng, edit_count, cx);
buffer_snapshot = buffer.snapshot(cx); // buffer_snapshot = buffer.snapshot(cx);
buffer_edits.extend(subscription.consume()); // buffer_edits.extend(subscription.consume());
}); // });
} // }
} // }
log::info!("Buffer text: {:?}", buffer_snapshot.text()); // log::info!("Buffer text: {:?}", buffer_snapshot.text());
let (inlay_snapshot, inlay_edits) = // let (inlay_snapshot, inlay_edits) =
inlay_map.sync(buffer_snapshot.clone(), buffer_edits); // inlay_map.sync(buffer_snapshot.clone(), buffer_edits);
log::info!("InlayMap text: {:?}", inlay_snapshot.text()); // log::info!("InlayMap text: {:?}", inlay_snapshot.text());
let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits); // let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits);
log::info!("FoldMap text: {:?}", fold_snapshot.text()); // log::info!("FoldMap text: {:?}", fold_snapshot.text());
let (tabs_snapshot, tab_edits) = tab_map.sync(fold_snapshot, fold_edits, tab_size); // let (tabs_snapshot, tab_edits) = tab_map.sync(fold_snapshot, fold_edits, tab_size);
log::info!("TabMap text: {:?}", tabs_snapshot.text()); // log::info!("TabMap text: {:?}", tabs_snapshot.text());
let unwrapped_text = tabs_snapshot.text(); // let unwrapped_text = tabs_snapshot.text();
let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper); // let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper);
let (mut snapshot, wrap_edits) = // let (mut snapshot, wrap_edits) =
wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot.clone(), tab_edits, cx)); // wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot.clone(), tab_edits, cx));
snapshot.check_invariants(); // snapshot.check_invariants();
snapshot.verify_chunks(&mut rng); // snapshot.verify_chunks(&mut rng);
edits.push((snapshot, wrap_edits)); // edits.push((snapshot, wrap_edits));
if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) && rng.gen_bool(0.4) { // if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) && rng.gen_bool(0.4) {
log::info!("Waiting for wrapping to finish"); // log::info!("Waiting for wrapping to finish");
while wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { // while wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
notifications.next().await.unwrap(); // notifications.next().await.unwrap();
} // }
wrap_map.read_with(cx, |map, _| assert!(map.pending_edits.is_empty())); // wrap_map.read_with(cx, |map, _| assert!(map.pending_edits.is_empty()));
} // }
if !wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { // if !wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
let (mut wrapped_snapshot, wrap_edits) = // let (mut wrapped_snapshot, wrap_edits) =
wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, Vec::new(), cx)); // wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, Vec::new(), cx));
let actual_text = wrapped_snapshot.text(); // let actual_text = wrapped_snapshot.text();
let actual_longest_row = wrapped_snapshot.longest_row(); // let actual_longest_row = wrapped_snapshot.longest_row();
log::info!("Wrapping finished: {:?}", actual_text); // log::info!("Wrapping finished: {:?}", actual_text);
wrapped_snapshot.check_invariants(); // wrapped_snapshot.check_invariants();
wrapped_snapshot.verify_chunks(&mut rng); // wrapped_snapshot.verify_chunks(&mut rng);
edits.push((wrapped_snapshot.clone(), wrap_edits)); // edits.push((wrapped_snapshot.clone(), wrap_edits));
assert_eq!( // assert_eq!(
actual_text, expected_text, // actual_text, expected_text,
"unwrapped text is: {:?}", // "unwrapped text is: {:?}",
unwrapped_text // unwrapped_text
); // );
let mut summary = TextSummary::default(); // let mut summary = TextSummary::default();
for (ix, item) in wrapped_snapshot // for (ix, item) in wrapped_snapshot
.transforms // .transforms
.items(&()) // .items(&())
.into_iter() // .into_iter()
.enumerate() // .enumerate()
{ // {
summary += &item.summary.output; // summary += &item.summary.output;
log::info!("{} summary: {:?}", ix, item.summary.output,); // log::info!("{} summary: {:?}", ix, item.summary.output,);
} // }
if tab_size.get() == 1 // if tab_size.get() == 1
|| !wrapped_snapshot // || !wrapped_snapshot
.tab_snapshot // .tab_snapshot
.fold_snapshot // .fold_snapshot
.text() // .text()
.contains('\t') // .contains('\t')
{ // {
let mut expected_longest_rows = Vec::new(); // let mut expected_longest_rows = Vec::new();
let mut longest_line_len = -1; // let mut longest_line_len = -1;
for (row, line) in expected_text.split('\n').enumerate() { // for (row, line) in expected_text.split('\n').enumerate() {
let line_char_count = line.chars().count() as isize; // let line_char_count = line.chars().count() as isize;
if line_char_count > longest_line_len { // if line_char_count > longest_line_len {
expected_longest_rows.clear(); // expected_longest_rows.clear();
longest_line_len = line_char_count; // longest_line_len = line_char_count;
} // }
if line_char_count >= longest_line_len { // if line_char_count >= longest_line_len {
expected_longest_rows.push(row as u32); // expected_longest_rows.push(row as u32);
} // }
} // }
assert!( // assert!(
expected_longest_rows.contains(&actual_longest_row), // expected_longest_rows.contains(&actual_longest_row),
"incorrect longest row {}. expected {:?} with length {}", // "incorrect longest row {}. expected {:?} with length {}",
actual_longest_row, // actual_longest_row,
expected_longest_rows, // expected_longest_rows,
longest_line_len, // longest_line_len,
) // )
} // }
} // }
} // }
let mut initial_text = Rope::from(initial_snapshot.text().as_str()); // let mut initial_text = Rope::from(initial_snapshot.text().as_str());
for (snapshot, patch) in edits { // for (snapshot, patch) in edits {
let snapshot_text = Rope::from(snapshot.text().as_str()); // let snapshot_text = Rope::from(snapshot.text().as_str());
for edit in &patch { // for edit in &patch {
let old_start = initial_text.point_to_offset(Point::new(edit.new.start, 0)); // let old_start = initial_text.point_to_offset(Point::new(edit.new.start, 0));
let old_end = initial_text.point_to_offset(cmp::min( // let old_end = initial_text.point_to_offset(cmp::min(
Point::new(edit.new.start + edit.old.len() as u32, 0), // Point::new(edit.new.start + edit.old.len() as u32, 0),
initial_text.max_point(), // initial_text.max_point(),
)); // ));
let new_start = snapshot_text.point_to_offset(Point::new(edit.new.start, 0)); // let new_start = snapshot_text.point_to_offset(Point::new(edit.new.start, 0));
let new_end = snapshot_text.point_to_offset(cmp::min( // let new_end = snapshot_text.point_to_offset(cmp::min(
Point::new(edit.new.end, 0), // Point::new(edit.new.end, 0),
snapshot_text.max_point(), // snapshot_text.max_point(),
)); // ));
let new_text = snapshot_text // let new_text = snapshot_text
.chunks_in_range(new_start..new_end) // .chunks_in_range(new_start..new_end)
.collect::<String>(); // .collect::<String>();
initial_text.replace(old_start..old_end, &new_text); // initial_text.replace(old_start..old_end, &new_text);
} // }
assert_eq!(initial_text.to_string(), snapshot_text.to_string()); // assert_eq!(initial_text.to_string(), snapshot_text.to_string());
} // }
if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { // if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
log::info!("Waiting for wrapping to finish"); // log::info!("Waiting for wrapping to finish");
while wrap_map.read_with(cx, |map, _| map.is_rewrapping()) { // while wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
notifications.next().await.unwrap(); // notifications.next().await.unwrap();
} // }
} // }
wrap_map.read_with(cx, |map, _| assert!(map.pending_edits.is_empty())); // wrap_map.read_with(cx, |map, _| assert!(map.pending_edits.is_empty()));
} // }
fn init_test(cx: &mut gpui::TestAppContext) { // fn init_test(cx: &mut gpui::TestAppContext) {
cx.foreground_executor().forbid_parking(); // cx.foreground().forbid_parking();
cx.update(|cx| { // cx.update(|cx| {
cx.set_global(SettingsStore::test(cx)); // cx.set_global(SettingsStore::test(cx));
theme::init((), cx); // theme::init((), cx);
}); // });
} // }
fn wrap_text( // fn wrap_text(
unwrapped_text: &str, // unwrapped_text: &str,
wrap_width: Option<f32>, // wrap_width: Option<f32>,
line_wrapper: &mut LineWrapper, // line_wrapper: &mut LineWrapper,
) -> String { // ) -> String {
if let Some(wrap_width) = wrap_width { // if let Some(wrap_width) = wrap_width {
let mut wrapped_text = String::new(); // let mut wrapped_text = String::new();
for (row, line) in unwrapped_text.split('\n').enumerate() { // for (row, line) in unwrapped_text.split('\n').enumerate() {
if row > 0 { // if row > 0 {
wrapped_text.push('\n') // wrapped_text.push('\n')
} // }
let mut prev_ix = 0; // let mut prev_ix = 0;
for boundary in line_wrapper.wrap_line(line, wrap_width) { // for boundary in line_wrapper.wrap_line(line, wrap_width) {
wrapped_text.push_str(&line[prev_ix..boundary.ix]); // wrapped_text.push_str(&line[prev_ix..boundary.ix]);
wrapped_text.push('\n'); // wrapped_text.push('\n');
wrapped_text.push_str(&" ".repeat(boundary.next_indent as usize)); // wrapped_text.push_str(&" ".repeat(boundary.next_indent as usize));
prev_ix = boundary.ix; // prev_ix = boundary.ix;
} // }
wrapped_text.push_str(&line[prev_ix..]); // wrapped_text.push_str(&line[prev_ix..]);
} // }
wrapped_text // wrapped_text
} else { // } else {
unwrapped_text.to_string() // unwrapped_text.to_string()
} // }
} // }
impl WrapSnapshot { // impl WrapSnapshot {
pub fn text(&self) -> String { // pub fn text(&self) -> String {
self.text_chunks(0).collect() // self.text_chunks(0).collect()
} // }
pub fn text_chunks(&self, wrap_row: u32) -> impl Iterator<Item = &str> { // pub fn text_chunks(&self, wrap_row: u32) -> impl Iterator<Item = &str> {
self.chunks( // self.chunks(
wrap_row..self.max_point().row() + 1, // wrap_row..self.max_point().row() + 1,
false, // false,
Highlights::default(), // Highlights::default(),
) // )
.map(|h| h.text) // .map(|h| h.text)
} // }
fn verify_chunks(&mut self, rng: &mut impl Rng) { // fn verify_chunks(&mut self, rng: &mut impl Rng) {
for _ in 0..5 { // for _ in 0..5 {
let mut end_row = rng.gen_range(0..=self.max_point().row()); // let mut end_row = rng.gen_range(0..=self.max_point().row());
let start_row = rng.gen_range(0..=end_row); // let start_row = rng.gen_range(0..=end_row);
end_row += 1; // end_row += 1;
let mut expected_text = self.text_chunks(start_row).collect::<String>(); // let mut expected_text = self.text_chunks(start_row).collect::<String>();
if expected_text.ends_with('\n') { // if expected_text.ends_with('\n') {
expected_text.push('\n'); // expected_text.push('\n');
} // }
let mut expected_text = expected_text // let mut expected_text = expected_text
.lines() // .lines()
.take((end_row - start_row) as usize) // .take((end_row - start_row) as usize)
.collect::<Vec<_>>() // .collect::<Vec<_>>()
.join("\n"); // .join("\n");
if end_row <= self.max_point().row() { // if end_row <= self.max_point().row() {
expected_text.push('\n'); // expected_text.push('\n');
} // }
let actual_text = self // let actual_text = self
.chunks(start_row..end_row, true, Highlights::default()) // .chunks(start_row..end_row, true, Highlights::default())
.map(|c| c.text) // .map(|c| c.text)
.collect::<String>(); // .collect::<String>();
assert_eq!( // assert_eq!(
expected_text, // expected_text,
actual_text, // actual_text,
"chunks != highlighted_chunks for rows {:?}", // "chunks != highlighted_chunks for rows {:?}",
start_row..end_row // start_row..end_row
); // );
} // }
} // }
} // }
} // }

View file

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

View file

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