feat: Vendor pezkuwi-subxt and pezkuwi-zombienet-sdk into monorepo
- Add pezkuwi-subxt crates to vendor/pezkuwi-subxt - Add pezkuwi-zombienet-sdk crates to vendor/pezkuwi-zombienet-sdk - Convert git dependencies to path dependencies - Add vendor crates to workspace members - Remove test/example crates from vendor (not needed for SDK) - Fix feature propagation issues detected by zepter - Fix workspace inheritance for internal dependencies - All 606 crates now in workspace - All 6919 internal dependency links verified correct - No git dependencies remaining
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
[package]
|
||||
name = "zombienet-sdk"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
publish = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
description = "Zombienet SDK, entrypoint for using zombienet"
|
||||
keywords = ["zombienet", "sdk"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
async-trait = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
lazy_static = { workspace = true }
|
||||
pezkuwi-subxt = { workspace = true }
|
||||
pezkuwi-subxt-signer = { workspace = true, features = ["subxt"] }
|
||||
|
||||
# Zombienet deps
|
||||
configuration = { workspace = true }
|
||||
orchestrator = { workspace = true }
|
||||
provider = { workspace = true }
|
||||
support = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
tracing-subscriber = { workspace = true }
|
||||
kube = { workspace = true, features = ["ws", "runtime"] }
|
||||
k8s-openapi = { workspace = true, features = ["v1_27"] }
|
||||
serde_json = {workspace = true }
|
||||
@@ -0,0 +1,90 @@
|
||||
//! Helpers functions to get configuration (e.g. Provider and images) from the env vars
|
||||
use std::{env, future::Future, path::PathBuf, pin::Pin};
|
||||
|
||||
use crate::{
|
||||
AttachToLive, AttachToLiveNetwork, LocalFileSystem, Network, NetworkConfig, NetworkConfigExt,
|
||||
OrchestratorError,
|
||||
};
|
||||
|
||||
const DEFAULT_POLKADOT_IMAGE: &str = "docker.io/parity/polkadot:latest";
|
||||
const DEFAULT_CUMULUS_IMAGE: &str = "docker.io/parity/polkadot-parachain:latest";
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Images {
|
||||
pub polkadot: String,
|
||||
pub cumulus: String,
|
||||
}
|
||||
|
||||
impl Images {
|
||||
/// Alias for polkadot field - returns reference to pezkuwi/polkadot image
|
||||
pub fn pezkuwi(&self) -> &str {
|
||||
&self.polkadot
|
||||
}
|
||||
|
||||
/// Alias for cumulus field - returns reference to pezcumulus/cumulus image
|
||||
pub fn pezcumulus(&self) -> &str {
|
||||
&self.cumulus
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Provider {
|
||||
Native,
|
||||
K8s,
|
||||
Docker,
|
||||
}
|
||||
|
||||
impl Provider {
|
||||
pub fn get_spawn_fn(
|
||||
&self,
|
||||
) -> fn(NetworkConfig) -> Pin<Box<dyn Future<Output = SpawnResult> + Send>> {
|
||||
match self {
|
||||
Provider::Native => NetworkConfigExt::spawn_native,
|
||||
Provider::K8s => NetworkConfigExt::spawn_k8s,
|
||||
Provider::Docker => NetworkConfigExt::spawn_docker,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use `docker` as default provider
|
||||
impl From<String> for Provider {
|
||||
fn from(value: String) -> Self {
|
||||
match value.to_ascii_lowercase().as_ref() {
|
||||
"native" => Provider::Native,
|
||||
"k8s" => Provider::K8s,
|
||||
_ => Provider::Docker, // default provider
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_images_from_env() -> Images {
|
||||
let polkadot = env::var("POLKADOT_IMAGE").unwrap_or(DEFAULT_POLKADOT_IMAGE.into());
|
||||
let cumulus = env::var("CUMULUS_IMAGE").unwrap_or(DEFAULT_CUMULUS_IMAGE.into());
|
||||
Images { polkadot, cumulus }
|
||||
}
|
||||
|
||||
pub fn get_provider_from_env() -> Provider {
|
||||
env::var("ZOMBIE_PROVIDER").unwrap_or_default().into()
|
||||
}
|
||||
|
||||
pub type SpawnResult = Result<Network<LocalFileSystem>, OrchestratorError>;
|
||||
pub fn get_spawn_fn() -> fn(NetworkConfig) -> Pin<Box<dyn Future<Output = SpawnResult> + Send>> {
|
||||
let provider = get_provider_from_env();
|
||||
|
||||
match provider {
|
||||
Provider::Native => NetworkConfigExt::spawn_native,
|
||||
Provider::K8s => NetworkConfigExt::spawn_k8s,
|
||||
Provider::Docker => NetworkConfigExt::spawn_docker,
|
||||
}
|
||||
}
|
||||
|
||||
pub type AttachResult = Result<Network<LocalFileSystem>, OrchestratorError>;
|
||||
|
||||
pub fn get_attach_fn() -> fn(PathBuf) -> Pin<Box<dyn Future<Output = AttachResult> + Send>> {
|
||||
let provider = get_provider_from_env();
|
||||
|
||||
match provider {
|
||||
Provider::Native => AttachToLiveNetwork::attach_native,
|
||||
Provider::K8s => AttachToLiveNetwork::attach_k8s,
|
||||
Provider::Docker => AttachToLiveNetwork::attach_docker,
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use async_trait::async_trait;
|
||||
pub use configuration::{
|
||||
GlobalSettings, GlobalSettingsBuilder, NetworkConfig, NetworkConfigBuilder,
|
||||
RegistrationStrategy, WithRelaychain,
|
||||
};
|
||||
pub use orchestrator::{
|
||||
errors::OrchestratorError,
|
||||
network::{node::NetworkNode, Network},
|
||||
sc_chain_spec, AddCollatorOptions, AddNodeOptions, Orchestrator,
|
||||
};
|
||||
|
||||
// Helpers used for interact with the network
|
||||
pub mod tx_helper {
|
||||
pub use orchestrator::{
|
||||
network::chain_upgrade::ChainUpgrade, shared::types::RuntimeUpgradeOptions,
|
||||
};
|
||||
}
|
||||
|
||||
use provider::{DockerProvider, KubernetesProvider, NativeProvider};
|
||||
pub use support::fs::local::LocalFileSystem;
|
||||
|
||||
pub mod environment;
|
||||
pub const PROVIDERS: [&str; 3] = ["k8s", "native", "docker"];
|
||||
|
||||
// re-export pezkuwi-subxt (with subxt alias for backwards compatibility)
|
||||
pub use pezkuwi_subxt;
|
||||
pub use pezkuwi_subxt as subxt;
|
||||
pub use pezkuwi_subxt_signer;
|
||||
pub use pezkuwi_subxt_signer as subxt_signer;
|
||||
|
||||
#[async_trait]
|
||||
pub trait NetworkConfigExt {
|
||||
/// Spawns a network using the native or k8s provider.
|
||||
///
|
||||
/// # Example:
|
||||
/// ```rust
|
||||
/// # use zombienet_sdk::{NetworkConfig, NetworkConfigExt};
|
||||
/// # async fn example() -> Result<(), zombienet_sdk::OrchestratorError> {
|
||||
/// let network = NetworkConfig::load_from_toml("config.toml")?
|
||||
/// .spawn_native()
|
||||
/// .await?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
async fn spawn_native(self) -> Result<Network<LocalFileSystem>, OrchestratorError>;
|
||||
async fn spawn_k8s(self) -> Result<Network<LocalFileSystem>, OrchestratorError>;
|
||||
async fn spawn_docker(self) -> Result<Network<LocalFileSystem>, OrchestratorError>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait AttachToLive {
|
||||
/// Attaches to a running live network using the native, docker or k8s provider.
|
||||
///
|
||||
/// # Example:
|
||||
/// ```rust
|
||||
/// # use zombienet_sdk::{AttachToLive, AttachToLiveNetwork};
|
||||
/// # use std::path::PathBuf;
|
||||
/// # async fn example() -> Result<(), zombienet_sdk::OrchestratorError> {
|
||||
/// let zombie_json_path = PathBuf::from("some/path/zombie.json");
|
||||
/// let network = AttachToLiveNetwork::attach_native(zombie_json_path).await?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
async fn attach_native(
|
||||
zombie_json_path: PathBuf,
|
||||
) -> Result<Network<LocalFileSystem>, OrchestratorError>;
|
||||
async fn attach_k8s(
|
||||
zombie_json_path: PathBuf,
|
||||
) -> Result<Network<LocalFileSystem>, OrchestratorError>;
|
||||
async fn attach_docker(
|
||||
zombie_json_path: PathBuf,
|
||||
) -> Result<Network<LocalFileSystem>, OrchestratorError>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl NetworkConfigExt for NetworkConfig {
|
||||
async fn spawn_native(self) -> Result<Network<LocalFileSystem>, OrchestratorError> {
|
||||
let filesystem = LocalFileSystem;
|
||||
let provider = NativeProvider::new(filesystem.clone());
|
||||
let orchestrator = Orchestrator::new(filesystem, provider);
|
||||
orchestrator.spawn(self).await
|
||||
}
|
||||
|
||||
async fn spawn_k8s(self) -> Result<Network<LocalFileSystem>, OrchestratorError> {
|
||||
let filesystem = LocalFileSystem;
|
||||
let provider = KubernetesProvider::new(filesystem.clone()).await;
|
||||
let orchestrator = Orchestrator::new(filesystem, provider);
|
||||
orchestrator.spawn(self).await
|
||||
}
|
||||
|
||||
async fn spawn_docker(self) -> Result<Network<LocalFileSystem>, OrchestratorError> {
|
||||
let filesystem = LocalFileSystem;
|
||||
let provider = DockerProvider::new(filesystem.clone()).await;
|
||||
let orchestrator = Orchestrator::new(filesystem, provider);
|
||||
orchestrator.spawn(self).await
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AttachToLiveNetwork;
|
||||
|
||||
#[async_trait]
|
||||
impl AttachToLive for AttachToLiveNetwork {
|
||||
async fn attach_native(
|
||||
zombie_json_path: PathBuf,
|
||||
) -> Result<Network<LocalFileSystem>, OrchestratorError> {
|
||||
let filesystem = LocalFileSystem;
|
||||
let provider = NativeProvider::new(filesystem.clone());
|
||||
let orchestrator = Orchestrator::new(filesystem, provider);
|
||||
orchestrator.attach_to_live(zombie_json_path.as_ref()).await
|
||||
}
|
||||
|
||||
async fn attach_k8s(
|
||||
zombie_json_path: PathBuf,
|
||||
) -> Result<Network<LocalFileSystem>, OrchestratorError> {
|
||||
let filesystem = LocalFileSystem;
|
||||
let provider = KubernetesProvider::new(filesystem.clone()).await;
|
||||
let orchestrator = Orchestrator::new(filesystem, provider);
|
||||
orchestrator.attach_to_live(zombie_json_path.as_ref()).await
|
||||
}
|
||||
|
||||
async fn attach_docker(
|
||||
zombie_json_path: PathBuf,
|
||||
) -> Result<Network<LocalFileSystem>, OrchestratorError> {
|
||||
let filesystem = LocalFileSystem;
|
||||
let provider = DockerProvider::new(filesystem.clone()).await;
|
||||
let orchestrator = Orchestrator::new(filesystem, provider);
|
||||
orchestrator.attach_to_live(zombie_json_path.as_ref()).await
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
use futures::StreamExt;
|
||||
use zombienet_sdk::{environment::get_spawn_fn, NetworkConfigBuilder};
|
||||
|
||||
const BEST_BLOCK_METRIC: &str = "block_height{status=\"best\"}";
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn rococo_local_with_omni_node_and_wasm_runtime() {
|
||||
let _ = tracing_subscriber::fmt::try_init();
|
||||
|
||||
let config = NetworkConfigBuilder::new()
|
||||
.with_relaychain(|relaychain| {
|
||||
relaychain
|
||||
.with_chain("rococo-local")
|
||||
.with_default_command("polkadot")
|
||||
.with_default_image("docker.io/parity/polkadot:latest")
|
||||
.with_validator(|node| node.with_name("alice"))
|
||||
.with_validator(|node| node.with_name("bob"))
|
||||
})
|
||||
.with_parachain(|parachain| {
|
||||
parachain
|
||||
.with_id(100).cumulus_based(true)
|
||||
.with_chain("asset-hub-rococo-local")
|
||||
.with_default_command("polkadot-omni-node")
|
||||
.with_default_image("docker.io/parity/polkadot-omni-node:latest")
|
||||
.with_chain_spec_runtime("https://github.com/polkadot-fellows/runtimes/releases/download/v1.9.2/asset-hub-polkadot_runtime-v1009002.compact.compressed.wasm", None )
|
||||
.with_collator(|collator| collator.with_name("omni-collator-1"))
|
||||
.with_collator(|collator| collator.with_name("omni-collator-2"))
|
||||
})
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let spawn_fn = get_spawn_fn();
|
||||
let network = spawn_fn(config).await.unwrap();
|
||||
|
||||
println!("🚀🚀🚀🚀 network deployed");
|
||||
|
||||
// wait 2 blocks
|
||||
let alice = network.get_node("alice").unwrap();
|
||||
assert!(alice
|
||||
.wait_metric(BEST_BLOCK_METRIC, |b| b > 2_f64)
|
||||
.await
|
||||
.is_ok());
|
||||
|
||||
// omni-collator-1
|
||||
let collator = network.get_node("omni-collator-1").unwrap();
|
||||
let client = collator
|
||||
.wait_client::<subxt::PolkadotConfig>()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// wait 1 blocks
|
||||
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(1);
|
||||
while let Some(block) = blocks.next().await {
|
||||
println!(
|
||||
"Block (omni-collator-1) #{}",
|
||||
block.unwrap().header().number
|
||||
);
|
||||
}
|
||||
|
||||
// omni-collator-2
|
||||
let collator = network.get_node("omni-collator-2").unwrap();
|
||||
let client = collator
|
||||
.wait_client::<subxt::PolkadotConfig>()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// wait 1 blocks
|
||||
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(1);
|
||||
while let Some(block) = blocks.next().await {
|
||||
println!(
|
||||
"Block (omni-collator-2) #{}",
|
||||
block.unwrap().header().number
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
use futures::StreamExt;
|
||||
use zombienet_sdk::{environment::get_spawn_fn, NetworkConfigBuilder};
|
||||
|
||||
const BEST_BLOCK_METRIC: &str = "block_height{status=\"best\"}";
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn polkadot_local_with_chain_spec_runtime() {
|
||||
let _ = tracing_subscriber::fmt::try_init();
|
||||
|
||||
let config = NetworkConfigBuilder::new()
|
||||
.with_relaychain(|relaychain| {
|
||||
relaychain
|
||||
.with_chain("polkadot-local")
|
||||
.with_default_command("polkadot")
|
||||
.with_default_image("docker.io/parity/polkadot:latest")
|
||||
.with_chain_spec_runtime("https://github.com/polkadot-fellows/runtimes/releases/download/v1.9.3/polkadot_runtime-v1009003.compact.compressed.wasm", None)
|
||||
.with_validator(|node| node.with_name("alice"))
|
||||
.with_validator(|node| node.with_name("bob"))
|
||||
})
|
||||
.with_parachain(|parachain| {
|
||||
parachain
|
||||
.with_id(100)
|
||||
.with_chain("asset-hub-polkadot-local")
|
||||
.with_default_command("polkadot-parachain")
|
||||
.with_default_image("docker.io/parity/polkadot-parachain:latest")
|
||||
.with_chain_spec_runtime("https://github.com/polkadot-fellows/runtimes/releases/download/v1.9.2/asset-hub-polkadot_runtime-v1009002.compact.compressed.wasm", None)
|
||||
.with_collator(|collator| collator.with_name("asset-hub-collator-1"))
|
||||
.with_collator(|collator| collator.with_name("asset-hub-collator-2"))
|
||||
})
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let spawn_fn = get_spawn_fn();
|
||||
let network = spawn_fn(config).await.unwrap();
|
||||
|
||||
println!("🚀🚀🚀🚀 network deployed");
|
||||
|
||||
// wait 2 blocks
|
||||
let alice = network.get_node("alice").unwrap();
|
||||
assert!(alice
|
||||
.wait_metric(BEST_BLOCK_METRIC, |b| b > 2_f64)
|
||||
.await
|
||||
.is_ok());
|
||||
|
||||
// asset-hub-collator-1
|
||||
let collator = network.get_node("asset-hub-collator-1").unwrap();
|
||||
let client = collator
|
||||
.wait_client::<subxt::PolkadotConfig>()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// wait 1 blocks
|
||||
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(1);
|
||||
while let Some(block) = blocks.next().await {
|
||||
println!(
|
||||
"Block (asset-hub-collator-1) #{}",
|
||||
block.unwrap().header().number
|
||||
);
|
||||
}
|
||||
|
||||
// asset-hub-collator-2
|
||||
let collator = network.get_node("asset-hub-collator-2").unwrap();
|
||||
let client = collator
|
||||
.wait_client::<subxt::PolkadotConfig>()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// wait 1 blocks
|
||||
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(1);
|
||||
while let Some(block) = blocks.next().await {
|
||||
println!(
|
||||
"Block (asset-hub-collator-2) #{}",
|
||||
block.unwrap().header().number
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
use std::time::Instant;
|
||||
|
||||
use configuration::{NetworkConfig, NetworkConfigBuilder};
|
||||
use zombienet_sdk::environment::get_spawn_fn;
|
||||
|
||||
fn small_network() -> NetworkConfig {
|
||||
NetworkConfigBuilder::new()
|
||||
.with_relaychain(|r| {
|
||||
r.with_chain("rococo-local")
|
||||
.with_default_command("polkadot")
|
||||
.with_default_image("docker.io/parity/polkadot:v1.20.2")
|
||||
.with_validator(|node| node.with_name("alice"))
|
||||
.with_validator(|node| node.with_name("bob"))
|
||||
})
|
||||
.with_parachain(|p| {
|
||||
p.with_id(2000)
|
||||
.cumulus_based(true)
|
||||
.with_default_image("docker.io/parity/polkadot-parachain:v1.20.2")
|
||||
.with_collator(|n| n.with_name("collator").with_command("polkadot-parachain"))
|
||||
})
|
||||
.with_parachain(|p| {
|
||||
p.with_id(3000)
|
||||
.cumulus_based(true)
|
||||
.with_default_image("docker.io/parity/polkadot-omni-node:v1.20.2")
|
||||
.with_chain_spec_runtime("https://github.com/polkadot-fellows/runtimes/releases/download/v1.9.2/asset-hub-polkadot_runtime-v1009002.compact.compressed.wasm", None)
|
||||
.with_collator(|n| n.with_name("collator-omni").with_command("polkadot-omni-node"))
|
||||
})
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn ci_native_smoke_should_works() {
|
||||
tracing_subscriber::fmt::init();
|
||||
const BEST_BLOCK_METRIC: &str = "block_height{status=\"best\"}";
|
||||
let now = Instant::now();
|
||||
let config = small_network();
|
||||
let spawn_fn = get_spawn_fn();
|
||||
|
||||
let network = spawn_fn(config).await.unwrap();
|
||||
|
||||
let elapsed = now.elapsed();
|
||||
println!("🚀🚀🚀🚀 network deployed in {elapsed:.2?}");
|
||||
|
||||
network.wait_until_is_up(20).await.unwrap();
|
||||
|
||||
let elapsed = now.elapsed();
|
||||
println!("✅✅✅✅ network is up in {elapsed:.2?}");
|
||||
|
||||
// Get a ref to the node
|
||||
let alice = network.get_node("alice").unwrap();
|
||||
// wait 10 blocks
|
||||
alice
|
||||
.wait_metric(BEST_BLOCK_METRIC, |x| x > 9_f64)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
use std::{path::PathBuf, time::Instant};
|
||||
|
||||
use configuration::{NetworkConfig, NetworkConfigBuilder};
|
||||
use futures::{stream::StreamExt, try_join};
|
||||
use orchestrator::{AddCollatorOptions, AddNodeOptions};
|
||||
use zombienet_sdk::environment::{get_attach_fn, get_spawn_fn};
|
||||
|
||||
fn small_network() -> NetworkConfig {
|
||||
NetworkConfigBuilder::new()
|
||||
.with_relaychain(|r| {
|
||||
r.with_chain("rococo-local")
|
||||
.with_default_command("polkadot")
|
||||
.with_default_image("docker.io/parity/polkadot:v1.20.2")
|
||||
.with_validator(|node| node.with_name("alice"))
|
||||
.with_validator(|node| node.with_name("bob"))
|
||||
})
|
||||
.with_parachain(|p| {
|
||||
p.with_id(2000).cumulus_based(true).with_collator(|n| {
|
||||
n.with_name("collator")
|
||||
.with_command("polkadot-parachain")
|
||||
.with_image("docker.io/parity/polkadot-parachain:1.7.0")
|
||||
})
|
||||
})
|
||||
.with_parachain(|p| {
|
||||
p.with_id(3000).cumulus_based(true).with_collator(|n| {
|
||||
n.with_name("collator-new")
|
||||
.with_command("polkadot-parachain")
|
||||
.with_image("docker.io/parity/polkadot-parachain:v1.20.2")
|
||||
})
|
||||
})
|
||||
.with_global_settings(|g| {
|
||||
g.with_base_dir(PathBuf::from("/tmp/zombie-1"))
|
||||
.with_tear_down_on_failure(false)
|
||||
})
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn ci_k8s_basic_functionalities_should_works() {
|
||||
let _ = tracing_subscriber::fmt::try_init();
|
||||
|
||||
const BEST_BLOCK_METRIC: &str = "block_height{status=\"best\"}";
|
||||
let now = Instant::now();
|
||||
|
||||
let config = small_network();
|
||||
let spawn_fn = get_spawn_fn();
|
||||
|
||||
let network = spawn_fn(config).await.unwrap();
|
||||
|
||||
let elapsed = now.elapsed();
|
||||
println!("🚀🚀🚀🚀 network deployed in {elapsed:.2?}");
|
||||
|
||||
// detach and attach to running
|
||||
network.detach().await;
|
||||
drop(network);
|
||||
let attach_fn = get_attach_fn();
|
||||
let zombie_path = PathBuf::from("/tmp/zombie-1/zombie.json");
|
||||
let mut network = attach_fn(zombie_path).await.unwrap();
|
||||
|
||||
// Get a ref to the node
|
||||
let alice = network.get_node("alice").unwrap();
|
||||
|
||||
let (_best_block_pass, client) = try_join!(
|
||||
alice.wait_metric(BEST_BLOCK_METRIC, |x| x > 5_f64),
|
||||
alice.wait_client::<subxt::PolkadotConfig>()
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
alice
|
||||
.wait_log_line_count("*rted #1*", true, 10)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// check best block through metrics with timeout
|
||||
assert!(alice
|
||||
.wait_metric_with_timeout(BEST_BLOCK_METRIC, |x| x > 10_f64, 45_u32)
|
||||
.await
|
||||
.is_ok());
|
||||
|
||||
// ensure timeout error
|
||||
let best_block = alice.reports(BEST_BLOCK_METRIC).await.unwrap();
|
||||
let res = alice
|
||||
.wait_metric_with_timeout(BEST_BLOCK_METRIC, |x| x > (best_block * 2_f64), 10_u32)
|
||||
.await;
|
||||
|
||||
assert!(res.is_err());
|
||||
|
||||
// get single metric
|
||||
let role = alice.reports("node_roles").await.unwrap();
|
||||
println!("Role is {role}");
|
||||
assert_eq!(role, 4.0);
|
||||
|
||||
// subxt
|
||||
// wait 3 blocks
|
||||
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(3);
|
||||
while let Some(block) = blocks.next().await {
|
||||
println!("Block #{}", block.unwrap().header().number);
|
||||
}
|
||||
|
||||
// drop the client
|
||||
drop(client);
|
||||
|
||||
// check best block through metrics
|
||||
let best_block = alice
|
||||
.reports("block_height{status=\"best\"}")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(best_block >= 2.0, "Current best {best_block}");
|
||||
|
||||
// collator
|
||||
let collator = network.get_node("collator").unwrap();
|
||||
let client = collator
|
||||
.wait_client::<subxt::PolkadotConfig>()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// wait 3 blocks
|
||||
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(3);
|
||||
while let Some(block) = blocks.next().await {
|
||||
println!("Block (para) #{}", block.unwrap().header().number);
|
||||
}
|
||||
|
||||
// add node
|
||||
let opts = AddNodeOptions {
|
||||
rpc_port: Some(9444),
|
||||
is_validator: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
network.add_node("new1", opts).await.unwrap();
|
||||
|
||||
// add collator
|
||||
let col_opts = AddCollatorOptions {
|
||||
command: Some("polkadot-parachain".try_into().unwrap()),
|
||||
image: Some(
|
||||
"docker.io/parity/polkadot-parachain:1.7.0"
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
network
|
||||
.add_collator("new-col-1", col_opts, 2000)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// pause / resume
|
||||
let alice = network.get_node("alice").unwrap();
|
||||
alice.pause().await.unwrap();
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
||||
|
||||
let res_err = alice
|
||||
.wait_metric_with_timeout(BEST_BLOCK_METRIC, |x| x > 5_f64, 5_u32)
|
||||
.await;
|
||||
|
||||
assert!(res_err.is_err());
|
||||
|
||||
alice.resume().await.unwrap();
|
||||
alice
|
||||
.wait_metric_with_timeout(BEST_BLOCK_METRIC, |x| x > 5_f64, 5_u32)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// timeout connecting ws
|
||||
let collator = network.get_node("collator").unwrap();
|
||||
collator.pause().await.unwrap();
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
||||
|
||||
let r = collator
|
||||
.wait_client_with_timeout::<subxt::PolkadotConfig>(1_u32)
|
||||
.await;
|
||||
assert!(r.is_err());
|
||||
|
||||
// tear down (optional if you don't detach the network)
|
||||
network.destroy().await.unwrap();
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
use zombienet_sdk::{environment::get_spawn_fn, NetworkConfigBuilder};
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn two_paras_same_id() {
|
||||
tracing_subscriber::fmt::init();
|
||||
let spawn_fn = get_spawn_fn();
|
||||
let config = NetworkConfigBuilder::new()
|
||||
.with_relaychain(|r| {
|
||||
r.with_chain("rococo-local")
|
||||
.with_default_command("polkadot")
|
||||
.with_default_image("docker.io/parity/polkadot:v1.7.0")
|
||||
.with_validator(|node| node.with_name("alice"))
|
||||
.with_validator(|node| node.with_name("bob"))
|
||||
})
|
||||
.with_parachain(|p| {
|
||||
p.with_id(2000)
|
||||
.with_default_command("polkadot-parachain")
|
||||
.with_default_image("docker.io/parity/polkadot-parachain:1.7.0")
|
||||
.with_collator(|n| n.with_name("collator"))
|
||||
})
|
||||
.with_parachain(|p| {
|
||||
p.with_id(2000)
|
||||
.with_default_command("polkadot-parachain")
|
||||
.with_default_image("docker.io/parity/polkadot-parachain:1.7.0")
|
||||
.with_registration_strategy(zombienet_sdk::RegistrationStrategy::Manual)
|
||||
.with_collator(|n| n.with_name("collator1"))
|
||||
})
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let network = spawn_fn(config).await.unwrap();
|
||||
|
||||
assert!(network.get_node("collator").is_ok());
|
||||
assert!(network.get_node("collator1").is_ok());
|
||||
|
||||
// First parachain (out of two) is fetched
|
||||
assert_eq!(network.parachain(2000).unwrap().unique_id(), "2000");
|
||||
|
||||
// First and second parachain hav the same para_id
|
||||
assert_eq!(
|
||||
network.parachain_by_unique_id("2000").unwrap().para_id(),
|
||||
network.parachain_by_unique_id("2000-1").unwrap().para_id(),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user