quickcheck: The random selection doesn't appear to be very random

I have a type which wraps an i32, and wrote an Arbitrary impl like so:

trait Arbitrary<PgDate> {
    fn arbitrary<G: Gen>() -> Self {
          PgDate(i32::arbitrary())
    }
}

When I actually output what it’s running with, the values are only ranging from 100 to -100, instead of 100 completely random numbers as I’d expect. Additionally, shrink appears to be flawed on these types. My understanding was that quickcheck would test for known problematic values for a given type. For i32 I’d expect that to at minimum be 1, 0, -1, i32::MAX and i32::MIN, but when I add the shrink like so:

fn shrink(&self) -> Box<Iterator<Item=Self>> {
    Box::new(self.0.shrink().map(PgDate))

I just see the same range of -100 to 100. This caused a critical bug that occurs for any values less than -2451545 to go unnoticed.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 17 (10 by maintainers)

Commits related to this issue

Most upvoted comments

There is interest. But I maintain dozens of projects, so it can take me a very long time to merge PRs and/or it’s very easy for me to lose track of PRs. Editing comments to include status updates probably doesn’t help, as was done in #221. I don’t get emails when edits are made.

No worries and I did not mean to criticize, of course. It’s just a matter of my personal PR hygiene that I close unmerged PRs on my own after a while when I’ve also moved on to other things and no longer intend to keep them updated / mergeable.

Maybe it’s time to make a change like #99, but for numbers?

  1. With 1/4 probability, pick a number from [-100,100]
  2. With 3/4-1/25 probability, pick random bit pattern interpreted as a number
  3. With 3/100 probability, pick a power of two + [-3,3]
  4. With 1/100 probability, pick a number from some pre-selected set of tricky numbers that have more than one bug about and not already included in “1.” or “3.”. Some typical constants for CRC or prime numbers may appear there.

That could make “sane default” for multiple varied uses. Obviously one could override the distribution to task-specific.

There needs to be a new api for requesting a quickcheck-controlled size value. Something that’s appropriate for selecting the size of a datastructure to generate. I think I mostly use usize’s Arbitrary impl for that at the moment.