mirror of
https://github.com/barrucadu/dejafu.git
synced 2024-12-18 19:11:37 +03:00
Merge branch 'discard'
This commit is contained in:
commit
50712c54cd
@ -7,6 +7,7 @@ import qualified Cases.MultiThreaded as M
|
|||||||
import qualified Cases.Refinement as R
|
import qualified Cases.Refinement as R
|
||||||
import qualified Cases.Litmus as L
|
import qualified Cases.Litmus as L
|
||||||
import qualified Cases.Async as A
|
import qualified Cases.Async as A
|
||||||
|
import qualified Cases.Discard as D
|
||||||
|
|
||||||
-- | Run all the test cases.
|
-- | Run all the test cases.
|
||||||
testCases :: [Test]
|
testCases :: [Test]
|
||||||
@ -16,4 +17,5 @@ testCases = map (uncurry testGroup)
|
|||||||
, ("Refinement", R.tests)
|
, ("Refinement", R.tests)
|
||||||
, ("Litmus", L.tests)
|
, ("Litmus", L.tests)
|
||||||
, ("Async", A.tests)
|
, ("Async", A.tests)
|
||||||
|
, ("Discard", D.tests)
|
||||||
]
|
]
|
||||||
|
25
dejafu-tests/Cases/Discard.hs
Normal file
25
dejafu-tests/Cases/Discard.hs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
module Cases.Discard where
|
||||||
|
|
||||||
|
import Control.Concurrent.Classy
|
||||||
|
import Test.DejaFu (gives')
|
||||||
|
import Test.Framework (Test)
|
||||||
|
import Test.Framework.Providers.HUnit (hUnitTestToTests)
|
||||||
|
import Test.HUnit (test)
|
||||||
|
import Test.HUnit.DejaFu (Discard(..), defaultMemType, defaultWay, testDejafuDiscard)
|
||||||
|
|
||||||
|
tests :: [Test]
|
||||||
|
tests = hUnitTestToTests $ test
|
||||||
|
[ check "all results" [1, 2, 3] (const Nothing)
|
||||||
|
, check "no results" [] (const $ Just DiscardResultAndTrace)
|
||||||
|
, check "some results" [1, 2] (\x -> if x == Right 3 then Just DiscardResultAndTrace else Nothing)
|
||||||
|
]
|
||||||
|
where
|
||||||
|
check name xs f = testDejafuDiscard f defaultWay defaultMemType nondet name (gives' xs)
|
||||||
|
|
||||||
|
nondet :: MonadConc m => m Int
|
||||||
|
nondet = do
|
||||||
|
mvar <- newEmptyMVar
|
||||||
|
fork $ putMVar mvar 1
|
||||||
|
fork $ putMVar mvar 2
|
||||||
|
fork $ putMVar mvar 3
|
||||||
|
readMVar mvar
|
@ -25,6 +25,7 @@ executable dejafu-tests
|
|||||||
, Cases.MultiThreaded
|
, Cases.MultiThreaded
|
||||||
, Cases.Refinement
|
, Cases.Refinement
|
||||||
, Cases.Litmus
|
, Cases.Litmus
|
||||||
|
, Cases.Discard
|
||||||
|
|
||||||
, Examples
|
, Examples
|
||||||
, Examples.AutoUpdate
|
, Examples.AutoUpdate
|
||||||
|
@ -6,6 +6,35 @@ All notable changes to this project will be documented in this file.
|
|||||||
This project is versioned according to the [Package Versioning Policy](https://pvp.haskell.org), the
|
This project is versioned according to the [Package Versioning Policy](https://pvp.haskell.org), the
|
||||||
*de facto* standard Haskell versioning scheme.
|
*de facto* standard Haskell versioning scheme.
|
||||||
|
|
||||||
|
unreleased
|
||||||
|
----------
|
||||||
|
|
||||||
|
### Test.DejaFu
|
||||||
|
|
||||||
|
- Exposed the new SCT discard functions through `dejafuDiscard` and `dejafuDiscardIO`.
|
||||||
|
|
||||||
|
There are no `dejafusDiscard` and `dejafusDiscardIO` functions because this would probably be
|
||||||
|
confusing, as the traces are shared.
|
||||||
|
|
||||||
|
- The `Discard` type and `defaultDiscard` function are also exposed.
|
||||||
|
|
||||||
|
### Test.DejaFu.Defaults
|
||||||
|
|
||||||
|
- Added a new `defaultDiscarder` function, which discards nothing.
|
||||||
|
|
||||||
|
### Test.DejaFu.SCT
|
||||||
|
|
||||||
|
- Added new SCT functions to selectively discard results or traces, which can be a significant
|
||||||
|
memory saving if you know what sorts of results you are interested in:
|
||||||
|
- New type: `Discard`.
|
||||||
|
- New functions: `runSCTDiscard`, `resultsSetDiscard`, `sctBoundDiscard`,
|
||||||
|
`sctUniformRandomDiscard`, and `sctWeightedRandomDiscard`.
|
||||||
|
- `resultsSet` and `resultsSet'` now discard traces as they are produced, rather than all at the
|
||||||
|
end, greatly improving performance when traces are large.
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
0.7.0.2 [2017-06-12] (git tag: [dejafu-0.7.0.2][])
|
0.7.0.2 [2017-06-12] (git tag: [dejafu-0.7.0.2][])
|
||||||
-------
|
-------
|
||||||
|
@ -107,6 +107,12 @@ module Test.DejaFu
|
|||||||
, dejafusWay
|
, dejafusWay
|
||||||
, dejafusWayIO
|
, dejafusWayIO
|
||||||
|
|
||||||
|
, Discard(..)
|
||||||
|
, defaultDiscarder
|
||||||
|
|
||||||
|
, dejafuDiscard
|
||||||
|
, dejafuDiscardIO
|
||||||
|
|
||||||
-- ** Memory Models
|
-- ** Memory Models
|
||||||
|
|
||||||
-- | Threads running under modern multicore processors do not behave
|
-- | Threads running under modern multicore processors do not behave
|
||||||
@ -378,7 +384,26 @@ dejafuWay :: Show a
|
|||||||
-> (String, Predicate a)
|
-> (String, Predicate a)
|
||||||
-- ^ The predicate (with a name) to check
|
-- ^ The predicate (with a name) to check
|
||||||
-> IO Bool
|
-> IO Bool
|
||||||
dejafuWay way memtype conc test = dejafusWay way memtype conc [test]
|
dejafuWay = dejafuDiscard (const Nothing)
|
||||||
|
|
||||||
|
-- | Variant of 'dejafuWay' which can selectively discard results.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
dejafuDiscard :: Show a
|
||||||
|
=> (Either Failure a -> Maybe Discard)
|
||||||
|
-- ^ Selectively discard results.
|
||||||
|
-> Way
|
||||||
|
-- ^ How to run the concurrent program.
|
||||||
|
-> MemType
|
||||||
|
-- ^ The memory model to use for non-synchronised @CRef@ operations.
|
||||||
|
-> (forall t. ConcST t a)
|
||||||
|
-- ^ The computation to test
|
||||||
|
-> (String, Predicate a)
|
||||||
|
-- ^ The predicate (with a name) to check
|
||||||
|
-> IO Bool
|
||||||
|
dejafuDiscard discard way memtype conc (name, test) = do
|
||||||
|
let traces = runST (runSCTDiscard discard way memtype conc)
|
||||||
|
doTest name (test traces)
|
||||||
|
|
||||||
-- | Variant of 'dejafu' which takes a collection of predicates to
|
-- | Variant of 'dejafu' which takes a collection of predicates to
|
||||||
-- test, returning 'True' if all pass.
|
-- test, returning 'True' if all pass.
|
||||||
@ -421,8 +446,15 @@ dejafuIO = dejafuWayIO defaultWay defaultMemType
|
|||||||
--
|
--
|
||||||
-- @since 0.6.0.0
|
-- @since 0.6.0.0
|
||||||
dejafuWayIO :: Show a => Way -> MemType -> ConcIO a -> (String, Predicate a) -> IO Bool
|
dejafuWayIO :: Show a => Way -> MemType -> ConcIO a -> (String, Predicate a) -> IO Bool
|
||||||
dejafuWayIO way memtype concio test =
|
dejafuWayIO = dejafuDiscardIO (const Nothing)
|
||||||
dejafusWayIO way memtype concio [test]
|
|
||||||
|
-- | Variant of 'dejafuDiscard' for computations which do 'IO'.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
dejafuDiscardIO :: Show a => (Either Failure a -> Maybe Discard) -> Way -> MemType -> ConcIO a -> (String, Predicate a) -> IO Bool
|
||||||
|
dejafuDiscardIO discard way memtype concio (name, test) = do
|
||||||
|
traces <- runSCTDiscard discard way memtype concio
|
||||||
|
doTest name (test traces)
|
||||||
|
|
||||||
-- | Variant of 'dejafus' for computations which do 'IO'.
|
-- | Variant of 'dejafus' for computations which do 'IO'.
|
||||||
--
|
--
|
||||||
|
@ -742,6 +742,7 @@ instance NFData Decision where
|
|||||||
--
|
--
|
||||||
-- @since 0.5.0.0
|
-- @since 0.5.0.0
|
||||||
showTrace :: Trace -> String
|
showTrace :: Trace -> String
|
||||||
|
showTrace [] = "<trace discarded>"
|
||||||
showTrace trc = intercalate "\n" $ concatMap go trc : strkey where
|
showTrace trc = intercalate "\n" $ concatMap go trc : strkey where
|
||||||
go (_,_,CommitCRef _ _) = "C-"
|
go (_,_,CommitCRef _ _) = "C-"
|
||||||
go (Start (ThreadId _ i),_,_) = "S" ++ show i ++ "-"
|
go (Start (ThreadId _ i),_,_) = "S" ++ show i ++ "-"
|
||||||
|
@ -19,6 +19,12 @@ import Test.DejaFu.SCT
|
|||||||
defaultWay :: Way
|
defaultWay :: Way
|
||||||
defaultWay = systematically defaultBounds
|
defaultWay = systematically defaultBounds
|
||||||
|
|
||||||
|
-- | Do not discard any results.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
defaultDiscarder :: Either Failure a -> Maybe Discard
|
||||||
|
defaultDiscarder = const Nothing
|
||||||
|
|
||||||
-- | The default memory model: @TotalStoreOrder@
|
-- | The default memory model: @TotalStoreOrder@
|
||||||
--
|
--
|
||||||
-- @since 0.2.0.0
|
-- @since 0.2.0.0
|
||||||
|
@ -18,9 +18,18 @@ module Test.DejaFu.SCT
|
|||||||
, uniformly
|
, uniformly
|
||||||
, swarmy
|
, swarmy
|
||||||
, runSCT
|
, runSCT
|
||||||
, runSCT'
|
|
||||||
, resultsSet
|
, resultsSet
|
||||||
|
|
||||||
|
-- ** Discarding variants
|
||||||
|
, Discard(..)
|
||||||
|
, runSCTDiscard
|
||||||
|
, resultsSetDiscard
|
||||||
|
|
||||||
|
-- ** Strict variants
|
||||||
|
, runSCT'
|
||||||
, resultsSet'
|
, resultsSet'
|
||||||
|
, runSCTDiscard'
|
||||||
|
, resultsSetDiscard'
|
||||||
|
|
||||||
-- * Bounded Partial-order Reduction
|
-- * Bounded Partial-order Reduction
|
||||||
|
|
||||||
@ -51,6 +60,7 @@ module Test.DejaFu.SCT
|
|||||||
, Bounds(..)
|
, Bounds(..)
|
||||||
, noBounds
|
, noBounds
|
||||||
, sctBound
|
, sctBound
|
||||||
|
, sctBoundDiscard
|
||||||
|
|
||||||
-- ** Pre-emption Bounding
|
-- ** Pre-emption Bounding
|
||||||
|
|
||||||
@ -91,8 +101,11 @@ module Test.DejaFu.SCT
|
|||||||
|
|
||||||
, sctUniformRandom
|
, sctUniformRandom
|
||||||
, sctWeightedRandom
|
, sctWeightedRandom
|
||||||
|
, sctUniformRandomDiscard
|
||||||
|
, sctWeightedRandomDiscard
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Control.Applicative ((<|>))
|
||||||
import Control.DeepSeq (NFData(..))
|
import Control.DeepSeq (NFData(..))
|
||||||
import Control.Monad.Ref (MonadRef)
|
import Control.Monad.Ref (MonadRef)
|
||||||
import Data.List (foldl')
|
import Data.List (foldl')
|
||||||
@ -201,21 +214,7 @@ runSCT :: MonadRef r n
|
|||||||
-> ConcT r n a
|
-> ConcT r n a
|
||||||
-- ^ The computation to run many times.
|
-- ^ The computation to run many times.
|
||||||
-> n [(Either Failure a, Trace)]
|
-> n [(Either Failure a, Trace)]
|
||||||
runSCT (Systematic cb) memtype = sctBound memtype cb
|
runSCT = runSCTDiscard (const Nothing)
|
||||||
runSCT (Weighted g lim use) memtype = sctWeightedRandom memtype g lim use
|
|
||||||
runSCT (Uniform g lim) memtype = sctUniformRandom memtype g lim
|
|
||||||
|
|
||||||
-- | A strict variant of 'runSCT'.
|
|
||||||
--
|
|
||||||
-- Demanding the result of this will force it to normal form, which
|
|
||||||
-- may be more efficient in some situations.
|
|
||||||
--
|
|
||||||
-- @since 0.6.0.0
|
|
||||||
runSCT' :: (MonadRef r n, NFData a)
|
|
||||||
=> Way -> MemType -> ConcT r n a -> n [(Either Failure a, Trace)]
|
|
||||||
runSCT' way memtype conc = do
|
|
||||||
res <- runSCT way memtype conc
|
|
||||||
rnf res `seq` pure res
|
|
||||||
|
|
||||||
-- | Return the set of results of a concurrent program.
|
-- | Return the set of results of a concurrent program.
|
||||||
--
|
--
|
||||||
@ -228,8 +227,67 @@ resultsSet :: (MonadRef r n, Ord a)
|
|||||||
-> ConcT r n a
|
-> ConcT r n a
|
||||||
-- ^ The computation to run many times.
|
-- ^ The computation to run many times.
|
||||||
-> n (Set (Either Failure a))
|
-> n (Set (Either Failure a))
|
||||||
resultsSet way memtype conc =
|
resultsSet = resultsSetDiscard (const Nothing)
|
||||||
S.fromList . map fst <$> runSCT way memtype conc
|
|
||||||
|
-- | An @Either Failure a -> Maybe Discard@ value can be used to
|
||||||
|
-- selectively discard results.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
data Discard
|
||||||
|
= DiscardTrace
|
||||||
|
-- ^ Discard the trace but keep the result. The result will appear
|
||||||
|
-- to have an empty trace.
|
||||||
|
| DiscardResultAndTrace
|
||||||
|
-- ^ Discard the result and the trace. It will simply not be
|
||||||
|
-- reported as a possible behaviour of the program.
|
||||||
|
deriving (Eq, Show, Read, Ord, Enum, Bounded)
|
||||||
|
|
||||||
|
instance NFData Discard where
|
||||||
|
rnf d = d `seq` ()
|
||||||
|
|
||||||
|
-- | A variant of 'runSCT' which can selectively discard results.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
runSCTDiscard :: MonadRef r n
|
||||||
|
=> (Either Failure a -> Maybe Discard)
|
||||||
|
-- ^ Selectively discard results.
|
||||||
|
-> Way
|
||||||
|
-- ^ How to run the concurrent program.
|
||||||
|
-> MemType
|
||||||
|
-- ^ The memory model to use for non-synchronised @CRef@ operations.
|
||||||
|
-> ConcT r n a
|
||||||
|
-- ^ The computation to run many times.
|
||||||
|
-> n [(Either Failure a, Trace)]
|
||||||
|
runSCTDiscard discard (Systematic cb) memtype = sctBoundDiscard discard memtype cb
|
||||||
|
runSCTDiscard discard (Weighted g lim use) memtype = sctWeightedRandomDiscard discard memtype g lim use
|
||||||
|
runSCTDiscard discard (Uniform g lim) memtype = sctUniformRandomDiscard discard memtype g lim
|
||||||
|
|
||||||
|
-- | A variant of 'resultsSet' which can selectively discard results.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
resultsSetDiscard :: (MonadRef r n, Ord a)
|
||||||
|
=> (Either Failure a -> Maybe Discard)
|
||||||
|
-- ^ Selectively discard results. Traces are always discarded.
|
||||||
|
-> Way
|
||||||
|
-- ^ How to run the concurrent program.
|
||||||
|
-> MemType
|
||||||
|
-- ^ The memory model to use for non-synchronised @CRef@ operations.
|
||||||
|
-> ConcT r n a
|
||||||
|
-- ^ The computation to run many times.
|
||||||
|
-> n (Set (Either Failure a))
|
||||||
|
resultsSetDiscard discard way memtype conc =
|
||||||
|
let discard' efa = discard efa <|> Just DiscardTrace
|
||||||
|
in S.fromList . map fst <$> runSCTDiscard discard' way memtype conc
|
||||||
|
|
||||||
|
-- | A strict variant of 'runSCT'.
|
||||||
|
--
|
||||||
|
-- Demanding the result of this will force it to normal form, which
|
||||||
|
-- may be more efficient in some situations.
|
||||||
|
--
|
||||||
|
-- @since 0.6.0.0
|
||||||
|
runSCT' :: (MonadRef r n, NFData a)
|
||||||
|
=> Way -> MemType -> ConcT r n a -> n [(Either Failure a, Trace)]
|
||||||
|
runSCT' = runSCTDiscard' (const Nothing)
|
||||||
|
|
||||||
-- | A strict variant of 'resultsSet'.
|
-- | A strict variant of 'resultsSet'.
|
||||||
--
|
--
|
||||||
@ -239,8 +297,30 @@ resultsSet way memtype conc =
|
|||||||
-- @since 0.6.0.0
|
-- @since 0.6.0.0
|
||||||
resultsSet' :: (MonadRef r n, Ord a, NFData a)
|
resultsSet' :: (MonadRef r n, Ord a, NFData a)
|
||||||
=> Way -> MemType -> ConcT r n a -> n (Set (Either Failure a))
|
=> Way -> MemType -> ConcT r n a -> n (Set (Either Failure a))
|
||||||
resultsSet' way memtype conc = do
|
resultsSet' = resultsSetDiscard' (const Nothing)
|
||||||
res <- resultsSet' way memtype conc
|
|
||||||
|
-- | A strict variant of 'runSCTDiscard'.
|
||||||
|
--
|
||||||
|
-- Demanding the result of this will force it to normal form, which
|
||||||
|
-- may be more efficient in some situations.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
runSCTDiscard' :: (MonadRef r n, NFData a)
|
||||||
|
=> (Either Failure a -> Maybe Discard) -> Way -> MemType -> ConcT r n a -> n [(Either Failure a, Trace)]
|
||||||
|
runSCTDiscard' discard way memtype conc = do
|
||||||
|
res <- runSCTDiscard discard way memtype conc
|
||||||
|
rnf res `seq` pure res
|
||||||
|
|
||||||
|
-- | A strict variant of 'resultsSetDiscard'.
|
||||||
|
--
|
||||||
|
-- Demanding the result of this will force it to normal form, which
|
||||||
|
-- may be more efficient in some situations.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
resultsSetDiscard' :: (MonadRef r n, Ord a, NFData a)
|
||||||
|
=> (Either Failure a -> Maybe Discard) -> Way -> MemType -> ConcT r n a -> n (Set (Either Failure a))
|
||||||
|
resultsSetDiscard' discard way memtype conc = do
|
||||||
|
res <- resultsSetDiscard discard way memtype conc
|
||||||
rnf res `seq` pure res
|
rnf res `seq` pure res
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -394,7 +474,22 @@ sctBound :: MonadRef r n
|
|||||||
-> ConcT r n a
|
-> ConcT r n a
|
||||||
-- ^ The computation to run many times
|
-- ^ The computation to run many times
|
||||||
-> n [(Either Failure a, Trace)]
|
-> n [(Either Failure a, Trace)]
|
||||||
sctBound memtype cb conc = go initialState where
|
sctBound = sctBoundDiscard (const Nothing)
|
||||||
|
|
||||||
|
-- | A variant of 'sctBound' which can selectively discard results.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
sctBoundDiscard :: MonadRef r n
|
||||||
|
=> (Either Failure a -> Maybe Discard)
|
||||||
|
-- ^ Selectively discard results.
|
||||||
|
-> MemType
|
||||||
|
-- ^ The memory model to use for non-synchronised @CRef@ operations.
|
||||||
|
-> Bounds
|
||||||
|
-- ^ The combined bounds.
|
||||||
|
-> ConcT r n a
|
||||||
|
-- ^ The computation to run many times
|
||||||
|
-> n [(Either Failure a, Trace)]
|
||||||
|
sctBoundDiscard discard memtype cb conc = go initialState where
|
||||||
-- Repeatedly run the computation gathering all the results and
|
-- Repeatedly run the computation gathering all the results and
|
||||||
-- traces into a list until there are no schedules remaining to try.
|
-- traces into a list until there are no schedules remaining to try.
|
||||||
go dp = case findSchedulePrefix dp of
|
go dp = case findSchedulePrefix dp of
|
||||||
@ -408,8 +503,8 @@ sctBound memtype cb conc = go initialState where
|
|||||||
let newDPOR = addTrace conservative trace dp
|
let newDPOR = addTrace conservative trace dp
|
||||||
|
|
||||||
if schedIgnore s
|
if schedIgnore s
|
||||||
then go newDPOR
|
then go newDPOR
|
||||||
else ((res, trace):) <$> go (addBacktracks bpoints newDPOR)
|
else checkDiscard discard res trace $ go (addBacktracks bpoints newDPOR)
|
||||||
|
|
||||||
Nothing -> pure []
|
Nothing -> pure []
|
||||||
|
|
||||||
@ -443,14 +538,32 @@ sctUniformRandom :: (MonadRef r n, RandomGen g)
|
|||||||
-> ConcT r n a
|
-> ConcT r n a
|
||||||
-- ^ The computation to run many times.
|
-- ^ The computation to run many times.
|
||||||
-> n [(Either Failure a, Trace)]
|
-> n [(Either Failure a, Trace)]
|
||||||
sctUniformRandom memtype g0 lim0 conc = go g0 (max 0 lim0) where
|
sctUniformRandom = sctUniformRandomDiscard (const Nothing)
|
||||||
|
|
||||||
|
-- | A variant of 'sctUniformRandom' which can selectively discard
|
||||||
|
-- results.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
sctUniformRandomDiscard :: (MonadRef r n, RandomGen g)
|
||||||
|
=> (Either Failure a -> Maybe Discard)
|
||||||
|
-- ^ Selectively discard results.
|
||||||
|
-> MemType
|
||||||
|
-- ^ The memory model to use for non-synchronised @CRef@ operations.
|
||||||
|
-> g
|
||||||
|
-- ^ The random number generator.
|
||||||
|
-> Int
|
||||||
|
-- ^ The number of executions to perform.
|
||||||
|
-> ConcT r n a
|
||||||
|
-- ^ The computation to run many times.
|
||||||
|
-> n [(Either Failure a, Trace)]
|
||||||
|
sctUniformRandomDiscard discard memtype g0 lim0 conc = go g0 (max 0 lim0) where
|
||||||
go _ 0 = pure []
|
go _ 0 = pure []
|
||||||
go g n = do
|
go g n = do
|
||||||
(res, s, trace) <- runConcurrent (randSched $ \g' -> (1, g'))
|
(res, s, trace) <- runConcurrent (randSched $ \g' -> (1, g'))
|
||||||
memtype
|
memtype
|
||||||
(initialRandSchedState Nothing g)
|
(initialRandSchedState Nothing g)
|
||||||
conc
|
conc
|
||||||
((res, trace):) <$> go (schedGen s) (n-1)
|
checkDiscard discard res trace $ go (schedGen s) (n-1)
|
||||||
|
|
||||||
-- | SCT via weighted random scheduling.
|
-- | SCT via weighted random scheduling.
|
||||||
--
|
--
|
||||||
@ -472,7 +585,27 @@ sctWeightedRandom :: (MonadRef r n, RandomGen g)
|
|||||||
-> ConcT r n a
|
-> ConcT r n a
|
||||||
-- ^ The computation to run many times.
|
-- ^ The computation to run many times.
|
||||||
-> n [(Either Failure a, Trace)]
|
-> n [(Either Failure a, Trace)]
|
||||||
sctWeightedRandom memtype g0 lim0 use0 conc = go g0 (max 0 lim0) (max 1 use0) M.empty where
|
sctWeightedRandom = sctWeightedRandomDiscard (const Nothing)
|
||||||
|
|
||||||
|
-- | A variant of 'sctWeightedRandom' which can selectively discard
|
||||||
|
-- results.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
sctWeightedRandomDiscard :: (MonadRef r n, RandomGen g)
|
||||||
|
=> (Either Failure a -> Maybe Discard)
|
||||||
|
-- ^ Selectively discard results.
|
||||||
|
-> MemType
|
||||||
|
-- ^ The memory model to use for non-synchronised @CRef@ operations.
|
||||||
|
-> g
|
||||||
|
-- ^ The random number generator.
|
||||||
|
-> Int
|
||||||
|
-- ^ The number of executions to perform.
|
||||||
|
-> Int
|
||||||
|
-- ^ The number of executions to use the same set of weights for.
|
||||||
|
-> ConcT r n a
|
||||||
|
-- ^ The computation to run many times.
|
||||||
|
-> n [(Either Failure a, Trace)]
|
||||||
|
sctWeightedRandomDiscard discard memtype g0 lim0 use0 conc = go g0 (max 0 lim0) (max 1 use0) M.empty where
|
||||||
go _ 0 _ _ = pure []
|
go _ 0 _ _ = pure []
|
||||||
go g n 0 _ = go g n (max 1 use0) M.empty
|
go g n 0 _ = go g n (max 1 use0) M.empty
|
||||||
go g n use ws = do
|
go g n use ws = do
|
||||||
@ -480,7 +613,7 @@ sctWeightedRandom memtype g0 lim0 use0 conc = go g0 (max 0 lim0) (max 1 use0) M.
|
|||||||
memtype
|
memtype
|
||||||
(initialRandSchedState (Just ws) g)
|
(initialRandSchedState (Just ws) g)
|
||||||
conc
|
conc
|
||||||
((res, trace):) <$> go (schedGen s) (n-1) (use-1) (schedWeights s)
|
checkDiscard discard res trace $ go (schedGen s) (n-1) (use-1) (schedWeights s)
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Utilities
|
-- Utilities
|
||||||
@ -542,3 +675,10 @@ trueBound _ _ = True
|
|||||||
-- satisfied.
|
-- satisfied.
|
||||||
(&+&) :: BoundFunc -> BoundFunc -> BoundFunc
|
(&+&) :: BoundFunc -> BoundFunc -> BoundFunc
|
||||||
(&+&) b1 b2 ts dl = b1 ts dl && b2 ts dl
|
(&+&) b1 b2 ts dl = b1 ts dl && b2 ts dl
|
||||||
|
|
||||||
|
-- | Apply the discard function.
|
||||||
|
checkDiscard :: Functor f => (a -> Maybe Discard) -> a -> [b] -> f [(a, [b])] -> f [(a, [b])]
|
||||||
|
checkDiscard discard res trace rest = case discard res of
|
||||||
|
Just DiscardResultAndTrace -> rest
|
||||||
|
Just DiscardTrace -> ((res, []):) <$> rest
|
||||||
|
Nothing -> ((res, trace):) <$> rest
|
||||||
|
@ -7,6 +7,23 @@ This project is versioned according to the [Package Versioning Policy](https://p
|
|||||||
*de facto* standard Haskell versioning scheme.
|
*de facto* standard Haskell versioning scheme.
|
||||||
|
|
||||||
|
|
||||||
|
unreleased
|
||||||
|
----------
|
||||||
|
|
||||||
|
### Test.HUnit.DejaFu
|
||||||
|
|
||||||
|
- Two new functions: `testDejafuDiscard` and `testDejafuDiscardIO`, allowing you to selectively
|
||||||
|
discard results or traces.
|
||||||
|
- The `Discard` type and `defaultDiscarder` function from dejafu is now re-exported.
|
||||||
|
|
||||||
|
### Miscellaneous
|
||||||
|
|
||||||
|
- Only dejafu UNRELEASED is supported.
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
0.6.0.0 [2017-06-07] (git tag: [hunit-dejafu-0.6.0.0][])
|
0.6.0.0 [2017-06-07] (git tag: [hunit-dejafu-0.6.0.0][])
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ module Test.HUnit.DejaFu
|
|||||||
, testDejafuWay
|
, testDejafuWay
|
||||||
, testDejafusWay
|
, testDejafusWay
|
||||||
|
|
||||||
|
, testDejafuDiscard
|
||||||
|
|
||||||
-- ** @IO@
|
-- ** @IO@
|
||||||
, testAutoIO
|
, testAutoIO
|
||||||
, testDejafuIO
|
, testDejafuIO
|
||||||
@ -54,6 +56,8 @@ module Test.HUnit.DejaFu
|
|||||||
, testDejafuWayIO
|
, testDejafuWayIO
|
||||||
, testDejafusWayIO
|
, testDejafusWayIO
|
||||||
|
|
||||||
|
, testDejafuDiscardIO
|
||||||
|
|
||||||
-- ** Re-exports
|
-- ** Re-exports
|
||||||
, Way
|
, Way
|
||||||
, defaultWay
|
, defaultWay
|
||||||
@ -65,6 +69,8 @@ module Test.HUnit.DejaFu
|
|||||||
, defaultBounds
|
, defaultBounds
|
||||||
, MemType(..)
|
, MemType(..)
|
||||||
, defaultMemType
|
, defaultMemType
|
||||||
|
, Discard(..)
|
||||||
|
, defaultDiscarder
|
||||||
|
|
||||||
-- * Refinement property testing
|
-- * Refinement property testing
|
||||||
, testProperty
|
, testProperty
|
||||||
@ -96,11 +102,11 @@ import Test.HUnit.Lang (HUnitFailure(..))
|
|||||||
-- instance :(
|
-- instance :(
|
||||||
import Unsafe.Coerce (unsafeCoerce)
|
import Unsafe.Coerce (unsafeCoerce)
|
||||||
|
|
||||||
runSCTst :: Way -> MemType -> (forall t. Conc.ConcST t a) -> [(Either Failure a, Conc.Trace)]
|
runSCTst :: (Either Failure a -> Maybe Discard) -> Way -> MemType -> (forall t. Conc.ConcST t a) -> [(Either Failure a, Conc.Trace)]
|
||||||
runSCTst way memtype conc = runST (SCT.runSCT way memtype conc)
|
runSCTst discard way memtype conc = runST (SCT.runSCTDiscard discard way memtype conc)
|
||||||
|
|
||||||
runSCTio :: Way -> MemType -> Conc.ConcIO a -> IO [(Either Failure a, Conc.Trace)]
|
runSCTio :: (Either Failure a -> Maybe Discard) -> Way -> MemType -> Conc.ConcIO a -> IO [(Either Failure a, Conc.Trace)]
|
||||||
runSCTio = SCT.runSCT
|
runSCTio = SCT.runSCTDiscard
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- HUnit-style unit testing
|
-- HUnit-style unit testing
|
||||||
@ -124,12 +130,12 @@ instance Assertable (Conc.ConcST t ()) where
|
|||||||
conc' = try conc
|
conc' = try conc
|
||||||
|
|
||||||
runSCTst' :: Conc.ConcST t (Either HUnitFailure ()) -> [(Either Failure (Either HUnitFailure ()), Conc.Trace)]
|
runSCTst' :: Conc.ConcST t (Either HUnitFailure ()) -> [(Either Failure (Either HUnitFailure ()), Conc.Trace)]
|
||||||
runSCTst' = unsafeCoerce $ runSCTst defaultWay defaultMemType
|
runSCTst' = unsafeCoerce $ runSCTst (const Nothing) defaultWay defaultMemType
|
||||||
|
|
||||||
-- | @since 0.3.0.0
|
-- | @since 0.3.0.0
|
||||||
instance Assertable (Conc.ConcIO ()) where
|
instance Assertable (Conc.ConcIO ()) where
|
||||||
assert conc = do
|
assert conc = do
|
||||||
traces <- runSCTio defaultWay defaultMemType (try conc)
|
traces <- runSCTio (const Nothing) defaultWay defaultMemType (try conc)
|
||||||
assertString . showErr $ assertableP traces
|
assertString . showErr $ assertableP traces
|
||||||
|
|
||||||
assertableP :: Predicate (Either HUnitFailure ())
|
assertableP :: Predicate (Either HUnitFailure ())
|
||||||
@ -221,8 +227,27 @@ testDejafuWay :: Show a
|
|||||||
-> Predicate a
|
-> Predicate a
|
||||||
-- ^ The predicate to check
|
-- ^ The predicate to check
|
||||||
-> Test
|
-> Test
|
||||||
testDejafuWay way memtype conc name p =
|
testDejafuWay = testDejafuDiscard (const Nothing)
|
||||||
testDejafusWay way memtype conc [(name, p)]
|
|
||||||
|
-- | Variant of 'testDejafuWay' which can selectively discard results.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
testDejafuDiscard :: Show a
|
||||||
|
=> (Either Failure a -> Maybe Discard)
|
||||||
|
-- ^ Selectively discard results.
|
||||||
|
-> Way
|
||||||
|
-- ^ How to execute the concurrent program.
|
||||||
|
-> MemType
|
||||||
|
-- ^ The memory model to use for non-synchronised @CRef@ operations.
|
||||||
|
-> (forall t. Conc.ConcST t a)
|
||||||
|
-- ^ The computation to test
|
||||||
|
-> String
|
||||||
|
-- ^ The name of the test.
|
||||||
|
-> Predicate a
|
||||||
|
-- ^ The predicate to check
|
||||||
|
-> Test
|
||||||
|
testDejafuDiscard discard way memtype conc name test =
|
||||||
|
testst discard way memtype conc [(name, test)]
|
||||||
|
|
||||||
-- | Variant of 'testDejafu' which takes a collection of predicates to
|
-- | Variant of 'testDejafu' which takes a collection of predicates to
|
||||||
-- test. This will share work between the predicates, rather than
|
-- test. This will share work between the predicates, rather than
|
||||||
@ -251,7 +276,7 @@ testDejafusWay :: Show a
|
|||||||
-> [(String, Predicate a)]
|
-> [(String, Predicate a)]
|
||||||
-- ^ The list of predicates (with names) to check
|
-- ^ The list of predicates (with names) to check
|
||||||
-> Test
|
-> Test
|
||||||
testDejafusWay = testst
|
testDejafusWay = testst (const Nothing)
|
||||||
|
|
||||||
-- | Variant of 'testDejafu' for computations which do 'IO'.
|
-- | Variant of 'testDejafu' for computations which do 'IO'.
|
||||||
--
|
--
|
||||||
@ -264,8 +289,14 @@ testDejafuIO = testDejafuWayIO defaultWay defaultMemType
|
|||||||
-- @since 0.5.0.0
|
-- @since 0.5.0.0
|
||||||
testDejafuWayIO :: Show a
|
testDejafuWayIO :: Show a
|
||||||
=> Way -> MemType -> Conc.ConcIO a -> String -> Predicate a -> Test
|
=> Way -> MemType -> Conc.ConcIO a -> String -> Predicate a -> Test
|
||||||
testDejafuWayIO way memtype concio name p =
|
testDejafuWayIO = testDejafuDiscardIO (const Nothing)
|
||||||
testDejafusWayIO way memtype concio [(name, p)]
|
|
||||||
|
-- | Variant of 'testDejafuDiscard' for computations which do 'IO'.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
testDejafuDiscardIO :: Show a => (Either Failure a -> Maybe Discard) -> Way -> MemType -> Conc.ConcIO a -> String -> Predicate a -> Test
|
||||||
|
testDejafuDiscardIO discard way memtype concio name test =
|
||||||
|
testio discard way memtype concio [(name, test)]
|
||||||
|
|
||||||
-- | Variant of 'testDejafus' for computations which do 'IO'.
|
-- | Variant of 'testDejafus' for computations which do 'IO'.
|
||||||
--
|
--
|
||||||
@ -278,7 +309,7 @@ testDejafusIO = testDejafusWayIO defaultWay defaultMemType
|
|||||||
-- @since 0.5.0.0
|
-- @since 0.5.0.0
|
||||||
testDejafusWayIO :: Show a
|
testDejafusWayIO :: Show a
|
||||||
=> Way -> MemType -> Conc.ConcIO a -> [(String, Predicate a)] -> Test
|
=> Way -> MemType -> Conc.ConcIO a -> [(String, Predicate a)] -> Test
|
||||||
testDejafusWayIO = testio
|
testDejafusWayIO = testio (const Nothing)
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -302,8 +333,13 @@ testProperty = testprop
|
|||||||
|
|
||||||
-- | Produce a HUnit 'Test' from a Deja Fu test.
|
-- | Produce a HUnit 'Test' from a Deja Fu test.
|
||||||
testst :: Show a
|
testst :: Show a
|
||||||
=> Way -> MemType -> (forall t. Conc.ConcST t a) -> [(String, Predicate a)] -> Test
|
=> (Either Failure a -> Maybe Discard)
|
||||||
testst way memtype conc tests = case map toTest tests of
|
-> Way
|
||||||
|
-> MemType
|
||||||
|
-> (forall t. Conc.ConcST t a)
|
||||||
|
-> [(String, Predicate a)]
|
||||||
|
-> Test
|
||||||
|
testst discard way memtype conc tests = case map toTest tests of
|
||||||
[t] -> t
|
[t] -> t
|
||||||
ts -> TestList ts
|
ts -> TestList ts
|
||||||
|
|
||||||
@ -311,12 +347,17 @@ testst way memtype conc tests = case map toTest tests of
|
|||||||
toTest (name, p) = TestLabel name . TestCase $
|
toTest (name, p) = TestLabel name . TestCase $
|
||||||
assertString . showErr $ p traces
|
assertString . showErr $ p traces
|
||||||
|
|
||||||
traces = runSCTst way memtype conc
|
traces = runSCTst discard way memtype conc
|
||||||
|
|
||||||
-- | Produce a HUnit 'Test' from an IO-using Deja Fu test.
|
-- | Produce a HUnit 'Test' from an IO-using Deja Fu test.
|
||||||
testio :: Show a
|
testio :: Show a
|
||||||
=> Way -> MemType -> Conc.ConcIO a -> [(String, Predicate a)] -> Test
|
=> (Either Failure a -> Maybe Discard)
|
||||||
testio way memtype concio tests = case map toTest tests of
|
-> Way
|
||||||
|
-> MemType
|
||||||
|
-> Conc.ConcIO a
|
||||||
|
-> [(String, Predicate a)]
|
||||||
|
-> Test
|
||||||
|
testio discard way memtype concio tests = case map toTest tests of
|
||||||
[t] -> t
|
[t] -> t
|
||||||
ts -> TestList ts
|
ts -> TestList ts
|
||||||
|
|
||||||
@ -326,7 +367,7 @@ testio way memtype concio tests = case map toTest tests of
|
|||||||
-- really unsafe) here, as 'test' doesn't allow side-effects
|
-- really unsafe) here, as 'test' doesn't allow side-effects
|
||||||
-- (eg, constructing an 'MVar' to share the traces after one
|
-- (eg, constructing an 'MVar' to share the traces after one
|
||||||
-- test computed them).
|
-- test computed them).
|
||||||
traces <- runSCTio way memtype concio
|
traces <- runSCTio discard way memtype concio
|
||||||
assertString . showErr $ p traces
|
assertString . showErr $ p traces
|
||||||
|
|
||||||
-- | Produce a HUnit 'Test' from a Deja Fu refinement property test.
|
-- | Produce a HUnit 'Test' from a Deja Fu refinement property test.
|
||||||
|
@ -7,6 +7,23 @@ This project is versioned according to the [Package Versioning Policy](https://p
|
|||||||
*de facto* standard Haskell versioning scheme.
|
*de facto* standard Haskell versioning scheme.
|
||||||
|
|
||||||
|
|
||||||
|
unreleased
|
||||||
|
----------
|
||||||
|
|
||||||
|
### Test.Tasty.DejaFu
|
||||||
|
|
||||||
|
- Two new functions: `testDejafuDiscard` and `testDejafuDiscardIO`, allowing you to selectively
|
||||||
|
discard results or traces.
|
||||||
|
- The `Discard` type and `defaultDiscarder` function from dejafu is now re-exported.
|
||||||
|
|
||||||
|
### Miscellaneous
|
||||||
|
|
||||||
|
- Only dejafu UNRELEASED is supported.
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
0.6.0.0 [2017-04-08] (git tag: [tasty-dejafu-0.6.0.0][])
|
0.6.0.0 [2017-04-08] (git tag: [tasty-dejafu-0.6.0.0][])
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
@ -42,6 +42,8 @@ module Test.Tasty.DejaFu
|
|||||||
, testDejafuWay
|
, testDejafuWay
|
||||||
, testDejafusWay
|
, testDejafusWay
|
||||||
|
|
||||||
|
, testDejafuDiscard
|
||||||
|
|
||||||
-- ** @IO@
|
-- ** @IO@
|
||||||
, testAutoIO
|
, testAutoIO
|
||||||
, testDejafuIO
|
, testDejafuIO
|
||||||
@ -51,6 +53,8 @@ module Test.Tasty.DejaFu
|
|||||||
, testDejafuWayIO
|
, testDejafuWayIO
|
||||||
, testDejafusWayIO
|
, testDejafusWayIO
|
||||||
|
|
||||||
|
, testDejafuDiscardIO
|
||||||
|
|
||||||
-- ** Re-exports
|
-- ** Re-exports
|
||||||
, Way
|
, Way
|
||||||
, defaultWay
|
, defaultWay
|
||||||
@ -62,6 +66,8 @@ module Test.Tasty.DejaFu
|
|||||||
, defaultBounds
|
, defaultBounds
|
||||||
, MemType(..)
|
, MemType(..)
|
||||||
, defaultMemType
|
, defaultMemType
|
||||||
|
, Discard(..)
|
||||||
|
, defaultDiscarder
|
||||||
|
|
||||||
-- * Refinement property testing
|
-- * Refinement property testing
|
||||||
, testProperty
|
, testProperty
|
||||||
@ -99,11 +105,11 @@ import Test.Tasty.Providers (IsTest(..), singleTest, testFailed,
|
|||||||
-- instance :(
|
-- instance :(
|
||||||
import Unsafe.Coerce (unsafeCoerce)
|
import Unsafe.Coerce (unsafeCoerce)
|
||||||
|
|
||||||
runSCTst :: Way -> MemType -> (forall t. Conc.ConcST t a) -> [(Either Failure a, Conc.Trace)]
|
runSCTst :: (Either Failure a -> Maybe Discard) -> Way -> MemType -> (forall t. Conc.ConcST t a) -> [(Either Failure a, Conc.Trace)]
|
||||||
runSCTst way memtype conc = runST (SCT.runSCT way memtype conc)
|
runSCTst discard way memtype conc = runST (SCT.runSCTDiscard discard way memtype conc)
|
||||||
|
|
||||||
runSCTio :: Way -> MemType -> Conc.ConcIO a -> IO [(Either Failure a, Conc.Trace)]
|
runSCTio :: (Either Failure a -> Maybe Discard) -> Way -> MemType -> Conc.ConcIO a -> IO [(Either Failure a, Conc.Trace)]
|
||||||
runSCTio = SCT.runSCT
|
runSCTio = SCT.runSCTDiscard
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Tasty-style unit testing
|
-- Tasty-style unit testing
|
||||||
@ -116,7 +122,7 @@ instance Typeable t => IsTest (Conc.ConcST t (Maybe String)) where
|
|||||||
let memtype = lookupOption options :: MemType
|
let memtype = lookupOption options :: MemType
|
||||||
let way = lookupOption options :: Way
|
let way = lookupOption options :: Way
|
||||||
let runSCTst' :: Conc.ConcST t (Maybe String) -> [(Either Failure (Maybe String), Conc.Trace)]
|
let runSCTst' :: Conc.ConcST t (Maybe String) -> [(Either Failure (Maybe String), Conc.Trace)]
|
||||||
runSCTst' = unsafeCoerce $ runSCTst way memtype
|
runSCTst' = unsafeCoerce $ runSCTst (const Nothing) way memtype
|
||||||
let traces = runSCTst' conc
|
let traces = runSCTst' conc
|
||||||
run options (ConcTest traces assertableP) callback
|
run options (ConcTest traces assertableP) callback
|
||||||
|
|
||||||
@ -127,7 +133,7 @@ instance IsTest (Conc.ConcIO (Maybe String)) where
|
|||||||
run options conc callback = do
|
run options conc callback = do
|
||||||
let memtype = lookupOption options
|
let memtype = lookupOption options
|
||||||
let way = lookupOption options
|
let way = lookupOption options
|
||||||
let traces = runSCTio way memtype conc
|
let traces = runSCTio (const Nothing) way memtype conc
|
||||||
run options (ConcIOTest traces assertableP) callback
|
run options (ConcIOTest traces assertableP) callback
|
||||||
|
|
||||||
concOptions :: [OptionDescription]
|
concOptions :: [OptionDescription]
|
||||||
@ -245,8 +251,27 @@ testDejafuWay :: Show a
|
|||||||
-> Predicate a
|
-> Predicate a
|
||||||
-- ^ The predicate to check
|
-- ^ The predicate to check
|
||||||
-> TestTree
|
-> TestTree
|
||||||
testDejafuWay way memtype conc name p =
|
testDejafuWay = testDejafuDiscard (const Nothing)
|
||||||
testDejafusWay way memtype conc [(name, p)]
|
|
||||||
|
-- | Variant of 'testDejafuWay' which can selectively discard results.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
testDejafuDiscard :: Show a
|
||||||
|
=> (Either Failure a -> Maybe Discard)
|
||||||
|
-- ^ Selectively discard results.
|
||||||
|
-> Way
|
||||||
|
-- ^ How to execute the concurrent program.
|
||||||
|
-> MemType
|
||||||
|
-- ^ The memory model to use for non-synchronised @CRef@ operations.
|
||||||
|
-> (forall t. Conc.ConcST t a)
|
||||||
|
-- ^ The computation to test
|
||||||
|
-> String
|
||||||
|
-- ^ The name of the test.
|
||||||
|
-> Predicate a
|
||||||
|
-- ^ The predicate to check
|
||||||
|
-> TestTree
|
||||||
|
testDejafuDiscard discard way memtype conc name test =
|
||||||
|
testst discard way memtype conc [(name, test)]
|
||||||
|
|
||||||
-- | Variant of 'testDejafu' which takes a collection of predicates to
|
-- | Variant of 'testDejafu' which takes a collection of predicates to
|
||||||
-- test. This will share work between the predicates, rather than
|
-- test. This will share work between the predicates, rather than
|
||||||
@ -275,7 +300,7 @@ testDejafusWay :: Show a
|
|||||||
-> [(TestName, Predicate a)]
|
-> [(TestName, Predicate a)]
|
||||||
-- ^ The list of predicates (with names) to check
|
-- ^ The list of predicates (with names) to check
|
||||||
-> TestTree
|
-> TestTree
|
||||||
testDejafusWay = testst
|
testDejafusWay = testst (const Nothing)
|
||||||
|
|
||||||
-- | Variant of 'testDejafu' for computations which do 'IO'.
|
-- | Variant of 'testDejafu' for computations which do 'IO'.
|
||||||
--
|
--
|
||||||
@ -288,8 +313,14 @@ testDejafuIO = testDejafuWayIO defaultWay defaultMemType
|
|||||||
-- @since 0.5.0.0
|
-- @since 0.5.0.0
|
||||||
testDejafuWayIO :: Show a
|
testDejafuWayIO :: Show a
|
||||||
=> Way -> MemType -> Conc.ConcIO a -> TestName -> Predicate a -> TestTree
|
=> Way -> MemType -> Conc.ConcIO a -> TestName -> Predicate a -> TestTree
|
||||||
testDejafuWayIO way memtype concio name p =
|
testDejafuWayIO = testDejafuDiscardIO (const Nothing)
|
||||||
testDejafusWayIO way memtype concio [(name, p)]
|
|
||||||
|
-- | Variant of 'testDejafuDiscard' for computations which do 'IO'.
|
||||||
|
--
|
||||||
|
-- @since unreleased
|
||||||
|
testDejafuDiscardIO :: Show a => (Either Failure a -> Maybe Discard) -> Way -> MemType -> Conc.ConcIO a -> String -> Predicate a -> TestTree
|
||||||
|
testDejafuDiscardIO discard way memtype concio name test =
|
||||||
|
testio discard way memtype concio [(name, test)]
|
||||||
|
|
||||||
-- | Variant of 'testDejafus' for computations which do 'IO'.
|
-- | Variant of 'testDejafus' for computations which do 'IO'.
|
||||||
--
|
--
|
||||||
@ -302,7 +333,7 @@ testDejafusIO = testDejafusWayIO defaultWay defaultMemType
|
|||||||
-- @since 0.5.0.0
|
-- @since 0.5.0.0
|
||||||
testDejafusWayIO :: Show a
|
testDejafusWayIO :: Show a
|
||||||
=> Way -> MemType -> Conc.ConcIO a -> [(TestName, Predicate a)] -> TestTree
|
=> Way -> MemType -> Conc.ConcIO a -> [(TestName, Predicate a)] -> TestTree
|
||||||
testDejafusWayIO = testio
|
testDejafusWayIO = testio (const Nothing)
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -368,20 +399,30 @@ instance IsTest PropTest where
|
|||||||
|
|
||||||
-- | Produce a Tasty 'TestTree' from a Deja Fu test.
|
-- | Produce a Tasty 'TestTree' from a Deja Fu test.
|
||||||
testst :: Show a
|
testst :: Show a
|
||||||
=> Way -> MemType -> (forall t. Conc.ConcST t a) -> [(TestName, Predicate a)] -> TestTree
|
=> (Either Failure a -> Maybe Discard)
|
||||||
testst way memtype conc tests = case map toTest tests of
|
-> Way
|
||||||
|
-> MemType
|
||||||
|
-> (forall t. Conc.ConcST t a)
|
||||||
|
-> [(TestName, Predicate a)]
|
||||||
|
-> TestTree
|
||||||
|
testst discard way memtype conc tests = case map toTest tests of
|
||||||
[t] -> t
|
[t] -> t
|
||||||
ts -> testGroup "Deja Fu Tests" ts
|
ts -> testGroup "Deja Fu Tests" ts
|
||||||
|
|
||||||
where
|
where
|
||||||
toTest (name, p) = singleTest name $ ConcTest traces p
|
toTest (name, p) = singleTest name $ ConcTest traces p
|
||||||
|
|
||||||
traces = runSCTst way memtype conc
|
traces = runSCTst discard way memtype conc
|
||||||
|
|
||||||
-- | Produce a Tasty 'Test' from an IO-using Deja Fu test.
|
-- | Produce a Tasty 'Test' from an IO-using Deja Fu test.
|
||||||
testio :: Show a
|
testio :: Show a
|
||||||
=> Way -> MemType -> Conc.ConcIO a -> [(TestName, Predicate a)] -> TestTree
|
=> (Either Failure a -> Maybe Discard)
|
||||||
testio way memtype concio tests = case map toTest tests of
|
-> Way
|
||||||
|
-> MemType
|
||||||
|
-> Conc.ConcIO a
|
||||||
|
-> [(TestName, Predicate a)]
|
||||||
|
-> TestTree
|
||||||
|
testio discard way memtype concio tests = case map toTest tests of
|
||||||
[t] -> t
|
[t] -> t
|
||||||
ts -> testGroup "Deja Fu Tests" ts
|
ts -> testGroup "Deja Fu Tests" ts
|
||||||
|
|
||||||
@ -390,7 +431,7 @@ testio way memtype concio tests = case map toTest tests of
|
|||||||
|
|
||||||
-- As with HUnit, constructing a test is side-effect free, so
|
-- As with HUnit, constructing a test is side-effect free, so
|
||||||
-- sharing of traces can't happen here.
|
-- sharing of traces can't happen here.
|
||||||
traces = runSCTio way memtype concio
|
traces = runSCTio discard way memtype concio
|
||||||
|
|
||||||
-- | Produce a Tasty 'TestTree' from a Deja Fu refinement property test.
|
-- | Produce a Tasty 'TestTree' from a Deja Fu refinement property test.
|
||||||
testprop :: (R.Testable p, R.Listable (R.X p), Eq (R.X p), Show (R.X p), Show (R.O p))
|
testprop :: (R.Testable p, R.Listable (R.X p), Eq (R.X p), Show (R.X p), Show (R.O p))
|
||||||
|
Loading…
Reference in New Issue
Block a user