darcs vcs, with my patches &c.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | {-# LANGUAGE MultiParamTypeClasses, DeriveDataTypeable #-}
module Main ( main ) where
import qualified Darcs.Test.Misc
import qualified Darcs.Test.Patch
import qualified Darcs.Test.Email
import Control.Monad (when)
import Data.List ( isPrefixOf, isSuffixOf, sort )
import qualified Data.ByteString.Char8 as B
import System.Console.CmdLib
import System.FilePath( takeDirectory, takeBaseName, isAbsolute )
import Test.Framework.Providers.API
import Test.Framework
import Shellish hiding ( liftIO, run )
import qualified Shellish
doUnit :: IO [Test]
doUnit = do
putStr Darcs.Test.Patch.testInfo
return unitTests
-- | This is the big list of tests that will be run using testrunner.
unitTests :: [Test]
unitTests =
[ Darcs.Test.Email.testSuite
, Darcs.Test.Misc.testSuite
, Darcs.Test.Patch.testSuite
]
-- ----------------------------------------------------------------------
-- shell tests
-- ----------------------------------------------------------------------
data Format = Hashed | Darcs2 | OldFashioned deriving Show
data Running = Running deriving Show
data Result = Success | Skipped | Failed String
instance Show Result where
show Success = "Success"
show Skipped = "Skipped"
show (Failed f) = unlines (map ("| " ++) $ lines f)
instance TestResultlike Running Result where
testSucceeded Success = True
testSucceeded Skipped = True
testSucceeded _ = False
data ShellTest = ShellTest { format :: Format
, testfile :: FilePath
, testdir :: Maybe FilePath -- ^ only if you want to set it explicitly
, _darcspath :: FilePath
}
runtest' :: ShellTest -> FilePath -> ShIO Result
runtest' (ShellTest fmt _ _ dp) srcdir =
do wd <- pwd
setenv "HOME" wd
setenv "TESTDATA" (srcdir </> "tests" </> "data")
setenv "TESTBIN" (srcdir </> "tests" </> "bin")
setenv "DARCS_TESTING_PREFS_DIR" $ wd </> ".darcs"
setenv "EMAIL" "tester"
setenv "DARCS_DONT_COLOR" "1"
setenv "DARCS_DONT_ESCAPE_ANYTHING" "1"
getenv "PATH" >>= setenv "PATH" . ((takeDirectory dp ++ ":") ++)
setenv "DARCS" dp
mkdir ".darcs"
writefile ".darcs/defaults" defaults
-- Warning: A do-notation statement discarded a result of type String.
_ <- Shellish.run "bash" [ "test" ]
return Success
`catch_sh` \e -> case e of
RunFailed _ 200 _ -> return Skipped
RunFailed _ _ _ -> Failed <$> B.unpack <$> lastOutput
where defaults = unlines ["ALL " ++ fmtstr, "send no-edit-description", "ALL ignore-times"]
fmtstr = case fmt of
Darcs2 -> "darcs-2"
Hashed -> "hashed"
OldFashioned -> "old-fashioned-inventory"
runtest :: ShellTest -> ShIO Result
runtest t =
withTmp $ \dir -> do
cp "tests/lib" dir
cp ("tests" </> testfile t) (dir </> "test")
srcdir <- pwd
silently $ sub $ cd dir >> runtest' t srcdir
where
withTmp =
case testdir t of
Just dir -> \job -> do
let d = (dir </> show (format t) </> takeBaseName (testfile t))
mkdir_p d
job d
Nothing -> withTmpDir
instance Testlike Running Result ShellTest where
testTypeName _ = "Shell"
runTest _ test = runImprovingIO $ do yieldImprovement Running
liftIO (shellish $ runtest test)
shellTest :: FilePath -> Format -> Maybe FilePath -> String -> Test
shellTest dp fmt tdir file = Test (file ++ " (" ++ show fmt ++ ")") $ ShellTest fmt file tdir dp
findShell :: FilePath -> Maybe FilePath -> Bool -> ShIO [Test]
findShell dp tdir isFailing =
do files <- sort <$> grep relevant <$> grep (".sh" `isSuffixOf`) <$> ls "tests"
return [ shellTest dp fmt tdir file
| fmt <- [ Darcs2, Hashed, OldFashioned ]
, file <- files ]
where relevant = (if isFailing then id else not) . ("failing-" `isPrefixOf`)
findNetwork :: FilePath -> Maybe FilePath -> ShIO [Test]
findNetwork dp tdir =
do files <- sort <$> grep (".sh" `isSuffixOf`) <$> ls "tests/network"
return [ shellTest dp Darcs2 tdir ("network" </> file) | file <- files ]
-- ----------------------------------------------------------------------
-- harness
-- ----------------------------------------------------------------------
data Config = Config { failing :: Bool
, shell :: Bool
, network :: Bool
, unit :: Bool
, darcs :: String
, tests :: [String]
, testDir :: Maybe FilePath
, plain :: Bool
, threads :: Int }
deriving (Data, Typeable, Eq)
instance Attributes Config where
attributes _ = group "Options"
[ failing %> Help "Run the failing (shell) tests."
, shell %> Help "Run the passing, non-network shell tests." %+ Default True
, network %> Help "Run the network shell tests."
, unit %> Help "Run the unit tests." %+ Default True
, tests %> Help "Pattern to limit the tests to run." %+ short 't'
, testDir %> Help "Directory to run tests in" %+ Default (Nothing :: Maybe FilePath)
, plain %> Help "Use plain-text output."
, threads %> Default (1 :: Int) %+ short 'j' ]
data DarcsTest = DarcsTest deriving Typeable
instance Command DarcsTest (Record Config) where
run _ conf _ = do
let args = [ "-j", show $ threads conf ] ++ concat [ ["-t", x ] | x <- tests conf ] ++ [ "--plain" | True <- [plain conf] ]
case testDir conf of
Nothing -> return ()
Just d -> do e <- shellish (test_e d)
when e $ fail ("Directory " ++ d ++ " already exists. Cowardly exiting")
when (shell conf || network conf || failing conf) $ do
when (null $ darcs conf) $
fail ("No darcs specified. Perhaps --darcs `pwd`/dist/build/darcs/darcs?")
when (not (isAbsolute (darcs conf))) $
fail ("Argument to --darcs should be an absolute path")
ftests <- shellish $ if failing conf then findShell (darcs conf) (testDir conf) True else return []
stests <- shellish $ if shell conf then findShell (darcs conf) (testDir conf) False else return []
utests <- if unit conf then doUnit else return []
ntests <- shellish $ if network conf then findNetwork (darcs conf) (testDir conf) else return []
defaultMainWithArgs (ftests ++ stests ++ utests ++ ntests) args
main :: IO ()
main = getArgs >>= execute DarcsTest
|