1

I'm using shake for a test suite. I have multiples independent tests represented as a set of Rule. If any of theses rules fails, the test fails. Finally, I produce a report containing all the tests status.

My issues are :

a) I need to detect which test runs or fails. Actually I'm cheating using actionOnException, but that's lot of boilerplate in each command in each rules and that's complicated (I must write status file or play with IORef to store the failing status).

b) I want to write the Shake report as part of my final report, however shakeReport does not write the file in case of error, my only solution is to run again the build using --no-build --report out.html which is not convenient.

Edit: Actually the tests are in action and build their dependencies. The build roughly looks like :

main = do
  -- when this fails, `dumpTests` is called,
  -- but the shake report is not written
  _ <- (try shakeMain) :: IO (Either SomeException ())

  -- This write my test report from the success informations it can gather
  -- in the directory hierarchy
  dumpTests

smakeMain = shakeArgs {shakeStaunch=True, shakeReport=["report.html"]} $ do

   "tests" ~> need ["test1/done", "test2/done", ...]

   -- this rules completly runs a test
   "*/done" %> \done -> do
       let test = takeDirectory done
       -- clear all the leftover to be sure that there is nothing useless left. This is important because I use theses outputs to know which command succeeds or fails.
       liftIO $ removeFiles test ["stdout.log", "*/image/*.exr", "*/image/*.png", "done"]

       need [test </> "stdout.log"]

       results <- getDirectoryFiles (test </> "image") ["*.exr"]

       need (map (-<.> "png") results)

       writeFile' done "done"

   "*/stdout.log" %> \log -> do
        let path = takeDirectory log </> "test"
        need [path]

        aCmd path -- this builds stdout.log and all exrs

   "*/image/*.png" %> \png -> do
         need [(png -<.> "exr")]
         toExr png

Thank you.

Guillaum
  • 170
  • 6
  • Are the tests in `Action` or `IO`? Do they "build" their dependencies first? – Neil Mitchell Apr 27 '16 at 14:10
  • Example added, everything is in `Action`/`Rule` except the final report creation. Actually I'll be happy to have the final report creation in a `Rule`, but I need a way of creating it even if its dependencies fail. – Guillaum Apr 28 '16 at 08:21

1 Answers1

0

Question b is simplest to answer. If the build raises an error it won't write out a report - it's reasonable that could be changed (I can see arguments both ways). However, you can automate the --no-build piece by having main call shake twice - first as you do now, and second with withArgs or using shake shakeOptions{shakeReport=...} mempty. Essentially you do exactly what you are doing now "by hand", but put it into the main function so it's automatic.

For the main question, I suspect the answer is you should be marking fails not with exceptions, but with a result value. For example, test1/done could record a TRUE/FALSE saying whether the test worked or not. Then you can have alldone which depends on all the */done values and writes a single report. That way your build would always pass (unless you got something fundamentally wrong), but the result on passing would be either "TESTS PASS" or "TESTS FAIL".

Neil Mitchell
  • 9,090
  • 1
  • 27
  • 85
  • For the main question, your solution works, however it forces me to think about cleaning the test1/done before attempting the command, because if the command fails for any reason, the test1/done will keep the results of the previous attempt, which may be misleading. However you confirmed that there is no easy "out of the box" solution, which is a satisfying answer for me. Thank you. – Guillaum Apr 28 '16 at 16:44
  • If the test1/done rule always succeeds (as far as Shake is concerned), but success/failure of the test is written down to a file, then everything will always be updated properly. – Neil Mitchell Apr 28 '16 at 19:21
  • PS. If you want to discuss more thoroughly the mailing list or github tracker might be a better venue, and we can update SO with the answer afterwards (both linked from the bottom of http://shakebuild.com/) – Neil Mitchell Apr 28 '16 at 19:22