From c3b4739a117a2ca79c8ebf8b29cef66eb4fc20af Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Tue, 14 May 2019 10:01:20 +1000 Subject: [PATCH] Add untested ssz_static test impl --- tests/ef_tests/Cargo.toml | 1 + tests/ef_tests/src/lib.rs | 2 ++ tests/ef_tests/src/ssz_static.rs | 49 +++++++++++++++++++++++++++++++ tests/ef_tests/src/test_decode.rs | 19 ++++++++++++ tests/ef_tests/tests/tests.rs | 2 +- 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 tests/ef_tests/src/ssz_static.rs diff --git a/tests/ef_tests/Cargo.toml b/tests/ef_tests/Cargo.toml index 8a5cc43723..638b0ecfd8 100644 --- a/tests/ef_tests/Cargo.toml +++ b/tests/ef_tests/Cargo.toml @@ -11,3 +11,4 @@ serde = "1.0" serde_derive = "1.0" serde_yaml = "0.8" ssz = { path = "../../eth2/utils/ssz" } +types = { path = "../../eth2/types" } diff --git a/tests/ef_tests/src/lib.rs b/tests/ef_tests/src/lib.rs index 19df3754cb..4e58bdb86a 100644 --- a/tests/ef_tests/src/lib.rs +++ b/tests/ef_tests/src/lib.rs @@ -5,10 +5,12 @@ use ssz::Decode; use std::fmt::Debug; use test_decode::TestDecode; +pub use crate::error::*; pub use crate::ssz_generic::*; mod error; mod ssz_generic; +mod ssz_static; mod test_decode; #[derive(Debug, Deserialize)] diff --git a/tests/ef_tests/src/ssz_static.rs b/tests/ef_tests/src/ssz_static.rs new file mode 100644 index 0000000000..6c0d3f9e1d --- /dev/null +++ b/tests/ef_tests/src/ssz_static.rs @@ -0,0 +1,49 @@ +use super::*; +use types::Fork; + +#[derive(Debug, Clone, Deserialize)] +pub struct SszStatic { + pub type_name: String, + pub value: String, + pub serialized: String, + pub root: String, +} + +impl Test for TestDoc { + fn test(&self) -> Vec> { + self.test_cases + .iter() + .enumerate() + .map(|(i, tc)| { + let result = match tc.type_name.as_ref() { + "Fork" => ssz_static_test::(&tc.value, &tc.serialized, &tc.root), + _ => Err(Error::FailedToParseTest(format!( + "Unknown type: {}", + tc.type_name + ))), + }; + + TestCaseResult { + case_index: i, + case: tc.clone(), + result, + } + }) + .collect() + } +} + +/// Execute a `ssz_generic` test case. +fn ssz_static_test(value: &String, serialized: &String, root: &String) -> Result<(), Error> +where + T: Decode + TestDecode + Debug + PartialEq, +{ + let ssz = + hex::decode(&serialized[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?; + + let expected = T::test_decode(value)?; + + let decoded = T::from_ssz_bytes(&ssz); + + compare_result(decoded, Some(expected)) +} diff --git a/tests/ef_tests/src/test_decode.rs b/tests/ef_tests/src/test_decode.rs index dbbbcdae0f..6003968fc0 100644 --- a/tests/ef_tests/src/test_decode.rs +++ b/tests/ef_tests/src/test_decode.rs @@ -1,9 +1,12 @@ use super::*; +use types::Fork; pub trait TestDecode: Sized { + /// Decode an object from the test specification YAML. fn test_decode(string: &String) -> Result; } +/// Basic types can general be decoded with the `parse` fn if they implement `str::FromStr`. macro_rules! impl_via_parse { ($ty: ty) => { impl TestDecode for $ty { @@ -21,6 +24,8 @@ impl_via_parse!(u16); impl_via_parse!(u32); impl_via_parse!(u64); +/// Some `ethereum-types` methods have a `str::FromStr` implementation that expects `0x`-prefixed +/// hex, so we use `from_dec_str` instead. macro_rules! impl_via_from_dec_str { ($ty: ty) => { impl TestDecode for $ty { @@ -33,3 +38,17 @@ macro_rules! impl_via_from_dec_str { impl_via_from_dec_str!(U128); impl_via_from_dec_str!(U256); + +/// Types that already implement `serde::Deserialize` can be decoded using `serde_yaml`. +macro_rules! impl_via_serde_yaml { + ($ty: ty) => { + impl TestDecode for $ty { + fn test_decode(string: &String) -> Result { + serde_yaml::from_str(string) + .map_err(|e| Error::FailedToParseTest(format!("{:?}", e))) + } + } + }; +} + +impl_via_serde_yaml!(Fork); diff --git a/tests/ef_tests/tests/tests.rs b/tests/ef_tests/tests/tests.rs index e62c16c28f..f27aacf06e 100644 --- a/tests/ef_tests/tests/tests.rs +++ b/tests/ef_tests/tests/tests.rs @@ -18,7 +18,7 @@ fn load_test_case(test_name: &str) -> TestDoc { } #[test] -fn ssz() { +fn ssz_generic() { let doc: TestDoc = load_test_case("ssz_generic/uint/uint_bounds.yaml"); let results = doc.test();