lvish-1.1.1.1: tests/PureMapTests.hs
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE DataKinds, TypeFamilies #-}
{-# LANGUAGE CPP #-}
-- | Tests for the Data.LVar.PureMap and Data.LVar.SLMap modules.
module PureMapTests(tests, runTests) where
import Data.LVar.PureSet as IS
import Data.LVar.PureMap as IM
#include "CommonMapTests.hs"
--------------------------------------------------------------------------------
tests :: Test
tests = testGroup "" [tests_here, tests_common ]
tests_here :: Test
tests_here = $(testGroupGenerator)
runTests :: IO ()
runTests = defaultMainSeqTests [tests]
--------------------------------------------------------------------------------
-- [2013.08.05] RRN: Observing nondeterministic blocked-indefinitely
-- exception here.
case_i7b :: Assertion
case_i7b = do
allowSomeExceptions ["Multiple puts"] $
assertEqual "racing insert and modify"
(M.fromList [(1,S.fromList [3.33]),
(2,S.fromList [0.11,4.44])]) =<<
i7b
return ()
-- | A quasi-deterministic example.
i7b :: IO (M.Map Int (S.Set Float))
-- A manual nested freeze instead of DeepFrz:
i7b = runParIO $ do
mp <- IM.newEmptyMap
s1 <- IS.newEmptySet
s2 <- IS.newEmptySet
IS.insert 0.11 s2
f1 <- IV.spawn_ $ do IM.insert 1 s1 mp
IM.insert 2 s2 mp
f2 <- IV.spawn_ $ do s <- IM.getKey 1 mp
IS.insert 3.33 s
-- RACE: this modify is racing with the insert of s2:
IM.modify mp 2 IS.newEmptySet (IS.insert 4.44)
IV.get f1; IV.get f2
mp2 <- IM.freezeMap mp
traverse IS.freezeSet mp2
-- | This example is valid because two modifies may race.
v7c :: IO (M.Map Int (S.Set Float))
-- Do we need a "deep freeze" that freezes nested structures?
v7c = runParIO $ do
mp <- IM.newEmptyMap
s1 <- IS.newEmptySet
f1 <- IV.spawn_ $ IM.insert 1 s1 mp
f2 <- IV.spawn_ $ do s <- IM.getKey 1 mp
IS.insert 3.33 s
IM.modify mp 2 IS.newEmptySet (IS.insert 4.44)
f3 <- IV.spawn_ $ IM.modify mp 3 IS.newEmptySet (IS.insert 5.55)
f4 <- IV.spawn_ $ IM.modify mp 3 IS.newEmptySet (IS.insert 6.6)
-- No easy way to wait on the total size of all contained sets...
--
-- Need a barrier here.. should have a monad-transformer that provides cilk "sync"
-- Global quiesce is convenient too..
IV.get f1; IV.get f2; IV.get f3; IV.get f4
mp2 <- IM.freezeMap mp
traverse IS.freezeSet mp2
case_v7c :: Assertion
case_v7c = assertEqual "imap test - racing modifies"
(M.fromList [(1,S.fromList [3.33]),
(2,S.fromList [4.44]),
(3,S.fromList [5.55,6.6])]) =<<
v7c
------------------------------------------------------------------------------------------
-- Show instances
------------------------------------------------------------------------------------------
case_show03 :: Assertion
case_show03 = assertEqual "show for PureMap" "{IMap: (\"key1\",33), (\"key2\",44)}" show03
show03 :: String
show03 = show$ runParThenFreeze $ do
mp <- IM.newEmptyMap
IM.insert "key1" (33::Int) mp
IM.insert "key2" (44::Int) mp
return mp