-
Notifications
You must be signed in to change notification settings - Fork 408
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
Ensure preconditions are satisified when shrinking Commands actions #739
Ensure preconditions are satisified when shrinking Commands actions #739
Conversation
In some cases a failing command sequence would shrink to a single command whose precondition was not satisfied, e.g. dequeueing from an initially empty queue. Ensuring preconditions are satisfied means shrinking outputs a valid sequence of commands.
This is one part of #632, split out into its own commit, and now with tests. Let me know if you'd like me to simplify the test. I'm sure it's possible, though the benefits are unclear to me: since many members of |
It appears `Commands.scala` is inherently jvm-specific
I haven't used the commands API a lot. How would a test case satisfy the pre-conditions, but then the failure cause it to shrink to something invalid? Are sequential commands being shrunk from the left-hand side when they should be shrunk from the right? Seems like it shouldn't be doing that. It should be following the same shrinking rules for lists in ScalaCheck. |
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.
How would a test case satisfy the pre-conditions, but then the failure cause it to shrink to something invalid? Are sequential commands being shrunk from the left-hand side when they should be shrunk from the right? Seems like it shouldn't be doing that. It should be following the same shrinking rules for lists in ScalaCheck.
The shrinking rule for lists as I understand it try the first half, then the last half, then mixes either half with shrunk versions of the other half. (The rule restarts when another failing case is verified.)
For instance with commandds, if we were testing a Map
-like structure implementation which turns out to be no-op and always return None
Scalacheck might find this failing test case:
SetItem("A", 1)
SetItem("B", 2)
RemoveItem("B")
GetItemOrNone("A") -> None
# failSetItem("C", 3)
We know that only items (1) and (4) are required to reproduce a failure, therefore (1, 4) will be the minimum shrink.
If RemoveItem
has the precondition that the key already exist (unlike GetItemOrNone
), Scalacheck might discover that:
- You can remove (5) or (3) without changing the outcome
- Removing (4) would keep the failure from occurring
- Removing (2) would cause (3) to fail its precondition.
- Removing both (2) and (3) doesn't change the outcome.
Surprisingly, I didn't encounter issues where Scalacheck would fail to verify preconditions during shrinking in 1.14
, though I cannot figure out what exactly enforced this. It will be good to have this explicitly checked and tested.
My bounded queue example also demonstrates this, though not in exactly in the gisted form. Here's a diff with gist links (and slightly mismatching file names), and first the session it produces:
As the name suggests, the shrunk command sequence tries to dequeue out of an empty queue, which violates the dequeue precondition. Here's the diff (relative to the gist URLs) which created this session:
|
Is there something I can help with here to get this into a mergeable state? |
I have tested the PR on two examples where shrinking previously lead to invalid command sequences and this seems to solve the problem 👍 |
Sorry for the delay. If this is fixing the issue for others, as in #839, we should get this merged. Thanks for the contribution. If it used to work, I wonder if we should track down what the change since 1.14.3 was that introduced the defect? |
Thank you for reviewing! I'm not familiar with the PR process in this project, who is expected to hit merge on this PR? |
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 second @ashawley's question about tracking down what broke since 1.14. But if that investigation reveals an even deeper problem, we can roll this back without affecting bincompat. All evidence is that this is good now.
In some cases a failing command sequence would shrink to a single
command whose precondition was not satisfied, e.g. dequeueing from an
initially empty queue. Ensuring preconditions are satisfied means
shrinking outputs a valid sequence of commands.