Skip to content

Commit da41c7b

Browse files
committed
Add concurrency abstractions from lifted-async and lifted-base
1 parent 06f32cd commit da41c7b

File tree

2 files changed

+99
-6
lines changed

2 files changed

+99
-6
lines changed

hedgehog-extras.cabal

+8
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ common exceptions { build-depends: exceptions
2828
common filepath { build-depends: filepath }
2929
common hedgehog { build-depends: hedgehog }
3030
common http-conduit { build-depends: http-conduit }
31+
common lifted-async { build-depends: lifted-async }
32+
common lifted-base { build-depends: lifted-base }
33+
common monad-control { build-depends: monad-control }
3134
common mmorph { build-depends: mmorph }
3235
common mtl { build-depends: mtl }
3336
common network { build-depends: network }
@@ -39,6 +42,7 @@ common temporary { build-depends: temporary
3942
common text { build-depends: text }
4043
common time { build-depends: time >= 1.9.1 }
4144
common transformers { build-depends: transformers }
45+
common transformers-base { build-depends: transformers-base }
4246
common unliftio { build-depends: unliftio }
4347
common yaml { build-depends: yaml }
4448
common zlib { build-depends: zlib }
@@ -71,6 +75,9 @@ library
7175
filepath,
7276
hedgehog,
7377
http-conduit,
78+
lifted-async,
79+
lifted-base,
80+
monad-control,
7481
mmorph,
7582
mtl,
7683
network,
@@ -82,6 +89,7 @@ library
8289
text,
8390
time,
8491
transformers,
92+
transformers-base,
8593
unliftio,
8694
Win32,
8795
yaml,
+91-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,101 @@
1+
{-# LANGUAGE FlexibleInstances #-}
2+
{-# LANGUAGE MultiParamTypeClasses #-}
3+
{-# LANGUAGE TypeFamilies #-}
4+
{-# OPTIONS_GHC -Wno-orphans #-}
5+
6+
7+
{- | This modules provides concurrency abstractions for hedgehog tests. Using "lifted-base" one can execute
8+
expensive test actions concurrently.
9+
10+
For example, the actions invoked inside 'mapConcurrently_' are invoked in the same 'MonadTest' as the outer
11+
monad of 'mapConcurrently_'.
12+
13+
@
14+
import qualified Hedgehog.Extras.Test.Concurrent as H
15+
16+
setUpEnvironment = H.mapConcurrently_ id
17+
[ H.threadDelay 100 >> pure 1
18+
, H.threadDelay 200 >> pure 2
19+
, H.threadDelay 300 >> pure 3
20+
]
21+
@
22+
23+
24+
__Warning: Do not use this module for running concurrent checks!__ The 'MonadBaseControl' instance does not
25+
aggregate effects for 'PropertyT'. Consider the following code:
26+
27+
@
28+
LA.mapConcurrently_ id
29+
[ do
30+
H.note_ \"FAIL1\"
31+
success
32+
, do
33+
IO.threadDelay 1_000_000
34+
H.note_ \"FAIL2\"
35+
failure
36+
, do
37+
H.note_ \"FAIL3\"
38+
failure
39+
]
40+
@
41+
42+
Executing this code will give you the following output in the test report:
43+
44+
@
45+
66 ┃ LA.mapConcurrently_ id
46+
67 ┃ [ do
47+
68 ┃ H.note_ \"FAIL1\"
48+
┃ │ FAIL1
49+
69 ┃ success
50+
70 ┃ , do
51+
71 ┃ IO.threadDelay 1_000_000
52+
72 ┃ H.note_ \"FAIL2\"
53+
┃ │ FAIL2
54+
73 ┃ failure
55+
┃ ^^^^^^^
56+
74 ┃ , do
57+
75 ┃ H.note_ \"FAIL3\"
58+
76 ┃ failure
59+
77 ┃ ]
60+
@
61+
Please note that only @FAIL1@ and @FAIL2@ annotations were reported - @FAIL3@ annotation and the failure
62+
below was swallowed without any information.
63+
64+
__Don't use concurrency abstractions from this module, when you need to aggregate and report failures!__
65+
66+
-}
167
module Hedgehog.Extras.Test.Concurrent
268
( threadDelay
69+
-- * Re-exports of concurrency abstractions from @lifted-base@
70+
, module Control.Concurrent.Async.Lifted
71+
, module System.Timeout.Lifted
372
) where
473

5-
import Control.Monad.IO.Class (MonadIO)
6-
import Data.Function (($), (.))
74+
import Control.Applicative
75+
import Control.Concurrent.Async.Lifted
76+
import qualified Control.Concurrent.Lifted as IO
77+
import Control.Monad.Base
78+
import Control.Monad.IO.Class
79+
import Control.Monad.Trans.Control
80+
import Control.Monad.Trans.Resource
81+
import Data.Function
782
import Data.Int
8-
import Hedgehog (MonadTest)
9-
10-
import qualified Control.Concurrent as IO
1183
import qualified GHC.Stack as GHC
84+
import System.IO (IO)
85+
import System.Timeout.Lifted
86+
import qualified UnliftIO
87+
88+
import Hedgehog
1289
import qualified Hedgehog as H
1390

14-
-- Delay the thread by 'n' milliseconds.
91+
-- | Delay the thread by 'n' milliseconds.
1592
threadDelay :: (MonadTest m, MonadIO m) => Int -> m ()
1693
threadDelay n = GHC.withFrozenCallStack . H.evalIO $ IO.threadDelay n
94+
95+
instance MonadBase IO (ResourceT IO) where
96+
liftBase = liftIO
97+
98+
instance MonadBaseControl IO (ResourceT IO) where
99+
type StM (ResourceT IO) a = a
100+
liftBaseWith = UnliftIO.withRunInIO
101+
restoreM = pure

0 commit comments

Comments
 (0)