From 6efadd19dd582f8157a467187e25c0a0d865e9a5 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 29 Jul 2021 08:53:10 -0600 Subject: [PATCH] Reuse FontCache across randomized tests Co-Authored-By: Antonio Scandurra --- gpui/src/app.rs | 25 ++++++---- gpui/src/lib.rs | 2 +- gpui/src/platform/test.rs | 8 +-- gpui_macros/src/lib.rs | 101 +++++++++++++++++++++++--------------- 4 files changed, 83 insertions(+), 53 deletions(-) diff --git a/gpui/src/app.rs b/gpui/src/app.rs index 8ac9d41111d50cdaf23a7c72da09700c456578ba..72b9bbd2f6f0d168cff8edea975662eaf61acd1c 100644 --- a/gpui/src/app.rs +++ b/gpui/src/app.rs @@ -118,15 +118,19 @@ pub struct TestAppContext { } impl App { - pub fn test T>(f: F) -> T { - let foreground_platform = platform::test::foreground_platform(); - let platform = platform::test::platform(); + pub fn test T>( + foreground_platform: Rc, + platform: Arc, + font_cache: Arc, + f: F, + ) -> T { let foreground = Rc::new(executor::Foreground::test()); let cx = Rc::new(RefCell::new(MutableAppContext::new( foreground, Arc::new(executor::Background::new()), - Arc::new(platform), - Rc::new(foreground_platform), + platform, + foreground_platform, + font_cache, (), ))); cx.borrow_mut().weak_self = Some(Rc::downgrade(&cx)); @@ -143,6 +147,7 @@ impl App { Arc::new(executor::Background::new()), platform.clone(), foreground_platform.clone(), + Arc::new(FontCache::new(platform.fonts())), asset_source, )))); @@ -245,17 +250,19 @@ impl App { impl TestAppContext { pub fn new( + foreground_platform: Rc, + platform: Arc, foreground: Rc, background: Arc, + font_cache: Arc, first_entity_id: usize, ) -> Self { - let platform = Arc::new(platform::test::platform()); - let foreground_platform = Rc::new(platform::test::foreground_platform()); let mut cx = MutableAppContext::new( foreground.clone(), background, platform, foreground_platform.clone(), + font_cache, (), ); cx.next_entity_id = first_entity_id; @@ -593,9 +600,9 @@ impl MutableAppContext { background: Arc, platform: Arc, foreground_platform: Rc, + font_cache: Arc, asset_source: impl AssetSource, ) -> Self { - let fonts = platform.fonts(); Self { weak_self: None, foreground_platform, @@ -607,7 +614,7 @@ impl MutableAppContext { values: Default::default(), ref_counts: Arc::new(Mutex::new(RefCounts::default())), background, - font_cache: Arc::new(FontCache::new(fonts)), + font_cache, platform, }, actions: HashMap::new(), diff --git a/gpui/src/lib.rs b/gpui/src/lib.rs index 591d220bbae8f701e1479912ba6e2c5bc7231664..f2f935d142719da38d7ccfe6d6c57193e136646e 100644 --- a/gpui/src/lib.rs +++ b/gpui/src/lib.rs @@ -23,7 +23,7 @@ pub use executor::Task; pub mod color; pub mod json; pub mod keymap; -mod platform; +pub mod platform; pub use gpui_macros::test; pub use platform::FontSystem; pub use platform::{Event, PathPromptOptions, Platform, PromptLevel}; diff --git a/gpui/src/platform/test.rs b/gpui/src/platform/test.rs index 2927b36b4d5325544f8a657bea773d9112f211c6..77e23d5aa6773c5790545f04c47dca4291f22b40 100644 --- a/gpui/src/platform/test.rs +++ b/gpui/src/platform/test.rs @@ -9,14 +9,14 @@ use std::{ sync::Arc, }; -pub(crate) struct Platform { +pub struct Platform { dispatcher: Arc, fonts: Arc, current_clipboard_item: Mutex>, } #[derive(Default)] -pub(crate) struct ForegroundPlatform { +pub struct ForegroundPlatform { last_prompt_for_new_path_args: RefCell)>)>>, } @@ -191,10 +191,10 @@ impl super::Window for Window { } } -pub(crate) fn platform() -> Platform { +pub fn platform() -> Platform { Platform::new() } -pub(crate) fn foreground_platform() -> ForegroundPlatform { +pub fn foreground_platform() -> ForegroundPlatform { ForegroundPlatform::default() } diff --git a/gpui_macros/src/lib.rs b/gpui_macros/src/lib.rs index 05fde3f98c661fc7e7df34a92d6d15fe5b00b4b2..7de36f66ee27e3c7290c9552d03f67b4c320db65 100644 --- a/gpui_macros/src/lib.rs +++ b/gpui_macros/src/lib.rs @@ -67,9 +67,14 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream { match last_segment.map(|s| s.ident.to_string()).as_deref() { Some("TestAppContext") => { let first_entity_id = ix * 100_000; - inner_fn_args.extend( - quote!(#namespace::TestAppContext::new(foreground.clone(), background.clone(), #first_entity_id),) - ); + inner_fn_args.extend(quote!(#namespace::TestAppContext::new( + foreground_platform.clone(), + platform.clone(), + foreground.clone(), + background.clone(), + font_cache.clone(), + #first_entity_id), + )); } Some("StdRng") => { inner_fn_args.extend(quote!(rand::SeedableRng::seed_from_u64(seed))); @@ -99,8 +104,8 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream { #inner_fn let is_randomized = #num_iterations > 1; - let mut num_iterations = #num_iterations; - let mut starting_seed = #starting_seed; + let mut num_iterations = #num_iterations as u64; + let mut starting_seed = #starting_seed as u64; if is_randomized { if let Ok(value) = std::env::var("SEED") { starting_seed = value.parse().expect("invalid SEED variable"); @@ -110,34 +115,43 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream { } } + let mut atomic_seed = std::sync::atomic::AtomicU64::new(starting_seed as u64); let mut retries = 0; - let mut i = 0; - loop { - let seed = (starting_seed + i) as u64; - if is_randomized { - dbg!(seed); - } + loop { let result = std::panic::catch_unwind(|| { - let (foreground, background) = #namespace::executor::deterministic(seed); - foreground.run(#inner_fn_name(#inner_fn_args)); + let foreground_platform = std::rc::Rc::new(#namespace::platform::test::foreground_platform()); + let platform = std::sync::Arc::new(#namespace::platform::test::platform()); + let font_system = #namespace::Platform::fonts(platform.as_ref()); + let font_cache = std::sync::Arc::new(#namespace::FontCache::new(font_system)); + + loop { + let seed = atomic_seed.load(std::sync::atomic::Ordering::SeqCst); + if seed >= starting_seed + num_iterations { + break; + } + + if is_randomized { + dbg!(seed); + } + + let (foreground, background) = #namespace::executor::deterministic(seed); + foreground.run(#inner_fn_name(#inner_fn_args)); + atomic_seed.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + } }); match result { Ok(result) => { - retries = 0; - i += 1; - if i == num_iterations { - return result - } + break; } Err(error) => { if retries < #max_retries { retries += 1; println!("retrying: attempt {}", retries); } else { - if num_iterations > 1 { - eprintln!("failing seed: {}", seed); + if is_randomized { + eprintln!("failing seed: {}", atomic_seed.load(std::sync::atomic::Ordering::SeqCst)); } std::panic::resume_unwind(error); } @@ -171,8 +185,8 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream { #inner_fn let is_randomized = #num_iterations > 1; - let mut num_iterations = #num_iterations; - let mut starting_seed = #starting_seed; + let mut num_iterations = #num_iterations as u64; + let mut starting_seed = #starting_seed as u64; if is_randomized { if let Ok(value) = std::env::var("SEED") { starting_seed = value.parse().expect("invalid SEED variable"); @@ -182,35 +196,44 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream { } } + let mut atomic_seed = std::sync::atomic::AtomicU64::new(starting_seed as u64); let mut retries = 0; - let mut i = 0; - loop { - let seed = (starting_seed + i) as u64; - if is_randomized { - dbg!(seed); - } + loop { let result = std::panic::catch_unwind(|| { - #namespace::App::test(|cx| { - #inner_fn_name(#inner_fn_args); - }); + let foreground_platform = std::rc::Rc::new(#namespace::platform::test::foreground_platform()); + let platform = std::sync::Arc::new(#namespace::platform::test::platform()); + let font_system = #namespace::Platform::fonts(platform.as_ref()); + let font_cache = std::sync::Arc::new(#namespace::FontCache::new(font_system)); + + loop { + let seed = atomic_seed.load(std::sync::atomic::Ordering::SeqCst); + if seed >= starting_seed + num_iterations { + break; + } + + if is_randomized { + dbg!(seed); + } + + #namespace::App::test(foreground_platform.clone(), platform.clone(), font_cache.clone(), |cx| { + #inner_fn_name(#inner_fn_args); + }); + atomic_seed.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + } }); match result { - Ok(result) => { - retries = 0; - i += 1; - if i == num_iterations { - return result - } + Ok(_) => { + break; } Err(error) => { if retries < #max_retries { retries += 1; println!("retrying: attempt {}", retries); } else { - if #num_iterations > 1 { - eprintln!("failing seed: {}", seed); + if is_randomized { + eprintln!("failing seed: {}", atomic_seed.load(std::sync::atomic::Ordering::SeqCst)); } std::panic::resume_unwind(error); }