From 9542a0aa9968bfef56cf9824a0c166bf47254920 Mon Sep 17 00:00:00 2001 From: Ben Kunkle Date: Fri, 17 Apr 2026 12:12:54 +0200 Subject: [PATCH 1/2] fix latent race conditions in extension test --- .../src/extension_store_test.rs | 53 +++++++++++++++---- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/crates/extension_host/src/extension_store_test.rs b/crates/extension_host/src/extension_store_test.rs index a2722da336b4d5..59217fdb54584a 100644 --- a/crates/extension_host/src/extension_store_test.rs +++ b/crates/extension_host/src/extension_store_test.rs @@ -721,6 +721,11 @@ async fn test_extension_store_with_test_extension(cx: &mut TestAppContext) { .detach(); }); + let mut extension_events = cx.events(&cx.update(|cx| { + extension::ExtensionEvents::try_global(cx) + .expect("ExtensionEvents should be initialized in tests") + })); + let executor = cx.executor(); await_or_timeout( &executor, @@ -733,6 +738,24 @@ async fn test_extension_store_with_test_extension(cx: &mut TestAppContext) { .await .unwrap(); + await_or_timeout( + &executor, + "awaiting ExtensionsInstalledChanged", + 10, + async { + while let Some(event) = extension_events.next().await { + if matches!(event, extension::Event::ExtensionsInstalledChanged) { + return; + } + } + + panic!( + "[test_extension_store_with_test_extension] extension event stream ended before ExtensionsInstalledChanged" + ); + }, + ) + .await; + let mut fake_servers = language_registry.register_fake_lsp_server( LanguageServerName("gleam".into()), lsp::ServerCapabilities { @@ -743,12 +766,14 @@ async fn test_extension_store_with_test_extension(cx: &mut TestAppContext) { ); cx.executor().run_until_parked(); + let mut project_events = cx.events(&project); + let buffer_path = project_dir.join("test.gleam"); let (buffer, _handle) = await_or_timeout( &executor, "awaiting open_local_buffer_with_lsp", 5, project.update(cx, |project, cx| { - project.open_local_buffer_with_lsp(project_dir.join("test.gleam"), cx) + project.open_local_buffer_with_lsp(buffer_path.clone(), cx) }), ) .await @@ -870,18 +895,28 @@ async fn test_extension_store_with_test_extension(cx: &mut TestAppContext) { ]))) }); - // `register_fake_lsp_server` can yield a server instance before the client has finished the LSP - // initialization handshake. Wait until we observe the client's `initialized` notification before - // issuing requests like completion. + // `register_fake_lsp_server` can yield a server instance before the client has fully registered + // the buffer with the project LSP plumbing. Wait for the project to observe that registration + // before issuing requests like completion. await_or_timeout( &executor, - "awaiting LSP Initialized notification", + "awaiting LanguageServerBufferRegistered", 5, async { - fake_server - .clone() - .try_receive_notification::() - .await; + while let Some(event) = project_events.next().await { + if let project::Event::LanguageServerBufferRegistered { + buffer_abs_path, .. + } = event + && buffer_abs_path == buffer_path + { + return; + } + } + + panic!( + "[test_extension_store_with_test_extension] project event stream ended before buffer registration for {}", + buffer_path.display() + ); }, ) .await; From 82e5a1ecfa2b6951b53e63365af20216762db284 Mon Sep 17 00:00:00 2001 From: Ben Kunkle Date: Fri, 17 Apr 2026 13:32:57 +0200 Subject: [PATCH 2/2] fix path comparisons --- crates/extension_host/src/extension_store_test.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/extension_host/src/extension_store_test.rs b/crates/extension_host/src/extension_store_test.rs index 59217fdb54584a..c395aedb260036 100644 --- a/crates/extension_host/src/extension_store_test.rs +++ b/crates/extension_host/src/extension_store_test.rs @@ -780,6 +780,8 @@ async fn test_extension_store_with_test_extension(cx: &mut TestAppContext) { .unwrap(); cx.executor().run_until_parked(); + let buffer_remote_id = buffer.read_with(cx, |buffer, _cx| buffer.remote_id()); + let fake_server = await_or_timeout( &executor, "awaiting first fake server spawn", @@ -904,12 +906,10 @@ async fn test_extension_store_with_test_extension(cx: &mut TestAppContext) { 5, async { while let Some(event) = project_events.next().await { - if let project::Event::LanguageServerBufferRegistered { - buffer_abs_path, .. - } = event - && buffer_abs_path == buffer_path - { - return; + if let project::Event::LanguageServerBufferRegistered { buffer_id, .. } = event { + if buffer_id == buffer_remote_id { + return; + } } }