Enforce Optimistic Sync Conditions & CLI Tests (v2) (#3050)

## Description

This PR adds a single, trivial commit (f5d2b27d78) atop #2986 to resolve a tests compile error. The original author (@ethDreamer) is AFK so I'm getting this one merged ☺️ 

Please see #2986 for more information about the other, significant changes in this PR.


Co-authored-by: Mark Mackey <mark@sigmaprime.io>
Co-authored-by: ethDreamer <37123614+ethDreamer@users.noreply.github.com>
This commit is contained in:
Paul Hauner
2022-03-01 22:56:47 +00:00
parent a1b730c043
commit b6493d5e24
16 changed files with 348 additions and 49 deletions

View File

@@ -10,7 +10,7 @@ use std::process::Command;
use std::str::FromStr;
use std::string::ToString;
use tempfile::TempDir;
use types::{Address, Checkpoint, Epoch, Hash256};
use types::{Address, Checkpoint, Epoch, ExecutionBlockHash, Hash256, MainnetEthSpec};
use unused_port::{unused_tcp_port, unused_udp_port};
const DEFAULT_ETH1_ENDPOINT: &str = "http://localhost:8545/";
@@ -206,7 +206,35 @@ fn eth1_purge_cache_flag() {
.with_config(|config| assert!(config.eth1.purge_cache));
}
// Tests for Merge flags.
// Tests for Bellatrix flags.
#[test]
fn merge_flag() {
CommandLineTest::new()
.flag("merge", None)
.run_with_zero_port()
.with_config(|config| assert!(config.execution_endpoints.is_some()));
}
#[test]
fn merge_execution_endpoints_flag() {
use sensitive_url::SensitiveUrl;
let urls = vec!["http://sigp.io/no-way:1337", "http://infura.not_real:4242"];
let endpoints = urls
.iter()
.map(|s| SensitiveUrl::parse(s).unwrap())
.collect::<Vec<_>>();
let mut endpoint_arg = urls[0].to_string();
for url in urls.into_iter().skip(1) {
endpoint_arg.push(',');
endpoint_arg.push_str(url);
}
// this is way better but intersperse is still a nightly feature :/
// let endpoint_arg: String = urls.into_iter().intersperse(",").collect();
CommandLineTest::new()
.flag("merge", None)
.flag("execution-endpoints", Some(&endpoint_arg))
.run_with_zero_port()
.with_config(|config| assert_eq!(config.execution_endpoints.as_ref(), Some(&endpoints)));
}
#[test]
fn merge_fee_recipient_flag() {
CommandLineTest::new()
@@ -223,6 +251,62 @@ fn merge_fee_recipient_flag() {
)
});
}
#[test]
fn terminal_total_difficulty_override_flag() {
use beacon_node::beacon_chain::types::Uint256;
CommandLineTest::new()
.flag("terminal-total-difficulty-override", Some("1337424242"))
.run_with_zero_port()
.with_spec::<MainnetEthSpec, _>(|spec| {
assert_eq!(spec.terminal_total_difficulty, Uint256::from(1337424242))
});
}
#[test]
fn terminal_block_hash_and_activation_epoch_override_flags() {
CommandLineTest::new()
.flag("terminal-block-hash-epoch-override", Some("1337"))
.flag(
"terminal-block-hash-override",
Some("0x4242424242424242424242424242424242424242424242424242424242424242"),
)
.run_with_zero_port()
.with_spec::<MainnetEthSpec, _>(|spec| {
assert_eq!(
spec.terminal_block_hash,
ExecutionBlockHash::from_str(
"0x4242424242424242424242424242424242424242424242424242424242424242"
)
.unwrap()
);
assert_eq!(spec.terminal_block_hash_activation_epoch, 1337);
});
}
#[test]
#[should_panic]
fn terminal_block_hash_missing_activation_epoch() {
CommandLineTest::new()
.flag(
"terminal-block-hash-override",
Some("0x4242424242424242424242424242424242424242424242424242424242424242"),
)
.run_with_zero_port();
}
#[test]
#[should_panic]
fn epoch_override_missing_terminal_block_hash() {
CommandLineTest::new()
.flag("terminal-block-hash-epoch-override", Some("1337"))
.run_with_zero_port();
}
#[test]
fn safe_slots_to_import_optimistically_flag() {
CommandLineTest::new()
.flag("safe-slots-to-import-optimistically", Some("421337"))
.run_with_zero_port()
.with_spec::<MainnetEthSpec, _>(|spec| {
assert_eq!(spec.safe_slots_to_import_optimistically, 421337)
});
}
// Tests for Network flags.
#[test]
@@ -410,6 +494,15 @@ fn zero_ports_flag() {
assert_eq!(config.http_metrics.listen_port, 0);
});
}
#[test]
fn network_load_flag() {
CommandLineTest::new()
.flag("network-load", Some("4"))
.run_with_zero_port()
.with_config(|config| {
assert_eq!(config.network.network_load, 4);
});
}
// Tests for ENR flags.
#[test]
@@ -527,6 +620,13 @@ fn http_allow_origin_all_flag() {
.with_config(|config| assert_eq!(config.http_api.allow_origin, Some("*".to_string())));
}
#[test]
fn http_allow_sync_stalled_flag() {
CommandLineTest::new()
.flag("http-allow-sync-stalled", None)
.run_with_zero_port()
.with_config(|config| assert_eq!(config.http_api.allow_sync_stalled, true));
}
#[test]
fn http_tls_flags() {
let dir = TempDir::new().expect("Unable to create temporary directory");
CommandLineTest::new()

View File

@@ -5,6 +5,7 @@ use std::path::PathBuf;
use std::process::{Command, Output};
use std::str::from_utf8;
use tempfile::TempDir;
use types::{ChainSpec, Config, EthSpec};
pub trait CommandLineTestExec {
type Config: DeserializeOwned;
@@ -23,19 +24,22 @@ pub trait CommandLineTestExec {
/// 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.
/// Options `--datadir`, `--dump-config`, `--dump-chain-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");
let tmp_chain_config_path: PathBuf = tmp_dir.path().join("chain_spec.yaml");
// Add args --datadir <tmp_dir> --dump-config <tmp_config_path> --immediate-shutdown
// Add args --datadir <tmp_dir> --dump-config <tmp_config_path> --dump-chain-config <tmp_chain_config_path> --immediate-shutdown
let cmd = self.cmd_mut();
cmd.arg("--datadir")
.arg(tmp_dir.path().as_os_str())
.arg(format!("--{}", "--dump-config"))
.arg(format!("--{}", "dump-config"))
.arg(tmp_config_path.as_os_str())
.arg(format!("--{}", "dump-chain-config"))
.arg(tmp_chain_config_path.as_os_str())
.arg("--immediate-shutdown");
// Run the command.
@@ -47,23 +51,32 @@ pub trait CommandLineTestExec {
// 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");
// Grab the chain config.
let spec_file =
File::open(tmp_chain_config_path).expect("Unable to open dumped chain spec");
let chain_config: Config =
serde_yaml::from_reader(spec_file).expect("Unable to deserialize config");
CompletedTest::new(config, tmp_dir)
CompletedTest::new(config, chain_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.
/// Options `--dump-config`, `--dump-chain-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");
let tmp_chain_config_path: PathBuf = tmp_dir.path().join("chain_spec.yaml");
// Add args --datadir <tmp_dir> --dump-config <tmp_config_path> --immediate-shutdown
// Add args --datadir <tmp_dir> --dump-config <tmp_config_path> --dump-chain-config <tmp_chain_config_path> --immediate-shutdown
let cmd = self.cmd_mut();
cmd.arg(format!("--{}", "--dump-config"))
cmd.arg(format!("--{}", "dump-config"))
.arg(tmp_config_path.as_os_str())
.arg(format!("--{}", "dump-chain-config"))
.arg(tmp_chain_config_path.as_os_str())
.arg("--immediate-shutdown");
// Run the command.
@@ -75,8 +88,13 @@ pub trait CommandLineTestExec {
// 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");
// Grab the chain config.
let spec_file =
File::open(tmp_chain_config_path).expect("Unable to open dumped chain spec");
let chain_config: Config =
serde_yaml::from_reader(spec_file).expect("Unable to deserialize config");
CompletedTest::new(config, tmp_dir)
CompletedTest::new(config, chain_config, tmp_dir)
}
}
@@ -95,19 +113,35 @@ fn output_result(cmd: &mut Command) -> Result<Output, String> {
pub struct CompletedTest<C> {
config: C,
chain_config: Config,
dir: TempDir,
}
impl<C> CompletedTest<C> {
fn new(config: C, dir: TempDir) -> Self {
CompletedTest { config, dir }
fn new(config: C, chain_config: Config, dir: TempDir) -> Self {
CompletedTest {
config,
chain_config,
dir,
}
}
pub fn with_config<F: Fn(&C)>(self, func: F) {
func(&self.config);
}
pub fn with_spec<E: EthSpec, F: Fn(ChainSpec)>(self, func: F) {
let spec = ChainSpec::from_config::<E>(&self.chain_config).unwrap();
func(spec);
}
pub fn with_config_and_dir<F: Fn(&C, &TempDir)>(self, func: F) {
func(&self.config, &self.dir);
}
#[allow(dead_code)]
pub fn with_config_and_spec<E: EthSpec, F: Fn(&C, ChainSpec)>(self, func: F) {
let spec = ChainSpec::from_config::<E>(&self.chain_config).unwrap();
func(&self.config, spec);
}
}