From 9b61544d75f5e44aad742f4546f0e83f2639394c Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 17 Jul 2024 18:27:35 +1000 Subject: [PATCH 1/3] Add more logs --- proptest/src/test_runner/runner.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/proptest/src/test_runner/runner.rs b/proptest/src/test_runner/runner.rs index 27d0ddf8..c8011d4b 100644 --- a/proptest/src/test_runner/runner.rs +++ b/proptest/src/test_runner/runner.rs @@ -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")] @@ -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; } } From b52c68ff423efe4a558b5967c86c17c457d3a84d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 17 Jul 2024 18:42:59 +1000 Subject: [PATCH 2/3] Pass state explicitly --- proptest-state-machine/src/strategy.rs | 29 ++++++++++++++++++-------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/proptest-state-machine/src/strategy.rs b/proptest-state-machine/src/strategy.rs index 32e139d6..15abfb44 100644 --- a/proptest-state-machine/src/strategy.rs +++ b/proptest-state-machine/src/strategy.rs @@ -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(); @@ -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; @@ -409,8 +414,7 @@ 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); @@ -418,6 +422,8 @@ impl< } 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; @@ -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()); @@ -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) -> bool { + fn check_acceptable(&self, ix: Option, 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 { @@ -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 @@ -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(); From dd600c694df705480c5ab9553f5acd5820107948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Mon, 29 Jul 2024 14:40:04 +0100 Subject: [PATCH 3/3] state-machine/changelog: add #482 --- proptest-state-machine/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proptest-state-machine/CHANGELOG.md b/proptest-state-machine/CHANGELOG.md index 6acebb51..8fe48a5b 100644 --- a/proptest-state-machine/CHANGELOG.md +++ b/proptest-state-machine/CHANGELOG.md @@ -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