11{-# LANGUAGE OverloadedStrings #-}
2+ {-# LANGUAGE RecordWildCards #-}
3+ {-# LANGUAGE LambdaCase #-}
24module Main ( main ) where
35
46import Codec.Archive
@@ -7,6 +9,7 @@ import Codec.Archive.Test
79import qualified Data.ByteString as BS
810import qualified Data.ByteString.Lazy as BSL
911import Data.Either (isRight)
12+ import Data.List (uncons)
1013import Data.Foldable (traverse_)
1114import System.Directory (doesDirectoryExist, listDirectory)
1215import System.FilePath ((</>))
@@ -19,6 +22,11 @@ import Test.Hspec.Core.Runner
1922#endif
2023import Test.Hspec
2124
25+ import qualified Data.ByteString.Base16 as B16
26+ import qualified Crypto.Hash.SHA256 as SHA256
27+ import qualified Data.Text.Encoding as E
28+ import qualified Data.Text as T
29+
2230testFp :: FilePath -> Spec
2331testFp fp = it ("sucessfully unpacks/packs (" ++ fp ++ ")") $
2432 roundtrip fp >>= (`shouldSatisfy` isRight)
@@ -58,14 +66,28 @@ repack packer str fp = it ("should repack (" ++ str ++ ")") $ do
5866bsValid :: Either a BSL.ByteString -> Bool
5967bsValid = \x -> case x of { Left{} -> False; Right b -> not $ BSL.null b }
6068
69+ testArchiveContentChecksum :: FilePath -- ^ archive
70+ -> FilePath -- ^ file inside archive
71+ -> String -- ^ base64 encoded sha256sum
72+ -> Spec
73+ testArchiveContentChecksum archive file sha = it ("Verify checksum of " <> file <> " in archive " <> archive) $ do
74+ entries' <- runArchiveM (readArchiveFile archive)
75+ entries <- either (ioError . userError . show) pure $ entries'
76+ let cabal_exe = uncons . fmap content . filter (\Entry{..} -> filepath == file) $ entries
77+ c <- case cabal_exe of
78+ (Just (NormalFile c, _)) -> pure c
79+ _ -> ioError $ userError $ "Could not find file " <> file <> " in archive " <> archive
80+ digest <- either (ioError . userError . show) pure . E.decodeUtf8' . B16.encode . SHA256.hash $ c
81+ digest `shouldBe` T.pack sha
82+
6183main :: IO ()
6284main = do
6385
6486 dir <- doesDirectoryExist "test/data"
6587 tarballs <- if dir then listDirectory "test/data" else pure []
6688 let tarPaths = ("test/data" </>) <$> tarballs
6789
68- hspec' $
90+ hspec' $ do
6991 describe "roundtrip" $ do
7092
7193 traverse_ testFp tarPaths
@@ -113,6 +135,13 @@ main = do
113135 [ stripOwnership (simpleFile "a.txt" (NormalFile "text")) ]
114136 xcontext "having entry without timestamp" . itPacksUnpacks $
115137 [ stripTime (simpleFile "a.txt" (NormalFile "text")) ]
138+
139+ describe "checksums" $ do
140+ testArchiveContentChecksum
141+ "test/data/cabal-install-3.14.2.0-x86_64-mingw64.zip"
142+ "cabal.exe"
143+ "4b43a1d5a6bba82bc703db6b8ebd98b0712b2269ca7799a0f0bf6df5b5c683d0"
144+
116145 where
117146#ifdef mingw32_HOST_OS
118147 hspec' spec = getArgs >>= readConfig defaultConfig >>= (\c -> withArgs [] . runSpec spec $ c{ configConcurrentJobs = Nothing }) >>= evaluateSummary
0 commit comments