1
1
-- | Running tests
2
- {-# LANGUAGE ScopedTypeVariables, ExistentialQuantification, RankNTypes, FlexibleContexts #-}
2
+ {-# LANGUAGE ScopedTypeVariables, ExistentialQuantification, RankNTypes,
3
+ FlexibleContexts, BangPatterns #-}
3
4
module Test.Tasty.Run
4
5
( Status (.. )
5
6
, StatusMap
@@ -10,6 +11,7 @@ import qualified Data.IntMap as IntMap
10
11
import qualified Data.Sequence as Seq
11
12
import qualified Data.Foldable as F
12
13
import Data.Maybe
14
+ import Data.Time.Clock.POSIX
13
15
import Control.Monad.State
14
16
import Control.Monad.Writer
15
17
import Control.Monad.Reader
@@ -95,15 +97,15 @@ executeTest action statusVar timeoutOpt inits fins = mask $ \restore -> do
95
97
-- handler doesn't interfere with our timeout.
96
98
withAsync (action yieldProgress) $ \ asy -> do
97
99
labelThread (asyncThreadId asy) " tasty_test_execution_thread"
98
- applyTimeout timeoutOpt $ wait asy
100
+ timed $ applyTimeout timeoutOpt $ wait asy
99
101
100
102
-- no matter what, try to run each finalizer
101
103
mbExn <- destroyResources restore
102
104
103
105
atomically . writeTVar statusVar $ Done $
104
106
case resultOrExn <* maybe (Right () ) Left mbExn of
105
107
Left ex -> exceptionResult ex
106
- Right r -> r
108
+ Right (t,r) -> r { resultTime = t }
107
109
108
110
where
109
111
initResources :: IO ()
@@ -138,6 +140,7 @@ executeTest action statusVar timeoutOpt inits fins = mask $ \restore -> do
138
140
{ resultOutcome = Failure $ TestTimedOut t
139
141
, resultDescription =
140
142
" Timed out after " ++ tstr
143
+ , resultTime = fromIntegral t
141
144
}
142
145
fromMaybe timeoutResult <$> timeout t a
143
146
@@ -244,17 +247,19 @@ getResource var =
244
247
launchTestTree
245
248
:: OptionSet
246
249
-> TestTree
247
- -> (StatusMap -> IO a )
250
+ -> (StatusMap -> IO ( Double -> IO a ) )
248
251
-> IO a
249
252
launchTestTree opts tree k = do
250
253
(testActions, rvars) <- createTestActions opts tree
251
254
let NumThreads numTheads = lookupOption opts
252
- abortTests <- runInParallel numTheads (fst <$> testActions)
253
- (do let smap = IntMap. fromList $ zip [0 .. ] (snd <$> testActions)
254
- k smap)
255
- `finally` do
256
- abortTests
257
- waitForResources rvars
255
+ (t,k) <- timed $ do
256
+ abortTests <- runInParallel numTheads (fst <$> testActions)
257
+ (do let smap = IntMap. fromList $ zip [0 .. ] (snd <$> testActions)
258
+ k smap)
259
+ `finally` do
260
+ abortTests
261
+ waitForResources rvars
262
+ k t
258
263
where
259
264
alive :: Resource r -> Bool
260
265
alive r = case r of
@@ -271,3 +276,13 @@ launchTestTree opts tree k = do
271
276
272
277
unexpectedState :: String -> Resource r -> SomeException
273
278
unexpectedState where_ r = toException $ UnexpectedState where_ (show r)
279
+
280
+ timed :: IO a -> IO (Double , a )
281
+ timed t = do
282
+ start <- getTime
283
+ ! r <- t
284
+ end <- getTime
285
+ return (end- start, r)
286
+
287
+ getTime :: IO Double
288
+ getTime = realToFrac <$> getPOSIXTime
0 commit comments