mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 08:47:57 +00:00
Try to fix flaky temp-base-path-work test (#13505)
* Try to fix flaky `temp-base-path-work` test The test is most of the time failing when checking if the database path was deleted. The assumption is that it takes a little bit more time by the OS to actually clean up the temp path under high load. The pr tries to fix this by checking multiple times if the path was deleted. Besides that it also ensures that the tests that require the benchmark feature don't fail when compiled without the feature. * ".git/.scripts/commands/fmt/fmt.sh" * Capture signals earlier * Rewrite tests to let them having one big timeout * Remove unneeded dep * Update bin/node/cli/tests/common.rs Co-authored-by: Koute <koute@users.noreply.github.com> * Review feedback * Update bin/node/cli/tests/common.rs Co-authored-by: Anton <anton.kalyaev@gmail.com> --------- Co-authored-by: command-bot <> Co-authored-by: Koute <koute@users.noreply.github.com> Co-authored-by: Anton <anton.kalyaev@gmail.com>
This commit is contained in:
@@ -197,10 +197,15 @@ pub trait SubstrateCli: Sized {
|
||||
command: &T,
|
||||
) -> error::Result<Runner<Self>> {
|
||||
let tokio_runtime = build_runtime()?;
|
||||
|
||||
// `capture` needs to be called in a tokio context.
|
||||
// Also capture them as early as possible.
|
||||
let signals = tokio_runtime.block_on(async { Signals::capture() })?;
|
||||
|
||||
let config = command.create_configuration(self, tokio_runtime.handle().clone())?;
|
||||
|
||||
command.init(&Self::support_url(), &Self::impl_version(), |_, _| {}, &config)?;
|
||||
Runner::new(config, tokio_runtime)
|
||||
Runner::new(config, tokio_runtime, signals)
|
||||
}
|
||||
|
||||
/// Create a runner for the command provided in argument. The `logger_hook` can be used to setup
|
||||
@@ -231,10 +236,15 @@ pub trait SubstrateCli: Sized {
|
||||
F: FnOnce(&mut LoggerBuilder, &Configuration),
|
||||
{
|
||||
let tokio_runtime = build_runtime()?;
|
||||
|
||||
// `capture` needs to be called in a tokio context.
|
||||
// Also capture them as early as possible.
|
||||
let signals = tokio_runtime.block_on(async { Signals::capture() })?;
|
||||
|
||||
let config = command.create_configuration(self, tokio_runtime.handle().clone())?;
|
||||
|
||||
command.init(&Self::support_url(), &Self::impl_version(), logger_hook, &config)?;
|
||||
Runner::new(config, tokio_runtime)
|
||||
Runner::new(config, tokio_runtime, signals)
|
||||
}
|
||||
/// Native runtime version.
|
||||
fn native_runtime_version(chain_spec: &Box<dyn ChainSpec>) -> &'static RuntimeVersion;
|
||||
|
||||
@@ -18,54 +18,72 @@
|
||||
|
||||
use crate::{error::Error as CliError, Result, SubstrateCli};
|
||||
use chrono::prelude::*;
|
||||
use futures::{future, future::FutureExt, pin_mut, select, Future};
|
||||
use futures::{
|
||||
future::{self, BoxFuture, FutureExt},
|
||||
pin_mut, select, Future,
|
||||
};
|
||||
use log::info;
|
||||
use sc_service::{Configuration, Error as ServiceError, TaskManager};
|
||||
use sc_utils::metrics::{TOKIO_THREADS_ALIVE, TOKIO_THREADS_TOTAL};
|
||||
use std::{marker::PhantomData, time::Duration};
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
async fn main<F, E>(func: F) -> std::result::Result<(), E>
|
||||
where
|
||||
F: Future<Output = std::result::Result<(), E>> + future::FusedFuture,
|
||||
E: std::error::Error + Send + Sync + 'static + From<ServiceError>,
|
||||
{
|
||||
use tokio::signal::unix::{signal, SignalKind};
|
||||
/// Abstraction over OS signals to handle the shutdown of the node smoothly.
|
||||
///
|
||||
/// On `unix` this represents `SigInt` and `SigTerm`.
|
||||
pub struct Signals(BoxFuture<'static, ()>);
|
||||
|
||||
let mut stream_int = signal(SignalKind::interrupt()).map_err(ServiceError::Io)?;
|
||||
let mut stream_term = signal(SignalKind::terminate()).map_err(ServiceError::Io)?;
|
||||
impl Signals {
|
||||
/// Capture the relevant signals to handle shutdown of the node smoothly.
|
||||
///
|
||||
/// Needs to be called in a Tokio context to have access to the tokio reactor.
|
||||
#[cfg(target_family = "unix")]
|
||||
pub fn capture() -> std::result::Result<Self, ServiceError> {
|
||||
use tokio::signal::unix::{signal, SignalKind};
|
||||
|
||||
let t1 = stream_int.recv().fuse();
|
||||
let t2 = stream_term.recv().fuse();
|
||||
let t3 = func;
|
||||
let mut stream_int = signal(SignalKind::interrupt()).map_err(ServiceError::Io)?;
|
||||
let mut stream_term = signal(SignalKind::terminate()).map_err(ServiceError::Io)?;
|
||||
|
||||
pin_mut!(t1, t2, t3);
|
||||
|
||||
select! {
|
||||
_ = t1 => {},
|
||||
_ = t2 => {},
|
||||
res = t3 => res?,
|
||||
Ok(Signals(
|
||||
async move {
|
||||
future::select(stream_int.recv().boxed(), stream_term.recv().boxed()).await;
|
||||
}
|
||||
.boxed(),
|
||||
))
|
||||
}
|
||||
|
||||
Ok(())
|
||||
/// Capture the relevant signals to handle shutdown of the node smoothly.
|
||||
///
|
||||
/// Needs to be called in a Tokio context to have access to the tokio reactor.
|
||||
#[cfg(not(unix))]
|
||||
pub fn capture() -> std::result::Result<Self, ServiceError> {
|
||||
use tokio::signal::ctrl_c;
|
||||
|
||||
Ok(Signals(
|
||||
async move {
|
||||
let _ = ctrl_c().await;
|
||||
}
|
||||
.boxed(),
|
||||
))
|
||||
}
|
||||
|
||||
/// A dummy signal that never returns.
|
||||
pub fn dummy() -> Self {
|
||||
Self(future::pending().boxed())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
async fn main<F, E>(func: F) -> std::result::Result<(), E>
|
||||
async fn main<F, E>(func: F, signals: impl Future<Output = ()>) -> std::result::Result<(), E>
|
||||
where
|
||||
F: Future<Output = std::result::Result<(), E>> + future::FusedFuture,
|
||||
E: std::error::Error + Send + Sync + 'static + From<ServiceError>,
|
||||
E: std::error::Error + Send + Sync + 'static,
|
||||
{
|
||||
use tokio::signal::ctrl_c;
|
||||
let signals = signals.fuse();
|
||||
|
||||
let t1 = ctrl_c().fuse();
|
||||
let t2 = func;
|
||||
|
||||
pin_mut!(t1, t2);
|
||||
pin_mut!(func, signals);
|
||||
|
||||
select! {
|
||||
_ = t1 => {},
|
||||
res = t2 => res?,
|
||||
_ = signals => {},
|
||||
res = func => res?,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -89,6 +107,7 @@ fn run_until_exit<F, E>(
|
||||
tokio_runtime: tokio::runtime::Runtime,
|
||||
future: F,
|
||||
task_manager: TaskManager,
|
||||
signals: impl Future<Output = ()>,
|
||||
) -> std::result::Result<(), E>
|
||||
where
|
||||
F: Future<Output = std::result::Result<(), E>> + future::Future,
|
||||
@@ -97,7 +116,7 @@ where
|
||||
let f = future.fuse();
|
||||
pin_mut!(f);
|
||||
|
||||
tokio_runtime.block_on(main(f))?;
|
||||
tokio_runtime.block_on(main(f, signals))?;
|
||||
drop(task_manager);
|
||||
|
||||
Ok(())
|
||||
@@ -107,13 +126,18 @@ where
|
||||
pub struct Runner<C: SubstrateCli> {
|
||||
config: Configuration,
|
||||
tokio_runtime: tokio::runtime::Runtime,
|
||||
signals: Signals,
|
||||
phantom: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C: SubstrateCli> Runner<C> {
|
||||
/// Create a new runtime with the command provided in argument
|
||||
pub fn new(config: Configuration, tokio_runtime: tokio::runtime::Runtime) -> Result<Runner<C>> {
|
||||
Ok(Runner { config, tokio_runtime, phantom: PhantomData })
|
||||
pub fn new(
|
||||
config: Configuration,
|
||||
tokio_runtime: tokio::runtime::Runtime,
|
||||
signals: Signals,
|
||||
) -> Result<Runner<C>> {
|
||||
Ok(Runner { config, tokio_runtime, signals, phantom: PhantomData })
|
||||
}
|
||||
|
||||
/// Log information about the node itself.
|
||||
@@ -147,7 +171,7 @@ impl<C: SubstrateCli> Runner<C> {
|
||||
self.print_node_infos();
|
||||
|
||||
let mut task_manager = self.tokio_runtime.block_on(initialize(self.config))?;
|
||||
let res = self.tokio_runtime.block_on(main(task_manager.future().fuse()));
|
||||
let res = self.tokio_runtime.block_on(main(task_manager.future().fuse(), self.signals.0));
|
||||
// We need to drop the task manager here to inform all tasks that they should shut down.
|
||||
//
|
||||
// This is important to be done before we instruct the tokio runtime to shutdown. Otherwise
|
||||
@@ -210,7 +234,7 @@ impl<C: SubstrateCli> Runner<C> {
|
||||
E: std::error::Error + Send + Sync + 'static + From<ServiceError> + From<CliError>,
|
||||
{
|
||||
let (future, task_manager) = runner(self.config)?;
|
||||
run_until_exit::<_, E>(self.tokio_runtime, future, task_manager)
|
||||
run_until_exit::<_, E>(self.tokio_runtime, future, task_manager, self.signals.0)
|
||||
}
|
||||
|
||||
/// Get an immutable reference to the node Configuration
|
||||
@@ -369,6 +393,7 @@ mod tests {
|
||||
runtime_cache_size: 2,
|
||||
},
|
||||
runtime,
|
||||
Signals::dummy(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user