import Control.Concurrent import Control.Concurrent.MVar import Control.Exception import Control.Monad import Network.NNTP hiding (Connection) import Network.NNTP.RFC977 import Network.Socket import Test.HUnit import System.IO main = runTestTT tests >>= const (return ()) where tests = TestList [heloTest] heloTest = TestLabel "helo" (TestList [TestCase posting, TestCase not_posting]) where posting = initConnection True >>= uncurry quitConnection not_posting = initConnection False >>= uncurry quitConnection initConnection :: Bool -> IO (Connection, Handle) initConnection p = do (serverHandle, clientHandle) <- createPipe if p then hPutStr serverHandle "200 Test Helo Server\r\n" else hPutStr serverHandle "201 Test Helo Server\r\n" (nntp, posting) <- joinToHandle clientHandle if p then assertBool "Posting reported as not-allowed" p else assertBool "Posting reported as allowed" (not p) return (nntp, serverHandle) quitConnection :: Connection -> Handle -> IO () quitConnection c h = do hPutStr h "205 .\r\n" disconnect c hGetLine h >>= ("QUIT\r"@?=) createPipe :: IO (Handle, Handle) createPipe = do ai <- head `fmap` getAddrInfo (localhostHints) (Just "localhost") Nothing serverSocket <- socket AF_INET Stream 0 clientSocket <- socket AF_INET Stream 0 bindSocket serverSocket (addrAddress ai) listen serverSocket 1 connect clientSocket =<< getSocketName serverSocket (serverSocketConn, _) <- accept serverSocket serverHandle <- socketToHandle serverSocketConn ReadWriteMode clientHandle <- socketToHandle clientSocket ReadWriteMode hSetBuffering serverHandle LineBuffering hSetBuffering clientHandle LineBuffering return (serverHandle, clientHandle) localhostHints = Just $ AddrInfo { addrFlags = [AI_ADDRCONFIG,AI_PASSIVE], addrFamily = AF_INET, addrSocketType = Stream, addrProtocol = defaultProtocol, addrAddress = undefined, addrCanonName = undefined }