Skip to content

Implement tests for callLocal #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 14, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 88 additions & 2 deletions src/Control/Distributed/Process/Tests/CH.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import Network.Transport.Test (TestTransport(..))
import Data.Binary (Binary(..))
import Data.Typeable (Typeable)
import Data.Foldable (forM_)
import Control.Concurrent (forkIO, threadDelay, myThreadId, throwTo, ThreadId)
import Data.IORef
( readIORef
, writeIORef
, newIORef
)
import Control.Concurrent (forkIO, threadDelay, myThreadId, throwTo, ThreadId, yield)
import Control.Concurrent.MVar
( MVar
, newEmptyMVar
Expand All @@ -18,7 +23,7 @@ import Control.Concurrent.MVar
, readMVar
)
import Control.Monad (replicateM_, replicateM, forever, void, unless, join)
import Control.Exception (SomeException, throwIO)
import Control.Exception (SomeException, throwIO, ErrorCall(..))
import qualified Control.Exception as Ex (catch)
import Control.Applicative ((<$>), (<*>), pure, (<|>))
import qualified Network.Transport as NT (closeEndPoint, EndPointAddress)
Expand Down Expand Up @@ -1371,6 +1376,86 @@ testUnsafeSendChan TestTransport{..} = do

takeMVar clientDone

testCallLocal :: TestTransport -> Assertion
testCallLocal TestTransport{..} = do
node <- newLocalNode testTransport initRemoteTable

-- Testing that (/=) <$> getSelfPid <*> callLocal getSelfPid.
result <- newEmptyMVar
runProcess node $ do
r <- (/=) <$> getSelfPid <*> callLocal getSelfPid
liftIO $ putMVar result r
True <- takeMVar result
return ()

-- Testing that when callLocal is interrupted, the worker is interrupted.
ibox <- newIORef False
runProcess node $ do
keeper <- getSelfPid
spawnLocal $ do
caller <- getSelfPid
send keeper caller
onException
(callLocal $ do
onException (do send keeper caller
expect)
(do liftIO $ writeIORef ibox True))
(send keeper ())
caller <- expect
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This expect call is unnecessary if the caller is sent by the worker instead of ().

exit caller "test"
() <- expect
return ()
True <- readIORef ibox
return ()

-- Testing that when the worker raises an exception, the exception is propagated to the parent.
ibox2 <- newIORef False
runProcess node $ do
r <- try (callLocal $ error "e" >> return ())
liftIO $ writeIORef ibox2 (r == Left (ErrorCall "e"))
True <- readIORef ibox
return ()

-- Test that caller waits for the worker in correct situation
ibox3 <- newIORef False
result3 <- newEmptyMVar
runProcess node $ do
keeper <- getSelfPid
spawnLocal $ do
callLocal $
(do us <- getSelfPid
send keeper us
() <- expect
liftIO yield)
`finally` (liftIO $ writeIORef ibox3 True)
liftIO $ putMVar result3 =<< readIORef ibox3
worker <- expect
send worker ()
True <- takeMVar result3
return ()

-- Test that caller waits for the worker in case when caller gets an exception
ibox4 <- newIORef False
result4 <- newEmptyMVar
runProcess node $ do
keeper <- getSelfPid
spawnLocal $ do
caller <- getSelfPid
callLocal
((do send keeper caller
expect)
`finally` (liftIO $ writeIORef ibox4 True))
`finally` (liftIO $ putMVar result4 =<< readIORef ibox4)
caller <- expect
exit caller "hi!"
True <- takeMVar result4
return ()
-- XXX: Testing that when mask_ $ callLocal p runs p in masked state.





tests :: TestTransport -> IO [Test]
tests testtrans = return [
testGroup "Basic features" [
Expand Down Expand Up @@ -1403,6 +1488,7 @@ tests testtrans = return [
, testCase "MaskRestoreScope" (testMaskRestoreScope testtrans)
, testCase "ExitLocal" (testExitLocal testtrans)
, testCase "ExitRemote" (testExitRemote testtrans)
, testCase "TextCallLocal" (testCallLocal testtrans)
-- Unsafe Primitives
, testCase "TestUnsafeSend" (testUnsafeSend testtrans)
, testCase "TestUnsafeNSend" (testUnsafeNSend testtrans)
Expand Down