@@ -4,12 +4,11 @@ module TestTransport where
4import Prelude hiding (catch, (>>=), (>>), return, fail)
4import Prelude hiding (catch, (>>=), (>>), return, fail)
5import TestAuxiliary (forkTry, runTests, trySome, randomThreadDelay)
5import TestAuxiliary (forkTry, runTests, trySome, randomThreadDelay)
6import Control.Concurrent (forkIO, killThread, yield)
6import Control.Concurrent (forkIO, killThread, yield)
7−import Control.Concurrent.MVar (newEmptyMVar, takeMVar, putMVar, readMVar)
7+import Control.Concurrent.MVar (newEmptyMVar, takeMVar, putMVar, readMVar, tryTakeMVar)
8−import Control.Exception (evaluate, throw)
8+import Control.Exception (evaluate, throw, throwIO)
9import Control.Monad (replicateM, replicateM_, when, guard, forM, forM_)
9import Control.Monad (replicateM, replicateM_, when, guard, forM, forM_)
10import Control.Monad.Error ()
10import Control.Monad.Error ()
11−import Network.Transport hiding (connect)
11+import Network.Transport
12−import qualified Network.Transport as NT
13import Network.Transport.Internal (tlog)
12import Network.Transport.Internal (tlog)
14import Network.Transport.Util (spawn)
13import Network.Transport.Util (spawn)
15import System.Random (randomIO)
14import System.Random (randomIO)
@@ -22,10 +21,6 @@ import Data.Maybe (catMaybes)
22import Data.List (permutations)
21import Data.List (permutations)
23import Traced
22import Traced
25−-- | We overload connect to always pass the default hints
26−connect :: EndPoint -> EndPointAddress -> Reliability -> IO (Either (TransportError ConnectErrorCode) Connection)
27−connect ep addr rel = NT.connect ep addr rel defaultConnectHints
29-- | Server that echoes messages straight back to the origin endpoint.
24-- | Server that echoes messages straight back to the origin endpoint.
30echoServer :: EndPoint -> IO ()
25echoServer :: EndPoint -> IO ()
31echoServer endpoint = do
26echoServer endpoint = do
@@ -37,7 +32,7 @@ echoServer endpoint = do
37 case event of
32 case event of
38 ConnectionOpened cid rel addr -> do
33 ConnectionOpened cid rel addr -> do
39 tlog $ "Opened new connection " ++ show cid
34 tlog $ "Opened new connection " ++ show cid
40− Right conn <- connect endpoint addr rel
35+ Right conn <- connect endpoint addr rel defaultConnectHints
41 go (Map.insert cid conn cs)
36 go (Map.insert cid conn cs)
42 Received cid payload -> do
37 Received cid payload -> do
43 send (Map.findWithDefault (error $ "Received: Invalid cid " ++ show cid) cid cs) payload
38 send (Map.findWithDefault (error $ "Received: Invalid cid " ++ show cid) cid cs) payload
@@ -59,7 +54,7 @@ ping :: EndPoint -> EndPointAddress -> Int -> ByteString -> IO ()
59ping endpoint server numPings msg = do
54ping endpoint server numPings msg = do
60 -- Open connection to the server
55 -- Open connection to the server
61 tlog "Connect to echo server"
56 tlog "Connect to echo server"
62− Right conn <- connect endpoint server ReliableOrdered
57+ Right conn <- connect endpoint server ReliableOrdered defaultConnectHints
64 -- Wait for the server to open reply connection
59 -- Wait for the server to open reply connection
65 tlog "Wait for ConnectionOpened message"
60 tlog "Wait for ConnectionOpened message"
@@ -126,10 +121,10 @@ testConnections transport numPings = do
126 Right endpoint <- newEndPoint transport
121 Right endpoint <- newEndPoint transport
128 -- Open two connections to the server
123 -- Open two connections to the server
129− Right conn1 <- connect endpoint server ReliableOrdered
124+ Right conn1 <- connect endpoint server ReliableOrdered defaultConnectHints
130 ConnectionOpened serv1 _ _ <- receive endpoint
125 ConnectionOpened serv1 _ _ <- receive endpoint
132− Right conn2 <- connect endpoint server ReliableOrdered
127+ Right conn2 <- connect endpoint server ReliableOrdered defaultConnectHints
133 ConnectionOpened serv2 _ _ <- receive endpoint
128 ConnectionOpened serv2 _ _ <- receive endpoint
135 -- One thread to send "pingA" on the first connection
130 -- One thread to send "pingA" on the first connection
@@ -164,10 +159,10 @@ testCloseOneConnection transport numPings = do
164 Right endpoint <- newEndPoint transport
159 Right endpoint <- newEndPoint transport
166 -- Open two connections to the server
161 -- Open two connections to the server
167− Right conn1 <- connect endpoint server ReliableOrdered
162+ Right conn1 <- connect endpoint server ReliableOrdered defaultConnectHints
168 ConnectionOpened serv1 _ _ <- receive endpoint
163 ConnectionOpened serv1 _ _ <- receive endpoint
170− Right conn2 <- connect endpoint server ReliableOrdered
165+ Right conn2 <- connect endpoint server ReliableOrdered defaultConnectHints
171 ConnectionOpened serv2 _ _ <- receive endpoint
166 ConnectionOpened serv2 _ _ <- receive endpoint
173 -- One thread to send "pingA" on the first connection
168 -- One thread to send "pingA" on the first connection
@@ -212,7 +207,7 @@ testCloseOneDirection transport numPings = do
213 -- Connect to B
208 -- Connect to B
214 tlog "Connect to B"
209 tlog "Connect to B"
215− Right conn <- readMVar addrB >>= \addr -> connect endpoint addr ReliableOrdered
210+ Right conn <- readMVar addrB >>= \addr -> connect endpoint addr ReliableOrdered defaultConnectHints
217 -- Wait for B to connect to us
212 -- Wait for B to connect to us
218 tlog "Wait for B"
213 tlog "Wait for B"
@@ -252,7 +247,7 @@ testCloseOneDirection transport numPings = do
253 -- Connect to A
248 -- Connect to A
254 tlog "Connect to A"
249 tlog "Connect to A"
255− Right conn <- readMVar addrA >>= \addr -> connect endpoint addr ReliableOrdered
250+ Right conn <- readMVar addrA >>= \addr -> connect endpoint addr ReliableOrdered defaultConnectHints
257 -- Wait for A's pings
252 -- Wait for A's pings
258 tlog "Wait for pings from A"
253 tlog "Wait for pings from A"
@@ -331,7 +326,7 @@ testCloseReopen transport numPings = do
331 forM_ [1 .. numRepeats] $ \i -> do
326 forM_ [1 .. numRepeats] $ \i -> do
332 tlog "A connecting"
327 tlog "A connecting"
333 -- Connect to B
328 -- Connect to B
334− Right conn <- readMVar addrB >>= \addr -> connect endpoint addr ReliableOrdered
329+ Right conn <- readMVar addrB >>= \addr -> connect endpoint addr ReliableOrdered defaultConnectHints
336 tlog "A pinging"
331 tlog "A pinging"
337 -- Say hi
332 -- Say hi
@@ -368,7 +363,7 @@ testParallelConnects transport numPings = do
369 -- Spawn lots of clients
364 -- Spawn lots of clients
370 forM_ [1 .. numPings] $ \i -> forkTry $ do
365 forM_ [1 .. numPings] $ \i -> forkTry $ do
371− Right conn <- connect endpoint server ReliableOrdered
366+ Right conn <- connect endpoint server ReliableOrdered defaultConnectHints
372 send conn [pack $ "ping" ++ show i]
367 send conn [pack $ "ping" ++ show i]
373 send conn [pack $ "ping" ++ show i]
368 send conn [pack $ "ping" ++ show i]
374 close conn
369 close conn
@@ -393,8 +388,8 @@ testSendAfterClose transport numRepeats = do
394 -- We request two lightweight connections
389 -- We request two lightweight connections
395 replicateM numRepeats $ do
390 replicateM numRepeats $ do
396− Right conn1 <- connect endpoint server ReliableOrdered
391+ Right conn1 <- connect endpoint server ReliableOrdered defaultConnectHints
397− Right conn2 <- connect endpoint server ReliableOrdered
392+ Right conn2 <- connect endpoint server ReliableOrdered defaultConnectHints
399 -- Close the second, but leave the first open; then output on the second
394 -- Close the second, but leave the first open; then output on the second
400 -- connection (i.e., on a closed connection while there is still another
395 -- connection (i.e., on a closed connection while there is still another
@@ -424,8 +419,8 @@ testCloseTwice transport numRepeats = do
425 replicateM numRepeats $ do
420 replicateM numRepeats $ do
426 -- We request two lightweight connections
421 -- We request two lightweight connections
427− Right conn1 <- connect endpoint server ReliableOrdered
422+ Right conn1 <- connect endpoint server ReliableOrdered defaultConnectHints
428− Right conn2 <- connect endpoint server ReliableOrdered
423+ Right conn2 <- connect endpoint server ReliableOrdered defaultConnectHints
430 -- Close the second one twice
425 -- Close the second one twice
431 close conn2
426 close conn2
@@ -455,7 +450,7 @@ testConnectToSelf transport numPings = do
455 Right endpoint <- newEndPoint transport
450 Right endpoint <- newEndPoint transport
457 tlog "Creating self-connection"
452 tlog "Creating self-connection"
458− Right conn <- connect endpoint (address endpoint) ReliableOrdered
453+ Right conn <- connect endpoint (address endpoint) ReliableOrdered defaultConnectHints
460 tlog "Talk to myself"
455 tlog "Talk to myself"
@@ -496,8 +491,8 @@ testConnectToSelfTwice transport numPings = do
496 Right endpoint <- newEndPoint transport
491 Right endpoint <- newEndPoint transport
498 tlog "Creating self-connection"
493 tlog "Creating self-connection"
499− Right conn1 <- connect endpoint (address endpoint) ReliableOrdered
494+ Right conn1 <- connect endpoint (address endpoint) ReliableOrdered defaultConnectHints
500− Right conn2 <- connect endpoint (address endpoint) ReliableOrdered
495+ Right conn2 <- connect endpoint (address endpoint) ReliableOrdered defaultConnectHints
502 tlog "Talk to myself"
497 tlog "Talk to myself"
@@ -541,9 +536,9 @@ testCloseSelf newTransport = do
541 Right transport <- newTransport
536 Right transport <- newTransport
542 Right endpoint1 <- newEndPoint transport
537 Right endpoint1 <- newEndPoint transport
543 Right endpoint2 <- newEndPoint transport
538 Right endpoint2 <- newEndPoint transport
544− Right conn1 <- connect endpoint1 (address endpoint1) ReliableOrdered
539+ Right conn1 <- connect endpoint1 (address endpoint1) ReliableOrdered defaultConnectHints
545− Right conn2 <- connect endpoint1 (address endpoint1) ReliableOrdered
540+ Right conn2 <- connect endpoint1 (address endpoint1) ReliableOrdered defaultConnectHints
546− Right conn3 <- connect endpoint2 (address endpoint2) ReliableOrdered
541+ Right conn3 <- connect endpoint2 (address endpoint2) ReliableOrdered defaultConnectHints
548 -- Close the conneciton and try to send
543 -- Close the conneciton and try to send
549 close conn1
544 close conn1
@@ -554,13 +549,13 @@ testCloseSelf newTransport = do
554 -- to the second endpoint should still be fine
549 -- to the second endpoint should still be fine
555 closeEndPoint endpoint1
550 closeEndPoint endpoint1
556 Left (TransportError SendFailed _) <- send conn2 ["ping"]
551 Left (TransportError SendFailed _) <- send conn2 ["ping"]
557− Left (TransportError ConnectFailed _) <- connect endpoint1 (address endpoint1) ReliableOrdered
552+ Left (TransportError ConnectFailed _) <- connect endpoint1 (address endpoint1) ReliableOrdered defaultConnectHints
558 Right () <- send conn3 ["ping"]
553 Right () <- send conn3 ["ping"]
560 -- Close the transport; now the second should no longer work
555 -- Close the transport; now the second should no longer work
561 closeTransport transport
556 closeTransport transport
562 Left (TransportError SendFailed _) <- send conn3 ["ping"]
557 Left (TransportError SendFailed _) <- send conn3 ["ping"]
563− Left (TransportError ConnectFailed _) <- connect endpoint2 (address endpoint2) ReliableOrdered
558+ Left (TransportError ConnectFailed _) <- connect endpoint2 (address endpoint2) ReliableOrdered defaultConnectHints
565 return ()
560 return ()
@@ -592,7 +587,7 @@ testCloseEndPoint transport _ = do
592 ConnectionOpened cid ReliableOrdered addr <- receive endpoint ; True <- return $ addr == theirAddr
587 ConnectionOpened cid ReliableOrdered addr <- receive endpoint ; True <- return $ addr == theirAddr
593 Received cid' ["ping"] <- receive endpoint ; True <- return $ cid == cid'
588 Received cid' ["ping"] <- receive endpoint ; True <- return $ cid == cid'
595− Right conn <- connect endpoint theirAddr ReliableOrdered
590+ Right conn <- connect endpoint theirAddr ReliableOrdered defaultConnectHints
596 send conn ["pong"]
591 send conn ["pong"]
598 ConnectionClosed cid'' <- receive endpoint ; True <- return $ cid == cid''
593 ConnectionClosed cid'' <- receive endpoint ; True <- return $ cid == cid''
@@ -614,7 +609,7 @@ testCloseEndPoint transport _ = do
614 putMVar clientAddr1 (address endpoint)
609 putMVar clientAddr1 (address endpoint)
616 -- Connect to the server, then close the endpoint without disconnecting explicitly
611 -- Connect to the server, then close the endpoint without disconnecting explicitly
617− Right _ <- connect endpoint theirAddr ReliableOrdered
612+ Right _ <- connect endpoint theirAddr ReliableOrdered defaultConnectHints
618 closeEndPoint endpoint
613 closeEndPoint endpoint
619 EndPointClosed <- receive endpoint
614 EndPointClosed <- receive endpoint
620 return ()
615 return ()
@@ -624,7 +619,7 @@ testCloseEndPoint transport _ = do
624 Right endpoint <- newEndPoint transport
619 Right endpoint <- newEndPoint transport
625 putMVar clientAddr2 (address endpoint)
620 putMVar clientAddr2 (address endpoint)
627− Right conn <- connect endpoint theirAddr ReliableOrdered
622+ Right conn <- connect endpoint theirAddr ReliableOrdered defaultConnectHints
628 send conn ["ping"]
623 send conn ["ping"]
630 -- Reply from the server
625 -- Reply from the server
@@ -642,7 +637,7 @@ testCloseEndPoint transport _ = do
642 () <- close conn
637 () <- close conn
644 -- And so should an attempt to connect
639 -- And so should an attempt to connect
645− Left (TransportError ConnectFailed _) <- connect endpoint theirAddr ReliableOrdered
640+ Left (TransportError ConnectFailed _) <- connect endpoint theirAddr ReliableOrdered defaultConnectHints
647 return ()
642 return ()
@@ -677,7 +672,7 @@ testCloseTransport newTransport = do
677 ConnectionOpened cid2 ReliableOrdered addr' <- receive endpoint ; True <- return $ addr' == theirAddr2
672 ConnectionOpened cid2 ReliableOrdered addr' <- receive endpoint ; True <- return $ addr' == theirAddr2
678 Received cid2' ["ping"] <- receive endpoint ; True <- return $ cid2' == cid2
673 Received cid2' ["ping"] <- receive endpoint ; True <- return $ cid2' == cid2
680− Right conn <- connect endpoint theirAddr2 ReliableOrdered
675+ Right conn <- connect endpoint theirAddr2 ReliableOrdered defaultConnectHints
681 send conn ["pong"]
676 send conn ["pong"]
683 -- Client now closes down its transport. We should receive connection closed messages (we don't know the precise order, however)
678 -- Client now closes down its transport. We should receive connection closed messages (we don't know the precise order, however)
@@ -703,13 +698,13 @@ testCloseTransport newTransport = do
703 putMVar clientAddr1 (address endpoint1)
698 putMVar clientAddr1 (address endpoint1)
705 -- Connect to the server, then close the endpoint without disconnecting explicitly
700 -- Connect to the server, then close the endpoint without disconnecting explicitly
706− Right _ <- connect endpoint1 theirAddr ReliableOrdered
701+ Right _ <- connect endpoint1 theirAddr ReliableOrdered defaultConnectHints
708 -- Set up an endpoint with one outgoing and out incoming connection
703 -- Set up an endpoint with one outgoing and out incoming connection
709 Right endpoint2 <- newEndPoint transport
704 Right endpoint2 <- newEndPoint transport
710 putMVar clientAddr2 (address endpoint2)
705 putMVar clientAddr2 (address endpoint2)
712− Right conn <- connect endpoint2 theirAddr ReliableOrdered
707+ Right conn <- connect endpoint2 theirAddr ReliableOrdered defaultConnectHints
713 send conn ["ping"]
708 send conn ["ping"]
715 -- Reply from the server
710 -- Reply from the server
@@ -730,8 +725,8 @@ testCloseTransport newTransport = do
730 () <- close conn
725 () <- close conn
732 -- And so should an attempt to connect on either endpoint
727 -- And so should an attempt to connect on either endpoint
733− Left (TransportError ConnectFailed _) <- connect endpoint1 theirAddr ReliableOrdered
728+ Left (TransportError ConnectFailed _) <- connect endpoint1 theirAddr ReliableOrdered defaultConnectHints
734− Left (TransportError ConnectFailed _) <- connect endpoint2 theirAddr ReliableOrdered
729+ Left (TransportError ConnectFailed _) <- connect endpoint2 theirAddr ReliableOrdered defaultConnectHints
736 -- And finally, so should an attempt to create a new endpoint
731 -- And finally, so should an attempt to create a new endpoint
737 Left (TransportError NewEndPointFailed _) <- newEndPoint transport
732 Left (TransportError NewEndPointFailed _) <- newEndPoint transport
@@ -760,7 +755,7 @@ testConnectClosedEndPoint transport = do
760 Right endpoint <- newEndPoint transport
755 Right endpoint <- newEndPoint transport
761 readMVar serverClosed
756 readMVar serverClosed
763− Left (TransportError ConnectNotFound _) <- readMVar serverAddr >>= \addr -> connect endpoint addr ReliableOrdered
758+ Left (TransportError ConnectNotFound _) <- readMVar serverAddr >>= \addr -> connect endpoint addr ReliableOrdered defaultConnectHints
765 putMVar clientDone ()
760 putMVar clientDone ()
@@ -794,7 +789,7 @@ testSendException newTransport = do
794 Right endpoint2 <- newEndPoint transport
789 Right endpoint2 <- newEndPoint transport
796 -- Connect endpoint1 to endpoint2
791 -- Connect endpoint1 to endpoint2
797− Right conn <- connect endpoint1 (address endpoint2) ReliableOrdered
792+ Right conn <- connect endpoint1 (address endpoint2) ReliableOrdered defaultConnectHints
798 ConnectionOpened _ _ _ <- receive endpoint2
793 ConnectionOpened _ _ _ <- receive endpoint2
800 -- Send an exceptional value
795 -- Send an exceptional value
@@ -807,7 +802,7 @@ testSendException newTransport = do
807 ErrorEvent (TransportError (EventConnectionLost _ [_]) _) <- receive endpoint2
802 ErrorEvent (TransportError (EventConnectionLost _ [_]) _) <- receive endpoint2
809 -- A new connection will re-establish the connection
804 -- A new connection will re-establish the connection
810− Right conn2 <- connect endpoint1 (address endpoint2) ReliableOrdered
805+ Right conn2 <- connect endpoint1 (address endpoint2) ReliableOrdered defaultConnectHints
811 send conn2 ["ping"]
806 send conn2 ["ping"]
812 close conn2
807 close conn2
@@ -836,7 +831,7 @@ testKill newTransport numThreads = do
836 done <- newEmptyMVar
831 done <- newEmptyMVar
837 tid <- forkIO $ do
832 tid <- forkIO $ do
838 randomThreadDelay 10
833 randomThreadDelay 10
839− Right conn <- connect endpoint1 (address endpoint2) ReliableOrdered
834+ Right conn <- connect endpoint1 (address endpoint2) ReliableOrdered defaultConnectHints
840 randomThreadDelay 10
835 randomThreadDelay 10
841 Right () <- send conn ["ping"]
836 Right () <- send conn ["ping"]
842 randomThreadDelay 10
837 randomThreadDelay 10
@@ -869,8 +864,13 @@ testCrossing :: Transport -> Int -> IO ()
869testCrossing transport numRepeats = do
864testCrossing transport numRepeats = do
870 [aAddr, bAddr] <- replicateM 2 newEmptyMVar
865 [aAddr, bAddr] <- replicateM 2 newEmptyMVar
871 [aDone, bDone] <- replicateM 2 newEmptyMVar
866 [aDone, bDone] <- replicateM 2 newEmptyMVar
867+ [aTimeout, bTimeout] <- replicateM 2 newEmptyMVar
872 go <- newEmptyMVar
868 go <- newEmptyMVar
870+ let hints = defaultConnectHints {
871+ connectTimeout = Just 5000000
875 forkTry $ do
875 forkTry $ do
876 Right endpoint <- newEndPoint transport
876 Right endpoint <- newEndPoint transport
@@ -879,8 +879,16 @@ testCrossing transport numRepeats = do
880 replicateM_ numRepeats $ do
880 replicateM_ numRepeats $ do
881 takeMVar go >> yield
881 takeMVar go >> yield
882+ -- Because we are creating lots of connections, it's possible that
883+ -- connect times out (for instance, in the TCP transport,
884+ -- Network.Socket.connect may time out). We shouldn't regard this as an
885+ -- error in the Transport, though.
882− Right conn <- connect endpoint theirAddress ReliableOrdered
886+ connectResult <- connect endpoint theirAddress ReliableOrdered hints
887+ case connectResult of
883− close conn
888+ Right conn -> close conn
889+ Left (TransportError ConnectTimeout _) -> putMVar aTimeout ()
890+ Left (TransportError ConnectFailed _) -> readMVar bTimeout
891+ Left err -> throwIO . userError $ "testCrossed: " ++ show err
884 putMVar aDone ()
892 putMVar aDone ()
@@ -891,12 +899,19 @@ testCrossing transport numRepeats = do
892 replicateM_ numRepeats $ do
900 replicateM_ numRepeats $ do
893 takeMVar go >> yield
901 takeMVar go >> yield
894− Right conn <- connect endpoint theirAddress ReliableOrdered
902+ connectResult <- connect endpoint theirAddress ReliableOrdered hints
903+ case connectResult of
895− close conn
904+ Right conn -> close conn
905+ Left (TransportError ConnectTimeout _) -> putMVar bTimeout ()
906+ Left (TransportError ConnectFailed _) -> readMVar aTimeout
907+ Left err -> throwIO . userError $ "testCrossed: " ++ show err
896 putMVar bDone ()
908 putMVar bDone ()
898 -- Driver
910 -- Driver
899 forM_ [1 .. numRepeats] $ \_i -> do
911 forM_ [1 .. numRepeats] $ \_i -> do
912+ -- putStrLn $ "Round " ++ show _i
913+ tryTakeMVar aTimeout
914+ tryTakeMVar bTimeout
900 putMVar go ()
915 putMVar go ()
901 putMVar go ()
916 putMVar go ()
902 takeMVar aDone
917 takeMVar aDone