1+ {-# LANGUAGE NumericUnderscores #-}
12module Control.Distributed.Process.Tests.CH (tests ) where
23
34
@@ -42,8 +43,9 @@ import Control.Distributed.Process.Node
4243import Control.Distributed.Process.Tests.Internal.Utils (pause )
4344import Control.Distributed.Process.Serializable (Serializable )
4445import Data.Maybe (isNothing , isJust )
46+ import System.Timeout (timeout )
4547import Test.Tasty (TestTree , testGroup )
46- import Test.Tasty.HUnit (Assertion , assertBool , assertEqual , testCase )
48+ import Test.Tasty.HUnit (Assertion , assertBool , assertEqual , testCase , assertFailure )
4749
4850newtype Ping = Ping ProcessId
4951 deriving (Typeable , Binary , Show )
@@ -70,7 +72,12 @@ ping = do
7072 ping
7173
7274verifyClient :: String -> MVar Bool -> IO ()
73- verifyClient s b = takeMVar b >>= assertBool s
75+ verifyClient s b =
76+ -- The timeout below must be generous enough to support
77+ -- running tests in the Github Actions CI environment, which is quite slow.
78+ timeout 60_000_000
79+ (takeMVar b >>= assertBool s)
80+ >>= maybe (assertFailure $ " verifyClient timeout: " <> s) (\ _ -> pure () )
7481
7582expectPing :: MVar Bool -> Process ()
7683expectPing mv = expect >>= liftIO . putMVar mv . checkPing
@@ -175,14 +182,14 @@ monitorTestProcess theirAddr mOrL un reason monitorSetup done =
175182 unmonitor ref
176183 liftIO $ putMVar done ()
177184 (False , ref) -> do
178- receiveWait [
185+ receiveTimeout 1_000_000 [
179186 match (\ (ProcessMonitorNotification ref' pid reason') -> do
180187 liftIO $ do
181188 assertBool " Bad Monitor Signal"
182189 (Just ref' == ref && pid == theirAddr &&
183190 mOrL && reason == reason')
184191 putMVar done () )
185- ]
192+ ] >>= maybe (liftIO $ assertFailure " No ProcessMonitorNotification received within timeout window " ) pure
186193 )
187194 (\ (ProcessLinkException pid reason') -> do
188195 (liftIO $ assertBool " link exception unmatched" $
@@ -220,11 +227,11 @@ testPing TestTransport{..} = do
220227 p <- expectTimeout 3000000
221228 case p of
222229 Just (Ping _) -> return ()
223- Nothing -> die " Failed to receive Ping"
230+ Nothing -> let msg = " Failed to receive Ping" in liftIO (putMVar clientDone ( Left msg)) >> die msg
224231
225- putMVar clientDone ()
232+ putMVar clientDone (Right () )
226233
227- takeMVar clientDone
234+ takeMVar clientDone >>= either assertFailure pure
228235
229236-- | Monitor a process on an unreachable node
230237testMonitorUnreachable :: TestTransport -> Bool -> Bool -> Assertion
@@ -348,6 +355,7 @@ testMonitorDisconnect TestTransport{..} mOrL un = do
348355 putMVar processAddr addr
349356 readMVar monitorSetup
350357 NT. closeEndPoint (localEndPoint localNode)
358+ threadDelay 100_000
351359 putMVar processAddr2 addr2
352360
353361 forkIO $ do
@@ -430,7 +438,7 @@ testTimeout TestTransport{..} = do
430438 done <- newEmptyMVar
431439
432440 runProcess localNode $ do
433- res <- receiveTimeout 1000000 [match (\ Add {} -> return () )]
441+ res <- receiveTimeout 1_000_000 [match (\ Add {} -> return () )]
434442 liftIO $ putMVar done $ res == Nothing
435443
436444 verifyClient " Expected receiveTimeout to timeout..." done
@@ -447,7 +455,7 @@ testTimeout0 TestTransport{..} = do
447455 -- Variation on the venerable ping server which uses a zero timeout
448456 partner <- fix $ \ loop ->
449457 receiveTimeout 0 [match (\ (Pong partner) -> return partner)]
450- >>= maybe (liftIO (threadDelay 100000 ) >> loop) return
458+ >>= maybe (liftIO (threadDelay 100_000 ) >> loop) return
451459 self <- getSelfPid
452460 send partner (Ping self)
453461 putMVar serverAddr addr
@@ -459,7 +467,7 @@ testTimeout0 TestTransport{..} = do
459467 pid <- getSelfPid
460468 -- Send a bunch of messages. A large number of messages that the server
461469 -- is not interested in, and then a single message that it wants
462- replicateM_ 10000 $ send server " Irrelevant message"
470+ replicateM_ 10_000 $ send server " Irrelevant message"
463471 send server (Pong pid)
464472 expectPing clientDone
465473
@@ -582,7 +590,7 @@ testMergeChannels TestTransport{..} = do
582590 charChannel c = do
583591 (sport, rport) <- newChan
584592 replicateM_ 3 $ sendChan sport c
585- liftIO $ threadDelay 10000 -- Make sure messages have been sent
593+ liftIO $ threadDelay 10_000 -- Make sure messages have been sent
586594 return rport
587595
588596testTerminate :: TestTransport -> Assertion
@@ -621,15 +629,19 @@ testMonitorLiveNode TestTransport{..} = do
621629 forkProcess node2 $ do
622630 ref <- monitorNode (localNodeId node1)
623631 liftIO $ putMVar ready ()
632+ -- node1 gets closed
624633 liftIO $ takeMVar readyr
625634 send p ()
626- receiveWait [
635+ receiveTimeout 10_000_000 [
627636 match (\ (NodeMonitorNotification ref' nid _) ->
628637 (return $ ref == ref' && nid == localNodeId node1))
629- ] >>= liftIO . putMVar done
638+ ] >>= maybe
639+ (liftIO $ assertFailure " Did not receive NodeMonitorNotification message within timeout window" )
640+ (liftIO . putMVar done)
630641
631642 takeMVar ready
632643 closeLocalNode node1
644+ threadDelay 1_000_000
633645 putMVar readyr ()
634646
635647 verifyClient " Expected NodeMonitorNotification for LIVE node" done
@@ -638,22 +650,27 @@ testMonitorChannel :: TestTransport -> Assertion
638650testMonitorChannel TestTransport {.. } = do
639651 [node1, node2] <- replicateM 2 $ newLocalNode testTransport initRemoteTable
640652 gotNotification <- newEmptyMVar
653+ ready <- newEmptyMVar
641654
642655 pid <- forkProcess node1 $ do
656+ liftIO $ putMVar ready ()
643657 sport <- expect :: Process (SendPort () )
644658 ref <- monitorPort sport
645- receiveWait [
659+ receiveTimeout 10_000_000 [
646660 -- reason might be DiedUnknownId if the receive port is GCed before the
647661 -- monitor is established (TODO: not sure that this is reasonable)
648662 match (\ (PortMonitorNotification ref' port' reason) ->
649663 return $ ref' == ref && port' == sendPortId sport &&
650664 (reason == DiedNormal || reason == DiedUnknownId ))
651- ] >>= liftIO . putMVar gotNotification
665+ ] >>= maybe
666+ (liftIO $ assertFailure " Did not receive PortMonitorNotification message within timeout window" )
667+ (liftIO . putMVar gotNotification)
652668
653669 runProcess node2 $ do
654670 (sport, _) <- newChan :: Process (SendPort () , ReceivePort () )
671+ liftIO $ takeMVar ready
655672 send pid sport
656- liftIO $ threadDelay 100000
673+ liftIO $ threadDelay 100_000
657674
658675 verifyClient " Expected PortMonitorNotification" gotNotification
659676
0 commit comments