forked from commercialhaskell/stack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVerifiedSpec.hs
More file actions
132 lines (114 loc) · 5.28 KB
/
VerifiedSpec.hs
File metadata and controls
132 lines (114 loc) · 5.28 KB
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
121
122
123
124
125
126
127
128
129
130
131
132
{-# LANGUAGE NoImplicitPrelude #-}
module Network.HTTP.Download.VerifiedSpec where
import Control.Retry (limitRetries)
import Crypto.Hash
import Network.HTTP.Client.Conduit
import Network.HTTP.Download.Verified
import Path
import Path.IO hiding (withSystemTempDir)
import Stack.Prelude
import Stack.Types.Runner
import System.IO (writeFile, readFile)
import Test.Hspec
-- TODO: share across test files
withTempDir' :: (Path Abs Dir -> IO a) -> IO a
withTempDir' = withSystemTempDir "NHD_VerifiedSpec"
-- | An example path to download the exampleReq.
getExamplePath :: Path Abs Dir -> IO (Path Abs File)
getExamplePath dir = do
file <- parseRelFile "cabal-install-1.22.4.0.tar.gz"
return (dir </> file)
-- | An example DownloadRequest that uses a SHA1
exampleReq :: DownloadRequest
exampleReq = fromMaybe (error "exampleReq") $ do
let req = parseRequest_ "http://download.fpcomplete.com/stackage-cli/linux64/cabal-install-1.22.4.0.tar.gz"
return DownloadRequest
{ drRequest = req
, drHashChecks = [exampleHashCheck]
, drLengthCheck = Just exampleLengthCheck
, drRetryPolicy = limitRetries 1
}
exampleHashCheck :: HashCheck
exampleHashCheck = HashCheck
{ hashCheckAlgorithm = SHA1
, hashCheckHexDigest = CheckHexDigestString "b98eea96d321cdeed83a201c192dac116e786ec2"
}
exampleLengthCheck :: LengthCheck
exampleLengthCheck = 302513
-- | The wrong ContentLength for exampleReq
exampleWrongContentLength :: Int
exampleWrongContentLength = 302512
-- | The wrong SHA1 digest for exampleReq
exampleWrongDigest :: CheckHexDigest
exampleWrongDigest = CheckHexDigestString "b98eea96d321cdeed83a201c192dac116e786ec3"
exampleWrongContent :: String
exampleWrongContent = "example wrong content"
isWrongContentLength :: VerifiedDownloadException -> Bool
isWrongContentLength WrongContentLength{} = True
isWrongContentLength _ = False
isWrongDigest :: VerifiedDownloadException -> Bool
isWrongDigest WrongDigest{} = True
isWrongDigest _ = False
spec :: Spec
spec = do
let exampleProgressHook _ = return ()
describe "verifiedDownload" $ do
let run func = withRunner LevelError True True ColorNever Nothing False
$ \runner -> runRIO runner func
-- Preconditions:
-- * the exampleReq server is running
-- * the test runner has working internet access to it
it "downloads the file correctly" $ withTempDir' $ \dir -> do
examplePath <- getExamplePath dir
doesFileExist examplePath `shouldReturn` False
let go = run $ verifiedDownload exampleReq examplePath exampleProgressHook
go `shouldReturn` True
doesFileExist examplePath `shouldReturn` True
it "is idempotent, and doesn't redownload unnecessarily" $ withTempDir' $ \dir -> do
examplePath <- getExamplePath dir
doesFileExist examplePath `shouldReturn` False
let go = run $ verifiedDownload exampleReq examplePath exampleProgressHook
go `shouldReturn` True
doesFileExist examplePath `shouldReturn` True
go `shouldReturn` False
doesFileExist examplePath `shouldReturn` True
-- https://github.com/commercialhaskell/stack/issues/372
it "does redownload when the destination file is wrong" $ withTempDir' $ \dir -> do
examplePath <- getExamplePath dir
let exampleFilePath = toFilePath examplePath
writeFile exampleFilePath exampleWrongContent
doesFileExist examplePath `shouldReturn` True
readFile exampleFilePath `shouldReturn` exampleWrongContent
let go = run $ verifiedDownload exampleReq examplePath exampleProgressHook
go `shouldReturn` True
doesFileExist examplePath `shouldReturn` True
readFile exampleFilePath `shouldNotReturn` exampleWrongContent
it "rejects incorrect content length" $ withTempDir' $ \dir -> do
examplePath <- getExamplePath dir
let wrongContentLengthReq = exampleReq
{ drLengthCheck = Just exampleWrongContentLength
}
let go = run $ verifiedDownload wrongContentLengthReq examplePath exampleProgressHook
go `shouldThrow` isWrongContentLength
doesFileExist examplePath `shouldReturn` False
it "rejects incorrect digest" $ withTempDir' $ \dir -> do
examplePath <- getExamplePath dir
let wrongHashCheck = exampleHashCheck { hashCheckHexDigest = exampleWrongDigest }
let wrongDigestReq = exampleReq { drHashChecks = [wrongHashCheck] }
let go = run $ verifiedDownload wrongDigestReq examplePath exampleProgressHook
go `shouldThrow` isWrongDigest
doesFileExist examplePath `shouldReturn` False
-- https://github.com/commercialhaskell/stack/issues/240
it "can download hackage tarballs" $ withTempDir' $ \dir -> do
dest <- (dir </>) <$> parseRelFile "acme-missiles-0.3.tar.gz"
let req = parseRequest_ "http://hackage.haskell.org/package/acme-missiles-0.3/acme-missiles-0.3.tar.gz"
let dReq = DownloadRequest
{ drRequest = req
, drHashChecks = []
, drLengthCheck = Nothing
, drRetryPolicy = limitRetries 1
}
let go = run $ verifiedDownload dReq dest exampleProgressHook
doesFileExist dest `shouldReturn` False
go `shouldReturn` True
doesFileExist dest `shouldReturn` True