Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Update test-runner api #9302

Merged
merged 26 commits into from
Jul 12, 2021
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions bin/node/test-runner-example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ sc-informant = { version = "0.9.0", path = "../../../client/informant" }
sc-consensus = { version = "0.9.0", path = "../../../client/consensus/common" }

sp-runtime = { path = "../../../primitives/runtime", version = "3.0.0" }
sp-consensus = { path = "../../../primitives/consensus/common", version = "0.9.0" }
sp-keyring = { version = "3.0.0", path = "../../../primitives/keyring" }
sp-timestamp = { version = "3.0.0", path = "../../../primitives/timestamp" }
sp-api = { version = "3.0.0", path = "../../../primitives/api" }
Expand Down
167 changes: 31 additions & 136 deletions bin/node/test-runner-example/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,16 @@

// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#![deny(unused_extern_crates, missing_docs)]

//! Basic example of end to end runtime tests.

use test_runner::{Node, ChainInfo, SignatureVerificationOverride, default_config};
use test_runner::{ChainInfo, SignatureVerificationOverride};
use grandpa::GrandpaBlockImport;
use sc_service::{TFullBackend, TFullClient, Configuration, TaskManager, new_full_parts, TaskExecutor};
use std::sync::Arc;
use sp_inherents::CreateInherentDataProviders;
use sc_service::{TFullBackend, TFullClient};
use sc_consensus_babe::BabeBlockImport;
use sp_keystore::SyncCryptoStorePtr;
use sp_keyring::sr25519::Keyring::Alice;
use sp_consensus_babe::AuthorityId;
use sc_consensus_manual_seal::{
ConsensusDataProvider, consensus::babe::{BabeConsensusDataProvider, SlotTimestampProvider},
};
use sp_runtime::{traits::IdentifyAccount, MultiSigner, generic::Era};
use node_cli::chain_spec::development_config;
use sc_consensus_manual_seal::consensus::babe::SlotTimestampProvider;
use sp_runtime::generic::Era;

type BlockImport<B, BE, C, SC> = BabeBlockImport<B, C, GrandpaBlockImport<BE, B, C, SC>>;

Expand Down Expand Up @@ -74,137 +67,39 @@ impl ChainInfo for NodeTemplateChainInfo {
pallet_transaction_payment::ChargeTransactionPayment::<Self::Runtime>::from(0),
)
}

fn config(task_executor: TaskExecutor) -> Configuration {
default_config(task_executor, Box::new(development_config()))
}

fn create_client_parts(
config: &Configuration,
) -> Result<
(
Arc<TFullClient<Self::Block, Self::RuntimeApi, Self::Executor>>,
Arc<TFullBackend<Self::Block>>,
SyncCryptoStorePtr,
TaskManager,
Box<dyn CreateInherentDataProviders<
Self::Block,
(),
InherentDataProviders = Self::InherentDataProviders
>>,
Option<
Box<
dyn ConsensusDataProvider<
Self::Block,
Transaction = sp_api::TransactionFor<
TFullClient<Self::Block, Self::RuntimeApi, Self::Executor>,
Self::Block,
>,
>,
>,
>,
Self::SelectChain,
Self::BlockImport,
),
sc_service::Error,
> {
let (client, backend, keystore, task_manager) =
new_full_parts::<Self::Block, Self::RuntimeApi, Self::Executor>(config, None)?;
let client = Arc::new(client);

let select_chain = sc_consensus::LongestChain::new(backend.clone());

let (grandpa_block_import, ..) =
grandpa::block_import(
client.clone(),
&(client.clone() as Arc<_>),
select_chain.clone(),
None
)?;

let slot_duration = sc_consensus_babe::Config::get_or_compute(&*client)?;
let (block_import, babe_link) = sc_consensus_babe::block_import(
slot_duration.clone(),
grandpa_block_import,
client.clone(),
)?;

let consensus_data_provider = BabeConsensusDataProvider::new(
client.clone(),
keystore.sync_keystore(),
babe_link.epoch_changes().clone(),
vec![(AuthorityId::from(Alice.public()), 1000)],
)
.expect("failed to create ConsensusDataProvider");

Ok((
client.clone(),
backend,
keystore.sync_keystore(),
task_manager,
Box::new(move |_, _| {
let client = client.clone();
async move {
let timestamp = SlotTimestampProvider::new(client.clone()).map_err(|err| format!("{:?}", err))?;
let babe = sp_consensus_babe::inherents::InherentDataProvider::new(timestamp.slot().into());
Ok((timestamp, babe))
}
}),
Some(Box::new(consensus_data_provider)),
select_chain,
block_import,
))
}

fn dispatch_with_root(call: <Self::Runtime as frame_system::Config>::Call, node: &mut Node<Self>) {
let alice = MultiSigner::from(Alice.public()).into_account();
let call = pallet_sudo::Call::sudo(Box::new(call));
node.submit_extrinsic(call, alice);
node.seal_blocks(1);
}
}

#[cfg(test)]
mod tests {
use super::*;
use test_runner::NodeConfig;
use log::LevelFilter;
use test_runner::{Node, client_parts, ConfigOrChainSpec, build_runtime, task_executor};
use sp_keyring::sr25519::Keyring::Alice;
use node_cli::chain_spec::development_config;
use sp_runtime::{traits::IdentifyAccount, MultiSigner};

#[test]
fn test_runner() {
let config = NodeConfig {
log_targets: vec![
("yamux", LevelFilter::Off),
("multistream_select", LevelFilter::Off),
("libp2p", LevelFilter::Off),
("jsonrpc_client_transports", LevelFilter::Off),
("sc_network", LevelFilter::Off),
("tokio_reactor", LevelFilter::Off),
("parity-db", LevelFilter::Off),
("sub-libp2p", LevelFilter::Off),
("sync", LevelFilter::Off),
("peerset", LevelFilter::Off),
("ws", LevelFilter::Off),
("sc_network", LevelFilter::Off),
("sc_service", LevelFilter::Off),
("sc_basic_authorship", LevelFilter::Off),
("telemetry-logger", LevelFilter::Off),
("sc_peerset", LevelFilter::Off),
("rpc", LevelFilter::Off),
("runtime", LevelFilter::Trace),
("babe", LevelFilter::Debug)
],
};
let mut node = Node::<NodeTemplateChainInfo>::new(config).unwrap();
// seals blocks
node.seal_blocks(1);
// submit extrinsics
let alice = MultiSigner::from(Alice.public()).into_account();
node.submit_extrinsic(frame_system::Call::remark((b"hello world").to_vec()), alice);

// look ma, I can read state.
let _events = node.with_state(|| frame_system::Pallet::<node_runtime::Runtime>::events());
// get access to the underlying client.
let _client = node.client();
let mut 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 node = Node::<NodeTemplateChainInfo>::new(rpc, task_manager, client, pool, command_sink, backend);

tokio_runtime.block_on(async {
// seals blocks
node.seal_blocks(1).await;
// submit extrinsics
let alice = MultiSigner::from(Alice.public()).into_account();
let _hash = node.submit_extrinsic(frame_system::Call::remark((b"hello world").to_vec()), alice)
.await
.unwrap();

// look ma, I can read state.
let _events = node.with_state(|| frame_system::Pallet::<node_runtime::Runtime>::events());
// get access to the underlying client.
let _client = node.client();
})
}
}
38 changes: 22 additions & 16 deletions client/cli/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,22 +160,7 @@ impl<C: SubstrateCli> Runner<C> {
/// 2020-06-03 16:14:21 ⛓ Native runtime: node-251 (substrate-node-1.tx1.au10)
/// ```
fn print_node_infos(&self) {
info!("{}", C::impl_name());
info!("✌️ version {}", C::impl_version());
info!(
"❤️ by {}, {}-{}",
C::author(),
C::copyright_start_year(),
Local::today().year(),
);
info!("📋 Chain specification: {}", self.config.chain_spec.name());
info!("🏷 Node name: {}", self.config.network.node_name);
info!("👤 Role: {}", self.config.display_role());
info!("💾 Database: {} at {}",
self.config.database,
self.config.database.path().map_or_else(|| "<unknown>".to_owned(), |p| p.display().to_string())
);
info!("⛓ Native runtime: {}", C::native_runtime_version(&self.config.chain_spec));
print_node_infos::<C>(self.config())
}

/// A helper function that runs a node with tokio and stops if the process receives the signal
Expand Down Expand Up @@ -229,3 +214,24 @@ impl<C: SubstrateCli> Runner<C> {
&mut self.config
}
}

/// Log information about the node itself.
pub fn print_node_infos<C: SubstrateCli>(config: &Configuration) {
info!("{}", C::impl_name());
info!("✌️ version {}", C::impl_version());
info!(
"❤️ by {}, {}-{}",
C::author(),
C::copyright_start_year(),
Local::today().year(),
);
info!("📋 Chain specification: {}", config.chain_spec.name());
info!("🏷 Node name: {}", config.network.node_name);
info!("👤 Role: {}", config.display_role());
info!("💾 Database: {} at {}",
config.database,
config.database.path().map_or_else(|| "<unknown>".to_owned(), |p| p.display().to_string())
);
info!("⛓ Native runtime: {}", C::native_runtime_version(&config.chain_spec));
}

Loading