module Network.Transport.Tests.Multicast where
import Network.Transport
import Control.Monad (replicateM, replicateM_, forM_, when)
import Control.Concurrent (forkIO)
import Control.Concurrent.MVar (MVar, newEmptyMVar, takeMVar, putMVar, readMVar)
import Data.ByteString (ByteString)
import Data.List (elemIndex)
import Network.Transport.Tests.Auxiliary (runTests)
noConfusionNode :: Transport
-> [MVar MulticastAddress]
-> [MVar ()]
-> Int
-> [ByteString]
-> MVar ()
-> IO ()
noConfusionNode transport groups ready numPings msgs done = do
Right endpoint <- newEndPoint transport
Right myGroup <- newMulticastGroup endpoint
putMVar (head groups) (multicastAddress myGroup)
addrs <- mapM readMVar (tail groups)
forM_ addrs $ \addr -> do Right group <- resolveMulticastGroup endpoint addr
multicastSubscribe group
putMVar (head ready) ()
mapM_ readMVar (tail ready)
forkIO . replicateM_ numPings $ multicastSend myGroup [head msgs]
replicateM_ (2 * numPings) $ do
event <- receive endpoint
case event of
ReceivedMulticast addr [msg] ->
let mix = addr `elemIndex` addrs in
case mix of
Nothing -> error "Message from unexpected source"
Just ix -> when (msgs !! (ix + 1) /= msg) $ error "Unexpected message"
_ ->
error "Unexpected event"
putMVar done ()
testNoConfusion :: Transport -> Int -> IO ()
testNoConfusion transport numPings = do
[group1, group2, group3] <- replicateM 3 newEmptyMVar
[readyA, readyB, readyC] <- replicateM 3 newEmptyMVar
[doneA, doneB, doneC] <- replicateM 3 newEmptyMVar
let [msgA, msgB, msgC] = ["A says hi", "B says hi", "C says hi"]
forkIO $ noConfusionNode transport [group1, group1, group2] [readyA, readyB, readyC] numPings [msgA, msgA, msgB] doneA
forkIO $ noConfusionNode transport [group2, group1, group3] [readyB, readyC, readyA] numPings [msgB, msgA, msgC] doneB
forkIO $ noConfusionNode transport [group3, group2, group3] [readyC, readyA, readyB] numPings [msgC, msgB, msgC] doneC
mapM_ takeMVar [doneA, doneB, doneC]
testMulticast :: Transport -> IO ()
testMulticast transport =
runTests
[ ("NoConfusion", testNoConfusion transport 10000) ]