@@ -23,6 +23,7 @@ import Control.Monad.Trans.Except
2323import Crypto.Random (ChaChaDRG )
2424import Data.ByteString.Char8 (ByteString )
2525import Data.Int (Int64 )
26+ import qualified Data.Map.Strict as M
2627import Data.Time.Clock.System (getSystemTime )
2728import Simplex.Messaging.Crypto (pattern MaxLenBS )
2829import qualified Simplex.Messaging.Crypto as C
@@ -31,7 +32,9 @@ import Simplex.Messaging.Server.MsgStore.STM
3132import Simplex.Messaging.Server.MsgStore.Types
3233import Simplex.Messaging.Server.QueueStore
3334import Simplex.Messaging.Server.QueueStore.QueueInfo
35+ import Simplex.Messaging.Server.QueueStore.STM (STMQueueStore (.. ))
3436import Simplex.Messaging.Server.QueueStore.Types
37+ import Simplex.Messaging.TMap (TMap )
3538import Test.Hspec hiding (fit , it )
3639import Util
3740
@@ -50,7 +53,9 @@ import SMPClient (testStoreDBOpts)
5053
5154msgStoreTests :: Spec
5255msgStoreTests = do
53- describe " STM message store" $ someMsgStoreTests testSMTStoreConfig
56+ describe " STM message store" $ do
57+ someMsgStoreTests testSMTStoreConfig
58+ it " should remove deleted queues from queue store maps" $ withMsgStore testSMTStoreConfig testDeleteQueueMaps
5459#if defined(dbServerPostgres)
5560 describe " Postgres-only message store" $ do
5661 someMsgStoreTests testPostgresStoreConfig
@@ -126,6 +131,18 @@ testNewQueueRecData g qm queueData = do
126131 where
127132 rndId = atomically $ EntityId <$> C. randomBytes 24 g
128133
134+ testNtfCreds :: TVar ChaChaDRG -> IO NtfCreds
135+ testNtfCreds g = do
136+ (notifierKey, _) <- atomically $ C. generateAuthKeyPair C. SX25519 g
137+ (k, pk) <- atomically $ C. generateKeyPair @ 'C.X25519 g
138+ pure
139+ NtfCreds
140+ { notifierId = EntityId " ijkl" ,
141+ notifierKey,
142+ rcvNtfDhSecret = C. dh' k pk,
143+ ntfServiceId = Nothing
144+ }
145+
129146testGetQueue :: MsgStoreClass s => s -> IO ()
130147testGetQueue ms = do
131148 g <- C. newRandom
@@ -217,6 +234,56 @@ testLinkDataSecuredQueue ms = do
217234 void $ ExceptT $ deleteQueue ms q
218235 void $ ExceptT $ deleteQueue ms cq
219236
237+ -- sizes of queues, senders, links and notifiers maps
238+ type QueueMapSizes = (Int , Int , Int , Int )
239+
240+ queueMapSizes :: STMMsgStore -> IO QueueMapSizes
241+ queueMapSizes ms = (,,,) <$> size queues <*> size senders <*> size links <*> size notifiers
242+ where
243+ STMQueueStore {queues, senders, links, notifiers} = queueStore ms
244+ size :: TMap k v -> IO Int
245+ size = fmap M. size . readTVarIO
246+
247+ testDeleteQueueMaps :: STMMsgStore -> IO ()
248+ testDeleteQueueMaps ms = do
249+ g <- C. newRandom
250+ ntfCreds <- testNtfCreds g
251+ let newLinkId = atomically $ EntityId <$> C. randomBytes 24 g
252+ lnkId1 <- newLinkId
253+ lnkId2 <- newLinkId
254+ lnkId3 <- newLinkId
255+ (rId1, qr1) <- testNewQueueRec g QMMessaging
256+ (rId2, qr2) <- testNewQueueRecData g QMContact (Just (lnkId1, testLinkData))
257+ (rId3, qr3) <- testNewQueueRec g QMMessaging
258+ (rId4, qr4) <- testNewQueueRec g QMMessaging
259+ let rIds = [rId1, rId2, rId3, rId4] :: [RecipientId ]
260+ sIds = map senderId [qr1, qr2, qr3, qr4]
261+ lnkIds = [lnkId1, lnkId2, lnkId3] :: [LinkId ]
262+ queueMapSizes ms `shouldReturn` (0 , 0 , 0 , 0 )
263+ runRight_ $ do
264+ q1 <- ExceptT $ addQueue ms rId1 qr1 {notifier = Just ntfCreds}
265+ q2 <- ExceptT $ addQueue ms rId2 qr2
266+ q3 <- ExceptT $ addQueue ms rId3 qr3
267+ q4 <- ExceptT $ addQueue ms rId4 qr4
268+ ExceptT $ addQueueLinkData (queueStore ms) q3 lnkId2 testLinkData
269+ ExceptT $ addQueueLinkData (queueStore ms) q4 lnkId3 testLinkData
270+ forM_ sIds $ void . ExceptT . getQueue ms SSender
271+ forM_ lnkIds $ void . ExceptT . getQueue ms SSenderLink
272+ liftIO $ queueMapSizes ms `shouldReturn` (4 , 4 , 3 , 1 )
273+ ExceptT $ deleteQueueLinkData (queueStore ms) q3
274+ liftIO $ queueMapSizes ms `shouldReturn` (4 , 4 , 2 , 1 )
275+ forM_ ([q1, q2, q3, q4] :: [STMQueue ]) $ void . ExceptT . deleteQueue ms
276+ queueMapSizes ms `shouldReturn` (0 , 0 , 0 , 0 )
277+ forM_ rIds $ \ rId -> getQueue ms SRecipient rId >>= expectAuth
278+ forM_ sIds $ \ sId -> getQueue ms SSender sId >>= expectAuth
279+ forM_ lnkIds $ \ lnkId -> getQueue ms SSenderLink lnkId >>= expectAuth
280+ queueMapSizes ms `shouldReturn` (0 , 0 , 0 , 0 )
281+ where
282+ expectAuth = either (`shouldBe` AUTH ) (\ _ -> expectationFailure " deleted queue is still found" )
283+
284+ testLinkData :: QueueLinkData
285+ testLinkData = (EncDataBytes " fixed data" , EncDataBytes " user data" )
286+
220287#if defined(dbServerPostgres)
221288testUpdateMessageCounts :: PostgresMsgStore -> IO ()
222289testUpdateMessageCounts ms = do
0 commit comments