diff --git a/Cargo.lock b/Cargo.lock
index 529fbfc17315f..e255d11689eee 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -8077,6 +8077,7 @@ dependencies = [
"log 0.4.14",
"serde_json",
"substrate-prometheus-endpoint",
+ "tokio",
]
[[package]]
diff --git a/bin/node/cli/tests/running_the_node_and_interrupt.rs b/bin/node/cli/tests/running_the_node_and_interrupt.rs
index 7a945a30a4166..af19f9edd1b06 100644
--- a/bin/node/cli/tests/running_the_node_and_interrupt.rs
+++ b/bin/node/cli/tests/running_the_node_and_interrupt.rs
@@ -16,23 +16,24 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+#![cfg(unix)]
+
use assert_cmd::cargo::cargo_bin;
-use std::{convert::TryInto, process::Command, thread, time::Duration};
+use nix::{
+ sys::signal::{
+ kill,
+ Signal::{self, SIGINT, SIGTERM},
+ },
+ unistd::Pid,
+};
+use sc_service::Deref;
+use std::{convert::TryInto, ops::DerefMut, process::{Child, Command}, thread, time::Duration};
use tempfile::tempdir;
pub mod common;
#[test]
-#[cfg(unix)]
fn running_the_node_works_and_can_be_interrupted() {
- use nix::{
- sys::signal::{
- kill,
- Signal::{self, SIGINT, SIGTERM},
- },
- unistd::Pid,
- };
-
fn run_command_and_kill(signal: Signal) {
let base_path = tempdir().expect("could not create a temp dir");
let mut cmd = Command::new(cargo_bin("substrate"))
@@ -55,3 +56,57 @@ fn running_the_node_works_and_can_be_interrupted() {
run_command_and_kill(SIGINT);
run_command_and_kill(SIGTERM);
}
+
+struct KillChildOnDrop(Child);
+
+impl Drop for KillChildOnDrop {
+ fn drop(&mut self) {
+ let _ = self.0.kill();
+ }
+}
+
+impl Deref for KillChildOnDrop {
+ type Target = Child;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+impl DerefMut for KillChildOnDrop {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.0
+ }
+}
+
+#[test]
+fn running_two_nodes_with_the_same_ws_port_should_work() {
+ fn start_node() -> Child {
+ Command::new(cargo_bin("substrate"))
+ .args(&["--dev", "--tmp", "--ws-port=45789"])
+ .spawn()
+ .unwrap()
+ }
+
+ let mut first_node = KillChildOnDrop(start_node());
+ let mut second_node = KillChildOnDrop(start_node());
+
+ thread::sleep(Duration::from_secs(30));
+
+ assert!(first_node.try_wait().unwrap().is_none(), "The first node should still be running");
+ assert!(second_node.try_wait().unwrap().is_none(), "The second node should still be running");
+
+ kill(Pid::from_raw(first_node.id().try_into().unwrap()), SIGINT).unwrap();
+ kill(Pid::from_raw(second_node.id().try_into().unwrap()), SIGINT).unwrap();
+
+ assert_eq!(
+ common::wait_for(&mut first_node, 30).map(|x| x.success()),
+ Some(true),
+ "The first node must exit gracefully",
+ );
+ assert_eq!(
+ common::wait_for(&mut second_node, 30).map(|x| x.success()),
+ Some(true),
+ "The second node must exit gracefully",
+ );
+}
diff --git a/bin/node/test-runner-example/src/lib.rs b/bin/node/test-runner-example/src/lib.rs
index 6164372ab4f2f..e7fe1ee002423 100644
--- a/bin/node/test-runner-example/src/lib.rs
+++ b/bin/node/test-runner-example/src/lib.rs
@@ -88,18 +88,17 @@ mod tests {
use node_cli::chain_spec::development_config;
use sp_keyring::sr25519::Keyring::Alice;
use sp_runtime::{traits::IdentifyAccount, MultiSigner};
- use test_runner::{build_runtime, client_parts, task_executor, ConfigOrChainSpec, Node};
+ use test_runner::{build_runtime, client_parts, ConfigOrChainSpec, Node};
#[test]
fn test_runner() {
let tokio_runtime = build_runtime().unwrap();
- let task_executor = task_executor(tokio_runtime.handle().clone());
- let (rpc, task_manager, client, pool, command_sink, backend) = client_parts::<
- NodeTemplateChainInfo,
- >(
- ConfigOrChainSpec::ChainSpec(Box::new(development_config()), task_executor),
- )
- .unwrap();
+ let (rpc, task_manager, client, pool, command_sink, backend) =
+ client_parts::(ConfigOrChainSpec::ChainSpec(
+ Box::new(development_config()),
+ tokio_runtime.handle().clone(),
+ ))
+ .unwrap();
let node = Node::::new(
rpc,
task_manager,
diff --git a/client/cli/src/commands/run_cmd.rs b/client/cli/src/commands/run_cmd.rs
index fcc486297b21a..98f2090c6f446 100644
--- a/client/cli/src/commands/run_cmd.rs
+++ b/client/cli/src/commands/run_cmd.rs
@@ -127,10 +127,6 @@ pub struct RunCmd {
#[structopt(long = "ws-max-connections", value_name = "COUNT")]
pub ws_max_connections: Option,
- /// Size of the RPC HTTP server thread pool.
- #[structopt(long = "rpc-http-threads", value_name = "COUNT")]
- pub rpc_http_threads: Option,
-
/// Specify browser Origins allowed to access the HTTP & WS RPC servers.
///
/// A comma-separated list of origins (protocol://domain or special `null`
@@ -381,10 +377,6 @@ impl CliConfiguration for RunCmd {
Ok(self.ws_max_connections)
}
- fn rpc_http_threads(&self) -> Result