on master help sign in
Address review comments and rebase with master
5177433Ranjeet Ranjan
streamly.cabal+2
@@ -169,6 +169,8 @@ extra-source-files:
169 test/Streamly/Test/Data/Parser/ParserD.hs
169 test/Streamly/Test/Data/Parser/ParserD.hs
170 test/Streamly/Test/FileSystem/Event.hs
170 test/Streamly/Test/FileSystem/Event.hs
171 test/Streamly/Test/FileSystem/Handle.hs
171 test/Streamly/Test/FileSystem/Handle.hs
172+ test/Streamly/Test/Network/Socket.hs
173+ test/Streamly/Test/Network/Inet/TCP.hs
172 test/Streamly/Test/Prelude.hs
174 test/Streamly/Test/Prelude.hs
173 test/Streamly/Test/Prelude/*.hs
175 test/Streamly/Test/Prelude/*.hs
174 test/Streamly/Test/Unicode/Stream.hs
176 test/Streamly/Test/Unicode/Stream.hs
test/Streamly/Test/Network/Inet/TCP.hs+38−30
@@ -19,12 +19,12 @@ import Streamly.Prelude (SerialT)
19import Test.QuickCheck (Property)
19import Test.QuickCheck (Property)
20import Test.QuickCheck.Monadic (monadicIO, assert, run)
20import Test.QuickCheck.Monadic (monadicIO, assert, run)
21
21
22−import qualified Streamly.Internal.Data.Array.Storable.Foreign.Types as A
22+import qualified Streamly.Internal.Data.Array.Storable.Foreign.Types as Array
23−import qualified Streamly.Internal.Data.Unfold as UF
23+import qualified Streamly.Internal.Data.Unfold as Unfold
24import qualified Streamly.Internal.Network.Inet.TCP as TCP
24import qualified Streamly.Internal.Network.Inet.TCP as TCP
25−import qualified Streamly.Internal.Network.Socket as SK
25+import qualified Streamly.Internal.Network.Socket as Socket
26−import qualified Streamly.Internal.Unicode.Stream as U
26+import qualified Streamly.Internal.Unicode.Stream as Unicode
27−import qualified Streamly.Prelude as S
27+import qualified Streamly.Prelude as Stream
28
28
29import Test.Hspec
29import Test.Hspec
30import Test.Hspec.QuickCheck
30import Test.Hspec.QuickCheck
@@ -35,32 +35,32 @@ import Test.Hspec.QuickCheck
35testData :: String
35testData :: String
36testData = "Test data 1234567891012131415!@#$%^&*()`~ABCD"
36testData = "Test data 1234567891012131415!@#$%^&*()`~ABCD"
37
37
38−testDataLarge :: String
38+testDataSource :: String
39−testDataLarge = (concat $ replicate 1000 testData)
39+testDataSource = (concat $ replicate 1000 testData)
40
40
41------------------------------------------------------------------------------
41------------------------------------------------------------------------------
42-- Read and Write data on a socket
42-- Read and Write data on a socket
43------------------------------------------------------------------------------
43------------------------------------------------------------------------------
44handlerRW :: Socket -> IO ()
44handlerRW :: Socket -> IO ()
45handlerRW sk =
45handlerRW sk =
46− S.unfold SK.read sk
46+ Stream.unfold Socket.read sk
47− & S.fold (SK.write sk)
47+ & Stream.fold (Socket.write sk)
48 & discard
48 & discard
49
49
50------------------------------------------------------------------------------
50------------------------------------------------------------------------------
51−-- Accept connecttions and handle connected sockets
51+-- Accept connections and handle connected sockets
52------------------------------------------------------------------------------
52------------------------------------------------------------------------------
53server
53server
54− :: UF.Unfold IO PortNumber Socket
54+ :: Unfold.Unfold IO PortNumber Socket
55 -> PortNumber
55 -> PortNumber
56 -> MVar ()
56 -> MVar ()
57 -> (Socket -> IO ())
57 -> (Socket -> IO ())
58 -> IO ()
58 -> IO ()
59server addr port sem handler = do
59server addr port sem handler = do
60 putMVar sem ()
60 putMVar sem ()
61− (S.serially $ S.unfold addr port)
61+ (Stream.serially $ Stream.unfold addr port)
62− & (S.asyncly . S.mapM (SK.handleWithM handler))
62+ & (Stream.asyncly . Stream.mapM (Socket.handleWithM handler))
63− & S.drain
63+ & Stream.drain
64
64
65remoteAddr :: (Word8,Word8,Word8,Word8)
65remoteAddr :: (Word8,Word8,Word8,Word8)
66remoteAddr = (127, 0, 0, 1)
66remoteAddr = (127, 0, 0, 1)
@@ -69,38 +69,46 @@ sender :: PortNumber -> MVar () -> SerialT IO Char
69sender port sem = do
69sender port sem = do
70 _ <- liftIO $ takeMVar sem
70 _ <- liftIO $ takeMVar sem
71 liftIO $ threadDelay 1000000 -- wait for server
71 liftIO $ threadDelay 1000000 -- wait for server
72− S.replicate 1 testDataLarge -- SerialT IO String
72+ Stream.replicate 1000 testData -- SerialT IO String
73− & U.unwords UF.fromList -- SerialT IO Char
73+ & Stream.concatMap Stream.fromList -- SerialT IO Char
74− & U.encodeLatin1 -- SerialT IO Word8
74+ & Unicode.encodeLatin1 -- SerialT IO Word8
75 & TCP.transformBytesWith remoteAddr port -- SerialT IO Word8
75 & TCP.transformBytesWith remoteAddr port -- SerialT IO Word8
76− & U.decodeLatin1 -- SerialT IO Char
76+ & Unicode.decodeLatin1 -- SerialT IO Char
77
77
78execute
78execute
79− :: UF.Unfold IO PortNumber Socket
79+ :: Unfold.Unfold IO PortNumber Socket
80 -> PortNumber
80 -> PortNumber
81 -> Int
81 -> Int
82 -> (Socket -> IO ())
82 -> (Socket -> IO ())
83− -> IO [Char]
83+ -> IO (SerialT IO Char)
84execute addr port size handler = do
84execute addr port size handler = do
85 sem <- newEmptyMVar
85 sem <- newEmptyMVar
86 tid <- forkIO $ server addr port sem handler
86 tid <- forkIO $ server addr port sem handler
87− lst <- sender port sem
87+ let lst = sender port sem
88− & S.take size
88+ & Stream.take size
89− & S.toList
90− killThread tid
89+ & Stream.finally (killThread tid)
91 return $ lst
90 return $ lst
92
91
93validateOnPort :: Property
92validateOnPort :: Property
94validateOnPort = monadicIO $ do
93validateOnPort = monadicIO $ do
94+ res <- run $ do
95− ls2 <- run $ execute TCP.acceptOnPort 8000 A.defaultChunkSize handlerRW
95+ ls2 <- execute TCP.acceptOnPort 8007 Array.defaultChunkSize handlerRW
96− assert (take A.defaultChunkSize testDataLarge == ls2)
96+ let dataChunk = take Array.defaultChunkSize testDataSource
97+ Stream.eqBy (==) (Stream.fromList dataChunk) ls2
98+ assert res
97
99
98validateOnPortLocal :: Property
100validateOnPortLocal :: Property
99validateOnPortLocal = monadicIO $ do
101validateOnPortLocal = monadicIO $ do
100− ls2 <-
101− run
102+ res <- run $ do
103+ ls2 <-
104+ execute
102− $ execute TCP.acceptOnPortLocal 8001 A.defaultChunkSize handlerRW
105+ TCP.acceptOnPortLocal
106+ 8008
107+ Array.defaultChunkSize
108+ handlerRW
103− assert (take A.defaultChunkSize testDataLarge == ls2)
109+ let dataChunk = take Array.defaultChunkSize testDataSource
110+ Stream.eqBy (==) (Stream.fromList dataChunk) ls2
111+ assert res
104
112
105main :: IO ()
113main :: IO ()
106main = hspec $ do
114main = hspec $ do
test/Streamly/Test/Network/Socket.hs+40−33
@@ -19,12 +19,11 @@ import Streamly.Prelude (SerialT)
19import Test.QuickCheck (Property)
19import Test.QuickCheck (Property)
20import Test.QuickCheck.Monadic (monadicIO, assert, run)
20import Test.QuickCheck.Monadic (monadicIO, assert, run)
21
21
22−import qualified Streamly.Internal.Data.Array.Storable.Foreign.Types as A
22+import qualified Streamly.Internal.Data.Array.Storable.Foreign.Types as Array
23−import qualified Streamly.Internal.Data.Unfold as UF
24import qualified Streamly.Internal.Network.Inet.TCP as TCP
23import qualified Streamly.Internal.Network.Inet.TCP as TCP
25−import qualified Streamly.Internal.Network.Socket as SK
24+import qualified Streamly.Internal.Network.Socket as Socket
26−import qualified Streamly.Internal.Unicode.Stream as U
25+import qualified Streamly.Internal.Unicode.Stream as Unicode
27−import qualified Streamly.Prelude as S
26+import qualified Streamly.Prelude as Stream
28
27
29import Test.Hspec
28import Test.Hspec
30import Test.Hspec.QuickCheck
29import Test.Hspec.QuickCheck
@@ -43,26 +42,26 @@ testDataSource = concat $ replicate 1000 testData
43------------------------------------------------------------------------------
42------------------------------------------------------------------------------
44handlerChunksWithBuffer :: Socket -> IO ()
43handlerChunksWithBuffer :: Socket -> IO ()
45handlerChunksWithBuffer sk =
44handlerChunksWithBuffer sk =
46− S.unfold SK.readChunksWithBufferOf (100, sk)
45+ Stream.unfold Socket.readChunksWithBufferOf (100, sk)
47− & S.fold (SK.writeChunks sk)
46+ & Stream.fold (Socket.writeChunks sk)
48 & discard
47 & discard
49
48
50handlerChunks :: Socket -> IO ()
49handlerChunks :: Socket -> IO ()
51handlerChunks sk =
50handlerChunks sk =
52− S.unfold SK.readChunks sk
51+ Stream.unfold Socket.readChunks sk
53− & S.fold (SK.writeChunks sk)
52+ & Stream.fold (Socket.writeChunks sk)
54 & discard
53 & discard
55
54
56handlerwithbuffer :: Socket -> IO ()
55handlerwithbuffer :: Socket -> IO ()
57handlerwithbuffer sk =
56handlerwithbuffer sk =
58− S.unfold SK.readWithBufferOf (100, sk)
57+ Stream.unfold Socket.readWithBufferOf (100, sk)
59− & S.fold (SK.writeWithBufferOf 100 sk)
58+ & Stream.fold (Socket.writeWithBufferOf 100 sk)
60 & discard
59 & discard
61
60
62handlerRW :: Socket -> IO ()
61handlerRW :: Socket -> IO ()
63handlerRW sk =
62handlerRW sk =
64− S.unfold SK.read sk
63+ Stream.unfold Socket.read sk
65− & S.fold (SK.write sk)
64+ & Stream.fold (Socket.write sk)
66 & discard
65 & discard
67------------------------------------------------------------------------------
66------------------------------------------------------------------------------
68-- Accept connecttions and handle connected sockets
67-- Accept connecttions and handle connected sockets
@@ -71,9 +70,9 @@ handlerRW sk =
71server :: PortNumber -> MVar () -> (Socket -> IO ()) -> IO ()
70server :: PortNumber -> MVar () -> (Socket -> IO ()) -> IO ()
72server port sem handler = do
71server port sem handler = do
73 putMVar sem ()
72 putMVar sem ()
74− (S.serially $ S.unfold TCP.acceptOnPort port)
73+ (Stream.serially $ Stream.unfold TCP.acceptOnPort port)
75− & (S.asyncly . S.mapM (SK.handleWithM handler))
74+ & (Stream.asyncly . Stream.mapM (Socket.handleWithM handler))
76− & S.drain
75+ & Stream.drain
77
76
78remoteAddr :: (Word8,Word8,Word8,Word8)
77remoteAddr :: (Word8,Word8,Word8,Word8)
79remoteAddr = (127, 0, 0, 1)
78remoteAddr = (127, 0, 0, 1)
@@ -82,41 +81,49 @@ sender :: PortNumber -> MVar () -> SerialT IO Char
82sender port sem = do
81sender port sem = do
83 _ <- liftIO $ takeMVar sem
82 _ <- liftIO $ takeMVar sem
84 liftIO $ threadDelay 1000000 -- wait for server
83 liftIO $ threadDelay 1000000 -- wait for server
85− S.replicate 1 testDataSource -- SerialT IO String
84+ Stream.replicate 1000 testData -- SerialT IO String
86− & U.unwords UF.fromList -- SerialT IO Char
85+ & Stream.concatMap Stream.fromList -- SerialT IO Char
87− & U.encodeLatin1 -- SerialT IO Word8
86+ & Unicode.encodeLatin1 -- SerialT IO Word8
88 & TCP.transformBytesWith remoteAddr port -- SerialT IO Word8
87 & TCP.transformBytesWith remoteAddr port -- SerialT IO Word8
89− & U.decodeLatin1 -- SerialT IO Char
88+ & Unicode.decodeLatin1 -- SerialT IO Char
90
89
91−execute :: PortNumber -> Int -> (Socket -> IO ()) -> IO [Char]
90+execute :: PortNumber -> Int -> (Socket -> IO ()) -> IO (SerialT IO Char)
92execute port size handler = do
91execute port size handler = do
93 sem <- newEmptyMVar
92 sem <- newEmptyMVar
94 tid <- forkIO $ server port sem handler
93 tid <- forkIO $ server port sem handler
95− lst <- sender port sem
94+ let lst = sender port sem
96− & S.take size
95+ & Stream.take size
97− & S.toList
98− killThread tid
96+ & Stream.finally (killThread tid)
99 return $ lst
97 return $ lst
100
98
101validateWithBufferOf :: Property
99validateWithBufferOf :: Property
102validateWithBufferOf = monadicIO $ do
100validateWithBufferOf = monadicIO $ do
101+ res <- run $ do
103− ls2 <- run $ execute 8000 45000 handlerwithbuffer
102+ ls2 <- execute 8000 45000 handlerwithbuffer
104− assert (testDataSource == ls2)
103+ Stream.eqBy (==) (Stream.fromList testDataSource) ls2
104+ assert res
105
105
106validateRW :: Property
106validateRW :: Property
107validateRW = monadicIO $ do
107validateRW = monadicIO $ do
108+ res <- run $ do
108− ls2 <- run $ execute 8001 A.defaultChunkSize handlerRW
109+ ls2 <- execute 8001 Array.defaultChunkSize handlerRW
109− assert (take A.defaultChunkSize testDataSource == ls2)
110+ let dataChunk = take Array.defaultChunkSize testDataSource
111+ Stream.eqBy (==) (Stream.fromList dataChunk) ls2
112+ assert res
110
113
111validateChunks :: Property
114validateChunks :: Property
112validateChunks = monadicIO $ do
115validateChunks = monadicIO $ do
116+ res <- run $ do
113− ls2 <- run $ execute 8002 45000 handlerChunks
117+ ls2 <- execute 8002 45000 handlerChunks
114− assert (testDataSource == ls2)
118+ Stream.eqBy (==) (Stream.fromList testDataSource) ls2
119+ assert res
115
120
116validateChunksWithBufferOf :: Property
121validateChunksWithBufferOf :: Property
117validateChunksWithBufferOf = monadicIO $ do
122validateChunksWithBufferOf = monadicIO $ do
123+ res <- run $ do
118− ls2 <- run $ execute 8003 45000 handlerChunksWithBuffer
124+ ls2 <- execute 8003 45000 handlerChunksWithBuffer
119− assert (testDataSource == ls2)
125+ Stream.eqBy (==) (Stream.fromList testDataSource) ls2
126+ assert res
120
127
121main :: IO ()
128main :: IO ()
122main = hspec $ do
129main = hspec $ do
test/Streamly/Test/Unicode/Stream.hs+15−16
@@ -86,23 +86,23 @@ propASCIIToLatin1 =
86
86
87propUnicodeToLatin1 :: Property
87propUnicodeToLatin1 :: Property
88propUnicodeToLatin1 =
88propUnicodeToLatin1 =
89− monadicIO $ do
89+ monadicIO $ do
90− let wrds =
90+ let wrds =
91− SS.decodeLatin1
91+ SS.decodeLatin1
92− $ SS.encodeLatin1
92+ $ SS.encodeLatin1
93− $ S.fromList unicodeTestData
93+ $ S.fromList unicodeTestData
94− lst <- run $ S.toList wrds
94+ lst <- run $ S.toList wrds
95− assert (latin1TestData == lst)
95+ assert (latin1TestData == lst)
96
96
97propUnicodeToLatin1' :: Property
97propUnicodeToLatin1' :: Property
98propUnicodeToLatin1' =
98propUnicodeToLatin1' =
99− monadicIO $ do
99+ monadicIO $ do
100− let wrds =
100+ let wrds =
101− SS.decodeLatin1
101+ SS.decodeLatin1
102− $ SS.encodeLatin1'
102+ $ SS.encodeLatin1'
103− $ S.fromList unicodeTestData
103+ $ S.fromList unicodeTestData
104− lst <- run $ S.toList wrds
104+ lst <- run $ S.toList wrds
105− assert (latin1TestData == lst)
105+ assert (latin1TestData == lst)
106
106
107testLines :: Property
107testLines :: Property
108testLines =
108testLines =
@@ -167,7 +167,7 @@ main = H.hspec
167 prop "decodeUtf8Arrays . encodeUtf8' == id"
167 prop "decodeUtf8Arrays . encodeUtf8' == id"
168 propDecodeEncodeIdArrays
168 propDecodeEncodeIdArrays
169 prop "Streamly.Data.String.lines == Prelude.lines" testLines
169 prop "Streamly.Data.String.lines == Prelude.lines" testLines
170− prop "Arrays Streamly.Data.String.lines == Prelude.lines"
170+ prop "Arrays Streamly.Data.String.lines == Prelude.lines"
171 testLinesArray
171 testLinesArray
172 prop "Streamly.Data.String.words == Prelude.words" testWords
172 prop "Streamly.Data.String.words == Prelude.words" testWords
173 prop
173 prop
@@ -181,4 +181,3 @@ main = H.hspec
181 prop "ASCII to Latin1" propASCIIToLatin1
181 prop "ASCII to Latin1" propASCIIToLatin1
182 prop "Unicode to Latin1" propUnicodeToLatin1
182 prop "Unicode to Latin1" propUnicodeToLatin1
183 prop "Unicode to Latin1'" $ expectFailure propUnicodeToLatin1'
183 prop "Unicode to Latin1'" $ expectFailure propUnicodeToLatin1'
184−
test/streamly-tests.cabal+11
@@ -128,6 +128,7 @@ common test-dependencies
128 , directory >= 1.2.2 && < 1.4
128 , directory >= 1.2.2 && < 1.4
129 , filepath >= 1.4.1 && < 1.5
129 , filepath >= 1.4.1 && < 1.5
130 , temporary >= 1.3 && < 1.4
130 , temporary >= 1.3 && < 1.4
131+ , network >= 3.1 && < 3.2
131
132
132 if flag(fusion-plugin) && !impl(ghcjs) && !impl(ghc < 8.6)
133 if flag(fusion-plugin) && !impl(ghcjs) && !impl(ghc < 8.6)
133 build-depends:
134 build-depends:
@@ -336,3 +337,13 @@ test-suite FileSystem.Handle
336 type: exitcode-stdio-1.0
337 type: exitcode-stdio-1.0
337 main-is: Streamly/Test/FileSystem/Handle.hs
338 main-is: Streamly/Test/FileSystem/Handle.hs
338 ghc-options: -main-is Streamly.Test.FileSystem.Handle.main
339 ghc-options: -main-is Streamly.Test.FileSystem.Handle.main
340+
341+test-suite Network.Socket
342+ import: test-options
343+ type: exitcode-stdio-1.0
344+ main-is: Streamly/Test/Network/Socket.hs
345+
346+test-suite Inet.TCP
347+ import: test-options
348+ type: exitcode-stdio-1.0
349+ main-is: Streamly/Test/Network/Inet/TCP.hs