{-# LANGUAGE OverloadedStrings #-} module Main where import qualified Data.ByteString as B import Control.Concurrent (forkIO) import Control.Concurrent.MVar import Control.Monad import Control.Monad.Trans.Resource import Control.Monad.IO.Class (liftIO) import Network.Connection import Data.Conduit import qualified Data.Conduit.List as CL import qualified Network.Connection.Conduit as CCon import Network.Socket hiding (send, sendTo, recv, recvFrom) import Network.Socket.ByteString import Test.HUnit import Test.Framework as TF (defaultMain, testGroup, Test) import Test.Framework.Providers.HUnit main :: IO () main = defaultMain tests setupSocket :: IO (Socket, PortNumber) setupSocket = do let addr = SockAddrInet aNY_PORT iNADDR_ANY s <- socket AF_INET Stream defaultProtocol bind s addr listen s 5 p <- socketPort s return (s, p) testSinkConnection :: Assertion testSinkConnection = do (s, p) <- setupSocket let input = ["abcde", "fghij", "klmno"] mOutput <- newEmptyMVar _ <- forkIO $ do (s', _) <- accept s let recvAll l = do b <- recv s' 4096 if b == B.empty then return l else recvAll (l ++ [b]) o <- recvAll [] putMVar mOutput o close s' runResourceT $ do ctx <- liftIO initConnectionContext c <- CCon.connectTo ctx (ConnectionParams "localhost" p Nothing Nothing) CL.sourceList input $$ CCon.sinkConnection c output <- takeMVar mOutput B.concat input @=? B.concat output close s testSourceConnection :: Assertion testSourceConnection = do (s, p) <- setupSocket let input = ["abcde", "fghij", "klmno"] _ <- forkIO $ do (s', _) <- accept s forM_ input (send s') close s' output <- runResourceT $ do ctx <- liftIO initConnectionContext c <- CCon.connectTo ctx (ConnectionParams "localhost" p Nothing Nothing) CCon.sourceConnection c $$ CL.consume B.concat input @=? B.concat output close s tests :: [TF.Test] tests = [ testGroup "HUnit tests Network.Connection.Conduit" [ testCase "sourceConnection" testSourceConnection , testCase "sinkConnection" testSinkConnection ] ]