shelltest: use test-framework as test runner
We can now run shell tests in parallel which seems to be a big win. Tests which took 3.5s now run in .13s.
This commit is contained in:
		
							parent
							
								
									e11c828aaf
								
							
						
					
					
						commit
						f1f4a0c023
					
				| @ -1,12 +1,18 @@ | |||||||
| #!/usr/bin/env runhaskell | #!/usr/bin/env runhaskell | ||||||
| {- | {- | ||||||
| 
 | 
 | ||||||
|  | shelltest.hs (c) 2009 Simon Michael <simon@joyful.com> | ||||||
|  | 
 | ||||||
| Run one or more hledger command-line tests, specified by .test files like | Run one or more hledger command-line tests, specified by .test files like | ||||||
| those used in the ledger project. A ledger-style .test file contains a | those used in the ledger project. A ledger-style .test file contains a | ||||||
| partial command line, input, expected output, expected error output, and | partial command line, input, expected output, expected error output, and | ||||||
| expected exit code separated by delimiters. | expected exit code separated by delimiters. | ||||||
| 
 | 
 | ||||||
| Usage: $ shelltest *.test | Usage: $ shelltest [OPTS] *.test | ||||||
|  | 
 | ||||||
|  | This version uses the test-framework test runner. Any command-line arguments | ||||||
|  | beginning with - are passed through to that. So avoid spaces: use -tpattern | ||||||
|  | not -t pattern. To get a speedup, try adding -j8. | ||||||
| 
 | 
 | ||||||
| Here is the .test file format: | Here is the .test file format: | ||||||
| @ | @ | ||||||
| @ -24,8 +30,8 @@ error output | |||||||
| ; | ; | ||||||
| ; Lines whose first non-whitespace character is ; are ignored. | ; Lines whose first non-whitespace character is ; are ignored. | ||||||
| ; The first line is the command line. "hledger" is prepended, and "-f-" is | ; The first line is the command line. "hledger" is prepended, and "-f-" is | ||||||
| ; appended unless there is a -f or <... argument (in which case any | ; appended unless there is a -f or <... argument, in which case any | ||||||
| ; provided input is ignored.) | ; provided input is ignored. | ||||||
| ; Then there is a line containing <<< and 0 or more lines of input. | ; Then there is a line containing <<< and 0 or more lines of input. | ||||||
| ; Then a line containing >>> (or >>>1 for ledger testrunner compatibility) | ; Then a line containing >>> (or >>>1 for ledger testrunner compatibility) | ||||||
| ; and 0 or more lines of expected output. | ; and 0 or more lines of expected output. | ||||||
| @ -37,14 +43,25 @@ error output | |||||||
| -} | -} | ||||||
| 
 | 
 | ||||||
| module Main where | module Main where | ||||||
| import System (getArgs) | --import System (getArgs) | ||||||
|  | import System.Environment (getArgs,withArgs) | ||||||
| import System.Exit (exitFailure, exitWith, ExitCode(..)) | import System.Exit (exitFailure, exitWith, ExitCode(..)) | ||||||
| import System.IO (hGetContents, hPutStr, hFlush, stderr, stdout) | import System.IO (hGetContents, hPutStr, stderr {-, stdout, hFlush-}) | ||||||
| import System.Process (runInteractiveCommand, waitForProcess) | import System.Process (runInteractiveCommand, waitForProcess) | ||||||
| import Text.Printf (printf) | import Text.Printf (printf) | ||||||
| import Text.ParserCombinators.Parsec | import Text.ParserCombinators.Parsec | ||||||
| import Control.Monad (liftM,when) | import Control.Monad (liftM,when) | ||||||
| import Data.Maybe (fromMaybe) | import Data.Maybe (fromMaybe) | ||||||
|  | import Data.List (partition) | ||||||
|  | 
 | ||||||
|  | import Test.Framework (defaultMain {-, testGroup-}) | ||||||
|  | import Test.Framework.Providers.HUnit (hUnitTestToTests) | ||||||
|  | --import Test.Framework.Providers.QuickCheck2 (testProperty) | ||||||
|  | import Test.HUnit hiding (Test) | ||||||
|  | import qualified Test.HUnit (Test) | ||||||
|  | --import Test.QuickCheck | ||||||
|  | --import Tests (tests) | ||||||
|  | 
 | ||||||
| import Debug.Trace | import Debug.Trace | ||||||
| strace :: Show a => a -> a | strace :: Show a => a -> a | ||||||
| strace a = trace (show a) a | strace a = trace (show a) a | ||||||
| @ -64,9 +81,13 @@ data ShellTest = ShellTest { | |||||||
| 
 | 
 | ||||||
| main :: IO () | main :: IO () | ||||||
| main = do | main = do | ||||||
|   files <- getArgs |   args <- getArgs | ||||||
|   ok <-  mapM (\f -> parseShellTest f >>= runShellTest) files |   let (opts,files) = partition ((=="-").take 1) args | ||||||
|   if any not ok then exitFailure else exitWith ExitSuccess |   shelltests <-  mapM parseShellTest files | ||||||
|  |   withArgs opts $ defaultMain $ concatMap (hUnitTestToTests.shellTestToHUnitTest) shelltests | ||||||
|  | 
 | ||||||
|  | shellTestToHUnitTest :: ShellTest -> Test.HUnit.Test | ||||||
|  | shellTestToHUnitTest t = filename t ~: do {r <- runShellTest t; assertBool "" r} | ||||||
| 
 | 
 | ||||||
| parseShellTest :: FilePath -> IO ShellTest | parseShellTest :: FilePath -> IO ShellTest | ||||||
| parseShellTest = liftM (either (error.show) id) . parseFromFile shelltest | parseShellTest = liftM (either (error.show) id) . parseFromFile shelltest | ||||||
| @ -96,11 +117,11 @@ expectedexitcode = string "===" >> liftM (toExitCode.read) line -- `catch` (\e - | |||||||
| 
 | 
 | ||||||
| runShellTest :: ShellTest -> IO Bool | runShellTest :: ShellTest -> IO Bool | ||||||
| runShellTest ShellTest{ | runShellTest ShellTest{ | ||||||
|     filename=f,command=c,stdin=i,stdoutExpected=o,stderrExpected=e,exitCodeExpected=x} = do |     filename=_,command=c,stdin=i,stdoutExpected=o,stderrExpected=e,exitCodeExpected=x} = do | ||||||
|   let cmd = unwords [exe,c,if (any isinputarg $ words c) then "" else "-f-"] |   let cmd = unwords [exe,c,if (any isinputarg $ words c) then "" else "-f-"] | ||||||
|             where isinputarg a = take 2 a == "-f" || (take 1 a == "<") |             where isinputarg a = take 2 a == "-f" || (take 1 a == "<") | ||||||
|       (i',o',e',x') = (fromMaybe "" i, fromMaybe "" o, fromMaybe "" e, fromMaybe ExitSuccess x) |       (i',o',e',x') = (fromMaybe "" i, fromMaybe "" o, fromMaybe "" e, fromMaybe ExitSuccess x) | ||||||
|   printf "%s .. " f; hFlush stdout |   -- printf "%s .. " f; hFlush stdout | ||||||
|   (ih,oh,eh,ph) <- runInteractiveCommand cmd |   (ih,oh,eh,ph) <- runInteractiveCommand cmd | ||||||
|   hPutStr ih i' |   hPutStr ih i' | ||||||
|   out <- hGetContents oh |   out <- hGetContents oh | ||||||
| @ -109,10 +130,10 @@ runShellTest ShellTest{ | |||||||
|   let (outputok, errorok, exitok) = (out==o', err==e', exit==x') |   let (outputok, errorok, exitok) = (out==o', err==e', exit==x') | ||||||
|   if outputok && errorok && exitok  |   if outputok && errorok && exitok  | ||||||
|    then do |    then do | ||||||
|      putStrLn "ok" |      -- putStrLn "ok" | ||||||
|      return True  |      return True  | ||||||
|    else do |    else do | ||||||
|      hPutStr stderr $ printf "FAIL\n" |      -- hPutStr stderr $ printf "FAIL\n" | ||||||
|      when (not outputok) $ printExpectedActual "stdout" o' out |      when (not outputok) $ printExpectedActual "stdout" o' out | ||||||
|      when (not errorok)  $ printExpectedActual "stderr" e' err |      when (not errorok)  $ printExpectedActual "stderr" e' err | ||||||
|      when (not exitok)   $ printExpectedActual "exit code" (show (fromExitCode x')++"\n") (show (fromExitCode exit)++"\n") |      when (not exitok)   $ printExpectedActual "exit code" (show (fromExitCode x')++"\n") (show (fromExitCode exit)++"\n") | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user