mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-08-28 00:44:38 +00:00
agent: add reopenStore function for postgres; run notification tests with postgres (#1435)
This commit is contained in:
+1
-1
@@ -414,6 +414,7 @@ test-suite simplexmq-test
|
||||
AgentTests.EqInstances
|
||||
AgentTests.FunctionalAPITests
|
||||
AgentTests.MigrationTests
|
||||
AgentTests.NotificationTests
|
||||
AgentTests.ServerChoice
|
||||
CLITests
|
||||
CoreTests.BatchingTests
|
||||
@@ -446,7 +447,6 @@ test-suite simplexmq-test
|
||||
Paths_simplexmq
|
||||
if !flag(client_postgres)
|
||||
other-modules:
|
||||
AgentTests.NotificationTests
|
||||
AgentTests.SchemaDump
|
||||
AgentTests.SQLiteTests
|
||||
hs-source-dirs:
|
||||
|
||||
@@ -73,6 +73,9 @@ createStore dbFilePath dbKey keepKey = Store.createDBStore dbFilePath dbKey keep
|
||||
closeStore :: DBStore -> IO ()
|
||||
closeStore = Store.closeDBStore
|
||||
|
||||
reopenStore :: DBStore -> IO ()
|
||||
reopenStore = Store.reopenDBStore
|
||||
|
||||
execSQL :: DB.Connection -> Text -> IO [Text]
|
||||
execSQL = Store.execSQL
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE NamedFieldPuns #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
@@ -6,7 +7,8 @@
|
||||
module Simplex.Messaging.Agent.Store.Postgres
|
||||
( createDBStore,
|
||||
closeDBStore,
|
||||
execSQL
|
||||
reopenDBStore,
|
||||
execSQL,
|
||||
)
|
||||
where
|
||||
|
||||
@@ -15,7 +17,7 @@ import Control.Monad (unless, void)
|
||||
import Data.Functor (($>))
|
||||
import Data.String (fromString)
|
||||
import Data.Text (Text)
|
||||
import Database.PostgreSQL.Simple (ConnectInfo (..), Only (..), defaultConnectInfo)
|
||||
import Database.PostgreSQL.Simple (ConnectInfo (..), Only (..))
|
||||
import qualified Database.PostgreSQL.Simple as PSQL
|
||||
import Database.PostgreSQL.Simple.SqlQQ (sql)
|
||||
import Simplex.Messaging.Agent.Store.Migrations (migrateSchema)
|
||||
@@ -24,7 +26,7 @@ import qualified Simplex.Messaging.Agent.Store.Postgres.DB as DB
|
||||
import Simplex.Messaging.Agent.Store.Postgres.Util (createDBAndUserIfNotExists)
|
||||
import Simplex.Messaging.Agent.Store.Shared (Migration (..), MigrationConfirmation (..), MigrationError (..))
|
||||
import Simplex.Messaging.Util (ifM)
|
||||
import UnliftIO.Exception (onException)
|
||||
import UnliftIO.Exception (bracketOnError, onException)
|
||||
import UnliftIO.MVar
|
||||
import UnliftIO.STM
|
||||
|
||||
@@ -44,11 +46,11 @@ createDBStore connectInfo schema migrations confirmMigrations = do
|
||||
Left e -> closeDBStore st $> Left e
|
||||
|
||||
connectPostgresStore :: ConnectInfo -> String -> IO DBStore
|
||||
connectPostgresStore dbConnectInfo schema = do
|
||||
(dbConn, dbNew) <- connectDB dbConnectInfo schema -- TODO [postgres] analogue for dbBusyLoop?
|
||||
connectPostgresStore dbConnectInfo dbSchema = do
|
||||
(dbConn, dbNew) <- connectDB dbConnectInfo dbSchema -- TODO [postgres] analogue for dbBusyLoop?
|
||||
dbConnection <- newMVar dbConn
|
||||
dbClosed <- newTVarIO False
|
||||
pure DBStore {dbConnectInfo, dbConnection, dbNew, dbClosed}
|
||||
pure DBStore {dbConnectInfo, dbSchema, dbConnection, dbNew, dbClosed}
|
||||
|
||||
connectDB :: ConnectInfo -> String -> IO (DB.Connection, Bool)
|
||||
connectDB dbConnectInfo schema = do
|
||||
@@ -81,6 +83,22 @@ closeDBStore st@DBStore {dbClosed} =
|
||||
DB.close conn
|
||||
atomically $ writeTVar dbClosed True
|
||||
|
||||
openPostgresStore_ :: DBStore -> IO ()
|
||||
openPostgresStore_ DBStore {dbConnectInfo, dbSchema, dbConnection, dbClosed} =
|
||||
bracketOnError
|
||||
(takeMVar dbConnection)
|
||||
(tryPutMVar dbConnection)
|
||||
$ \_dbConn -> do
|
||||
(dbConn, _dbNew) <- connectDB dbConnectInfo dbSchema
|
||||
atomically $ writeTVar dbClosed False
|
||||
putMVar dbConnection dbConn
|
||||
|
||||
reopenDBStore :: DBStore -> IO ()
|
||||
reopenDBStore st@DBStore {dbClosed} =
|
||||
ifM (readTVarIO dbClosed) open (putStrLn "reopenDBStore: already opened")
|
||||
where
|
||||
open = openPostgresStore_ st
|
||||
|
||||
-- TODO [postgres] not necessary for postgres (used for ExecAgentStoreSQL, ExecChatStoreSQL)
|
||||
execSQL :: PSQL.Connection -> Text -> IO [Text]
|
||||
execSQL _db _query = throwIO (userError "not implemented")
|
||||
|
||||
@@ -17,6 +17,7 @@ import UnliftIO.STM
|
||||
-- TODO [postgres] use log_min_duration_statement instead of custom slow queries (SQLite's Connection type)
|
||||
data DBStore = DBStore
|
||||
{ dbConnectInfo :: PSQL.ConnectInfo,
|
||||
dbSchema :: String,
|
||||
dbConnection :: MVar PSQL.Connection,
|
||||
dbClosed :: TVar Bool,
|
||||
dbNew :: Bool
|
||||
|
||||
@@ -208,7 +208,7 @@ CREATE TABLE ntf_tokens(
|
||||
tkn_action BYTEA,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT (now()),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT (now()),
|
||||
ntf_mode TEXT NULL,
|
||||
ntf_mode BYTEA NULL,
|
||||
PRIMARY KEY(provider, device_token, ntf_host, ntf_port),
|
||||
FOREIGN KEY(ntf_host, ntf_port) REFERENCES ntf_servers
|
||||
ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
@@ -222,8 +222,8 @@ CREATE TABLE ntf_subscriptions(
|
||||
ntf_port TEXT NOT NULL,
|
||||
ntf_sub_id BYTEA,
|
||||
ntf_sub_status TEXT NOT NULL,
|
||||
ntf_sub_action TEXT,
|
||||
ntf_sub_smp_action TEXT,
|
||||
ntf_sub_action BYTEA,
|
||||
ntf_sub_smp_action BYTEA,
|
||||
ntf_sub_action_ts TIMESTAMPTZ,
|
||||
updated_by_supervisor SMALLINT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT (now()),
|
||||
|
||||
@@ -27,13 +27,12 @@
|
||||
module Simplex.Messaging.Agent.Store.SQLite
|
||||
( createDBStore,
|
||||
closeDBStore,
|
||||
reopenDBStore,
|
||||
execSQL,
|
||||
-- used in Simplex.Chat.Archive
|
||||
sqlString,
|
||||
keyString,
|
||||
storeKey,
|
||||
-- used in Simplex.Chat.Mobile and tests
|
||||
reopenSQLiteStore,
|
||||
-- used in tests
|
||||
connectSQLiteStore,
|
||||
openSQLiteStore,
|
||||
@@ -127,14 +126,14 @@ openSQLiteStore_ DBStore {dbConnection, dbFilePath, dbKey, dbClosed} key keepKey
|
||||
writeTVar dbKey $! storeKey key keepKey
|
||||
putMVar dbConnection DB.Connection {conn, slow}
|
||||
|
||||
reopenSQLiteStore :: DBStore -> IO ()
|
||||
reopenSQLiteStore st@DBStore {dbKey, dbClosed} =
|
||||
ifM (readTVarIO dbClosed) open (putStrLn "reopenSQLiteStore: already opened")
|
||||
reopenDBStore :: DBStore -> IO ()
|
||||
reopenDBStore st@DBStore {dbKey, dbClosed} =
|
||||
ifM (readTVarIO dbClosed) open (putStrLn "reopenDBStore: already opened")
|
||||
where
|
||||
open =
|
||||
readTVarIO dbKey >>= \case
|
||||
Just key -> openSQLiteStore_ st key True
|
||||
Nothing -> fail "reopenSQLiteStore: no key"
|
||||
Nothing -> fail "reopenDBStore: no key"
|
||||
|
||||
keyString :: ScrubbedBytes -> Text
|
||||
keyString = sqlString . safeDecodeUtf8 . BA.convert
|
||||
|
||||
+6
-6
@@ -12,6 +12,7 @@ import AgentTests.ConnectionRequestTests
|
||||
import AgentTests.DoubleRatchetTests (doubleRatchetTests)
|
||||
import AgentTests.FunctionalAPITests (functionalAPITests)
|
||||
import AgentTests.MigrationTests (migrationTests)
|
||||
import AgentTests.NotificationTests (notificationTests)
|
||||
import AgentTests.ServerChoice (serverChoiceTests)
|
||||
import Simplex.Messaging.Transport (ATransport (..))
|
||||
import Test.Hspec
|
||||
@@ -19,7 +20,6 @@ import Test.Hspec
|
||||
import Fixtures
|
||||
import Simplex.Messaging.Agent.Store.Postgres.Util (dropAllSchemasExceptSystem)
|
||||
#else
|
||||
import AgentTests.NotificationTests (notificationTests)
|
||||
import AgentTests.SQLiteTests (storeTests)
|
||||
#endif
|
||||
|
||||
@@ -30,12 +30,12 @@ agentTests (ATransport t) = do
|
||||
describe "Double ratchet tests" doubleRatchetTests
|
||||
#if defined(dbPostgres)
|
||||
after_ (dropAllSchemasExceptSystem testDBConnectInfo) $ do
|
||||
#else
|
||||
do
|
||||
#endif
|
||||
describe "Functional API" $ functionalAPITests (ATransport t)
|
||||
describe "Chosen servers" serverChoiceTests
|
||||
#else
|
||||
describe "Functional API" $ functionalAPITests (ATransport t)
|
||||
describe "Chosen servers" serverChoiceTests
|
||||
-- notifications aren't tested with postgres, as we don't plan to use iOS client with it
|
||||
describe "Notification tests" $ notificationTests (ATransport t)
|
||||
describe "Notification tests" $ notificationTests (ATransport t)
|
||||
#if !defined(dbPostgres)
|
||||
describe "SQLite store" storeTests
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
{-# LANGUAGE GADTs #-}
|
||||
@@ -53,7 +54,6 @@ import qualified Data.ByteString.Char8 as B
|
||||
import Data.List.NonEmpty (NonEmpty (..))
|
||||
import qualified Data.List.NonEmpty as L
|
||||
import Data.Text.Encoding (encodeUtf8)
|
||||
import Database.SQLite.Simple.QQ (sql)
|
||||
import NtfClient
|
||||
import SMPAgentClient (agentCfg, initAgentServers, initAgentServers2, testDB, testDB2, testNtfServer, testNtfServer2)
|
||||
import SMPClient (cfg, cfgVPrev, testPort, testPort2, testStoreLogFile2, testStoreMsgsDir2, withSmpServer, withSmpServerConfigOn, withSmpServerStoreLogOn, withSmpServerStoreMsgLogOn)
|
||||
@@ -62,9 +62,9 @@ import Simplex.Messaging.Agent.Client (ProtocolTestFailure (..), ProtocolTestSte
|
||||
import Simplex.Messaging.Agent.Env.SQLite (AgentConfig, Env (..), InitialAgentServers)
|
||||
import Simplex.Messaging.Agent.Protocol hiding (CON, CONF, INFO, SENT)
|
||||
import Simplex.Messaging.Agent.Store.AgentStore (getSavedNtfToken)
|
||||
import Simplex.Messaging.Agent.Store.SQLite (closeDBStore, reopenSQLiteStore)
|
||||
import Simplex.Messaging.Agent.Store.SQLite.Common (withTransaction)
|
||||
import qualified Simplex.Messaging.Agent.Store.SQLite.DB as DB
|
||||
import Simplex.Messaging.Agent.Store (closeStore, reopenStore)
|
||||
import Simplex.Messaging.Agent.Store.Common (withTransaction)
|
||||
import qualified Simplex.Messaging.Agent.Store.DB as DB
|
||||
import qualified Simplex.Messaging.Crypto as C
|
||||
import Simplex.Messaging.Encoding.String
|
||||
import Simplex.Messaging.Notifications.Protocol
|
||||
@@ -78,6 +78,11 @@ import Simplex.Messaging.Server.Env.STM (ServerConfig (..))
|
||||
import Simplex.Messaging.Transport (ATransport)
|
||||
import Test.Hspec
|
||||
import UnliftIO
|
||||
#if defined(dbPostgres)
|
||||
import Database.PostgreSQL.Simple.SqlQQ (sql)
|
||||
#else
|
||||
import Database.SQLite.Simple.QQ (sql)
|
||||
#endif
|
||||
|
||||
notificationTests :: ATransport -> Spec
|
||||
notificationTests t = do
|
||||
@@ -496,7 +501,7 @@ testNotificationSubscriptionExistingConnection apns baseId alice@AgentClient {ag
|
||||
|
||||
threadDelay 500000
|
||||
suspendAgent alice 0
|
||||
closeDBStore store
|
||||
closeStore store
|
||||
threadDelay 1000000
|
||||
putStrLn "before opening the database from another agent"
|
||||
|
||||
@@ -507,7 +512,7 @@ testNotificationSubscriptionExistingConnection apns baseId alice@AgentClient {ag
|
||||
|
||||
threadDelay 1000000
|
||||
putStrLn "after closing the database in another agent"
|
||||
reopenSQLiteStore store
|
||||
reopenStore store
|
||||
foregroundAgent alice
|
||||
threadDelay 500000
|
||||
|
||||
|
||||
@@ -604,7 +604,7 @@ testCloseReopenStore = do
|
||||
hasMigrations st
|
||||
closeDBStore st
|
||||
errorGettingMigrations st
|
||||
reopenSQLiteStore st
|
||||
reopenDBStore st
|
||||
hasMigrations st
|
||||
|
||||
testCloseReopenEncryptedStore :: IO ()
|
||||
@@ -615,13 +615,13 @@ testCloseReopenEncryptedStore = do
|
||||
closeDBStore st
|
||||
closeDBStore st
|
||||
errorGettingMigrations st
|
||||
reopenSQLiteStore st `shouldThrow` \(e :: SomeException) -> "reopenSQLiteStore: no key" `isInfixOf` show e
|
||||
reopenDBStore st `shouldThrow` \(e :: SomeException) -> "reopenDBStore: no key" `isInfixOf` show e
|
||||
openSQLiteStore st key True
|
||||
openSQLiteStore st key True
|
||||
hasMigrations st
|
||||
closeDBStore st
|
||||
errorGettingMigrations st
|
||||
reopenSQLiteStore st
|
||||
reopenDBStore st
|
||||
hasMigrations st
|
||||
|
||||
testReopenEncryptedStoreKeepKey :: IO ()
|
||||
@@ -631,7 +631,7 @@ testReopenEncryptedStoreKeepKey = do
|
||||
hasMigrations st
|
||||
closeDBStore st
|
||||
errorGettingMigrations st
|
||||
reopenSQLiteStore st
|
||||
reopenDBStore st
|
||||
hasMigrations st
|
||||
|
||||
getMigrations :: DBStore -> IO Bool
|
||||
|
||||
Reference in New Issue
Block a user