{-# LANGUAGE CPP #-} module Test(main) where import Development.Shake.Command import System.Directory.Extra import System.IO.Extra import System.Time.Extra import System.Environment.Extra import System.FilePath import Control.Monad import Control.Exception.Extra import Control.Concurrent import System.Process import Data.List.Extra import Data.IORef import Data.Char import Control.Applicative import qualified Example import Prelude import Development.Bake.Test.Simulate main :: IO () main = do args <- getArgs if args /= [] then Example.main else do simulate dir <- getCurrentDirectory test $ dir ++ "/.bake-test" test :: FilePath -> IO () test dir = do let repo = "file:///" ++ dropWhile (== '/') (replace "\\" "/" dir) ++ "/repo" b <- doesDirectoryExist dir when b $ do unit $ cmd "chmod -R 755 .bake-test" unit $ cmd "rm -rf .bake-test" return () #if __GLASGOW_HASKELL__ >= 708 setEnv "http_proxy" "" #endif createDirectoryIfMissing True (dir "repo") withCurrentDirectory (dir "repo") $ do unit $ cmd "git init" unit $ cmd "git config user.email" ["gwen@example.com"] unit $ cmd "git config user.name" ["Ms Gwen"] writeFile "Main.hs" "module Main where\n\n-- Entry point\nmain = print 1\n" unit $ cmd "git add Main.hs" unit $ cmd "git commit -m" ["Initial version"] unit $ cmd "git checkout -b none" -- so I can git push to master forM_ ["bob","tony"] $ \s -> do createDirectoryIfMissing True (dir "repo-" ++ s) withCurrentDirectory (dir "repo-" ++ s) $ do print "clone" unit $ cmd "git clone" repo "." unit $ cmd "git config user.email" [s ++ "@example.com"] unit $ cmd "git config user.name" ["Mr " ++ toUpper (head s) : map toLower (tail s)] unit $ cmd "git checkout -b" s aborting <- newIORef False let createProcessAlive p = do t <- myThreadId (_,_,_,pid) <- createProcess p forkIO $ do waitForProcess pid b <- readIORef aborting when (not b) $ throwTo t $ ErrorCall "Process died" sleep 2 return pid exe <- getExecutablePath createDirectoryIfMissing True $ dir "server" curdir <- getCurrentDirectory environment <- (\env -> ("REPO",repo):("bake_datadir",curdir):env) <$> getEnvironment p0 <- createProcessAlive (proc exe ["server","--author=admin"]) {cwd=Just $ dir "server", env=Just environment} sleep 5 ps <- forM (zip [1..] Example.platforms) $ \(i,p) -> do sleep 0.5 -- so they don't ping at the same time createDirectoryIfMissing True $ dir "client-" ++ show p createProcessAlive (proc exe $ ["client","--ping=1","--name=" ++ show p,"--threads=" ++ show i,"--provide=" ++ show p]) {cwd=Just $ dir "client-" ++ show p,env=Just environment} flip finally (do writeIORef aborting True; mapM_ terminateProcess $ p0 : ps) $ do let edit name act = withCurrentDirectory (dir "repo-" ++ name) $ do act unit $ cmd "git add *" unit $ cmd "git commit -m" ["Update from " ++ name] unit $ cmd "git push origin" name Stdout sha1 <- cmd "git rev-parse HEAD" unit $ cmd exe "addpatch" ("--name=" ++ name ++ "=" ++ sha1) ("--author=" ++ name) putStrLn "% MAKING EDIT AS BOB" edit "bob" $ writeFile "Main.hs" "module Main(main) where\n\n-- Entry point\nmain = print 1\n" sleep 2 putStrLn "% MAKING EDIT AS TONY" edit "tony" $ writeFile "Main.hs" "module Main where\n\n-- Entry point\nmain :: IO ()\nmain = print 1\n" retry 10 $ do sleep 10 withTempDir $ \d -> withCurrentDirectory d $ do unit $ cmd "git clone" repo "." unit $ cmd "git checkout master" src <- readFile "Main.hs" let expect = "module Main(main) where\n\n-- Entry point\nmain :: IO ()\nmain = print 1\n" when (src /= expect) $ do error $ "Expected to have updated Main, but got:\n" ++ src unit $ cmd exe "pause" putStrLn "% MAKING A GOOD EDIT AS BOB" edit "bob" $ do unit $ cmd "git fetch origin" unit $ cmd "git merge origin/master" writeFile "Main.hs" "module Main(main) where\n\n-- Entry point\nmain :: IO ()\nmain = print 1\n\n" putStrLn "% MAKING A BAD EDIT AS BOB" edit "bob" $ writeFile "Main.hs" "module Main(main) where\nimport System.Environment\n-- Entry point\nmain :: IO ()\nmain = do [[_]] <- getArgs; print 1\n\n" putStrLn "% MAKING A GOOD EDIT AS TONY" edit "tony" $ do unit $ cmd "git fetch origin" unit $ cmd "git merge origin/master" writeFile "Main.hs" "-- Tony waz ere\nmodule Main(main) where\n\n-- Entry point\nmain :: IO ()\nmain = print 1\n" putStrLn "% MAKING A MERGE CONFLICT AS BOB" edit "bob" $ writeFile "Main.hs" "-- Bob waz ere\nmodule Main(main) where\nimport System.Environment\n-- Entry point\nmain :: IO ()\nmain = do [[_]] <- getArgs; print 1\n\n" putStrLn "% MAKING ANOTHER GOOD EDIT AS TONY" edit "tony" $ do writeFile "Main.hs" "-- Tony waz ere 1981\nmodule Main(main) where\n\n-- Entry point\nmain :: IO ()\nmain = print 1\n" unit $ cmd exe "unpause" retry 15 $ do sleep 10 withTempDir $ \d -> withCurrentDirectory d $ do unit $ cmd "git clone" repo "." unit $ cmd "git checkout master" src <- readFile "Main.hs" let expect = "-- Tony waz ere 1981\nmodule Main(main) where\n\n-- Entry point\nmain :: IO ()\nmain = print 1\n\n" when (src /= expect) $ do error $ "Expected to have updated Main, but got:\n" ++ src putStrLn "Completed successfully!" -- putStrLn "Waiting (time to view webpage)..." >> sleep 120