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