1 module UnitTests
.Distribution
.Client
.Store
(tests
) where
3 -- import Control.Monad
4 -- import Control.Concurrent (forkIO, threadDelay)
5 -- import Control.Concurrent.MVar
6 import qualified Data
.Set
as Set
7 import System
.Directory
10 -- import System.Random
12 import Distribution
.Compiler
(CompilerFlavor
(..), CompilerId
(..))
13 import Distribution
.Package
(UnitId
, mkUnitId
)
14 import Distribution
.Simple
.Utils
(withTempDirectory
)
15 import Distribution
.Verbosity
(Verbosity
, silent
)
16 import Distribution
.Version
(mkVersion
)
18 import Distribution
.Client
.RebuildMonad
19 import Distribution
.Client
.Store
22 import Test
.Tasty
.HUnit
26 [ testCase
"list content empty" testListEmpty
27 , testCase
"install serial" testInstallSerial
28 -- , testCase "install parallel" testInstallParallel
29 -- TODO: figure out some way to do a parallel test, see issue below
32 testListEmpty
:: Assertion
34 withTempDirectory verbosity
"." "store-" $ \tmp
-> do
35 let storeDirLayout
= defaultStoreDirLayout
(tmp
</> "store")
37 assertStoreEntryExists storeDirLayout compid unitid
False
38 assertStoreContent tmp storeDirLayout compid Set
.empty
40 compid
= CompilerId GHC
(mkVersion
[1, 0])
41 unitid
= mkUnitId
"foo-1.0-xyz"
43 testInstallSerial
:: Assertion
45 withTempDirectory verbosity
"." "store-" $ \tmp
-> do
46 let storeDirLayout
= defaultStoreDirLayout
(tmp
</> "store")
47 copyFiles file content dir
= do
48 -- we copy into a prefix inside the tmp dir and return the prefix
49 let destprefix
= dir
</> "prefix"
50 createDirectory destprefix
51 writeFile (destprefix
</> file
) content
52 return (destprefix
, [])
59 (copyFiles
"file1" "content-foo")
68 (copyFiles
"file1" "content-foo")
77 (copyFiles
"file2" "content-bar")
81 let pkgDir
:: UnitId
-> FilePath
82 pkgDir
= storePackageDirectory storeDirLayout compid
83 assertFileEqual
(pkgDir unitid1
</> "file1") "content-foo"
84 assertFileEqual
(pkgDir unitid2
</> "file2") "content-bar"
86 compid
= CompilerId GHC
(mkVersion
[1, 0])
87 unitid1
= mkUnitId
"foo-1.0-xyz"
88 unitid2
= mkUnitId
"bar-2.0-xyz"
91 -- unfortunately a parallel test like the one below is thwarted by the normal
92 -- process-internal file locking. If that locking were not in place then we
93 -- ought to get the blocking behaviour, but due to the normal Handle locking
94 -- it just fails instead.
96 testInstallParallel :: Assertion
98 withTempDirectory verbosity "." "store-" $ \tmp -> do
99 let storeDirLayout = defaultStoreDirLayout (tmp </> "store")
101 sync1 <- newEmptyMVar
102 sync2 <- newEmptyMVar
104 regv <- newMVar (0 :: Int)
108 let copyFiles dir = do
109 delay <- randomRIO (1,100000)
110 writeFile (dir </> "file") (show n)
115 modifyMVar_ regv (return . (+1))
117 o <- newStoreEntry verbosity storeDirLayout
121 | n <- [0..9 :: Int] ]
123 replicateM_ 10 (takeMVar sync1)
124 -- all threads are in the copyFiles action concurrently, release them:
127 outcomes <- replicateM 10 (takeMVar outv)
128 regcount <- readMVar regv
129 let regcount' = length [ () | (_, UseNewStoreEntry) <- outcomes ]
131 assertEqual "num registrations" 1 regcount
132 assertEqual "num registrations" 1 regcount'
134 assertStoreContent tmp storeDirLayout compid (Set.singleton unitid)
136 let pkgDir :: UnitId -> FilePath
137 pkgDir = storePackageDirectory storeDirLayout compid
138 case [ n | (n, UseNewStoreEntry) <- outcomes ] of
139 [n] -> assertFileEqual (pkgDir unitid </> "file") (show n)
140 _ -> assertFailure "impossible"
143 compid = CompilerId GHC (mkVersion [1,0])
144 unitid = mkUnitId "foo-1.0-xyz"
155 -> (FilePath -> IO (FilePath, [FilePath]))
157 -> NewStoreEntryOutcome
167 entries
<- runRebuild tmp
$ getStoreEntries storeDirLayout compid
176 assertEqual
"newStoreEntry outcome" expectedOutcome outcome
177 assertStoreEntryExists storeDirLayout compid unitid
True
178 let expected
= Set
.insert unitid entries
179 assertStoreContent tmp storeDirLayout compid expected
181 assertStoreEntryExists
187 assertStoreEntryExists storeDirLayout compid unitid expected
= do
188 actual
<- doesStoreEntryExist storeDirLayout compid unitid
189 assertEqual
"store entry exists" expected actual
197 assertStoreContent tmp storeDirLayout compid expected
= do
198 actual
<- runRebuild tmp
$ getStoreEntries storeDirLayout compid
199 assertEqual
"store content" actual expected
201 assertFileEqual
:: FilePath -> String -> Assertion
202 assertFileEqual path expected
= do
203 exists
<- doesFileExist path
204 assertBool
("file does not exist:\n" ++ path
) exists
205 actual
<- readFile path
206 assertEqual
("file content for:\n" ++ path
) expected actual
208 verbosity
:: Verbosity