Skip to content

Commit

Permalink
Improve test coverage
Browse files Browse the repository at this point in the history
Improved test coverage for genesis block sanity check, especially when run locally in
debug mode. This PR removed the need for all `fn XXXX_genesis_sanity_check()` tests to
be compiled for a specific target network.

`cargo.exe test --release --lib blocks::genesis_block` will now run all 6x tests.

This also works in a CI environment where `cargo nextest` is called.
  • Loading branch information
hansieodendaal committed Sep 5, 2024
1 parent 14a6631 commit 966a665
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 53 deletions.
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions base_layer/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ env_logger = "0.7.0"
tempfile = "3.1.0"
toml = { version = "0.5" }
quickcheck = "1.0"
serial_test = "0.5"

[build-dependencies]
tari_common = { path = "../../common", features = ["build"], version = "1.4.0-pre.0" }
Expand Down
101 changes: 83 additions & 18 deletions base_layer/core/src/blocks/genesis_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,10 +469,12 @@ fn get_raw_block(genesis_timestamp: &DateTime<FixedOffset>, not_before_proof: &P
}
}

// Note: Tests in this module are serialized to prevent domain separated network hash conflicts
#[cfg(test)]
mod test {
use std::convert::TryFrom;

use serial_test::serial;
use tari_common_types::{epoch::VnEpoch, types::Commitment};

use super::*;
Expand All @@ -489,61 +491,91 @@ mod test {
};

#[test]
#[cfg(tari_target_network_testnet)]
#[serial]
fn esmeralda_genesis_sanity_check() {
let _ = Network::set_current(Network::Esmeralda);
let network = Network::Esmeralda;
set_network_by_env_var_or_force_set(network);
if !network_matches(network) {
panic!("Network could not be set ('esmeralda_genesis_sanity_check()')");
}
// Note: Generate new data for `pub fn get_esmeralda_genesis_block()` and `fn get_esmeralda_genesis_block_raw()`
// if consensus values change, e.g. new pre_mine or other
let block = get_esmeralda_genesis_block();
check_block(Network::Esmeralda, &block, 164, 1);
check_block(network, &block, 164, 1);
remove_network_env_var();
}

#[test]
#[cfg(tari_target_network_nextnet)]
#[serial]
fn nextnet_genesis_sanity_check() {
let _ = Network::set_current(Network::NextNet);
let network = Network::NextNet;
set_network_by_env_var_or_force_set(network);
if !network_matches(network) {
panic!("Network could not be set ('nextnet_genesis_sanity_check()')");
}
// Note: Generate new data for `pub fn get_nextnet_genesis_block()` and `fn get_stagenet_genesis_block_raw()`
// if consensus values change, e.g. new pre_mine or other
let block = get_nextnet_genesis_block();
check_block(Network::NextNet, &block, 0, 0);
check_block(network, &block, 0, 0);
remove_network_env_var();
}

#[test]
#[cfg(tari_target_network_mainnet)]
#[serial]
fn mainnet_genesis_sanity_check() {
let _ = Network::set_current(Network::MainNet);
let network = Network::MainNet;
set_network_by_env_var_or_force_set(network);
if !network_matches(network) {
panic!("Network could not be set ('mainnet_genesis_sanity_check()')");
}
// Note: Generate new data for `pub fn get_nextnet_genesis_block()` and `fn get_stagenet_genesis_block_raw()`
// if consensus values change, e.g. new pre_mine or other
let block = get_mainnet_genesis_block();
check_block(Network::MainNet, &block, 164, 1);
check_block(network, &block, 164, 1);
remove_network_env_var();
}

#[test]
#[cfg(tari_target_network_mainnet)]
#[serial]
fn stagenet_genesis_sanity_check() {
let _ = Network::set_current(Network::StageNet);
let network = Network::StageNet;
set_network_by_env_var_or_force_set(network);
if !network_matches(network) {
panic!("Network could not be set ('stagenet_genesis_sanity_check()')");
}
// Note: Generate new data for `pub fn get_stagenet_genesis_block()` and `fn get_stagenet_genesis_block_raw()`
// if consensus values change, e.g. new pre_mine or other
let block = get_stagenet_genesis_block();
check_block(Network::StageNet, &block, 0, 0);
check_block(network, &block, 0, 0);
remove_network_env_var();
}

#[test]
#[cfg(tari_target_network_testnet)]
#[serial]
fn igor_genesis_sanity_check() {
let _ = Network::set_current(Network::Igor);
let network = Network::Igor;
set_network_by_env_var_or_force_set(network);
if !network_matches(network) {
panic!("Network could not be set ('igor_genesis_sanity_check()')");
}
// Note: If outputs and kernels are added, this test will fail unless you explicitly check that network == Igor
let block = get_igor_genesis_block();
check_block(Network::Igor, &block, 0, 0);
check_block(network, &block, 0, 0);
remove_network_env_var();
}

#[test]
#[cfg(tari_target_network_testnet)]
#[serial]
fn localnet_genesis_sanity_check() {
let _ = Network::set_current(Network::LocalNet);
let network = Network::LocalNet;
set_network_by_env_var_or_force_set(network);
if !network_matches(network) {
panic!("Network could not be set ('localnet_genesis_sanity_check()')");
}
// Note: If outputs and kernels are added, this test will fail unless you explicitly check that network == Igor
let block = get_localnet_genesis_block();
check_block(Network::LocalNet, &block, 0, 0);
check_block(network, &block, 0, 0);
remove_network_env_var();
}

fn check_block(network: Network, block: &ChainBlock, expected_outputs: usize, expected_kernels: usize) {
Expand Down Expand Up @@ -624,4 +656,37 @@ mod test {
.validate(&*lock, 0, &utxo_sum, &kernel_sum, &Commitment::default())
.unwrap();
}

fn set_network_by_env_var_or_force_set(network: Network) {
set_network_by_env_var(network);
if Network::get_current_or_user_setting_or_default() != network {
let _ = Network::set_current(network);
}
}

// Targeted network compilations will override inferred network hashes; this has effect only if
// `Network::set_current(<NETWORK>)` has not been called.
fn set_network_by_env_var(network: Network) {
// Do not override the env_var if network is already set; another test may fail
if std::env::var("TARI_NETWORK").is_err() {
std::env::set_var("TARI_NETWORK", network.as_key_str());
}
}

fn remove_network_env_var() {
std::env::remove_var("TARI_NETWORK");
}

fn network_matches(network: Network) -> bool {
let current_network = Network::get_current_or_user_setting_or_default();
if current_network == network {
true
} else {
println!(
"\nNetwork mismatch!! Required: {:?}, current: {:?}.\n",
network, current_network
);
false
}
}
}
85 changes: 50 additions & 35 deletions base_layer/core/src/consensus/consensus_encoding/hashing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,44 +145,59 @@ mod tests {

#[test]
fn it_uses_the_network_environment_variable_if_set() {
// This test will not pass if `Network::set_current(<NETWORK>)` is called before the test
if !Network::is_set() {
let label = "test";
let input = [1u8; 32];

for network in [
Network::MainNet,
Network::StageNet,
Network::NextNet,
Network::LocalNet,
Network::Igor,
Network::Esmeralda,
] {
println!("Testing network: {:?}", network);
// Generate a specific network hash
let hash_specify_network =
DomainSeparatedConsensusHasher::<TestHashDomain, Blake2b<U32>>::new_with_network(label, network)
.chain(&input)
.finalize();

// Generate an inferred network hash
std::env::set_var("TARI_NETWORK", network.as_key_str());
println!(
"TARI_NETWORK: {:?}",
std::env::var("TARI_NETWORK").unwrap_or_default()
);
println!(
"Network: {:?}\n",
Network::get_current_or_user_setting_or_default()
);
let inferred_network_hash = DomainSeparatedConsensusHasher::<TestHashDomain, Blake2b<U32>>::new(label)
// Targeted network compilations will override inferred network hashes; this only has effect if
// `Network::set_current(<NETWORK>)` has not been called. The test may also not run if
// `std::env::var("TARI_NETWORK")` has been set by some other test.
if Network::is_set() {
println!(
"\nNote!! Static network constant is set, cannot run \
`it_uses_the_network_environment_variable_if_set`\n"
);
return;
}
if std::env::var("TARI_NETWORK").is_ok() {
println!(
"\nNote!! env_var 'TARI_NETWORK' in use, cannot run \
`it_uses_the_network_environment_variable_if_set`\n"
);
return;
}

let label = "test";
let input = [1u8; 32];

for network in [
Network::MainNet,
Network::StageNet,
Network::NextNet,
Network::LocalNet,
Network::Igor,
Network::Esmeralda,
] {
println!("Testing network: {:?}", network);
// Generate a specific network hash
let hash_specify_network =
DomainSeparatedConsensusHasher::<TestHashDomain, Blake2b<U32>>::new_with_network(label, network)
.chain(&input)
.finalize();
std::env::remove_var("TARI_NETWORK");

// They should be equal
assert_eq!(hash_specify_network, inferred_network_hash);
}
// Generate an inferred network hash
std::env::set_var("TARI_NETWORK", network.as_key_str());
println!(
"TARI_NETWORK: {:?}",
std::env::var("TARI_NETWORK").unwrap_or_default()
);
println!(
"Network: {:?}\n",
Network::get_current_or_user_setting_or_default()
);
let inferred_network_hash = DomainSeparatedConsensusHasher::<TestHashDomain, Blake2b<U32>>::new(label)
.chain(&input)
.finalize();
std::env::remove_var("TARI_NETWORK");

// They should be equal
assert_eq!(hash_specify_network, inferred_network_hash);
}
}
}

0 comments on commit 966a665

Please sign in to comment.