diff --git a/Cargo.toml b/Cargo.toml index ff7fe5d..23ce984 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "chaindev" -version = "0.42.1" +version = "0.42.2" edition = "2021" authors = ["hui.fan@mail.ru"] description = "Powerful development and testing utils for blockchain developers." diff --git a/src/beacon_based/ddev/mod.rs b/src/beacon_based/ddev/mod.rs index b3ef61e..2c23734 100644 --- a/src/beacon_based/ddev/mod.rs +++ b/src/beacon_based/ddev/mod.rs @@ -160,6 +160,9 @@ where env.show(); }), Op::ShowAll => Env::::show_all().c(d!()), + Op::DebugFailedNodes => Env::::load_env_by_cfg(self) + .c(d!()) + .and_then(|env| env.debug_failed_nodes().c(d!())), Op::List => Env::::list_all().c(d!()), Op::HostPutFile { local_path, @@ -1047,6 +1050,59 @@ where Ok(()) } + fn debug_failed_nodes(&self) -> Result<()> { + let mut failed_cases = vec![]; + let mut errlist: Vec> = vec![]; + + for nodes in self + .meta + .nodes + .values() + .chain(self.meta.fuhrers.values()) + .collect::>() + .chunks(24) + { + thread::scope(|s| { + nodes + .iter() + .map(|n| { + let cmd = + self.node_cmdline_generator.cmd_cnt_running(n, &self.meta); + s.spawn(move || { + let process_cnt = Remote::from(&n.host) + .exec_cmd(&cmd) + .c(d!())? + .trim() + .parse::() + .c(d!())?; + if 3 > process_cnt { + Ok((n, true)) // failed status + } else { + Ok((n, false)) // well status + } + }) + }) + .collect::>() + .into_iter() + .flat_map(|hdr| hdr.join()) + .for_each(|ret| match ret { + Ok((n, failed)) => { + if failed { + failed_cases.push((n.id, n.host.host_id())); + } + } + Err(e) => { + errlist.push(e); + } + }); + }) + } + + println!("{}", serde_json::to_string_pretty(&failed_cases).c(d!())?); + + check_errlist!(errlist) + } + // List the names of all existing ENVs fn list_all() -> Result<()> { let list = Self::get_env_list().c(d!())?; @@ -1680,6 +1736,7 @@ where StopAll(bool /*force or not*/), Show, ShowAll, + DebugFailedNodes, List, HostPutFile { local_path: String, diff --git a/src/beacon_based/dev.rs b/src/beacon_based/dev.rs index 3cec0b8..4859b4d 100644 --- a/src/beacon_based/dev.rs +++ b/src/beacon_based/dev.rs @@ -160,6 +160,9 @@ where }) } Op::ShowAll => Env::::show_all().c(d!()), + Op::DebugFailedNodes => Env::::load_env_by_cfg(self) + .c(d!()) + .and_then(|env| env.debug_failed_nodes().c(d!())), Op::List => Env::::list_all().c(d!()), Op::Custom(custom_op) => custom_op.exec(&self.name).c(d!()), Op::Nil(_) => unreachable!(), @@ -595,6 +598,26 @@ where Ok(()) } + fn debug_failed_nodes(&self) -> Result<()> { + let mut failed_cases = vec![]; + + for n in self.meta.nodes.values().chain(self.meta.fuhrers.values()) { + let cmd = self.node_cmdline_generator.cmd_cnt_running(n, &self.meta); + let process_cnt = cmd::exec_output(&cmd) + .c(d!(&cmd))? + .trim() + .parse::() + .c(d!())?; + if 3 > process_cnt { + failed_cases.push(n.id); + } + } + + serde_json::to_string_pretty(&failed_cases) + .c(d!()) + .map(|s| println!("{s}")) + } + // list the names of all existing ENVs fn list_all() -> Result<()> { let list = Self::get_env_list().c(d!())?; @@ -1029,6 +1052,7 @@ where StopAll(bool /*force or not*/), Show, ShowAll, + DebugFailedNodes, List, Custom(Ops), Nil(Ports),