From 83aa42e649b488432019b0996d6b13a23aa7779c Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Sun, 26 Jun 2022 21:07:37 -0300 Subject: [PATCH] tests(config): Add tests for old configs (#4676) * change `initial_mainnet_peers` and `initial_testnet_peers` type to `IndexSet` * add tests for zebra config files * add serde feature to indexmap * remove async * update config * fix `stored_config_path()` * skip tests if config is not found * improve error * use CARGO_MANIFEST_DIR * remove `stored_config_is_newest` test * move `stored_config_works` test to the end of `valid_generated_config_test` * space --- Cargo.lock | 1 + zebra-network/Cargo.toml | 1 + zebra-network/src/config.rs | 13 ++-- .../src/peer_set/initialize/tests/vectors.rs | 10 +-- .../components/inbound/tests/real_peer_set.rs | 7 +- zebrad/tests/acceptance.rs | 30 ++++++++- zebrad/tests/common/config.rs | 11 +++- zebrad/tests/common/config.toml | 64 +++++++++++++++++++ zebrad/tests/common/launch.rs | 6 +- 9 files changed, 124 insertions(+), 19 deletions(-) create mode 100644 zebrad/tests/common/config.toml diff --git a/Cargo.lock b/Cargo.lock index 7a254766b2b..6a00e257286 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6282,6 +6282,7 @@ dependencies = [ "futures", "hex", "humantime-serde", + "indexmap", "lazy_static", "metrics", "ordered-map", diff --git a/zebra-network/Cargo.toml b/zebra-network/Cargo.toml index 602d52cee9a..a7d74177708 100644 --- a/zebra-network/Cargo.toml +++ b/zebra-network/Cargo.toml @@ -19,6 +19,7 @@ bytes = "1.1.0" chrono = "0.4.19" hex = "0.4.3" humantime-serde = "1.1.1" +indexmap = { version = "1.8.2", features = ["serde"] } lazy_static = "1.4.0" ordered-map = "0.4.2" pin-project = "1.0.10" diff --git a/zebra-network/src/config.rs b/zebra-network/src/config.rs index cb993059fa6..e041eb80069 100644 --- a/zebra-network/src/config.rs +++ b/zebra-network/src/config.rs @@ -5,6 +5,7 @@ use std::{ time::Duration, }; +use indexmap::IndexSet; use serde::{de, Deserialize, Deserializer}; use zebra_chain::parameters::Network; @@ -55,11 +56,11 @@ pub struct Config { /// A list of initial peers for the peerset when operating on /// mainnet. - pub initial_mainnet_peers: HashSet, + pub initial_mainnet_peers: IndexSet, /// A list of initial peers for the peerset when operating on /// testnet. - pub initial_testnet_peers: HashSet, + pub initial_testnet_peers: IndexSet, /// The initial target size for the peer set. /// @@ -127,7 +128,7 @@ impl Config { } /// Returns the initial seed peer hostnames for the configured network. - pub fn initial_peer_hostnames(&self) -> &HashSet { + pub fn initial_peer_hostnames(&self) -> &IndexSet { match self.network { Network::Mainnet => &self.initial_mainnet_peers, Network::Testnet => &self.initial_testnet_peers, @@ -136,7 +137,7 @@ impl Config { /// Resolve initial seed peer IP addresses, based on the configured network. pub async fn initial_peers(&self) -> HashSet { - Config::resolve_peers(self.initial_peer_hostnames()).await + Config::resolve_peers(&self.initial_peer_hostnames().iter().cloned().collect()).await } /// Concurrently resolves `peers` into zero or more IP addresses, with a @@ -296,8 +297,8 @@ impl<'de> Deserialize<'de> for Config { struct DConfig { listen_addr: String, network: Network, - initial_mainnet_peers: HashSet, - initial_testnet_peers: HashSet, + initial_mainnet_peers: IndexSet, + initial_testnet_peers: IndexSet, peerset_initial_target_size: usize, #[serde(alias = "new_peer_interval", with = "humantime_serde")] crawl_new_peer_interval: Duration, diff --git a/zebra-network/src/peer_set/initialize/tests/vectors.rs b/zebra-network/src/peer_set/initialize/tests/vectors.rs index bf71a933553..ebcc1d4d860 100644 --- a/zebra-network/src/peer_set/initialize/tests/vectors.rs +++ b/zebra-network/src/peer_set/initialize/tests/vectors.rs @@ -14,7 +14,6 @@ //! skip all the network tests by setting the `ZEBRA_SKIP_NETWORK_TESTS` environmental variable. use std::{ - collections::HashSet, net::{Ipv4Addr, SocketAddr}, sync::Arc, time::{Duration, Instant}, @@ -22,6 +21,7 @@ use std::{ use chrono::Utc; use futures::{channel::mpsc, FutureExt, StreamExt}; +use indexmap::IndexSet; use tokio::{net::TcpStream, task::JoinHandle}; use tower::{service_fn, Service}; use tracing::Span; @@ -1137,7 +1137,7 @@ async fn add_initial_peers_deadlock() { // Create a list of dummy IPs, and initialize a config using them as the // initial peers. The amount of these peers will overflow // `PEERSET_INITIAL_TARGET_SIZE`. - let mut peers = HashSet::new(); + let mut peers = IndexSet::new(); for address_number in 0..PEER_COUNT { peers.insert( SocketAddr::new(Ipv4Addr::new(127, 1, 1, address_number as _).into(), 1).to_string(), @@ -1173,8 +1173,8 @@ async fn local_listener_port_with(listen_addr: SocketAddr, network: Network) { network, // Stop Zebra making outbound connections - initial_mainnet_peers: HashSet::new(), - initial_testnet_peers: HashSet::new(), + initial_mainnet_peers: IndexSet::new(), + initial_testnet_peers: IndexSet::new(), ..Config::default() }; @@ -1468,7 +1468,7 @@ where { // Create a list of dummy IPs and initialize a config using them as the // initial peers. - let mut peers = HashSet::new(); + let mut peers = IndexSet::new(); for address_number in 0..peer_count { peers.insert( SocketAddr::new(Ipv4Addr::new(127, 1, 1, address_number as _).into(), 1).to_string(), diff --git a/zebrad/src/components/inbound/tests/real_peer_set.rs b/zebrad/src/components/inbound/tests/real_peer_set.rs index f1bc7310651..c6dbb46f24e 100644 --- a/zebrad/src/components/inbound/tests/real_peer_set.rs +++ b/zebrad/src/components/inbound/tests/real_peer_set.rs @@ -1,8 +1,9 @@ //! Inbound service tests with a real peer set. -use std::{collections::HashSet, iter, net::SocketAddr, sync::Arc}; +use std::{iter, net::SocketAddr, sync::Arc}; use futures::FutureExt; +use indexmap::IndexSet; use tokio::{sync::oneshot, task::JoinHandle}; use tower::{ buffer::Buffer, @@ -655,8 +656,8 @@ async fn setup( listen_addr: config_listen_addr, // Stop Zebra making outbound connections - initial_mainnet_peers: HashSet::new(), - initial_testnet_peers: HashSet::new(), + initial_mainnet_peers: IndexSet::new(), + initial_testnet_peers: IndexSet::new(), ..NetworkConfig::default() }; diff --git a/zebrad/tests/acceptance.rs b/zebrad/tests/acceptance.rs index f969febd87e..ea7609b5694 100644 --- a/zebrad/tests/acceptance.rs +++ b/zebrad/tests/acceptance.rs @@ -123,7 +123,7 @@ mod common; use common::{ check::{is_zebrad_version, EphemeralCheck, EphemeralConfig}, - config::{default_test_config, persistent_test_config, testdir}, + config::{default_test_config, persistent_test_config, stored_config_path, testdir}, launch::{ spawn_zebrad_for_rpc_without_initial_peers, ZebradTestDirExt, BETWEEN_NODES_DELAY, LAUNCH_DELAY, @@ -509,6 +509,9 @@ fn valid_generated_config_test() -> Result<()> { // cache conflicts. valid_generated_config("start", "Starting zebrad")?; + // Check that the stored configuration we have for Zebra works + stored_config_works()?; + Ok(()) } @@ -561,6 +564,31 @@ fn valid_generated_config(command: &str, expect_stdout_line_contains: &str) -> R Ok(()) } +fn stored_config_works() -> Result<()> { + let stored_config_path = stored_config_path(); + let run_dir = testdir()?; + + // run zebra with stored config + let mut child = + run_dir.spawn_child(args!["-c", stored_config_path.to_str().unwrap(), "start"])?; + + // zebra was able to start with the stored config + child.expect_stdout_line_matches("Starting zebrad".to_string())?; + + // finish + child.kill()?; + + let output = child.wait_with_output()?; + let output = output.assert_failure()?; + + // [Note on port conflict](#Note on port conflict) + output + .assert_was_killed() + .wrap_err("Possible port conflict. Are there other acceptance tests running?")?; + + Ok(()) +} + /// Test if `zebrad` can sync the first checkpoint on mainnet. /// /// The first checkpoint contains a single genesis block. diff --git a/zebrad/tests/common/config.rs b/zebrad/tests/common/config.rs index 60913f00501..25afa16dba3 100644 --- a/zebrad/tests/common/config.rs +++ b/zebrad/tests/common/config.rs @@ -5,7 +5,11 @@ //! Test functions in this file will not be run. //! This file is only for test library code. -use std::{env, time::Duration}; +use std::{ + env, + path::{Path, PathBuf}, + time::Duration, +}; use color_eyre::eyre::Result; use tempfile::TempDir; @@ -80,3 +84,8 @@ pub fn testdir() -> Result { .tempdir() .map_err(Into::into) } + +/// Get stored config path +pub fn stored_config_path() -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/common/config.toml") +} diff --git a/zebrad/tests/common/config.toml b/zebrad/tests/common/config.toml new file mode 100644 index 00000000000..2291b5fb274 --- /dev/null +++ b/zebrad/tests/common/config.toml @@ -0,0 +1,64 @@ +# Default configuration for zebrad. +# +# This file can be used as a skeleton for custom configs. +# +# Unspecified fields use default values. Optional fields are Some(field) if the +# field is present and None if it is absent. +# +# This file is generated as an example using zebrad's current defaults. +# You should set only the config options you want to keep, and delete the rest. +# Only a subset of fields are present in the skeleton, since optional values +# whose default is None are omitted. +# +# The config format (including a complete list of sections and fields) is +# documented here: +# https://doc.zebra.zfnd.org/zebrad/config/struct.ZebradConfig.html +# +# zebrad attempts to load configs in the following order: +# +# 1. The -c flag on the command line, e.g., `zebrad -c myconfig.toml start`; +# 2. The file `zebrad.toml` in the users's preference directory (platform-dependent); +# 3. The default config. + +[consensus] +checkpoint_sync = true +debug_skip_parameter_preload = false + +[mempool] +eviction_memory_time = '1h' +tx_cost_limit = 80000000 + +[metrics] + +[network] +crawl_new_peer_interval = '1m 1s' +initial_mainnet_peers = [ + 'dnsseed.z.cash:8233', + 'dnsseed.str4d.xyz:8233', + 'mainnet.seeder.zfnd.org:8233', + 'mainnet.is.yolo.money:8233', +] +initial_testnet_peers = [ + 'dnsseed.testnet.z.cash:18233', + 'testnet.seeder.zfnd.org:18233', + 'testnet.is.yolo.money:18233', +] +listen_addr = '0.0.0.0:8233' +network = 'Mainnet' +peerset_initial_target_size = 25 + +[rpc] + +[state] +cache_dir = 'cache_dir' +delete_old_database = true +ephemeral = false + +[sync] +lookahead_limit = 400 +max_concurrent_block_requests = 25 + +[tracing] +force_use_color = false +use_color = true +use_journald = false diff --git a/zebrad/tests/common/launch.rs b/zebrad/tests/common/launch.rs index fad4315d393..c6972614bda 100644 --- a/zebrad/tests/common/launch.rs +++ b/zebrad/tests/common/launch.rs @@ -6,7 +6,6 @@ //! This file is only for test library code. use std::{ - collections::HashSet, env, net::SocketAddr, path::{Path, PathBuf}, @@ -14,6 +13,7 @@ use std::{ }; use color_eyre::eyre::Result; +use indexmap::IndexSet; use zebra_chain::parameters::Network; use zebra_test::{ @@ -201,8 +201,8 @@ pub fn spawn_zebrad_for_rpc_without_initial_peers( .expect("Failed to create a config file with a known RPC listener port"); config.state.ephemeral = false; - config.network.initial_mainnet_peers = HashSet::new(); - config.network.initial_testnet_peers = HashSet::new(); + config.network.initial_mainnet_peers = IndexSet::new(); + config.network.initial_testnet_peers = IndexSet::new(); config.network.network = network; config.mempool.debug_enable_at_height = Some(0);