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.Typeable (Typeable)
15import System.Directory (copyFile, createDirectory,
16 createDirectoryIfMissing, removeFile)
17import System.Exit (ExitCode (ExitSuccess))
18import System.FilePath ((<.>), (</>))
19import System.IO (IOMode (WriteMode, AppendMode),
21import System.Process (runProcess, waitForProcess)
23runTestSuites :: BuildSettings -> BuildPlan -> IO ()
24runTestSuites settings' bp = do
25 settings <- fixBuildSettings settings'
26 let selected = Map.filterWithKey notSkipped $ bpPackages bp
27 putStrLn "Running test suites"
28 let testdir = "runtests"
30 createDirectory testdir
31 allPass <- parFoldM (testWorkerThreads settings) (runTestSuite settings testdir) (&&) True $ Map.toList selected
32 unless allPass $ error $ "There were failures, please see the logs in " ++ testdir
34 notSkipped p _ = p `Set.notMember` bpSkippedTests bp
36parFoldM :: Int -- ^ number of threads
42parFoldM threadCount0 f g a0 bs0 = do
45 signal <- C.newEmptyMVar
46 tids <- replicateM threadCount0 $ C.forkIO $ worker ma mbs signal
47 wait threadCount0 signal tids
50 worker ma mbs signal =
52 (C.putMVar signal . Just)
53 (loop >> C.putMVar signal Nothing)
56 mb <- C.modifyMVar mbs $ \bs -> return $
59 b:bs' -> (bs', Just b)
64 C.modifyMVar_ ma $ \a -> return $! g a c
66 wait threadCount signal tids
67 | threadCount == 0 = return ()
69 me <- C.takeMVar signal
71 Nothing -> wait (threadCount - 1) signal tids
73 mapM_ C.killThread tids
74 throwIO (e :: SomeException)
76data TestException = TestException
77 deriving (Show, Typeable)
78instance Exception TestException
80runTestSuite :: BuildSettings
82 -> (PackageName, SelectedPackageInfo)
84runTestSuite settings testdir (packageName, SelectedPackageInfo {..}) = do
85 -- Set up a new environment that includes the sandboxed bin folder in PATH.
86 env' <- getModifiedEnv settings
88 = Just $ (if addGPP then (("GHC_PACKAGE_PATH", packageDir settings ++ ":"):) else id)
90 -- FIXME why do these packages require the workaround?
91 bannedSandboxVar = map PackageName $ words "wai-logger warp"
93 | packageName `elem` bannedSandboxVar = id
94 | otherwise = (("HASKELL_PACKAGE_SANDBOX", packageDir settings):)
96 let runGen addGPP cmd args wdir handle' = do
97 ph <- runProcess cmd args (Just wdir) (menv addGPP) Nothing (Just handle') (Just handle')
98 ec <- waitForProcess ph
99 unless (ec == ExitSuccess) $ throwIO TestException
101 let run = runGen False
102 runGhcPackagePath = runGen True
104 passed <- handle (\TestException -> return False) $ do
105 package' <- replaceTarball (tarballDir settings) package
106 getHandle WriteMode $ run "cabal" ["unpack", package'] testdir
107 case cabalFileDir settings of
110 let PackageName name = packageName
111 basename = name ++ ".cabal"
112 src = dir </> basename
113 dst = cfd </> basename
114 createDirectoryIfMissing True cfd
116 getHandle AppendMode $ run "cabal" (addCabalArgs settings BSTest ["configure", "--enable-tests"]) dir
117 when spiHasTests $ do
118 getHandle AppendMode $ run "cabal" ["build"] dir
119 getHandle AppendMode $ runGhcPackagePath "cabal" ["test"] dir
120 when (buildDocs settings) $
121 getHandle AppendMode $ run "cabal" ["haddock"] dir
123 let expectedFailure = packageName `Set.member` expectedFailuresBuild settings
127 when expectedFailure $ putStrLn $ package ++ " passed, but I didn't think it would."
128 else unless expectedFailure $ putStrLn $ concat
129 [ "Test suite failed: "
132 , unMaintainer spiMaintainer
133 , case spiGithubUser of
139 return $! passed || expectedFailure
141 logfile = testdir </> package <.> "log"
142 dir = testdir </> package
143 getHandle mode = withBinaryFile logfile mode
144 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