forked from NorfairKing/sydtest
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: do not catch async exception as test failure
This is related to NorfairKing#80 The current exception handler for test was incorrectly catching async exception (the handler for `AsyncException` was not enough, the "parent" of the async exception hierarchy is `SomeAsyncException`). This lead to surprising behaviors with ctrl-C. when receiving a `ctrl-c` (e.g. an interruption of the test-suite by the user), the test runner was cancelled, cancelling the print loop of the test and cancelling all workers. However, the exception was caught in workers as a "test-failure", leading to it being ignored and the different tests retrieved and meaning that the test runner survived the interruption. They will hence continue their life (e.g. purging the job queue). It was sometime leading to a lot of delay before ending the process, or even sometime other errors related to the different involved `MVar` (when no producer / consumer detection detects the error. Note that a second ctrl-c would cancels the program execution completely (Because that's how the RTS behaves). HOWEVER, the behavior is completely different in the repl, because the repl won't terminate itself on second ctrl-C. Hence the worker threads are leaked and continues running, and even survives the repl reloads. In the best case, that's a waste of resources and CPU time, but if you happen to rerun new sydtest, it can stacks and some tests may run concurrently with the "ghost" version of themself, which may or may not work ;)
- Loading branch information
Showing
6 changed files
with
61 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,8 @@ tests: | |
- sydtest >=0.17 | ||
- text | ||
- vector | ||
- time | ||
- async | ||
|
||
sydtest-output-test: | ||
main: Main.hs | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{-# LANGUAGE NumericUnderscores #-} | ||
|
||
module Test.Syd.ExceptionSpec where | ||
|
||
import Control.Concurrent (threadDelay) | ||
import Control.Concurrent.Async | ||
import Control.Exception (AsyncException, try) | ||
import Data.Time.Clock | ||
import Test.Syd | ||
|
||
spec :: TestDefM outers () () | ||
spec = describe "exception handling" $ do | ||
it "stops immediatly with async" $ do | ||
-- Tests that when an async exception is sent to sydTest (for example, | ||
-- ctrl-c), it behaves as expected and terminates immediately and does not | ||
-- do anything surprising. | ||
startTime <- liftIO getCurrentTime | ||
|
||
-- Runs two threads, one will be done in 1s, and the other is a test suite | ||
-- with one test which should run for 10s. | ||
-- When the first threads terminate, it will throw AsyncCancel in the | ||
-- sydTest test suite, which should terminate asap. | ||
-- This will be checked using the timer t. That's fragile, but we know that: | ||
-- | ||
-- t should be more than 100ms (because of the first threadDelay) | ||
-- t should be no much more than 100ms. Especially, it should not be 10s | ||
-- (waiting for the complete threadDelay in the test suite) or even more if | ||
-- the exception is completly ignored (or test is retried) | ||
_ <- race (threadDelay 100_000) $ do | ||
sydTest $ do | ||
it "is a dumb slow test" $ do | ||
threadDelay 10_000_000 | ||
|
||
endTime <- liftIO getCurrentTime | ||
|
||
-- Less than 1 second | ||
(endTime `diffUTCTime` startTime) `shouldSatisfy` (< 1) | ||
pure () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters