Skip to content

Commit

Permalink
Merge branch 'fix/always-check-acceptable-current-state' (#482)
Browse files Browse the repository at this point in the history
* fix/always-check-acceptable-current-state:
  state-machine/changelog: add #482
  Pass state explicitly
  Add more logs
  • Loading branch information
tzemanovic committed Jul 29, 2024
2 parents e1125b1 + dd600c6 commit c012218
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 9 deletions.
3 changes: 3 additions & 0 deletions proptest-state-machine/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## Unreleased

- Fixed checking of pre-conditions with a shrinked or complicated initial state.
([\#482](https://github.com/proptest-rs/proptest/pull/482/commits/9b61544d75f5e44aad742f4546f0e83f2639394c))

## 0.3.0

### New Features
Expand Down
29 changes: 20 additions & 9 deletions proptest-state-machine/src/strategy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,9 @@ impl<
DeleteTransition(ix - 1)
};
// If this delete is not acceptable, undo it and try again
if !self.check_acceptable(None) {
if !self
.check_acceptable(None, self.last_valid_initial_state.clone())
{
self.included_transitions.set(ix);
self.last_shrink = None;
return self.try_simplify();
Expand Down Expand Up @@ -389,7 +391,10 @@ impl<
self.shrink = self.next_shrink_transition(ix);
} else if self.transitions[ix].simplify() {
self.last_shrink = Some(self.shrink);
if self.check_acceptable(Some(ix)) {
if self.check_acceptable(
Some(ix),
self.last_valid_initial_state.clone(),
) {
self.acceptable_transitions[ix] =
(Accepted, self.transitions[ix].current());
return true;
Expand All @@ -409,15 +414,16 @@ impl<

if let InitialState = self.shrink {
if self.initial_state.simplify() {
if self.check_acceptable(None) {
// Store the valid initial state
if self.check_acceptable(None, self.initial_state.current()) {
self.last_valid_initial_state =
self.initial_state.current();
self.last_shrink = Some(self.shrink);
return true;
} else {
// If the shrink is not acceptable, clear it out
self.last_shrink = None;

// `initial_state` is "dirty" here but we won't ever use it again because it is unshrinkable from here.
}
}
self.is_initial_state_shrinkable = false;
Expand All @@ -436,7 +442,10 @@ impl<
let mut ix_to_check = ix;
loop {
if self.included_transitions.test(ix_to_check)
&& self.check_acceptable(Some(ix_to_check))
&& self.check_acceptable(
Some(ix_to_check),
self.last_valid_initial_state.clone(),
)
{
self.acceptable_transitions[ix_to_check] =
(Accepted, self.transitions[ix_to_check].current());
Expand All @@ -458,9 +467,8 @@ impl<
/// Check if the sequence of included transitions is acceptable by the
/// pre-conditions. When `ix` is not `None`, the transition at the given
/// index is taken from its current value.
fn check_acceptable(&self, ix: Option<usize>) -> bool {
fn check_acceptable(&self, ix: Option<usize>, mut state: State) -> bool {
let transitions = self.get_included_acceptable_transitions(ix);
let mut state = self.last_valid_initial_state.clone();
for transition in transitions.iter() {
let is_acceptable = (self.preconditions)(&state, transition);
if is_acceptable {
Expand Down Expand Up @@ -588,7 +596,10 @@ impl<
Some(Transition(ix)) => {
let ix = *ix;
if self.transitions[ix].complicate() {
if self.check_acceptable(Some(ix)) {
if self.check_acceptable(
Some(ix),
self.last_valid_initial_state.clone(),
) {
self.acceptable_transitions[ix] =
(Accepted, self.transitions[ix].current());
// Don't unset prev_shrink; we may be able to complicate
Expand All @@ -606,7 +617,7 @@ impl<
}
Some(InitialState) => {
if self.initial_state.complicate()
&& self.check_acceptable(None)
&& self.check_acceptable(None, self.initial_state.current())
{
self.last_valid_initial_state =
self.initial_state.current();
Expand Down
14 changes: 14 additions & 0 deletions proptest/src/test_runner/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,8 @@ impl TestRunner {
#[cfg(feature = "std")]
let start_time = time::Instant::now();

verbose_message!(self, TRACE, "Starting shrinking");

if case.simplify() {
loop {
#[cfg(feature = "std")]
Expand Down Expand Up @@ -858,12 +860,24 @@ impl TestRunner {
// the function under test is acceptable.
Ok(_) | Err(TestCaseError::Reject(..)) => {
if !case.complicate() {
verbose_message!(
self,
TRACE,
"Cannot complicate further"
);

break;
}
}
Err(TestCaseError::Fail(why)) => {
last_failure = Some(why);
if !case.simplify() {
verbose_message!(
self,
TRACE,
"Cannot simplify further"
);

break;
}
}
Expand Down

0 comments on commit c012218

Please sign in to comment.