@@ -3,9 +3,16 @@ module Control.Distributed.Process.Tests.Mx (tests) where
4import Control.Distributed.Process.Tests.Internal.Utils
4import Control.Distributed.Process.Tests.Internal.Utils
5import Network.Transport.Test (TestTransport(..))
5import Network.Transport.Test (TestTransport(..))
6−
6+import Control.Exception (SomeException)
7−import Control.Distributed.Process
7+import Control.Distributed.Process hiding (bracket, finally, try)
8+import Control.Distributed.Process.Internal.Types (ProcessExitException(..))
8import Control.Distributed.Process.Node
9import Control.Distributed.Process.Node
10+import qualified Control.Distributed.Process.UnsafePrimitives as Unsafe
9import Control.Distributed.Process.Management
16import Control.Distributed.Process.Management
10 ( MxEvent(..)
17 ( MxEvent(..)
11 , MxAgentId(..)
18 , MxAgentId(..)
@@ -22,12 +29,13 @@ import Control.Distributed.Process.Management
22 , mxBroadcast
29 , mxBroadcast
24import Control.Monad (void, unless)
31import Control.Monad (void, unless)
32+import Control.Monad.Catch(finally, bracket, try)
25import Control.Rematch (equalTo)
33import Control.Rematch (equalTo)
26import Data.Binary
34import Data.Binary
27import Data.List (find, sort)
35import Data.List (find, sort)
28−import Data.Maybe (isJust, isNothing)
36+import Data.Maybe (isJust, fromJust, isNothing)
29import Data.Typeable
37import Data.Typeable
30−import GHC.Generics
38+import GHC.Generics hiding (from)
31#if ! MIN_VERSION_base(4,6,0)
39#if ! MIN_VERSION_base(4,6,0)
32import Prelude hiding (catch, log)
40import Prelude hiding (catch, log)
@@ -51,7 +59,7 @@ awaitExit pid =
51 (\_ -> return ())
59 (\_ -> return ())
54− withMonitorRef pid = bracket (monitor pid) unmonitor
62+ withMonitorRef p = bracket (monitor p) unmonitor
56testAgentBroadcast :: TestResult () -> Process ()
64testAgentBroadcast :: TestResult () -> Process ()
57testAgentBroadcast result = do
65testAgentBroadcast result = do
@@ -313,43 +321,173 @@ testMxRegMon remoteNode result = do
313ensure :: Process () -> Process () -> Process ()
321ensure :: Process () -> Process () -> Process ()
314ensure = flip finally
322ensure = flip finally
324+type SendTest = ProcessId -> ReceivePort MxEvent -> Process Bool
326+testNSend :: (String -> () -> Process ())
330+testNSend op n r = testMxSend n r $ \p1 sink -> do
332+ let label = "testMxSend"
333+ let isValid = isValidLabel n label
336+ reg1 <- receiveChanTimeout delay sink
338+ Just (MxRegistered pd lb)
339+ | pd == p1 && isValid lb -> return ()
340+ _ -> die $ "Reg-Failed: " ++ show reg1
345+ sent <- receiveChanTimeout delay sink
347+ Just (MxSentToName lb by _)
348+ | by == us && isValid lb -> return True
349+ _ -> die $ "Send-Failed: " ++ show sent
352+ isValidLabel n l1 l2
354+ | isJust n = l2 == l1 ++ "@" ++ show (localNodeId $ fromJust n)
357+testSend :: (ProcessId -> () -> Process ()) -> Maybe LocalNode -> TestResult Bool -> Process ()
358+testSend op n r = testMxSend n r $ \p1 sink -> do
362+ -- verify the management event
364+ sent <- receiveChanTimeout 5000000 sink
366+ Just (MxSent pidTo pidFrom _)
367+ | pidTo == p1 && pidFrom == us -> return True
370+testMxSend :: Maybe LocalNode -> TestResult Bool -> SendTest -> Process ()
371+testMxSend mNode result test = do
373+ (chan, sink) <- newChan
374+ agent <- mxAgent (MxAgentId $ agentLabel us) () [
377+ m@(MxSent _ fromPid _)
378+ | fromPid == us -> liftMX $ sendChan chan m
379+ m@(MxSentToName _ fromPid _)
380+ | fromPid == us -> liftMX $ sendChan chan m
381+ m@(MxRegistered _ name)
382+ | name == label -> liftMX $ sendChan chan m
389+ Nothing -> void $ spawnLocal (proc sp)
390+ Just remoteNode -> void $ liftIO $ forkProcess remoteNode $ proc sp
392+ p1 <- receiveChan rp
393+ res <- try (test p1 sink)
395+ Left (ProcessExitException _ m) -> (liftIO $ putStrLn $ "SomeException-" ++ show m) >> stash result False
396+ Right tr -> stash result tr
401+ label = "testMxSend"
402+ agentLabel s = "mx-unsafe-check-agent-" ++ show s
403+ proc sp' = getSelfPid >>= sendChan sp' >> expect :: Process ()
316tests :: TestTransport -> IO [Test]
405tests :: TestTransport -> IO [Test]
317tests TestTransport{..} = do
406tests TestTransport{..} = do
318 node1 <- newLocalNode testTransport initRemoteTable
407 node1 <- newLocalNode testTransport initRemoteTable
319 node2 <- newLocalNode testTransport initRemoteTable
408 node2 <- newLocalNode testTransport initRemoteTable
409+ let nid = localNodeId node2
321− testGroup "Mx Agents" [
411+ testGroup "MxAgents" [
322− testCase "Event Handling"
412+ testCase "EventHandling"
323 (delayedAssertion
413 (delayedAssertion
324 "expected True, but events where not as expected"
414 "expected True, but events where not as expected"
325 node1 True testAgentEventHandling)
415 node1 True testAgentEventHandling)
326− , testCase "Inter-Agent Broadcast"
416+ , testCase "InterAgentBroadcast"
327 (delayedAssertion
417 (delayedAssertion
328 "expected (), but no broadcast was received"
418 "expected (), but no broadcast was received"
329 node1 () testAgentBroadcast)
419 node1 () testAgentBroadcast)
330− , testCase "Agent Mailbox Handling"
420+ , testCase "AgentMailboxHandling"
331 (delayedAssertion
421 (delayedAssertion
332 "expected (Just ()), but no regular (mailbox) input was handled"
422 "expected (Just ()), but no regular (mailbox) input was handled"
333 node1 (Just ()) testAgentMailboxHandling)
423 node1 (Just ()) testAgentMailboxHandling)
334− , testCase "Agent Dual Input Handling"
424+ , testCase "AgentDualInputHandling"
335 (delayedAssertion
425 (delayedAssertion
336 "expected sum = 15, but the result was Nothing"
426 "expected sum = 15, but the result was Nothing"
337 node1 (Just 15 :: Maybe Int) testAgentDualInput)
427 node1 (Just 15 :: Maybe Int) testAgentDualInput)
338− , testCase "Agent Input Prioritisation"
428+ , testCase "AgentInputPrioritisation"
339 (delayedAssertion
429 (delayedAssertion
340 "expected [first, second, third, fourth, fifth], but result diverged"
430 "expected [first, second, third, fourth, fifth], but result diverged"
341 node1 (sort ["first", "second",
431 node1 (sort ["first", "second",
342 "third", "fourth",
432 "third", "fourth",
343 "fifth"]) testAgentPrioritisation)
433 "fifth"]) testAgentPrioritisation)
345− , testGroup "Mx Events" [
435+ , testGroup "MxEvents" [
346− testCase "Name Registration Events"
436+ testCase "NameRegistrationEvents"
347 (delayedAssertion
437 (delayedAssertion
348 "expected registration events to map to the correct ProcessId"
438 "expected registration events to map to the correct ProcessId"
349 node1 () testMxRegEvents)
439 node1 () testMxRegEvents)
350− , testCase "Post Death Name UnRegistration Events"
440+ , testCase "PostDeathNameUnRegistrationEvents"
351 (delayedAssertion
441 (delayedAssertion
352 "expected process deaths to result in unregistration events"
442 "expected process deaths to result in unregistration events"
353 node1 () (testMxRegMon node2))
443 node1 () (testMxRegMon node2))
444+ , testGroup "SentEvents" [
445+ testGroup "RemoteTargets" [
446+ testCase "Unsafe.nsend"
447+ (delayedAssertion "expected mx events failed"
448+ node1 True (testNSend Unsafe.nsend $ Just node2))
449+ , testCase "Unsafe.nsendRemote"
450+ (delayedAssertion "expected mx events failed"
451+ node1 True (testNSend (Unsafe.nsendRemote nid) $ Just node2))
452+ , testCase "Unsafe.send"
453+ (delayedAssertion "expected mx events failed"
454+ node1 True (testSend Unsafe.send $ Just node2))
455+ , testCase "Unsafe.usend"
456+ (delayedAssertion "expected mx events failed"
457+ node1 True (testSend Unsafe.usend $ Just node2))
459+ (delayedAssertion "expected mx events failed"
460+ node1 True (testNSend nsend $ Just node2))
461+ , testCase "nsendRemote"
462+ (delayedAssertion "expected mx events failed"
463+ node1 True (testNSend (nsendRemote nid) $ Just node2))
465+ (delayedAssertion "expected mx events failed"
466+ node1 True (testSend send $ Just node2))
468+ (delayedAssertion "expected mx events failed"
469+ node1 True (testSend usend $ Just node2))
471+ , testGroup "LocalTargets" [
472+ testCase "Unsafe.nsend"
473+ (delayedAssertion "expected mx events failed"
474+ node1 True (testNSend Unsafe.nsend Nothing))
475+ , testCase "Unsafe.send"
476+ (delayedAssertion "expected mx events failed"
477+ node1 True (testSend Unsafe.send Nothing))
478+ , testCase "Unsafe.usend"
479+ (delayedAssertion "expected mx events failed"
480+ node1 True (testSend Unsafe.usend Nothing))
482+ (delayedAssertion "expected mx events failed"
483+ node1 True (testNSend nsend Nothing))
485+ (delayedAssertion "expected mx events failed"
486+ node1 True (testSend send Nothing))
488+ (delayedAssertion "expected mx events failed"
489+ node1 True (testSend usend Nothing))