-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce proptest in chainstate #294
Conversation
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.
Looks good. Just some small nitpicks.
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.
👍
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.
Besides the naming, I think everything looks fine.
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.
Added some comments. The one on TestFramework::random_block
I consider quite important to address (to be discussed whether now or as a subsequent PR)
Was experimenting a bit with ways we could pass custom or randomly-initialized seeds to test cases, and the following hacekd together prototype seemed to work okay: use test_case::test_case;
use rand::{rngs::StdRng, Rng, SeedableRng, RngCore};
type Seed = <StdRng as SeedableRng>::Seed;
// The test previously failed with these seeds. Fixed in commit 0xabcd, blah blah.
#[test_case([0x12; 32])]
#[test_case([0x13; 32])]
// Generate a new seed at random.
#[test_case(rand::thread_rng().gen())]
fn silly(seed: Seed) {
let mut rng = StdRng::from_seed(seed);
let x = rng.next_u32() as u64;
assert_eq!(2 * x, x + x)
} It uses the Note this prototype uses #[test_case(Seed::from_str("1212121212121212..."))]
#[test_case(Seed::from_str("1313131313131313..."))]
#[test_case(Seed::fresh())] If the Thoughts / comments? |
If this prints the seeded value, then I think it's a good choice. |
I like the idea and will try to apply it. Sam, I believe that seed will be printed with the same function as right now (or maybe in fixture, not sure yet). The difference is that a seed would be a parameter to test case and the regression list would be explicit. |
Sorry closed the PR by accident |
Well there are two options:
I am leaning towards (1) since it gives more freedom to pick these crates. It also only prints the seed, in case the table driven testing is used for more stuff besides the seed (i.e. there are multiple arguments, only one of them is seed, we probably want to only print the seed, not several kB of block data). However, there might be other criteria that I have not considered. |
Let's start with simple printing, since Stanislav showed that nextest also prints things correctly and doesn't mix output from different threads. |
The However, there are some other criteria that come to my mind that should be considered when picking the crate to use:
Please be aware that I only used |
cargo test --package chainstate --lib -- detail::tests::double_spend_tests
Also these test cases can be filtered by name |
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.
Adding some comments. All minor suggestions or discussion points. I am happy with merging the PR as is from what I see.
That looks good. I think we can give that a shot. |
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.
I think this looks good now. A good step in the right direction.
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.
Cool stuff
Replace explicit random number generation in chainstate tests with proptest.
This crate generates input values automatically. In case of a test failure it performs input shrinking (the process of finding minimal test input to reproduce the fail). After that it store the seed of failed case in a file for future regressions.
Example of regression seeds:
By default every test is run 256 times with different inputs. But for the cases in chainstate it's an overhead, so I configured proptest to run each test once.
P.S. while reading the code I noticed that chainstate/src/lib.rs exposes
ChainstateInterfaceImpl
anddetail::Chainstate
as public, which looks wrong considering there is dedicated public interfaceChainstateInterface
.