use serde_derive::Deserialize; use serde_yaml; #[cfg(not(debug_assertions))] use state_processing::{ per_block_processing, per_block_processing_without_verifying_block_signature, per_slot_processing, }; use std::{fs::File, io::prelude::*, path::PathBuf}; use types::*; #[allow(unused_imports)] use yaml_utils; #[derive(Debug, Deserialize)] pub struct TestCase { pub name: String, pub config: ChainSpec, pub verify_signatures: bool, pub initial_state: BeaconState, pub blocks: Vec, } #[derive(Debug, Deserialize)] pub struct TestDoc { pub title: String, pub summary: String, pub fork: String, pub test_cases: Vec, } fn load_test_case(test_name: &str) -> TestDoc { let mut file = { let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR")); file_path_buf.push(format!("yaml_utils/specs/{}", test_name)); File::open(file_path_buf).unwrap() }; let mut yaml_str = String::new(); file.read_to_string(&mut yaml_str).unwrap(); yaml_str = yaml_str.to_lowercase(); serde_yaml::from_str(&yaml_str.as_str()).unwrap() } fn run_state_transition_test(test_name: &str) { let doc = load_test_case(test_name); // Run Tests let mut ok = true; for (i, test_case) in doc.test_cases.iter().enumerate() { let fake_crypto = cfg!(feature = "fake_crypto"); if !test_case.verify_signatures == fake_crypto { println!("Running {}", test_case.name); } else { println!( "Skipping {} (fake_crypto: {}, need fake: {})", test_case.name, fake_crypto, !test_case.verify_signatures ); continue; } let mut state = test_case.initial_state.clone(); for (j, block) in test_case.blocks.iter().enumerate() { while block.slot > state.slot { let latest_block_header = state.latest_block_header.clone(); per_slot_processing(&mut state, &latest_block_header, &test_case.config).unwrap(); } let res = per_block_processing(&mut state, &block, &test_case.config); if res.is_err() { println!("Error in {} (#{}), on block {}", test_case.name, i, j); println!("{:?}", res); ok = false; }; } } assert!(ok, "one or more tests failed, see above"); } #[test] #[cfg(not(debug_assertions))] fn test_read_yaml() { load_test_case("sanity-check_small-config_32-vals.yaml"); load_test_case("sanity-check_default-config_100-vals.yaml"); } #[test] #[cfg(not(debug_assertions))] fn run_state_transition_tests_small() { run_state_transition_test("sanity-check_small-config_32-vals.yaml"); } #[test] #[cfg(not(debug_assertions))] fn run_state_transition_tests_large() { run_state_transition_test("sanity-check_default-config_100-vals.yaml"); }