1{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE RecordWildCards #-}
7import qualified Control.Concurrent as C
8import Control.Exception (Exception, SomeException, handle, throwIO)
9import Control.Monad (replicateM, unless, when)
10import qualified Data.Map as Map
11import qualified Data.Set as Set
12import Data.Version (parseVersion, Version (Version))
13import Data.Typeable (Typeable)
16import System.Directory (copyFile, createDirectory,
17 createDirectoryIfMissing, removeFile)
18import System.Exit (ExitCode (ExitSuccess))
19import System.FilePath ((<.>), (</>))
20import System.IO (IOMode (WriteMode, AppendMode),
22import System.Process (readProcess, runProcess, waitForProcess)
23import Text.ParserCombinators.ReadP (readP_to_S)
25runTestSuites :: BuildSettings -> BuildPlan -> IO ()
26runTestSuites settings' bp = do
27 settings <- fixBuildSettings settings'
28 let selected = Map.filterWithKey notSkipped $ bpPackages bp
29 putStrLn "Running test suites"
30 let testdir = "runtests"
32 createDirectory testdir
33 cabalVersion <- getCabalVersion
34 allPass <- parFoldM (testWorkerThreads settings) (runTestSuite cabalVersion settings testdir) (&&) True $ Map.toList selected
35 unless allPass $ error $ "There were failures, please see the logs in " ++ testdir
37 notSkipped p _ = p `Set.notMember` bpSkippedTests bp
39getCabalVersion :: IO CabalVersion
41 output <- readProcess "cabal" ["--numeric-version"] ""
42 case filter (null . snd) $ readP_to_S parseVersion $ filter notCRLF output of
43 (Version (x:y:_) _, _):_ -> return $ CabalVersion x y
44 _ -> error $ "Invalid cabal version: " ++ show output
50parFoldM :: Int -- ^ number of threads
56parFoldM threadCount0 f g a0 bs0 = do
59 signal <- C.newEmptyMVar
60 tids <- replicateM threadCount0 $ C.forkIO $ worker ma mbs signal
61 wait threadCount0 signal tids
64 worker ma mbs signal =
66 (C.putMVar signal . Just)
67 (loop >> C.putMVar signal Nothing)
70 mb <- C.modifyMVar mbs $ \bs -> return $
73 b:bs' -> (bs', Just b)
78 C.modifyMVar_ ma $ \a -> return $! g a c
80 wait threadCount signal tids
81 | threadCount == 0 = return ()
83 me <- C.takeMVar signal
85 Nothing -> wait (threadCount - 1) signal tids
87 mapM_ C.killThread tids
88 throwIO (e :: SomeException)
90data TestException = TestException
91 deriving (Show, Typeable)
92instance Exception TestException
94data CabalVersion = CabalVersion Int Int
95 deriving (Eq, Ord, Show)
97runTestSuite :: CabalVersion
100 -> (PackageName, SelectedPackageInfo)
102runTestSuite cabalVersion settings testdir (packageName, SelectedPackageInfo {..}) = do
103 -- Set up a new environment that includes the sandboxed bin folder in PATH.
104 env' <- getModifiedEnv settings
105 let menv = Just $ addSandbox env'
106 addSandbox = (("HASKELL_PACKAGE_SANDBOX", packageDir settings):)
108 let run cmd args wdir handle' = do
109 ph <- runProcess cmd args (Just wdir) menv Nothing (Just handle') (Just handle')
110 ec <- waitForProcess ph
111 unless (ec == ExitSuccess) $ throwIO TestException
113 passed <- handle (\TestException -> return False) $ do
114 package' <- replaceTarball (tarballDir settings) package
115 getHandle WriteMode $ run "cabal" ["unpack", package'] testdir
116 case cabalFileDir settings of
119 let PackageName name = packageName
120 basename = name ++ ".cabal"
121 src = dir </> basename
122 dst = cfd </> basename
123 createDirectoryIfMissing True cfd
125 getHandle AppendMode $ run "cabal" (addCabalArgs settings BSTest ["configure", "--enable-tests"]) dir
126 when spiHasTests $ do
127 getHandle AppendMode $ run "cabal" ["build"] dir
128 getHandle AppendMode $ run "cabal" (concat
130 , if cabalVersion >= CabalVersion 1 20
131 then ["--show-details=streaming"] -- FIXME temporary workaround for https://github.com/haskell/cabal/issues/1810
134 when (buildDocs settings) $
135 getHandle AppendMode $ run "cabal" ["haddock"] dir
137 let expectedFailure = packageName `Set.member` expectedFailuresBuild settings
141 when expectedFailure $ putStrLn $ " " ++ package ++ " passed, but I didn't think it would."
142 else unless expectedFailure $ putStrLn $ concat
143 [ "Test suite failed: "
146 , unMaintainer spiMaintainer
147 , githubMentions spiGithubUser
151 return $! passed || expectedFailure
153 logfile = testdir </> package <.> "log"
154 dir = testdir </> package
155 getHandle mode = withBinaryFile logfile mode
156 package = packageVersionString (packageName, spiVersion)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list