polkadot_sdk_docs/guides/
your_first_node.rs#![doc = docify::embed!("./src/guides/your_first_node.rs", build_runtime)]
#![doc = docify::embed!("./src/guides/your_first_node.rs", csb)]
#[cfg(test)]
mod tests {
use assert_cmd::Command;
use cmd_lib::*;
use rand::Rng;
use sc_chain_spec::{DEV_RUNTIME_PRESET, LOCAL_TESTNET_RUNTIME_PRESET};
use sp_genesis_builder::PresetId;
use std::path::PathBuf;
const PARA_RUNTIME: &'static str = "parachain-template-runtime";
const FIRST_RUNTIME: &'static str = "polkadot-sdk-docs-first-runtime";
const MINIMAL_RUNTIME: &'static str = "minimal-template-runtime";
const CHAIN_SPEC_BUILDER: &'static str = "chain-spec-builder";
const OMNI_NODE: &'static str = "polkadot-omni-node";
fn cargo() -> Command {
Command::new(std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_string()))
}
fn get_target_directory() -> Option<PathBuf> {
let output = cargo().arg("metadata").arg("--format-version=1").output().ok()?;
if !output.status.success() {
return None;
}
let metadata: serde_json::Value = serde_json::from_slice(&output.stdout).ok()?;
let target_directory = metadata["target_directory"].as_str()?;
Some(PathBuf::from(target_directory))
}
fn find_release_binary(name: &str) -> Option<PathBuf> {
let target_dir = get_target_directory()?;
let release_path = target_dir.join("release").join(name);
if release_path.exists() {
Some(release_path)
} else {
None
}
}
fn find_wasm(runtime_name: &str) -> Option<PathBuf> {
let target_dir = get_target_directory()?;
let wasm_path = target_dir
.join("release")
.join("wbuild")
.join(runtime_name)
.join(format!("{}.wasm", runtime_name.replace('-', "_")));
if wasm_path.exists() {
Some(wasm_path)
} else {
None
}
}
fn maybe_build_runtimes() {
if find_wasm(&PARA_RUNTIME).is_none() {
println!("Building parachain-template-runtime...");
Command::new("cargo")
.arg("build")
.arg("--release")
.arg("-p")
.arg(PARA_RUNTIME)
.assert()
.success();
}
if find_wasm(&FIRST_RUNTIME).is_none() {
println!("Building polkadot-sdk-docs-first-runtime...");
#[docify::export_content]
fn build_runtime() {
run_cmd!(
cargo build --release -p $FIRST_RUNTIME
)
.expect("Failed to run command");
}
build_runtime()
}
assert!(find_wasm(PARA_RUNTIME).is_some());
assert!(find_wasm(FIRST_RUNTIME).is_some());
}
fn maybe_build_chain_spec_builder() {
if find_release_binary(CHAIN_SPEC_BUILDER).is_none() {
println!("Building chain-spec-builder...");
Command::new("cargo")
.arg("build")
.arg("--release")
.arg("-p")
.arg("staging-chain-spec-builder")
.assert()
.success();
}
assert!(find_release_binary(CHAIN_SPEC_BUILDER).is_some());
}
fn maybe_build_omni_node() {
if find_release_binary(OMNI_NODE).is_none() {
println!("Building polkadot-omni-node...");
Command::new("cargo")
.arg("build")
.arg("--release")
.arg("-p")
.arg("polkadot-omni-node")
.assert()
.success();
}
}
fn test_runtime_preset(runtime: &'static str, block_time: u64, maybe_preset: Option<PresetId>) {
sp_tracing::try_init_simple();
maybe_build_runtimes();
maybe_build_chain_spec_builder();
maybe_build_omni_node();
let chain_spec_builder =
find_release_binary(&CHAIN_SPEC_BUILDER).expect("we built it above; qed");
let omni_node = find_release_binary(OMNI_NODE).expect("we built it above; qed");
let runtime_path = find_wasm(runtime).expect("we built it above; qed");
let random_seed: u32 = rand::thread_rng().gen();
let chain_spec_file = std::env::current_dir()
.unwrap()
.join(format!("{}_{}_{}.json", runtime, block_time, random_seed));
Command::new(chain_spec_builder)
.args(["-c", chain_spec_file.to_str().unwrap()])
.arg("create")
.args(["--para-id", "1000", "--relay-chain", "dontcare"])
.args(["-r", runtime_path.to_str().unwrap()])
.args(match maybe_preset {
Some(preset) => vec!["named-preset".to_string(), preset.to_string()],
None => vec!["default".to_string()],
})
.assert()
.success();
let output = Command::new(omni_node)
.arg("--tmp")
.args(["--chain", chain_spec_file.to_str().unwrap()])
.args(["--dev-block-time", block_time.to_string().as_str()])
.timeout(std::time::Duration::from_secs(10))
.output()
.unwrap();
std::fs::remove_file(chain_spec_file).unwrap();
let expected_blocks = (10_000 / block_time).saturating_div(2);
assert!(expected_blocks > 0, "test configuration is bad, should give it more time");
let output = String::from_utf8(output.stderr).unwrap();
let want = format!("Imported #{}", expected_blocks);
if !output.contains(&want) {
panic!(
"Output did not contain the pattern:\n\npattern: {}\n\noutput: {}\n",
want, output
);
}
}
#[test]
fn works_with_different_block_times() {
test_runtime_preset(PARA_RUNTIME, 100, Some(DEV_RUNTIME_PRESET.into()));
test_runtime_preset(PARA_RUNTIME, 3000, Some(DEV_RUNTIME_PRESET.into()));
#[docify::export_content(csb)]
fn build_para_chain_spec_works() {
let chain_spec_builder = find_release_binary(&CHAIN_SPEC_BUILDER).unwrap();
let runtime_path = find_wasm(PARA_RUNTIME).unwrap();
let output = "/tmp/demo-chain-spec.json";
let runtime_str = runtime_path.to_str().unwrap();
run_cmd!(
$chain_spec_builder -c $output create --para-id 1000 --relay-chain dontcare -r $runtime_str named-preset development
).expect("Failed to run command");
std::fs::remove_file(output).unwrap();
}
build_para_chain_spec_works();
}
#[test]
#[ignore]
fn parachain_runtime_works() {
[Some(DEV_RUNTIME_PRESET.into()), Some(LOCAL_TESTNET_RUNTIME_PRESET.into())]
.into_iter()
.for_each(|preset| {
test_runtime_preset(PARA_RUNTIME, 1000, preset);
});
}
#[test]
fn minimal_runtime_works() {
[None, Some(DEV_RUNTIME_PRESET.into())].into_iter().for_each(|preset| {
test_runtime_preset(MINIMAL_RUNTIME, 1000, preset);
});
}
#[test]
fn guide_first_runtime_works() {
[Some(DEV_RUNTIME_PRESET.into())].into_iter().for_each(|preset| {
test_runtime_preset(FIRST_RUNTIME, 1000, preset);
});
}
#[test]
fn omni_node_dev_mode_works() {
let dev_chain_spec = std::env::current_dir()
.unwrap()
.parent()
.unwrap()
.parent()
.unwrap()
.join("templates")
.join("parachain")
.join("dev_chain_spec.json");
maybe_build_omni_node();
let omni_node = find_release_binary(OMNI_NODE).unwrap();
let output = Command::new(omni_node)
.arg("--dev")
.args(["--chain", dev_chain_spec.to_str().unwrap()])
.timeout(std::time::Duration::from_secs(70))
.output()
.unwrap();
assert!(String::from_utf8(output.stderr)
.unwrap()
.contains(format!("Imported #{}", 7).to_string().as_str()));
}
}