Make AllSubsystems usage easier in tests (#1794)

* Make `AllSubsystems` usage easier in tests

This makes the usage of `AllSubsystems` easier in tests by introducing
new methods.

- `dummy` initializes `AllSubsystems` with all systems set to dummy
- `replace_*` to replace any subsystem

Besides that this pr adds a `ForwardSubsystem` that is also useful for
tests. This subsystem will forward all incoming messages to the given channel.

* Update node/overseer/src/lib.rs

Co-authored-by: Andronik Ordian <write@reusable.software>

* Update node/subsystem/src/lib.rs

Co-authored-by: Andronik Ordian <write@reusable.software>

* Update node/subsystem/src/lib.rs

Co-authored-by: Andronik Ordian <write@reusable.software>

* Move ForwardSubsystem and add a test

* Break some lines

Co-authored-by: Andronik Ordian <write@reusable.software>
This commit is contained in:
Bastian Köcher
2020-10-08 11:27:19 +02:00
committed by GitHub
parent fc1153681e
commit f2d7b6f5ac
6 changed files with 505 additions and 135 deletions
+1
View File
@@ -5060,6 +5060,7 @@ dependencies = [
"polkadot-node-primitives", "polkadot-node-primitives",
"polkadot-node-subsystem", "polkadot-node-subsystem",
"polkadot-node-subsystem-util", "polkadot-node-subsystem-util",
"polkadot-overseer",
"polkadot-primitives", "polkadot-primitives",
"polkadot-statement-table", "polkadot-statement-table",
"sc-network", "sc-network",
@@ -30,10 +30,7 @@ use kv_log_macro as log;
use polkadot_primitives::v1::{BlockData, PoV}; use polkadot_primitives::v1::{BlockData, PoV};
use polkadot_overseer::{Overseer, AllSubsystems}; use polkadot_overseer::{Overseer, AllSubsystems};
use polkadot_subsystem::{ use polkadot_subsystem::{Subsystem, SubsystemContext, SpawnedSubsystem, FromOverseer};
Subsystem, SubsystemContext, DummySubsystem,
SpawnedSubsystem, FromOverseer,
};
use polkadot_subsystem::messages::{ use polkadot_subsystem::messages::{
CandidateValidationMessage, CandidateBackingMessage, AllMessages, CandidateValidationMessage, CandidateBackingMessage, AllMessages,
}; };
@@ -141,23 +138,9 @@ fn main() {
Delay::new(Duration::from_secs(1)).await; Delay::new(Duration::from_secs(1)).await;
}); });
let all_subsystems = AllSubsystems { let all_subsystems = AllSubsystems::<()>::dummy()
candidate_validation: Subsystem2, .replace_candidate_validation(Subsystem2)
candidate_backing: Subsystem1, .replace_candidate_backing(Subsystem1);
candidate_selection: DummySubsystem,
statement_distribution: DummySubsystem,
availability_distribution: DummySubsystem,
bitfield_signing: DummySubsystem,
bitfield_distribution: DummySubsystem,
provisioner: DummySubsystem,
pov_distribution: DummySubsystem,
runtime_api: DummySubsystem,
availability_store: DummySubsystem,
network_bridge: DummySubsystem,
chain_api: DummySubsystem,
collation_generation: DummySubsystem,
collator_protocol: DummySubsystem,
};
let (overseer, _handler) = Overseer::new( let (overseer, _handler) = Overseer::new(
vec![], vec![],
all_subsystems, all_subsystems,
+436 -112
View File
@@ -83,7 +83,7 @@ use polkadot_subsystem::messages::{
}; };
pub use polkadot_subsystem::{ pub use polkadot_subsystem::{
Subsystem, SubsystemContext, OverseerSignal, FromOverseer, SubsystemError, SubsystemResult, Subsystem, SubsystemContext, OverseerSignal, FromOverseer, SubsystemError, SubsystemResult,
SpawnedSubsystem, ActiveLeavesUpdate, SpawnedSubsystem, ActiveLeavesUpdate, DummySubsystem,
}; };
use polkadot_node_subsystem_util::metrics::{self, prometheus}; use polkadot_node_subsystem_util::metrics::{self, prometheus};
use polkadot_node_primitives::SpawnNamed; use polkadot_node_primitives::SpawnNamed;
@@ -348,7 +348,7 @@ struct OverseenSubsystem<M> {
} }
/// The `Overseer` itself. /// The `Overseer` itself.
pub struct Overseer<S: SpawnNamed> { pub struct Overseer<S> {
/// A candidate validation subsystem. /// A candidate validation subsystem.
candidate_validation_subsystem: OverseenSubsystem<CandidateValidationMessage>, candidate_validation_subsystem: OverseenSubsystem<CandidateValidationMessage>,
@@ -429,10 +429,10 @@ pub struct Overseer<S: SpawnNamed> {
/// Each [`Subsystem`] is supposed to implement some interface that is generic over /// Each [`Subsystem`] is supposed to implement some interface that is generic over
/// message type that is specific to this [`Subsystem`]. At the moment not all /// message type that is specific to this [`Subsystem`]. At the moment not all
/// subsystems are implemented and the rest can be mocked with the [`DummySubsystem`]. /// subsystems are implemented and the rest can be mocked with the [`DummySubsystem`].
/// pub struct AllSubsystems<
/// [`Subsystem`]: trait.Subsystem.html CV = (), CB = (), CS = (), SD = (), AD = (), BS = (), BD = (), P = (),
/// [`DummySubsystem`]: struct.DummySubsystem.html PoVD = (), RA = (), AS = (), NB = (), CA = (), CG = (), CP = ()
pub struct AllSubsystems<CV, CB, CS, SD, AD, BS, BD, P, PoVD, RA, AS, NB, CA, CG, CP> { > {
/// A candidate validation subsystem. /// A candidate validation subsystem.
pub candidate_validation: CV, pub candidate_validation: CV,
/// A candidate backing subsystem. /// A candidate backing subsystem.
@@ -465,6 +465,418 @@ pub struct AllSubsystems<CV, CB, CS, SD, AD, BS, BD, P, PoVD, RA, AS, NB, CA, CG
pub collator_protocol: CP, pub collator_protocol: CP,
} }
impl<CV, CB, CS, SD, AD, BS, BD, P, PoVD, RA, AS, NB, CA, CG, CP>
AllSubsystems<CV, CB, CS, SD, AD, BS, BD, P, PoVD, RA, AS, NB, CA, CG, CP>
{
/// Create a new instance of [`AllSubsystems`].
///
/// Each subsystem is set to [`DummySystem`].
///
///# Note
///
/// Because of a bug in rustc it is required that when calling this function,
/// you provide a "random" type for the first generic parameter:
///
/// ```
/// polkadot_overseer::AllSubsystems::<()>::dummy();
/// ```
pub fn dummy() -> AllSubsystems<
DummySubsystem,
DummySubsystem,
DummySubsystem,
DummySubsystem,
DummySubsystem,
DummySubsystem,
DummySubsystem,
DummySubsystem,
DummySubsystem,
DummySubsystem,
DummySubsystem,
DummySubsystem,
DummySubsystem,
DummySubsystem,
DummySubsystem
> {
AllSubsystems {
candidate_validation: DummySubsystem,
candidate_backing: DummySubsystem,
candidate_selection: DummySubsystem,
statement_distribution: DummySubsystem,
availability_distribution: DummySubsystem,
bitfield_signing: DummySubsystem,
bitfield_distribution: DummySubsystem,
provisioner: DummySubsystem,
pov_distribution: DummySubsystem,
runtime_api: DummySubsystem,
availability_store: DummySubsystem,
network_bridge: DummySubsystem,
chain_api: DummySubsystem,
collation_generation: DummySubsystem,
collator_protocol: DummySubsystem,
}
}
/// Replace the `candidate_validation` instance in `self`.
pub fn replace_candidate_validation<NEW>(
self,
candidate_validation: NEW,
) -> AllSubsystems<NEW, CB, CS, SD, AD, BS, BD, P, PoVD, RA, AS, NB, CA, CG, CP> {
AllSubsystems {
candidate_validation,
candidate_backing: self.candidate_backing,
candidate_selection: self.candidate_selection,
statement_distribution: self.statement_distribution,
availability_distribution: self.availability_distribution,
bitfield_signing: self.bitfield_signing,
bitfield_distribution: self.bitfield_distribution,
provisioner: self.provisioner,
pov_distribution: self.pov_distribution,
runtime_api: self.runtime_api,
availability_store: self.availability_store,
network_bridge: self.network_bridge,
chain_api: self.chain_api,
collation_generation: self.collation_generation,
collator_protocol: self.collator_protocol,
}
}
/// Replace the `candidate_backing` instance in `self`.
pub fn replace_candidate_backing<NEW>(
self,
candidate_backing: NEW,
) -> AllSubsystems<CV, NEW, CS, SD, AD, BS, BD, P, PoVD, RA, AS, NB, CA, CG, CP> {
AllSubsystems {
candidate_validation: self.candidate_validation,
candidate_backing,
candidate_selection: self.candidate_selection,
statement_distribution: self.statement_distribution,
availability_distribution: self.availability_distribution,
bitfield_signing: self.bitfield_signing,
bitfield_distribution: self.bitfield_distribution,
provisioner: self.provisioner,
pov_distribution: self.pov_distribution,
runtime_api: self.runtime_api,
availability_store: self.availability_store,
network_bridge: self.network_bridge,
chain_api: self.chain_api,
collation_generation: self.collation_generation,
collator_protocol: self.collator_protocol,
}
}
/// Replace the `candidate_selection` instance in `self`.
pub fn replace_candidate_selection<NEW>(
self,
candidate_selection: NEW,
) -> AllSubsystems<CV, CB, NEW, SD, AD, BS, BD, P, PoVD, RA, AS, NB, CA, CG, CP> {
AllSubsystems {
candidate_validation: self.candidate_validation,
candidate_backing: self.candidate_backing,
candidate_selection,
statement_distribution: self.statement_distribution,
availability_distribution: self.availability_distribution,
bitfield_signing: self.bitfield_signing,
bitfield_distribution: self.bitfield_distribution,
provisioner: self.provisioner,
pov_distribution: self.pov_distribution,
runtime_api: self.runtime_api,
availability_store: self.availability_store,
network_bridge: self.network_bridge,
chain_api: self.chain_api,
collation_generation: self.collation_generation,
collator_protocol: self.collator_protocol,
}
}
/// Replace the `statement_distribution` instance in `self`.
pub fn replace_statement_distribution<NEW>(
self,
statement_distribution: NEW,
) -> AllSubsystems<CV, CB, CS, NEW, AD, BS, BD, P, PoVD, RA, AS, NB, CA, CG, CP> {
AllSubsystems {
candidate_validation: self.candidate_validation,
candidate_backing: self.candidate_backing,
candidate_selection: self.candidate_selection,
statement_distribution,
availability_distribution: self.availability_distribution,
bitfield_signing: self.bitfield_signing,
bitfield_distribution: self.bitfield_distribution,
provisioner: self.provisioner,
pov_distribution: self.pov_distribution,
runtime_api: self.runtime_api,
availability_store: self.availability_store,
network_bridge: self.network_bridge,
chain_api: self.chain_api,
collation_generation: self.collation_generation,
collator_protocol: self.collator_protocol,
}
}
/// Replace the `availability_distribution` instance in `self`.
pub fn replace_availability_distribution<NEW>(
self,
availability_distribution: NEW,
) -> AllSubsystems<CV, CB, CS, SD, NEW, BS, BD, P, PoVD, RA, AS, NB, CA, CG, CP> {
AllSubsystems {
candidate_validation: self.candidate_validation,
candidate_backing: self.candidate_backing,
candidate_selection: self.candidate_selection,
statement_distribution: self.statement_distribution,
availability_distribution,
bitfield_signing: self.bitfield_signing,
bitfield_distribution: self.bitfield_distribution,
provisioner: self.provisioner,
pov_distribution: self.pov_distribution,
runtime_api: self.runtime_api,
availability_store: self.availability_store,
network_bridge: self.network_bridge,
chain_api: self.chain_api,
collation_generation: self.collation_generation,
collator_protocol: self.collator_protocol,
}
}
/// Replace the `bitfield_signing` instance in `self`.
pub fn replace_bitfield_signing<NEW>(
self,
bitfield_signing: NEW,
) -> AllSubsystems<CV, CB, CS, SD, AD, NEW, BD, P, PoVD, RA, AS, NB, CA, CG, CP> {
AllSubsystems {
candidate_validation: self.candidate_validation,
candidate_backing: self.candidate_backing,
candidate_selection: self.candidate_selection,
statement_distribution: self.statement_distribution,
availability_distribution: self.availability_distribution,
bitfield_signing,
bitfield_distribution: self.bitfield_distribution,
provisioner: self.provisioner,
pov_distribution: self.pov_distribution,
runtime_api: self.runtime_api,
availability_store: self.availability_store,
network_bridge: self.network_bridge,
chain_api: self.chain_api,
collation_generation: self.collation_generation,
collator_protocol: self.collator_protocol,
}
}
/// Replace the `bitfield_distribution` instance in `self`.
pub fn replace_bitfield_distribution<NEW>(
self,
bitfield_distribution: NEW,
) -> AllSubsystems<CV, CB, CS, SD, AD, BS, NEW, P, PoVD, RA, AS, NB, CA, CG, CP> {
AllSubsystems {
candidate_validation: self.candidate_validation,
candidate_backing: self.candidate_backing,
candidate_selection: self.candidate_selection,
statement_distribution: self.statement_distribution,
availability_distribution: self.availability_distribution,
bitfield_signing: self.bitfield_signing,
bitfield_distribution,
provisioner: self.provisioner,
pov_distribution: self.pov_distribution,
runtime_api: self.runtime_api,
availability_store: self.availability_store,
network_bridge: self.network_bridge,
chain_api: self.chain_api,
collation_generation: self.collation_generation,
collator_protocol: self.collator_protocol,
}
}
/// Replace the `provisioner` instance in `self`.
pub fn replace_provisioner<NEW>(
self,
provisioner: NEW,
) -> AllSubsystems<CV, CB, CS, SD, AD, BS, BD, NEW, PoVD, RA, AS, NB, CA, CG, CP> {
AllSubsystems {
candidate_validation: self.candidate_validation,
candidate_backing: self.candidate_backing,
candidate_selection: self.candidate_selection,
statement_distribution: self.statement_distribution,
availability_distribution: self.availability_distribution,
bitfield_signing: self.bitfield_signing,
bitfield_distribution: self.bitfield_distribution,
provisioner,
pov_distribution: self.pov_distribution,
runtime_api: self.runtime_api,
availability_store: self.availability_store,
network_bridge: self.network_bridge,
chain_api: self.chain_api,
collation_generation: self.collation_generation,
collator_protocol: self.collator_protocol,
}
}
/// Replace the `pov_distribution` instance in `self`.
pub fn replace_pov_distribution<NEW>(
self,
pov_distribution: NEW,
) -> AllSubsystems<CV, CB, CS, SD, AD, BS, BD, P, NEW, RA, AS, NB, CA, CG, CP> {
AllSubsystems {
candidate_validation: self.candidate_validation,
candidate_backing: self.candidate_backing,
candidate_selection: self.candidate_selection,
statement_distribution: self.statement_distribution,
availability_distribution: self.availability_distribution,
bitfield_signing: self.bitfield_signing,
bitfield_distribution: self.bitfield_distribution,
provisioner: self.provisioner,
pov_distribution,
runtime_api: self.runtime_api,
availability_store: self.availability_store,
network_bridge: self.network_bridge,
chain_api: self.chain_api,
collation_generation: self.collation_generation,
collator_protocol: self.collator_protocol,
}
}
/// Replace the `runtime_api` instance in `self`.
pub fn replace_runtime_api<NEW>(
self,
runtime_api: NEW,
) -> AllSubsystems<CV, CB, CS, SD, AD, BS, BD, P, PoVD, NEW, AS, NB, CA, CG, CP> {
AllSubsystems {
candidate_validation: self.candidate_validation,
candidate_backing: self.candidate_backing,
candidate_selection: self.candidate_selection,
statement_distribution: self.statement_distribution,
availability_distribution: self.availability_distribution,
bitfield_signing: self.bitfield_signing,
bitfield_distribution: self.bitfield_distribution,
provisioner: self.provisioner,
pov_distribution: self.pov_distribution,
runtime_api,
availability_store: self.availability_store,
network_bridge: self.network_bridge,
chain_api: self.chain_api,
collation_generation: self.collation_generation,
collator_protocol: self.collator_protocol,
}
}
/// Replace the `availability_store` instance in `self`.
pub fn replace_availability_store<NEW>(
self,
availability_store: NEW,
) -> AllSubsystems<CV, CB, CS, SD, AD, BS, BD, P, PoVD, RA, NEW, NB, CA, CG, CP> {
AllSubsystems {
candidate_validation: self.candidate_validation,
candidate_backing: self.candidate_backing,
candidate_selection: self.candidate_selection,
statement_distribution: self.statement_distribution,
availability_distribution: self.availability_distribution,
bitfield_signing: self.bitfield_signing,
bitfield_distribution: self.bitfield_distribution,
provisioner: self.provisioner,
pov_distribution: self.pov_distribution,
runtime_api: self.runtime_api,
availability_store,
network_bridge: self.network_bridge,
chain_api: self.chain_api,
collation_generation: self.collation_generation,
collator_protocol: self.collator_protocol,
}
}
/// Replace the `network_bridge` instance in `self`.
pub fn replace_network_bridge<NEW>(
self,
network_bridge: NEW,
) -> AllSubsystems<CV, CB, CS, SD, AD, BS, BD, P, PoVD, RA, AS, NEW, CA, CG, CP> {
AllSubsystems {
candidate_validation: self.candidate_validation,
candidate_backing: self.candidate_backing,
candidate_selection: self.candidate_selection,
statement_distribution: self.statement_distribution,
availability_distribution: self.availability_distribution,
bitfield_signing: self.bitfield_signing,
bitfield_distribution: self.bitfield_distribution,
provisioner: self.provisioner,
pov_distribution: self.pov_distribution,
runtime_api: self.runtime_api,
availability_store: self.availability_store,
network_bridge,
chain_api: self.chain_api,
collation_generation: self.collation_generation,
collator_protocol: self.collator_protocol,
}
}
/// Replace the `chain_api` instance in `self`.
pub fn replace_chain_api<NEW>(
self,
chain_api: NEW,
) -> AllSubsystems<CV, CB, CS, SD, AD, BS, BD, P, PoVD, RA, AS, NB, NEW, CG, CP> {
AllSubsystems {
candidate_validation: self.candidate_validation,
candidate_backing: self.candidate_backing,
candidate_selection: self.candidate_selection,
statement_distribution: self.statement_distribution,
availability_distribution: self.availability_distribution,
bitfield_signing: self.bitfield_signing,
bitfield_distribution: self.bitfield_distribution,
provisioner: self.provisioner,
pov_distribution: self.pov_distribution,
runtime_api: self.runtime_api,
availability_store: self.availability_store,
network_bridge: self.network_bridge,
chain_api,
collation_generation: self.collation_generation,
collator_protocol: self.collator_protocol,
}
}
/// Replace the `collation_generation` instance in `self`.
pub fn replace_collation_generation<NEW>(
self,
collation_generation: NEW,
) -> AllSubsystems<CV, CB, CS, SD, AD, BS, BD, P, PoVD, RA, AS, NB, CA, NEW, CP> {
AllSubsystems {
candidate_validation: self.candidate_validation,
candidate_backing: self.candidate_backing,
candidate_selection: self.candidate_selection,
statement_distribution: self.statement_distribution,
availability_distribution: self.availability_distribution,
bitfield_signing: self.bitfield_signing,
bitfield_distribution: self.bitfield_distribution,
provisioner: self.provisioner,
pov_distribution: self.pov_distribution,
runtime_api: self.runtime_api,
availability_store: self.availability_store,
network_bridge: self.network_bridge,
chain_api: self.chain_api,
collation_generation,
collator_protocol: self.collator_protocol,
}
}
/// Replace the `collator_protocol` instance in `self`.
pub fn replace_collator_protocol<NEW>(
self,
collator_protocol: NEW,
) -> AllSubsystems<CV, CB, CS, SD, AD, BS, BD, P, PoVD, RA, AS, NB, CA, CG, NEW> {
AllSubsystems {
candidate_validation: self.candidate_validation,
candidate_backing: self.candidate_backing,
candidate_selection: self.candidate_selection,
statement_distribution: self.statement_distribution,
availability_distribution: self.availability_distribution,
bitfield_signing: self.bitfield_signing,
bitfield_distribution: self.bitfield_distribution,
provisioner: self.provisioner,
pov_distribution: self.pov_distribution,
runtime_api: self.runtime_api,
availability_store: self.availability_store,
network_bridge: self.network_bridge,
chain_api: self.chain_api,
collation_generation: self.collation_generation,
collator_protocol,
}
}
}
/// Overseer Prometheus metrics. /// Overseer Prometheus metrics.
#[derive(Clone)] #[derive(Clone)]
struct MetricsInner { struct MetricsInner {
@@ -591,23 +1003,7 @@ where
/// ///
/// # fn main() { executor::block_on(async move { /// # fn main() { executor::block_on(async move {
/// let spawner = sp_core::testing::TaskExecutor::new(); /// let spawner = sp_core::testing::TaskExecutor::new();
/// let all_subsystems = AllSubsystems { /// let all_subsystems = AllSubsystems::<()>::dummy().replace_candidate_validation(ValidationSubsystem);
/// candidate_validation: ValidationSubsystem,
/// candidate_backing: DummySubsystem,
/// candidate_selection: DummySubsystem,
/// statement_distribution: DummySubsystem,
/// availability_distribution: DummySubsystem,
/// bitfield_signing: DummySubsystem,
/// bitfield_distribution: DummySubsystem,
/// provisioner: DummySubsystem,
/// pov_distribution: DummySubsystem,
/// runtime_api: DummySubsystem,
/// availability_store: DummySubsystem,
/// network_bridge: DummySubsystem,
/// chain_api: DummySubsystem,
/// collation_generation: DummySubsystem,
/// collator_protocol: DummySubsystem,
/// };
/// let (overseer, _handler) = Overseer::new( /// let (overseer, _handler) = Overseer::new(
/// vec![], /// vec![],
/// all_subsystems, /// all_subsystems,
@@ -1228,7 +1624,6 @@ mod tests {
use futures::{executor, pin_mut, select, channel::mpsc, FutureExt}; use futures::{executor, pin_mut, select, channel::mpsc, FutureExt};
use polkadot_primitives::v1::{BlockData, CollatorPair, PoV}; use polkadot_primitives::v1::{BlockData, CollatorPair, PoV};
use polkadot_subsystem::DummySubsystem;
use polkadot_subsystem::messages::RuntimeApiRequest; use polkadot_subsystem::messages::RuntimeApiRequest;
use polkadot_node_primitives::{Collation, CollationGenerationConfig}; use polkadot_node_primitives::{Collation, CollationGenerationConfig};
use polkadot_node_network_protocol::{PeerId, ReputationChange, NetworkBridgeEvent}; use polkadot_node_network_protocol::{PeerId, ReputationChange, NetworkBridgeEvent};
@@ -1237,7 +1632,6 @@ mod tests {
use super::*; use super::*;
struct TestSubsystem1(mpsc::Sender<usize>); struct TestSubsystem1(mpsc::Sender<usize>);
impl<C> Subsystem<C> for TestSubsystem1 impl<C> Subsystem<C> for TestSubsystem1
@@ -1334,26 +1728,13 @@ mod tests {
let spawner = sp_core::testing::TaskExecutor::new(); let spawner = sp_core::testing::TaskExecutor::new();
executor::block_on(async move { executor::block_on(async move {
let (s1_tx, mut s1_rx) = mpsc::channel(64); let (s1_tx, mut s1_rx) = mpsc::channel::<usize>(64);
let (s2_tx, mut s2_rx) = mpsc::channel(64); let (s2_tx, mut s2_rx) = mpsc::channel::<usize>(64);
let all_subsystems = AllSubsystems::<()>::dummy()
.replace_candidate_validation(TestSubsystem1(s1_tx))
.replace_candidate_backing(TestSubsystem2(s2_tx));
let all_subsystems = AllSubsystems {
candidate_validation: TestSubsystem1(s1_tx),
candidate_backing: TestSubsystem2(s2_tx),
candidate_selection: DummySubsystem,
statement_distribution: DummySubsystem,
availability_distribution: DummySubsystem,
bitfield_signing: DummySubsystem,
bitfield_distribution: DummySubsystem,
provisioner: DummySubsystem,
pov_distribution: DummySubsystem,
runtime_api: DummySubsystem,
availability_store: DummySubsystem,
network_bridge: DummySubsystem,
chain_api: DummySubsystem,
collation_generation: DummySubsystem,
collator_protocol: DummySubsystem,
};
let (overseer, mut handler) = Overseer::new( let (overseer, mut handler) = Overseer::new(
vec![], vec![],
all_subsystems, all_subsystems,
@@ -1421,23 +1802,7 @@ mod tests {
number: 3, number: 3,
}; };
let all_subsystems = AllSubsystems { let all_subsystems = AllSubsystems::<()>::dummy();
collation_generation: DummySubsystem,
candidate_validation: DummySubsystem,
candidate_backing: DummySubsystem,
candidate_selection: DummySubsystem,
collator_protocol: DummySubsystem,
statement_distribution: DummySubsystem,
availability_distribution: DummySubsystem,
bitfield_signing: DummySubsystem,
bitfield_distribution: DummySubsystem,
provisioner: DummySubsystem,
pov_distribution: DummySubsystem,
runtime_api: DummySubsystem,
availability_store: DummySubsystem,
network_bridge: DummySubsystem,
chain_api: DummySubsystem,
};
let registry = prometheus::Registry::new(); let registry = prometheus::Registry::new();
let (overseer, mut handler) = Overseer::new( let (overseer, mut handler) = Overseer::new(
vec![first_block], vec![first_block],
@@ -1491,23 +1856,9 @@ mod tests {
executor::block_on(async move { executor::block_on(async move {
let (s1_tx, _) = mpsc::channel(64); let (s1_tx, _) = mpsc::channel(64);
let all_subsystems = AllSubsystems { let all_subsystems = AllSubsystems::<()>::dummy()
candidate_validation: TestSubsystem1(s1_tx), .replace_candidate_validation(TestSubsystem1(s1_tx))
candidate_backing: TestSubsystem4, .replace_candidate_backing(TestSubsystem4);
candidate_selection: DummySubsystem,
statement_distribution: DummySubsystem,
availability_distribution: DummySubsystem,
bitfield_signing: DummySubsystem,
bitfield_distribution: DummySubsystem,
provisioner: DummySubsystem,
pov_distribution: DummySubsystem,
runtime_api: DummySubsystem,
availability_store: DummySubsystem,
network_bridge: DummySubsystem,
chain_api: DummySubsystem,
collation_generation: DummySubsystem,
collator_protocol: DummySubsystem,
};
let (overseer, _handle) = Overseer::new( let (overseer, _handle) = Overseer::new(
vec![], vec![],
all_subsystems, all_subsystems,
@@ -1611,23 +1962,9 @@ mod tests {
let (tx_5, mut rx_5) = mpsc::channel(64); let (tx_5, mut rx_5) = mpsc::channel(64);
let (tx_6, mut rx_6) = mpsc::channel(64); let (tx_6, mut rx_6) = mpsc::channel(64);
let all_subsystems = AllSubsystems { let all_subsystems = AllSubsystems::<()>::dummy()
candidate_validation: TestSubsystem5(tx_5), .replace_candidate_validation(TestSubsystem5(tx_5))
candidate_backing: TestSubsystem6(tx_6), .replace_candidate_backing(TestSubsystem6(tx_6));
candidate_selection: DummySubsystem,
statement_distribution: DummySubsystem,
availability_distribution: DummySubsystem,
bitfield_signing: DummySubsystem,
bitfield_distribution: DummySubsystem,
provisioner: DummySubsystem,
pov_distribution: DummySubsystem,
runtime_api: DummySubsystem,
availability_store: DummySubsystem,
network_bridge: DummySubsystem,
chain_api: DummySubsystem,
collation_generation: DummySubsystem,
collator_protocol: DummySubsystem,
};
let (overseer, mut handler) = Overseer::new( let (overseer, mut handler) = Overseer::new(
vec![first_block], vec![first_block],
all_subsystems, all_subsystems,
@@ -1716,23 +2053,10 @@ mod tests {
let (tx_5, mut rx_5) = mpsc::channel(64); let (tx_5, mut rx_5) = mpsc::channel(64);
let (tx_6, mut rx_6) = mpsc::channel(64); let (tx_6, mut rx_6) = mpsc::channel(64);
let all_subsystems = AllSubsystems { let all_subsystems = AllSubsystems::<()>::dummy()
candidate_validation: TestSubsystem5(tx_5), .replace_candidate_validation(TestSubsystem5(tx_5))
candidate_backing: TestSubsystem6(tx_6), .replace_candidate_backing(TestSubsystem6(tx_6));
candidate_selection: DummySubsystem,
statement_distribution: DummySubsystem,
availability_distribution: DummySubsystem,
bitfield_signing: DummySubsystem,
bitfield_distribution: DummySubsystem,
provisioner: DummySubsystem,
pov_distribution: DummySubsystem,
runtime_api: DummySubsystem,
availability_store: DummySubsystem,
network_bridge: DummySubsystem,
chain_api: DummySubsystem,
collation_generation: DummySubsystem,
collator_protocol: DummySubsystem,
};
// start with two forks of different height. // start with two forks of different height.
let (overseer, mut handler) = Overseer::new( let (overseer, mut handler) = Overseer::new(
vec![first_block, second_block], vec![first_block, second_block],
@@ -22,3 +22,6 @@ polkadot-statement-table = { path = "../../statement-table" }
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
smallvec = "1.4.1" smallvec = "1.4.1"
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
[dev-dependencies]
polkadot-overseer = { path = "../overseer" }
@@ -17,7 +17,10 @@
//! Utilities for testing subsystems. //! Utilities for testing subsystems.
use polkadot_node_subsystem::messages::AllMessages; use polkadot_node_subsystem::messages::AllMessages;
use polkadot_node_subsystem::{FromOverseer, SubsystemContext, SubsystemError, SubsystemResult}; use polkadot_node_subsystem::{
FromOverseer, SubsystemContext, SubsystemError, SubsystemResult, Subsystem,
SpawnedSubsystem, OverseerSignal,
};
use polkadot_node_subsystem_util::TimeoutExt; use polkadot_node_subsystem_util::TimeoutExt;
use futures::channel::mpsc; use futures::channel::mpsc;
@@ -283,3 +286,59 @@ pub fn subsystem_test_harness<M, OverseerFactory, Overseer, TestFactory, Test>(
.expect("test timed out instead of completing") .expect("test timed out instead of completing")
}); });
} }
/// A forward subsystem that implements [`Subsystem`].
///
/// It forwards all communication from the overseer to the internal message
/// channel.
///
/// This subsystem is useful for testing functionality that interacts with the overseer.
pub struct ForwardSubsystem<Msg>(pub mpsc::Sender<Msg>);
impl<C: SubsystemContext<Message = Msg>, Msg: Send + 'static> Subsystem<C> for ForwardSubsystem<Msg> {
fn start(mut self, mut ctx: C) -> SpawnedSubsystem {
let future = Box::pin(async move {
loop {
match ctx.recv().await {
Ok(FromOverseer::Signal(OverseerSignal::Conclude)) => return,
Ok(FromOverseer::Communication { msg }) => {
let _ = self.0.send(msg).await;
},
Err(_) => return,
_ => (),
}
}
});
SpawnedSubsystem {
name: "forward-subsystem",
future,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use polkadot_overseer::{Overseer, AllSubsystems};
use futures::executor::block_on;
use polkadot_node_subsystem::messages::CandidateSelectionMessage;
#[test]
fn forward_subsystem_works() {
let spawner = sp_core::testing::TaskExecutor::new();
let (tx, rx) = mpsc::channel(2);
let all_subsystems = AllSubsystems::<()>::dummy().replace_candidate_selection(ForwardSubsystem(tx));
let (overseer, mut handler) = Overseer::new(
Vec::new(),
all_subsystems,
None,
spawner.clone(),
).unwrap();
spawner.spawn("overseer", overseer.run().then(|_| async { () }).boxed());
block_on(handler.send_msg(CandidateSelectionMessage::Invalid(Default::default(), Default::default()))).unwrap();
assert!(matches!(block_on(rx.into_future()).0.unwrap(), CandidateSelectionMessage::Invalid(_, _)));
}
}
+1 -1
View File
@@ -223,7 +223,7 @@ impl<C: SubsystemContext> Subsystem<C> for DummySubsystem {
}); });
SpawnedSubsystem { SpawnedSubsystem {
name: "DummySubsystem", name: "dummy-subsystem",
future, future,
} }
} }