Skip to content
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

Grow size faster with a small number of tests #475

Closed
wants to merge 5 commits into from

Commits on Dec 2, 2022

  1. Use state to update a Command's input.

    This allows you to write commands whose input changes when a previous
    Command shrinks.
    
    For example, suppose the state contains `someList :: [Bool]` and
    you have a command whose input expects "index into `someList` pointing
    at `True`". You can generate that index directly, but if an earlier
    command shrinks, `someList` might change and your index now points at
    `False`.
    
    (This is contrived, but hopefully points at the sorts of more
    complicated situations where it might be useful.)
    
    With this you can instead generate a number between 0 and (the number of
    `True` elements). Then use `mkInput` to turn that number into an index
    into `someList`. This will still be valid as long as the number of
    `True` elements doesn't shrink below the generated value.
    
    You could also pass this number directly into `exec`. But then in `exec`
    you'd need to get `someList` directly from the concrete model, which
    might be complicated and/or slow.
    
    I implemented this by adding a new `Command` constructor, `CommandA`
    where A is for Advanced. I don't love this. I could have simply changed
    the existing constructor, but that means every existing Command needs to
    be updated. (It's a simple change, `commandMkInput = const Just` means
    they work as before, but still a massive pain.) The downside of this
    approach is implementation complexity, plus any user functions taking a
    `Command` as input may need to be updated.
    
    Other approaches we could take here:
    
    1. We could pass the concrete state into `exec` along with the concrete
    input. Then you wouldn't need to get `someList` from the model. But you
    might still need to do complicated calculations in `exec` which could
    make the failure output hard to follow.
    
         If we did this we'd have the same tradeoff between changing the
         existing constructor and adding a new one.
    
    2. We could add a callback
    
        ```haskell
        MapMaybeInput
          (state Symbolic -> input Symbolic -> Maybe (input Symbolic)
        ```
    
        Each of these would be applied in turn to update the input.
        (`Require` would be equivalent to a `MapMaybeInput` that ignores
        state, and either returns the input unchanged or `Nothing`.)
    
        This would be compatible with existing commands, but functions
        accepting a `Command` or a `Callback` as input might still need
        changing.
    ChickenProp committed Dec 2, 2022
    Configuration menu
    Copy the full SHA
    0e011ae View commit details
    Browse the repository at this point in the history
  2. Simplify Action.

    We don't need `actionInput0`, because it was only used to pass to
    `actionRefreshInput`. So we can just hide it in a closure.
    ChickenProp committed Dec 2, 2022
    Configuration menu
    Copy the full SHA
    485cbb5 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    51194f0 View commit details
    Browse the repository at this point in the history

Commits on Jan 30, 2023

  1. Remove recheck.

    It's not useful with `recheckAt`, and makes fast growth more awkward to
    implement. This might break compatibility more than upstream wants, but
    at this point I've mostly given up on getting things merged there. If
    they do want fast growth we can figure out something.
    ChickenProp committed Jan 30, 2023
    Configuration menu
    Copy the full SHA
    ce7a7c9 View commit details
    Browse the repository at this point in the history
  2. Grow sizes faster when we run a small number of tests.

    Closes hedgehogqa#472. We now grow test size in fixed increments from 0 to 99, or
    as close as we can without going over, in however many tests we run. If
    we run more than n * 100 tests, then we go from 0 to 99 n times, and
    then do fixed increments for the remainder. Additionally, if we discard
    a bunch of times in a row we start to grow the size.
    ChickenProp committed Jan 30, 2023
    Configuration menu
    Copy the full SHA
    3d2e125 View commit details
    Browse the repository at this point in the history