Add regression tests for boot_node (#2749)
## Issue Addressed
Resolves #2602
## Proposed Changes
*Note: For a review it might help to look at the individual commits.*
### `boot_node`
Add support for the flags `dump-config` and `immediate-shutdown`. For `immediate-shutdown` the actual behavior could be described as `dump-config-and-exit`.
Both flags are handled in `boot_node::main`, which appears to be the simplest approach.
### `boot_node` regression tests
Added in `lighthouse/tests/boot_node.rs`.
### `CommandLineTestExec`
Factors out boilerplate related to CLI tests. It's used in the regression tests for `boot_node`, `beacon_node` and `validator_client`.
## Open TODO
Add tests for `boot_node` flags `enable-enr-auto-update` and `disable-packet-filter`. They end up in [`Discv5Config`](9ed2cba6bc/boot_node/src/config.rs (L29)
), which doesn't support serde (de)serialization.
I haven't found a workaround - guidance would be appreciated.
This commit is contained in:
parent
fbafe416d1
commit
d01fe02824
5
Cargo.lock
generated
5
Cargo.lock
generated
@ -479,11 +479,15 @@ version = "2.0.1"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"beacon_node",
|
"beacon_node",
|
||||||
"clap",
|
"clap",
|
||||||
|
"clap_utils",
|
||||||
"eth2_ssz",
|
"eth2_ssz",
|
||||||
"hex",
|
"hex",
|
||||||
"lighthouse_network",
|
"lighthouse_network",
|
||||||
"log",
|
"log",
|
||||||
"logging",
|
"logging",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
"slog",
|
"slog",
|
||||||
"slog-async",
|
"slog-async",
|
||||||
"slog-scope",
|
"slog-scope",
|
||||||
@ -3193,6 +3197,7 @@ dependencies = [
|
|||||||
"lighthouse_network",
|
"lighthouse_network",
|
||||||
"lighthouse_version",
|
"lighthouse_version",
|
||||||
"malloc_utils",
|
"malloc_utils",
|
||||||
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"slashing_protection",
|
"slashing_protection",
|
||||||
"slog",
|
"slog",
|
||||||
|
@ -7,6 +7,7 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
beacon_node = { path = "../beacon_node" }
|
beacon_node = { path = "../beacon_node" }
|
||||||
clap = "2.33.3"
|
clap = "2.33.3"
|
||||||
|
clap_utils = { path = "../common/clap_utils" }
|
||||||
lighthouse_network = { path = "../beacon_node/lighthouse_network" }
|
lighthouse_network = { path = "../beacon_node/lighthouse_network" }
|
||||||
types = { path = "../consensus/types" }
|
types = { path = "../consensus/types" }
|
||||||
eth2_ssz = "0.4.0"
|
eth2_ssz = "0.4.0"
|
||||||
@ -19,3 +20,6 @@ slog-async = "2.5.0"
|
|||||||
slog-scope = "4.3.0"
|
slog-scope = "4.3.0"
|
||||||
slog-stdlog = "4.0.0"
|
slog-stdlog = "4.0.0"
|
||||||
hex = "0.4.2"
|
hex = "0.4.2"
|
||||||
|
serde = "1.0.116"
|
||||||
|
serde_derive = "1.0.116"
|
||||||
|
serde_json = "1.0.66"
|
||||||
|
@ -5,6 +5,7 @@ use lighthouse_network::{
|
|||||||
discovery::{create_enr_builder_from_config, load_enr_from_disk, use_or_load_enr},
|
discovery::{create_enr_builder_from_config, load_enr_from_disk, use_or_load_enr},
|
||||||
load_private_key, CombinedKeyExt, NetworkConfig,
|
load_private_key, CombinedKeyExt, NetworkConfig,
|
||||||
};
|
};
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use ssz::Encode;
|
use ssz::Encode;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
@ -130,3 +131,35 @@ impl<T: EthSpec> TryFrom<&ArgMatches<'_>> for BootNodeConfig<T> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The set of configuration parameters that can safely be (de)serialized.
|
||||||
|
///
|
||||||
|
/// Its fields are a subset of the fields of `BootNodeConfig`.
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct BootNodeConfigSerialization {
|
||||||
|
pub listen_socket: SocketAddr,
|
||||||
|
// TODO: Generalise to multiaddr
|
||||||
|
pub boot_nodes: Vec<Enr>,
|
||||||
|
pub local_enr: Enr,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BootNodeConfigSerialization {
|
||||||
|
/// Returns a `BootNodeConfigSerialization` obtained from copying resp. cloning the
|
||||||
|
/// relevant fields of `config`
|
||||||
|
pub fn from_config_ref<T: EthSpec>(config: &BootNodeConfig<T>) -> Self {
|
||||||
|
let BootNodeConfig {
|
||||||
|
listen_socket,
|
||||||
|
boot_nodes,
|
||||||
|
local_enr,
|
||||||
|
local_key: _,
|
||||||
|
discv5_config: _,
|
||||||
|
phantom: _,
|
||||||
|
} = config;
|
||||||
|
|
||||||
|
BootNodeConfigSerialization {
|
||||||
|
listen_socket: *listen_socket,
|
||||||
|
boot_nodes: boot_nodes.clone(),
|
||||||
|
local_enr: local_enr.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,17 +3,24 @@ use clap::ArgMatches;
|
|||||||
use slog::{o, Drain, Level, Logger};
|
use slog::{o, Drain, Level, Logger};
|
||||||
|
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::path::PathBuf;
|
||||||
mod cli;
|
mod cli;
|
||||||
mod config;
|
pub mod config;
|
||||||
mod server;
|
mod server;
|
||||||
pub use cli::cli_app;
|
pub use cli::cli_app;
|
||||||
use config::BootNodeConfig;
|
use config::{BootNodeConfig, BootNodeConfigSerialization};
|
||||||
use types::{EthSpec, EthSpecId};
|
use types::{EthSpec, EthSpecId};
|
||||||
|
|
||||||
const LOG_CHANNEL_SIZE: usize = 2048;
|
const LOG_CHANNEL_SIZE: usize = 2048;
|
||||||
|
|
||||||
/// Run the bootnode given the CLI configuration.
|
/// Run the bootnode given the CLI configuration.
|
||||||
pub fn run(matches: &ArgMatches<'_>, eth_spec_id: EthSpecId, debug_level: String) {
|
pub fn run(
|
||||||
|
lh_matches: &ArgMatches<'_>,
|
||||||
|
bn_matches: &ArgMatches<'_>,
|
||||||
|
eth_spec_id: EthSpecId,
|
||||||
|
debug_level: String,
|
||||||
|
) {
|
||||||
let debug_level = match debug_level.as_str() {
|
let debug_level = match debug_level.as_str() {
|
||||||
"trace" => log::Level::Trace,
|
"trace" => log::Level::Trace,
|
||||||
"debug" => log::Level::Debug,
|
"debug" => log::Level::Debug,
|
||||||
@ -49,24 +56,40 @@ pub fn run(matches: &ArgMatches<'_>, eth_spec_id: EthSpecId, debug_level: String
|
|||||||
let log = slog_scope::logger();
|
let log = slog_scope::logger();
|
||||||
// Run the main function emitting any errors
|
// Run the main function emitting any errors
|
||||||
if let Err(e) = match eth_spec_id {
|
if let Err(e) = match eth_spec_id {
|
||||||
EthSpecId::Minimal => main::<types::MinimalEthSpec>(matches, log),
|
EthSpecId::Minimal => main::<types::MinimalEthSpec>(lh_matches, bn_matches, log),
|
||||||
EthSpecId::Mainnet => main::<types::MainnetEthSpec>(matches, log),
|
EthSpecId::Mainnet => main::<types::MainnetEthSpec>(lh_matches, bn_matches, log),
|
||||||
} {
|
} {
|
||||||
slog::crit!(slog_scope::logger(), "{}", e);
|
slog::crit!(slog_scope::logger(), "{}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main<T: EthSpec>(matches: &ArgMatches<'_>, log: slog::Logger) -> Result<(), String> {
|
fn main<T: EthSpec>(
|
||||||
|
lh_matches: &ArgMatches<'_>,
|
||||||
|
bn_matches: &ArgMatches<'_>,
|
||||||
|
log: slog::Logger,
|
||||||
|
) -> Result<(), String> {
|
||||||
// Builds a custom executor for the bootnode
|
// Builds a custom executor for the bootnode
|
||||||
let runtime = tokio::runtime::Builder::new_multi_thread()
|
let runtime = tokio::runtime::Builder::new_multi_thread()
|
||||||
.enable_all()
|
.enable_all()
|
||||||
.build()
|
.build()
|
||||||
.map_err(|e| format!("Failed to build runtime: {}", e))?;
|
.map_err(|e| format!("Failed to build runtime: {}", e))?;
|
||||||
|
|
||||||
// parse the CLI args into a useable config
|
// Parse the CLI args into a useable config
|
||||||
let config: BootNodeConfig<T> = BootNodeConfig::try_from(matches)?;
|
let config: BootNodeConfig<T> = BootNodeConfig::try_from(bn_matches)?;
|
||||||
|
|
||||||
|
// Dump config if `dump-config` flag is set
|
||||||
|
let dump_config = clap_utils::parse_optional::<PathBuf>(lh_matches, "dump-config")?;
|
||||||
|
if let Some(dump_path) = dump_config {
|
||||||
|
let config_sz = BootNodeConfigSerialization::from_config_ref(&config);
|
||||||
|
let mut file = File::create(dump_path)
|
||||||
|
.map_err(|e| format!("Failed to create dumped config: {:?}", e))?;
|
||||||
|
serde_json::to_writer(&mut file, &config_sz)
|
||||||
|
.map_err(|e| format!("Error serializing config: {:?}", e))?;
|
||||||
|
}
|
||||||
|
|
||||||
// Run the boot node
|
// Run the boot node
|
||||||
|
if !lh_matches.is_present("immediate-shutdown") {
|
||||||
runtime.block_on(server::run(config, log));
|
runtime.block_on(server::run(config, log));
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ lighthouse_version = { path = "../common/lighthouse_version" }
|
|||||||
account_utils = { path = "../common/account_utils" }
|
account_utils = { path = "../common/account_utils" }
|
||||||
lighthouse_metrics = { path = "../common/lighthouse_metrics" }
|
lighthouse_metrics = { path = "../common/lighthouse_metrics" }
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
serde = { version = "1.0.116", features = ["derive"] }
|
||||||
serde_json = "1.0.59"
|
serde_json = "1.0.59"
|
||||||
task_executor = { path = "../common/task_executor" }
|
task_executor = { path = "../common/task_executor" }
|
||||||
malloc_utils = { path = "../common/malloc_utils" }
|
malloc_utils = { path = "../common/malloc_utils" }
|
||||||
|
@ -204,7 +204,7 @@ fn main() {
|
|||||||
.expect("Debug-level must be present")
|
.expect("Debug-level must be present")
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
boot_node::run(bootnode_matches, eth_spec_id, debug_info);
|
boot_node::run(&matches, bootnode_matches, eth_spec_id, debug_info);
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,21 @@
|
|||||||
use beacon_node::ClientConfig as Config;
|
use beacon_node::ClientConfig as Config;
|
||||||
|
|
||||||
|
use crate::exec::{CommandLineTestExec, CompletedTest};
|
||||||
use lighthouse_network::PeerId;
|
use lighthouse_network::PeerId;
|
||||||
use serde_json::from_reader;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::net::{IpAddr, Ipv4Addr};
|
use std::net::{IpAddr, Ipv4Addr};
|
||||||
use std::net::{TcpListener, UdpSocket};
|
use std::net::{TcpListener, UdpSocket};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::{Command, Output};
|
use std::process::Command;
|
||||||
use std::str::{from_utf8, FromStr};
|
use std::str::FromStr;
|
||||||
use std::string::ToString;
|
use std::string::ToString;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use types::{Checkpoint, Epoch, Hash256};
|
use types::{Checkpoint, Epoch, Hash256};
|
||||||
|
|
||||||
const BEACON_CMD: &str = "beacon_node";
|
|
||||||
const CONFIG_NAME: &str = "bn_dump.json";
|
|
||||||
const DUMP_CONFIG_CMD: &str = "dump-config";
|
|
||||||
const IMMEDIATE_SHUTDOWN_CMD: &str = "immediate-shutdown";
|
|
||||||
const DEFAULT_ETH1_ENDPOINT: &str = "http://localhost:8545/";
|
const DEFAULT_ETH1_ENDPOINT: &str = "http://localhost:8545/";
|
||||||
|
|
||||||
/// Returns the `lighthouse beacon_node --immediate-shutdown` command.
|
/// Returns the `lighthouse beacon_node` command.
|
||||||
fn base_cmd() -> Command {
|
fn base_cmd() -> Command {
|
||||||
let lighthouse_bin = env!("CARGO_BIN_EXE_lighthouse");
|
let lighthouse_bin = env!("CARGO_BIN_EXE_lighthouse");
|
||||||
let path = lighthouse_bin
|
let path = lighthouse_bin
|
||||||
@ -27,25 +23,10 @@ fn base_cmd() -> Command {
|
|||||||
.expect("should parse CARGO_TARGET_DIR");
|
.expect("should parse CARGO_TARGET_DIR");
|
||||||
|
|
||||||
let mut cmd = Command::new(path);
|
let mut cmd = Command::new(path);
|
||||||
cmd.arg(BEACON_CMD)
|
cmd.arg("beacon_node");
|
||||||
.arg(format!("--{}", IMMEDIATE_SHUTDOWN_CMD));
|
|
||||||
|
|
||||||
cmd
|
cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Executes a `Command`, returning a `Result` based upon the success exit code of the command.
|
|
||||||
fn output_result(cmd: &mut Command) -> Result<Output, String> {
|
|
||||||
let output = cmd.output().expect("should run command");
|
|
||||||
|
|
||||||
if output.status.success() {
|
|
||||||
Ok(output)
|
|
||||||
} else {
|
|
||||||
Err(from_utf8(&output.stderr)
|
|
||||||
.expect("stderr is not utf8")
|
|
||||||
.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrapper around `Command` for easier Command Line Testing.
|
// Wrapper around `Command` for easier Command Line Testing.
|
||||||
struct CommandLineTest {
|
struct CommandLineTest {
|
||||||
cmd: Command,
|
cmd: Command,
|
||||||
@ -56,89 +37,24 @@ impl CommandLineTest {
|
|||||||
CommandLineTest { cmd: base_cmd }
|
CommandLineTest { cmd: base_cmd }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flag(mut self, flag: &str, value: Option<&str>) -> Self {
|
fn run_with_zero_port(&mut self) -> CompletedTest<Config> {
|
||||||
// Build the command by adding the flag and any values.
|
self.cmd.arg("-z");
|
||||||
self.cmd.arg(format!("--{}", flag));
|
self.run()
|
||||||
if let Some(value) = value {
|
|
||||||
self.cmd.arg(value);
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run(&mut self) -> CompletedTest {
|
|
||||||
// Setup temp directories.
|
|
||||||
let tmp_dir = TempDir::new().expect("Unable to create temporary directory");
|
|
||||||
let tmp_path: PathBuf = tmp_dir.path().join(CONFIG_NAME);
|
|
||||||
|
|
||||||
// Add --datadir <temp_dir> --dump-config <temp_path> -z to cmd.
|
|
||||||
self.cmd
|
|
||||||
.arg("--datadir")
|
|
||||||
.arg(tmp_dir.path().as_os_str())
|
|
||||||
.arg(format!("--{}", DUMP_CONFIG_CMD))
|
|
||||||
.arg(tmp_path.as_os_str())
|
|
||||||
.arg("-z");
|
|
||||||
|
|
||||||
// Run the command.
|
|
||||||
let output = output_result(&mut self.cmd);
|
|
||||||
if let Err(e) = output {
|
|
||||||
panic!("{:?}", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grab the config.
|
|
||||||
let config: Config =
|
|
||||||
from_reader(File::open(tmp_path).expect("Unable to open dumped config"))
|
|
||||||
.expect("Unable to deserialize to ClientConfig");
|
|
||||||
CompletedTest {
|
|
||||||
config,
|
|
||||||
dir: tmp_dir,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_with_no_zero_port(&mut self) -> CompletedTest {
|
impl CommandLineTestExec for CommandLineTest {
|
||||||
// Setup temp directories.
|
type Config = Config;
|
||||||
let tmp_dir = TempDir::new().expect("Unable to create temporary directory");
|
|
||||||
let tmp_path: PathBuf = tmp_dir.path().join(CONFIG_NAME);
|
|
||||||
|
|
||||||
// Add --datadir <temp_dir> --dump-config <temp_path> to cmd.
|
fn cmd_mut(&mut self) -> &mut Command {
|
||||||
self.cmd
|
&mut self.cmd
|
||||||
.arg("--datadir")
|
|
||||||
.arg(tmp_dir.path().as_os_str())
|
|
||||||
.arg(format!("--{}", DUMP_CONFIG_CMD))
|
|
||||||
.arg(tmp_path.as_os_str());
|
|
||||||
|
|
||||||
// Run the command.
|
|
||||||
let output = output_result(&mut self.cmd);
|
|
||||||
if let Err(e) = output {
|
|
||||||
panic!("{:?}", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grab the config.
|
|
||||||
let config: Config =
|
|
||||||
from_reader(File::open(tmp_path).expect("Unable to open dumped config"))
|
|
||||||
.expect("Unable to deserialize to ClientConfig");
|
|
||||||
CompletedTest {
|
|
||||||
config,
|
|
||||||
dir: tmp_dir,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
struct CompletedTest {
|
|
||||||
config: Config,
|
|
||||||
dir: TempDir,
|
|
||||||
}
|
|
||||||
impl CompletedTest {
|
|
||||||
fn with_config<F: Fn(&Config)>(self, func: F) {
|
|
||||||
func(&self.config);
|
|
||||||
}
|
|
||||||
fn with_config_and_dir<F: Fn(&Config, &TempDir)>(self, func: F) {
|
|
||||||
func(&self.config, &self.dir);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn datadir_flag() {
|
fn datadir_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config_and_dir(|config, dir| assert_eq!(config.data_dir, dir.path().join("beacon")));
|
.with_config_and_dir(|config, dir| assert_eq!(config.data_dir, dir.path().join("beacon")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +62,7 @@ fn datadir_flag() {
|
|||||||
fn staking_flag() {
|
fn staking_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("staking", None)
|
.flag("staking", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert!(config.http_api.enabled);
|
assert!(config.http_api.enabled);
|
||||||
assert!(config.sync_eth1_chain);
|
assert!(config.sync_eth1_chain);
|
||||||
@ -166,21 +82,21 @@ fn wss_checkpoint_flag() {
|
|||||||
"wss-checkpoint",
|
"wss-checkpoint",
|
||||||
Some("0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef:1010"),
|
Some("0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef:1010"),
|
||||||
)
|
)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.chain.weak_subjectivity_checkpoint, state));
|
.with_config(|config| assert_eq!(config.chain.weak_subjectivity_checkpoint, state));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn max_skip_slots_flag() {
|
fn max_skip_slots_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("max-skip-slots", Some("10"))
|
.flag("max-skip-slots", Some("10"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.chain.import_max_skip_slots, Some(10)));
|
.with_config(|config| assert_eq!(config.chain.import_max_skip_slots, Some(10)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn enable_lock_timeouts_default() {
|
fn enable_lock_timeouts_default() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(config.chain.enable_lock_timeouts));
|
.with_config(|config| assert!(config.chain.enable_lock_timeouts));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +104,7 @@ fn enable_lock_timeouts_default() {
|
|||||||
fn disable_lock_timeouts_flag() {
|
fn disable_lock_timeouts_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("disable-lock-timeouts", None)
|
.flag("disable-lock-timeouts", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(!config.chain.enable_lock_timeouts));
|
.with_config(|config| assert!(!config.chain.enable_lock_timeouts));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +113,7 @@ fn freezer_dir_flag() {
|
|||||||
let dir = TempDir::new().expect("Unable to create temporary directory");
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("freezer-dir", dir.path().as_os_str().to_str())
|
.flag("freezer-dir", dir.path().as_os_str().to_str())
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.freezer_db_path, Some(dir.path().to_path_buf())));
|
.with_config(|config| assert_eq!(config.freezer_db_path, Some(dir.path().to_path_buf())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +121,7 @@ fn freezer_dir_flag() {
|
|||||||
fn graffiti_flag() {
|
fn graffiti_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("graffiti", Some("nice-graffiti"))
|
.flag("graffiti", Some("nice-graffiti"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.graffiti.to_string(),
|
config.graffiti.to_string(),
|
||||||
@ -222,7 +138,7 @@ fn trusted_peers_flag() {
|
|||||||
"trusted-peers",
|
"trusted-peers",
|
||||||
Some(format!("{},{}", peers[0].to_string(), peers[1].to_string()).as_str()),
|
Some(format!("{},{}", peers[0].to_string(), peers[1].to_string()).as_str()),
|
||||||
)
|
)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
PeerId::from(config.network.trusted_peers[0].clone()).to_bytes(),
|
PeerId::from(config.network.trusted_peers[0].clone()).to_bytes(),
|
||||||
@ -240,14 +156,14 @@ fn trusted_peers_flag() {
|
|||||||
fn dummy_eth1_flag() {
|
fn dummy_eth1_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("dummy-eth1", None)
|
.flag("dummy-eth1", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(config.dummy_eth1_backend));
|
.with_config(|config| assert!(config.dummy_eth1_backend));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn eth1_flag() {
|
fn eth1_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("eth1", None)
|
.flag("eth1", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(config.sync_eth1_chain));
|
.with_config(|config| assert!(config.sync_eth1_chain));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -257,7 +173,7 @@ fn eth1_endpoints_flag() {
|
|||||||
"eth1-endpoints",
|
"eth1-endpoints",
|
||||||
Some("http://localhost:9545,https://infura.io/secret"),
|
Some("http://localhost:9545,https://infura.io/secret"),
|
||||||
)
|
)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.eth1.endpoints[0].full.to_string(),
|
config.eth1.endpoints[0].full.to_string(),
|
||||||
@ -279,14 +195,14 @@ fn eth1_endpoints_flag() {
|
|||||||
fn eth1_blocks_per_log_query_flag() {
|
fn eth1_blocks_per_log_query_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("eth1-blocks-per-log-query", Some("500"))
|
.flag("eth1-blocks-per-log-query", Some("500"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.eth1.blocks_per_log_query, 500));
|
.with_config(|config| assert_eq!(config.eth1.blocks_per_log_query, 500));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn eth1_purge_cache_flag() {
|
fn eth1_purge_cache_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("eth1-purge-cache", None)
|
.flag("eth1-purge-cache", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(config.eth1.purge_cache));
|
.with_config(|config| assert!(config.eth1.purge_cache));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,14 +212,14 @@ fn network_dir_flag() {
|
|||||||
let dir = TempDir::new().expect("Unable to create temporary directory");
|
let dir = TempDir::new().expect("Unable to create temporary directory");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("network-dir", dir.path().as_os_str().to_str())
|
.flag("network-dir", dir.path().as_os_str().to_str())
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.network.network_dir, dir.path()));
|
.with_config(|config| assert_eq!(config.network.network_dir, dir.path()));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn network_target_peers_flag() {
|
fn network_target_peers_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("target-peers", Some("55"))
|
.flag("target-peers", Some("55"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.target_peers, "55".parse::<usize>().unwrap());
|
assert_eq!(config.network.target_peers, "55".parse::<usize>().unwrap());
|
||||||
});
|
});
|
||||||
@ -312,27 +228,27 @@ fn network_target_peers_flag() {
|
|||||||
fn network_subscribe_all_subnets_flag() {
|
fn network_subscribe_all_subnets_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("subscribe-all-subnets", None)
|
.flag("subscribe-all-subnets", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(config.network.subscribe_all_subnets));
|
.with_config(|config| assert!(config.network.subscribe_all_subnets));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn network_import_all_attestations_flag() {
|
fn network_import_all_attestations_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("import-all-attestations", None)
|
.flag("import-all-attestations", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(config.network.import_all_attestations));
|
.with_config(|config| assert!(config.network.import_all_attestations));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn network_shutdown_after_sync_flag() {
|
fn network_shutdown_after_sync_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("shutdown-after-sync", None)
|
.flag("shutdown-after-sync", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(config.network.shutdown_after_sync));
|
.with_config(|config| assert!(config.network.shutdown_after_sync));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn network_shutdown_after_sync_disabled_flag() {
|
fn network_shutdown_after_sync_disabled_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(!config.network.shutdown_after_sync));
|
.with_config(|config| assert!(!config.network.shutdown_after_sync));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -340,7 +256,7 @@ fn network_listen_address_flag() {
|
|||||||
let addr = "127.0.0.2".parse::<Ipv4Addr>().unwrap();
|
let addr = "127.0.0.2".parse::<Ipv4Addr>().unwrap();
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("listen-address", Some("127.0.0.2"))
|
.flag("listen-address", Some("127.0.0.2"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.network.listen_address, addr));
|
.with_config(|config| assert_eq!(config.network.listen_address, addr));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -348,7 +264,7 @@ fn network_port_flag() {
|
|||||||
let port = unused_port("tcp").expect("Unable to find unused port.");
|
let port = unused_port("tcp").expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("port", Some(port.to_string().as_str()))
|
.flag("port", Some(port.to_string().as_str()))
|
||||||
.run_with_no_zero_port()
|
.run()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.libp2p_port, port);
|
assert_eq!(config.network.libp2p_port, port);
|
||||||
assert_eq!(config.network.discovery_port, port);
|
assert_eq!(config.network.discovery_port, port);
|
||||||
@ -361,7 +277,7 @@ fn network_port_and_discovery_port_flags() {
|
|||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("port", Some(port1.to_string().as_str()))
|
.flag("port", Some(port1.to_string().as_str()))
|
||||||
.flag("discovery-port", Some(port2.to_string().as_str()))
|
.flag("discovery-port", Some(port2.to_string().as_str()))
|
||||||
.run_with_no_zero_port()
|
.run()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.libp2p_port, port1);
|
assert_eq!(config.network.libp2p_port, port1);
|
||||||
assert_eq!(config.network.discovery_port, port2);
|
assert_eq!(config.network.discovery_port, port2);
|
||||||
@ -371,14 +287,14 @@ fn network_port_and_discovery_port_flags() {
|
|||||||
fn disable_discovery_flag() {
|
fn disable_discovery_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("disable-discovery", None)
|
.flag("disable-discovery", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(config.network.disable_discovery));
|
.with_config(|config| assert!(config.network.disable_discovery));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn disable_upnp_flag() {
|
fn disable_upnp_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("disable-upnp", None)
|
.flag("disable-upnp", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(!config.network.upnp_enabled));
|
.with_config(|config| assert!(!config.network.upnp_enabled));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -404,7 +320,9 @@ fn default_boot_nodes() {
|
|||||||
"enr:-LK4QKWrXTpV9T78hNG6s8AM6IO4XH9kFT91uZtFg1GcsJ6dKovDOr1jtAAFPnS2lvNltkOGA9k29BUN7lFh_sjuc9QBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhANAdd-Jc2VjcDI1NmsxoQLQa6ai7y9PMN5hpLe5HmiJSlYzMuzP7ZhwRiwHvqNXdoN0Y3CCI4yDdWRwgiOM"
|
"enr:-LK4QKWrXTpV9T78hNG6s8AM6IO4XH9kFT91uZtFg1GcsJ6dKovDOr1jtAAFPnS2lvNltkOGA9k29BUN7lFh_sjuc9QBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhANAdd-Jc2VjcDI1NmsxoQLQa6ai7y9PMN5hpLe5HmiJSlYzMuzP7ZhwRiwHvqNXdoN0Y3CCI4yDdWRwgiOM"
|
||||||
];
|
];
|
||||||
|
|
||||||
CommandLineTest::new().run().with_config(|config| {
|
CommandLineTest::new()
|
||||||
|
.run_with_zero_port()
|
||||||
|
.with_config(|config| {
|
||||||
// Lighthouse Team (Sigma Prime)
|
// Lighthouse Team (Sigma Prime)
|
||||||
assert_eq!(config.network.boot_nodes_enr[0].to_base64(), mainnet[0]);
|
assert_eq!(config.network.boot_nodes_enr[0].to_base64(), mainnet[0]);
|
||||||
assert_eq!(config.network.boot_nodes_enr[1].to_base64(), mainnet[1]);
|
assert_eq!(config.network.boot_nodes_enr[1].to_base64(), mainnet[1]);
|
||||||
@ -432,7 +350,7 @@ fn boot_nodes_flag() {
|
|||||||
let enr: Vec<&str> = nodes.split(',').collect();
|
let enr: Vec<&str> = nodes.split(',').collect();
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("boot-nodes", Some(nodes))
|
.flag("boot-nodes", Some(nodes))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.boot_nodes_enr[0].to_base64(), enr[0]);
|
assert_eq!(config.network.boot_nodes_enr[0].to_base64(), enr[0]);
|
||||||
assert_eq!(config.network.boot_nodes_enr[1].to_base64(), enr[1]);
|
assert_eq!(config.network.boot_nodes_enr[1].to_base64(), enr[1]);
|
||||||
@ -445,7 +363,7 @@ fn boot_nodes_multiaddr_flag() {
|
|||||||
let multiaddr: Vec<&str> = nodes.split(',').collect();
|
let multiaddr: Vec<&str> = nodes.split(',').collect();
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("boot-nodes", Some(nodes))
|
.flag("boot-nodes", Some(nodes))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.network.boot_nodes_multiaddr[0].to_string(),
|
config.network.boot_nodes_multiaddr[0].to_string(),
|
||||||
@ -461,12 +379,14 @@ fn boot_nodes_multiaddr_flag() {
|
|||||||
fn private_flag() {
|
fn private_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("private", None)
|
.flag("private", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(config.network.private));
|
.with_config(|config| assert!(config.network.private));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn zero_ports_flag() {
|
fn zero_ports_flag() {
|
||||||
CommandLineTest::new().run().with_config(|config| {
|
CommandLineTest::new()
|
||||||
|
.run_with_zero_port()
|
||||||
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.enr_address, None);
|
assert_eq!(config.network.enr_address, None);
|
||||||
assert_eq!(config.http_api.listen_port, 0);
|
assert_eq!(config.http_api.listen_port, 0);
|
||||||
assert_eq!(config.http_metrics.listen_port, 0);
|
assert_eq!(config.http_metrics.listen_port, 0);
|
||||||
@ -479,7 +399,7 @@ fn enr_udp_port_flags() {
|
|||||||
let port = unused_port("udp").expect("Unable to find unused port.");
|
let port = unused_port("udp").expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.network.enr_udp_port, Some(port)));
|
.with_config(|config| assert_eq!(config.network.enr_udp_port, Some(port)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -487,7 +407,7 @@ fn enr_tcp_port_flags() {
|
|||||||
let port = unused_port("tcp").expect("Unable to find unused port.");
|
let port = unused_port("tcp").expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-tcp-port", Some(port.to_string().as_str()))
|
.flag("enr-tcp-port", Some(port.to_string().as_str()))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.network.enr_tcp_port, Some(port)));
|
.with_config(|config| assert_eq!(config.network.enr_tcp_port, Some(port)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -500,7 +420,7 @@ fn enr_match_flag() {
|
|||||||
.flag("listen-address", Some("127.0.0.2"))
|
.flag("listen-address", Some("127.0.0.2"))
|
||||||
.flag("discovery-port", Some(port1.to_string().as_str()))
|
.flag("discovery-port", Some(port1.to_string().as_str()))
|
||||||
.flag("port", Some(port2.to_string().as_str()))
|
.flag("port", Some(port2.to_string().as_str()))
|
||||||
.run_with_no_zero_port()
|
.run()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.listen_address, addr);
|
assert_eq!(config.network.listen_address, addr);
|
||||||
assert_eq!(config.network.enr_address, Some(addr));
|
assert_eq!(config.network.enr_address, Some(addr));
|
||||||
@ -515,7 +435,7 @@ fn enr_address_flag() {
|
|||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-address", Some("192.167.1.1"))
|
.flag("enr-address", Some("192.167.1.1"))
|
||||||
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.enr_address, Some(addr));
|
assert_eq!(config.network.enr_address, Some(addr));
|
||||||
assert_eq!(config.network.enr_udp_port, Some(port));
|
assert_eq!(config.network.enr_udp_port, Some(port));
|
||||||
@ -529,7 +449,7 @@ fn enr_address_dns_flag() {
|
|||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-address", Some("localhost"))
|
.flag("enr-address", Some("localhost"))
|
||||||
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert!(
|
assert!(
|
||||||
config.network.enr_address == Some(addr)
|
config.network.enr_address == Some(addr)
|
||||||
@ -542,7 +462,7 @@ fn enr_address_dns_flag() {
|
|||||||
fn disable_enr_auto_update_flag() {
|
fn disable_enr_auto_update_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("disable-enr-auto-update", None)
|
.flag("disable-enr-auto-update", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(config.network.discv5_config.enr_update));
|
.with_config(|config| assert!(config.network.discv5_config.enr_update));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,7 +471,7 @@ fn disable_enr_auto_update_flag() {
|
|||||||
fn http_flag() {
|
fn http_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("http", None)
|
.flag("http", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(config.http_api.enabled));
|
.with_config(|config| assert!(config.http_api.enabled));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -559,7 +479,7 @@ fn http_address_flag() {
|
|||||||
let addr = "127.0.0.99".parse::<Ipv4Addr>().unwrap();
|
let addr = "127.0.0.99".parse::<Ipv4Addr>().unwrap();
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("http-address", Some("127.0.0.99"))
|
.flag("http-address", Some("127.0.0.99"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.http_api.listen_addr, addr));
|
.with_config(|config| assert_eq!(config.http_api.listen_addr, addr));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -569,14 +489,14 @@ fn http_port_flag() {
|
|||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("http-port", Some(port1.to_string().as_str()))
|
.flag("http-port", Some(port1.to_string().as_str()))
|
||||||
.flag("port", Some(port2.to_string().as_str()))
|
.flag("port", Some(port2.to_string().as_str()))
|
||||||
.run_with_no_zero_port()
|
.run()
|
||||||
.with_config(|config| assert_eq!(config.http_api.listen_port, port1));
|
.with_config(|config| assert_eq!(config.http_api.listen_port, port1));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn http_allow_origin_flag() {
|
fn http_allow_origin_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("http-allow-origin", Some("127.0.0.99"))
|
.flag("http-allow-origin", Some("127.0.0.99"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.http_api.allow_origin, Some("127.0.0.99".to_string()));
|
assert_eq!(config.http_api.allow_origin, Some("127.0.0.99".to_string()));
|
||||||
});
|
});
|
||||||
@ -585,7 +505,7 @@ fn http_allow_origin_flag() {
|
|||||||
fn http_allow_origin_all_flag() {
|
fn http_allow_origin_all_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("http-allow-origin", Some("*"))
|
.flag("http-allow-origin", Some("*"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.http_api.allow_origin, Some("*".to_string())));
|
.with_config(|config| assert_eq!(config.http_api.allow_origin, Some("*".to_string())));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -601,7 +521,7 @@ fn http_tls_flags() {
|
|||||||
"http-tls-key",
|
"http-tls-key",
|
||||||
dir.path().join("private.key").as_os_str().to_str(),
|
dir.path().join("private.key").as_os_str().to_str(),
|
||||||
)
|
)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
let tls_config = config
|
let tls_config = config
|
||||||
.http_api
|
.http_api
|
||||||
@ -618,7 +538,7 @@ fn http_tls_flags() {
|
|||||||
fn metrics_flag() {
|
fn metrics_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("metrics", None)
|
.flag("metrics", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert!(config.http_metrics.enabled);
|
assert!(config.http_metrics.enabled);
|
||||||
assert!(config.network.metrics_enabled);
|
assert!(config.network.metrics_enabled);
|
||||||
@ -630,7 +550,7 @@ fn metrics_address_flag() {
|
|||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("metrics", None)
|
.flag("metrics", None)
|
||||||
.flag("metrics-address", Some("127.0.0.99"))
|
.flag("metrics-address", Some("127.0.0.99"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.http_metrics.listen_addr, addr));
|
.with_config(|config| assert_eq!(config.http_metrics.listen_addr, addr));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -641,7 +561,7 @@ fn metrics_port_flag() {
|
|||||||
.flag("metrics", None)
|
.flag("metrics", None)
|
||||||
.flag("metrics-port", Some(port1.to_string().as_str()))
|
.flag("metrics-port", Some(port1.to_string().as_str()))
|
||||||
.flag("port", Some(port2.to_string().as_str()))
|
.flag("port", Some(port2.to_string().as_str()))
|
||||||
.run_with_no_zero_port()
|
.run()
|
||||||
.with_config(|config| assert_eq!(config.http_metrics.listen_port, port1));
|
.with_config(|config| assert_eq!(config.http_metrics.listen_port, port1));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -649,7 +569,7 @@ fn metrics_allow_origin_flag() {
|
|||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("metrics", None)
|
.flag("metrics", None)
|
||||||
.flag("metrics-allow-origin", Some("http://localhost:5059"))
|
.flag("metrics-allow-origin", Some("http://localhost:5059"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.http_metrics.allow_origin,
|
config.http_metrics.allow_origin,
|
||||||
@ -662,7 +582,7 @@ fn metrics_allow_origin_all_flag() {
|
|||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("metrics", None)
|
.flag("metrics", None)
|
||||||
.flag("metrics-allow-origin", Some("*"))
|
.flag("metrics-allow-origin", Some("*"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.http_metrics.allow_origin, Some("*".to_string())));
|
.with_config(|config| assert_eq!(config.http_metrics.allow_origin, Some("*".to_string())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,7 +591,7 @@ fn metrics_allow_origin_all_flag() {
|
|||||||
fn validator_monitor_auto_flag() {
|
fn validator_monitor_auto_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("validator-monitor-auto", None)
|
.flag("validator-monitor-auto", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(config.validator_monitor_auto));
|
.with_config(|config| assert!(config.validator_monitor_auto));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -679,7 +599,7 @@ fn validator_monitor_pubkeys_flag() {
|
|||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("validator-monitor-pubkeys", Some("0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef,\
|
.flag("validator-monitor-pubkeys", Some("0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef,\
|
||||||
0xbeefdeadbeefdeaddeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"))
|
0xbeefdeadbeefdeaddeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.validator_monitor_pubkeys[0].to_string(), "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
assert_eq!(config.validator_monitor_pubkeys[0].to_string(), "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
||||||
assert_eq!(config.validator_monitor_pubkeys[1].to_string(), "0xbeefdeadbeefdeaddeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
assert_eq!(config.validator_monitor_pubkeys[1].to_string(), "0xbeefdeadbeefdeaddeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
||||||
@ -694,7 +614,7 @@ fn validator_monitor_file_flag() {
|
|||||||
.expect("Unable to write to file");
|
.expect("Unable to write to file");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("validator-monitor-file", dir.path().join("pubkeys.txt").as_os_str().to_str())
|
.flag("validator-monitor-file", dir.path().join("pubkeys.txt").as_os_str().to_str())
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.validator_monitor_pubkeys[0].to_string(), "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
assert_eq!(config.validator_monitor_pubkeys[0].to_string(), "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
||||||
assert_eq!(config.validator_monitor_pubkeys[1].to_string(), "0xbeefdeadbeefdeaddeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
assert_eq!(config.validator_monitor_pubkeys[1].to_string(), "0xbeefdeadbeefdeaddeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
||||||
@ -706,21 +626,21 @@ fn validator_monitor_file_flag() {
|
|||||||
fn slots_per_restore_point_flag() {
|
fn slots_per_restore_point_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("slots-per-restore-point", Some("64"))
|
.flag("slots-per-restore-point", Some("64"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.store.slots_per_restore_point, 64));
|
.with_config(|config| assert_eq!(config.store.slots_per_restore_point, 64));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn block_cache_size_flag() {
|
fn block_cache_size_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("block-cache-size", Some("4"))
|
.flag("block-cache-size", Some("4"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.store.block_cache_size, 4_usize));
|
.with_config(|config| assert_eq!(config.store.block_cache_size, 4_usize));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn auto_compact_db_flag() {
|
fn auto_compact_db_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("auto-compact-db", Some("false"))
|
.flag("auto-compact-db", Some("false"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(!config.store.compact_on_prune));
|
.with_config(|config| assert!(!config.store.compact_on_prune));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -728,20 +648,20 @@ fn compact_db_flag() {
|
|||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("auto-compact-db", Some("false"))
|
.flag("auto-compact-db", Some("false"))
|
||||||
.flag("compact-db", None)
|
.flag("compact-db", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(config.store.compact_on_init));
|
.with_config(|config| assert!(config.store.compact_on_init));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn reconstruct_historic_states_flag() {
|
fn reconstruct_historic_states_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("reconstruct-historic-states", None)
|
.flag("reconstruct-historic-states", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(config.chain.reconstruct_historic_states));
|
.with_config(|config| assert!(config.chain.reconstruct_historic_states));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn no_reconstruct_historic_states_flag() {
|
fn no_reconstruct_historic_states_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert!(!config.chain.reconstruct_historic_states));
|
.with_config(|config| assert!(!config.chain.reconstruct_historic_states));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,7 +671,7 @@ fn slasher_flag() {
|
|||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("slasher", None)
|
.flag("slasher", None)
|
||||||
.flag("slasher-max-db-size", Some("16"))
|
.flag("slasher-max-db-size", Some("16"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config_and_dir(|config, dir| {
|
.with_config_and_dir(|config, dir| {
|
||||||
if let Some(slasher_config) = &config.slasher {
|
if let Some(slasher_config) = &config.slasher {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -770,7 +690,7 @@ fn slasher_dir_flag() {
|
|||||||
.flag("slasher", None)
|
.flag("slasher", None)
|
||||||
.flag("slasher-dir", dir.path().as_os_str().to_str())
|
.flag("slasher-dir", dir.path().as_os_str().to_str())
|
||||||
.flag("slasher-max-db-size", Some("16"))
|
.flag("slasher-max-db-size", Some("16"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
if let Some(slasher_config) = &config.slasher {
|
if let Some(slasher_config) = &config.slasher {
|
||||||
assert_eq!(slasher_config.database_path, dir.path());
|
assert_eq!(slasher_config.database_path, dir.path());
|
||||||
@ -785,7 +705,7 @@ fn slasher_update_period_flag() {
|
|||||||
.flag("slasher", None)
|
.flag("slasher", None)
|
||||||
.flag("slasher-max-db-size", Some("16"))
|
.flag("slasher-max-db-size", Some("16"))
|
||||||
.flag("slasher-update-period", Some("100"))
|
.flag("slasher-update-period", Some("100"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
if let Some(slasher_config) = &config.slasher {
|
if let Some(slasher_config) = &config.slasher {
|
||||||
assert_eq!(slasher_config.update_period, 100);
|
assert_eq!(slasher_config.update_period, 100);
|
||||||
@ -819,7 +739,7 @@ fn slasher_history_length_flag() {
|
|||||||
.flag("slasher", None)
|
.flag("slasher", None)
|
||||||
.flag("slasher-max-db-size", Some("16"))
|
.flag("slasher-max-db-size", Some("16"))
|
||||||
.flag("slasher-history-length", Some("2048"))
|
.flag("slasher-history-length", Some("2048"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
if let Some(slasher_config) = &config.slasher {
|
if let Some(slasher_config) = &config.slasher {
|
||||||
assert_eq!(slasher_config.history_length, 2048);
|
assert_eq!(slasher_config.history_length, 2048);
|
||||||
@ -833,7 +753,7 @@ fn slasher_max_db_size_flag() {
|
|||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("slasher", None)
|
.flag("slasher", None)
|
||||||
.flag("slasher-max-db-size", Some("10"))
|
.flag("slasher-max-db-size", Some("10"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
let slasher_config = config
|
let slasher_config = config
|
||||||
.slasher
|
.slasher
|
||||||
@ -848,7 +768,7 @@ fn slasher_chunk_size_flag() {
|
|||||||
.flag("slasher", None)
|
.flag("slasher", None)
|
||||||
.flag("slasher-chunk-size", Some("32"))
|
.flag("slasher-chunk-size", Some("32"))
|
||||||
.flag("slasher-max-db-size", Some("16"))
|
.flag("slasher-max-db-size", Some("16"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
let slasher_config = config
|
let slasher_config = config
|
||||||
.slasher
|
.slasher
|
||||||
@ -863,7 +783,7 @@ fn slasher_validator_chunk_size_flag() {
|
|||||||
.flag("slasher", None)
|
.flag("slasher", None)
|
||||||
.flag("slasher-max-db-size", Some("16"))
|
.flag("slasher-max-db-size", Some("16"))
|
||||||
.flag("slasher-validator-chunk-size", Some("512"))
|
.flag("slasher-validator-chunk-size", Some("512"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
let slasher_config = config
|
let slasher_config = config
|
||||||
.slasher
|
.slasher
|
||||||
@ -878,7 +798,7 @@ fn slasher_broadcast_flag() {
|
|||||||
.flag("slasher", None)
|
.flag("slasher", None)
|
||||||
.flag("slasher-broadcast", None)
|
.flag("slasher-broadcast", None)
|
||||||
.flag("slasher-max-db-size", Some("16"))
|
.flag("slasher-max-db-size", Some("16"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
let slasher_config = config
|
let slasher_config = config
|
||||||
.slasher
|
.slasher
|
||||||
@ -891,7 +811,7 @@ fn slasher_broadcast_flag() {
|
|||||||
pub fn malloc_tuning_flag() {
|
pub fn malloc_tuning_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("disable-malloc-tuning", None)
|
.flag("disable-malloc-tuning", None)
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert!(!config.http_metrics.allocator_metrics_enabled);
|
assert!(!config.http_metrics.allocator_metrics_enabled);
|
||||||
});
|
});
|
||||||
@ -902,7 +822,7 @@ fn ensure_panic_on_failed_launch() {
|
|||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("slasher", None)
|
.flag("slasher", None)
|
||||||
.flag("slasher-chunk-size", Some("10"))
|
.flag("slasher-chunk-size", Some("10"))
|
||||||
.run()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
let slasher_config = config
|
let slasher_config = config
|
||||||
.slasher
|
.slasher
|
||||||
|
164
lighthouse/tests/boot_node.rs
Normal file
164
lighthouse/tests/boot_node.rs
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
use boot_node::config::BootNodeConfigSerialization;
|
||||||
|
|
||||||
|
use crate::exec::{CommandLineTestExec, CompletedTest};
|
||||||
|
use beacon_node::get_eth2_network_config;
|
||||||
|
use clap::ArgMatches;
|
||||||
|
use lighthouse_network::discovery::ENR_FILENAME;
|
||||||
|
use lighthouse_network::Enr;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::net::{Ipv4Addr, UdpSocket};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::Command;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use tempfile::TempDir;
|
||||||
|
|
||||||
|
const IP_ADDRESS: &str = "192.168.2.108";
|
||||||
|
|
||||||
|
/// Returns the `lighthouse boot_node` command.
|
||||||
|
fn base_cmd() -> Command {
|
||||||
|
let lighthouse_bin = env!("CARGO_BIN_EXE_lighthouse");
|
||||||
|
let path = lighthouse_bin
|
||||||
|
.parse::<PathBuf>()
|
||||||
|
.expect("should parse CARGO_TARGET_DIR");
|
||||||
|
|
||||||
|
let mut cmd = Command::new(path);
|
||||||
|
cmd.arg("boot_node");
|
||||||
|
cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CommandLineTest {
|
||||||
|
cmd: Command,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CommandLineTest {
|
||||||
|
fn new() -> CommandLineTest {
|
||||||
|
let base_cmd = base_cmd();
|
||||||
|
CommandLineTest { cmd: base_cmd }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_with_ip(&mut self) -> CompletedTest<BootNodeConfigSerialization> {
|
||||||
|
self.cmd.arg(IP_ADDRESS);
|
||||||
|
self.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CommandLineTestExec for CommandLineTest {
|
||||||
|
type Config = BootNodeConfigSerialization;
|
||||||
|
|
||||||
|
fn cmd_mut(&mut self) -> &mut Command {
|
||||||
|
&mut self.cmd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unused_port() -> u16 {
|
||||||
|
let socket =
|
||||||
|
UdpSocket::bind("127.0.0.1:0").expect("should create udp socket to find unused port");
|
||||||
|
let local_addr = socket
|
||||||
|
.local_addr()
|
||||||
|
.expect("should read udp socket to find unused port");
|
||||||
|
local_addr.port()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn enr_address_arg() {
|
||||||
|
let mut test = CommandLineTest::new();
|
||||||
|
test.run_with_ip().with_config(|config| {
|
||||||
|
assert_eq!(config.local_enr.ip(), Some(IP_ADDRESS.parse().unwrap()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn port_flag() {
|
||||||
|
let port = unused_port();
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("port", Some(port.to_string().as_str()))
|
||||||
|
.run_with_ip()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(config.listen_socket.port(), port);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn listen_address_flag() {
|
||||||
|
let addr = "127.0.0.2".parse::<Ipv4Addr>().unwrap();
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("listen-address", Some("127.0.0.2"))
|
||||||
|
.run_with_ip()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(config.listen_socket.ip(), addr);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn boot_nodes_flag() {
|
||||||
|
// Get hardcoded boot-nodes to verify they end up in the config.
|
||||||
|
// Pass empty `ArgMatches` to `get_eth2_network_config` as we want to
|
||||||
|
// receive the default `Eth2NetworkConfig`.
|
||||||
|
let empty_args = ArgMatches::default();
|
||||||
|
let default_enr = get_eth2_network_config(&empty_args)
|
||||||
|
.unwrap()
|
||||||
|
.boot_enr
|
||||||
|
.unwrap();
|
||||||
|
let default_enr: Vec<String> = default_enr.iter().map(|enr| enr.to_base64()).collect();
|
||||||
|
|
||||||
|
// Nodes passed via `--boot-nodes` are added to the local routing table.
|
||||||
|
let extra_nodes = "enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOonrkTfj499SZuOh8R33Ls8RRcy5wBgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPKY0yuDUmstAHYpMa2_oxVtw0RW_QAdpzBQA8yWM0xOIN1ZHCCdl8,enr:-LK4QFOFWca5ABQzxiCRcy37G7wy1K6zD4qMYBSN5ozzanwze_XVvXVhCk9JvF0cHXOBZrHK1E4vU7Gn-a0bHVczoDU6h2F0dG5ldHOIAAAAAAAAAACEZXRoMpA7CIeVAAAgCf__________gmlkgnY0gmlwhNIy-4iJc2VjcDI1NmsxoQJA3AXQJ6M3NpBWtJS3HPtbXG14t7qHjXuIaL6IOz89T4N0Y3CCIyiDdWRwgiMo";
|
||||||
|
let extra_enr: Vec<&str> = extra_nodes.split(",").collect();
|
||||||
|
|
||||||
|
// Construct vector of enr expected in config.
|
||||||
|
let default_enr_str: Vec<&str> = default_enr.iter().map(|s| s.as_str()).collect();
|
||||||
|
let mut expect_enr = Vec::new();
|
||||||
|
expect_enr.extend_from_slice(&default_enr_str);
|
||||||
|
expect_enr.extend_from_slice(&extra_enr);
|
||||||
|
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("boot-nodes", Some(extra_nodes))
|
||||||
|
.run_with_ip()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(config.boot_nodes.len(), expect_enr.len());
|
||||||
|
for (i, enr) in config.boot_nodes.iter().enumerate() {
|
||||||
|
assert_eq!(
|
||||||
|
enr.to_base64(),
|
||||||
|
expect_enr[i],
|
||||||
|
"ENR missmatch at index [{}]",
|
||||||
|
i
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn enr_port_flag() {
|
||||||
|
let port = unused_port();
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("enr-port", Some(port.to_string().as_str()))
|
||||||
|
.run_with_ip()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(config.local_enr.udp(), Some(port));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO add tests for flags `enable-enr-auto-update` and `disable-packet-filter`.
|
||||||
|
//
|
||||||
|
// These options end up in `Discv5Config`, which doesn't support serde (de)serialization.
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn network_dir_flag() {
|
||||||
|
// Save enr to temp dir.
|
||||||
|
let enr = Enr::from_str("enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOonrkTfj499SZuOh8R33Ls8RRcy5wBgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPKY0yuDUmstAHYpMa2_oxVtw0RW_QAdpzBQA8yWM0xOIN1ZHCCdl8").unwrap();
|
||||||
|
let tmp_dir = TempDir::new().unwrap();
|
||||||
|
save_enr_to_disk(tmp_dir.path(), &enr).unwrap();
|
||||||
|
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("network-dir", Some(tmp_dir.path().to_str().unwrap()))
|
||||||
|
.run()
|
||||||
|
.with_config(|config| assert_eq!(config.local_enr, enr))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save_enr_to_disk(dir: &Path, enr: &Enr) -> Result<(), String> {
|
||||||
|
let mut file = File::create(dir.join(Path::new(ENR_FILENAME)))
|
||||||
|
.map_err(|e| format!("Could not create ENR file: {:?}", e))?;
|
||||||
|
file.write_all(enr.to_base64().as_bytes())
|
||||||
|
.map_err(|e| format!("Could not write ENR to file: {:?}", e))
|
||||||
|
}
|
113
lighthouse/tests/exec.rs
Normal file
113
lighthouse/tests/exec.rs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
use serde_json::from_reader;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::process::{Command, Output};
|
||||||
|
use std::str::from_utf8;
|
||||||
|
use tempfile::TempDir;
|
||||||
|
|
||||||
|
pub trait CommandLineTestExec {
|
||||||
|
type Config: DeserializeOwned;
|
||||||
|
|
||||||
|
fn cmd_mut(&mut self) -> &mut Command;
|
||||||
|
|
||||||
|
/// Adds a flag with optional value to the command.
|
||||||
|
fn flag(&mut self, flag: &str, value: Option<&str>) -> &mut Self {
|
||||||
|
self.cmd_mut().arg(format!("--{}", flag));
|
||||||
|
if let Some(value) = value {
|
||||||
|
self.cmd_mut().arg(value);
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Executes the `Command` returned by `Self::cmd_mut` with temporary data directory, dumps
|
||||||
|
/// the configuration and shuts down immediately.
|
||||||
|
///
|
||||||
|
/// Options `--datadir`, `--dump-config` and `--immediate-shutdown` must not be set on the
|
||||||
|
/// command.
|
||||||
|
fn run(&mut self) -> CompletedTest<Self::Config> {
|
||||||
|
// Setup temp directory.
|
||||||
|
let tmp_dir = TempDir::new().expect("Unable to create temporary directory");
|
||||||
|
let tmp_config_path: PathBuf = tmp_dir.path().join("config.json");
|
||||||
|
|
||||||
|
// Add args --datadir <tmp_dir> --dump-config <tmp_config_path> --immediate-shutdown
|
||||||
|
let cmd = self.cmd_mut();
|
||||||
|
cmd.arg("--datadir")
|
||||||
|
.arg(tmp_dir.path().as_os_str())
|
||||||
|
.arg(format!("--{}", "--dump-config"))
|
||||||
|
.arg(tmp_config_path.as_os_str())
|
||||||
|
.arg("--immediate-shutdown");
|
||||||
|
|
||||||
|
// Run the command.
|
||||||
|
let output = output_result(cmd);
|
||||||
|
if let Err(e) = output {
|
||||||
|
panic!("{:?}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab the config.
|
||||||
|
let config_file = File::open(tmp_config_path).expect("Unable to open dumped config");
|
||||||
|
let config: Self::Config = from_reader(config_file).expect("Unable to deserialize config");
|
||||||
|
|
||||||
|
CompletedTest::new(config, tmp_dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Executes the `Command` returned by `Self::cmd_mut` dumps the configuration and
|
||||||
|
/// shuts down immediately.
|
||||||
|
///
|
||||||
|
/// Options `--dump-config` and `--immediate-shutdown` must not be set on the command.
|
||||||
|
fn run_with_no_datadir(&mut self) -> CompletedTest<Self::Config> {
|
||||||
|
// Setup temp directory.
|
||||||
|
let tmp_dir = TempDir::new().expect("Unable to create temporary directory");
|
||||||
|
let tmp_config_path: PathBuf = tmp_dir.path().join("config.json");
|
||||||
|
|
||||||
|
// Add args --datadir <tmp_dir> --dump-config <tmp_config_path> --immediate-shutdown
|
||||||
|
let cmd = self.cmd_mut();
|
||||||
|
cmd.arg(format!("--{}", "--dump-config"))
|
||||||
|
.arg(tmp_config_path.as_os_str())
|
||||||
|
.arg("--immediate-shutdown");
|
||||||
|
|
||||||
|
// Run the command.
|
||||||
|
let output = output_result(cmd);
|
||||||
|
if let Err(e) = output {
|
||||||
|
panic!("{:?}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab the config.
|
||||||
|
let config_file = File::open(tmp_config_path).expect("Unable to open dumped config");
|
||||||
|
let config: Self::Config = from_reader(config_file).expect("Unable to deserialize config");
|
||||||
|
|
||||||
|
CompletedTest::new(config, tmp_dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Executes a `Command`, returning a `Result` based upon the success exit code of the command.
|
||||||
|
fn output_result(cmd: &mut Command) -> Result<Output, String> {
|
||||||
|
let output = cmd.output().expect("should run command");
|
||||||
|
|
||||||
|
if output.status.success() {
|
||||||
|
Ok(output)
|
||||||
|
} else {
|
||||||
|
Err(from_utf8(&output.stderr)
|
||||||
|
.expect("stderr is not utf8")
|
||||||
|
.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CompletedTest<C> {
|
||||||
|
config: C,
|
||||||
|
dir: TempDir,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> CompletedTest<C> {
|
||||||
|
fn new(config: C, dir: TempDir) -> Self {
|
||||||
|
CompletedTest { config, dir }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_config<F: Fn(&C)>(self, func: F) {
|
||||||
|
func(&self.config);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_config_and_dir<F: Fn(&C, &TempDir)>(self, func: F) {
|
||||||
|
func(&self.config, &self.dir);
|
||||||
|
}
|
||||||
|
}
|
@ -2,4 +2,6 @@
|
|||||||
|
|
||||||
mod account_manager;
|
mod account_manager;
|
||||||
mod beacon_node;
|
mod beacon_node;
|
||||||
|
mod boot_node;
|
||||||
|
mod exec;
|
||||||
mod validator_client;
|
mod validator_client;
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
use validator_client::Config;
|
use validator_client::Config;
|
||||||
|
|
||||||
|
use crate::exec::CommandLineTestExec;
|
||||||
use bls::{Keypair, PublicKeyBytes};
|
use bls::{Keypair, PublicKeyBytes};
|
||||||
use serde_json::from_reader;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::{Command, Output};
|
use std::process::Command;
|
||||||
use std::str::from_utf8;
|
|
||||||
use std::string::ToString;
|
use std::string::ToString;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
|
|
||||||
const VALIDATOR_CMD: &str = "validator_client";
|
/// Returns the `lighthouse validator_client` command.
|
||||||
const CONFIG_NAME: &str = "vc_dump.json";
|
|
||||||
const DUMP_CONFIG_CMD: &str = "dump-config";
|
|
||||||
const IMMEDIATE_SHUTDOWN_CMD: &str = "immediate-shutdown";
|
|
||||||
|
|
||||||
/// Returns the `lighthouse validator_client --immediate-shutdown` command.
|
|
||||||
fn base_cmd() -> Command {
|
fn base_cmd() -> Command {
|
||||||
let lighthouse_bin = env!("CARGO_BIN_EXE_lighthouse");
|
let lighthouse_bin = env!("CARGO_BIN_EXE_lighthouse");
|
||||||
let path = lighthouse_bin
|
let path = lighthouse_bin
|
||||||
@ -24,25 +18,10 @@ fn base_cmd() -> Command {
|
|||||||
.expect("should parse CARGO_TARGET_DIR");
|
.expect("should parse CARGO_TARGET_DIR");
|
||||||
|
|
||||||
let mut cmd = Command::new(path);
|
let mut cmd = Command::new(path);
|
||||||
cmd.arg(VALIDATOR_CMD)
|
cmd.arg("validator_client");
|
||||||
.arg(format!("--{}", IMMEDIATE_SHUTDOWN_CMD));
|
|
||||||
|
|
||||||
cmd
|
cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Executes a `Command`, returning a `Result` based upon the success exit code of the command.
|
|
||||||
fn output_result(cmd: &mut Command) -> Result<Output, String> {
|
|
||||||
let output = cmd.output().expect("should run command");
|
|
||||||
|
|
||||||
if output.status.success() {
|
|
||||||
Ok(output)
|
|
||||||
} else {
|
|
||||||
Err(from_utf8(&output.stderr)
|
|
||||||
.expect("stderr is not utf8")
|
|
||||||
.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrapper around `Command` for easier Command Line Testing.
|
// Wrapper around `Command` for easier Command Line Testing.
|
||||||
struct CommandLineTest {
|
struct CommandLineTest {
|
||||||
cmd: Command,
|
cmd: Command,
|
||||||
@ -52,76 +31,13 @@ impl CommandLineTest {
|
|||||||
let base_cmd = base_cmd();
|
let base_cmd = base_cmd();
|
||||||
CommandLineTest { cmd: base_cmd }
|
CommandLineTest { cmd: base_cmd }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flag(mut self, flag: &str, value: Option<&str>) -> Self {
|
|
||||||
// Build the command by adding the flag and any values.
|
|
||||||
self.cmd.arg(format!("--{}", flag));
|
|
||||||
if let Some(value) = value {
|
|
||||||
self.cmd.arg(value);
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&mut self) -> CompletedTest {
|
impl CommandLineTestExec for CommandLineTest {
|
||||||
// Setup temp directories.
|
type Config = Config;
|
||||||
let tmp_dir = TempDir::new().expect("Unable to create temporary directory");
|
|
||||||
let tmp_path: PathBuf = tmp_dir.path().join(CONFIG_NAME);
|
|
||||||
|
|
||||||
// Add --datadir <temp_dir> --dump-config <temp_path> to cmd.
|
fn cmd_mut(&mut self) -> &mut Command {
|
||||||
self.cmd
|
&mut self.cmd
|
||||||
.arg("--datadir")
|
|
||||||
.arg(tmp_dir.path().as_os_str())
|
|
||||||
.arg(format!("--{}", DUMP_CONFIG_CMD))
|
|
||||||
.arg(tmp_path.as_os_str());
|
|
||||||
|
|
||||||
// Run the command.
|
|
||||||
let _output = output_result(&mut self.cmd).expect("Unable to run command");
|
|
||||||
|
|
||||||
// Grab the config.
|
|
||||||
let config: Config =
|
|
||||||
from_reader(File::open(tmp_path).expect("Unable to open dumped config"))
|
|
||||||
.expect("Unable to deserialize to ClientConfig");
|
|
||||||
CompletedTest {
|
|
||||||
config,
|
|
||||||
dir: tmp_dir,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// In order to test custom validator and secrets directory flags,
|
|
||||||
// datadir cannot be defined.
|
|
||||||
fn run_with_no_datadir(&mut self) -> CompletedTest {
|
|
||||||
// Setup temp directories
|
|
||||||
let tmp_dir = TempDir::new().expect("Unable to create temporary directory");
|
|
||||||
let tmp_path: PathBuf = tmp_dir.path().join(CONFIG_NAME);
|
|
||||||
|
|
||||||
// Add --dump-config <temp_path> to cmd.
|
|
||||||
self.cmd
|
|
||||||
.arg(format!("--{}", DUMP_CONFIG_CMD))
|
|
||||||
.arg(tmp_path.as_os_str());
|
|
||||||
|
|
||||||
// Run the command.
|
|
||||||
let _output = output_result(&mut self.cmd).expect("Unable to run command");
|
|
||||||
|
|
||||||
// Grab the config.
|
|
||||||
let config: Config =
|
|
||||||
from_reader(File::open(tmp_path).expect("Unable to open dumped config"))
|
|
||||||
.expect("Unable to deserialize to ClientConfig");
|
|
||||||
CompletedTest {
|
|
||||||
config,
|
|
||||||
dir: tmp_dir,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
struct CompletedTest {
|
|
||||||
config: Config,
|
|
||||||
dir: TempDir,
|
|
||||||
}
|
|
||||||
impl CompletedTest {
|
|
||||||
fn with_config<F: Fn(&Config)>(self, func: F) {
|
|
||||||
func(&self.config);
|
|
||||||
}
|
|
||||||
fn with_config_and_dir<F: Fn(&Config, &TempDir)>(self, func: F) {
|
|
||||||
func(&self.config, &self.dir);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user