-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Conversation
…ls-battle-testing-2
frame/support/src/lib.rs
Outdated
@@ -428,6 +428,13 @@ macro_rules! parameter_types_impl_thread_local { | |||
pub fn set(t: $type) { | |||
[<$name:snake:upper>].with(|v| *v.borrow_mut() = t); | |||
} | |||
|
|||
/// Mutate the internal value in place. | |||
pub fn mutate<F: FnOnce(&mut $type) -> ()>(mutate: F) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a unrelated change -- small enough to sneak in here, but I can also extract.
primitives/runtime/src/lib.rs
Outdated
@@ -825,7 +827,7 @@ pub fn verify_encoded_lazy<V: Verify, T: codec::Encode>( | |||
macro_rules! assert_eq_error_rate { | |||
($x:expr, $y:expr, $error:expr $(,)?) => { | |||
assert!( | |||
($x) >= (($y) - ($error)) && ($x) <= (($y) + ($error)), | |||
($x >= $crate::Saturating::saturating_sub($y, $error)) && ($x <= $crate::Saturating::saturating_add($y, $error)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a unrelated change -- small enough to sneak in here, but I can also extract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really cool to see some fuzzing. Looks good to me!
…ls-battle-testing-2
We could create a tool which generates a set of calls from the metadata of a pallet. Could even be done in PolkadotJS, as general fuzzy testing framework. |
// NOTE: use this to get predictable (non)randomness: | ||
// use::{rngs::SmallRng, SeedableRng}; | ||
// let mut rng = SmallRng::from_seed([0u8; 32]); | ||
let mut rng = thread_rng(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good follow up:
From experience I can tell you that it is a good idea to create a random seed, print it, and add the possibility to overide it via env variable.
Then you always have a different set of tests, but if it fails, you can reproduce by using the printed seed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
excellent idea, I actually have this in my code as a commented code that: If you want reproducible output, do this and that, but using a seed and env var makes a whole lot more sense.
let mut rng = thread_rng(); | ||
let mut ext = sp_io::TestExternalities::new_empty(); | ||
// NOTE: sadly events don't fulfill the requirements of hashmap or btreemap. | ||
let mut events_histogram = Vec::<(PoolsEvents<T>, u32)>::default(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it not enough to use the event index, or do you also want the values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah index could have been enough too
}); | ||
System::reset_events(); | ||
|
||
if iteration % ERA == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some smol doc please.
Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
…bstrate into kiz-pools-battle-testing-2
/cmd queue -c fmt $ 1 |
@kianenigma https://gitlab.parity.io/parity/mirrors/substrate/-/jobs/1831586 was started for your command Comment |
@kianenigma Command |
bot merge |
* some additional tests and stuff * make sanity public * add some sort of fuzz test for pools * breaks every now and then * breaks every now and then * IT WORKS AND PASSES 100k TESTS * cleanup * safe id addition * fix assert_eq_error_rate * Update frame/nomination-pools/src/tests.rs Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update frame/nomination-pools/src/tests.rs Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * add some doc * Fix * ".git/.scripts/fmt.sh" 1 Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: command-bot <>
This PR is itself pretty insubstantial, there is not real code change other than adding a fuzz-style test for nomination pools.
Some notes about the approach: For now, I mainly did the fuzz-testing without using a proper fuzzer because it would allow for the
mock
to be reused. In the past we gatedmock.rs
behind some feature flag to make it available, and this time around I wanted to try the alternative approach.Having done this, I can say that the main advantage of this type of testing is seamless setup, and the downside is reproducibility of failing tests.
For now, in order to have reproducible errors, you have to use a seeded randomness, and then re-use it. It requires a little bit of manual work, but it did allow me to solve every single test failure.
It is probably still better to move the fuzz-test use a proper fuzzer as follow-up. Nonetheless, it must be done such that the mock file is reused (a good first issue for a new team member or external contributor).
Some notes about the fuzzing outcome: As you see in the code, I randomly generate calls that may or may not be valid and bombard the pallet with these calls, and every so often I execute the entire set of sanity checks that are defined in the pallet.
Moreover, I inject a single agent into a random pool that is manually tracking the expected reward amount (see
Agent
in the code for details).The tests generally get quite slow, particularly if you want to execute the sanity checks often. In the default setup, the state grows until 1000 pools and 10000 members, and with 1 million random submissions, this is the final outcome:
All in all, this was super useful and I feel way more confident about nomination pools now.