Get RPC2 tests passing

Conrad Irwin , Conrad , and Kyle created

Co-authored-by: Conrad <conrad@zed.dev>
Co-authored-by: Kyle <kyle@zed.dev>

Change summary

Cargo.lock                                   |  38 +++
Cargo.toml                                   |   1 
crates/client2/Cargo.toml                    |   6 
crates/client2/src/client2.rs                |   8 
crates/client2/src/user.rs                   |   2 
crates/gpui2/src/platform/test/dispatcher.rs |  19 +
crates/language2/Cargo.toml                  |   3 
crates/language2/src/buffer.rs               |   4 
crates/language2/src/language2.rs            | 217 +++++++++++----------
crates/language2/src/proto.rs                |   2 
crates/project2/Cargo.toml                   |   4 
crates/project2/src/worktree.rs              |   6 
crates/rpc2/Cargo.toml                       |   8 
crates/rpc2/src/conn.rs                      |  16 -
crates/rpc2/src/peer.rs                      |  64 +++---
crates/rpc2/src/proto.rs                     |   4 
crates/zed2/Cargo.toml                       |   2 
17 files changed, 218 insertions(+), 186 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -1481,7 +1481,7 @@ dependencies = [
  "parking_lot 0.11.2",
  "postage",
  "rand 0.8.5",
- "rpc",
+ "rpc2",
  "schemars",
  "serde",
  "serde_derive",
@@ -4248,7 +4248,6 @@ dependencies = [
  "collections",
  "ctor",
  "env_logger 0.9.3",
- "fs",
  "futures 0.3.28",
  "fuzzy2",
  "git",
@@ -4262,7 +4261,7 @@ dependencies = [
  "postage",
  "rand 0.8.5",
  "regex",
- "rpc",
+ "rpc2",
  "schemars",
  "serde",
  "serde_derive",
@@ -6050,7 +6049,7 @@ dependencies = [
  "pretty_assertions",
  "rand 0.8.5",
  "regex",
- "rpc",
+ "rpc2",
  "schemars",
  "serde",
  "serde_derive",
@@ -6802,6 +6801,35 @@ dependencies = [
  "zstd",
 ]
 
+[[package]]
+name = "rpc2"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "async-lock",
+ "async-tungstenite",
+ "base64 0.13.1",
+ "clock",
+ "collections",
+ "ctor",
+ "env_logger 0.9.3",
+ "futures 0.3.28",
+ "gpui2",
+ "parking_lot 0.11.2",
+ "prost 0.8.0",
+ "prost-build",
+ "rand 0.8.5",
+ "rsa 0.4.0",
+ "serde",
+ "serde_derive",
+ "smol",
+ "smol-timeout",
+ "tempdir",
+ "tracing",
+ "util",
+ "zstd",
+]
+
 [[package]]
 name = "rsa"
 version = "0.4.0"
@@ -10767,7 +10795,7 @@ dependencies = [
  "postage",
  "rand 0.8.5",
  "regex",
- "rpc",
+ "rpc2",
  "rsa 0.4.0",
  "rust-embed",
  "schemars",

Cargo.toml 🔗

@@ -71,6 +71,7 @@ members = [
     "crates/recent_projects",
     "crates/rope",
     "crates/rpc",
+    "crates/rpc2",
     "crates/search",
     "crates/settings",
     "crates/settings2",

crates/client2/Cargo.toml 🔗

@@ -9,14 +9,14 @@ path = "src/client2.rs"
 doctest = false
 
 [features]
-test-support = ["collections/test-support", "gpui2/test-support", "rpc/test-support"]
+test-support = ["collections/test-support", "gpui2/test-support", "rpc2/test-support"]
 
 [dependencies]
 collections = { path = "../collections" }
 db2 = { path = "../db2" }
 gpui2 = { path = "../gpui2" }
 util = { path = "../util" }
-rpc = { path = "../rpc" }
+rpc2 = { path = "../rpc2" }
 text = { path = "../text" }
 settings2 = { path = "../settings2" }
 feature_flags2 = { path = "../feature_flags2" }
@@ -47,6 +47,6 @@ url = "2.2"
 [dev-dependencies]
 collections = { path = "../collections", features = ["test-support"] }
 gpui2 = { path = "../gpui2", features = ["test-support"] }
-rpc = { path = "../rpc", features = ["test-support"] }
+rpc2 = { path = "../rpc2", features = ["test-support"] }
 settings = { path = "../settings", features = ["test-support"] }
 util = { path = "../util", features = ["test-support"] }

crates/client2/src/client2.rs 🔗

@@ -21,7 +21,7 @@ use lazy_static::lazy_static;
 use parking_lot::RwLock;
 use postage::watch;
 use rand::prelude::*;
-use rpc::proto::{AnyTypedEnvelope, EntityMessage, EnvelopedMessage, PeerId, RequestMessage};
+use rpc2::proto::{AnyTypedEnvelope, EntityMessage, EnvelopedMessage, PeerId, RequestMessage};
 use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
 use settings2::Settings;
@@ -43,7 +43,7 @@ use util::channel::ReleaseChannel;
 use util::http::HttpClient;
 use util::{ResultExt, TryFutureExt};
 
-pub use rpc::*;
+pub use rpc2::*;
 pub use telemetry::ClickhouseEvent;
 pub use user::*;
 
@@ -975,7 +975,7 @@ impl Client {
                 "Authorization",
                 format!("{} {}", credentials.user_id, credentials.access_token),
             )
-            .header("x-zed-protocol-version", rpc::PROTOCOL_VERSION);
+            .header("x-zed-protocol-version", rpc2::PROTOCOL_VERSION);
 
         let http = self.http.clone();
         cx.executor().spawn(async move {
@@ -1025,7 +1025,7 @@ impl Client {
             // zed server to encrypt the user's access token, so that it can'be intercepted by
             // any other app running on the user's device.
             let (public_key, private_key) =
-                rpc::auth::keypair().expect("failed to generate keypair for auth");
+                rpc2::auth::keypair().expect("failed to generate keypair for auth");
             let public_key_string =
                 String::try_from(public_key).expect("failed to serialize public key for auth");
 

crates/client2/src/user.rs 🔗

@@ -5,7 +5,7 @@ use feature_flags2::FeatureFlagAppExt;
 use futures::{channel::mpsc, future, AsyncReadExt, Future, StreamExt};
 use gpui2::{AsyncAppContext, EventEmitter, Handle, ImageData, ModelContext, Task};
 use postage::{sink::Sink, watch};
-use rpc::proto::{RequestMessage, UsersResponse};
+use rpc2::proto::{RequestMessage, UsersResponse};
 use std::sync::{Arc, Weak};
 use text::ReplicaId;
 use util::http::HttpClient;

crates/gpui2/src/platform/test/dispatcher.rs 🔗

@@ -1,6 +1,6 @@
 use crate::PlatformDispatcher;
 use async_task::Runnable;
-use collections::{BTreeMap, HashMap, VecDeque};
+use collections::{HashMap, VecDeque};
 use parking_lot::Mutex;
 use rand::prelude::*;
 use std::{
@@ -24,7 +24,7 @@ struct TestDispatcherState {
     random: StdRng,
     foreground: HashMap<TestDispatcherId, VecDeque<Runnable>>,
     background: Vec<Runnable>,
-    delayed: BTreeMap<Instant, Runnable>,
+    delayed: Vec<(Instant, Runnable)>,
     time: Instant,
     is_main_thread: bool,
     next_id: TestDispatcherId,
@@ -36,7 +36,7 @@ impl TestDispatcher {
             random,
             foreground: HashMap::default(),
             background: Vec::new(),
-            delayed: BTreeMap::new(),
+            delayed: Vec::new(),
             time: Instant::now(),
             is_main_thread: true,
             next_id: TestDispatcherId(1),
@@ -112,17 +112,20 @@ impl PlatformDispatcher for TestDispatcher {
     fn dispatch_after(&self, duration: std::time::Duration, runnable: Runnable) {
         let mut state = self.state.lock();
         let next_time = state.time + duration;
-        state.delayed.insert(next_time, runnable);
+        let ix = match state.delayed.binary_search_by_key(&next_time, |e| e.0) {
+            Ok(ix) | Err(ix) => ix,
+        };
+        state.delayed.insert(ix, (next_time, runnable));
     }
 
     fn poll(&self) -> bool {
         let mut state = self.state.lock();
 
-        while let Some((deadline, _)) = state.delayed.first_key_value() {
+        while let Some((deadline, _)) = state.delayed.first() {
             if *deadline > state.time {
                 break;
             }
-            let (_, runnable) = state.delayed.pop_first().unwrap();
+            let (_, runnable) = state.delayed.remove(0);
             state.background.push(runnable);
         }
 
@@ -134,8 +137,10 @@ impl PlatformDispatcher for TestDispatcher {
         let background_len = state.background.len();
 
         if foreground_len == 0 && background_len == 0 {
+            eprintln!("no runnables to poll");
             return false;
         }
+        eprintln!("runnables {} {}", foreground_len, background_len);
 
         let main_thread = state.random.gen_ratio(
             foreground_len as u32,
@@ -145,6 +150,7 @@ impl PlatformDispatcher for TestDispatcher {
         state.is_main_thread = main_thread;
 
         let runnable = if main_thread {
+            eprintln!("running next main thread");
             let state = &mut *state;
             let runnables = state
                 .foreground
@@ -155,6 +161,7 @@ impl PlatformDispatcher for TestDispatcher {
             runnables.pop_front().unwrap()
         } else {
             let ix = state.random.gen_range(0..background_len);
+            eprintln!("running background thread {ix}");
             state.background.swap_remove(ix)
         };
 

crates/language2/Cargo.toml 🔗

@@ -25,11 +25,10 @@ test-support = [
 clock = { path = "../clock" }
 collections = { path = "../collections" }
 fuzzy2 = { path = "../fuzzy2" }
-fs = { path = "../fs" }
 git = { path = "../git" }
 gpui2 = { path = "../gpui2" }
 lsp2 = { path = "../lsp2" }
-rpc = { path = "../rpc" }
+rpc2 = { path = "../rpc2" }
 settings2 = { path = "../settings2" }
 sum_tree = { path = "../sum_tree" }
 text = { path = "../text" }

crates/language2/src/buffer.rs 🔗

@@ -226,7 +226,7 @@ pub trait File: Send + Sync {
 
     fn as_any(&self) -> &dyn Any;
 
-    fn to_proto(&self) -> rpc::proto::File;
+    fn to_proto(&self) -> rpc2::proto::File;
 }
 
 pub trait LocalFile: File {
@@ -375,7 +375,7 @@ impl Buffer {
             file,
         );
         this.text.set_line_ending(proto::deserialize_line_ending(
-            rpc::proto::LineEnding::from_i32(message.line_ending)
+            rpc2::proto::LineEnding::from_i32(message.line_ending)
                 .ok_or_else(|| anyhow!("missing line_ending"))?,
         ));
         this.saved_version = proto::deserialize_version(&message.saved_version);

crates/language2/src/language2.rs 🔗

@@ -1862,111 +1862,112 @@ pub fn range_from_lsp(range: lsp2::Range) -> Range<Unclipped<PointUtf16>> {
     start..end
 }
 
-// #[cfg(test)]
-// mod tests {
-//     use super::*;
-//     use gpui::TestAppContext;
-
-//     #[gpui::test(iterations = 10)]
-//     async fn test_first_line_pattern(cx: &mut TestAppContext) {
-//         let mut languages = LanguageRegistry::test();
-//         languages.set_executor(cx.background());
-//         let languages = Arc::new(languages);
-//         languages.register(
-//             "/javascript",
-//             LanguageConfig {
-//                 name: "JavaScript".into(),
-//                 path_suffixes: vec!["js".into()],
-//                 first_line_pattern: Some(Regex::new(r"\bnode\b").unwrap()),
-//                 ..Default::default()
-//             },
-//             tree_sitter_typescript::language_tsx(),
-//             vec![],
-//             |_| Default::default(),
-//         );
-
-//         languages
-//             .language_for_file("the/script", None)
-//             .await
-//             .unwrap_err();
-//         languages
-//             .language_for_file("the/script", Some(&"nothing".into()))
-//             .await
-//             .unwrap_err();
-//         assert_eq!(
-//             languages
-//                 .language_for_file("the/script", Some(&"#!/bin/env node".into()))
-//                 .await
-//                 .unwrap()
-//                 .name()
-//                 .as_ref(),
-//             "JavaScript"
-//         );
-//     }
-
-//     #[gpui::test(iterations = 10)]
-//     async fn test_language_loading(cx: &mut TestAppContext) {
-//         let mut languages = LanguageRegistry::test();
-//         languages.set_executor(cx.background());
-//         let languages = Arc::new(languages);
-//         languages.register(
-//             "/JSON",
-//             LanguageConfig {
-//                 name: "JSON".into(),
-//                 path_suffixes: vec!["json".into()],
-//                 ..Default::default()
-//             },
-//             tree_sitter_json::language(),
-//             vec![],
-//             |_| Default::default(),
-//         );
-//         languages.register(
-//             "/rust",
-//             LanguageConfig {
-//                 name: "Rust".into(),
-//                 path_suffixes: vec!["rs".into()],
-//                 ..Default::default()
-//             },
-//             tree_sitter_rust::language(),
-//             vec![],
-//             |_| Default::default(),
-//         );
-//         assert_eq!(
-//             languages.language_names(),
-//             &[
-//                 "JSON".to_string(),
-//                 "Plain Text".to_string(),
-//                 "Rust".to_string(),
-//             ]
-//         );
-
-//         let rust1 = languages.language_for_name("Rust");
-//         let rust2 = languages.language_for_name("Rust");
-
-//         // Ensure language is still listed even if it's being loaded.
-//         assert_eq!(
-//             languages.language_names(),
-//             &[
-//                 "JSON".to_string(),
-//                 "Plain Text".to_string(),
-//                 "Rust".to_string(),
-//             ]
-//         );
-
-//         let (rust1, rust2) = futures::join!(rust1, rust2);
-//         assert!(Arc::ptr_eq(&rust1.unwrap(), &rust2.unwrap()));
-
-//         // Ensure language is still listed even after loading it.
-//         assert_eq!(
-//             languages.language_names(),
-//             &[
-//                 "JSON".to_string(),
-//                 "Plain Text".to_string(),
-//                 "Rust".to_string(),
-//             ]
-//         );
-
-//         // Loading an unknown language returns an error.
-//         assert!(languages.language_for_name("Unknown").await.is_err());
-//     }
-// }
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use gpui2::TestAppContext;
+
+    #[gpui2::test(iterations = 10)]
+    async fn test_first_line_pattern(cx: &mut TestAppContext) {
+        let mut languages = LanguageRegistry::test();
+
+        languages.set_executor(cx.executor().clone());
+        let languages = Arc::new(languages);
+        languages.register(
+            "/javascript",
+            LanguageConfig {
+                name: "JavaScript".into(),
+                path_suffixes: vec!["js".into()],
+                first_line_pattern: Some(Regex::new(r"\bnode\b").unwrap()),
+                ..Default::default()
+            },
+            tree_sitter_typescript::language_tsx(),
+            vec![],
+            |_| Default::default(),
+        );
+
+        languages
+            .language_for_file("the/script", None)
+            .await
+            .unwrap_err();
+        languages
+            .language_for_file("the/script", Some(&"nothing".into()))
+            .await
+            .unwrap_err();
+        assert_eq!(
+            languages
+                .language_for_file("the/script", Some(&"#!/bin/env node".into()))
+                .await
+                .unwrap()
+                .name()
+                .as_ref(),
+            "JavaScript"
+        );
+    }
+
+    #[gpui2::test(iterations = 10)]
+    async fn test_language_loading(cx: &mut TestAppContext) {
+        let mut languages = LanguageRegistry::test();
+        languages.set_executor(cx.executor().clone());
+        let languages = Arc::new(languages);
+        languages.register(
+            "/JSON",
+            LanguageConfig {
+                name: "JSON".into(),
+                path_suffixes: vec!["json".into()],
+                ..Default::default()
+            },
+            tree_sitter_json::language(),
+            vec![],
+            |_| Default::default(),
+        );
+        languages.register(
+            "/rust",
+            LanguageConfig {
+                name: "Rust".into(),
+                path_suffixes: vec!["rs".into()],
+                ..Default::default()
+            },
+            tree_sitter_rust::language(),
+            vec![],
+            |_| Default::default(),
+        );
+        assert_eq!(
+            languages.language_names(),
+            &[
+                "JSON".to_string(),
+                "Plain Text".to_string(),
+                "Rust".to_string(),
+            ]
+        );
+
+        let rust1 = languages.language_for_name("Rust");
+        let rust2 = languages.language_for_name("Rust");
+
+        // Ensure language is still listed even if it's being loaded.
+        assert_eq!(
+            languages.language_names(),
+            &[
+                "JSON".to_string(),
+                "Plain Text".to_string(),
+                "Rust".to_string(),
+            ]
+        );
+
+        let (rust1, rust2) = futures::join!(rust1, rust2);
+        assert!(Arc::ptr_eq(&rust1.unwrap(), &rust2.unwrap()));
+
+        // Ensure language is still listed even after loading it.
+        assert_eq!(
+            languages.language_names(),
+            &[
+                "JSON".to_string(),
+                "Plain Text".to_string(),
+                "Rust".to_string(),
+            ]
+        );
+
+        // Loading an unknown language returns an error.
+        assert!(languages.language_for_name("Unknown").await.is_err());
+    }
+}

crates/language2/src/proto.rs 🔗

@@ -5,7 +5,7 @@ use crate::{
 use anyhow::{anyhow, Result};
 use clock::ReplicaId;
 use lsp2::{DiagnosticSeverity, LanguageServerId};
-use rpc::proto;
+use rpc2::proto;
 use std::{ops::Range, sync::Arc};
 use text::*;
 

crates/project2/Cargo.toml 🔗

@@ -34,7 +34,7 @@ language2 = { path = "../language2" }
 lsp2 = { path = "../lsp2" }
 node_runtime = { path = "../node_runtime" }
 prettier2 = { path = "../prettier2" }
-rpc = { path = "../rpc" }
+rpc2 = { path = "../rpc2" }
 settings2 = { path = "../settings2" }
 sum_tree = { path = "../sum_tree" }
 terminal2 = { path = "../terminal2" }
@@ -78,7 +78,7 @@ lsp2 = { path = "../lsp2", features = ["test-support"] }
 settings2 = { path = "../settings2", features = ["test-support"] }
 prettier2 = { path = "../prettier2", features = ["test-support"] }
 util = { path = "../util", features = ["test-support"] }
-rpc = { path = "../rpc", features = ["test-support"] }
+rpc2 = { path = "../rpc2", features = ["test-support"] }
 git2.workspace = true
 tempdir.workspace = true
 unindent.workspace = true

crates/project2/src/worktree.rs 🔗

@@ -2646,8 +2646,8 @@ impl language2::File for File {
         self
     }
 
-    fn to_proto(&self) -> rpc::proto::File {
-        rpc::proto::File {
+    fn to_proto(&self) -> rpc2::proto::File {
+        rpc2::proto::File {
             worktree_id: self.worktree.entity_id().as_u64(),
             entry_id: self.entry_id.to_proto(),
             path: self.path.to_string_lossy().into(),
@@ -2713,7 +2713,7 @@ impl File {
     }
 
     pub fn from_proto(
-        proto: rpc::proto::File,
+        proto: rpc2::proto::File,
         worktree: Handle<Worktree>,
         cx: &AppContext,
     ) -> Result<Self> {

crates/rpc2/Cargo.toml 🔗

@@ -1,7 +1,7 @@
 [package]
 description = "Shared logic for communication between the Zed app and the zed.dev server"
 edition = "2021"
-name = "rpc"
+name = "rpc2"
 version = "0.1.0"
 publish = false
 
@@ -10,12 +10,12 @@ path = "src/rpc.rs"
 doctest = false
 
 [features]
-test-support = ["collections/test-support", "gpui/test-support"]
+test-support = ["collections/test-support", "gpui2/test-support"]
 
 [dependencies]
 clock = { path = "../clock" }
 collections = { path = "../collections" }
-gpui = { path = "../gpui", optional = true }
+gpui2 = { path = "../gpui2", optional = true }
 util = { path = "../util" }
 anyhow.workspace = true
 async-lock = "2.4"
@@ -37,7 +37,7 @@ prost-build = "0.9"
 
 [dev-dependencies]
 collections = { path = "../collections", features = ["test-support"] }
-gpui = { path = "../gpui", features = ["test-support"] }
+gpui2 = { path = "../gpui2", features = ["test-support"] }
 smol.workspace = true
 tempdir.workspace = true
 ctor.workspace = true

crates/rpc2/src/conn.rs 🔗

@@ -34,7 +34,7 @@ impl Connection {
 
     #[cfg(any(test, feature = "test-support"))]
     pub fn in_memory(
-        executor: std::sync::Arc<gpui::executor::Background>,
+        executor: gpui2::Executor,
     ) -> (Self, Self, std::sync::Arc<std::sync::atomic::AtomicBool>) {
         use std::sync::{
             atomic::{AtomicBool, Ordering::SeqCst},
@@ -53,7 +53,7 @@ impl Connection {
         #[allow(clippy::type_complexity)]
         fn channel(
             killed: Arc<AtomicBool>,
-            executor: Arc<gpui::executor::Background>,
+            executor: gpui2::Executor,
         ) -> (
             Box<dyn Send + Unpin + futures::Sink<WebSocketMessage, Error = anyhow::Error>>,
             Box<dyn Send + Unpin + futures::Stream<Item = Result<WebSocketMessage, anyhow::Error>>>,
@@ -66,14 +66,12 @@ impl Connection {
 
             let tx = tx.sink_map_err(|error| anyhow!(error)).with({
                 let killed = killed.clone();
-                let executor = Arc::downgrade(&executor);
+                let executor = executor.clone();
                 move |msg| {
                     let killed = killed.clone();
                     let executor = executor.clone();
                     Box::pin(async move {
-                        if let Some(executor) = executor.upgrade() {
-                            executor.simulate_random_delay().await;
-                        }
+                        executor.simulate_random_delay().await;
 
                         // Writes to a half-open TCP connection will error.
                         if killed.load(SeqCst) {
@@ -87,14 +85,12 @@ impl Connection {
 
             let rx = rx.then({
                 let killed = killed;
-                let executor = Arc::downgrade(&executor);
+                let executor = executor.clone();
                 move |msg| {
                     let killed = killed.clone();
                     let executor = executor.clone();
                     Box::pin(async move {
-                        if let Some(executor) = executor.upgrade() {
-                            executor.simulate_random_delay().await;
-                        }
+                        executor.simulate_random_delay().await;
 
                         // Reads from a half-open TCP connection will hang.
                         if killed.load(SeqCst) {

crates/rpc2/src/peer.rs 🔗

@@ -342,7 +342,7 @@ impl Peer {
     pub fn add_test_connection(
         self: &Arc<Self>,
         connection: Connection,
-        executor: Arc<gpui::executor::Background>,
+        executor: gpui2::Executor,
     ) -> (
         ConnectionId,
         impl Future<Output = anyhow::Result<()>> + Send,
@@ -557,7 +557,7 @@ mod tests {
     use super::*;
     use crate::TypedEnvelope;
     use async_tungstenite::tungstenite::Message as WebSocketMessage;
-    use gpui::TestAppContext;
+    use gpui2::TestAppContext;
 
     #[ctor::ctor]
     fn init_logger() {
@@ -566,9 +566,9 @@ mod tests {
         }
     }
 
-    #[gpui::test(iterations = 50)]
+    #[gpui2::test(iterations = 50)]
     async fn test_request_response(cx: &mut TestAppContext) {
-        let executor = cx.foreground();
+        let executor = cx.executor();
 
         // create 2 clients connected to 1 server
         let server = Peer::new(0);
@@ -576,18 +576,18 @@ mod tests {
         let client2 = Peer::new(0);
 
         let (client1_to_server_conn, server_to_client_1_conn, _kill) =
-            Connection::in_memory(cx.background());
+            Connection::in_memory(cx.executor().clone());
         let (client1_conn_id, io_task1, client1_incoming) =
-            client1.add_test_connection(client1_to_server_conn, cx.background());
+            client1.add_test_connection(client1_to_server_conn, cx.executor().clone());
         let (_, io_task2, server_incoming1) =
-            server.add_test_connection(server_to_client_1_conn, cx.background());
+            server.add_test_connection(server_to_client_1_conn, cx.executor().clone());
 
         let (client2_to_server_conn, server_to_client_2_conn, _kill) =
-            Connection::in_memory(cx.background());
+            Connection::in_memory(cx.executor().clone());
         let (client2_conn_id, io_task3, client2_incoming) =
-            client2.add_test_connection(client2_to_server_conn, cx.background());
+            client2.add_test_connection(client2_to_server_conn, cx.executor().clone());
         let (_, io_task4, server_incoming2) =
-            server.add_test_connection(server_to_client_2_conn, cx.background());
+            server.add_test_connection(server_to_client_2_conn, cx.executor().clone());
 
         executor.spawn(io_task1).detach();
         executor.spawn(io_task2).detach();
@@ -662,27 +662,27 @@ mod tests {
         }
     }
 
-    #[gpui::test(iterations = 50)]
+    #[gpui2::test(iterations = 50)]
     async fn test_order_of_response_and_incoming(cx: &mut TestAppContext) {
-        let executor = cx.foreground();
+        let executor = cx.executor();
         let server = Peer::new(0);
         let client = Peer::new(0);
 
         let (client_to_server_conn, server_to_client_conn, _kill) =
-            Connection::in_memory(cx.background());
+            Connection::in_memory(executor.clone());
         let (client_to_server_conn_id, io_task1, mut client_incoming) =
-            client.add_test_connection(client_to_server_conn, cx.background());
+            client.add_test_connection(client_to_server_conn, executor.clone());
+
         let (server_to_client_conn_id, io_task2, mut server_incoming) =
-            server.add_test_connection(server_to_client_conn, cx.background());
+            server.add_test_connection(server_to_client_conn, executor.clone());
 
         executor.spawn(io_task1).detach();
         executor.spawn(io_task2).detach();
 
         executor
             .spawn(async move {
-                let request = server_incoming
-                    .next()
-                    .await
+                let future = server_incoming.next().await;
+                let request = future
                     .unwrap()
                     .into_any()
                     .downcast::<TypedEnvelope<proto::Ping>>()
@@ -760,18 +760,18 @@ mod tests {
         );
     }
 
-    #[gpui::test(iterations = 50)]
+    #[gpui2::test(iterations = 50)]
     async fn test_dropping_request_before_completion(cx: &mut TestAppContext) {
-        let executor = cx.foreground();
+        let executor = cx.executor().clone();
         let server = Peer::new(0);
         let client = Peer::new(0);
 
         let (client_to_server_conn, server_to_client_conn, _kill) =
-            Connection::in_memory(cx.background());
+            Connection::in_memory(cx.executor().clone());
         let (client_to_server_conn_id, io_task1, mut client_incoming) =
-            client.add_test_connection(client_to_server_conn, cx.background());
+            client.add_test_connection(client_to_server_conn, cx.executor().clone());
         let (server_to_client_conn_id, io_task2, mut server_incoming) =
-            server.add_test_connection(server_to_client_conn, cx.background());
+            server.add_test_connection(server_to_client_conn, cx.executor().clone());
 
         executor.spawn(io_task1).detach();
         executor.spawn(io_task2).detach();
@@ -858,7 +858,7 @@ mod tests {
             .detach();
 
         // Allow the request to make some progress before dropping it.
-        cx.background().simulate_random_delay().await;
+        cx.executor().simulate_random_delay().await;
         drop(request1_task);
 
         request2_task.await;
@@ -872,15 +872,15 @@ mod tests {
         );
     }
 
-    #[gpui::test(iterations = 50)]
+    #[gpui2::test(iterations = 50)]
     async fn test_disconnect(cx: &mut TestAppContext) {
-        let executor = cx.foreground();
+        let executor = cx.executor();
 
-        let (client_conn, mut server_conn, _kill) = Connection::in_memory(cx.background());
+        let (client_conn, mut server_conn, _kill) = Connection::in_memory(executor.clone());
 
         let client = Peer::new(0);
         let (connection_id, io_handler, mut incoming) =
-            client.add_test_connection(client_conn, cx.background());
+            client.add_test_connection(client_conn, executor.clone());
 
         let (io_ended_tx, io_ended_rx) = oneshot::channel();
         executor
@@ -908,14 +908,14 @@ mod tests {
             .is_err());
     }
 
-    #[gpui::test(iterations = 50)]
+    #[gpui2::test(iterations = 50)]
     async fn test_io_error(cx: &mut TestAppContext) {
-        let executor = cx.foreground();
-        let (client_conn, mut server_conn, _kill) = Connection::in_memory(cx.background());
+        let executor = cx.executor();
+        let (client_conn, mut server_conn, _kill) = Connection::in_memory(executor.clone());
 
         let client = Peer::new(0);
         let (connection_id, io_handler, mut incoming) =
-            client.add_test_connection(client_conn, cx.background());
+            client.add_test_connection(client_conn, executor.clone());
         executor.spawn(io_handler).detach();
         executor
             .spawn(async move { incoming.next().await })

crates/rpc2/src/proto.rs 🔗

@@ -616,7 +616,7 @@ pub fn split_worktree_update(
 mod tests {
     use super::*;
 
-    #[gpui::test]
+    #[gpui2::test]
     async fn test_buffer_size() {
         let (tx, rx) = futures::channel::mpsc::unbounded();
         let mut sink = MessageStream::new(tx.sink_map_err(|_| anyhow!("")));
@@ -648,7 +648,7 @@ mod tests {
         assert!(stream.encoding_buffer.capacity() <= MAX_BUFFER_LEN);
     }
 
-    #[gpui::test]
+    #[gpui2::test]
     fn test_converting_peer_id_from_and_to_u64() {
         let peer_id = PeerId {
             owner_id: 10,

crates/zed2/Cargo.toml 🔗

@@ -57,7 +57,7 @@ node_runtime = { path = "../node_runtime" }
 # project_symbols = { path = "../project_symbols" }
 # quick_action_bar = { path = "../quick_action_bar" }
 # recent_projects = { path = "../recent_projects" }
-rpc = { path = "../rpc" }
+rpc2 = { path = "../rpc2" }
 settings2 = { path = "../settings2" }
 feature_flags = { path = "../feature_flags" }
 sum_tree = { path = "../sum_tree" }