@@ -8,11 +8,17 @@ import Data.Either
8
8
import qualified Data.ByteString as B
9
9
import qualified Data.ByteString.Char8 as BS
10
10
import qualified Data.Vector as V
11
+ import System.Socket (SocketException (.. ))
12
+ import System.Mem.Weak (Weak , deRefWeak )
13
+ import Control.Concurrent (throwTo )
14
+ import Control.Concurrent.Async
15
+ import Control.Exception
11
16
12
17
import Test.Tasty
13
18
import Test.Tasty.HUnit
14
19
15
20
import Database.PostgreSQL.Driver.Connection
21
+ import Database.PostgreSQL.Driver.RawConnection
16
22
import Database.PostgreSQL.Driver.StatementStorage
17
23
import Database.PostgreSQL.Driver.Query
18
24
import Database.PostgreSQL.Driver.Error
@@ -25,32 +31,56 @@ longQuery = Query "SELECT pg_sleep(5)" V.empty Text Text NeverCache
25
31
26
32
testFaults :: TestTree
27
33
testFaults = testGroup " Faults"
28
- [ testCase " Single batch by waitReadyForQuery" testBatchReadyForQuery
29
- , testCase " Single batch by readNextData " testBatchNextData
34
+ [ makeInterruptTest " Single batch by waitReadyForQuery"
35
+ testBatchReadyForQuery
36
+ , makeInterruptTest " Single batch by readNextData "
37
+ testBatchNextData
38
+ , makeInterruptTest " Simple Query"
39
+ testSimpleQuery
30
40
]
41
+ where
42
+ makeInterruptTest name action = testGroup name $
43
+ map (\ (caseName, interruptAction) ->
44
+ testCase caseName $ action interruptAction)
45
+ [ (" close" , close)
46
+ , (" close socket" , closeSocket)
47
+ , (" socket exception" , throwSocketException)
48
+ , (" other exception" , throwOtherException)
49
+ ]
31
50
32
- testBatchReadyForQuery :: IO ()
33
- testBatchReadyForQuery = withConnection $ \ c -> do
51
+ testBatchReadyForQuery :: ( Connection -> IO () ) -> IO ()
52
+ testBatchReadyForQuery interruptAction = withConnection $ \ c -> do
34
53
sendBatchAndSync c [longQuery]
35
- interruptConnection c
54
+ interruptAction c
36
55
r <- waitReadyForQuery c
37
56
assertUnexpected r
38
57
39
- testBatchNextData :: IO ()
40
- testBatchNextData = withConnection $ \ c -> do
58
+ testBatchNextData :: ( Connection -> IO () ) -> IO ()
59
+ testBatchNextData interruptAction = withConnection $ \ c -> do
41
60
sendBatchAndSync c [longQuery]
42
- interruptConnection c
61
+ interruptAction c
43
62
r <- readNextData c
44
63
assertUnexpected r
45
64
46
- -- testSimpleQuery :: IO ()
47
- -- testSimpleQuery = withConnection $ \c -> do
48
- -- r <- sendSimpleQuery c "SELECT pg_sleep(5)"
49
- -- interruptConnection c
50
- -- assertUnexpected r
65
+ testSimpleQuery :: (Connection -> IO () ) -> IO ()
66
+ testSimpleQuery interruptAction = withConnection $ \ c -> do
67
+ asyncVar <- async $ sendSimpleQuery c " SELECT pg_sleep(5)"
68
+ interruptAction c
69
+ r <- wait asyncVar
70
+ assertUnexpected r
71
+
72
+ closeSocket :: Connection -> IO ()
73
+ closeSocket = rClose . connRawConnection
74
+
75
+ throwSocketException :: Connection -> IO ()
76
+ throwSocketException conn = do
77
+ let exc = SocketException 2
78
+ maybe (pure () ) (`throwTo` exc) =<< deRefWeak (connReceiverThread conn)
51
79
52
- interruptConnection :: Connection -> IO ()
53
- interruptConnection = close
80
+ throwOtherException :: Connection -> IO ()
81
+ throwOtherException conn = do
82
+ let exc = PatternMatchFail " custom exc"
83
+ maybe (pure () ) (`throwTo` exc) =<< deRefWeak (connReceiverThread conn)
54
84
55
85
assertUnexpected :: Show a => Either Error a -> Assertion
56
86
assertUnexpected (Left (UnexpectedError _)) = pure ()
0 commit comments