22{-# LANGUAGE LambdaCase #-}
33{-# LANGUAGE ScopedTypeVariables #-}
44{-# LANGUAGE TupleSections #-}
5- {-# LANGUAGE TypeApplications #-}
65
76-- |
87-- Copyright: © 2018-2020 IOHK
@@ -22,13 +21,11 @@ import Prelude
2221import Control.Concurrent
2322 ( threadDelay )
2423import Control.Concurrent.Async
25- ( AsyncCancelled , async , race , race_ , wait )
24+ ( AsyncCancelled , async , race , wait )
2625import Control.Concurrent.MVar
2726 ( MVar , newEmptyMVar , putMVar , takeMVar )
2827import Control.Exception
29- ( SomeException , fromException , throwIO , try )
30- import Data.Maybe
31- ( isJust )
28+ ( SomeException , catch , throwIO )
3229import Test.Hspec
3330 ( ActionWith
3431 , HasCallStack
@@ -115,36 +112,29 @@ aroundAll acquire =
115112it :: HasCallStack => String -> ActionWith ctx -> SpecWith ctx
116113it = itWithCustomTimeout (10 * minute)
117114 where
118- minute = 60 * 1000 * 1000
115+ minute = 60
119116
120117-- | Like @it@ but with a custom timeout, which makes it realistic to test.
121- itWithCustomTimeout :: HasCallStack => Int -> String -> ActionWith ctx -> SpecWith ctx
122- itWithCustomTimeout micro title action = specify title $ \ ctx -> do
123- race_ timeout $ do
124- res1 <- try $ action ctx
125- case res1 of
126- Right r1 -> return r1
127- Left (e1 :: SomeException )
128- -- If we time out during the first attempt, then we /should/ time
129- -- out.
130- | isAsyncCancelled e1 -> throwIO e1
131- | otherwise -> do
132- res2 <- try $ action ctx
133- case res2 of
134- -- If the second try fails, return the first error. The
135- -- second error might not be helpful.
136- Left (e2 :: SomeException )
137- | isAsyncCancelled e2 -> throwIO e1
138- | otherwise -> throwIO e1
139- Right r2 -> return r2
118+ itWithCustomTimeout
119+ :: HasCallStack
120+ => Int -- ^ Timeout in seconds.
121+ -> String
122+ -> ActionWith ctx
123+ -> SpecWith ctx
124+ itWithCustomTimeout sec title action = specify title $ \ ctx -> timeout sec $ do
125+ action ctx
126+ `catch` (\ (_ :: AsyncCancelled ) -> return () )
127+ `catch` (\ (e :: SomeException ) -> action ctx
128+ `catch` (\ (_ :: SomeException ) -> throwIO e))
140129 where
141- isAsyncCancelled = isJust . fromException @ AsyncCancelled
142- timeout = do
143- threadDelay micro
144- expectationFailure
145- $ " timed out in "
146- <> show (micro `div` 1000000 )
147- <> " seconds"
130+ timeout t act =
131+ race (threadDelay (micro t)) act >>= \ case
132+ Right () ->
133+ return ()
134+ Left () ->
135+ expectationFailure $ " timed out in " <> show t <> " seconds"
136+ where
137+ micro = (* 1000 ) . (* 1000 )
148138
149139-- | Some helper to help readability on the thread synchronization above.
150140await :: MVar () -> IO ()
0 commit comments