{-# LANGUAGE OverloadedStrings #-} module ThreadSpec where import Control.Concurrent import Control.Concurrent.Async import Data.ByteString (ByteString) import qualified Data.ByteString.Lazy as L import Data.Foldable (traverse_) import Network.TLS import Test.Hspec import Test.Hspec.QuickCheck import API import Arbitrary () import Run spec :: Spec spec = do describe "thread safety" $ do prop "can read/write concurrently" $ \params -> runTLS params tlsClient tlsServer tlsClient :: Chan ByteString -> Context -> IO () tlsClient queue ctx = do handshake ctx runReaderWriters ctx "server-value" "client-value" d <- readChan queue sendData ctx (L.fromChunks [d]) checkCtxFinished ctx bye ctx tlsServer :: Context -> Chan [ByteString] -> IO () tlsServer ctx queue = do handshake ctx runReaderWriters ctx "client-value" "server-value" d <- recvData ctx writeChan queue [d] checkCtxFinished ctx bye ctx runReaderWriters :: Context -> ByteString -> L.ByteString -> IO () runReaderWriters ctx r w = -- run concurrently 10 readers and 10 writers on the same context let workers = concat $ replicate 10 [recvDataAssert ctx r, sendData ctx w] in runConcurrently $ traverse_ Concurrently workers