mirror of
https://github.com/barrucadu/dejafu.git
synced 2024-11-22 21:50:51 +03:00
Add tests for named threads, vars, and refs
This commit is contained in:
parent
b9d21788ce
commit
bc198a5e13
@ -29,6 +29,7 @@ library
|
|||||||
, Integration.Discard
|
, Integration.Discard
|
||||||
, Integration.Regressions
|
, Integration.Regressions
|
||||||
, Integration.SCT
|
, Integration.SCT
|
||||||
|
, Integration.Names
|
||||||
|
|
||||||
, Examples
|
, Examples
|
||||||
, Examples.AutoUpdate
|
, Examples.AutoUpdate
|
||||||
|
@ -6,6 +6,7 @@ import qualified Integration.Async as A
|
|||||||
import qualified Integration.Discard as D
|
import qualified Integration.Discard as D
|
||||||
import qualified Integration.Litmus as L
|
import qualified Integration.Litmus as L
|
||||||
import qualified Integration.MultiThreaded as M
|
import qualified Integration.MultiThreaded as M
|
||||||
|
import qualified Integration.Names as N
|
||||||
import qualified Integration.Refinement as R
|
import qualified Integration.Refinement as R
|
||||||
import qualified Integration.Regressions as G
|
import qualified Integration.Regressions as G
|
||||||
import qualified Integration.SCT as SC
|
import qualified Integration.SCT as SC
|
||||||
@ -20,6 +21,7 @@ tests =
|
|||||||
, testGroup "Discard" D.tests
|
, testGroup "Discard" D.tests
|
||||||
, testGroup "Litmus" L.tests
|
, testGroup "Litmus" L.tests
|
||||||
, testGroup "MultiThreaded" M.tests
|
, testGroup "MultiThreaded" M.tests
|
||||||
|
, testGroup "Names" N.tests
|
||||||
, testGroup "Refinement" R.tests
|
, testGroup "Refinement" R.tests
|
||||||
, testGroup "Regressions" G.tests
|
, testGroup "Regressions" G.tests
|
||||||
, testGroup "SingleThreaded" S.tests
|
, testGroup "SingleThreaded" S.tests
|
||||||
|
116
dejafu-tests/lib/Integration/Names.hs
Normal file
116
dejafu-tests/lib/Integration/Names.hs
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
module Integration.Names where
|
||||||
|
|
||||||
|
import Control.Concurrent.Classy hiding (check)
|
||||||
|
import Data.Maybe (mapMaybe)
|
||||||
|
import Test.DejaFu.Conc (ConcIO)
|
||||||
|
import Test.DejaFu.Internal (crefOf, mvarOf, simplifyAction,
|
||||||
|
tidsOf, tvarsOf)
|
||||||
|
import Test.DejaFu.SCT (runSCT)
|
||||||
|
import Test.DejaFu.Types
|
||||||
|
import Test.Tasty.HUnit
|
||||||
|
|
||||||
|
import Common
|
||||||
|
|
||||||
|
tests :: [TestTree]
|
||||||
|
tests =
|
||||||
|
toTestList
|
||||||
|
[ testCase "MVar names" testMVarNames
|
||||||
|
, testCase "CRef names" testCRefNames
|
||||||
|
, testCase "TVar names" testTVarNames
|
||||||
|
, testCase "Thread names" testThreadNames
|
||||||
|
]
|
||||||
|
|
||||||
|
check ::
|
||||||
|
String
|
||||||
|
-> ([ThreadAction] -> Bool)
|
||||||
|
-> ConcIO a
|
||||||
|
-> Assertion
|
||||||
|
check msg validActions testAction = do
|
||||||
|
outcomes <- runSCT defaultWay defaultMemType testAction
|
||||||
|
let extractActions = map $ \(_, _, action) -> action
|
||||||
|
actions = [extractActions trace | (_, trace) <- outcomes]
|
||||||
|
assertBool msg $ any validActions actions
|
||||||
|
|
||||||
|
testMVarNames :: Assertion
|
||||||
|
testMVarNames =
|
||||||
|
check "All traces should use only required MVar names" checkMVars $ do
|
||||||
|
mvar1 <- newEmptyMVarN mvarName1
|
||||||
|
mvar2 <- newEmptyMVarN mvarName2
|
||||||
|
_ <- takeMVar mvar1
|
||||||
|
_ <- fork $ putMVar mvar1 (1 :: Int)
|
||||||
|
_ <- fork $ putMVar mvar2 (2 :: Int)
|
||||||
|
_ <- fork $ putMVar mvar1 3
|
||||||
|
(,) <$> readMVar mvar1 <*> readMVar mvar2
|
||||||
|
where
|
||||||
|
mvarName1 = "first-mvar"
|
||||||
|
mvarName2 = "second-mvar"
|
||||||
|
mvarName (MVarId (Id (Just n) _)) = Just n
|
||||||
|
mvarName _ = Nothing
|
||||||
|
mvar (NewMVar mvid) = Just mvid
|
||||||
|
mvar a = mvarOf (simplifyAction a)
|
||||||
|
checkMVars =
|
||||||
|
let validMVid = maybe False (`elem` [mvarName1, mvarName2]) . mvarName
|
||||||
|
in all validMVid . mapMaybe mvar
|
||||||
|
|
||||||
|
testCRefNames :: Assertion
|
||||||
|
testCRefNames =
|
||||||
|
check "All traces should use only required CRef names" checkCRefs $ do
|
||||||
|
x <- newCRefN crefName1 (0::Int)
|
||||||
|
y <- newCRefN crefName2 (0::Int)
|
||||||
|
_ <- fork $ modifyCRefCAS x (const (1, ()))
|
||||||
|
_ <- fork $ writeCRef y 2
|
||||||
|
(,) <$> readCRef x <*> readCRef y
|
||||||
|
where
|
||||||
|
crefName1 = "cref-one"
|
||||||
|
crefName2 = "cref-two"
|
||||||
|
crefName (CRefId (Id (Just n) _)) = Just n
|
||||||
|
crefName _ = Nothing
|
||||||
|
cref (NewCRef ref) = Just ref
|
||||||
|
cref a = crefOf (simplifyAction a)
|
||||||
|
checkCRefs =
|
||||||
|
let validCRef = maybe False (`elem` [crefName1, crefName2]) . crefName
|
||||||
|
in all validCRef . mapMaybe cref
|
||||||
|
|
||||||
|
testTVarNames :: Assertion
|
||||||
|
testTVarNames =
|
||||||
|
check "All traces should use only required TVar names" checkTVars $ do
|
||||||
|
v1 <- atomically $ newTVarN tvarName1 (0::Int)
|
||||||
|
v2 <- atomically $ newTVarN tvarName2 (0::Int)
|
||||||
|
_ <-
|
||||||
|
fork . atomically $ do
|
||||||
|
writeTVar v1 1
|
||||||
|
modifyTVar v2 (+ 100)
|
||||||
|
_ <-
|
||||||
|
fork . atomically $ do
|
||||||
|
modifyTVar v1 (* 100)
|
||||||
|
writeTVar v2 42
|
||||||
|
pure ()
|
||||||
|
where
|
||||||
|
tvarName1 = "tvar-one"
|
||||||
|
tvarName2 = "tvar-two"
|
||||||
|
tvarName (TVarId (Id (Just n) _)) = Just n
|
||||||
|
tvarName _ = Nothing
|
||||||
|
checkTVars =
|
||||||
|
let validTVar =
|
||||||
|
maybe False (`elem` [tvarName1, tvarName2]) . tvarName
|
||||||
|
in all (all validTVar) . map tvarsOf
|
||||||
|
|
||||||
|
testThreadNames :: Assertion
|
||||||
|
testThreadNames =
|
||||||
|
check "All traces should use only required thread names" checkThreads $ do
|
||||||
|
x <- newEmptyMVar
|
||||||
|
tid <- forkN threadName2 $ putMVar x ()
|
||||||
|
_ <- forkN threadName1 $ readMVar x
|
||||||
|
_ <- forkN threadName3 $ pure ()
|
||||||
|
killThread tid
|
||||||
|
where
|
||||||
|
threadName1 = "thread-one"
|
||||||
|
threadName2 = "thread-two"
|
||||||
|
threadName3 = "thread-three"
|
||||||
|
threadName (ThreadId (Id (Just n) _)) = Just n
|
||||||
|
threadName _ = Nothing
|
||||||
|
checkThreads =
|
||||||
|
let validTid =
|
||||||
|
maybe False (`elem` [threadName1, threadName2, threadName3]) .
|
||||||
|
threadName
|
||||||
|
in all (all validTid) . map tidsOf
|
@ -105,6 +105,7 @@ tvarsWritten act = S.fromList $ case act of
|
|||||||
_ -> []
|
_ -> []
|
||||||
|
|
||||||
where
|
where
|
||||||
|
tvarsOf' (TNew tv) = [tv]
|
||||||
tvarsOf' (TWrite tv) = [tv]
|
tvarsOf' (TWrite tv) = [tv]
|
||||||
tvarsOf' (TOrElse ta tb) = concatMap tvarsOf' (ta ++ fromMaybe [] tb)
|
tvarsOf' (TOrElse ta tb) = concatMap tvarsOf' (ta ++ fromMaybe [] tb)
|
||||||
tvarsOf' (TCatch ta tb) = concatMap tvarsOf' (ta ++ fromMaybe [] tb)
|
tvarsOf' (TCatch ta tb) = concatMap tvarsOf' (ta ++ fromMaybe [] tb)
|
||||||
@ -263,6 +264,20 @@ mvarOf (SynchronisedRead c) = Just c
|
|||||||
mvarOf (SynchronisedWrite c) = Just c
|
mvarOf (SynchronisedWrite c) = Just c
|
||||||
mvarOf _ = Nothing
|
mvarOf _ = Nothing
|
||||||
|
|
||||||
|
-- | Get the @ThreadId@s involved in a @ThreadAction@.
|
||||||
|
tidsOf :: ThreadAction -> Set ThreadId
|
||||||
|
tidsOf (Fork tid) = S.singleton tid
|
||||||
|
tidsOf (ForkOS tid) = S.singleton tid
|
||||||
|
tidsOf (PutMVar _ tids) = S.fromList tids
|
||||||
|
tidsOf (TryPutMVar _ _ tids) = S.fromList tids
|
||||||
|
tidsOf (TakeMVar _ tids) = S.fromList tids
|
||||||
|
tidsOf (TryTakeMVar _ _ tids) = S.fromList tids
|
||||||
|
tidsOf (CommitCRef tid _) = S.singleton tid
|
||||||
|
tidsOf (STM _ tids) = S.fromList tids
|
||||||
|
tidsOf (ThrowTo tid) = S.singleton tid
|
||||||
|
tidsOf (BlockedThrowTo tid) = S.singleton tid
|
||||||
|
tidsOf _ = S.empty
|
||||||
|
|
||||||
-- | Throw away information from a 'ThreadAction' and give a
|
-- | Throw away information from a 'ThreadAction' and give a
|
||||||
-- simplified view of what is happening.
|
-- simplified view of what is happening.
|
||||||
--
|
--
|
||||||
|
Loading…
Reference in New Issue
Block a user