Files
lighthouse/testing/ef_tests/src/case_result.rs
Michael Sproul 61962898e2 In-memory tree states (#5533)
* Consensus changes

* EF tests

* lcli

* common and watch

* account manager

* cargo

* fork choice

* promise cache

* beacon chain

* interop genesis

* http api

* lighthouse

* op pool

* beacon chain misc

* parallel state cache

* store

* fix issues in store

* IT COMPILES

* Remove some unnecessary module qualification

* Revert Arced pubkey optimization (#5536)

* Merge remote-tracking branch 'origin/unstable' into tree-states-memory

* Fix caching, rebasing and some tests

* Remove unused deps

* Merge remote-tracking branch 'origin/unstable' into tree-states-memory

* Small cleanups

* Revert shuffling cache/promise cache changes

* Fix state advance bugs

* Fix shuffling tests

* Remove some resolved FIXMEs

* Remove StateProcessingStrategy

* Optimise withdrawals calculation

* Don't reorg if state cache is missed

* Remove inconsistent state func

* Fix beta compiler

* Rebase early, rebase often

* Fix state caching behaviour

* Update to milhouse release

* Fix on-disk consensus context format

* Merge remote-tracking branch 'origin/unstable' into tree-states-memory

* Squashed commit of the following:

commit 3a16649023
Author: Michael Sproul <michael@sigmaprime.io>
Date:   Thu Apr 18 14:26:09 2024 +1000

    Fix on-disk consensus context format

* Keep indexed attestations, thanks Sean

* Merge branch 'on-disk-consensus-context' into tree-states-memory

* Merge branch 'unstable' into tree-states-memory

* Address half of Sean's review

* More simplifications from Sean's review

* Cache state after get_advanced_hot_state
2024-04-24 01:22:36 +00:00

126 lines
3.8 KiB
Rust

use super::*;
use compare_fields::{CompareFields, Comparison, FieldComparison};
use std::fmt::Debug;
use std::path::{Path, PathBuf};
use types::BeaconState;
pub const MAX_VALUE_STRING_LEN: usize = 500;
#[derive(Debug, PartialEq, Clone)]
pub struct CaseResult {
pub case_index: usize,
pub desc: String,
pub path: PathBuf,
pub result: Result<(), Error>,
}
impl CaseResult {
pub fn new(
case_index: usize,
path: &Path,
case: &impl Case,
result: Result<(), Error>,
) -> Self {
CaseResult {
case_index,
desc: case.description(),
path: path.into(),
result,
}
}
}
/// Same as `compare_result_detailed`, however it drops the caches on both states before
/// comparison.
pub fn compare_beacon_state_results_without_caches<E: EthSpec, T: Debug>(
result: &mut Result<BeaconState<E>, T>,
expected: &mut Option<BeaconState<E>>,
) -> Result<(), Error> {
if let (Ok(ref mut result), Some(ref mut expected)) = (result.as_mut(), expected.as_mut()) {
result.drop_all_caches().unwrap();
expected.drop_all_caches().unwrap();
result.apply_pending_mutations().unwrap();
expected.apply_pending_mutations().unwrap();
}
compare_result_detailed(result, expected)
}
/// Same as `compare_result`, however utilizes the `CompareFields` trait to give a list of
/// mismatching fields when `Ok(result) != Some(expected)`.
pub fn compare_result_detailed<T, U>(
result: &Result<T, U>,
expected: &Option<T>,
) -> Result<(), Error>
where
T: PartialEq<T> + Debug + CompareFields,
U: Debug,
{
match (result, expected) {
(Ok(result), Some(expected)) => {
let mut mismatching_fields: Vec<Comparison> = expected
.compare_fields(result)
.into_iter()
// Filter all out all fields that are equal.
.filter(Comparison::not_equal)
.collect();
mismatching_fields
.iter_mut()
.for_each(|f| f.retain_children(FieldComparison::not_equal));
if !mismatching_fields.is_empty() {
Err(Error::NotEqual(format!(
"Fields not equal (a = expected, b = result): {:#?}",
mismatching_fields
)))
} else {
Ok(())
}
}
_ => compare_result(result, expected),
}
}
/// Compares `result` with `expected`.
///
/// If `expected.is_none()` then `result` is expected to be `Err`. Otherwise, `T` in `result` and
/// `expected` must be equal.
pub fn compare_result<T, U>(result: &Result<T, U>, expected: &Option<T>) -> Result<(), Error>
where
T: PartialEq<T> + Debug,
U: Debug,
{
match (result, expected) {
// Pass: The should have failed and did fail.
(Err(_), None) => Ok(()),
// Fail: The test failed when it should have produced a result (fail).
(Err(e), Some(expected)) => Err(Error::NotEqual(format!(
"Got {:?} | Expected {}",
e,
fmt_val(expected)
))),
// Fail: The test produced a result when it should have failed (fail).
(Ok(result), None) => Err(Error::DidntFail(format!("Got {:?}", fmt_val(result)))),
// Potential Pass: The test should have produced a result, and it did.
(Ok(result), Some(expected)) => {
if result == expected {
Ok(())
} else {
Err(Error::NotEqual(format!(
"Got {} | Expected {}",
fmt_val(result),
fmt_val(expected)
)))
}
}
}
}
fn fmt_val<T: Debug>(val: T) -> String {
let mut string = format!("{:?}", val);
string.truncate(MAX_VALUE_STRING_LEN);
string
}