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
.Package
(UnitId
, mkUnitId
)
13 import Distribution
.Simple
.Compiler
(AbiTag
(..), Compiler
(..), CompilerFlavor
(..), CompilerId
(..))
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 compiler unitid
False
38 assertStoreContent tmp storeDirLayout compiler Set
.empty
43 { compilerId
= CompilerId GHC
(mkVersion
[1, 0])
44 , compilerAbiTag
= NoAbiTag
46 , compilerLanguages
= []
47 , compilerExtensions
= []
48 , compilerProperties
= mempty
51 unitid
= mkUnitId
"foo-1.0-xyz"
53 testInstallSerial
:: Assertion
55 withTempDirectory verbosity
"." "store-" $ \tmp
-> do
56 let storeDirLayout
= defaultStoreDirLayout
(tmp
</> "store")
57 copyFiles file content dir
= do
58 -- we copy into a prefix inside the tmp dir and return the prefix
59 let destprefix
= dir
</> "prefix"
60 createDirectory destprefix
61 writeFile (destprefix
</> file
) content
62 return (destprefix
, [])
69 (copyFiles
"file1" "content-foo")
78 (copyFiles
"file1" "content-foo")
87 (copyFiles
"file2" "content-bar")
91 let pkgDir
:: UnitId
-> FilePath
92 pkgDir
= storePackageDirectory storeDirLayout compiler
93 assertFileEqual
(pkgDir unitid1
</> "file1") "content-foo"
94 assertFileEqual
(pkgDir unitid2
</> "file2") "content-bar"
99 { compilerId
= CompilerId GHC
(mkVersion
[1, 0])
100 , compilerAbiTag
= NoAbiTag
101 , compilerCompat
= []
102 , compilerLanguages
= []
103 , compilerExtensions
= []
104 , compilerProperties
= mempty
107 unitid1
= mkUnitId
"foo-1.0-xyz"
108 unitid2
= mkUnitId
"bar-2.0-xyz"
111 -- unfortunately a parallel test like the one below is thwarted by the normal
112 -- process-internal file locking. If that locking were not in place then we
113 -- ought to get the blocking behaviour, but due to the normal Handle locking
114 -- it just fails instead.
116 testInstallParallel :: Assertion
117 testInstallParallel =
118 withTempDirectory verbosity "." "store-" $ \tmp -> do
119 let storeDirLayout = defaultStoreDirLayout (tmp </> "store")
121 sync1 <- newEmptyMVar
122 sync2 <- newEmptyMVar
124 regv <- newMVar (0 :: Int)
128 let copyFiles dir = do
129 delay <- randomRIO (1,100000)
130 writeFile (dir </> "file") (show n)
135 modifyMVar_ regv (return . (+1))
137 o <- newStoreEntry verbosity storeDirLayout
141 | n <- [0..9 :: Int] ]
143 replicateM_ 10 (takeMVar sync1)
144 -- all threads are in the copyFiles action concurrently, release them:
147 outcomes <- replicateM 10 (takeMVar outv)
148 regcount <- readMVar regv
149 let regcount' = length [ () | (_, UseNewStoreEntry) <- outcomes ]
151 assertEqual "num registrations" 1 regcount
152 assertEqual "num registrations" 1 regcount'
154 assertStoreContent tmp storeDirLayout compid (Set.singleton unitid)
156 let pkgDir :: UnitId -> FilePath
157 pkgDir = storePackageDirectory storeDirLayout compid
158 case [ n | (n, UseNewStoreEntry) <- outcomes ] of
159 [n] -> assertFileEqual (pkgDir unitid </> "file") (show n)
160 _ -> assertFailure "impossible"
163 compid = CompilerId GHC (mkVersion [1,0])
164 unitid = mkUnitId "foo-1.0-xyz"
175 -> (FilePath -> IO (FilePath, [FilePath]))
177 -> NewStoreEntryOutcome
187 entries
<- runRebuild tmp
$ getStoreEntries storeDirLayout compiler
196 assertEqual
"newStoreEntry outcome" expectedOutcome outcome
197 assertStoreEntryExists storeDirLayout compiler unitid
True
198 let expected
= Set
.insert unitid entries
199 assertStoreContent tmp storeDirLayout compiler expected
201 assertStoreEntryExists
207 assertStoreEntryExists storeDirLayout compiler unitid expected
= do
208 actual
<- doesStoreEntryExist storeDirLayout compiler unitid
209 assertEqual
"store entry exists" expected actual
217 assertStoreContent tmp storeDirLayout compiler expected
= do
218 actual
<- runRebuild tmp
$ getStoreEntries storeDirLayout compiler
219 assertEqual
"store content" actual expected
221 assertFileEqual
:: FilePath -> String -> Assertion
222 assertFileEqual path expected
= do
223 exists
<- doesFileExist path
224 assertBool
("file does not exist:\n" ++ path
) exists
225 actual
<- readFile path
226 assertEqual
("file content for:\n" ++ path
) expected actual
228 verbosity
:: Verbosity