mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-20 13:24:44 +00:00
Improve ef_tests crate
This commit is contained in:
9
tests/ef_tests/src/error.rs
Normal file
9
tests/ef_tests/src/error.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Error {
|
||||
/// The value in the test didn't match our value.
|
||||
NotEqual(String),
|
||||
/// The test specified a failure and we did not experience one.
|
||||
DidntFail(String),
|
||||
/// Failed to parse the test (internal error).
|
||||
FailedToParseTest(String),
|
||||
}
|
||||
@@ -1,4 +1,12 @@
|
||||
use error::Error;
|
||||
use serde_derive::Deserialize;
|
||||
use ssz::Decode;
|
||||
use std::fmt::Debug;
|
||||
use ethereum_types::{U256, U128};
|
||||
use test_decode::TestDecode;
|
||||
|
||||
mod error;
|
||||
mod test_decode;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct TestDoc<T> {
|
||||
@@ -21,6 +29,66 @@ pub struct SszGenericCase {
|
||||
pub ssz: Option<String>,
|
||||
}
|
||||
|
||||
pub trait Test {
|
||||
fn test(&self) -> Vec<Result<(), Error>>;
|
||||
}
|
||||
|
||||
impl Test for TestDoc<SszGenericCase> {
|
||||
fn test(&self) -> Vec<Result<(), Error>> {
|
||||
self
|
||||
.test_cases
|
||||
.iter()
|
||||
.map(|tc| {
|
||||
if let Some(ssz) = &tc.ssz {
|
||||
match tc.type_name.as_ref() {
|
||||
"uint8" => compare_decoding::<u8>(tc.valid, ssz, &tc.value),
|
||||
"uint16" => compare_decoding::<u16>(tc.valid, ssz, &tc.value),
|
||||
"uint32" => compare_decoding::<u32>(tc.valid, ssz, &tc.value),
|
||||
"uint64" => compare_decoding::<u64>(tc.valid, ssz, &tc.value),
|
||||
"uint128" => compare_decoding::<U128>(tc.valid, ssz, &tc.value),
|
||||
"uint256" => compare_decoding::<U256>(tc.valid, ssz, &tc.value),
|
||||
_ => {
|
||||
Err(Error::FailedToParseTest(format!("Unknown type: {}", tc.type_name)))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Skip tests that do not have an ssz field.
|
||||
//
|
||||
// See: https://github.com/ethereum/eth2.0-specs/issues/1079
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_decoding<T>(should_pass: bool, ssz: &String, value: &String) -> Result<(), Error>
|
||||
where
|
||||
T: Decode + TestDecode + Debug + PartialEq<T>,
|
||||
{
|
||||
let ssz = hex::decode(&ssz[2..])
|
||||
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||
let expected = T::test_decode(value)?;
|
||||
|
||||
let decoded = T::from_ssz_bytes(&ssz);
|
||||
|
||||
if should_pass {
|
||||
let decoded = decoded.map_err(|e| Error::NotEqual(format!("{:?}", e)))?;
|
||||
|
||||
if decoded != expected {
|
||||
Err(Error::NotEqual(format!("{:?} != {:?}", decoded, expected)))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
if let Ok(decoded) = decoded {
|
||||
Err(Error::DidntFail(format!("Decoded as {:?}", decoded)))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
|
||||
35
tests/ef_tests/src/test_decode.rs
Normal file
35
tests/ef_tests/src/test_decode.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use super::*;
|
||||
|
||||
pub trait TestDecode: Sized {
|
||||
fn test_decode(string: &String) -> Result<Self, Error>;
|
||||
}
|
||||
|
||||
macro_rules! impl_via_parse {
|
||||
($ty: ty) => {
|
||||
impl TestDecode for $ty {
|
||||
fn test_decode(string: &String) -> Result<Self, Error> {
|
||||
string
|
||||
.parse::<Self>()
|
||||
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_via_parse!(u8);
|
||||
impl_via_parse!(u16);
|
||||
impl_via_parse!(u32);
|
||||
impl_via_parse!(u64);
|
||||
|
||||
macro_rules! impl_via_from_dec_str {
|
||||
($ty: ty) => {
|
||||
impl TestDecode for $ty {
|
||||
fn test_decode(string: &String) -> Result<Self, Error> {
|
||||
Self::from_dec_str(string).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_via_from_dec_str!(U128);
|
||||
impl_via_from_dec_str!(U256);
|
||||
Reference in New Issue
Block a user