@@ -13,13 +13,14 @@ import Control.Concurrent (threadDelay)
13import Control.Concurrent.MVar (MVar, newEmptyMVar, putMVar, takeMVar, readMVar, isEmptyMVar)
13import Control.Concurrent.MVar (MVar, newEmptyMVar, putMVar, takeMVar, readMVar, isEmptyMVar)
14import Control.Monad (replicateM, guard)
14import Control.Monad (replicateM, guard)
15import Control.Applicative ((<$>))
15import Control.Applicative ((<$>))
16+import Control.Exception (throw)
16import Network.Transport.TCP ( decodeEndPointAddress
17import Network.Transport.TCP ( decodeEndPointAddress
17 , EndPointId
18 , EndPointId
18 , ControlHeader(..)
19 , ControlHeader(..)
19 , ConnectionRequestResponse(..)
20 , ConnectionRequestResponse(..)
21import Network.Transport.Internal (encodeInt32, prependLength, tlog, tryIO)
22import Network.Transport.Internal (encodeInt32, prependLength, tlog, tryIO)
22−import Network.Transport.Internal.TCP (recvInt32)
23+import Network.Transport.Internal.TCP (recvInt32, forkServer, recvWithLength)
23import qualified Network.Socket as N ( getAddrInfo
24import qualified Network.Socket as N ( getAddrInfo
@@ -73,36 +74,37 @@ testEarlyDisconnect = do
73 putMVar serverAddr (fromJust . decodeEndPointAddress . address $ endpoint)
74 putMVar serverAddr (fromJust . decodeEndPointAddress . address $ endpoint)
74 theirAddr <- readMVar clientAddr
75 theirAddr <- readMVar clientAddr
76− -- First test: they connect to us, then drop the connection
77+ -- TEST 1: they connect to us, then drop the connection
77− ConnectionOpened cid _ addr <- receive endpoint
79+ ConnectionOpened cid _ addr <- receive endpoint
78− True <- return $ addr == theirAddr
80+ True <- return $ addr == theirAddr
80− ErrorEvent (ErrorEventConnectionLost addr' [cid']) <- receive endpoint
82+ ErrorEvent (ErrorEventConnectionLost addr' [cid']) <- receive endpoint
81− True <- return $ addr' == theirAddr && cid' == cid
83+ True <- return $ addr' == theirAddr && cid' == cid
83− -- Second test: after they dropped their connection to us, we now try to
87+ -- TEST 2: after they dropped their connection to us, we now try to
84 -- establish a connection to them. This should re-establish the broken
88 -- establish a connection to them. This should re-establish the broken
85 -- TCP connection.
89 -- TCP connection.
86 tlog "Trying to connect to client"
90 tlog "Trying to connect to client"
87− Right _ <- connect endpoint theirAddr ReliableOrdered
91+ Right conn <- connect endpoint theirAddr ReliableOrdered
89− putMVar serverDone ()
92− -- To test the connection, we do a simple ping test; as before, however,
93+ -- TEST 3: To test the connection, we do a simple ping test; as before,
93− -- the remote client won't close the connection nicely but just closes
94+ -- however, the remote client won't close the connection nicely but just
94− -- the socket
95+ -- closes the socket
96− send conn ["ping"]
97+ Right () <- send conn ["ping"]
97− cid <- expect endpoint (\(ConnectionOpened cid _ addr) -> (addr == theirAddr, cid))
98+ ConnectionOpened cid _ addr <- receive endpoint ; True <- return $ addr == theirAddr
98− expect' endpoint (\(Received cid' [msg]) -> cid' == cid && msg == "pong")
99+ Received cid' ["pong"] <- receive endpoint ; True <- return $ cid == cid'
99− expect' endpoint (\(ErrorEvent (ErrorEventConnectionLost addr [cid'])) -> addr == theirAddr && cid' == cid)
100+ ErrorEvent (ErrorEventConnectionLost addr' [cid'']) <- receive endpoint ; True <- return $ addr' == theirAddr && cid'' == cid
101− -- TODO: we now need to decide (and test) and should happen on a subsequent 'send'
103+ -- TEST 4: A subsequent send on an already-open connection will now break
102−
104+ Left (FailedWith SendConnectionClosed _) <- send conn ["ping2"]
107+ putMVar serverDone ()
107 client :: MVar (N.HostName, N.ServiceName, EndPointId) -> MVar EndPointAddress -> IO ()
109 client :: MVar (N.HostName, N.ServiceName, EndPointId) -> MVar EndPointAddress -> IO ()
108 client serverAddr clientAddr = do
110 client serverAddr clientAddr = do
@@ -111,7 +113,31 @@ testEarlyDisconnect = do
111 putMVar clientAddr ourAddress
113 putMVar clientAddr ourAddress
112 (_, _, endPointIx) <- readMVar serverAddr
114 (_, _, endPointIx) <- readMVar serverAddr
114−
116+ -- Listen for incoming messages
117+ forkServer "127.0.0.1" "8082" 5 throw $ \sock -> do
119+ 0 <- recvInt32 sock :: IO Int
120+ _ <- recvWithLength sock
121+ sendMany sock [encodeInt32 ConnectionRequestAccepted]
123+ -- Server requests a logical connection
124+ RequestConnectionId <- toEnum <$> (recvInt32 sock :: IO Int)
125+ reqId <- recvInt32 sock :: IO Int
126+ sendMany sock (encodeInt32 ControlResponse : encodeInt32 reqId : prependLength [encodeInt32 (10001 :: Int)])
128+ -- Server sends a message
129+ 10001 <- recvInt32 sock :: IO Int
130+ ["ping"] <- recvWithLength sock
133+ sendMany sock [encodeInt32 RequestConnectionId, encodeInt32 (10002 :: Int)]
134+ ControlResponse <- toEnum <$> (recvInt32 sock :: IO Int)
135+ 10002 <- recvInt32 sock :: IO Int
136+ [cid] <- recvWithLength sock
137+ sendMany sock (cid : prependLength ["pong"])
116 -- Connect to the server
142 -- Connect to the server
117 addr:_ <- N.getAddrInfo Nothing (Just "127.0.0.1") (Just "8081")
143 addr:_ <- N.getAddrInfo Nothing (Just "127.0.0.1") (Just "8081")
@@ -132,6 +158,7 @@ testEarlyDisconnect = do
132 -- The server should still receive a ConnectionClosed message
158 -- The server should still receive a ConnectionClosed message
133 N.sClose sock
159 N.sClose sock
135-- | Test the creation of a transport with an invalid address
162-- | Test the creation of a transport with an invalid address
136testInvalidAddress :: IO ()
163testInvalidAddress :: IO ()
137testInvalidAddress = do
164testInvalidAddress = do
@@ -344,10 +371,11 @@ main :: IO ()
345 tryIO $ runTests
372 tryIO $ runTests
346 [ ("EarlyDisconnect", testEarlyDisconnect)
373 [ ("EarlyDisconnect", testEarlyDisconnect)
347− , ("InvalidAddress", testInvalidAddress)
374+ , ("InvalidAddress", testInvalidAddress)
348− , ("InvalidConnect", testInvalidConnect)
375+ , ("InvalidConnect", testInvalidConnect)
349− , ("IgnoreCloseSocket", testIgnoreCloseSocket)
376+ , ("IgnoreCloseSocket", testIgnoreCloseSocket)
350− , ("BlockAfterCloseSocket", testBlockAfterCloseSocket)
377+ , ("BlockAfterCloseSocket", testBlockAfterCloseSocket)
352 Right transport <- createTransport "127.0.0.1" "8080"
379 Right transport <- createTransport "127.0.0.1" "8080"
353 testTransport transport
380 testTransport transport