diff --git a/beacon_node/beacon_chain/test_harness/examples/chain.yaml b/beacon_node/beacon_chain/test_harness/examples/chain.yaml index 5d8e34795..b170a0b2e 100644 --- a/beacon_node/beacon_chain/test_harness/examples/chain.yaml +++ b/beacon_node/beacon_chain/test_harness/examples/chain.yaml @@ -8,6 +8,7 @@ test_cases: epoch_length: 64 deposits_for_chain_start: 1000 num_slots: 32 # Testing advancing state to slot < SlotsPerEpoch + skip_slots: [2, 3] results: slot: 32 num_validators: 1000 diff --git a/beacon_node/beacon_chain/test_harness/src/bin.rs b/beacon_node/beacon_chain/test_harness/src/bin.rs index 007ec3f60..48f349d4a 100644 --- a/beacon_node/beacon_chain/test_harness/src/bin.rs +++ b/beacon_node/beacon_chain/test_harness/src/bin.rs @@ -1,8 +1,10 @@ use self::beacon_chain_harness::BeaconChainHarness; use self::validator_harness::ValidatorHarness; +use beacon_chain::CheckPoint; use clap::{App, Arg}; use env_logger::{Builder, Env}; -use log::info; +use log::{info, warn}; +use std::collections::HashMap; use std::{fs::File, io::prelude::*}; use types::*; use yaml_rust::{Yaml, YamlLoader}; @@ -39,7 +41,7 @@ fn main() { for doc in &docs { for test_case in doc["test_cases"].as_vec().unwrap() { let manifest = Manifest::from_yaml(test_case); - manifest.execute(); + manifest.assert_result_valid(manifest.execute()) } } } @@ -68,7 +70,7 @@ impl Manifest { spec } - pub fn execute(&self) { + pub fn execute(&self) -> ExecutionResult { let spec = self.spec(); let validator_count = self.config.deposits_for_chain_start; let slots = self.results.slot; @@ -82,18 +84,47 @@ impl Manifest { info!("Starting simulation across {} slots...", slots); - for _ in 0..self.results.slot { - harness.advance_chain_with_block(); + for slot_height in 0..self.results.slot { + match self.config.skip_slots { + Some(ref skip_slots) if skip_slots.contains(&slot_height) => { + warn!("Skipping slot at height {}.", slot_height); + harness.increment_beacon_chain_slot(); + } + _ => { + info!("Producing block at slot height {}.", slot_height); + harness.advance_chain_with_block(); + } + } } harness.run_fork_choice(); - let dump = harness.chain_dump().expect("Chain dump failed."); + info!("Test execution complete!"); - assert_eq!(dump.len() as u64, slots + 1); // + 1 for genesis block. - - // harness.dump_to_file("/tmp/chaindump.json".to_string(), &dump); + ExecutionResult { + chain: harness.chain_dump().expect("Chain dump failed."), + } } + + pub fn assert_result_valid(&self, result: ExecutionResult) { + info!("Verifying test results..."); + + if let Some(ref skip_slots) = self.config.skip_slots { + for checkpoint in result.chain { + let block_slot = checkpoint.beacon_block.slot.as_u64(); + assert!( + !skip_slots.contains(&block_slot), + "Slot {} was not skipped.", + block_slot + ); + } + } + info!("OK: Skipped slots not present in chain."); + } +} + +struct ExecutionResult { + pub chain: Vec, } struct Results { @@ -117,6 +148,7 @@ impl Results { struct Config { pub deposits_for_chain_start: usize, pub epoch_length: Option, + pub skip_slots: Option>, } impl Config { @@ -125,6 +157,7 @@ impl Config { deposits_for_chain_start: as_usize(&yaml, "deposits_for_chain_start") .expect("Must specify validator count"), epoch_length: as_u64(&yaml, "epoch_length"), + skip_slots: as_vec_u64(yaml, "skip_slots"), } } }