mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-16 01:44:03 +03:00
f2931a4d32
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5735 Co-authored-by: Vamshi Surabhi <6562944+0x777@users.noreply.github.com> Co-authored-by: Alexis King <759911+lexi-lambda@users.noreply.github.com> Co-authored-by: Rakesh Emmadi <12475069+rakeshkky@users.noreply.github.com> Co-authored-by: Auke Booij <164426+abooij@users.noreply.github.com> Co-authored-by: Brandon Simmons <210815+jberryman@users.noreply.github.com> Co-authored-by: Lyndon Maydwell <92299+sordina@users.noreply.github.com> Co-authored-by: Anon Ray <616387+ecthiender@users.noreply.github.com> Co-authored-by: Evie Ciobanu <1017953+eviefp@users.noreply.github.com> Co-authored-by: Swann Moreau <62569634+evertedsphere@users.noreply.github.com> Co-authored-by: jkachmar <8461423+jkachmar@users.noreply.github.com> Co-authored-by: Robert <132113+robx@users.noreply.github.com> Co-authored-by: awjchen <13142944+awjchen@users.noreply.github.com> Co-authored-by: Karthikeyan Chinnakonda <15602904+codingkarthik@users.noreply.github.com> Co-authored-by: Tom Harding <6302310+i-am-tom@users.noreply.github.com> GitOrigin-RevId: 6a3940b2596fc178379b85d5fa79bd9ac83457e2
138 lines
4.0 KiB
Haskell
138 lines
4.0 KiB
Haskell
{-# LANGUAGE BlockArguments #-}
|
|
{-# LANGUAGE LambdaCase #-}
|
|
{-# LANGUAGE NamedFieldPuns #-}
|
|
{-# LANGUAGE NumericUnderscores #-}
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
|
|
{-# HLINT ignore "Use sleep" #-}
|
|
|
|
module Main (main) where
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
import Control.Concurrent (forkIO, threadDelay)
|
|
import Control.Monad.Trans.Class (MonadTrans (lift))
|
|
import Control.Monad.Trans.Except (runExceptT)
|
|
import Data.ByteString.Char8 qualified as BS
|
|
import Database.PG.Query
|
|
import Interrupt (specInterrupt)
|
|
import Jsonb (specJsonb)
|
|
import System.Environment qualified as Env
|
|
import Test.Hspec (describe, hspec, it, shouldReturn)
|
|
import Timeout (specTimeout)
|
|
import Prelude
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
{- Note [Running tests]
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
The tests in this module expect a postgres instance running. No setup is
|
|
required, these tests do not run any query on the database. The only requirement
|
|
is that the environment variable DATABASE_URL is set such that it is a valid
|
|
connection string to this instance (e.g.
|
|
"postgres://user:pass@127.0.0.1:5432/instance?sslmode=disable").
|
|
|
|
TODO: run these tests as part of CI.
|
|
-}
|
|
|
|
main :: IO ()
|
|
main = hspec $ do
|
|
describe "acquiring connections" do
|
|
it "acquire a single available resource" do
|
|
simpleTest `shouldReturn` Nothing
|
|
it "error when no connections available" do
|
|
noConnectionAvailable `shouldReturn` Nothing
|
|
it "release and acquire works correctly" do
|
|
releaseAndAcquire `shouldReturn` Nothing
|
|
it "release and acquire works correctly" do
|
|
releaseAndAcquireWithTimeout `shouldReturn` Nothing
|
|
it "time out works correctly" do
|
|
releaseAndAcquireWithTimeoutNegative `shouldReturn` Nothing
|
|
specInterrupt
|
|
specTimeout
|
|
specJsonb
|
|
|
|
mkPool :: IO PGPool
|
|
mkPool = do
|
|
dbUri <- BS.pack <$> Env.getEnv "DATABASE_URL"
|
|
initPGPool (connInfo dbUri) connParams logger
|
|
where
|
|
connInfo uri = ConnInfo {ciRetries, ciDetails = mkDetails uri}
|
|
ciRetries = 0
|
|
mkDetails = CDDatabaseURI
|
|
logger = mempty
|
|
connParams = ConnParams 1 1 60 True Nothing (Just 3) False
|
|
|
|
withFreshPool ::
|
|
(FromPGConnErr e) =>
|
|
PGPool ->
|
|
IO a ->
|
|
IO (Either e a)
|
|
withFreshPool pool action =
|
|
runExceptT
|
|
. withConn pool
|
|
. const
|
|
$ lift action
|
|
|
|
err :: Show a => a -> IO (Maybe String)
|
|
err = pure . Just . show
|
|
|
|
nada :: IO ()
|
|
nada = mempty
|
|
|
|
simpleTest :: IO (Maybe String)
|
|
simpleTest = do
|
|
pool <- mkPool
|
|
withFreshPool pool nada >>= \case
|
|
Left (e :: PGExecErr) -> err e
|
|
Right _ -> mempty
|
|
|
|
noConnectionAvailable :: IO (Maybe String)
|
|
noConnectionAvailable = do
|
|
pool <- mkPool
|
|
withFreshPool pool (action pool) >>= \case
|
|
Left (e :: PGExecErr) -> err e
|
|
Right _ -> mempty
|
|
where
|
|
action pool =
|
|
withFreshPool pool nada >>= \case
|
|
Left (_ :: PGExecErr) -> mempty
|
|
Right _ -> err "connection acquisition expected to fail"
|
|
|
|
releaseAndAcquire :: IO (Maybe String)
|
|
releaseAndAcquire = do
|
|
pool <- mkPool
|
|
_ <-
|
|
withFreshPool pool nada >>= \case
|
|
Left (e :: PGExecErr) -> err e
|
|
Right _ -> mempty
|
|
withFreshPool pool nada >>= \case
|
|
Left (e :: PGExecErr) -> err e
|
|
Right _ -> mempty
|
|
|
|
releaseAndAcquireWithTimeout :: IO (Maybe String)
|
|
releaseAndAcquireWithTimeout = do
|
|
pool <- mkPool
|
|
_ <-
|
|
forkIO $
|
|
withFreshPool pool (threadDelay 300_000) >>= \case
|
|
Left (_ :: PGExecErr) -> error "unexpected error when acquiring connections"
|
|
Right _ -> mempty
|
|
threadDelay 100_000
|
|
withFreshPool pool nada >>= \case
|
|
Left (e :: PGExecErr) -> err e
|
|
Right _ -> mempty
|
|
|
|
releaseAndAcquireWithTimeoutNegative :: IO (Maybe String)
|
|
releaseAndAcquireWithTimeoutNegative = do
|
|
pool <- mkPool
|
|
_ <-
|
|
forkIO $
|
|
withFreshPool pool (threadDelay 10_000_000) >>= \case
|
|
Left (_ :: PGExecErr) -> error "unexpected error when acquiring connections"
|
|
Right _ -> mempty
|
|
threadDelay 1_000_000
|
|
withFreshPool pool nada >>= \case
|
|
Left (_ :: PGExecErr) -> mempty
|
|
Right _ -> err "Wat"
|