@@ -53,14 +53,14 @@ import Control.ActionRegistry (AbortActionRegistryError (..),
5353import Control.Concurrent.Class.MonadMVar.Strict
5454import Control.Concurrent.Class.MonadSTM.Strict
5555import Control.Exception (assert )
56- import Control.Monad (forM_ , void , (<=<) )
56+ import Control.Monad (forM_ , (<=<) )
57+ import Control.Monad.Class.MonadST (MonadST )
5758import Control.Monad.Class.MonadThrow (Exception (.. ), Handler (.. ),
58- MonadCatch (.. ), MonadThrow (.. ), SomeException , catches ,
59- displayException , fromException )
59+ MonadCatch (.. ), MonadMask , MonadThrow (.. ), SomeException ,
60+ catches , displayException , fromException )
6061import Control.Monad.IOSim
6162import Control.Monad.Primitive
6263import Control.Monad.Reader (ReaderT (.. ))
63- import qualified Control.Monad.ST.Lazy as ST
6464import Control.RefCount (RefException , checkForgottenRefs ,
6565 ignoreForgottenRefs )
6666import Control.Tracer (Tracer , nullTracer )
@@ -120,10 +120,6 @@ import Test.Database.LSMTree.StateMachine.Op (HasBlobRef (getBlobRef),
120120 Op (.. ))
121121import qualified Test.QuickCheck as QC
122122import Test.QuickCheck (Arbitrary , Gen , Property )
123- import qualified Test.QuickCheck.Extras as QD
124- import qualified Test.QuickCheck.Monadic as QC
125- import Test.QuickCheck.Monadic (PropertyM )
126- import qualified Test.QuickCheck.StateModel as QD
127123import Test.QuickCheck.StateModel hiding (Var )
128124import Test.QuickCheck.StateModel.Lockstep
129125import qualified Test.QuickCheck.StateModel.Lockstep.Defaults as Lockstep.Defaults
@@ -365,53 +361,37 @@ propLockstep_RealImpl_MockFS_IO tr cleanupFlag fsFlag refsFlag (QC.Fixed salt) =
365361 )
366362 tagFinalState'
367363
368- -- We can not use @bracket@ inside @PropertyM@, so @acquire_RealImpl_MockFS@ and
369- -- @release_RealImpl_MockFS@ are not run in a masked state and it is not
370- -- guaranteed that the latter runs if the former succeeded. Therefore, if
371- -- @runActions@ fails (with exceptions), then not having @bracket@ might lead to
372- -- more exceptions, which can obfuscate the original reason that the property
373- -- failed. Because of this, if @prop@ fails, it's probably best to also try
374- -- running the @IO@ version of this property with the failing seed, and compare
375- -- the counterexamples to see which one is more interesting.
376364propLockstep_RealImpl_MockFS_IOSim ::
377365 (forall s . Tracer (IOSim s ) R. LSMTreeTrace )
378366 -> CheckCleanup
379367 -> CheckFS
380368 -> CheckRefs
381369 -> QC. Fixed R. Salt
370+ -> Actions (Lockstep (ModelState (IOSim RealWorld ) R. Table ))
382371 -> QC. Property
383372propLockstep_RealImpl_MockFS_IOSim tr cleanupFlag fsFlag refsFlag (QC. Fixed salt) =
384- flip QC. monadic prop $ \ x -> QC. ioProperty $ do
385- trac <- ST. stToIO $ runSimTraceST x
386- case traceResult False trac of
387- Left e -> pure $ QC. counterexample (show e) False
388- Right p -> pure p
389- where
390- prop :: forall s . Typeable s => PropertyM (IOSim s ) Property
391- prop = do
392- actions <- QC. pick QC. arbitrary
393- (fsVar, session, errsVar, logVar) <- QC. run (acquire_RealImpl_MockFS tr salt)
394- faultsVar <- QC. run $ newMutVar []
395- let
396- env :: RealEnv R. Table (IOSim s )
397- env = RealEnv {
398- envSession = session
399- , envHandlers = realErrorHandlers @ (IOSim s )
400- , envErrors = errsVar
401- , envErrorsLog = logVar
402- , envInjectFaultResults = faultsVar
403- }
404- void $ QD. runPropertyReaderT
405- (QD. runActions @ (Lockstep (ModelState (IOSim s ) R. Table )) actions)
406- env
407- faults <- QC. run $ readMutVar faultsVar
408- p <- QC. run $ propCleanup cleanupFlag $
409- release_RealImpl_MockFS fsFlag (fsVar, session, errsVar, logVar)
410- p' <- QC. run $ propRefs refsFlag
411- pure
412- $ tagFinalState actions tagFinalState'
413- $ QC. tabulate " Fault results" (fmap show faults)
414- $ p QC. .&&. p'
373+ runActionsBracket
374+ (Proxy @ (ModelState (IOSim RealWorld ) R. Table ))
375+ cleanupFlag
376+ refsFlag
377+ (acquire_RealImpl_MockFS tr salt)
378+ (release_RealImpl_MockFS fsFlag)
379+ (\ r (_, session, errsVar, logVar) -> do
380+ faultsVar <- newMutVar []
381+ let
382+ env :: RealEnv R. Table (IOSim RealWorld )
383+ env = RealEnv {
384+ envSession = session
385+ , envHandlers = realErrorHandlers @ (IOSim RealWorld )
386+ , envErrors = errsVar
387+ , envErrorsLog = logVar
388+ , envInjectFaultResults = faultsVar
389+ }
390+ prop <- runReaderT r env
391+ faults <- readMutVar faultsVar
392+ pure $ QC. tabulate " Fault results" (fmap show faults) prop
393+ )
394+ tagFinalState'
415395
416396acquire_RealImpl_MockFS ::
417397 R. IOLike m
@@ -2862,18 +2842,21 @@ tagFinalState' (getModel -> ModelState finalState finalStats) = concat [
28622842-- count how often something happens over the course of running these actions,
28632843-- then we would want to only tag the final state, not intermediate steps.
28642844runActionsBracket ::
2865- forall state st m e prop . (
2845+ forall state st m n e prop . (
28662846 RunLockstep state m
28672847 , e ~ Error (Lockstep state ) m
28682848 , forall a . IsPerformResult e a
28692849 , QC. Testable prop
2850+ , MonadMask n
2851+ , MonadST n
2852+ , QLS. IOProperty n
28702853 )
28712854 => Proxy state
28722855 -> CheckCleanup
28732856 -> CheckRefs
2874- -> IO st
2875- -> (st -> IO prop )
2876- -> (m QC. Property -> st -> IO QC. Property )
2857+ -> n st
2858+ -> (st -> n prop )
2859+ -> (m QC. Property -> st -> n QC. Property )
28772860 -> (Lockstep state -> [(String , [FinalTag ])])
28782861 -> Actions (Lockstep state ) -> QC. Property
28792862runActionsBracket p cleanupFlag refsFlag init cleanup runner tagger actions =
0 commit comments