shake-0.15.3: src/Test/Errors.hs
module Test.Errors(main) where
import Development.Shake
import Development.Shake.FilePath
import Test.Type
import Data.List
import Control.Monad
import Control.Concurrent
import Control.Exception.Extra hiding (assert)
import System.Directory as IO
import qualified System.IO.Extra as IO
main = shaken2 test $ \args obj -> do
obj "norule" %> \_ ->
need [obj "norule_isavailable"]
obj "failcreate" %> \_ ->
return ()
[obj "failcreates", obj "failcreates2"] &%> \_ ->
writeFile' (obj "failcreates") ""
obj "recursive" %> \out ->
need [out]
obj "systemcmd" %> \_ ->
cmd "random_missing_command"
obj "stack1" %> \_ -> need [obj "stack2"]
obj "stack2" %> \_ -> need [obj "stack3"]
obj "stack3" %> \_ -> error "crash"
obj "staunch1" %> \out -> do
liftIO $ sleep 0.1
writeFile' out "test"
obj "staunch2" %> \_ -> error "crash"
let catcher out op = obj out %> \out -> do
writeFile' out "0"
op $ do src <- IO.readFile' out; writeFile out $ show (read src + 1 :: Int)
catcher "finally1" $ actionFinally $ fail "die"
catcher "finally2" $ actionFinally $ return ()
catcher "finally3" $ actionFinally $ liftIO $ sleep 10
catcher "finally4" $ actionFinally $ need ["wait"]
"wait" ~> do liftIO $ sleep 10
catcher "exception1" $ actionOnException $ fail "die"
catcher "exception2" $ actionOnException $ return ()
res <- newResource "resource_name" 1
obj "resource" %> \out -> do
withResource res 1 $
need ["resource-dep"]
obj "overlap.txt" %> \out -> writeFile' out "overlap.txt"
obj "overlap.t*" %> \out -> writeFile' out "overlap.t*"
obj "overlap.*" %> \out -> writeFile' out "overlap.*"
alternatives $ do
obj "alternative.t*" %> \out -> writeFile' out "alternative.txt"
obj "alternative.*" %> \out -> writeFile' out "alternative.*"
obj "chain.2" %> \out -> do
src <- readFile' $ obj "chain.1"
if src == "err" then error "err_chain" else writeFileChanged out src
obj "chain.3" %> \out -> copyFile' (obj "chain.2") out
obj "tempfile" %> \out -> do
file <- withTempFile $ \file -> do
liftIO $ assertExists file
return file
liftIO $ assertMissing file
withTempFile $ \file -> do
liftIO $ assertExists file
writeFile' out file
fail "tempfile-died"
obj "tempdir" %> \out -> do
file <- withTempDir $ \dir -> do
let file = dir </> "foo.txt"
liftIO $ writeFile (dir </> "foo.txt") ""
-- will throw if the directory does not exist
writeFile' out ""
return file
liftIO $ assertMissing file
phony "fail1" $ fail "die1"
phony "fail2" $ fail "die2"
when ("die" `elem` args) $ action $ error "death error"
test build obj = do
let crash args parts = assertException parts (build $ "--quiet" : args)
build ["clean"]
build ["--sleep"]
writeFile (obj "chain.1") "x"
build ["$chain.3","--sleep"]
writeFile (obj "chain.1") "err"
crash ["$chain.3"] ["err_chain"]
crash ["$norule"] ["norule_isavailable"]
crash ["$failcreate"] ["failcreate"]
crash ["$failcreates"] ["failcreates"]
crash ["$recursive"] ["recursive"]
crash ["$systemcmd"] ["systemcmd","random_missing_command"]
crash ["$stack1"] ["stack1","stack2","stack3","crash"]
b <- IO.doesFileExist $ obj "staunch1"
when b $ removeFile $ obj "staunch1"
crash ["$staunch1","$staunch2","-j2"] ["crash"]
b <- IO.doesFileExist $ obj "staunch1"
assert (not b) "File should not exist, should have crashed first"
crash ["$staunch1","$staunch2","-j2","--keep-going","--silent"] ["crash"]
b <- IO.doesFileExist $ obj "staunch1"
assert b "File should exist, staunch should have let it be created"
crash ["$finally1"] ["die"]
assertContents (obj "finally1") "1"
build ["$finally2"]
assertContents (obj "finally2") "1"
crash ["$exception1"] ["die"]
assertContents (obj "exception1") "1"
build ["$exception2"]
assertContents (obj "exception2") "0"
forM_ ["finally3","finally4"] $ \name -> do
t <- forkIO $ ignore $ build ['$':name,"--exception"]
retry 10 $ sleep 0.1 >> assertContents (obj name) "0"
throwTo t (IndexOutOfBounds "test")
retry 10 $ sleep 0.1 >> assertContents (obj name) "1"
crash ["$resource"] ["cannot currently call apply","withResource","resource_name"]
build ["$overlap.foo"]
assertContents (obj "overlap.foo") "overlap.*"
build ["$overlap.txt"]
assertContents (obj "overlap.txt") "overlap.txt"
crash ["$overlap.txx"] ["key matches multiple rules","overlap.txx"]
build ["$alternative.foo","$alternative.txt"]
assertContents (obj "alternative.foo") "alternative.*"
assertContents (obj "alternative.txt") "alternative.txt"
crash ["$tempfile"] ["tempfile-died"]
src <- readFile $ obj "tempfile"
assertMissing src
build ["$tempdir"]
crash ["!die"] ["Shake","action","death error"]
putStrLn "## BUILD errors"
(out,_) <- IO.captureOutput $ build []
assert ("nothing to do" `isInfixOf` out) $ "Expected 'nothing to do', but got: " ++ out
putStrLn "## BUILD errors fail1 fail2 -k -j2"
(out,_) <- IO.captureOutput $ try_ $ build ["fail1","fail2","-k","-j2",""]
assert ("die1" `isInfixOf` out && "die2" `isInfixOf` out) $ "Expected 'die1' and 'die2', but got: " ++ out