diff --git a/testing/integration-tests/src/utils/node_proc.rs b/testing/integration-tests/src/utils/node_proc.rs index 65ce790b3f..b2c0197d5f 100644 --- a/testing/integration-tests/src/utils/node_proc.rs +++ b/testing/integration-tests/src/utils/node_proc.rs @@ -11,10 +11,32 @@ use subxt::{ Config, OnlineClient, }; +// The URL that we'll connect to for our tests comes from SUBXT_TEXT_HOST env var, +// defaulting to localhost if not provided. If the env var is set, we won't spawn +// a binary. Note though that some tests expect and modify a fresh state, and so will +// fail. Fo a similar reason wyou should also use `--test-threads 1` when running tests +// to reduce the number of conflicts between state altering tests. +const URL_ENV_VAR: &str = "SUBXT_TEST_URL"; +fn is_url_provided() -> bool { + std::env::var(URL_ENV_VAR).is_ok() +} +fn get_url(port: Option) -> String { + match (std::env::var(URL_ENV_VAR).ok(), port) { + (Some(host), None) => host, + (None, Some(port)) => format!("ws://127.0.0.1:{port}"), + (Some(_), Some(_)) => { + panic!("{URL_ENV_VAR} and port provided: only one or the other should exist") + } + (None, None) => { + panic!("No {URL_ENV_VAR} or port was provided, so we don't know where to connect to") + } + } +} + /// Spawn a local substrate node for testing subxt. pub struct TestNodeProcess { // Keep a handle to the node; once it's dropped the node is killed. - proc: SubstrateNode, + proc: Option, // Lazily construct these when asked for. unstable_client: RefCell>>, @@ -50,7 +72,7 @@ where /// Hand back an RPC client connected to the test node. pub async fn rpc_client(&self) -> rpc::RpcClient { - let url = format!("ws://127.0.0.1:{}", self.proc.ws_port()); + let url = get_url(self.proc.as_ref().map(|p| p.ws_port())); rpc::RpcClient::from_url(url) .await .expect("Unable to connect RPC client to test node") @@ -124,17 +146,21 @@ impl TestNodeProcessBuilder { where R: Config, { - let mut node_builder = SubstrateNode::builder(); + // Only spawn a process if a URL to target wasn't provided as an env var. + let proc = if !is_url_provided() { + let mut node_builder = SubstrateNode::builder(); + node_builder.binary_paths(&self.node_paths); - node_builder.binary_paths(&self.node_paths); + if let Some(authority) = &self.authority { + node_builder.arg(authority.to_lowercase()); + } - if let Some(authority) = &self.authority { - node_builder.arg(authority.to_lowercase()); - } + Some(node_builder.spawn().map_err(|e| e.to_string())?) + } else { + None + }; - // Spawn the node and retrieve a URL to it: - let proc = node_builder.spawn().map_err(|e| e.to_string())?; - let ws_url = format!("ws://127.0.0.1:{}", proc.ws_port()); + let ws_url = get_url(proc.as_ref().map(|p| p.ws_port())); let rpc_client = build_rpc_client(&ws_url) .await .map_err(|e| format!("Failed to connect to node at {ws_url}: {e}"))?; @@ -173,7 +199,7 @@ impl TestNodeProcessBuilder { } async fn build_rpc_client(ws_url: &str) -> Result { - let rpc_client = rpc::RpcClient::from_url(ws_url) + let rpc_client = rpc::RpcClient::from_insecure_url(ws_url) .await .map_err(|e| format!("Cannot construct RPC client: {e}"))?; @@ -217,10 +243,18 @@ async fn build_unstable_client( } #[cfg(lightclient)] -async fn build_light_client(proc: &SubstrateNode) -> Result, String> { +async fn build_light_client( + maybe_proc: &Option, +) -> Result, String> { use subxt::lightclient::{ChainConfig, LightClient}; - // RPC endpoint. + let proc = if let Some(proc) = maybe_proc { + proc + } else { + return Err("Cannot build light client: no substrate node is running (you can't start a light client when pointing to an external node)".into()); + }; + + // RPC endpoint. Only localhost works. let ws_url = format!("ws://127.0.0.1:{}", proc.ws_port()); // Wait for a few blocks to be produced using the subxt client.