File: SendFileSpec.hs

package info (click to toggle)
haskell-warp 3.4.9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 456 kB
  • sloc: haskell: 4,873; makefile: 10
file content (120 lines) | stat: -rw-r--r-- 4,528 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
{-# LANGUAGE OverloadedStrings #-}

module SendFileSpec where

import Control.Monad (when)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import Network.Wai.Handler.Warp.Buffer
import Network.Wai.Handler.Warp.SendFile
import Network.Wai.Handler.Warp.Types
import System.Directory
import System.Exit
import qualified System.IO as IO
import System.Process (system)
import Test.Hspec
import Control.Exception

main :: IO ()
main = hspec spec

spec :: Spec
spec = do
    describe "packHeader" $ do
        it "returns how much the buffer is consumed (1)" $
            tryPackHeader 10 ["foo"] `shouldReturn` 3
        it "returns how much the buffer is consumed (2)" $
            tryPackHeader 10 ["foo", "bar"] `shouldReturn` 6
        it "returns how much the buffer is consumed (3)" $
            tryPackHeader 10 ["0123456789"] `shouldReturn` 0
        it "returns how much the buffer is consumed (4)" $
            tryPackHeader 10 ["01234", "56789"] `shouldReturn` 0
        it "returns how much the buffer is consumed (5)" $
            tryPackHeader 10 ["01234567890", "12"] `shouldReturn` 3
        it "returns how much the buffer is consumed (6)" $
            tryPackHeader 10 ["012345678901234567890123456789012", "34"] `shouldReturn` 5

        it "sends headers correctly (1)" $
            tryPackHeader2 10 ["foo"] "" `shouldReturn` True
        it "sends headers correctly (2)" $
            tryPackHeader2 10 ["foo", "bar"] "" `shouldReturn` True
        it "sends headers correctly (3)" $
            tryPackHeader2 10 ["0123456789"] "0123456789" `shouldReturn` True
        it "sends headers correctly (4)" $
            tryPackHeader2 10 ["01234", "56789"] "0123456789" `shouldReturn` True
        it "sends headers correctly (5)" $
            tryPackHeader2 10 ["01234567890", "12"] "0123456789" `shouldReturn` True
        it "sends headers correctly (6)" $
            tryPackHeader2
                10
                ["012345678901234567890123456789012", "34"]
                "012345678901234567890123456789"
                `shouldReturn` True

    describe "readSendFile" $ do
        it "sends a file correctly (1)" $
            tryReadSendFile 10 0 1474 ["foo"] `shouldReturn` ExitSuccess
        it "sends a file correctly (2)" $
            tryReadSendFile 10 0 1474 ["012345678", "901234"] `shouldReturn` ExitSuccess
        it "sends a file correctly (3)" $
            tryReadSendFile 10 20 100 ["012345678", "901234"] `shouldReturn` ExitSuccess

tryPackHeader :: Int -> [ByteString] -> IO Int
tryPackHeader siz hdrs = bracket (allocateBuffer siz) freeBuffer $ \buf ->
    packHeader buf siz send hook hdrs 0
  where
    send _ = return ()
    hook = return ()

tryPackHeader2 :: Int -> [ByteString] -> ByteString -> IO Bool
tryPackHeader2 siz hdrs ans = bracket setup teardown $ \buf -> do
    _ <- packHeader buf siz send hook hdrs 0
    checkFile outputFile ans
  where
    setup = allocateBuffer siz
    teardown buf = freeBuffer buf >> removeFileIfExists outputFile
    outputFile = "tempfile"
    send = BS.appendFile outputFile
    hook = return ()

tryReadSendFile :: Int -> Integer -> Integer -> [ByteString] -> IO ExitCode
tryReadSendFile siz off len hdrs = bracket setup teardown $ \buf -> do
    mapM_ (BS.appendFile expectedFile) hdrs
    copyfile inputFile expectedFile off len
    readSendFile buf siz send fid off len hook hdrs
    compareFiles expectedFile outputFile
  where
    hook = return ()
    setup = allocateBuffer siz
    teardown buf = do
        freeBuffer buf
        removeFileIfExists outputFile
        removeFileIfExists expectedFile
    inputFile = "test/inputFile"
    outputFile = "outputFile"
    expectedFile = "expectedFile"
    fid = FileId inputFile Nothing
    send = BS.appendFile outputFile

checkFile :: FilePath -> ByteString -> IO Bool
checkFile path bs = do
    exist <- doesFileExist path
    if exist
        then do
            bs' <- BS.readFile path
            return $ bs == bs'
        else return $ bs == ""

compareFiles :: FilePath -> FilePath -> IO ExitCode
compareFiles file1 file2 = system $ "cmp -s " ++ file1 ++ " " ++ file2

copyfile :: FilePath -> FilePath -> Integer -> Integer -> IO ()
copyfile src dst off len =
    IO.withBinaryFile src IO.ReadMode $ \h -> do
        IO.hSeek h IO.AbsoluteSeek off
        BS.hGet h (fromIntegral len) >>= BS.appendFile dst

removeFileIfExists :: FilePath -> IO ()
removeFileIfExists file = do
    exist <- doesFileExist file
    when exist $ removeFile file