Skip to content

Commit

Permalink
tests wip
Browse files Browse the repository at this point in the history
  • Loading branch information
spaced4ndy committed Dec 16, 2024
1 parent e8803b8 commit ce69f74
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 49 deletions.
11 changes: 1 addition & 10 deletions src/Simplex/FileTransfer/Description.hs
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ import Simplex.Messaging.Protocol (XFTPServer)
import Simplex.Messaging.ServiceScheme (ServiceScheme (..))
import Simplex.Messaging.Util (bshow, safeDecodeUtf8, (<$?>))
#if defined(dbPostgres)
import Database.PostgreSQL.Simple (ResultError (..))
import Database.PostgreSQL.Simple.FromField (FromField (..), returnError)
import Database.PostgreSQL.Simple.FromField (FromField (..))
import Database.PostgreSQL.Simple.ToField (ToField (..))
#else
import Database.SQLite.Simple.FromField (FromField (..))
Expand Down Expand Up @@ -301,14 +300,6 @@ instance (Integral a, Show a) => IsString (FileSize a) where

#if defined(dbPostgres)
instance FromField a => FromField (FileSize a) where fromField = fromField

-- TODO [postgres] orphan instance
instance FromField Word32 where
fromField field mData = do
i <- fromField field mData
if i >= (0 :: Int64)
then pure (fromIntegral i :: Word32)
else returnError ConversionFailed field "Negative value can't be converted to Word32"
#else
instance FromField a => FromField (FileSize a) where fromField f = FileSize <$> fromField f
#endif
Expand Down
7 changes: 5 additions & 2 deletions src/Simplex/Messaging/Agent/Store/AgentStore.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1727,7 +1727,10 @@ instance FromField MsgReceiptStatus where fromField = fromTextField_ $ eitherToM
instance ToField (Version v) where toField (Version v) = toField v

#if defined(dbPostgres)
instance FromField (Version v) where fromField = fromField
instance FromField (Version v) where
fromField field mData = do
i <- fromField field mData
pure $ Version i
#else
instance FromField (Version v) where fromField f = Version <$> fromField f
#endif
Expand Down Expand Up @@ -1909,7 +1912,7 @@ getConnData db connId' =
|]
(Only connId')
where
cData (userId, connId, cMode, connAgentVersion, enableNtfs_, lastExternalSndId, deleted, ratchetSyncState, pqSupport) =
cData (userId, connId, cMode, connAgentVersion, enableNtfs_, lastExternalSndId, BI deleted, ratchetSyncState, pqSupport) =
(ConnData {userId, connId, connAgentVersion, enableNtfs = maybe True unBI enableNtfs_, lastExternalSndId, deleted, ratchetSyncState, pqSupport}, cMode)

setConnDeleted :: DB.Connection -> Bool -> ConnId -> IO ()
Expand Down
73 changes: 40 additions & 33 deletions src/Simplex/Messaging/Agent/Store/Postgres.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ module Simplex.Messaging.Agent.Store.Postgres
createDBAndUserIfNotExists,
dropSchema,
dropAllSchemasExceptSystem,
dropDatabaseAndUser,
dropDatabaseAndUserIfExists,
)
where

import Control.Exception (bracket, throwIO)
import Control.Monad (forM_, unless, void)
import Control.Monad (forM_, unless, void, when)
import Data.Functor (($>))
import Data.String (fromString)
import Data.Text (Text)
Expand Down Expand Up @@ -59,31 +59,36 @@ createDBAndUserIfNotExists :: ConnectInfo -> IO ()
createDBAndUserIfNotExists ConnectInfo {connectUser = user, connectDatabase = dbName} = do
-- connect to the default "postgres" maintenance database
bracket (PSQL.connect defaultConnectInfo {connectUser = "postgres", connectDatabase = "postgres"}) PSQL.close $
\db -> do
\postgresDB -> do
-- check if the user exists, create if not
[Only userExists] <-
PSQL.query
db
postgresDB
[sql|
SELECT EXISTS (
SELECT 1 FROM pg_catalog.pg_roles
WHERE rolname = ?
)
|]
(Only user)
unless userExists $ void $ PSQL.execute_ db (fromString $ "CREATE USER " <> user)
unless userExists $ void $ PSQL.execute_ postgresDB (fromString $ "CREATE USER " <> user)
-- check if the database exists, create if not
[Only dbExists] <-
PSQL.query
db
[sql|
SELECT EXISTS (
SELECT 1 FROM pg_catalog.pg_database
WHERE datname = ?
)
|]
(Only dbName)
unless dbExists $ void $ PSQL.execute_ db (fromString $ "CREATE DATABASE " <> dbName <> " OWNER " <> user)
dbExists <- checkDBExists postgresDB dbName
unless dbExists $ void $ PSQL.execute_ postgresDB (fromString $ "CREATE DATABASE " <> dbName <> " OWNER " <> user)

checkDBExists :: PSQL.Connection -> String -> IO Bool
checkDBExists postgresDB dbName = do
[Only dbExists] <-
PSQL.query
postgresDB
[sql|
SELECT EXISTS (
SELECT 1 FROM pg_catalog.pg_database
WHERE datname = ?
)
|]
(Only dbName)
pure dbExists

connectPostgresStore :: ConnectInfo -> String -> IO DBStore
connectPostgresStore dbConnectInfo schema = do
Expand Down Expand Up @@ -147,21 +152,23 @@ dropAllSchemasExceptSystem connectInfo =
forM_ schemaNames $ \(Only schema) ->
PSQL.execute_ db (fromString $ "DROP SCHEMA " <> schema <> " CASCADE")

dropDatabaseAndUser :: ConnectInfo -> IO ()
dropDatabaseAndUser ConnectInfo {connectUser = user, connectDatabase = dbName} =
dropDatabaseAndUserIfExists :: ConnectInfo -> IO ()
dropDatabaseAndUserIfExists ConnectInfo {connectUser = user, connectDatabase = dbName} =
bracket (PSQL.connect defaultConnectInfo {connectUser = "postgres", connectDatabase = "postgres"}) PSQL.close $
\db -> do
void $ PSQL.execute_ db (fromString $ "ALTER DATABASE " <> dbName <> " WITH ALLOW_CONNECTIONS false")
-- terminate all connections to the database
_r :: [Only Bool] <-
PSQL.query
db
[sql|
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = ?
AND pid <> pg_backend_pid()
|]
(Only dbName)
void $ PSQL.execute_ db (fromString $ "DROP DATABASE " <> dbName)
void $ PSQL.execute_ db (fromString $ "DROP USER " <> user)
\postgresDB -> do
dbExists <- checkDBExists postgresDB dbName
when dbExists $ do
void $ PSQL.execute_ postgresDB (fromString $ "ALTER DATABASE " <> dbName <> " WITH ALLOW_CONNECTIONS false")
-- terminate all connections to the database
_r :: [Only Bool] <-
PSQL.query
postgresDB
[sql|
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = ?
AND pid <> pg_backend_pid()
|]
(Only dbName)
void $ PSQL.execute_ postgresDB (fromString $ "DROP DATABASE " <> dbName)
void $ PSQL.execute_ postgresDB (fromString $ "DROP USER IF EXISTS " <> user)
24 changes: 23 additions & 1 deletion src/Simplex/Messaging/Agent/Store/Postgres/DB.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ module Simplex.Messaging.Agent.Store.Postgres.DB
where

import Control.Monad (void)
import Data.Int (Int32, Int64)
import Data.Word (Word16, Word32)
import Database.PostgreSQL.Simple (ResultError (..))
import qualified Database.PostgreSQL.Simple as PSQL
import Database.PostgreSQL.Simple.FromField (FromField (..))
import Database.PostgreSQL.Simple.FromField (FromField (..), returnError)
import Database.PostgreSQL.Simple.ToField (ToField (..))

newtype BoolInt v = BI {unBI :: Bool}
deriving (Eq, Show)

instance FromField (BoolInt v) where
fromField field mData = do
Expand All @@ -41,3 +45,21 @@ execute_ db q = void $ PSQL.execute_ db q
executeMany :: PSQL.ToRow q => PSQL.Connection -> PSQL.Query -> [q] -> IO ()
executeMany db q qs = void $ PSQL.executeMany db q qs
{-# INLINE executeMany #-}

-- orphan instances

-- used in FileSize
instance FromField Word32 where
fromField field mData = do
i <- fromField field mData
if i >= (0 :: Int64)
then pure (fromIntegral i :: Word32)
else returnError ConversionFailed field "Negative value can't be converted to Word32"

-- used in Version
instance FromField Word16 where
fromField field mData = do
i <- fromField field mData
if i >= (0 :: Int32)
then pure (fromIntegral i :: Word16)
else returnError ConversionFailed field "Negative value can't be converted to Word16"
1 change: 1 addition & 0 deletions src/Simplex/Messaging/Agent/Store/SQLite/DB.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import qualified Simplex.Messaging.TMap as TM
import Simplex.Messaging.Util (diffToMilliseconds, tshow)

newtype BoolInt v = BI {unBI :: Bool}
deriving (Eq, Show)
deriving newtype (FromField, ToField)

data Connection = Connection
Expand Down
6 changes: 3 additions & 3 deletions tests/Test.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import XFTPCLI
import XFTPServerTests (xftpServerTests)
#if defined(dbPostgres)
import Fixtures
import Simplex.Messaging.Agent.Store.Postgres (createDBAndUserIfNotExists, dropDatabaseAndUser)
import Simplex.Messaging.Agent.Store.Postgres (createDBAndUserIfNotExists, dropDatabaseAndUserIfExists)
#else
import AgentTests.SchemaDump (schemaDumpTest)
#endif
Expand All @@ -52,8 +52,8 @@ main = do
setEnv "APNS_KEY_FILE" "./tests/fixtures/AuthKey_H82WD9K9AQ.p8"
hspec
#if defined(dbPostgres)
. beforeAll_ (createDBAndUserIfNotExists testDBConnectInfo)
. afterAll_ (dropDatabaseAndUser testDBConnectInfo)
. beforeAll_ (dropDatabaseAndUserIfExists testDBConnectInfo >> createDBAndUserIfNotExists testDBConnectInfo)
. afterAll_ (dropDatabaseAndUserIfExists testDBConnectInfo)
#endif
. before_ (createDirectoryIfMissing False "tests/tmp")
. after_ (eventuallyRemove "tests/tmp" 3)
Expand Down

0 comments on commit ce69f74

Please sign in to comment.