graphql-engine/server/lib/pg-client-hs/test/Spec.hs
kodiakhq[bot] f2931a4d32 server: import pg-client-hs with history
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
2022-09-14 14:51:34 +00:00

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"