1
0
mirror of synced 2025-01-24 06:29:21 +00:00

Add tests for blob dissemination (#416)

* Make nomos-cli config public

Split nomos-cli into lib and bin and make config public
so that it can be reused in tests

* Add tests for nomos-cli disseminate

* fmt

* feature gate whole file instead of function

* Exit unsuccessfully when failing dissemination
This commit is contained in:
Giacomo Pasini 2023-09-25 11:52:45 +02:00 committed by GitHub
parent 285804e1d5
commit 3b64cd6b3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 112 additions and 26 deletions

View File

@ -22,22 +22,22 @@ use std::{path::PathBuf, time::Duration};
pub struct Disseminate { pub struct Disseminate {
// TODO: accept bytes // TODO: accept bytes
#[clap(short, long)] #[clap(short, long)]
data: String, pub data: String,
/// Path to the network config file /// Path to the network config file
#[clap(short, long)] #[clap(short, long)]
network_config: PathBuf, pub network_config: PathBuf,
/// The data availability protocol to use. Defaults to full replication. /// The data availability protocol to use. Defaults to full replication.
#[clap(flatten)] #[clap(flatten)]
da_protocol: DaProtocolChoice, pub da_protocol: DaProtocolChoice,
/// Timeout in seconds. Defaults to 120 seconds. /// Timeout in seconds. Defaults to 120 seconds.
#[clap(short, long, default_value = "120")] #[clap(short, long, default_value = "120")]
timeout: u64, pub timeout: u64,
} }
#[derive(Debug, Clone, Args)] #[derive(Debug, Clone, Args)]
pub struct FullReplicationSettings { pub struct FullReplicationSettings {
#[clap(long, default_value = "1")] #[clap(long, default_value = "1")]
num_attestations: usize, pub num_attestations: usize,
} }
impl Disseminate { impl Disseminate {
@ -169,11 +169,23 @@ impl ServiceCore for DisseminateService {
let adapter = Libp2pAdapter::new(network_relay).await; let adapter = Libp2pAdapter::new(network_relay).await;
let da = FullReplication::new(AbsoluteNumber::new(da_settings.num_attestations)); let da = FullReplication::new(AbsoluteNumber::new(da_settings.num_attestations));
if tokio::time::timeout(settings.timeout, disseminate(da, settings.bytes, adapter)) match tokio::time::timeout(
.await settings.timeout,
.is_err() disseminate(da, settings.bytes, adapter),
)
.await
{ {
tracing::error!("Timeout reached, check the logs for additional details"); Err(_) => {
tracing::error!("Timeout reached, check the logs for additional details");
std::process::exit(1);
}
Ok(Err(_)) => {
tracing::error!(
"Could not disseminate blob, check logs for additional details"
);
std::process::exit(1);
}
_ => {}
} }
} }
} }
@ -191,21 +203,21 @@ impl ServiceCore for DisseminateService {
// We can enforce only sensible combinations of protocol/settings // We can enforce only sensible combinations of protocol/settings
// are specified by using special clap directives // are specified by using special clap directives
#[derive(Clone, Debug, Args)] #[derive(Clone, Debug, Args)]
pub(super) struct DaProtocolChoice { pub struct DaProtocolChoice {
#[clap(long, default_value = "full-replication")] #[clap(long, default_value = "full-replication")]
da_protocol: Protocol, pub da_protocol: Protocol,
#[clap(flatten)] #[clap(flatten)]
settings: ProtocolSettings, pub settings: ProtocolSettings,
} }
#[derive(Clone, Debug, Args)] #[derive(Clone, Debug, Args)]
struct ProtocolSettings { pub struct ProtocolSettings {
#[clap(flatten)] #[clap(flatten)]
full_replication: FullReplicationSettings, pub full_replication: FullReplicationSettings,
} }
#[derive(Clone, Debug, ValueEnum)] #[derive(Clone, Debug, ValueEnum)]
pub(super) enum Protocol { pub enum Protocol {
FullReplication, FullReplication,
} }

View File

@ -1,6 +1,6 @@
use clap::Subcommand; use clap::Subcommand;
mod disseminate; pub mod disseminate;
#[derive(Debug, Subcommand)] #[derive(Debug, Subcommand)]
pub enum Command { pub enum Command {

21
nomos-cli/src/lib.rs Normal file
View File

@ -0,0 +1,21 @@
pub mod cmds;
use clap::Parser;
use cmds::Command;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
pub struct Cli {
#[command(subcommand)]
command: Command,
}
impl Cli {
pub fn run(self) -> Result<(), Box<dyn std::error::Error>> {
self.command.run()
}
pub fn command(&self) -> &Command {
&self.command
}
}

View File

@ -1,15 +1,7 @@
mod cmds;
use clap::Parser; use clap::Parser;
use cmds::Command; use nomos_cli::Cli;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
#[command(subcommand)]
command: Command,
}
fn main() { fn main() {
let cli = Cli::parse(); let cli = Cli::parse();
cli.command.run().unwrap(); cli.run().unwrap();
} }

View File

@ -35,6 +35,7 @@ async-trait = "0.1"
fraction = "0.13" fraction = "0.13"
ntest = "0.9.0" ntest = "0.9.0"
criterion = { version = "0.5", features = ["async_tokio"] } criterion = { version = "0.5", features = ["async_tokio"] }
nomos-cli = { path = "../nomos-cli" }
[[test]] [[test]]
name = "test_consensus_happy_path" name = "test_consensus_happy_path"
@ -48,6 +49,12 @@ path = "src/tests/unhappy.rs"
name = "test_mixnet" name = "test_mixnet"
path = "src/tests/mixnet.rs" path = "src/tests/mixnet.rs"
[[test]]
name = "test_cli"
path = "src/tests/cli.rs"
# disseminate is only implemented for libp2p
required-features = ["libp2p"]
[[bench]] [[bench]]
name = "mixnet" name = "mixnet"
path = "src/benches/mixnet.rs" path = "src/benches/mixnet.rs"

View File

@ -35,6 +35,7 @@ pub struct NomosNode {
addr: SocketAddr, addr: SocketAddr,
_tempdir: tempfile::TempDir, _tempdir: tempfile::TempDir,
child: Child, child: Child,
config: Config,
} }
impl Drop for NomosNode { impl Drop for NomosNode {
@ -77,6 +78,7 @@ impl NomosNode {
addr: config.http.backend.address, addr: config.http.backend.address,
child, child,
_tempdir: dir, _tempdir: dir,
config,
}; };
tokio::time::timeout(std::time::Duration::from_secs(10), async { tokio::time::timeout(std::time::Duration::from_secs(10), async {
node.wait_online().await node.wait_online().await
@ -131,6 +133,10 @@ impl NomosNode {
.map(|f| std::fs::read_to_string(f).unwrap()) .map(|f| std::fs::read_to_string(f).unwrap())
.collect::<String>() .collect::<String>()
} }
pub fn config(&self) -> &Config {
&self.config
}
} }
#[async_trait::async_trait] #[async_trait::async_trait]

48
tests/src/tests/cli.rs Normal file
View File

@ -0,0 +1,48 @@
use fraction::{Fraction, One};
use nomos_cli::cmds::{
disseminate::{
DaProtocolChoice, Disseminate, FullReplicationSettings, Protocol, ProtocolSettings,
},
Command,
};
use std::time::Duration;
use tempfile::NamedTempFile;
use tests::{MixNode, Node, NomosNode, SpawnConfig};
#[tokio::test]
async fn disseminate_blob() {
let (_mixnodes, mixnet_node_configs, mixnet_topology) = MixNode::spawn_nodes(2).await;
let mut nodes = NomosNode::spawn_nodes(SpawnConfig::Star {
n_participants: 2,
threshold: Fraction::one(),
timeout: Duration::from_secs(10),
mixnet_node_configs,
mixnet_topology,
})
.await;
// kill the node so that we can reuse its network config
nodes[1].stop();
let network_config = nodes[1].config().network.clone();
let mut file = NamedTempFile::new().unwrap();
let config_path = file.path().to_owned();
serde_yaml::to_writer(&mut file, &network_config).unwrap();
let cmd = Command::Disseminate(Disseminate {
data: "Hello World".into(),
timeout: 20,
network_config: config_path,
da_protocol: DaProtocolChoice {
da_protocol: Protocol::FullReplication,
settings: ProtocolSettings {
full_replication: FullReplicationSettings {
num_attestations: 1,
},
},
},
});
std::thread::spawn(move || cmd.run().unwrap())
.join()
.unwrap();
}