@@ -36,7 +36,7 @@ testData :: String
3636testData = "Test data 1234567891012131415!@#$%^&*()`~ABCD"
3737
3838testDataSource :: String
39−testDataSource = (concat $ replicate 1000 testData)
39+testDataSource = concat $ replicate 1000 testData
4040
4141------------------------------------------------------------------------------
4242-- Read and Write data on a socket
@@ -50,15 +50,28 @@ handlerRW sk =
5050------------------------------------------------------------------------------
5151-- Accept connections and handle connected sockets
5252------------------------------------------------------------------------------
53+
54+-- Ideally we should choose an available port automatically. However, to test
55+-- the APIs that do not allow choosing a port automatically we still need to
56+-- use a hardcoded port or search an available port on the system.
57+--
58+-- This is unreliable and the test may fail on systems where this port is not
59+-- available. We choose a higher port number so that the likelihood of it being
60+-- available is more.
61+--
62+-- Also, we cannot run the test after running it once until the timeout.
63+basePort :: PortNumber
64+basePort = 64100
65+
5366server
5467 :: Unfold.Unfold IO PortNumber Socket
5568 -> PortNumber
5669 -> MVar ()
5770 -> (Socket -> IO ())
5871 -> IO ()
59−server addr port sem handler = do
72+server listener port sem handler = do
6073 putMVar sem ()
61− (Stream.serially $ Stream.unfold addr port)
74+ Stream.serially (Stream.unfold listener port)
6275 & (Stream.asyncly . Stream.mapM (Socket.handleWithM handler))
6376 & Stream.drain
6477
@@ -69,8 +82,8 @@ sender :: PortNumber -> MVar () -> SerialT IO Char
6982sender port sem = do
7083 _ <- liftIO $ takeMVar sem
7184 liftIO $ threadDelay 1000000 -- wait for server
72− Stream.replicate 1000 testData -- SerialT IO String
73− & Stream.concatMap Stream.fromList -- SerialT IO Char
85+ Stream.replicate 1000 testData -- SerialT IO String
86+ & Stream.concatMap Stream.fromList -- SerialT IO Char
7487 & Unicode.encodeLatin1 -- SerialT IO Word8
7588 & TCP.transformBytesWith remoteAddr port -- SerialT IO Word8
7689 & Unicode.decodeLatin1 -- SerialT IO Char
@@ -81,18 +94,19 @@ execute
8194 -> Int
8295 -> (Socket -> IO ())
8396 -> IO (SerialT IO Char)
84−execute addr port size handler = do
97+execute listener port size handler = do
8598 sem <- newEmptyMVar
86− tid <- forkIO $ server addr port sem handler
99+ tid <- forkIO $ server listener port sem handler
87100 let lst = sender port sem
88101 & Stream.take size
89102 & Stream.finally (killThread tid)
90− return $ lst
103+ return lst
91104
92105validateOnPort :: Property
93106validateOnPort = monadicIO $ do
94107 res <- run $ do
95− ls2 <- execute TCP.acceptOnPort 8007 Array.defaultChunkSize handlerRW
108+ ls2 <-
109+ execute TCP.acceptOnPort basePort Array.defaultChunkSize handlerRW
96110 let dataChunk = take Array.defaultChunkSize testDataSource
97111 Stream.eqBy (==) (Stream.fromList dataChunk) ls2
98112 assert res
@@ -102,10 +116,10 @@ validateOnPortLocal = monadicIO $ do
102116 res <- run $ do
103117 ls2 <-
104118 execute
105− TCP.acceptOnPortLocal
106− 8008
107− Array.defaultChunkSize
108− handlerRW
119+ TCP.acceptOnPortLocal
120+ (basePort + 1)
121+ Array.defaultChunkSize
122+ handlerRW
109123 let dataChunk = take Array.defaultChunkSize testDataSource
110124 Stream.eqBy (==) (Stream.fromList dataChunk) ls2
111125 assert res
@@ -113,7 +127,7 @@ validateOnPortLocal = monadicIO $ do
113127main :: IO ()
114128main = hspec $ do
115129 modifyMaxSuccess (const 1) $ do
116− describe "TCP Tests: " $ do
130+ describe "Accept Connections" $ do
117131 prop "acceptOnPort" validateOnPort
118132 prop "acceptOnPortLocal" validateOnPortLocal
119133 -- prop "acceptOnAddr/connect" Tested as part of above test cases