diff --git a/src/Simplex/Messaging/Agent.hs b/src/Simplex/Messaging/Agent.hs index 71680a174..af01e2e59 100644 --- a/src/Simplex/Messaging/Agent.hs +++ b/src/Simplex/Messaging/Agent.hs @@ -54,6 +54,7 @@ module Simplex.Messaging.Agent ackMessage, suspendConnection, deleteConnection, + getConnectionServers, setSMPServers, setNtfServers, registerNtfToken, @@ -194,6 +195,10 @@ suspendConnection c = withAgentEnv c . suspendConnection' c deleteConnection :: AgentErrorMonad m => AgentClient -> ConnId -> m () deleteConnection c = withAgentEnv c . deleteConnection' c +-- | get servers used for connection +getConnectionServers :: AgentErrorMonad m => AgentClient -> ConnId -> m ConnectionStats +getConnectionServers c = withAgentEnv c . getConnectionServers' c + -- | Change servers to be used for creating new queues setSMPServers :: AgentErrorMonad m => AgentClient -> NonEmpty SMPServer -> m () setSMPServers c = withAgentEnv c . setSMPServers' c @@ -273,6 +278,7 @@ processCommand c (connId, cmd) = case cmd of ACK msgId -> ackMessage' c connId msgId $> (connId, OK) OFF -> suspendConnection' c connId $> (connId, OK) DEL -> deleteConnection' c connId $> (connId, OK) + CHK -> (connId,) . STAT <$> getConnectionServers' c connId newConn :: AgentMonad m => AgentClient -> ConnId -> SConnectionMode c -> m (ConnId, ConnectionRequestUri c) newConn c connId cMode = do @@ -708,6 +714,16 @@ deleteConnection' c connId = ns <- asks ntfSupervisor atomically $ writeTBQueue (ntfSubQ ns) (connId, NSCDelete) +getConnectionServers' :: AgentMonad m => AgentClient -> ConnId -> m ConnectionStats +getConnectionServers' c connId = connServers <$> withStore c (`getConn` connId) + where + connServers :: SomeConn -> ConnectionStats + connServers = \case + SomeConn _ (RcvConnection _ RcvQueue {server}) -> ConnectionStats {rcvServers = [server], sndServers = []} + SomeConn _ (SndConnection _ SndQueue {server}) -> ConnectionStats {rcvServers = [], sndServers = [server]} + SomeConn _ (DuplexConnection _ RcvQueue {server = s1} SndQueue {server = s2}) -> ConnectionStats {rcvServers = [s1], sndServers = [s2]} + SomeConn _ (ContactConnection _ RcvQueue {server}) -> ConnectionStats {rcvServers = [server], sndServers = []} + -- | Change servers to be used for creating new queues, in Reader monad setSMPServers' :: AgentMonad m => AgentClient -> NonEmpty SMPServer -> m () setSMPServers' c = atomically . writeTVar (smpServers c) @@ -1064,7 +1080,7 @@ processSMPTransmission c@AgentClient {smpClients, subQ} (srv, v, sessId, rId, cm parseMessage agentMsgBody >>= \case AgentConnInfo connInfo -> processConf connInfo SMPConfirmation {senderKey, e2ePubKey, connInfo, smpReplyQueues = []} False - AgentConnInfoReply smpQueues connInfo -> do + AgentConnInfoReply smpQueues connInfo -> processConf connInfo SMPConfirmation {senderKey, e2ePubKey, connInfo, smpReplyQueues = L.toList smpQueues} True _ -> prohibited where @@ -1074,7 +1090,8 @@ processSMPTransmission c@AgentClient {smpClients, subQ} (srv, v, sessId, rId, cm confId <- withStore c $ \db -> do setHandshakeVersion db connId agentVersion duplexHS createConfirmation db g newConfirmation - notify $ CONF confId connInfo + let srvs = map (\SMPQueueInfo {smpServer = s} -> s) $ smpReplyQueues senderConf + notify $ CONF confId srvs connInfo _ -> prohibited -- party accepting connection (DuplexConnection _ _ sq, Nothing) -> do @@ -1120,14 +1137,15 @@ processSMPTransmission c@AgentClient {smpClients, subQ} (srv, v, sessId, rId, cm _ -> prohibited smpInvitation :: ConnectionRequestUri 'CMInvitation -> ConnInfo -> m () - smpInvitation connReq cInfo = do + smpInvitation connReq@(CRInvitationUri crData _) cInfo = do logServer "<--" c srv rId "MSG " case conn of ContactConnection {} -> do g <- asks idsDrg let newInv = NewInvitation {contactConnId = connId, connReq, recipientConnInfo = cInfo} invId <- withStore c $ \db -> createInvitation db g newInv - notify $ REQ invId cInfo + let srvs = L.map (\SMPQueueUri {smpServer = s} -> s) $ crSmpQueues crData + notify $ REQ invId srvs cInfo _ -> prohibited checkMsgIntegrity :: PrevExternalSndId -> ExternalSndId -> PrevRcvMsgHash -> ByteString -> MsgIntegrity diff --git a/src/Simplex/Messaging/Agent/Client.hs b/src/Simplex/Messaging/Agent/Client.hs index 98d0cb6ea..451a4780c 100644 --- a/src/Simplex/Messaging/Agent/Client.hs +++ b/src/Simplex/Messaging/Agent/Client.hs @@ -342,7 +342,7 @@ newProtocolClient c srv clients connectClient reconnectClient clientVar = tryCon atomically $ putTMVar clientVar r successAction client Left e -> do - if e == BROKER NETWORK || e == BROKER TIMEOUT + if temporaryAgentError e then retryAction else atomically $ do putTMVar clientVar (Left e) diff --git a/src/Simplex/Messaging/Agent/Protocol.hs b/src/Simplex/Messaging/Agent/Protocol.hs index 0f60edf36..ab3ccc068 100644 --- a/src/Simplex/Messaging/Agent/Protocol.hs +++ b/src/Simplex/Messaging/Agent/Protocol.hs @@ -44,6 +44,7 @@ module Simplex.Messaging.Agent.Protocol SAParty (..), MsgHash, MsgMeta (..), + ConnectionStats (..), SMPConfirmation (..), AgentMsgEnvelope (..), AgentMessage (..), @@ -208,9 +209,9 @@ data ACommand (p :: AParty) where NEW :: AConnectionMode -> ACommand Client -- response INV INV :: AConnectionRequestUri -> ACommand Agent JOIN :: AConnectionRequestUri -> ConnInfo -> ACommand Client -- response OK - CONF :: ConfirmationId -> ConnInfo -> ACommand Agent -- ConnInfo is from sender + CONF :: ConfirmationId -> [SMPServer] -> ConnInfo -> ACommand Agent -- ConnInfo is from sender, [SMPServer] will be empty only in v1 handshake LET :: ConfirmationId -> ConnInfo -> ACommand Client -- ConnInfo is from client - REQ :: InvitationId -> ConnInfo -> ACommand Agent -- ConnInfo is from sender + REQ :: InvitationId -> L.NonEmpty SMPServer -> ConnInfo -> ACommand Agent -- ConnInfo is from sender ACPT :: InvitationId -> ConnInfo -> ACommand Client -- ConnInfo is from client RJCT :: InvitationId -> ACommand Client INFO :: ConnInfo -> ACommand Agent @@ -227,6 +228,8 @@ data ACommand (p :: AParty) where ACK :: AgentMsgId -> ACommand Client OFF :: ACommand Client DEL :: ACommand Client + CHK :: ACommand Client + STAT :: ConnectionStats -> ACommand Agent OK :: ACommand Agent ERR :: AgentErrorType -> ACommand Agent SUSPENDED :: ACommand Agent @@ -235,6 +238,22 @@ deriving instance Eq (ACommand p) deriving instance Show (ACommand p) +data ConnectionStats = ConnectionStats + { rcvServers :: [SMPServer], + sndServers :: [SMPServer] + } + deriving (Eq, Show, Generic) + +instance StrEncoding ConnectionStats where + strEncode ConnectionStats {rcvServers, sndServers} = + "rcv=" <> strEncodeList rcvServers <> " snd=" <> strEncodeList sndServers + strP = do + rcvServers <- "rcv=" *> strListP + sndServers <- " snd=" *> strListP + pure ConnectionStats {rcvServers, sndServers} + +instance ToJSON ConnectionStats where toEncoding = J.genericToEncoding J.defaultOptions + data NotificationsMode = NMPeriodic | NMInstant deriving (Eq, Show) @@ -747,7 +766,7 @@ data AgentErrorType AGENT {agentErr :: SMPAgentError} | -- | agent implementation or dependency errors INTERNAL {internalErr :: String} - deriving (Eq, Generic, Read, Show, Exception) + deriving (Eq, Generic, Show, Exception) instance ToJSON AgentErrorType where toJSON = J.genericToJSON $ sumTypeJSON id @@ -882,6 +901,8 @@ commandP = <|> "ACK " *> ackCmd <|> "OFF" $> ACmd SClient OFF <|> "DEL" $> ACmd SClient DEL + <|> "CHK" $> ACmd SClient CHK + <|> "STAT " *> statResp <|> "ERR " *> agentError <|> "CON" $> ACmd SAgent CON <|> "OK" $> ACmd SAgent OK @@ -889,9 +910,9 @@ commandP = newCmd = ACmd SClient . NEW <$> strP invResp = ACmd SAgent . INV <$> strP joinCmd = ACmd SClient .: JOIN <$> strP_ <*> A.takeByteString - confMsg = ACmd SAgent .: CONF <$> A.takeTill (== ' ') <* A.space <*> A.takeByteString + confMsg = ACmd SAgent .:. CONF <$> A.takeTill (== ' ') <* A.space <*> strListP <* A.space <*> A.takeByteString letCmd = ACmd SClient .: LET <$> A.takeTill (== ' ') <* A.space <*> A.takeByteString - reqMsg = ACmd SAgent .: REQ <$> A.takeTill (== ' ') <* A.space <*> A.takeByteString + reqMsg = ACmd SAgent .:. REQ <$> A.takeTill (== ' ') <* A.space <*> strP_ <*> A.takeByteString acptCmd = ACmd SClient .: ACPT <$> A.takeTill (== ' ') <* A.space <*> A.takeByteString rjctCmd = ACmd SClient . RJCT <$> A.takeByteString infoCmd = ACmd SAgent . INFO <$> A.takeByteString @@ -903,6 +924,7 @@ commandP = msgErrResp = ACmd SAgent .: MERR <$> A.decimal <* A.space <*> strP message = ACmd SAgent .:. MSG <$> msgMetaP <* A.space <*> smpP <* A.space <*> A.takeByteString ackCmd = ACmd SClient . ACK <$> A.decimal + statResp = ACmd SAgent . STAT <$> strP connections = strP `A.sepBy'` A.char ',' msgMetaP = do integrity <- strP @@ -922,9 +944,9 @@ serializeCommand = \case NEW cMode -> "NEW " <> strEncode cMode INV cReq -> "INV " <> strEncode cReq JOIN cReq cInfo -> B.unwords ["JOIN", strEncode cReq, serializeBinary cInfo] - CONF confId cInfo -> B.unwords ["CONF", confId, serializeBinary cInfo] + CONF confId srvs cInfo -> B.unwords ["CONF", confId, strEncodeList srvs, serializeBinary cInfo] LET confId cInfo -> B.unwords ["LET", confId, serializeBinary cInfo] - REQ invId cInfo -> B.unwords ["REQ", invId, serializeBinary cInfo] + REQ invId srvs cInfo -> B.unwords ["REQ", invId, strEncode srvs, serializeBinary cInfo] ACPT invId cInfo -> B.unwords ["ACPT", invId, serializeBinary cInfo] RJCT invId -> "RJCT " <> invId INFO cInfo -> "INFO " <> serializeBinary cInfo @@ -940,6 +962,8 @@ serializeCommand = \case ACK mId -> "ACK " <> bshow mId OFF -> "OFF" DEL -> "DEL" + CHK -> "CHK" + STAT srvs -> "STAT " <> strEncode srvs CON -> "CON" ERR e -> "ERR " <> strEncode e OK -> "OK" @@ -1012,9 +1036,9 @@ tGet party h = liftIO (tGetRaw h) >>= tParseLoadBody SEND msgFlags body -> SEND msgFlags <$$> getBody body MSG msgMeta msgFlags body -> MSG msgMeta msgFlags <$$> getBody body JOIN qUri cInfo -> JOIN qUri <$$> getBody cInfo - CONF confId cInfo -> CONF confId <$$> getBody cInfo + CONF confId srvs cInfo -> CONF confId srvs <$$> getBody cInfo LET confId cInfo -> LET confId <$$> getBody cInfo - REQ invId cInfo -> REQ invId <$$> getBody cInfo + REQ invId srvs cInfo -> REQ invId srvs <$$> getBody cInfo ACPT invId cInfo -> ACPT invId <$$> getBody cInfo INFO cInfo -> INFO <$$> getBody cInfo cmd -> pure $ Right cmd diff --git a/tests/AgentTests.hs b/tests/AgentTests.hs index b3d9a9870..83256ffe6 100644 --- a/tests/AgentTests.hs +++ b/tests/AgentTests.hs @@ -126,7 +126,7 @@ testDuplexConnection _ alice bob = do ("1", "bob", Right (INV cReq)) <- alice #: ("1", "bob", "NEW INV") let cReq' = strEncode cReq bob #: ("11", "alice", "JOIN " <> cReq' <> " 14\nbob's connInfo") #> ("11", "alice", OK) - ("", "bob", Right (CONF confId "bob's connInfo")) <- (alice <#:) + ("", "bob", Right (CONF confId _ "bob's connInfo")) <- (alice <#:) alice #: ("2", "bob", "LET " <> confId <> " 16\nalice's connInfo") #> ("2", "bob", OK) bob <# ("", "alice", INFO "alice's connInfo") bob <# ("", "alice", CON) @@ -159,7 +159,7 @@ testDuplexConnRandomIds _ alice bob = do ("1", bobConn, Right (INV cReq)) <- alice #: ("1", "", "NEW INV") let cReq' = strEncode cReq ("11", aliceConn, Right OK) <- bob #: ("11", "", "JOIN " <> cReq' <> " 14\nbob's connInfo") - ("", bobConn', Right (CONF confId "bob's connInfo")) <- (alice <#:) + ("", bobConn', Right (CONF confId _ "bob's connInfo")) <- (alice <#:) bobConn' `shouldBe` bobConn alice #: ("2", bobConn, "LET " <> confId <> " 16\nalice's connInfo") =#> \case ("2", c, OK) -> c == bobConn; _ -> False bob <# ("", aliceConn, INFO "alice's connInfo") @@ -193,9 +193,9 @@ testContactConnection _ alice bob tom = do let cReq' = strEncode cReq bob #: ("11", "alice", "JOIN " <> cReq' <> " 14\nbob's connInfo") #> ("11", "alice", OK) - ("", "alice_contact", Right (REQ aInvId "bob's connInfo")) <- (alice <#:) + ("", "alice_contact", Right (REQ aInvId _ "bob's connInfo")) <- (alice <#:) alice #: ("2", "bob", "ACPT " <> aInvId <> " 16\nalice's connInfo") #> ("2", "bob", OK) - ("", "alice", Right (CONF bConfId "alice's connInfo")) <- (bob <#:) + ("", "alice", Right (CONF bConfId _ "alice's connInfo")) <- (bob <#:) bob #: ("12", "alice", "LET " <> bConfId <> " 16\nbob's connInfo 2") #> ("12", "alice", OK) alice <# ("", "bob", INFO "bob's connInfo 2") alice <# ("", "bob", CON) @@ -206,9 +206,9 @@ testContactConnection _ alice bob tom = do bob #: ("13", "alice", "ACK 4") #> ("13", "alice", OK) tom #: ("21", "alice", "JOIN " <> cReq' <> " 14\ntom's connInfo") #> ("21", "alice", OK) - ("", "alice_contact", Right (REQ aInvId' "tom's connInfo")) <- (alice <#:) + ("", "alice_contact", Right (REQ aInvId' _ "tom's connInfo")) <- (alice <#:) alice #: ("4", "tom", "ACPT " <> aInvId' <> " 16\nalice's connInfo") #> ("4", "tom", OK) - ("", "alice", Right (CONF tConfId "alice's connInfo")) <- (tom <#:) + ("", "alice", Right (CONF tConfId _ "alice's connInfo")) <- (tom <#:) tom #: ("22", "alice", "LET " <> tConfId <> " 16\ntom's connInfo 2") #> ("22", "alice", OK) alice <# ("", "tom", INFO "tom's connInfo 2") alice <# ("", "tom", CON) @@ -224,11 +224,11 @@ testContactConnRandomIds _ alice bob = do let cReq' = strEncode cReq ("11", aliceConn, Right OK) <- bob #: ("11", "", "JOIN " <> cReq' <> " 14\nbob's connInfo") - ("", aliceContact', Right (REQ aInvId "bob's connInfo")) <- (alice <#:) + ("", aliceContact', Right (REQ aInvId _ "bob's connInfo")) <- (alice <#:) aliceContact' `shouldBe` aliceContact ("2", bobConn, Right OK) <- alice #: ("2", "", "ACPT " <> aInvId <> " 16\nalice's connInfo") - ("", aliceConn', Right (CONF bConfId "alice's connInfo")) <- (bob <#:) + ("", aliceConn', Right (CONF bConfId _ "alice's connInfo")) <- (bob <#:) aliceConn' `shouldBe` aliceConn bob #: ("12", aliceConn, "LET " <> bConfId <> " 16\nbob's connInfo 2") #> ("12", aliceConn, OK) @@ -246,7 +246,7 @@ testRejectContactRequest _ alice bob = do ("1", "a_contact", Right (INV cReq)) <- alice #: ("1", "a_contact", "NEW CON") let cReq' = strEncode cReq bob #: ("11", "alice", "JOIN " <> cReq' <> " 10\nbob's info") #> ("11", "alice", OK) - ("", "a_contact", Right (REQ aInvId "bob's info")) <- (alice <#:) + ("", "a_contact", Right (REQ aInvId _ "bob's info")) <- (alice <#:) -- RJCT must use correct contact connection alice #: ("2a", "bob", "RJCT " <> aInvId) #> ("2a", "bob", ERR $ CONN NOT_FOUND) alice #: ("2b", "a_contact", "RJCT " <> aInvId) #> ("2b", "a_contact", OK) @@ -387,7 +387,7 @@ testConcurrentMsgDelivery _ alice bob = do ("1", "bob2", Right (INV cReq)) <- alice #: ("1", "bob2", "NEW INV") let cReq' = strEncode cReq bob #: ("11", "alice2", "JOIN " <> cReq' <> " 14\nbob's connInfo") #> ("11", "alice2", OK) - ("", "bob2", Right (CONF _confId "bob's connInfo")) <- (alice <#:) + ("", "bob2", Right (CONF _confId _ "bob's connInfo")) <- (alice <#:) -- below commands would be needed to accept bob's connection, but alice does not -- alice #: ("2", "bob", "LET " <> _confId <> " 16\nalice's connInfo") #> ("2", "bob", OK) -- bob <# ("", "alice", INFO "alice's connInfo") @@ -426,7 +426,7 @@ connect (h1, name1) (h2, name2) = do ("c1", _, Right (INV cReq)) <- h1 #: ("c1", name2, "NEW INV") let cReq' = strEncode cReq h2 #: ("c2", name1, "JOIN " <> cReq' <> " 5\ninfo2") #> ("c2", name1, OK) - ("", _, Right (CONF connId "info2")) <- (h1 <#:) + ("", _, Right (CONF connId _ "info2")) <- (h1 <#:) h1 #: ("c3", name2, "LET " <> connId <> " 5\ninfo1") #> ("c3", name2, OK) h2 <# ("", name1, INFO "info1") h2 <# ("", name1, CON) @@ -447,7 +447,7 @@ sendMessage (h1, name1) (h2, name2) msg = do -- ("c1", conn2, Right (INV cReq)) <- h1 #: ("c1", "", "NEW INV") -- let cReq' = strEncode cReq -- ("c2", conn1, Right OK) <- h2 #: ("c2", "", "JOIN " <> cReq' <> " 5\ninfo2") --- ("", _, Right (REQ connId "info2")) <- (h1 <#:) +-- ("", _, Right (REQ connId _ "info2")) <- (h1 <#:) -- h1 #: ("c3", conn2, "ACPT " <> connId <> " 5\ninfo1") =#> \case ("c3", c, OK) -> c == conn2; _ -> False -- h2 <# ("", conn1, INFO "info1") -- h2 <# ("", conn1, CON) diff --git a/tests/AgentTests/FunctionalAPITests.hs b/tests/AgentTests/FunctionalAPITests.hs index 6f9514750..571d5606d 100644 --- a/tests/AgentTests/FunctionalAPITests.hs +++ b/tests/AgentTests/FunctionalAPITests.hs @@ -163,7 +163,7 @@ runAgentClientTest alice bob baseId = do Right () <- runExceptT $ do (bobId, qInfo) <- createConnection alice SCMInvitation aliceId <- joinConnection bob qInfo "bob's connInfo" - ("", _, CONF confId "bob's connInfo") <- get alice + ("", _, CONF confId _ "bob's connInfo") <- get alice allowConnection alice bobId confId "alice's connInfo" get alice ##> ("", bobId, CON) get bob ##> ("", aliceId, INFO "alice's connInfo") @@ -199,9 +199,9 @@ runAgentClientContactTest alice bob baseId = do Right () <- runExceptT $ do (_, qInfo) <- createConnection alice SCMContact aliceId <- joinConnection bob qInfo "bob's connInfo" - ("", _, REQ invId "bob's connInfo") <- get alice + ("", _, REQ invId _ "bob's connInfo") <- get alice bobId <- acceptContact alice invId "alice's connInfo" - ("", _, CONF confId "alice's connInfo") <- get bob + ("", _, CONF confId _ "alice's connInfo") <- get bob allowConnection bob aliceId confId "bob's connInfo" get alice ##> ("", bobId, INFO "bob's connInfo") get alice ##> ("", bobId, CON) @@ -250,7 +250,7 @@ testAsyncInitiatingOffline = do aliceId <- joinConnection bob cReq "bob's connInfo" alice' <- liftIO $ getSMPAgentClient agentCfg initAgentServers subscribeConnection alice' bobId - ("", _, CONF confId "bob's connInfo") <- get alice' + ("", _, CONF confId _ "bob's connInfo") <- get alice' allowConnection alice' bobId confId "alice's connInfo" get alice' ##> ("", bobId, CON) get bob ##> ("", aliceId, INFO "alice's connInfo") @@ -266,7 +266,7 @@ testAsyncJoiningOfflineBeforeActivation = do (bobId, qInfo) <- createConnection alice SCMInvitation aliceId <- joinConnection bob qInfo "bob's connInfo" disconnectAgentClient bob - ("", _, CONF confId "bob's connInfo") <- get alice + ("", _, CONF confId _ "bob's connInfo") <- get alice allowConnection alice bobId confId "alice's connInfo" bob' <- liftIO $ getSMPAgentClient agentCfg {dbFile = testDB2} initAgentServers subscribeConnection bob' aliceId @@ -287,7 +287,7 @@ testAsyncBothOffline = do disconnectAgentClient bob alice' <- liftIO $ getSMPAgentClient agentCfg initAgentServers subscribeConnection alice' bobId - ("", _, CONF confId "bob's connInfo") <- get alice' + ("", _, CONF confId _ "bob's connInfo") <- get alice' allowConnection alice' bobId confId "alice's connInfo" bob' <- liftIO $ getSMPAgentClient agentCfg {dbFile = testDB2} initAgentServers subscribeConnection bob' aliceId @@ -316,7 +316,7 @@ testAsyncServerOffline t = do srv1 `shouldBe` testSMPServer conns1 `shouldBe` [bobId] aliceId <- joinConnection bob cReq "bob's connInfo" - ("", _, CONF confId "bob's connInfo") <- get alice + ("", _, CONF confId _ "bob's connInfo") <- get alice allowConnection alice bobId confId "alice's connInfo" get alice ##> ("", bobId, CON) get bob ##> ("", aliceId, INFO "alice's connInfo") @@ -389,7 +389,7 @@ makeConnection :: AgentClient -> AgentClient -> ExceptT AgentErrorType IO (ConnI makeConnection alice bob = do (bobId, qInfo) <- createConnection alice SCMInvitation aliceId <- joinConnection bob qInfo "bob's connInfo" - ("", _, CONF confId "bob's connInfo") <- get alice + ("", _, CONF confId _ "bob's connInfo") <- get alice allowConnection alice bobId confId "alice's connInfo" get alice ##> ("", bobId, CON) get bob ##> ("", aliceId, INFO "alice's connInfo") diff --git a/tests/AgentTests/NotificationTests.hs b/tests/AgentTests/NotificationTests.hs index 62d8adbc9..bfaa9d06b 100644 --- a/tests/AgentTests/NotificationTests.hs +++ b/tests/AgentTests/NotificationTests.hs @@ -212,7 +212,7 @@ testNotificationSubscriptionExistingConnection APNSMockServer {apnsQ} = do -- establish connection (bobId, qInfo) <- createConnection alice SCMInvitation aliceId <- joinConnection bob qInfo "bob's connInfo" - ("", _, CONF confId "bob's connInfo") <- get alice + ("", _, CONF confId _ "bob's connInfo") <- get alice allowConnection alice bobId confId "alice's connInfo" get bob ##> ("", aliceId, INFO "alice's connInfo") get alice ##> ("", bobId, CON) @@ -276,7 +276,7 @@ testNotificationSubscriptionNewConnection APNSMockServer {apnsQ} = do aliceId <- joinConnection bob qInfo "bob's connInfo" liftIO $ print 0 void $ messageNotification apnsQ - ("", _, CONF confId "bob's connInfo") <- get alice + ("", _, CONF confId _ "bob's connInfo") <- get alice liftIO $ threadDelay 500000 allowConnection alice bobId confId "alice's connInfo" liftIO $ print 1 @@ -330,7 +330,7 @@ testChangeNotificationsMode APNSMockServer {apnsQ} = do -- establish connection (bobId, qInfo) <- createConnection alice SCMInvitation aliceId <- joinConnection bob qInfo "bob's connInfo" - ("", _, CONF confId "bob's connInfo") <- get alice + ("", _, CONF confId _ "bob's connInfo") <- get alice allowConnection alice bobId confId "alice's connInfo" get bob ##> ("", aliceId, INFO "alice's connInfo") get alice ##> ("", bobId, CON) @@ -395,7 +395,7 @@ testChangeToken APNSMockServer {apnsQ} = do -- establish connection (bobId, qInfo) <- createConnection alice SCMInvitation aliceId <- joinConnection bob qInfo "bob's connInfo" - ("", _, CONF confId "bob's connInfo") <- get alice + ("", _, CONF confId _ "bob's connInfo") <- get alice allowConnection alice bobId confId "alice's connInfo" get bob ##> ("", aliceId, INFO "alice's connInfo") get alice ##> ("", bobId, CON)