{-# LANGUAGE DeriveGeneric #-}
module Control.Distributed.Process.Tests.Mx (tests) where
import Control.Distributed.Process.Tests.Internal.Utils
import Network.Transport.Test (TestTransport(..))
import Control.Distributed.Process
import Control.Distributed.Process.Node
import Control.Distributed.Process.Management
( MxEvent(..)
, MxAgentId(..)
, mxAgent
, mxSink
, mxReady
, mxReceive
, mxDeactivate
, liftMX
, mxGetLocal
, mxSetLocal
, mxUpdateLocal
, mxNotify
, mxBroadcast
)
import Control.Monad (void)
import Data.Binary
import Data.List (find, sort)
import Data.Maybe (isJust)
import Data.Typeable
import GHC.Generics
#if ! MIN_VERSION_base(4,6,0)
import Prelude hiding (catch, log)
#endif
import Test.Framework
( Test
, testGroup
)
import Test.Framework.Providers.HUnit (testCase)
data Publish = Publish
deriving (Typeable, (forall x. Publish -> Rep Publish x)
-> (forall x. Rep Publish x -> Publish) -> Generic Publish
forall x. Rep Publish x -> Publish
forall x. Publish -> Rep Publish x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Publish -> Rep Publish x
from :: forall x. Publish -> Rep Publish x
$cto :: forall x. Rep Publish x -> Publish
to :: forall x. Rep Publish x -> Publish
Generic, Publish -> Publish -> Bool
(Publish -> Publish -> Bool)
-> (Publish -> Publish -> Bool) -> Eq Publish
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Publish -> Publish -> Bool
== :: Publish -> Publish -> Bool
$c/= :: Publish -> Publish -> Bool
/= :: Publish -> Publish -> Bool
Eq)
instance Binary Publish where
testAgentBroadcast :: TestResult () -> Process ()
testAgentBroadcast :: TestResult () -> Process ()
testAgentBroadcast TestResult ()
result = do
(SendPort ()
resultSP, ReceivePort ()
resultRP) <- Process (SendPort (), ReceivePort ())
forall a. Serializable a => Process (SendPort a, ReceivePort a)
newChan :: Process (SendPort (), ReceivePort ())
ProcessId
publisher <- MxAgentId -> () -> [MxSink ()] -> Process ProcessId
forall s. MxAgentId -> s -> [MxSink s] -> Process ProcessId
mxAgent (String -> MxAgentId
MxAgentId String
"publisher-agent") () [
(() -> MxAgent () MxAction) -> MxSink ()
forall s m. Serializable m => (m -> MxAgent s MxAction) -> MxSink s
mxSink ((() -> MxAgent () MxAction) -> MxSink ())
-> (() -> MxAgent () MxAction) -> MxSink ()
forall a b. (a -> b) -> a -> b
$ \() -> Publish -> MxAgent () ()
forall m s. Serializable m => m -> MxAgent s ()
mxBroadcast Publish
Publish MxAgent () () -> MxAgent () MxAction -> MxAgent () MxAction
forall a b. MxAgent () a -> MxAgent () b -> MxAgent () b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> MxAgent () MxAction
forall s. MxAgent s MxAction
mxReady
]
ProcessId
consumer <- MxAgentId -> () -> [MxSink ()] -> Process ProcessId
forall s. MxAgentId -> s -> [MxSink s] -> Process ProcessId
mxAgent (String -> MxAgentId
MxAgentId String
"consumer-agent") () [
(Publish -> MxAgent () MxAction) -> MxSink ()
forall s m. Serializable m => (m -> MxAgent s MxAction) -> MxSink s
mxSink ((Publish -> MxAgent () MxAction) -> MxSink ())
-> (Publish -> MxAgent () MxAction) -> MxSink ()
forall a b. (a -> b) -> a -> b
$ \Publish
Publish -> (Process () -> MxAgent () ()
forall a s. Process a -> MxAgent s a
liftMX (Process () -> MxAgent () ()) -> Process () -> MxAgent () ()
forall a b. (a -> b) -> a -> b
$ SendPort () -> () -> Process ()
forall a. Serializable a => SendPort a -> a -> Process ()
sendChan SendPort ()
resultSP ()) MxAgent () () -> MxAgent () MxAction -> MxAgent () MxAction
forall a b. MxAgent () a -> MxAgent () b -> MxAgent () b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> MxAgent () MxAction
forall s. MxAgent s MxAction
mxReady
]
() -> Process ()
forall a. Serializable a => a -> Process ()
mxNotify ()
TestResult () -> () -> Process ()
forall a. TestResult a -> a -> Process ()
stash TestResult ()
result (() -> Process ()) -> Process () -> Process ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ReceivePort () -> Process ()
forall a. Serializable a => ReceivePort a -> Process a
receiveChan ReceivePort ()
resultRP
ProcessId -> String -> Process ()
kill ProcessId
publisher String
"finished"
ProcessId -> String -> Process ()
kill ProcessId
consumer String
"finished"
testAgentDualInput :: TestResult (Maybe Int) -> Process ()
testAgentDualInput :: TestResult (Maybe Int) -> Process ()
testAgentDualInput TestResult (Maybe Int)
result = do
(SendPort Int
sp, ReceivePort Int
rp) <- Process (SendPort Int, ReceivePort Int)
forall a. Serializable a => Process (SendPort a, ReceivePort a)
newChan
ProcessId
_ <- MxAgentId -> Int -> [MxSink Int] -> Process ProcessId
forall s. MxAgentId -> s -> [MxSink s] -> Process ProcessId
mxAgent (String -> MxAgentId
MxAgentId String
"sum-agent") (Int
0 :: Int) [
(Int -> MxAgent Int MxAction) -> MxSink Int
forall s m. Serializable m => (m -> MxAgent s MxAction) -> MxSink s
mxSink ((Int -> MxAgent Int MxAction) -> MxSink Int)
-> (Int -> MxAgent Int MxAction) -> MxSink Int
forall a b. (a -> b) -> a -> b
$ (\(Int
i :: Int) -> do
Int -> MxAgent Int ()
forall s. s -> MxAgent s ()
mxSetLocal (Int -> MxAgent Int ()) -> (Int -> Int) -> Int -> MxAgent Int ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i) (Int -> MxAgent Int ()) -> MxAgent Int Int -> MxAgent Int ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< MxAgent Int Int
forall s. MxAgent s s
mxGetLocal
Int
i' <- MxAgent Int Int
forall s. MxAgent s s
mxGetLocal
if Int
i' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
15
then do MxAgent Int Int
forall s. MxAgent s s
mxGetLocal MxAgent Int Int -> (Int -> MxAgent Int ()) -> MxAgent Int ()
forall a b. MxAgent Int a -> (a -> MxAgent Int b) -> MxAgent Int b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Process () -> MxAgent Int ()
forall a s. Process a -> MxAgent s a
liftMX (Process () -> MxAgent Int ())
-> (Int -> Process ()) -> Int -> MxAgent Int ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SendPort Int -> Int -> Process ()
forall a. Serializable a => SendPort a -> a -> Process ()
sendChan SendPort Int
sp
String -> MxAgent Int MxAction
forall s. String -> MxAgent s MxAction
mxDeactivate String
"finished"
else MxAgent Int MxAction
forall s. MxAgent s MxAction
mxReady)
]
Int -> Process ()
forall a. Serializable a => a -> Process ()
mxNotify (Int
1 :: Int)
String -> Int -> Process ()
forall a. Serializable a => String -> a -> Process ()
nsend String
"sum-agent" (Int
3 :: Int)
Int -> Process ()
forall a. Serializable a => a -> Process ()
mxNotify (Int
2 :: Int)
String -> Int -> Process ()
forall a. Serializable a => String -> a -> Process ()
nsend String
"sum-agent" (Int
4 :: Int)
Int -> Process ()
forall a. Serializable a => a -> Process ()
mxNotify (Int
5 :: Int)
TestResult (Maybe Int) -> Maybe Int -> Process ()
forall a. TestResult a -> a -> Process ()
stash TestResult (Maybe Int)
result (Maybe Int -> Process ()) -> Process (Maybe Int) -> Process ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int -> ReceivePort Int -> Process (Maybe Int)
forall a.
Serializable a =>
Int -> ReceivePort a -> Process (Maybe a)
receiveChanTimeout Int
10000000 ReceivePort Int
rp
testAgentPrioritisation :: TestResult [String] -> Process ()
testAgentPrioritisation :: TestResult [String] -> Process ()
testAgentPrioritisation TestResult [String]
result = do
let name :: String
name = String
"prioritising-agent"
(SendPort [String]
sp, ReceivePort [String]
rp) <- Process (SendPort [String], ReceivePort [String])
forall a. Serializable a => Process (SendPort a, ReceivePort a)
newChan
Process ProcessId -> Process ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Process ProcessId -> Process ())
-> Process ProcessId -> Process ()
forall a b. (a -> b) -> a -> b
$ MxAgentId -> [String] -> [MxSink [String]] -> Process ProcessId
forall s. MxAgentId -> s -> [MxSink s] -> Process ProcessId
mxAgent (String -> MxAgentId
MxAgentId String
name) [String
"first"] [
(String -> MxAgent [String] MxAction) -> MxSink [String]
forall s m. Serializable m => (m -> MxAgent s MxAction) -> MxSink s
mxSink (\(String
s :: String) -> do
([String] -> [String]) -> MxAgent [String] ()
forall s. (s -> s) -> MxAgent s ()
mxUpdateLocal ((String
sString -> [String] -> [String]
forall a. a -> [a] -> [a]
:))
[String]
st <- MxAgent [String] [String]
forall s. MxAgent s s
mxGetLocal
case [String] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
st of
Int
n | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
5 -> do Process () -> MxAgent [String] ()
forall a s. Process a -> MxAgent s a
liftMX (Process () -> MxAgent [String] ())
-> Process () -> MxAgent [String] ()
forall a b. (a -> b) -> a -> b
$ SendPort [String] -> [String] -> Process ()
forall a. Serializable a => SendPort a -> a -> Process ()
sendChan SendPort [String]
sp [String]
st
String -> MxAgent [String] MxAction
forall s. String -> MxAgent s MxAction
mxDeactivate String
"finished"
Int
_ -> MxAgent [String] MxAction
forall s. MxAgent s MxAction
mxReceive
)
]
String -> String -> Process ()
forall a. Serializable a => String -> a -> Process ()
nsend String
name String
"second"
String -> Process ()
forall a. Serializable a => a -> Process ()
mxNotify String
"third"
String -> Process ()
forall a. Serializable a => a -> Process ()
mxNotify String
"fourth"
String -> String -> Process ()
forall a. Serializable a => String -> a -> Process ()
nsend String
name String
"fifth"
TestResult [String] -> [String] -> Process ()
forall a. TestResult a -> a -> Process ()
stash TestResult [String]
result ([String] -> Process ())
-> ([String] -> [String]) -> [String] -> Process ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
forall a. Ord a => [a] -> [a]
sort ([String] -> Process ()) -> Process [String] -> Process ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ReceivePort [String] -> Process [String]
forall a. Serializable a => ReceivePort a -> Process a
receiveChan ReceivePort [String]
rp
testAgentMailboxHandling :: TestResult (Maybe ()) -> Process ()
testAgentMailboxHandling :: TestResult (Maybe ()) -> Process ()
testAgentMailboxHandling TestResult (Maybe ())
result = do
(SendPort ()
sp, ReceivePort ()
rp) <- Process (SendPort (), ReceivePort ())
forall a. Serializable a => Process (SendPort a, ReceivePort a)
newChan
ProcessId
agent <- MxAgentId -> () -> [MxSink ()] -> Process ProcessId
forall s. MxAgentId -> s -> [MxSink s] -> Process ProcessId
mxAgent (String -> MxAgentId
MxAgentId String
"listener-agent") () [
(() -> MxAgent () MxAction) -> MxSink ()
forall s m. Serializable m => (m -> MxAgent s MxAction) -> MxSink s
mxSink ((() -> MxAgent () MxAction) -> MxSink ())
-> (() -> MxAgent () MxAction) -> MxSink ()
forall a b. (a -> b) -> a -> b
$ \() -> (Process () -> MxAgent () ()
forall a s. Process a -> MxAgent s a
liftMX (Process () -> MxAgent () ()) -> Process () -> MxAgent () ()
forall a b. (a -> b) -> a -> b
$ SendPort () -> () -> Process ()
forall a. Serializable a => SendPort a -> a -> Process ()
sendChan SendPort ()
sp ()) MxAgent () () -> MxAgent () MxAction -> MxAgent () MxAction
forall a b. MxAgent () a -> MxAgent () b -> MxAgent () b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> MxAgent () MxAction
forall s. MxAgent s MxAction
mxReady
]
String -> () -> Process ()
forall a. Serializable a => String -> a -> Process ()
nsend String
"listener-agent" ()
TestResult (Maybe ()) -> Maybe () -> Process ()
forall a. TestResult a -> a -> Process ()
stash TestResult (Maybe ())
result (Maybe () -> Process ()) -> Process (Maybe ()) -> Process ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int -> ReceivePort () -> Process (Maybe ())
forall a.
Serializable a =>
Int -> ReceivePort a -> Process (Maybe a)
receiveChanTimeout Int
1000000 ReceivePort ()
rp
ProcessId -> String -> Process ()
kill ProcessId
agent String
"finished"
testAgentEventHandling :: TestResult Bool -> Process ()
testAgentEventHandling :: TestResult Bool -> Process ()
testAgentEventHandling TestResult Bool
result = do
let initState :: [MxEvent]
initState = [] :: [MxEvent]
ProcessId
agentPid <- MxAgentId -> [MxEvent] -> [MxSink [MxEvent]] -> Process ProcessId
forall s. MxAgentId -> s -> [MxSink s] -> Process ProcessId
mxAgent (String -> MxAgentId
MxAgentId String
"lifecycle-listener-agent") [MxEvent]
initState [
((MxEvent -> MxAgent [MxEvent] MxAction) -> MxSink [MxEvent]
forall s m. Serializable m => (m -> MxAgent s MxAction) -> MxSink s
mxSink ((MxEvent -> MxAgent [MxEvent] MxAction) -> MxSink [MxEvent])
-> (MxEvent -> MxAgent [MxEvent] MxAction) -> MxSink [MxEvent]
forall a b. (a -> b) -> a -> b
$ \MxEvent
ev -> do
[MxEvent]
st <- MxAgent [MxEvent] [MxEvent]
forall s. MxAgent s s
mxGetLocal
let act :: MxAgent [MxEvent] ()
act =
case MxEvent
ev of
(MxSpawned ProcessId
_) -> [MxEvent] -> MxAgent [MxEvent] ()
forall s. s -> MxAgent s ()
mxSetLocal (MxEvent
evMxEvent -> [MxEvent] -> [MxEvent]
forall a. a -> [a] -> [a]
:[MxEvent]
st)
(MxProcessDied ProcessId
_ DiedReason
_) -> [MxEvent] -> MxAgent [MxEvent] ()
forall s. s -> MxAgent s ()
mxSetLocal (MxEvent
evMxEvent -> [MxEvent] -> [MxEvent]
forall a. a -> [a] -> [a]
:[MxEvent]
st)
MxEvent
_ -> () -> MxAgent [MxEvent] ()
forall a. a -> MxAgent [MxEvent] a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
MxAgent [MxEvent] ()
act MxAgent [MxEvent] ()
-> MxAgent [MxEvent] MxAction -> MxAgent [MxEvent] MxAction
forall a b.
MxAgent [MxEvent] a -> MxAgent [MxEvent] b -> MxAgent [MxEvent] b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> MxAgent [MxEvent] MxAction
forall s. MxAgent s MxAction
mxReady),
(((MxEvent, SendPort Bool) -> MxAgent [MxEvent] MxAction)
-> MxSink [MxEvent]
forall s m. Serializable m => (m -> MxAgent s MxAction) -> MxSink s
mxSink (((MxEvent, SendPort Bool) -> MxAgent [MxEvent] MxAction)
-> MxSink [MxEvent])
-> ((MxEvent, SendPort Bool) -> MxAgent [MxEvent] MxAction)
-> MxSink [MxEvent]
forall a b. (a -> b) -> a -> b
$ \(MxEvent
ev, SendPort Bool
sp :: SendPort Bool) -> do
[MxEvent]
st <- MxAgent [MxEvent] [MxEvent]
forall s. MxAgent s s
mxGetLocal
let found :: Bool
found =
case MxEvent
ev of
MxSpawned ProcessId
p ->
Maybe MxEvent -> Bool
forall a. Maybe a -> Bool
isJust (Maybe MxEvent -> Bool) -> Maybe MxEvent -> Bool
forall a b. (a -> b) -> a -> b
$ (MxEvent -> Bool) -> [MxEvent] -> Maybe MxEvent
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\MxEvent
ev' ->
case MxEvent
ev' of
(MxSpawned ProcessId
p') -> ProcessId
p' ProcessId -> ProcessId -> Bool
forall a. Eq a => a -> a -> Bool
== ProcessId
p
MxEvent
_ -> Bool
False) [MxEvent]
st
MxProcessDied ProcessId
p DiedReason
r ->
Maybe MxEvent -> Bool
forall a. Maybe a -> Bool
isJust (Maybe MxEvent -> Bool) -> Maybe MxEvent -> Bool
forall a b. (a -> b) -> a -> b
$ (MxEvent -> Bool) -> [MxEvent] -> Maybe MxEvent
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\MxEvent
ev' ->
case MxEvent
ev' of
(MxProcessDied ProcessId
p' DiedReason
r') -> ProcessId
p' ProcessId -> ProcessId -> Bool
forall a. Eq a => a -> a -> Bool
== ProcessId
p Bool -> Bool -> Bool
&& DiedReason
r DiedReason -> DiedReason -> Bool
forall a. Eq a => a -> a -> Bool
== DiedReason
r'
MxEvent
_ -> Bool
False) [MxEvent]
st
MxEvent
_ -> Bool
False
Process () -> MxAgent [MxEvent] ()
forall a s. Process a -> MxAgent s a
liftMX (Process () -> MxAgent [MxEvent] ())
-> Process () -> MxAgent [MxEvent] ()
forall a b. (a -> b) -> a -> b
$ SendPort Bool -> Bool -> Process ()
forall a. Serializable a => SendPort a -> a -> Process ()
sendChan SendPort Bool
sp Bool
found
MxAgent [MxEvent] MxAction
forall s. MxAgent s MxAction
mxReady)
]
MonitorRef
_ <- ProcessId -> Process MonitorRef
monitor ProcessId
agentPid
(SendPort ()
sp, ReceivePort ()
rp) <- Process (SendPort (), ReceivePort ())
forall a. Serializable a => Process (SendPort a, ReceivePort a)
newChan
ProcessId
pid <- Process () -> Process ProcessId
spawnLocal (Process () -> Process ProcessId)
-> Process () -> Process ProcessId
forall a b. (a -> b) -> a -> b
$ SendPort () -> () -> Process ()
forall a. Serializable a => SendPort a -> a -> Process ()
sendChan SendPort ()
sp ()
() <- ReceivePort () -> Process ()
forall a. Serializable a => ReceivePort a -> Process a
receiveChan ReceivePort ()
rp
ProcessId -> Process MonitorRef
monitor ProcessId
pid
[Match ()] -> Process ()
forall b. [Match b] -> Process b
receiveWait [ (ProcessMonitorNotification -> Process ()) -> Match ()
forall a b. Serializable a => (a -> Process b) -> Match b
match (\(ProcessMonitorNotification MonitorRef
_ ProcessId
_ DiedReason
_) -> () -> Process ()
forall a. a -> Process a
forall (m :: * -> *) a. Monad m => a -> m a
return ()) ]
(SendPort Bool
replyTo, ReceivePort Bool
reply) <- Process (SendPort Bool, ReceivePort Bool)
forall a. Serializable a => Process (SendPort a, ReceivePort a)
newChan :: Process (SendPort Bool, ReceivePort Bool)
(MxEvent, SendPort Bool) -> Process ()
forall a. Serializable a => a -> Process ()
mxNotify (ProcessId -> MxEvent
MxSpawned ProcessId
pid, SendPort Bool
replyTo)
(MxEvent, SendPort Bool) -> Process ()
forall a. Serializable a => a -> Process ()
mxNotify (ProcessId -> DiedReason -> MxEvent
MxProcessDied ProcessId
pid DiedReason
DiedNormal, SendPort Bool
replyTo)
Bool
seenAlive <- ReceivePort Bool -> Process Bool
forall a. Serializable a => ReceivePort a -> Process a
receiveChan ReceivePort Bool
reply
Bool
seenDead <- ReceivePort Bool -> Process Bool
forall a. Serializable a => ReceivePort a -> Process a
receiveChan ReceivePort Bool
reply
TestResult Bool -> Bool -> Process ()
forall a. TestResult a -> a -> Process ()
stash TestResult Bool
result (Bool -> Process ()) -> Bool -> Process ()
forall a b. (a -> b) -> a -> b
$ Bool
seenAlive Bool -> Bool -> Bool
&& Bool
seenDead
tests :: TestTransport -> IO [Test]
tests :: TestTransport -> IO [Test]
tests TestTransport{Transport
EndPointAddress -> EndPointAddress -> IO ()
testTransport :: Transport
testBreakConnection :: EndPointAddress -> EndPointAddress -> IO ()
testTransport :: TestTransport -> Transport
testBreakConnection :: TestTransport -> EndPointAddress -> EndPointAddress -> IO ()
..} = do
LocalNode
node1 <- Transport -> RemoteTable -> IO LocalNode
newLocalNode Transport
testTransport RemoteTable
initRemoteTable
[Test] -> IO [Test]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [
String -> [Test] -> Test
testGroup String
"Mx Agents" [
String -> IO () -> Test
testCase String
"Event Handling"
(String
-> LocalNode -> Bool -> (TestResult Bool -> Process ()) -> IO ()
forall a.
Eq a =>
String -> LocalNode -> a -> (TestResult a -> Process ()) -> IO ()
delayedAssertion
String
"expected True, but events where not as expected"
LocalNode
node1 Bool
True TestResult Bool -> Process ()
testAgentEventHandling)
, String -> IO () -> Test
testCase String
"Inter-Agent Broadcast"
(String -> LocalNode -> () -> (TestResult () -> Process ()) -> IO ()
forall a.
Eq a =>
String -> LocalNode -> a -> (TestResult a -> Process ()) -> IO ()
delayedAssertion
String
"expected (), but no broadcast was received"
LocalNode
node1 () TestResult () -> Process ()
testAgentBroadcast)
, String -> IO () -> Test
testCase String
"Agent Mailbox Handling"
(String
-> LocalNode
-> Maybe ()
-> (TestResult (Maybe ()) -> Process ())
-> IO ()
forall a.
Eq a =>
String -> LocalNode -> a -> (TestResult a -> Process ()) -> IO ()
delayedAssertion
String
"expected (Just ()), but no regular (mailbox) input was handled"
LocalNode
node1 (() -> Maybe ()
forall a. a -> Maybe a
Just ()) TestResult (Maybe ()) -> Process ()
testAgentMailboxHandling)
, String -> IO () -> Test
testCase String
"Agent Dual Input Handling"
(String
-> LocalNode
-> Maybe Int
-> (TestResult (Maybe Int) -> Process ())
-> IO ()
forall a.
Eq a =>
String -> LocalNode -> a -> (TestResult a -> Process ()) -> IO ()
delayedAssertion
String
"expected sum = 15, but the result was Nothing"
LocalNode
node1 (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
15 :: Maybe Int) TestResult (Maybe Int) -> Process ()
testAgentDualInput)
, String -> IO () -> Test
testCase String
"Agent Input Prioritisation"
(String
-> LocalNode
-> [String]
-> (TestResult [String] -> Process ())
-> IO ()
forall a.
Eq a =>
String -> LocalNode -> a -> (TestResult a -> Process ()) -> IO ()
delayedAssertion
String
"expected [first, second, third, fourth, fifth], but result diverged"
LocalNode
node1 ([String] -> [String]
forall a. Ord a => [a] -> [a]
sort [String
"first", String
"second",
String
"third", String
"fourth",
String
"fifth"]) TestResult [String] -> Process ()
testAgentPrioritisation)
]]